ATTPCROOT  0.3.0-alpha
A ROOT-based framework for analyzing data from active target detectors
AtStack.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 
9 // -------------------------------------------------------------------------
10 // ----- AtStack source file -----
11 // ----- M. Al-Turany June 2014 -----
12 // -------------------------------------------------------------------------
13 
14 #include "AtStack.h"
15 
16 #include "AtMCTrack.h" // for AtMCTrack
17 
18 #include <FairDetector.h> // for FairDetector
19 #include <FairGenericStack.h>
20 #include <FairLink.h> // for FairLink
21 #include <FairLogger.h>
22 #include <FairMCPoint.h> // for FairMCPoint
23 #include <FairRootManager.h> // for FairRootManager
24 
25 #include <Rtypes.h>
26 #include <TClonesArray.h> // for TClonesArray
27 #include <TIterator.h> // for TIterator
28 #include <TLorentzVector.h> // for TLorentzVector
29 #include <TMCProcess.h>
30 #include <TObject.h>
31 #include <TParticle.h> // for TParticle
32 #include <TRefArray.h> // for TRefArray
33 
34 #include <algorithm>
35 #include <iostream> // for operator<<, etc
36 #include <iterator>
37 
38 using std::cout;
39 using std::endl;
40 using std::pair;
41 
42 // ----- Default constructor -------------------------------------------
43 AtStack::AtStack(Int_t size)
44  : FairGenericStack(), fStack(), fParticles(new TClonesArray("TParticle", size)),
45  fTracks(new TClonesArray("AtMCTrack", size)), fStoreMap(), fStoreIter(), fIndexMap(), fIndexIter(), fPointsMap(),
46  fCurrentTrack(-1), fNPrimaries(0), fNParticles(0), fNTracks(0), fIndex(0), fStoreSecondaries(kTRUE), fMinPoints(1),
47  fEnergyCut(0.), fStoreMothers(kTRUE), fLogger(FairLogger::GetLogger())
48 {
49 }
50 
51 // -------------------------------------------------------------------------
52 
53 // ----- Destructor ----------------------------------------------------
55 {
56  if (fParticles) {
57  fParticles->Delete();
58  delete fParticles;
59  }
60  if (fTracks) {
61  fTracks->Delete();
62  delete fTracks;
63  }
64 }
65 // -------------------------------------------------------------------------
66 
67 void AtStack::PushTrack(Int_t toBeDone, Int_t parentId, Int_t pdgCode, Double_t px, Double_t py, Double_t pz,
68  Double_t e, Double_t vx, Double_t vy, Double_t vz, Double_t time, Double_t polx, Double_t poly,
69  Double_t polz, TMCProcess proc, Int_t &ntr, Double_t weight, Int_t is)
70 {
71 
72  PushTrack(toBeDone, parentId, pdgCode, px, py, pz, e, vx, vy, vz, time, polx, poly, polz, proc, ntr, weight, is, -1);
73 }
74 
75 // ----- Virtual public method PushTrack -------------------------------
76 void AtStack::PushTrack(Int_t toBeDone, Int_t parentId, Int_t pdgCode, Double_t px, Double_t py, Double_t pz,
77  Double_t e, Double_t vx, Double_t vy, Double_t vz, Double_t time, Double_t polx, Double_t poly,
78  Double_t polz, TMCProcess proc, Int_t &ntr, Double_t weight, Int_t is, Int_t secondparentID)
79 {
80 
81  // --> Get TParticle array
82  TClonesArray &partArray = *fParticles;
83 
84  // --> Create new TParticle and add it to the TParticle array
85  Int_t trackId = fNParticles;
86  Int_t nPoints = 0;
87  Int_t daughter1Id = -1;
88  Int_t daughter2Id = -1;
89  auto *particle = new (partArray[fNParticles++]) // NOLINT
90  TParticle(pdgCode, trackId, parentId, nPoints, daughter1Id, daughter2Id, px, py, pz, e, vx, vy, vz, time);
91  particle->SetPolarisation(polx, poly, polz);
92  particle->SetWeight(weight);
93  particle->SetUniqueID(proc);
94 
95  // --> Increment counter
96  if (parentId < 0) {
97  fNPrimaries++;
98  }
99 
100  // --> Set argument variable
101  ntr = trackId;
102 
103  // --> Push particle on the stack if toBeDone is set
104  if (toBeDone == 1) {
105  fStack.push(particle);
106  }
107 }
108 // -------------------------------------------------------------------------
109 
110 // ----- Virtual method PopNextTrack -----------------------------------
111 TParticle *AtStack::PopNextTrack(Int_t &iTrack)
112 {
113 
114  // If end of stack: Return empty pointer
115  if (fStack.empty()) {
116  iTrack = -1;
117  return nullptr;
118  }
119 
120  // If not, get next particle from stack
121  TParticle *thisParticle = fStack.top();
122  fStack.pop();
123 
124  if (!thisParticle) {
125  iTrack = 0;
126  return nullptr;
127  }
128 
129  fCurrentTrack = thisParticle->GetStatusCode();
130  iTrack = fCurrentTrack;
131 
132  return thisParticle;
133 }
134 // -------------------------------------------------------------------------
135 
136 // ----- Virtual method PopPrimaryForTracking --------------------------
137 TParticle *AtStack::PopPrimaryForTracking(Int_t iPrim)
138 {
139 
140  // Get the iPrimth particle from the fStack TClonesArray. This
141  // should be a primary (if the index is correct).
142 
143  // Test for index
144  if (iPrim < 0 || iPrim >= fNPrimaries) {
145  LOG(fatal) << "AtStack: Primary index out of range! " << iPrim;
146  }
147 
148  // Return the iPrim-th TParticle from the fParticle array. This should be
149  // a primary.
150  auto *part = dynamic_cast<TParticle *>(fParticles->At(iPrim));
151  if (!(part->GetMother(0) < 0)) {
152  LOG(fatal) << "AtStack:: Not a primary track! " << iPrim;
153  }
154 
155  return part;
156 }
157 // -------------------------------------------------------------------------
158 
159 // ----- Virtual public method GetCurrentTrack -------------------------
160 TParticle *AtStack::GetCurrentTrack() const
161 {
162  TParticle *currentPart = GetParticle(fCurrentTrack);
163  if (!currentPart) {
164  LOG(warning) << "AtStack: Current track not found in stack!";
165  }
166  return currentPart;
167 }
168 // -------------------------------------------------------------------------
169 
170 // ----- Public method AddParticle -------------------------------------
171 void AtStack::AddParticle(TParticle *oldPart)
172 {
173  TClonesArray &array = *fParticles;
174  auto *newPart = new (array[fIndex]) TParticle(*oldPart); // NOLINT
175  newPart->SetWeight(oldPart->GetWeight());
176  newPart->SetUniqueID(oldPart->GetUniqueID());
177  fIndex++;
178 }
179 // -------------------------------------------------------------------------
180 
181 // ----- Public method FillTrackArray ----------------------------------
183 {
184 
185  LOG(debug) << "AtStack: Filling MCTrack array..."; // NOLINT
186 
187  // --> Reset index map and number of output tracks
188  fIndexMap.clear();
189  fNTracks = 0;
190 
191  // --> Check tracks for selection criteria
192  SelectTracks();
193 
194  // --> Loop over fParticles array and copy selected tracks
195  for (Int_t iPart = 0; iPart < fNParticles; iPart++) {
196 
197  fStoreIter = fStoreMap.find(iPart);
198  if (fStoreIter == fStoreMap.end()) {
199  LOG(fatal) << "AtStack: Particle " << iPart << " not found in storage map! ";
200  }
201  Bool_t store = (*fStoreIter).second;
202 
203  if (store) {
204 
205  new ((*fTracks)[fNTracks]) AtMCTrack(GetParticle(iPart)); // NOLINT
206  fIndexMap[iPart] = fNTracks;
207  // --> Set the number of points in the detectors for this track
208  for (Int_t iDet = kAtTpc; iDet < kSTOPHERE; iDet++) {
209  pair<Int_t, Int_t> a(iPart, iDet);
210  // commented because this function did not do anything
211  // it was fully commented out in the source code. (5/23/21)
212  // track->SetNPoints(iDet, fPointsMap[a]);
213  }
214 
215  fNTracks++;
216  } else {
217  fIndexMap[iPart] = -2;
218  }
219  }
220 
221  // --> Map index for primary mothers
222  fIndexMap[-1] = -1;
223 
224  // --> Screen output
225  // Print(1);
226 }
227 // -------------------------------------------------------------------------
228 
229 // ----- Public method UpdateTrackIndex --------------------------------
230 void AtStack::UpdateTrackIndex(TRefArray *detList)
231 {
232 
233  LOG(debug) << "AtStack: Updating track indizes...";
234  Int_t nColl = 0;
235 
236  // First update mother ID in MCTracks
237  for (Int_t i = 0; i < fNTracks; i++) {
238  auto *track = dynamic_cast<AtMCTrack *>(fTracks->At(i));
239  Int_t iMotherOld = track->GetMotherId();
240  fIndexIter = fIndexMap.find(iMotherOld);
241  if (fIndexIter == fIndexMap.end()) {
242  LOG(fatal) << "AtStack: Particle index " << iMotherOld << " not found in dex map! ";
243  }
244  track->SetMotherId((*fIndexIter).second);
245  }
246 
247  if (fDetList == nullptr) {
248  // Now iterate through all active detectors
249  fDetIter = detList->MakeIterator();
250  fDetIter->Reset();
251  } else {
252  fDetIter->Reset();
253  }
254 
255  FairDetector *det = nullptr;
256  while ((det = dynamic_cast<FairDetector *>(fDetIter->Next()))) {
257 
258  // --> Get hit collections from detector
259  Int_t iColl = 0;
260  TClonesArray *hitArray = nullptr;
261  while ((hitArray = det->GetCollection(iColl++))) {
262  nColl++;
263  Int_t nPoints = hitArray->GetEntriesFast();
264 
265  // --> Update track index for all MCPoints in the collection
266  for (Int_t iPoint = 0; iPoint < nPoints; iPoint++) {
267  auto *point = dynamic_cast<FairMCPoint *>(hitArray->At(iPoint));
268  Int_t iTrack = point->GetTrackID();
269 
270  fIndexIter = fIndexMap.find(iTrack);
271  if (fIndexIter == fIndexMap.end()) {
272  LOG(fatal) << "AtStack: Particle index " << iTrack << " not found in index map! ";
273  Fatal("AtStack::UpdateTrackIndex", "Particle index not found in map");
274  }
275  point->SetTrackID((*fIndexIter).second);
276  point->SetLink(FairLink("MCTrack", (*fIndexIter).second));
277  }
278 
279  } // Collections of this detector
280  } // List of active detectors
281  LOG(debug) << "...stack and " << nColl << " collections updated.";
282 }
283 // -------------------------------------------------------------------------
284 
285 // ----- Public method Reset -------------------------------------------
287 {
288  fIndex = 0;
289  fCurrentTrack = -1;
290  fNPrimaries = fNParticles = fNTracks = 0;
291  while (!fStack.empty()) {
292  fStack.pop();
293  }
294  fParticles->Clear();
295  fTracks->Clear();
296  fPointsMap.clear();
297 }
298 // -------------------------------------------------------------------------
299 
300 // ----- Public method Register ----------------------------------------
302 {
303  FairRootManager::Instance()->Register("MCTrack", "Stack", fTracks, kTRUE);
304 }
305 // -------------------------------------------------------------------------
306 
307 // ----- Public method Print --------------------------------------------
308 void AtStack::Print(Int_t iVerbose) const
309 {
310  cout << "-I- AtStack: Number of primaries = " << fNPrimaries << endl;
311  cout << " Total number of particles = " << fNParticles << endl;
312  cout << " Number of tracks in output = " << fNTracks << endl;
313  if (iVerbose) {
314  for (Int_t iTrack = 0; iTrack < fNTracks; iTrack++) {
315  (dynamic_cast<AtMCTrack *>(fTracks->At(iTrack)))->Print(iTrack);
316  }
317  }
318 }
319 // -------------------------------------------------------------------------
320 
321 // ----- Public method AddPoint (for current track) --------------------
323 {
324  Int_t iDet = detId;
325  // cout << "Add point for Detektor" << iDet << endl;
326  pair<Int_t, Int_t> a(fCurrentTrack, iDet);
327  if (fPointsMap.find(a) == fPointsMap.end()) {
328  fPointsMap[a] = 1;
329  } else {
330  fPointsMap[a]++;
331  }
332 }
333 // -------------------------------------------------------------------------
334 
335 // ----- Public method AddPoint (for arbitrary track) -------------------
336 void AtStack::AddPoint(DetectorId detId, Int_t iTrack)
337 {
338  if (iTrack < 0) {
339  return;
340  }
341  Int_t iDet = detId;
342  pair<Int_t, Int_t> a(iTrack, iDet);
343  if (fPointsMap.find(a) == fPointsMap.end()) {
344  fPointsMap[a] = 1;
345  } else {
346  fPointsMap[a]++;
347  }
348 }
349 // -------------------------------------------------------------------------
350 
351 // ----- Virtual method GetCurrentParentTrackNumber --------------------
353 {
354  TParticle *currentPart = GetCurrentTrack();
355  if (currentPart) {
356  return currentPart->GetFirstMother();
357  } else {
358  return -1;
359  }
360 }
361 // -------------------------------------------------------------------------
362 
363 // ----- Public method GetParticle -------------------------------------
364 TParticle *AtStack::GetParticle(Int_t trackID) const
365 {
366  if (trackID < 0 || trackID >= fNParticles) {
367  LOG(fatal) << "AtStack: Particle index " << trackID << " out of range.";
368  Fatal("AtStack::GetParticle", "Index out of range");
369  }
370  return dynamic_cast<TParticle *>(fParticles->At(trackID));
371 }
372 // -------------------------------------------------------------------------
373 
374 // ----- Private method SelectTracks -----------------------------------
375 void AtStack::SelectTracks()
376 {
377 
378  // --> Clear storage map
379  fStoreMap.clear();
380 
381  // --> Check particles in the fParticle array
382  for (Int_t i = 0; i < fNParticles; i++) {
383 
384  TParticle *thisPart = GetParticle(i);
385  Bool_t store = kTRUE;
386 
387  // --> Get track parameters
388  Int_t iMother = thisPart->GetMother(0);
389  TLorentzVector p;
390  thisPart->Momentum(p);
391  Double_t energy = p.E();
392  Double_t mass = p.M();
393  // Double_t mass = thisPart->GetMass();
394  Double_t eKin = energy - mass;
395 
396  // --> Calculate number of points
397  Int_t nPoints = 0;
398  for (Int_t iDet = kAtTpc; iDet < kSTOPHERE; iDet++) {
399  pair<Int_t, Int_t> a(i, iDet);
400  if (fPointsMap.find(a) != fPointsMap.end()) {
401  nPoints += fPointsMap[a];
402  }
403  }
404 
405  // --> Check for cuts (store primaries in any case)
406  if (iMother < 0) {
407  store = kTRUE;
408  } else {
409  if (!fStoreSecondaries) {
410  store = kFALSE;
411  }
412  if (nPoints < fMinPoints) {
413  store = kFALSE;
414  }
415  if (eKin < fEnergyCut) {
416  store = kFALSE;
417  }
418  }
419 
420  // --> Set storage flag
421  fStoreMap[i] = store;
422  }
423 
424  // --> If flag is set, flag recursively mothers of selected tracks
425  if (fStoreMothers) {
426  for (Int_t i = 0; i < fNParticles; i++) {
427  if (fStoreMap[i]) {
428  Int_t iMother = GetParticle(i)->GetMother(0);
429  while (iMother >= 0) {
430  fStoreMap[iMother] = kTRUE;
431  iMother = GetParticle(iMother)->GetMother(0);
432  }
433  }
434  }
435  }
436 }
437 // -------------------------------------------------------------------------
438 
AtStack::Print
virtual void Print(Int_t iVerbose=0) const
Definition: AtStack.cxx:308
AtStack::GetParticle
TParticle * GetParticle(Int_t trackId) const
Definition: AtStack.cxx:364
AtStack::AddParticle
virtual void AddParticle(TParticle *part)
Definition: AtStack.cxx:171
AtStack::UpdateTrackIndex
virtual void UpdateTrackIndex(TRefArray *detArray=0)
Definition: AtStack.cxx:230
ClassImp
ClassImp(AtFindVertex)
AtStack::PopPrimaryForTracking
virtual TParticle * PopPrimaryForTracking(Int_t iPrim)
Definition: AtStack.cxx:137
AtStack::Register
virtual void Register()
Definition: AtStack.cxx:301
AtStack::~AtStack
virtual ~AtStack()
Definition: AtStack.cxx:54
DetectorId
DetectorId
Definition: AtDetectorList.h:20
AtStack::PopNextTrack
virtual TParticle * PopNextTrack(Int_t &iTrack)
Definition: AtStack.cxx:111
AtStack::Reset
virtual void Reset()
Definition: AtStack.cxx:286
AtStack::AddPoint
void AddPoint(DetectorId iDet)
Definition: AtStack.cxx:322
AtStack::FillTrackArray
virtual void FillTrackArray()
Definition: AtStack.cxx:182
AtStack::GetCurrentTrack
virtual TParticle * GetCurrentTrack() const
Definition: AtStack.cxx:160
AtStack.h
AtStack::GetCurrentParentTrackNumber
virtual Int_t GetCurrentParentTrackNumber() const
Definition: AtStack.cxx:352
kSTOPHERE
@ kSTOPHERE
Definition: AtDetectorList.h:31
AtStack::PushTrack
virtual void PushTrack(Int_t toBeDone, Int_t parentID, Int_t pdgCode, Double_t px, Double_t py, Double_t pz, Double_t e, Double_t vx, Double_t vy, Double_t vz, Double_t time, Double_t polx, Double_t poly, Double_t polz, TMCProcess proc, Int_t &ntr, Double_t weight, Int_t is)
Definition: AtStack.cxx:67
AtMCTrack
Definition: AtMCTrack.h:34
AtMCTrack::GetMotherId
Int_t GetMotherId() const
Definition: AtMCTrack.h:58
AtStack
Definition: AtStack.h:54
AtMCTrack.h
kAtTpc
@ kAtTpc
Definition: AtDetectorList.h:27
AtStack::AtStack
AtStack(Int_t size=100)
Definition: AtStack.cxx:43