ATTPCROOT  0.3.0-alpha
A ROOT-based framework for analyzing data from active target detectors
AtTpc.cxx
Go to the documentation of this file.
1 /********************************************************************************
2  * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
3  * *
4  * This software is distributed under the terms of the *
5  * GNU Lesser General Public Licence version 3 (LGPL) version 3, *
6  * copied verbatim in the file "LICENSE" *
7  ********************************************************************************/
8 #include "AtTpc.h"
9 
10 #include "AtDetectorList.h"
11 #include "AtMCPoint.h"
12 #include "AtStack.h"
13 #include "AtVertexPropagator.h"
14 
15 #include <FairDetector.h>
16 #include <FairLogger.h>
17 #include <FairRootManager.h>
18 #include <FairRun.h>
19 #include <FairRuntimeDb.h>
20 #include <FairVolume.h>
21 
22 #include <TClonesArray.h>
23 #include <TGeoManager.h>
24 #include <TLorentzVector.h>
25 #include <TVector3.h>
26 #include <TVirtualMC.h>
27 #include <TVirtualMCStack.h>
28 
29 #include <iostream>
30 
31 using std::cout;
32 using std::endl;
33 
34 constexpr auto cRED = "\033[1;31m";
35 constexpr auto cYELLOW = "\033[1;33m";
36 constexpr auto cNORMAL = "\033[0m";
37 constexpr auto cGREEN = "\033[1;32m";
38 constexpr auto cBLUE = "\033[1;34m";
39 
40 AtTpc::AtTpc() : AtTpc("AtTpc", true) {}
41 
42 AtTpc::AtTpc(const char *name, Bool_t active)
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)
45 {
46 }
47 
49 {
50  if (fAtTpcPointCollection) {
51  fAtTpcPointCollection->Delete();
52  delete fAtTpcPointCollection;
53  }
54 }
55 
57 {
58  FairDetector::Initialize();
59  FairRuntimeDb *rtdb = FairRun::Instance()->GetRuntimeDb();
60  rtdb->getContainer("AtTpcGeoPar");
61 }
62 
63 void AtTpc::trackEnteringVolume()
64 {
65  auto AZ = DecodePdG(gMC->TrackPid());
66  fELoss = 0.;
67  fELossAcc = 0.;
68  fTime = gMC->TrackTime() * 1.0e09;
69  fLength = gMC->TrackLength();
70  gMC->TrackPosition(fPosIn);
71  gMC->TrackMomentum(fMomIn);
72  fTrackID = gMC->GetStack()->GetCurrentTrackNumber();
73 
74  // Position of the first hit of the beam in the TPC volume ( For tracking purposes in the TPC)
75  if (AtVertexPropagator::Instance()->GetBeamEvtCnt() % 2 != 0 && fTrackID == 0 &&
76  (fVolName == "drift_volume" || fVolName == "cell"))
77  InPos = fPosIn;
78 
79  Int_t VolumeID = 0;
80 
81  if (AtVertexPropagator::Instance()->GetBeamEvtCnt() % 2 != 0)
82  LOG(debug) << cGREEN << " AtTPC: Beam Event ";
83  else if (AtVertexPropagator::Instance()->GetDecayEvtCnt() % 2 == 0)
84  LOG(debug) << cBLUE << " AtTPC: Reaction/Decay Event ";
85 
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();
96  LOG(debug) << " Mass of the Beam particle (gAVTP) : " << AtVertexPropagator::Instance()->GetBeamMass();
97  LOG(debug) << " Mass of the Tracked particle (gMC) : " << gMC->TrackMass(); // NB: with electrons
98  LOG(debug) << " Initial energy of the beam particle in this volume : "
99  << ((gMC->Etot() - AtVertexPropagator::Instance()->GetBeamMass() * 0.93149401) *
100  1000.); // Relativistic Mass
101  LOG(debug) << " Total energy of the current track (gMC) : "
102  << ((gMC->Etot() - gMC->TrackMass()) * 1000.); // Relativistic Mass
103  LOG(debug) << " ==================================================== " << cNORMAL;
104 }
105 
106 void AtTpc::getTrackParametersFromMC()
107 {
108  fELoss = gMC->Edep();
109  fELossAcc += fELoss;
110  fTime = gMC->TrackTime() * 1.0e09;
111  fLength = gMC->TrackLength();
112  gMC->TrackPosition(fPosIn);
113  gMC->TrackMomentum(fMomIn);
114  fTrackID = gMC->GetStack()->GetCurrentTrackNumber();
115 }
116 
117 void AtTpc::getTrackParametersWhileExiting()
118 {
119  fTrackID = gMC->GetStack()->GetCurrentTrackNumber();
120  gMC->TrackPosition(fPosOut);
121  gMC->TrackMomentum(fMomOut);
122 
123  // Correct fPosOut
124  if (gMC->IsTrackExiting()) {
125  correctPosOut();
126  if ((fVolName.Contains("drift_volume") || fVolName.Contains("cell")) &&
127  AtVertexPropagator::Instance()->GetBeamEvtCnt() % 2 != 0 && fTrackID == 0)
128  resetVertex();
129  }
130 }
131 
132 void AtTpc::resetVertex()
133 {
135  LOG(INFO) << cRED << " - AtTpc Warning : Beam punched through the AtTPC. Reseting Vertex! " << cNORMAL << std::endl;
136 }
137 
138 void AtTpc::correctPosOut()
139 {
140  const Double_t *oldpos = nullptr;
141  const Double_t *olddirection = nullptr;
142  Double_t newpos[3];
143  Double_t newdirection[3];
144  Double_t safety = 0;
145 
146  gGeoManager->FindNode(fPosOut.X(), fPosOut.Y(), fPosOut.Z());
147  oldpos = gGeoManager->GetCurrentPoint();
148  olddirection = gGeoManager->GetCurrentDirection();
149 
150  for (Int_t i = 0; i < 3; i++) {
151  newdirection[i] = -1 * olddirection[i];
152  }
153 
154  gGeoManager->SetCurrentDirection(newdirection);
155  safety = gGeoManager->GetSafeDistance(); // Get distance to boundry?
156  gGeoManager->SetCurrentDirection(-newdirection[0], -newdirection[1], -newdirection[2]);
157 
158  for (Int_t i = 0; i < 3; i++) {
159  newpos[i] = oldpos[i] - (3 * safety * olddirection[i]);
160  }
161 
162  fPosOut.SetX(newpos[0]);
163  fPosOut.SetY(newpos[1]);
164  fPosOut.SetZ(newpos[2]);
165 }
166 
167 bool AtTpc::reactionOccursHere()
168 {
169  bool atEnergyLoss = fELossAcc * 1000 > AtVertexPropagator::Instance()->GetRndELoss();
170  bool isPrimaryBeam = AtVertexPropagator::Instance()->GetBeamEvtCnt() % 2 != 0 && fTrackID == 0;
171  bool isInRightVolume = fVolName.Contains("drift_volume") || fVolName.Contains("cell");
172  return atEnergyLoss && isPrimaryBeam && isInRightVolume;
173 }
174 Bool_t AtTpc::ProcessHits(FairVolume *vol)
175 {
178  auto *stack = dynamic_cast<AtStack *>(gMC->GetStack());
179  fVolName = gMC->CurrentVolName();
180  fVolumeID = vol->getMCid();
181  fDetCopyID = vol->getCopyNo();
182 
183  if (gMC->IsTrackEntering())
184  trackEnteringVolume();
185 
186  getTrackParametersFromMC();
187 
188  if (gMC->IsTrackExiting() || gMC->IsTrackStop() || gMC->IsTrackDisappeared())
189  getTrackParametersWhileExiting();
190 
191  addHit();
192 
193  // Reaction Occurs here
194  if (reactionOccursHere())
195  startReactionEvent();
196 
197  // Increment number of AtTpc det points in TParticle
198  stack->AddPoint(kAtTpc);
199  return kTRUE;
200 }
201 
202 void AtTpc::startReactionEvent()
203 {
204 
205  gMC->StopTrack();
207 
208  TLorentzVector StopPos;
209  TLorentzVector StopMom;
210  gMC->TrackPosition(StopPos);
211  gMC->TrackMomentum(StopMom);
212  Double_t StopEnergy = ((gMC->Etot() - AtVertexPropagator::Instance()->GetBeamMass() * 0.93149401) * 1000.);
213 
214  LOG(debug) << cYELLOW << " Beam energy loss before reaction : " << fELossAcc * 1000;
215  LOG(debug) << " Mass of the Tracked particle : " << gMC->TrackMass();
216  LOG(debug) << " Mass of the Beam particle (gAVTP) : " << AtVertexPropagator::Instance()->GetBeamMass();
217  LOG(debug) << " Total energy of the Beam particle before reaction : " << StopEnergy << cNORMAL; // Relativistic Mass
218 
219  AtVertexPropagator::Instance()->SetVertex(StopPos.X(), StopPos.Y(), StopPos.Z(), InPos.X(), InPos.Y(), InPos.Z(),
220  StopMom.Px(), StopMom.Py(), StopMom.Pz(), StopEnergy);
221 }
222 
223 void AtTpc::addHit()
224 {
225  auto AZ = DecodePdG(gMC->TrackPid());
226 
227  Double_t EIni = 0;
228  Double_t AIni = 0;
229 
230  // We assume that the beam-like particle is fTrackID==0 since it is the first one added in the
231  // primary generator
232  if (AtVertexPropagator::Instance()->GetBeamEvtCnt() % 2 != 0 && fTrackID == 0) {
233  EIni = 0;
234  AIni = 0;
235  } else if (AtVertexPropagator::Instance()->GetDecayEvtCnt() % 2 == 0) {
236  EIni = AtVertexPropagator::Instance()->GetTrackEnergy(fTrackID);
237  AIni = AtVertexPropagator::Instance()->GetTrackAngle(fTrackID);
238  }
239 
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);
242 }
243 
245 {
246 
247  fAtTpcPointCollection->Clear();
248 }
249 
251 {
252  FairRootManager::Instance()->Register("AtTpcPoint", "AtTpc", fAtTpcPointCollection, kTRUE);
253 }
254 
255 TClonesArray *AtTpc::GetCollection(Int_t iColl) const
256 {
257  if (iColl == 0) {
258  return fAtTpcPointCollection;
259  } else {
260  return nullptr;
261  }
262 }
263 
265 {
266  fAtTpcPointCollection->Clear();
267 }
268 
269 void AtTpc::Print(Option_t *option) const
270 {
271  Int_t nHits = fAtTpcPointCollection->GetEntriesFast();
272  LOG(INFO) << "AtTPC: " << nHits << " points registered in this event";
273 }
274 
276 {
277  TString fileName = GetGeometryFileName();
278  if (fileName.EndsWith(".geo")) {
279  LOG(INFO) << "Constructing AtTPC geometry from ASCII file " << fileName;
280  // ConstructASCIIGeometry();
281  } else if (fileName.EndsWith(".root")) {
282  LOG(INFO) << "Constructing AtTPC geometry from ROOT file " << fileName;
283  ConstructRootGeometry();
284  } else {
285  std::cout << "Geometry format not supported." << std::endl;
286  }
287 }
288 
289 Bool_t AtTpc::CheckIfSensitive(std::string name)
290 {
291 
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;
295  return kTRUE;
296  }
297  return kFALSE;
298 }
299 
300 AtMCPoint *
301 AtTpc::AddHit(Int_t trackID, Int_t detID, TVector3 pos, TVector3 mom, Double_t time, Double_t length, Double_t eLoss)
302 {
303  TClonesArray &clref = *fAtTpcPointCollection;
304  Int_t size = clref.GetEntriesFast();
305  return new (clref[size]) AtMCPoint(trackID, detID, pos, mom, time, length, eLoss);
306 }
307 
308 // ----- Private method AddHit --------------------------------------------
309 AtMCPoint *AtTpc::AddHit(Int_t trackID, Int_t detID, TString VolName, Int_t detCopyID, TVector3 pos, TVector3 mom,
310  Double_t time, Double_t length, Double_t eLoss, Double_t EIni, Double_t AIni, Int_t A, Int_t Z)
311 {
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";
317 
318  return new (clref[size])
319  AtMCPoint(trackID, detID, pos, mom, time, length, eLoss, VolName, detCopyID, EIni, AIni, A, Z);
320 }
321 
322 std::pair<Int_t, Int_t> AtTpc::DecodePdG(Int_t PdG_Code)
323 {
324  Int_t A = PdG_Code / 10 % 1000;
325  Int_t Z = PdG_Code / 10000 % 1000;
326 
327  std::pair<Int_t, Int_t> nucleus;
328 
329  if (PdG_Code == 2212) {
330  nucleus.first = 1;
331  nucleus.second = 1;
332  } else if (PdG_Code == 2112) {
333  nucleus.first = 1;
334  nucleus.second = 0;
335  } else {
336  nucleus.first = A;
337  nucleus.second = Z;
338  }
339 
340  return nucleus;
341 }
342 
AtTpc::Initialize
virtual void Initialize() override
Definition: AtTpc.cxx:56
AtDetectorList.h
cNORMAL
constexpr auto cNORMAL
Definition: AtTpc.cxx:36
AtTpc::CheckIfSensitive
virtual Bool_t CheckIfSensitive(std::string name) override
Definition: AtTpc.cxx:289
ClassImp
ClassImp(AtFindVertex)
AtVertexPropagator::ResetVertex
void ResetVertex()
Definition: AtVertexPropagator.cxx:65
AtVertexPropagator::GetBeamEvtCnt
Int_t GetBeamEvtCnt()
Definition: AtVertexPropagator.cxx:188
AtTpc::AtTpc
AtTpc()
Definition: AtTpc.cxx:40
AtTpc
Definition: AtTpc.h:29
cBLUE
constexpr auto cBLUE
Definition: AtTpc.cxx:38
AtTpc::AddHit
AtMCPoint * AddHit(Int_t trackID, Int_t detID, TVector3 pos, TVector3 mom, Double_t time, Double_t length, Double_t eLoss)
Definition: AtTpc.cxx:301
AtVertexPropagator.h
AtStack.h
AtTpc::ProcessHits
virtual Bool_t ProcessHits(FairVolume *v=0) override
Definition: AtTpc.cxx:174
AtTpc::Register
virtual void Register() override
Definition: AtTpc.cxx:250
AtTpc::EndOfEvent
virtual void EndOfEvent() override
Definition: AtTpc.cxx:244
AtTpc::Print
virtual void Print(Option_t *option="") const override
Definition: AtTpc.cxx:269
AtVertexPropagator::GetBeamMass
Double_t GetBeamMass()
Definition: AtVertexPropagator.cxx:236
cYELLOW
constexpr auto cYELLOW
Definition: AtTpc.cxx:35
AtVertexPropagator::SetVertex
void SetVertex(Double_t vx, Double_t vy, Double_t vz, Double_t invx, Double_t invy, Double_t invz, Double_t px, Double_t py, Double_t pz, Double_t E)
Definition: AtVertexPropagator.cxx:40
AtMCPoint.h
AtVertexPropagator::GetRndELoss
Double_t GetRndELoss()
Definition: AtVertexPropagator.cxx:240
AtTpc.h
cRED
constexpr auto cRED
Definition: AtTpc.cxx:34
AtTpc::~AtTpc
virtual ~AtTpc()
Definition: AtTpc.cxx:48
AtVertexPropagator::Instance
static AtVertexPropagator * Instance()
Definition: AtVertexPropagator.cxx:18
AtMCPoint
Definition: AtMCPoint.h:26
AtVertexPropagator::GetTrackEnergy
Double_t GetTrackEnergy(int trackID)
Definition: AtVertexPropagator.cxx:109
AtTpc::ConstructGeometry
virtual void ConstructGeometry() override
Definition: AtTpc.cxx:275
AtTpc::GetCollection
virtual TClonesArray * GetCollection(Int_t iColl) const override
Definition: AtTpc.cxx:255
AtStack
Definition: AtStack.h:54
AtTpc::Reset
virtual void Reset() override
Definition: AtTpc.cxx:264
kAtTpc
@ kAtTpc
Definition: AtDetectorList.h:27
cGREEN
constexpr auto cGREEN
Definition: AtTpc.cxx:37
AtVertexPropagator::GetTrackAngle
Double_t GetTrackAngle(int trackID)
Definition: AtVertexPropagator.cxx:101