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>
49 inline auto GetLightYield(
const int charge,
const double length,
const double edep) ->
double
52 if (charge != 0 && length > 0)
57 if (TMath::Abs(charge) >= 2)
59 birkC1Mod *= 7.2 / 12.6;
62 const double dedxcm = 1000. * edep / length;
63 const double lightYield = edep / (1. + birkC1Mod * dedxcm +
BirkC2 * dedxcm * dedxcm);
81 : FairDetector{
"R3BNeuland", true,
kNEULAND }
93 :
R3BNeuland(fmt::format(
"neuland_v3_{}dp.geo.root", nDP), combi)
100 LOG(info) <<
"R3BNeuland initialization ...";
102 FairDetector::Initialize();
111 if (gMC->IsTrackEntering())
115 LOG(warn) <<
"R3BNeuland: Incomplete hit discarded";
129 track_pid_map_.emplace(gMC->GetStack()->GetCurrentTrackNumber(), gMC->TrackPid());
130 if (
auto search =
track_pid_map_.find(gMC->GetStack()->GetCurrentParentTrackNumber());
139 light_yield_ += GetLightYield(gMC->TrackCharge(), gMC->TrackStep(), gMC->Edep());
142 if (gMC->IsTrackExiting() || gMC->IsTrackStop() || gMC->IsTrackDisappeared())
145 constexpr auto minimum_energy_cutoff = 1e-20;
152 track_id_ = gMC->GetStack()->GetCurrentTrackNumber();
158 "R3BNeuland: Adding Point at (\"{}\", \"{}\", \"{}\") cm, paddle {}, track {}, energy loss {} GeV",
165 gMC->GetStack()->GetCurrentParentTrackNumber());
166 auto* neuland_point =
170 neuland_point->SetPosition(
pos_in_.Vect());
171 neuland_point->SetMomentum(
mom_in_.Vect());
172 neuland_point->SetTime(
time_);
173 neuland_point->SetLength(
length_);
175 neuland_point->SetEventID(gMC->CurrentEvent());
181 auto* stack =
dynamic_cast<R3BStack*
>(gMC->GetStack());
193 if (fVerboseLevel != 0)
206 points.push_back(*point);
212 LOG(info) <<
"R3BNeuland: " <<
neuland_points_.get_constref().size() <<
" Neuland Points registered in this event";
240 FairRuntimeDb* rtdb = FairRun::Instance()->GetRuntimeDb();
244 TGeoNode* geoNodeNeuland =
nullptr;
245 for (
int i{}; i < gGeoManager->GetTopNode()->GetNdaughters(); i++)
247 if (TString(gGeoManager->GetTopNode()->GetDaughter(i)->GetVolume()->GetName()) ==
"volNeuland")
249 geoNodeNeuland = gGeoManager->GetTopNode()->GetDaughter(i);
254 if (geoNodeNeuland ==
nullptr)
256 LOG(fatal) <<
"volNeuland not found";
289 auto* geo_loader = FairGeoLoader::Instance();
290 if (geo_loader ==
nullptr)
292 geo_loader = std::make_unique<FairGeoLoader>(
"TGeo",
"FairGeoLoader").release();
295 if (
auto* top_volume = gGeoManager->GetTopVolume(); top_volume !=
nullptr)
298 auto* neuland_node = top_volume->AddNode(neuland_geo, 0,
rot_trans_.MakeClone());
301 ExpandNode(neuland_node);
312 if (!GetGeometryFileName().EndsWith(
".root"))
314 R3BLOG(fatal, GetName() <<
" (which is a " << ClassName() <<
") geometry file is not specified");
317 fmt::format(
"Constructing {} (which is a {}) geometry from ROOT file {} ...",
320 GetGeometryFileName().Data()));
321 ConstructRootGeometry();
324 if (
auto* top_node = gGeoManager->GetTopNode(); top_node !=
nullptr)
326 auto* neuland_node = top_node->GetDaughter(gGeoManager->GetTopNode()->GetNdaughters() - 1);
327 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 tranlation 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.