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;
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 -----------------------------------
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 {
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.
std::map< int, std::array< int, kLAST+1 > > fPointsMap
STL map from track index and detector ID to number of MCPoints.
Definition R3BMCStack.h:232
Int_t fIndex
Number of entries in fTracks.
Definition R3BMCStack.h:239
Bool_t fStoreMothers
Definition R3BMCStack.h:246
void SelectTracks()
Mark tracks for output using selection criteria.
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.
TClonesArray * fParticles
Array of TParticles (contains all TParticles put into or created by the transport.
Definition R3BMCStack.h:218
virtual void Register()
Register the MCTrack array to the Root Manager.
Int_t fNParticles
Number of primary particles.
Definition R3BMCStack.h:237
virtual void AddParticle(TParticle *part)
Add a TParticle to the fParticles array.
Double32_t fEnergyCut
Definition R3BMCStack.h:245
virtual TParticle * PopPrimaryForTracking(Int_t iPrim)
Get primary particle by index for tracking from stack Declared in TVirtualMCStack.
std::map< Int_t, Bool_t >::iterator fStoreIter
Definition R3BMCStack.h:225
std::map< Int_t, Bool_t > fStoreMap
STL map from particle index to storage flag.
Definition R3BMCStack.h:224
Bool_t fStoreSecondaries
index for MC units testing
Definition R3BMCStack.h:243
std::stack< TParticle * > fStack
STL stack (FILO) used to handle the TParticles for tracking.
Definition R3BMCStack.h:213
virtual void Reset()
Resets arrays and stack and deletes particles and tracks.
std::map< Int_t, Int_t >::iterator fIndexIter
Definition R3BMCStack.h:229
Int_t fCurrentTrack
Some indizes and counters.
Definition R3BMCStack.h:235
virtual TParticle * GetCurrentTrack() const
Get the current track's particle Declared in TVirtualMCStack.
std::map< Int_t, Int_t > fIndexMap
STL map from particle index to track index.
Definition R3BMCStack.h:228
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.
Int_t fMC
Used for merging.
Definition R3BMCStack.h:240
Int_t fNTracks
Number of entries in fParticles.
Definition R3BMCStack.h:238
Int_t fNPrimaries
Index of current track.
Definition R3BMCStack.h:236
virtual ~R3BStack()
Destructor.
TParticle * GetParticle(Int_t trackId) const
Accessors.
R3BStack(Int_t size=100)
Default constructor param size Estimated track number.
Int_t fMinPoints
Definition R3BMCStack.h:244
virtual void FillTrackArray()
Fill the MCTrack output array, applying filter criteria.
Bool_t fDebug
Definition R3BMCStack.h:247
TClonesArray * fTracks
Array of R3BMCTracks containg the tracks written to the output.
Definition R3BMCStack.h:221