CbmRoot
Loading...
Searching...
No Matches
CbmStack.cxx
Go to the documentation of this file.
1/* Copyright (C) 2004-2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Volker Friese, Denis Bertini [committer], Florian Uhlig */
4
5// -------------------------------------------------------------------------
6// ----- CbmStack source file -----
7// ----- Created 10/08/04 by D. Bertini / V. Friese -----
8// -------------------------------------------------------------------------
9#include "CbmStack.h"
10
11#include "CbmMCTrack.h"
12
13#include "FairDetector.h"
14#include "FairMCPoint.h"
15#include "FairRootManager.h"
16
17#include "TClonesArray.h"
18#include "TLorentzVector.h"
19#include "TParticle.h"
20#include "TRefArray.h"
21
22#include <cassert>
23#include <list>
24
25
26using std::make_pair;
27using std::pair;
28using std::vector;
29
30
31// ----- Default constructor -------------------------------------------
33 : FairGenericStack()
34 , fStack()
35 , fFilter(new CbmStackFilter)
36 , fParticles(new TClonesArray("TParticle", size))
37 , fTracks(new TClonesArray("CbmMCTrack", size))
38 , fIndexMap()
39 , fIndexIter()
40 , fPointsMap()
41 , fCurrentTrack(-1)
42 , fNPrimaries(0)
43 , fNParticles(0)
44 , fNTracks(0)
45 , fIndex(0)
46 , fStoreSecondaries(kTRUE)
47 , fMinPoints(1)
48 , fEnergyCut(0.)
49 , fStoreMothers(kTRUE)
50 , fdoTracking(kTRUE)
51{
52}
53
54// -------------------------------------------------------------------------
55
56
57// ----- Destructor ----------------------------------------------------
59{
60 if (fParticles) {
61 fParticles->Delete();
62 delete fParticles;
63 }
64 if (fTracks) {
65 fTracks->Delete();
66 delete fTracks;
67 }
68}
69// -------------------------------------------------------------------------
70
71
72// ----- Push track (pure virtual from TVirtualMCStack) ----------------
73void CbmStack::PushTrack(Int_t toBeDone, Int_t parentId, Int_t pdgCode, Double_t px, Double_t py, Double_t pz,
74 Double_t e, Double_t vx, Double_t vy, Double_t vz, Double_t time, Double_t polx, Double_t poly,
75 Double_t polz, TMCProcess proc, Int_t& ntr, Double_t weight, Int_t is)
76{
77
78
79 // Channel all arguments to the method declared in FairGenericStack.
80 // Generator parent ID is set to -1.
81 PushTrack(toBeDone, parentId, pdgCode, px, py, pz, e, vx, vy, vz, time, polx, poly, polz, proc, ntr, weight, is, -1);
82}
83// -------------------------------------------------------------------------
84
85
86// ----- PushTrack (pure virtual from FairGenericStack -----------------
87void CbmStack::PushTrack(Int_t toBeDone, Int_t parentId, Int_t pdgCode, Double_t px, Double_t py, Double_t pz,
88 Double_t e, Double_t vx, Double_t vy, Double_t vz, Double_t time, Double_t polx, Double_t poly,
89 Double_t polz, TMCProcess proc, Int_t& ntr, Double_t weight, Int_t /*status*/,
90 Int_t generatorParentId)
91{
92
93 // --> If primary, increment counter
94 if (parentId < 0) fNPrimaries++;
95
96 // ---> Set parent ID to the generator parent ID for primaries
97 if (parentId == -1 && generatorParentId < fNParticles) parentId = generatorParentId;
98
99 // --> Create new TParticle and add it to the TParticle array
100 Int_t trackId = fNParticles;
101 Int_t nPoints = 0;
102 Int_t daughter1Id = -1;
103 Int_t daughter2Id = -1;
104 TParticle* particle = new ((*fParticles)[fNParticles++])
105 TParticle(pdgCode, trackId, parentId, nPoints, daughter1Id, daughter2Id, px, py, pz, e, vx, vy, vz, time);
106 particle->SetPolarisation(polx, poly, polz);
107 particle->SetWeight(weight);
108 // We use the TObject unique ID to store the creation process of a particle.
109 // According to the ROOT talk, the unique ID can be used at will if the object
110 // is not used via TRef or TRefArray.
111 particle->SetUniqueID(proc);
112
113 // --> Set return argument
114 ntr = trackId;
115
116 // --> Push particle on the stack if toBeDone is set
117 // Note that for particles created by TGeant4, toBeDone is kFALSE,
118 // meaning that particles will not be put onto the internal stack.
119 // Geant4 seems to have a separate, internal stack administration.
120 if (fdoTracking && toBeDone) {
121 particle->SetBit(1);
122 fStack.push(particle);
123 }
124}
125// -------------------------------------------------------------------------
126
127
128// ----- Virtual method PopNextTrack -----------------------------------
129TParticle* CbmStack::PopNextTrack(Int_t& iTrack)
130{
131
132 // If end of stack: Return empty pointer
133 if (fStack.empty()) {
134 iTrack = -1;
135 return nullptr;
136 }
137
138 // If not, get next particle from stack
139 TParticle* thisParticle = fStack.top();
140 fStack.pop();
141
142 if (!thisParticle) {
143 iTrack = 0;
144 return nullptr;
145 }
146
147 fCurrentTrack = thisParticle->GetStatusCode();
148 iTrack = fCurrentTrack;
149
150 return thisParticle;
151}
152// -------------------------------------------------------------------------
153
154
155// ----- Virtual method PopPrimaryForTracking --------------------------
156TParticle* CbmStack::PopPrimaryForTracking(Int_t iPrim)
157{
158
159 // Get the iPrimth particle from the fStack TClonesArray. This
160 // should be a primary (if the index is correct).
161 assert(iPrim >= 0 && iPrim < fNPrimaries);
162
163 // Return the iPrim-th TParticle from the fParticle array. This should be
164 // a primary.
165 TParticle* part = (TParticle*) fParticles->At(iPrim);
166 assert(part->GetUniqueID() == kPPrimary);
167 if (!part->TestBit(1)) { return NULL; }
168 else {
169 return part;
170 }
171}
172// -------------------------------------------------------------------------
173
174
175// ----- Virtual public method GetCurrentTrack -------------------------
177{
178 TParticle* currentPart = GetParticle(fCurrentTrack);
179 if (!currentPart) { LOG(warn) << "Current track not found in stack!"; }
180 return currentPart;
181}
182// -------------------------------------------------------------------------
183
184
185// ----- Public method AddParticle -------------------------------------
186void CbmStack::AddParticle(TParticle* oldPart)
187{
188 TClonesArray& array = *fParticles;
189 TParticle* newPart = new (array[fIndex]) TParticle(*oldPart);
190 newPart->SetWeight(oldPart->GetWeight());
191 newPart->SetUniqueID(oldPart->GetUniqueID());
192 fIndex++;
193}
194// -------------------------------------------------------------------------
195
196
197// ----- Fill the output MCTrack array ---------------------------------
199{
200
201 // Call the stack filter
202 assert(fFilter);
203 vector<Bool_t> store = fFilter->Select(*fParticles, fPointsMap);
204 auto nParticles = static_cast<std::size_t>(fParticles->GetEntriesFast());
205 assert(store.size() == nParticles);
206
207 // Reset index map
208 fIndexMap.clear();
209 fIndexMap[-1] = -1; // Map index for primary mothers
210
211 // Copy selected particles to the output
212 for (Int_t indexP = 0; indexP < fParticles->GetEntriesFast(); indexP++) {
213
214 if (store[indexP]) {
215
216 // Create a new MCTrack in the output from the particle
217 Int_t indexT = fTracks->GetEntriesFast();
218 CbmMCTrack* track = new ((*fTracks)[indexT]) CbmMCTrack(GetParticle(indexP));
219
220 // Map the particle index to the track index
221 fIndexMap[indexP] = indexT;
222
223 // Set the number of points in the detectors for this track
224 for (ECbmModuleId detector = ECbmModuleId::kRef; detector <= ECbmModuleId::kNofSystems; ++detector) {
225 auto it = fPointsMap.find(make_pair(indexP, detector));
226 if (it != fPointsMap.end()) track->SetNPoints(detector, it->second);
227 } //# detectors
228
229 } //? store particle
230
231 // For particles discarded from storage, the index is set to -2.
232 else {
233 fIndexMap[indexP] = -2;
234 } //? do not store particle
235
236 } //# stack particles
237
238 fNTracks = fTracks->GetEntriesFast();
239 LOG(info) << "CbmStack: " << fParticles->GetEntriesFast() << " particles, " << fNTracks << " written to output.";
240}
241// -------------------------------------------------------------------------
242
243
244// ----- Public method UpdateTrackIndex --------------------------------
245void CbmStack::UpdateTrackIndex(TRefArray* detList)
246{
247
248 LOG(debug) << "Updating track indizes...";
249 Int_t nColl = 0;
250
251 // First update mother ID in MCTracks
252 for (Int_t i = 0; i < fNTracks; i++) {
253 CbmMCTrack* track = (CbmMCTrack*) fTracks->At(i);
254 Int_t iMotherOld = track->GetMotherId();
255 fIndexIter = fIndexMap.find(iMotherOld);
256 if (fIndexIter == fIndexMap.end()) { LOG(fatal) << "Particle index " << iMotherOld << " not found in dex map! "; }
257 track->SetMotherId((*fIndexIter).second);
258 }
259
260 // Now iterate through all active detectors
261 TIterator* detIter = detList->MakeIterator();
262 detIter->Reset();
263 FairDetector* det = nullptr;
264 while ((det = (FairDetector*) detIter->Next())) {
265
266
267 // --> Get hit collections from detector
268 Int_t iColl = 0;
269 TClonesArray* hitArray;
270 while ((hitArray = det->GetCollection(iColl++))) {
271 nColl++;
272 Int_t nPoints = hitArray->GetEntriesFast();
273
274 // --> Update track index for all MCPoints in the collection
275 for (Int_t iPoint = 0; iPoint < nPoints; iPoint++) {
276 FairMCPoint* point = (FairMCPoint*) hitArray->At(iPoint);
277 Int_t iTrack = point->GetTrackID();
278
279 fIndexIter = fIndexMap.find(iTrack);
280 if (fIndexIter == fIndexMap.end()) { LOG(fatal) << "Particle index " << iTrack << " not found in index map! "; }
281 point->SetTrackID((*fIndexIter).second);
282 point->SetLink(FairLink("MCTrack", (*fIndexIter).second));
283 }
284
285 } // Collections of this detector
286 } // List of active detectors
287
288 delete detIter;
289 LOG(debug) << "...stack and " << nColl << " collections updated.";
290}
291// -------------------------------------------------------------------------
292
293
294// ----- Public method Reset -------------------------------------------
296{
297 fIndex = 0;
298 fCurrentTrack = -1;
300 while (!fStack.empty()) {
301 fStack.pop();
302 }
303 fParticles->Clear();
304 fTracks->Clear();
305 fPointsMap.clear();
306}
307// -------------------------------------------------------------------------
308
309
310// ----- Public method Register ----------------------------------------
311void CbmStack::Register() { FairRootManager::Instance()->Register("MCTrack", "Stack", fTracks, kTRUE); }
312// -------------------------------------------------------------------------
313
314
315// ----- Public method Print --------------------------------------------
316void CbmStack::Print(Option_t*) const
317{
318 LOG(debug) << "Number of primaries = " << fNPrimaries;
319 LOG(debug) << "Total number of particles = " << fNParticles;
320 LOG(debug) << "Number of tracks in output = " << fNTracks;
321 if (fair::Logger::Logging(fair::Severity::debug1)) {
322 for (Int_t iTrack = 0; iTrack < fNTracks; iTrack++) {
323 LOG(debug1) << "MCTrack " << iTrack << ((CbmMCTrack*) fTracks->At(iTrack))->ToString();
324 }
325 }
326}
327// -------------------------------------------------------------------------
328
329
330// ----- Public method AddPoint (for current track) --------------------
332{
333 pair<Int_t, ECbmModuleId> a(fCurrentTrack, detId);
334 if (fPointsMap.find(a) == fPointsMap.end()) { fPointsMap[a] = 1; }
335 else {
336 fPointsMap[a]++;
337 }
338}
339// -------------------------------------------------------------------------
340
341
342// ----- Public method AddPoint (for arbitrary track) -------------------
343void CbmStack::AddPoint(ECbmModuleId detId, Int_t iTrack)
344{
345 if (iTrack < 0) { return; }
346 pair<Int_t, ECbmModuleId> a(iTrack, detId);
347 if (fPointsMap.find(a) == fPointsMap.end()) { fPointsMap[a] = 1; }
348 else {
349 fPointsMap[a]++;
350 }
351}
352// -------------------------------------------------------------------------
353
354
355// ----- Virtual method GetCurrentParentTrackNumber --------------------
357{
358 TParticle* currentPart = GetCurrentTrack();
359 if (currentPart) { return currentPart->GetFirstMother(); }
360 else {
361 return -1;
362 }
363}
364// -------------------------------------------------------------------------
365
366
367// ----- Public method GetParticle -------------------------------------
368TParticle* CbmStack::GetParticle(Int_t trackID) const
369{
370 if (trackID < 0 || trackID >= fNParticles) { LOG(fatal) << "Particle index " << trackID << " out of range."; }
371 return (TParticle*) fParticles->At(trackID);
372}
373// -------------------------------------------------------------------------
374
375
ClassImp(CbmConverterManager)
ECbmModuleId
Definition CbmDefs.h:39
@ kRef
Reference plane.
@ kNofSystems
For loops over active systems.
static constexpr size_t size()
Definition KfSimdPseudo.h:2
void SetNPoints(ECbmModuleId iDet, int32_t np)
int32_t GetMotherId() const
Definition CbmMCTrack.h:69
void SetMotherId(int32_t id)
Definition CbmMCTrack.h:110
Class for filtering the stack before writing.
Int_t fCurrentTrack
Definition CbmStack.h:271
Int_t fNParticles
Number of primary particles.
Definition CbmStack.h:273
void AddPoint(ECbmModuleId iDet)
Definition CbmStack.cxx:331
virtual TParticle * PopNextTrack(Int_t &iTrack)
Definition CbmStack.cxx:129
virtual Int_t GetCurrentParentTrackNumber() const
Definition CbmStack.cxx:356
Int_t fIndex
Number of entries in fTracks.
Definition CbmStack.h:275
Int_t fNPrimaries
Index of current track.
Definition CbmStack.h:272
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 process, Int_t &ntr, Double_t weight, Int_t status)
Add a track to the stack (TVirtualMCStack)
Definition CbmStack.cxx:73
std::map< std::pair< Int_t, ECbmModuleId >, Int_t > fPointsMap
Definition CbmStack.h:267
virtual TParticle * PopPrimaryForTracking(Int_t iPrim)
Definition CbmStack.cxx:156
virtual ~CbmStack()
Definition CbmStack.cxx:58
virtual void Reset()
Definition CbmStack.cxx:295
virtual void AddParticle(TParticle *part)
Definition CbmStack.cxx:186
virtual TParticle * GetCurrentTrack() const
Definition CbmStack.cxx:176
TParticle * GetParticle(Int_t trackId) const
Definition CbmStack.cxx:368
std::map< Int_t, Int_t >::iterator fIndexIter
Definition CbmStack.h:263
virtual void FillTrackArray()
Definition CbmStack.cxx:198
Int_t fNTracks
Number of entries in fParticles.
Definition CbmStack.h:274
CbmStack(Int_t size=100)
Definition CbmStack.cxx:32
std::map< Int_t, Int_t > fIndexMap
Definition CbmStack.h:262
Bool_t fdoTracking
Definition CbmStack.h:285
TClonesArray * fParticles
Stack filter class.
Definition CbmStack.h:254
virtual void UpdateTrackIndex(TRefArray *detArray)
Definition CbmStack.cxx:245
virtual void Print(Option_t *="") const
Definition CbmStack.cxx:316
virtual void Register()
Definition CbmStack.cxx:311
std::stack< TParticle * > fStack
Definition CbmStack.h:245
std::unique_ptr< CbmStackFilter > fFilter
Definition CbmStack.h:248
TClonesArray * fTracks
Definition CbmStack.h:258