FairRoot
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FairStack.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 (LGPL) version 3, *
6  * copied verbatim in the file "LICENSE" *
7  ********************************************************************************/
8 // -------------------------------------------------------------------------
9 // ----- FairStack source file -----
10 // ----- Created 10/08/04 by D. Bertini / V. Friese -----
11 // -------------------------------------------------------------------------
12 #include "FairStack.h"
13 
14 #include "FairDetector.h" // for FairDetector
15 #include "FairLink.h" // for FairLink
16 #include "FairLogger.h" // for FairLogger, MESSAGE_ORIGIN
17 #include "FairMCPoint.h" // for FairMCPoint
18 #include "FairMCTrack.h" // for FairMCTrack
19 #include "FairRootManager.h" // for FairRootManager
20 
21 #include <TClonesArray.h> // for TClonesArray
22 #include <TIterator.h> // for TIterator
23 #include <TLorentzVector.h> // for TLorentzVector
24 #include <TParticle.h> // for TParticle
25 #include <TRefArray.h> // for TRefArray
26 #include <TVirtualMC.h> // for gMC
27 
28 using std::pair;
29 
32  , fStack()
33  , fParticles(new TClonesArray("TParticle", size))
34  , fTracks(new TClonesArray("FairMCTrack", size))
35  , fStoreMap()
36  , fStoreIter()
37  , fIndexMap()
38  , fIndexIter()
39  , fPointsMap()
40  , fCurrentTrack(-1)
41  , fNPrimaries(0)
42  , fNParticles(0)
43  , fNTracks(0)
44  , fIndex(0)
45  , fStoreSecondaries(kTRUE)
46  , fMinPoints(1)
47  , fEnergyCut(0.)
48  , fStoreMothers(kTRUE)
49 {}
50 
52 {
53  if (fParticles) {
54  fParticles->Delete();
55  delete fParticles;
56  }
57  if (fTracks) {
58  fTracks->Delete();
59  delete fTracks;
60  }
61 }
62 
63 void FairStack::PushTrack(Int_t toBeDone,
64  Int_t parentId,
65  Int_t pdgCode,
66  Double_t px,
67  Double_t py,
68  Double_t pz,
69  Double_t e,
70  Double_t vx,
71  Double_t vy,
72  Double_t vz,
73  Double_t time,
74  Double_t polx,
75  Double_t poly,
76  Double_t polz,
77  TMCProcess proc,
78  Int_t& ntr,
79  Double_t weight,
80  Int_t is)
81 {
82  PushTrack(
83  toBeDone, parentId, pdgCode, px, py, pz, e, vx, vy, vz, time, polx, poly, polz, proc, ntr, weight, is, -1);
84 }
85 
86 void FairStack::PushTrack(Int_t toBeDone,
87  Int_t parentId,
88  Int_t pdgCode,
89  Double_t px,
90  Double_t py,
91  Double_t pz,
92  Double_t e,
93  Double_t vx,
94  Double_t vy,
95  Double_t vz,
96  Double_t time,
97  Double_t polx,
98  Double_t poly,
99  Double_t polz,
100  TMCProcess proc,
101  Int_t& ntr,
102  Double_t weight,
103  Int_t /*is*/,
104  Int_t /*secondparentID*/)
105 {
106  // LOG(info) << "FairStack::PushTrack(" << toBeDone << ", " << parentId << ", " << pdgCode << ": "
107  // << vx << ", " << vy << ", " << vz << " / "
108  // << px << ", " << py << ", " << pz <<")";
109  // --> Get TParticle array
110  TClonesArray& partArray = *fParticles;
111 
112  // --> Create new TParticle and add it to the TParticle array
113  Int_t trackId = fNParticles;
114  Int_t nPoints = 0;
115  Int_t daughter1Id = -1;
116  Int_t daughter2Id = -1;
117  TParticle* particle = new (partArray[fNParticles++])
118  TParticle(pdgCode, trackId, parentId, nPoints, daughter1Id, daughter2Id, px, py, pz, e, vx, vy, vz, time);
119  particle->SetPolarisation(polx, poly, polz);
120  particle->SetWeight(weight);
121  particle->SetUniqueID(proc);
122 
123  // --> Increment counter
124  if (parentId < 0) {
125  fNPrimaries++;
126  }
127 
128  // --> Set argument variable
129  ntr = trackId;
130 
131  // --> Push particle on the stack if toBeDone is set
132  if (toBeDone == 1) {
133  fStack.push(particle);
134  }
135 }
136 
137 TParticle* FairStack::PopNextTrack(Int_t& iTrack)
138 {
139  // If end of stack: Return empty pointer
140  if (fStack.empty()) {
141  iTrack = -1;
142  return nullptr;
143  }
144 
145  // If not, get next particle from stack
146  TParticle* thisParticle = fStack.top();
147  fStack.pop();
148 
149  if (!thisParticle) {
150  iTrack = 0;
151  return nullptr;
152  }
153 
154  fCurrentTrack = thisParticle->GetStatusCode();
155  iTrack = fCurrentTrack;
156 
157  return thisParticle;
158 }
159 
160 TParticle* FairStack::PopPrimaryForTracking(Int_t iPrim)
161 {
162  // Get the iPrimth particle from the fStack TClonesArray. This
163  // should be a primary (if the index is correct).
164 
165  // Test for index
166  if (iPrim < 0 || iPrim >= fNPrimaries) {
167  LOG(fatal) << "Primary index out of range!" << iPrim;
168  }
169 
170  // Return the iPrim-th TParticle from the fParticle array. This should be
171  // a primary.
172  TParticle* part = static_cast<TParticle*>(fParticles->At(iPrim));
173  if (!(part->GetMother(0) < 0)) {
174  LOG(fatal) << "Not a primary track!" << iPrim;
175  }
176 
177  return part;
178 }
179 
180 TParticle* FairStack::GetCurrentTrack() const
181 {
182  TParticle* currentPart = GetParticle(fCurrentTrack);
183  if (!currentPart) {
184  LOG(warn) << "Current track not found in stack!";
185  }
186  return currentPart;
187 }
188 
189 void FairStack::AddParticle(TParticle* oldPart)
190 {
191  TClonesArray& array = *fParticles;
192  TParticle* newPart = new (array[fIndex]) TParticle(*oldPart);
193  newPart->SetWeight(oldPart->GetWeight());
194  newPart->SetUniqueID(oldPart->GetUniqueID());
195  fIndex++;
196 }
197 
199 {
200 
201  LOG(debug) << "Filling MCTrack array...";
202 
203  // --> Reset index map and number of output tracks
204  fIndexMap.clear();
205  fNTracks = 0;
206 
207  // --> Check tracks for selection criteria
208  SelectTracks();
209 
210  // --> Loop over fParticles array and copy selected tracks
211  for (Int_t iPart = 0; iPart < fNParticles; iPart++) {
212  Bool_t store = kFALSE;
213 
214  fStoreIter = fStoreMap.find(iPart);
215  if (fStoreIter == fStoreMap.end()) {
216  LOG(fatal) << "Particle " << iPart << " not found in storage map! ";
217  } else {
218  store = (*fStoreIter).second;
219  }
220 
221  if (store) {
222  FairMCTrack* track = new ((*fTracks)[fNTracks]) FairMCTrack(GetParticle(iPart));
223  fIndexMap[iPart] = fNTracks;
224  // --> Set the number of points in the detectors for this track
225  for (Int_t iDet = kREF; iDet < kSTOPHERE; iDet++) {
226  pair<Int_t, Int_t> a(iPart, iDet);
227  track->SetNPoints(iDet, fPointsMap[a]);
228  }
229  fNTracks++;
230  } else {
231  fIndexMap[iPart] = -2;
232  }
233  }
234 
235  // --> Map index for primary mothers
236  fIndexMap[-1] = -1;
237 
238  // --> Screen output
239  // Print(1);
240 }
241 
243 {
244  std::map<Int_t, Int_t>::const_iterator tempIter =
245  fFSTrackMap.find(fCurrentTrack); // check if the track was created by FastSimulation
246  if (tempIter != fFSTrackMap.end()) {
247  return tempIter->second;
248  }
249  return fCurrentTrack;
250 }
251 
252 void FairStack::UpdateTrackIndex(TRefArray* detList)
253 {
254  Int_t nColl = 0;
255 
256  // First update mother ID in MCTracks
257  for (Int_t i = 0; i < fNTracks; i++) {
258  FairMCTrack* track = static_cast<FairMCTrack*>(fTracks->At(i));
259  Int_t iMotherOld = track->GetMotherId();
260  fIndexIter = fIndexMap.find(iMotherOld);
261  if (fIndexIter == fIndexMap.end()) {
262  LOG(fatal) << "Particle index " << iMotherOld << " not found in index map!";
263  } else {
264  track->SetMotherId((*fIndexIter).second);
265  }
266  }
267 
268  if (fDetList == 0) {
269  // Now iterate through all active detectors
270  fDetIter = detList->MakeIterator();
271  fDetIter->Reset();
272  } else {
273  fDetIter->Reset();
274  }
275 
276  FairDetector* det = nullptr;
277  while ((det = static_cast<FairDetector*>(fDetIter->Next()))) {
278 
279  // --> Get hit collections from detector
280  Int_t iColl = 0;
281  TClonesArray* hitArray;
282  while ((hitArray = det->GetCollection(iColl++))) {
283  nColl++;
284  Int_t nPoints = hitArray->GetEntriesFast();
285 
286  // --> Update track index for all MCPoints in the collection
287  for (Int_t iPoint = 0; iPoint < nPoints; iPoint++) {
288  FairMCPoint* point = static_cast<FairMCPoint*>(hitArray->At(iPoint));
289  Int_t iTrack = point->GetTrackID();
290 
291  // LOG(debug) << "point at " << point->GetX() << "," << point->GetY() << "," << point->GetZ() <<
292  // " has trackID = " << point->GetTrackID();
293  FastSimUpdateTrackIndex<FairMCPoint>(point, iTrack);
294 
295  fIndexIter = fIndexMap.find(iTrack);
296  if (fIndexIter == fIndexMap.end()) {
297  LOG(fatal) << "Particle index " << iTrack << " not found in index map!";
298  } else {
299  point->SetTrackID((*fIndexIter).second);
300  point->SetLink(FairLink("MCTrack", (*fIndexIter).second));
301  }
302  }
303 
304  } // Collections of this detector
305  } // List of active detectors
306  LOG(debug) << "...stack and " << nColl << " collections updated.";
307 }
308 
310 {
311  fIndex = 0;
312  fCurrentTrack = -1;
313  fNPrimaries = fNParticles = fNTracks = 0;
314  while (!fStack.empty()) {
315  fStack.pop();
316  }
317  fParticles->Clear();
318  fTracks->Clear();
319  fFSTrackMap.clear();
320  fPointsMap.clear();
321 }
322 
324 {
325  if (gMC) {
326  FairRootManager::Instance()->Register("MCTrack", "Stack", fTracks, kTRUE);
327  } else {
328  FairRootManager::Instance()->RegisterAny("MCTrack", fTracks, kTRUE);
329  }
330 }
331 
332 void FairStack::Print(Option_t*) const
333 {
334  LOG(info) << "FairStack: Number of primaries = " << fNPrimaries;
335  LOG(info) << " Total number of particles = " << fNParticles;
336  LOG(info) << " Number of tracks in output = " << fNTracks;
337  if (gLogger->IsLogNeeded(fair::Severity::DEBUG1)) {
338  for (Int_t iTrack = 0; iTrack < fNTracks; iTrack++) {
339  (static_cast<FairMCTrack*>(fTracks->At(iTrack))->Print(iTrack));
340  }
341  }
342 }
343 
345 {
346  Int_t iDet = detId;
347  Int_t iTr = fCurrentTrack;
348  fFSTrackIter = fFSTrackMap.find(iTr); // check if this track is not already created by FastSimulation
349  if (fFSTrackIter != fFSTrackMap.end()) { // indeed the track has been created by the FastSimulation mechanism
350  iTr = fFSTrackIter->second; // use the ID of the original track
351  }
352 
353  pair<Int_t, Int_t> a(iTr, iDet);
354  if (fPointsMap.find(a) == fPointsMap.end()) {
355  fPointsMap[a] = 1;
356  } else {
357  fPointsMap[a]++;
358  }
359 }
360 
361 void FairStack::AddPoint(DetectorId detId, Int_t iTrack)
362 {
363  if (iTrack < 0) {
364  return;
365  }
366  Int_t iDet = detId;
367  Int_t iTr = iTrack;
368  fFSTrackIter = fFSTrackMap.find(iTr); // check if this track is not already created by FastSimulation
369  if (fFSTrackIter != fFSTrackMap.end()) { // indeed the track has been created by the FastSimulation mechanism
370  iTr = fFSTrackIter->second; // use the ID of the original track
371  }
372  pair<Int_t, Int_t> a(iTr, iDet);
373  if (fPointsMap.find(a) == fPointsMap.end()) {
374  fPointsMap[a] = 1;
375  } else {
376  fPointsMap[a]++;
377  }
378 }
379 
381 {
382  TParticle* currentPart = GetCurrentTrack();
383  if (currentPart) {
384  return currentPart->GetFirstMother();
385  } else {
386  return -1;
387  }
388 }
389 
390 TParticle* FairStack::GetParticle(Int_t trackID) const
391 {
392  if (trackID < 0 || trackID >= fNParticles) {
393  LOG(fatal) << "Particle index " << trackID << " out of range.";
394  }
395  return static_cast<TParticle*>(fParticles->At(trackID));
396 }
397 
398 void FairStack::SelectTracks()
399 {
400 
401  // --> Clear storage map
402  fStoreMap.clear();
403 
404  // loop over tracks created by FastSim to order the tracks
405  for (fFSTrackIter = fFSTrackMap.begin(); fFSTrackIter != fFSTrackMap.end(); ++fFSTrackIter) {
406  for (Int_t i = 0; i < fNParticles; i++) {
407  TParticle* thisPart = GetParticle(i);
408  if (thisPart->GetMother(0) == fFSTrackIter->first)
409  thisPart->SetMother(0, fFSTrackIter->second);
410  }
411  }
412 
413  // --> Check particles in the fParticle array
414  for (Int_t i = 0; i < fNParticles; i++) {
415 
416  TParticle* thisPart = GetParticle(i);
417  Bool_t store = kTRUE;
418 
419  // --> Get track parameters
420  Int_t iMother = thisPart->GetMother(0);
421  TLorentzVector p;
422  thisPart->Momentum(p);
423  Double_t energy = p.E();
424  Double_t mass = p.M();
425  // Double_t mass = thisPart->GetMass();
426  Double_t eKin = energy - mass;
427 
428  // --> Calculate number of points
429  Int_t nPoints = 0;
430  for (Int_t iDet = kREF; iDet < kSTOPHERE; iDet++) {
431  pair<Int_t, Int_t> a(i, iDet);
432  if (fPointsMap.find(a) != fPointsMap.end()) {
433  nPoints += fPointsMap[a];
434  }
435  }
436 
437  // check if the track was created by the FastSim mechanism. Do not store such tracks
438  Bool_t fastSimTrack = kFALSE;
439  fFSTrackIter = fFSTrackMap.find(i);
440  if (fFSTrackIter != fFSTrackMap.end())
441  fastSimTrack = kTRUE;
442 
443  // --> Check for cuts (store primaries in any case)
444  if (iMother < 0) {
445  store = kTRUE;
446  } else {
447  if (!fStoreSecondaries) {
448  store = kFALSE;
449  }
450  if (nPoints < fMinPoints) {
451  store = kFALSE;
452  }
453  if (eKin < fEnergyCut) {
454  store = kFALSE;
455  }
456  if (fastSimTrack) {
457  store = kFALSE;
458  }
459  }
460 
461  // --> Set storage flag
462  fStoreMap[i] = store;
463  }
464 
465  // --> If flag is set, flag recursively mothers of selected tracks
466  if (fStoreMothers) {
467  for (Int_t i = 0; i < fNParticles; i++) {
468  if (fStoreMap[i]) {
469  Int_t iMother = GetParticle(i)->GetMother(0);
470  while (iMother >= 0) {
471  fStoreMap[iMother] = kTRUE;
472  iMother = GetParticle(iMother)->GetMother(0);
473  }
474  }
475  }
476  }
477 }
478 
DetectorId
TIterator * fDetIter
void SetNPoints(Int_t iDet, Int_t np)
std::map< Int_t, Int_t >::iterator fFSTrackIter
Int_t GetMotherId() const
Definition: FairMCTrack.h:74
virtual void Print(Option_t *) const
Definition: FairStack.cxx:332
virtual TParticle * PopNextTrack(Int_t &iTrack)
Definition: FairStack.cxx:137
void SetMotherId(Int_t id)
Definition: FairMCTrack.h:95
static FairRootManager * Instance()
virtual Int_t GetCurrentTrackNumber() const
Definition: FairStack.cxx:242
ClassImp(FairEventBuilder)
virtual TParticle * GetCurrentTrack() const
Definition: FairStack.cxx:180
virtual Int_t GetCurrentParentTrackNumber() const
Definition: FairStack.cxx:380
Int_t GetTrackID() const
event identifier
Definition: FairMCPoint.h:58
virtual void AddParticle(TParticle *part)
Definition: FairStack.cxx:189
virtual void Reset()
Definition: FairStack.cxx:309
virtual TParticle * PopPrimaryForTracking(Int_t iPrim)
Definition: FairStack.cxx:160
#define gLogger
Definition: FairLogger.h:156
virtual void UpdateTrackIndex(TRefArray *detArray=0)
Definition: FairStack.cxx:252
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: FairStack.cxx:63
std::map< Int_t, Int_t > fFSTrackMap
virtual void Register()
Definition: FairStack.cxx:323
void Register(const char *name, const char *Foldername, TNamed *obj, Bool_t toFile)
TRefArray * fDetList
virtual TClonesArray * GetCollection(Int_t iColl) const =0
virtual void FillTrackArray()
Definition: FairStack.cxx:198
FairStack(Int_t size=100)
Definition: FairStack.cxx:30
virtual ~FairStack()
Definition: FairStack.cxx:51
void AddPoint(DetectorId iDet)
Definition: FairStack.cxx:344
void RegisterAny(const char *name, T *&obj, Bool_t toFile)
TParticle * GetParticle(Int_t trackId) const
Definition: FairStack.cxx:390