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