15 #include <FairDetector.h>
16 #include <FairLogger.h>
17 #include <FairRootManager.h>
19 #include <FairRuntimeDb.h>
20 #include <FairVolume.h>
22 #include <TClonesArray.h>
23 #include <TGeoManager.h>
24 #include <TLorentzVector.h>
26 #include <TVirtualMC.h>
27 #include <TVirtualMCStack.h>
34 constexpr
auto cRED =
"\033[1;31m";
37 constexpr
auto cGREEN =
"\033[1;32m";
38 constexpr
auto cBLUE =
"\033[1;34m";
43 : FairDetector(name, active,
kAtTpc), fTrackID(-1), fVolumeID(-1), fPos(), fMom(), fTime(-1.), fLength(-1.),
44 fELoss(-1), fPosIndex(-1), fAtTpcPointCollection(new TClonesArray(
"AtMCPoint")), fELossAcc(-1)
50 if (fAtTpcPointCollection) {
51 fAtTpcPointCollection->Delete();
52 delete fAtTpcPointCollection;
58 FairDetector::Initialize();
59 FairRuntimeDb *rtdb = FairRun::Instance()->GetRuntimeDb();
60 rtdb->getContainer(
"AtTpcGeoPar");
63 void AtTpc::trackEnteringVolume()
65 auto AZ = DecodePdG(gMC->TrackPid());
68 fTime = gMC->TrackTime() * 1.0e09;
69 fLength = gMC->TrackLength();
70 gMC->TrackPosition(fPosIn);
71 gMC->TrackMomentum(fMomIn);
72 fTrackID = gMC->GetStack()->GetCurrentTrackNumber();
76 (fVolName ==
"drift_volume" || fVolName ==
"cell"))
82 LOG(debug) <<
cGREEN <<
" AtTPC: Beam Event ";
84 LOG(debug) <<
cBLUE <<
" AtTPC: Reaction/Decay Event ";
86 LOG(debug) <<
" AtTPC: First hit in Volume " << fVolName;
87 LOG(debug) <<
" Particle : " << gMC->ParticleName(gMC->TrackPid());
88 LOG(debug) <<
" PID PdG : " << gMC->TrackPid();
89 LOG(debug) <<
" Atomic Mass : " << AZ.first;
90 LOG(debug) <<
" Atomic Number : " << AZ.second;
91 LOG(debug) <<
" Volume ID " << gMC->CurrentVolID(VolumeID);
92 LOG(debug) <<
" Track ID : " << fTrackID;
93 LOG(debug) <<
" Position : " << fPosIn.X() <<
" " << fPosIn.Y() <<
" " << fPosIn.Z();
94 LOG(debug) <<
" Momentum : " << fMomIn.X() <<
" " << fMomIn.Y() <<
" " << fMomIn.Z();
95 LOG(debug) <<
" Total relativistic energy " << gMC->Etot();
97 LOG(debug) <<
" Mass of the Tracked particle (gMC) : " << gMC->TrackMass();
98 LOG(debug) <<
" Initial energy of the beam particle in this volume : "
101 LOG(debug) <<
" Total energy of the current track (gMC) : "
102 << ((gMC->Etot() - gMC->TrackMass()) * 1000.);
103 LOG(debug) <<
" ==================================================== " <<
cNORMAL;
106 void AtTpc::getTrackParametersFromMC()
108 fELoss = gMC->Edep();
110 fTime = gMC->TrackTime() * 1.0e09;
111 fLength = gMC->TrackLength();
112 gMC->TrackPosition(fPosIn);
113 gMC->TrackMomentum(fMomIn);
114 fTrackID = gMC->GetStack()->GetCurrentTrackNumber();
117 void AtTpc::getTrackParametersWhileExiting()
119 fTrackID = gMC->GetStack()->GetCurrentTrackNumber();
120 gMC->TrackPosition(fPosOut);
121 gMC->TrackMomentum(fMomOut);
124 if (gMC->IsTrackExiting()) {
126 if ((fVolName.Contains(
"drift_volume") || fVolName.Contains(
"cell")) &&
132 void AtTpc::resetVertex()
135 LOG(INFO) <<
cRED <<
" - AtTpc Warning : Beam punched through the AtTPC. Reseting Vertex! " <<
cNORMAL << std::endl;
138 void AtTpc::correctPosOut()
140 const Double_t *oldpos =
nullptr;
141 const Double_t *olddirection =
nullptr;
143 Double_t newdirection[3];
146 gGeoManager->FindNode(fPosOut.X(), fPosOut.Y(), fPosOut.Z());
147 oldpos = gGeoManager->GetCurrentPoint();
148 olddirection = gGeoManager->GetCurrentDirection();
150 for (Int_t i = 0; i < 3; i++) {
151 newdirection[i] = -1 * olddirection[i];
154 gGeoManager->SetCurrentDirection(newdirection);
155 safety = gGeoManager->GetSafeDistance();
156 gGeoManager->SetCurrentDirection(-newdirection[0], -newdirection[1], -newdirection[2]);
158 for (Int_t i = 0; i < 3; i++) {
159 newpos[i] = oldpos[i] - (3 * safety * olddirection[i]);
162 fPosOut.SetX(newpos[0]);
163 fPosOut.SetY(newpos[1]);
164 fPosOut.SetZ(newpos[2]);
167 bool AtTpc::reactionOccursHere()
171 bool isInRightVolume = fVolName.Contains(
"drift_volume") || fVolName.Contains(
"cell");
172 return atEnergyLoss && isPrimaryBeam && isInRightVolume;
178 auto *stack =
dynamic_cast<AtStack *
>(gMC->GetStack());
179 fVolName = gMC->CurrentVolName();
180 fVolumeID = vol->getMCid();
181 fDetCopyID = vol->getCopyNo();
183 if (gMC->IsTrackEntering())
184 trackEnteringVolume();
186 getTrackParametersFromMC();
188 if (gMC->IsTrackExiting() || gMC->IsTrackStop() || gMC->IsTrackDisappeared())
189 getTrackParametersWhileExiting();
194 if (reactionOccursHere())
195 startReactionEvent();
202 void AtTpc::startReactionEvent()
208 TLorentzVector StopPos;
209 TLorentzVector StopMom;
210 gMC->TrackPosition(StopPos);
211 gMC->TrackMomentum(StopMom);
214 LOG(debug) <<
cYELLOW <<
" Beam energy loss before reaction : " << fELossAcc * 1000;
215 LOG(debug) <<
" Mass of the Tracked particle : " << gMC->TrackMass();
217 LOG(debug) <<
" Total energy of the Beam particle before reaction : " << StopEnergy <<
cNORMAL;
220 StopMom.Px(), StopMom.Py(), StopMom.Pz(), StopEnergy);
225 auto AZ = DecodePdG(gMC->TrackPid());
240 AddHit(fTrackID, fVolumeID, fVolName, fDetCopyID, TVector3(fPosIn.X(), fPosIn.Y(), fPosIn.Z()),
241 TVector3(fMomIn.Px(), fMomIn.Py(), fMomIn.Pz()), fTime, fLength, fELoss, EIni, AIni, AZ.first, AZ.second);
247 fAtTpcPointCollection->Clear();
252 FairRootManager::Instance()->Register(
"AtTpcPoint",
"AtTpc", fAtTpcPointCollection, kTRUE);
258 return fAtTpcPointCollection;
266 fAtTpcPointCollection->Clear();
271 Int_t nHits = fAtTpcPointCollection->GetEntriesFast();
272 LOG(INFO) <<
"AtTPC: " << nHits <<
" points registered in this event";
277 TString fileName = GetGeometryFileName();
278 if (fileName.EndsWith(
".geo")) {
279 LOG(INFO) <<
"Constructing AtTPC geometry from ASCII file " << fileName;
281 }
else if (fileName.EndsWith(
".root")) {
282 LOG(INFO) <<
"Constructing AtTPC geometry from ROOT file " << fileName;
283 ConstructRootGeometry();
285 std::cout <<
"Geometry format not supported." << std::endl;
292 TString tsname = name;
293 if (tsname.Contains(
"drift_volume") || tsname.Contains(
"window") || tsname.Contains(
"cell")) {
294 LOG(INFO) <<
" AtTPC geometry: Sensitive volume found: " << tsname;
301 AtTpc::AddHit(Int_t trackID, Int_t detID, TVector3 pos, TVector3 mom, Double_t time, Double_t length, Double_t eLoss)
303 TClonesArray &clref = *fAtTpcPointCollection;
304 Int_t size = clref.GetEntriesFast();
305 return new (clref[size])
AtMCPoint(trackID, detID, pos, mom, time, length, eLoss);
310 Double_t time, Double_t length, Double_t eLoss, Double_t EIni, Double_t AIni, Int_t A, Int_t Z)
312 TClonesArray &clref = *fAtTpcPointCollection;
313 Int_t size = clref.GetEntriesFast();
314 if (fVerboseLevel > 1)
315 LOG(INFO) <<
"AtTPC: Adding Point at (" << pos.X() <<
", " << pos.Y() <<
", " << pos.Z() <<
") cm, detector "
316 << detID <<
", track " << trackID <<
", energy loss " << eLoss * 1e06 <<
" keV";
318 return new (clref[size])
319 AtMCPoint(trackID, detID, pos, mom, time, length, eLoss, VolName, detCopyID, EIni, AIni, A, Z);
322 std::pair<Int_t, Int_t> AtTpc::DecodePdG(Int_t PdG_Code)
324 Int_t A = PdG_Code / 10 % 1000;
325 Int_t Z = PdG_Code / 10000 % 1000;
327 std::pair<Int_t, Int_t> nucleus;
329 if (PdG_Code == 2212) {
332 }
else if (PdG_Code == 2112) {