R3BROOT
R3B analysis software
Loading...
Searching...
No Matches
R3BMCStack.cxx
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (C) 2019 GSI Helmholtzzentrum für Schwerionenforschung GmbH *
3 * Copyright (C) 2019-2025 Members of R3B Collaboration *
4 * *
5 * This software is distributed under the terms of the *
6 * GNU General Public Licence (GPL) version 3, *
7 * copied verbatim in the file "LICENSE". *
8 * *
9 * In applying this license GSI does not waive the privileges and immunities *
10 * granted to it by virtue of its status as an Intergovernmental Organization *
11 * or submit itself to any jurisdiction. *
12 ******************************************************************************/
13
14// -------------------------------------------------------------------------
15// ----- R3BStack source file -----
16// ----- Created 10/08/04 by D. Bertini / V. Friese -----
17// -------------------------------------------------------------------------
18#include "R3BMCStack.h"
19#include <TClonesArray.h>
20
21#include "FairDetector.h"
22#include "FairLogger.h"
23#include "FairMCPoint.h"
24#include "FairRootManager.h"
25#include "R3BMCTrack.h"
26
27#include "TError.h"
28#include "TLorentzVector.h"
29#include "TParticle.h"
30#include "TRefArray.h"
31#include "TVirtualMC.h"
32
33#include <iostream>
34#include <list>
35
36using std::cout;
37using std::endl;
38using std::pair;
39
40// ----- Default constructor -------------------------------------------
42 : fStack()
43 , fParticles(new TClonesArray("TParticle", size))
44 , fTracks(new TClonesArray("R3BMCTrack", size))
45 , fStoreMap()
46 , fStoreIter()
47 , fIndexMap()
48 , fIndexIter()
49 , fPointsMap()
50 , fCurrentTrack(-1)
51 , fNPrimaries(0)
52 , fNParticles(0)
53 , fNTracks(0)
54 , fIndex(0)
55 , fMC(0)
56 , fStoreSecondaries(kTRUE)
57 , fMinPoints(0)
58 , fEnergyCut(0.)
59 , fStoreMothers(kTRUE)
60 , fDebug(kFALSE)
61{
62 TString MCName = gMC->GetName();
63 if (MCName.CompareTo("TGeant4") == 0)
64 {
65 fMC = 1;
66 }
67 else
68 {
69 fMC = 0;
70 }
71}
72
73// -------------------------------------------------------------------------
74
75// ----- Destructor ----------------------------------------------------
77{
78 if (fParticles)
79 {
80 fParticles->Delete();
81 delete fParticles;
82 }
83 if (fTracks)
84 {
85 fTracks->Delete();
86 delete fTracks;
87 }
88}
89// -------------------------------------------------------------------------
90
91// ----- Virtual public method PushTrack -------------------------------
92void R3BStack::PushTrack(Int_t toBeDone,
93 Int_t parentId,
94 Int_t pdgCode,
95 Double_t px,
96 Double_t py,
97 Double_t pz,
98 Double_t e,
99 Double_t vx,
100 Double_t vy,
101 Double_t vz,
102 Double_t time,
103 Double_t polx,
104 Double_t poly,
105 Double_t polz,
106 TMCProcess proc,
107 Int_t& ntr,
108 Double_t weight,
109 Int_t is)
110{
111
112 PushTrack(
113 toBeDone, parentId, pdgCode, px, py, pz, e, vx, vy, vz, time, polx, poly, polz, proc, ntr, weight, is, -1);
114}
115
116// ----- Virtual public method PushTrack -------------------------------
117void R3BStack::PushTrack(Int_t toBeDone,
118 Int_t parentId,
119 Int_t pdgCode,
120 Double_t px,
121 Double_t py,
122 Double_t pz,
123 Double_t e,
124 Double_t vx,
125 Double_t vy,
126 Double_t vz,
127 Double_t time,
128 Double_t polx,
129 Double_t poly,
130 Double_t polz,
131 TMCProcess proc,
132 Int_t& ntr,
133 Double_t weight,
134 Int_t is,
135 Int_t secondparentID)
136{
137
138 // --> Get TParticle array
139 TClonesArray& partArray = *fParticles;
140
141 // --> Create new TParticle and add it to the TParticle array
142 Int_t trackId = fNParticles;
143 Int_t nPoints = 0;
144 Int_t daughter1Id = -1;
145 Int_t daughter2Id = -1;
146 TParticle* particle = new (partArray[fNParticles++])
147 TParticle(pdgCode, trackId, parentId, nPoints, daughter1Id, daughter2Id, px, py, pz, e, vx, vy, vz, time);
148 particle->SetPolarisation(polx, poly, polz);
149 particle->SetWeight(weight);
150 particle->SetUniqueID(proc);
151
152 // --> Increment counter
153 if (parentId < 0)
154 fNPrimaries++;
155
156 // --> Set argument variable
157 ntr = trackId;
158
159 // --> Push particle on the stack if toBeDone is set
160 if (toBeDone == 1)
161 fStack.push(particle);
162}
163// -------------------------------------------------------------------------
164
165// ----- Virtual method PopNextTrack -----------------------------------
166TParticle* R3BStack::PopNextTrack(Int_t& iTrack)
167{
168
169 // If end of stack: Return empty pointer
170 if (fStack.empty())
171 {
172 iTrack = -1;
173 return NULL;
174 }
175
176 // If not, get next particle from stack
177 TParticle* thisParticle = fStack.top();
178 fStack.pop();
179
180 if (!thisParticle)
181 {
182 iTrack = 0;
183 return NULL;
184 }
185
186 fCurrentTrack = thisParticle->GetStatusCode();
187 iTrack = fCurrentTrack;
188
189 return thisParticle;
190}
191// -------------------------------------------------------------------------
192
193// ----- Virtual method PopPrimaryForTracking --------------------------
194TParticle* R3BStack::PopPrimaryForTracking(Int_t iPrim)
195{
196
197 // Get the iPrimth particle from the fStack TClonesArray. This
198 // should be a primary (if the index is correct).
199
200 // Test for index
201 if (iPrim < 0 || iPrim >= fNPrimaries)
202 {
203 LOG(fatal) << "R3BStack: Primary index out of range! " << iPrim;
204 }
205
206 // Return the iPrim-th TParticle from the fParticle array. This should be
207 // a primary.
208 TParticle* part = dynamic_cast<TParticle*>(fParticles->At(iPrim));
209 if (!(part->GetMother(0) < 0))
210 {
211 LOG(fatal) << "R3BStack:: Not a primary track! " << iPrim;
212 }
213
214 return part;
215}
216// -------------------------------------------------------------------------
217
218// ----- Virtual public method GetCurrentTrack -------------------------
220{
221 TParticle* currentPart = GetParticle(fCurrentTrack);
222 if (!currentPart)
223 {
224 LOG(warn) << "R3BStack: Current track not found in stack!";
225 }
226 return currentPart;
227}
228// -------------------------------------------------------------------------
229
230// ----- Public method AddParticle -------------------------------------
231void R3BStack::AddParticle(TParticle* oldPart)
232{
233 TClonesArray& array = *fParticles;
234 TParticle* newPart = new (array[fIndex]) TParticle(*oldPart);
235 newPart->SetWeight(oldPart->GetWeight());
236 newPart->SetUniqueID(oldPart->GetUniqueID());
237 fIndex++;
238}
239// -------------------------------------------------------------------------
240
241// ----- Public method FillTrackArray ----------------------------------
243{
244
245 LOG(debug) << "R3BStack: Filling MCTrack array...";
246
247 // --> Reset index map and number of output tracks
248 fIndexMap.clear();
249 fNTracks = 0;
250
251 //<DB> if no selection than no selection
252 /*
253 if ( fMinPoints == 0 ) {
254
255 for (Int_t iPart=0; iPart<fNParticles; iPart++) {
256 R3BMCTrack* track =
257 new( (*fTracks)[fNTracks]) R3BMCTrack(GetParticle(iPart));
258 fNTracks++;
259 }
260 cout << "-I- R3BStack: no select. MCTracks forwarded : " << fNParticles << endl;
261 return;
262 }//! fMinPoints
263 */
264
265 // --> Check tracks for selection criteria
266 SelectTracks();
267
268 // --> Loop over fParticles array and copy selected tracks
269 for (Int_t iPart = 0; iPart < fNParticles; iPart++)
270 {
271
272 fStoreIter = fStoreMap.find(iPart);
273 if (fStoreIter == fStoreMap.end())
274 {
275 LOG(fatal) << "R3BStack: Particle " << iPart << " not found in storage map!";
276 }
277 Bool_t store = (*fStoreIter).second;
278
279 if (store)
280 {
281 new ((*fTracks)[fNTracks]) R3BMCTrack(GetParticle(iPart), fPointsMap[iPart], fMC);
282 fIndexMap[iPart] = fNTracks;
283 fNTracks++;
284 // cout << "-I- TParticle time " << GetParticle(iPart)->T() << endl;
285 // cout << "-I- MC Track time " << track->GetStartT() << endl;
286 }
287 else
288 {
289 LOG(debug) << "R3BMCStack IndexMap ---> -2 for iPart: " << iPart;
290 fIndexMap[iPart] = -2;
291 }
292 }
293
294 // --> Map index for primary mothers
295 fIndexMap[-1] = -1;
296
297 // --> Screen output
298 PrintStack(0);
299}
300// -------------------------------------------------------------------------
301
302// ----- Public method UpdateTrackIndex --------------------------------
303void R3BStack::UpdateTrackIndex(TRefArray* detList)
304{
305
306 if (fMinPoints == 0)
307 return;
308 LOG(debug) << "R3BStack: Updating track indizes...";
309 Int_t nColl = 0;
310
311 // First update mother ID in MCTracks
312 for (Int_t i = 0; i < fNTracks; i++)
313 {
314 R3BMCTrack* track = dynamic_cast<R3BMCTrack*>(fTracks->At(i));
315 Int_t iMotherOld = track->GetMotherId();
316 fIndexIter = fIndexMap.find(iMotherOld);
317 if (fIndexIter == fIndexMap.end())
318 {
319 LOG(fatal) << "R3BStack: Particle index " << iMotherOld << " not found in dex map! ";
320 }
321 track->SetMotherId((*fIndexIter).second);
322 }
323
324 // Now iterate through all active detectors
325 TIterator* detIter = detList->MakeIterator();
326 detIter->Reset();
327 FairDetector* det = NULL;
328 while ((det = dynamic_cast<FairDetector*>(detIter->Next())))
329 {
330
331 // --> Get hit collections from detector
332 Int_t iColl = 0;
333 TClonesArray* hitArray;
334 while ((hitArray = det->GetCollection(iColl++)))
335 {
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 {
342 FairMCPoint* point = dynamic_cast<FairMCPoint*>(hitArray->At(iPoint));
343 Int_t iTrack = point->GetTrackID();
344
345 LOG(debug) << "R3BMCStack TrackID Get : " << iTrack;
346
347 fIndexIter = fIndexMap.find(iTrack);
348 if (fIndexIter == fIndexMap.end())
349 {
350 LOG(fatal) << "R3BStack: Particle index " << iTrack << " not found in index map! ";
351 }
352 LOG(debug) << "R3BMCStack TrackID Set : " << (*fIndexIter).second;
353 // if ( ((*fIndexIter).second ) < 0 ) {
354 // point->SetTrackID(iTrack);
355 // }else{
356 point->SetTrackID((*fIndexIter).second);
357 // }
358 }
359 }
360 } // List of active detectors
361
362 LOG(debug) << "...stack and " << nColl << " collections updated";
363}
364// -------------------------------------------------------------------------
365
366// ----- Public method Reset -------------------------------------------
368{
369 fIndex = 0;
370 fCurrentTrack = -1;
371 fNPrimaries = fNParticles = fNTracks = 0;
372 while (!fStack.empty())
373 fStack.pop();
374 fParticles->Clear();
375 fTracks->Clear();
376 fPointsMap.clear();
377}
378// -------------------------------------------------------------------------
379
380// ----- Public method Register ----------------------------------------
381void R3BStack::Register() { FairRootManager::Instance()->Register("MCTrack", "Stack", fTracks, kTRUE); }
382// -------------------------------------------------------------------------
383
384// ----- Public method Print --------------------------------------------
385void R3BStack::PrintStack(Int_t iVerbose) const
386{
387 if (1 == iVerbose)
388 {
389 LOG(info) << "R3BStack: Number of primaries = " << fNPrimaries;
390 LOG(info) << " Total number of particles = " << fNParticles;
391 LOG(info) << " Number of tracks in output = " << fNTracks;
392 for (Int_t iTrack = 0; iTrack < fNTracks; iTrack++)
393 {
394 char str[100];
395 sprintf(str, "%d", iTrack);
396 (dynamic_cast<R3BMCTrack*>(fTracks->At(iTrack)))->Print((Option_t*)str);
397 }
398 }
399}
400// -------------------------------------------------------------------------
401
402// ----- Public method AddPoint (for current track) --------------------
404{
405 if (fPointsMap.find(fCurrentTrack) == fPointsMap.end())
406 fPointsMap[fCurrentTrack][detId] = 1;
407 else
408 fPointsMap[fCurrentTrack][detId]++;
409}
410// -------------------------------------------------------------------------
411
412// ----- Public method AddPoint (for arbitrary track) -------------------
413void R3BStack::AddPoint(DetectorId detId, Int_t iTrack)
414{
415 if (iTrack < 0)
416 return;
417 if (fPointsMap.find(iTrack) == fPointsMap.end())
418 fPointsMap[iTrack][detId] = 1;
419 else
420 fPointsMap[iTrack][detId]++;
421}
422// -------------------------------------------------------------------------
423
424// ----- Virtual method GetCurrentParentTrackNumber --------------------
426{
427 TParticle* currentPart = GetCurrentTrack();
428 if (currentPart)
429 return currentPart->GetFirstMother();
430 else
431 return -1;
432}
433// -------------------------------------------------------------------------
434
435// ----- Public method GetParticle -------------------------------------
436TParticle* R3BStack::GetParticle(Int_t trackID) const
437{
438 if (trackID < 0 || trackID >= fNParticles)
439 {
440 LOG(fatal) << "-E- R3BStack: Particle index " << trackID << " out of range";
441 }
442 return dynamic_cast<TParticle*>(fParticles->At(trackID));
443}
444// -------------------------------------------------------------------------
445
446// ----- Private method SelectTracks -----------------------------------
447void R3BStack::SelectTracks()
448{
449
450 // --> Clear storage map
451 fStoreMap.clear();
452
453 // --> Check particles in the fParticle array
454 for (Int_t i = 0; i < fNParticles; i++)
455 {
456
457 TParticle* thisPart = GetParticle(i);
458 Bool_t store = kTRUE;
459
460 // --> Get track parameters
461 Int_t iMother = thisPart->GetMother(0);
462 TLorentzVector p;
463 thisPart->Momentum(p);
464 Double_t energy = p.E();
465 Double_t mass = thisPart->GetMass();
466 Double_t eKin = energy - mass;
467 if (eKin < 0.0)
468 eKin = 0.0; // sometimes due to different PDG masses between ROOT and G4!!!!!!
469 // --> Calculate number of points
470 Int_t nPoints = 0;
471 for (Int_t iDet = kREF; iDet < kLAST; iDet++)
472 {
473 if (fPointsMap.find(i) != fPointsMap.end())
474 nPoints += fPointsMap[i][iDet];
475 }
476
477 // --> Check for cuts (store primaries in any case)
478 if (iMother < 0)
479 store = kTRUE;
480 else
481 {
482 if (!fStoreSecondaries)
483 store = kFALSE;
484 if (nPoints < fMinPoints)
485 store = kFALSE;
486 if (eKin < fEnergyCut)
487 store = kFALSE;
488 }
489
490 // --> Set storage flag
491 fStoreMap[i] = store;
492 }
493
494 // --> If flag is set, flag recursively mothers of selected tracks
495 if (fStoreMothers)
496 {
497 for (Int_t i = 0; i < fNParticles; i++)
498 {
499 if (fStoreMap[i])
500 {
501 Int_t iMother = GetParticle(i)->GetMother(0);
502 while (iMother >= 0)
503 {
504 fStoreMap[iMother] = kTRUE;
505 iMother = GetParticle(iMother)->GetMother(0);
506 }
507 }
508 }
509 }
510}
511// -------------------------------------------------------------------------
512
DetectorId
Unique identifier for all R3B detector systems.
@ kLAST
@ kREF
ClassImp(R3B::Neuland::Cal2HitPar)
void SetMotherId(int id)
Modifiers.
Definition R3BMCTrack.h:72
int GetMotherId() const
Definition R3BMCTrack.h:49
R3BStack.h.
Definition R3BMCStack.h:55
virtual void PrintStack(Int_t iVerbose) const
Output to screen.
virtual void UpdateTrackIndex(TRefArray *detArray)
Update the track index in the MCTracks and MCPoints.
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)
Add a TParticle to the stack.
virtual Int_t GetCurrentParentTrackNumber() const
Get the track number of the parent of the current track Declared in TVirtualMCStack.
virtual void Register()
Register the MCTrack array to the Root Manager.
virtual void AddParticle(TParticle *part)
Add a TParticle to the fParticles array.
virtual TParticle * PopPrimaryForTracking(Int_t iPrim)
Get primary particle by index for tracking from stack Declared in TVirtualMCStack.
virtual void Reset()
Resets arrays and stack and deletes particles and tracks.
virtual TParticle * GetCurrentTrack() const
Get the current track's particle Declared in TVirtualMCStack.
virtual TParticle * PopNextTrack(Int_t &iTrack)
Get next particle for tracking from the stack.
void AddPoint(DetectorId iDet)
Increment number of points for the current track in a given detector.
virtual ~R3BStack()
Destructor.
TParticle * GetParticle(Int_t trackId) const
Accessors.
R3BStack(Int_t size=100)
Default constructor param size Estimated track number.
virtual void FillTrackArray()
Fill the MCTrack output array, applying filter criteria.