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