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