BmnRoot
Loading...
Searching...
No Matches
CbmStack.cxx
Go to the documentation of this file.
1// -------------------------------------------------------------------------
2// ----- CbmStack source file -----
3// ----- Created 10/08/04 by D. Bertini / V. Friese -----
4// -------------------------------------------------------------------------
5#include "CbmStack.h"
6
7#include "CbmMCTrack.h" // for CbmMCTrack
8#include "FairDetector.h" // for FairDetector
9#include "FairLink.h" // for FairLink
10#include "FairLogger.h" // for FairLogger, MESSAGE_ORIGIN
11#include "FairMCPoint.h" // for FairMCPoint
12#include "FairRootManager.h" // for FairRootManager
13
14#include <TIterator.h> // for TIterator
15#include <TLorentzVector.h> // for TLorentzVector
16#include <TParticlePDG.h> //AZ-031023
17#include <TVirtualMC.h> // for gMC
18
19using namespace std;
20
21// ----- Default constructor -------------------------------------------
23 : FairGenericStack()
24 , fStack()
25 , fParticles(new TClonesArray("TParticle", size))
26 , fTracks(new TClonesArray("CbmMCTrack", size))
27 , fStoreMap()
28 , fStoreIter()
29 , fIndexMap()
30 , fIndexIter()
31 , fPointsMap()
32 , fCurrentTrack(-1)
33 , fNPrimaries(0)
34 , fNParticles(0)
35 , fNTracks(0)
36 , fIndex(0)
37 , fStoreSecondaries(kTRUE)
38 , fMinPoints(1)
39 , fEnergyCut(0.)
40 , fStartZCut(1000000.)
41 , fStoreMothers(kTRUE)
42{}
43
44// ----- Destructor ----------------------------------------------------
46{
47 if (fParticles) {
48 fParticles->Delete();
49 delete fParticles;
50 }
51 if (fTracks) {
52 fTracks->Delete();
53 delete fTracks;
54 }
55}
56
57void CbmStack::PushTrack(Int_t toBeDone,
58 Int_t parentId,
59 Int_t pdgCode,
60 Double_t px,
61 Double_t py,
62 Double_t pz,
63 Double_t e,
64 Double_t vx,
65 Double_t vy,
66 Double_t vz,
67 Double_t time,
68 Double_t polx,
69 Double_t poly,
70 Double_t polz,
71 TMCProcess proc,
72 Int_t& ntr,
73 Double_t weight,
74 Int_t is)
75{
76 PushTrack(toBeDone, parentId, pdgCode, px, py, pz, e, vx, vy, vz, time, polx, poly, polz, proc, ntr, weight, is,
77 -1);
78}
79
80// ----- Virtual public method PushTrack -------------------------------
81void CbmStack::PushTrack(Int_t toBeDone,
82 Int_t parentId,
83 Int_t pdgCode,
84 Double_t px,
85 Double_t py,
86 Double_t pz,
87 Double_t e,
88 Double_t vx,
89 Double_t vy,
90 Double_t vz,
91 Double_t time,
92 Double_t polx,
93 Double_t poly,
94 Double_t polz,
95 TMCProcess proc,
96 Int_t& ntr,
97 Double_t weight,
98 Int_t /*is*/,
99 Int_t /*secondparentID*/)
100{
101 // LOG(info) << "CbmStack::PushTrack(" << toBeDone << ", " << parentId << ", " << pdgCode << ": "
102 // << vx << ", " << vy << ", " << vz << " / "
103 // << px << ", " << py << ", " << pz <<")";
104 // --> Get TParticle array
105 TClonesArray& partArray = *fParticles;
106
107 // --> Create new TParticle and add it to the TParticle array
108 Int_t trackId = fNParticles;
109 Int_t nPoints = 0;
110 Int_t daughter1Id = -1;
111 Int_t daughter2Id = -1;
112 TParticle* particle = new (partArray[fNParticles++])
113 TParticle(pdgCode, trackId, parentId, nPoints, daughter1Id, daughter2Id, px, py, pz, e, vx, vy, vz, time);
114 particle->SetPolarisation(polx, poly, polz);
115 particle->SetWeight(weight);
116 particle->SetUniqueID(proc);
117
118 // --> Increment counter
119 if (parentId < 0) {
120 fNPrimaries++;
121 }
122
123 // --> Set argument variable
124 ntr = trackId;
125
126 // --> Push particle on the stack if toBeDone is set
127 if (toBeDone == 1) {
128 fStack.push(particle);
129 }
130}
131
132// ----- Virtual method PopNextTrack -----------------------------------
133TParticle* CbmStack::PopNextTrack(Int_t& iTrack)
134{
135 // If end of stack: Return empty pointer
136 if (fStack.empty()) {
137 iTrack = -1;
138 return nullptr;
139 }
140
141 // If not, get next particle from stack
142 TParticle* thisParticle = fStack.top();
143 fStack.pop();
144
145 if (!thisParticle) {
146 iTrack = 0;
147 return nullptr;
148 }
149
150 fCurrentTrack = thisParticle->GetStatusCode();
151 iTrack = fCurrentTrack;
152
153 return thisParticle;
154}
155
156// ----- Virtual method PopPrimaryForTracking --------------------------
157TParticle* CbmStack::PopPrimaryForTracking(Int_t iPrim)
158{
159 // Get the iPrimth particle from the fStack TClonesArray. This
160 // should be a primary (if the index is correct).
161
162 // Test for index
163 if (iPrim < 0 || iPrim >= fNPrimaries) {
164 LOG(fatal) << "Primary index out of range!" << iPrim;
165 }
166
167 // Return the iPrim-th TParticle from the fParticle array. This should be
168 // a primary.
169 TParticle* part = static_cast<TParticle*>(fParticles->At(iPrim));
170 if (!(part->GetMother(0) < 0)) {
171 LOG(fatal) << "Not a primary track!" << iPrim;
172 }
173
174 return part;
175}
176
177// ----- Virtual public method GetCurrentTrack -------------------------
179{
180 TParticle* currentPart = GetParticle(fCurrentTrack);
181 if (!currentPart) {
182 LOG(warn) << "Current track not found in stack!";
183 }
184 return currentPart;
185}
186
187// ----- Public method AddParticle -------------------------------------
188void CbmStack::AddParticle(TParticle* oldPart)
189{
190 TClonesArray& array = *fParticles;
191 TParticle* newPart = new (array[fIndex]) TParticle(*oldPart);
192 newPart->SetWeight(oldPart->GetWeight());
193 newPart->SetUniqueID(oldPart->GetUniqueID());
194 fIndex++;
195}
196
197// ----- Public method FillTrackArray ----------------------------------
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 CbmMCTrack* track = new ((*fTracks)[fNTracks]) CbmMCTrack(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 < kNOFDETS; 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
242// ----- Public method UpdateTrackIndex --------------------------------
243void CbmStack::UpdateTrackIndex(TRefArray* detList)
244{
245 LOG(info) << "Updating track indices...";
246 Int_t nColl = 0;
247
248 // First update mother ID in MCTracks
249 for (Int_t i = 0; i < fNTracks; i++) {
250 CbmMCTrack* track = static_cast<CbmMCTrack*>(fTracks->At(i));
251 Int_t iMotherOld = track->GetMotherId();
252 if (iMotherOld < 0)
253 continue; // AZ-270324
254 fIndexIter = fIndexMap.find(iMotherOld);
255 if (fIndexIter == fIndexMap.end()) {
256 LOG(fatal) << "Particle index " << iMotherOld << " not found in index map!";
257 } else {
258 track->SetMotherId((*fIndexIter).second);
259 }
260 }
261
262 if (fDetList == 0) {
263 // Now iterate through all active detectors
264 fDetIter = detList->MakeIterator();
265 fDetIter->Reset();
266 } else {
267 fDetIter->Reset();
268 }
269
270 FairDetector* det = nullptr;
271 while ((det = static_cast<FairDetector*>(fDetIter->Next()))) {
272 // --> Get hit collections from detector
273 Int_t iColl = 0;
274 TClonesArray* hitArray;
275 while ((hitArray = det->GetCollection(iColl++))) {
276 nColl++;
277 Int_t nPoints = hitArray->GetEntriesFast();
278
279 // --> Update track index for all MCPoints in the collection
280 for (Int_t iPoint = 0; iPoint < nPoints; iPoint++) {
281 FairMCPoint* point = static_cast<FairMCPoint*>(hitArray->At(iPoint));
282 Int_t iTrack = point->GetTrackID();
283
284 // LOG(debug) << "point at " << point->GetX() << "," << point->GetY() << "," << point->GetZ() <<
285 // " has trackID = " << point->GetTrackID();
286 /*if (TString(det->GetName()).Contains("FHCAL"))
287 cout << " 777777 " << point->GetX() << " " << point->GetY() << " " << point->GetZ() << " " <<
288 point->GetTrackID() <<endl; //AZ-270324*/
289
290 fIndexIter = fIndexMap.find(iTrack);
291 if (fIndexIter == fIndexMap.end()) {
292 LOG(fatal) << "Particle index " << iTrack << " not found in index map!";
293 } else {
294 /*AZ-280324 point->SetTrackID((*fIndexIter).second);
295 point->SetLink(FairLink("MCTrack", (*fIndexIter).second));*/
296 // AZ-280324
297 int trid = fIndexIter->second;
298 if (trid == -2) {
299 // MCTrack was not stored (in FHCAL) - take nearest ancestor
300 trid = GetParticle(iTrack)->GetFirstMother();
301 }
302 point->SetTrackID(trid);
303 point->AddLink(FairLink("MCTrack", trid));
304 // AZ
305 }
306 }
307
308 } // Collections of this detector
309 } // List of active detectors
310 LOG(info) << "...stack and " << nColl << " collections updated.";
311}
312
313// ----- Public method Reset -------------------------------------------
315{
316 fIndex = 0;
317 fCurrentTrack = -1;
318 fNPrimaries = fNParticles = fNTracks = 0;
319 while (!fStack.empty()) {
320 fStack.pop();
321 }
322 fParticles->Delete();
323 fTracks->Delete();
324 fPointsMap.clear();
325}
326
327// ----- Public method Register ----------------------------------------
329{
330 if (gMC) {
331 FairRootManager::Instance()->Register("MCTrack", "Stack", fTracks, kTRUE);
332 } else {
333 FairRootManager::Instance()->RegisterAny("MCTrack", fTracks, kTRUE);
334 }
335}
336
337// ----- Public method Print --------------------------------------------
338void CbmStack::Print(Option_t*) const
339{
340 LOG(info) << "CbmStack: Number of primaries = " << fNPrimaries;
341 LOG(info) << " Total number of particles = " << fNParticles;
342 LOG(info) << " Number of tracks in output = " << fNTracks;
343 if (gLogger->IsLogNeeded(fair::Severity::debug1)) {
344 for (Int_t iTrack = 0; iTrack < fNTracks; iTrack++) {
345 (static_cast<CbmMCTrack*>(fTracks->At(iTrack))->Print(iTrack));
346 }
347 }
348}
349
350// ----- Public method AddPoint (for current track) --------------------
352{
353 Int_t iDet = detId;
354 Int_t iTr = fCurrentTrack;
355 pair<Int_t, Int_t> a(iTr, iDet);
356 if (fPointsMap.find(a) == fPointsMap.end()) {
357 fPointsMap[a] = 1;
358 } else {
359 fPointsMap[a]++;
360 }
361}
362
363// ----- Public method AddPoint (for arbitrary track) -------------------
364void CbmStack::AddPoint(DetectorId detId, Int_t iTrack)
365{
366 if (iTrack < 0) {
367 return;
368 }
369 Int_t iDet = detId;
370 Int_t iTr = iTrack;
371 pair<Int_t, Int_t> a(iTr, iDet);
372 if (fPointsMap.find(a) == fPointsMap.end()) {
373 fPointsMap[a] = 1;
374 } else {
375 fPointsMap[a]++;
376 }
377}
378
379// ----- Virtual method GetCurrentParentTrackNumber --------------------
381{
382 TParticle* currentPart = GetCurrentTrack();
383 if (currentPart) {
384 return currentPart->GetFirstMother();
385 } else {
386 return -1;
387 }
388}
389
390// ----- Public method GetParticle -------------------------------------
391TParticle* CbmStack::GetParticle(Int_t trackID) const
392{
393 if (trackID < 0 || trackID >= fNParticles) {
394 LOG(fatal) << "Particle index " << trackID << " out of range.";
395 }
396 return static_cast<TParticle*>(fParticles->At(trackID));
397}
398
399// ----- Private method SelectTracks -----------------------------------
400void CbmStack::SelectTracks()
401{
402 // --> Clear storage map
403 fStoreMap.clear();
404
405 // --> Check particles in the fParticle array
406 for (Int_t i = 0; i < fNParticles; i++) {
407
408 TParticle* thisPart = GetParticle(i);
409 Bool_t store = kTRUE;
410
411 // --> Get track parameters
412 Int_t iMother = thisPart->GetMother(0);
413 TLorentzVector p;
414 thisPart->Momentum(p);
415 Double_t energy = p.E();
416 Double_t mass = p.M();
417 // Double_t mass = thisPart->GetMass();
418 Double_t eKin = energy - mass;
419
420 // --> Calculate number of points
421 // AZ-260324 Int_t nPoints = 0;
422 Int_t nPoints = 0, nPointsFHCAL = 0, nPointsNoFHCAL = 0; // AZ-260324
423
424 for (Int_t iDet = kREF; iDet < kNOFDETS; iDet++) {
425 pair<Int_t, Int_t> a(i, iDet);
426 if (fPointsMap.find(a) != fPointsMap.end()) {
427 nPoints += fPointsMap[a];
428 if (iDet == kFHCAL)
429 nPointsFHCAL += fPointsMap[a]; // save points in FHCAL
430 else
431 nPointsNoFHCAL += fPointsMap[a]; // points not in FHCAL - AZ-260324
432 }
433 }
434
435 // --> Check for cuts (store primaries in any case)
436 if (iMother < 0) {
437 store = kTRUE;
438 } else {
439 if (!fStoreSecondaries) {
440 store = kFALSE;
441 }
442 if (nPoints < fMinPoints) {
443 store = kFALSE;
444 }
445 if (eKin < fEnergyCut) {
446 store = kFALSE;
447 }
448 if (thisPart->Vz() > fStartZCut) {
449 store = kFALSE;
450 }
451 if (nPointsFHCAL && !nPointsNoFHCAL)
452 store = kFALSE; // AZ-260324 - do not store FHCAL-only tracks
453 // AZ-031023 - !!!!! - store hyperons and their daughters
454 // if (nPoints < fMinPoints && thisPart->Vz() < fStartZCut) {
455 if (nPoints < fMinPoints) {
456 // if (TMath::Abs(thisPart->GetPDG()->Charge()) > 0.1) store = kTRUE;
457 TParticle* mother = GetParticle(iMother);
458 mass = thisPart->GetPDG()->Mass();
459 if (mass < 1.8 && mother->GetPDG()->Mass() < 1.8) {
460 if (mass > 1.0 || mother->GetPDG()->Mass() > 1.0)
461 store = kTRUE; // hyperon
462 } else if ((thisPart->GetPdgCode() > 1e9 && (thisPart->GetPdgCode() % 1000000000) / 10000000)
463 || (mother->GetPdgCode() > 1e9 && (mother->GetPdgCode() % 1000000000) / 10000000))
464 store = kTRUE; // hypernucleus
465 // if (store) cout << " Store: " << thisPart->GetPdgCode() << " " << mother->GetPdgCode() << endl;
466 }
467 // AZ
468 }
469
470 // --> Set storage flag
471 fStoreMap[i] = store;
472 }
473
474 // --> If flag is set, flag recursively mothers of selected tracks
475 /*AZ-031023
476 if (fStoreMothers) {
477 for (Int_t i = 0; i < fNParticles; i++) {
478 if (fStoreMap[i]) {
479 Int_t iMother = GetParticle(i)->GetMother(0);
480 while (iMother >= 0) {
481 fStoreMap[iMother] = kTRUE;
482 iMother = GetParticle(iMother)->GetMother(0);
483 }
484 }
485 }
486 }
487 */
488 // AZ-031023 If flag is set, flag recursively mothers of selected tracks and their sisters
489 if (fStoreMothers) {
490 // Fill mother map
491 std::multimap<Int_t, Int_t> moths;
492 std::multimap<Int_t, Int_t>::iterator it;
493 pair<std::multimap<Int_t, Int_t>::iterator, std::multimap<Int_t, Int_t>::iterator> ret;
494 std::map<Int_t, Bool_t> copyMap = fStoreMap;
495 for (Int_t i = 0; i < fNParticles; i++) {
496 Int_t iMother = GetParticle(i)->GetMother(0);
497 if (iMother >= 0)
498 moths.insert(pair<Int_t, Int_t>(iMother, i));
499 }
500
501 for (Int_t i = 0; i < fNParticles; i++) {
502 if (copyMap[i]) {
503 Int_t iMother = GetParticle(i)->GetMother(0);
504 while (iMother >= 0) {
505 fStoreMap[iMother] = kTRUE;
506 ret = moths.equal_range(iMother);
507 for (it = ret.first; it != ret.second; ++it)
508 fStoreMap[it->second] = kTRUE; // sister
509 iMother = GetParticle(iMother)->GetMother(0);
510 }
511 }
512 }
513
514 // AZ-270324 - If mother is not stored, find the nearest stored ancestor (code taken from MPD)
515 for (Int_t i = 0; i < fNParticles; ++i) {
516 //(AZ-280324 - should be for all) if (fStoreMap[i]) {
517 Int_t iMother = GetParticle(i)->GetMother(0);
518
519 while (iMother >= 0 && fStoreMap[iMother] == kFALSE) {
520 TParticle* mother = GetParticle(iMother);
521 iMother = mother->GetMother(0); // mother of the mother, loop again
522 }
523 if (iMother >= 0)
524 GetParticle(i)->SetFirstMother(iMother);
525 // if (GetParticle(i)->Vz() > 900.0) cout << " xxx " << i << " " << GetParticle(i)->Vz() << " " << iMother
526 // << endl; //AZ-260324
527 // }
528 }
529 // AZ-270324
530
531 } // if (fStoreMothers)
532}
int i
Definition P4_F32vec4.h:22
DetectorId
@ kREF
@ kNOFDETS
@ kFHCAL
Int_t GetMotherId() const
Definition CbmMCTrack.h:57
void SetNPoints(Int_t iDet, Long64_t np)
void SetMotherId(Int_t id)
Definition CbmMCTrack.h:80
virtual void UpdateTrackIndex(TRefArray *detArray=0)
Definition CbmStack.cxx:243
virtual TParticle * PopNextTrack(Int_t &iTrack)
Definition CbmStack.cxx:133
virtual Int_t GetCurrentParentTrackNumber() const
Definition CbmStack.cxx:380
void AddPoint(DetectorId iDet)
Definition CbmStack.cxx:351
virtual TParticle * PopPrimaryForTracking(Int_t iPrim)
Definition CbmStack.cxx:157
virtual ~CbmStack()
Definition CbmStack.cxx:45
virtual void Reset()
Definition CbmStack.cxx:314
virtual void AddParticle(TParticle *part)
Definition CbmStack.cxx:188
virtual TParticle * GetCurrentTrack() const
Definition CbmStack.cxx:178
virtual void Print(Option_t *) const
Definition CbmStack.cxx:338
TParticle * GetParticle(Int_t trackId) const
Definition CbmStack.cxx:391
virtual void FillTrackArray()
Definition CbmStack.cxx:198
CbmStack(Int_t size=100)
Definition CbmStack.cxx:22
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 CbmStack.cxx:57
virtual void Register()
Definition CbmStack.cxx:328
@ store
store tags as binary type
STL namespace.