16#include "FairRuntimeDb.h"
22#include "TClonesArray.h"
23#include "TGeoManager.h"
24#include "TVirtualMC.h"
25#include <FairGeoLoader.h>
26#include <FairRootManager.h>
27#include <FairVolume.h>
30#include <RtypesCore.h>
31#include <TCollection.h>
32#include <TGeoMatrix.h>
36#include <fairlogger/Logger.h>
38#include <fmt/format.h>
50 inline auto GetLightYield(
const int charge,
const double length,
const double edep) ->
double
53 if (charge != 0 && length > 0)
58 if (TMath::Abs(charge) >= 2)
60 birkC1Mod *= 7.2 / 12.6;
63 const double dedxcm = 1000. * edep / length;
64 const double lightYield = edep / (1. + birkC1Mod * dedxcm +
BirkC2 * dedxcm * dedxcm);
82 : FairDetector{
"R3BNeuland", true,
kNEULAND }
94 :
R3BNeuland(fmt::format(
"neuland_v3_{}dp.geo.root", nDP), combi)
101 LOG(info) <<
"R3BNeuland initialization ...";
103 FairDetector::Initialize();
112 if (gMC->IsTrackEntering())
116 LOG(warn) <<
"R3BNeuland: Incomplete hit discarded";
130 track_pid_map_.emplace(gMC->GetStack()->GetCurrentTrackNumber(), gMC->TrackPid());
131 if (
auto search =
track_pid_map_.find(gMC->GetStack()->GetCurrentParentTrackNumber());
140 light_yield_ += GetLightYield(gMC->TrackCharge(), gMC->TrackStep(), gMC->Edep());
143 if (gMC->IsTrackExiting() || gMC->IsTrackStop() || gMC->IsTrackDisappeared())
146 constexpr auto minimum_energy_cutoff = 1e-20;
153 track_id_ = gMC->GetStack()->GetCurrentTrackNumber();
159 "R3BNeuland: Adding Point at (\"{}\", \"{}\", \"{}\") cm, paddle {}, track {}, energy loss {} GeV",
166 gMC->GetStack()->GetCurrentParentTrackNumber());
167 auto* neuland_point =
171 neuland_point->SetPosition(
pos_in_.Vect());
172 neuland_point->SetMomentum(
mom_in_.Vect());
173 neuland_point->SetTime(
time_);
174 neuland_point->SetLength(
length_);
176 neuland_point->SetEventID(gMC->CurrentEvent());
182 auto* stack =
dynamic_cast<R3BStack*
>(gMC->GetStack());
194 if (fVerboseLevel != 0)
207 points.push_back(*point);
213 LOG(info) <<
"R3BNeuland: " <<
neuland_points_.get_constref().size() <<
" Neuland Points registered in this event";
241 FairRuntimeDb* rtdb = FairRun::Instance()->GetRuntimeDb();
245 TGeoNode* geoNodeNeuland =
nullptr;
246 for (
int i{}; i < gGeoManager->GetTopNode()->GetNdaughters(); i++)
248 if (TString(gGeoManager->GetTopNode()->GetDaughter(i)->GetVolume()->GetName()) ==
"volNeuland")
250 geoNodeNeuland = gGeoManager->GetTopNode()->GetDaughter(i);
255 if (geoNodeNeuland ==
nullptr)
257 LOG(fatal) <<
"volNeuland not found";
290 auto* geo_loader = FairGeoLoader::Instance();
291 if (geo_loader ==
nullptr)
293 geo_loader = std::make_unique<FairGeoLoader>(
"TGeo",
"FairGeoLoader").release();
296 if (
auto* top_volume = gGeoManager->GetTopVolume(); top_volume !=
nullptr)
299 auto* neuland_node = top_volume->AddNode(neuland_geo, 0,
rot_trans_.MakeClone());
302 ExpandNode(neuland_node);
313 if (!GetGeometryFileName().EndsWith(
".root"))
315 R3BLOG(fatal, GetName() <<
" (which is a " << ClassName() <<
") geometry file is not specified");
318 fmt::format(
"Constructing {} (which is a {}) geometry from ROOT file {} ...",
321 GetGeometryFileName().Data()));
322 ConstructRootGeometry();
325 if (
auto* top_node = gGeoManager->GetTopNode(); top_node !=
nullptr)
327 auto* neuland_node = top_node->GetDaughter(gGeoManager->GetTopNode()->GetNdaughters() - 1);
328 dynamic_cast<TGeoNodeMatrix*
>(neuland_node)->SetMatrix(
rot_trans_.MakeClone());
#define R3BLOG(severity, x)
constexpr auto seconds_to_nanoseconds
NeuLAND geometry parameter storage.
NeuLAND detector simulation class.
bool is_last_hit_done_
Flag to check if last hit finished.
auto CheckIfSensitive(std::string name) -> bool override
R3B::OutputVectorConnector< R3BNeulandPoint > neuland_points_
Output data written to the ROOT file.
int track_id_
A buffer for the track IDs.
TGeoCombiTrans rot_trans_
Rotation and translation of NeuLAND detector.
TLorentzVector pos_out_
A buffer for the position where the track goes out of the volume.
double energy_loss_
A buffer for the energy losses.
auto ProcessHits(FairVolume *=nullptr) -> bool override
int paddle_id_
A buffer for the paddle ids.
std::string geo_file_
Geometry file name. The file must be present if EnableAutoGeoBuild() is disabled.
double time_
A buffer for time values.
TLorentzVector mom_out_
A buffer for the position when the track goes out of the volume.
void FinishEvent() override
TLorentzVector pos_in_
A buffer for the position where the track goes into the volume.
void EndOfEvent() override
bool is_geo_auto_built
Flag to check if geo-build is needed.
R3B::Neuland::Geometry::Creator geo_creator_
Creating NeuLAND geometry if EnableAutoGeoBuild() is enabled.
void write_parameter_file()
void create_geo_from_root_file()
int particle_id_
A buffer for the particle IDs.
R3BNeulandGeoPar * neuland_geo_par_
Output parameter containing the geometry information.
int num_of_planes_
The number of planes.
R3BNeuland()
Default constructor.
int parent_particle_id_
A buffer for the parent particle IDs.
std::map< int, int > track_pid_map_
A map with the track ID as the key and the particle ID as the value.
void ConstructGeometry() override
auto GetCollection(int iColl) const -> TClonesArray *override
void Print(Option_t *="") const override
double length_
A buffer for track lengths.
double light_yield_
A buffer for the light yields.
void Initialize() override
TLorentzVector mom_in_
A buffer for the momentum when the track goes into the volume.
std::unique_ptr< TClonesArray > tca_points_buffer_
The TCA data buffer used to be returned by virtual method GetCollection(int iColl).
void SetLightYield(double light_yield)
void AddPoint(DetectorId iDet)
Increment number of points for the current track in a given detector.