forked from AliceO2Group/AliceO2
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStack.h
More file actions
315 lines (249 loc) · 11.3 KB
/
Stack.h
File metadata and controls
315 lines (249 loc) · 11.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
// Copyright CERN and copyright holders of ALICE O2. This software is
// distributed under the terms of the GNU General Public License v3 (GPL
// Version 3), copied verbatim in the file "COPYING".
//
// See http://alice-o2.web.cern.ch/license for full licensing information.
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.
/// \file Stack.h
/// \brief Definition of the Stack class
/// \author M. Al-Turany - June 2014
#ifndef ALICEO2_DATA_STACK_H_
#define ALICEO2_DATA_STACK_H_
#include "DetectorsCommonDataFormats/DetID.h"
#include "FairGenericStack.h"
#include "SimulationDataFormat/MCTrack.h"
#include "SimulationDataFormat/MCTruthContainer.h"
#include "SimulationDataFormat/TrackReference.h"
#include "Rtypes.h"
#include "TParticle.h"
#include <map>
#include <memory>
#include <stack>
#include <utility>
class TClonesArray;
class TRefArray;
namespace o2
{
namespace base
{
class Detector;
}
namespace data
{
/// This class handles the particle stack for the transport simulation.
/// For the stack FILO functunality, it uses the STL stack. To store
/// the tracks during transport, a TParticle array is used.
/// At the end of the event, tracks satisfying the filter criteria
/// are copied to a MCTrack array, which is stored in the output.
///
/// The filtering criteria for the output tracks are:
/// - primary tracks are stored in any case.
/// - secondary tracks are stored if they have a minimal number of
/// hits (sum of all detectors) and a minimal energy, or are the
///
/// The storage of secondaries can be switched off.
/// The storage of all mothers can be switched off.
/// By default, the minimal number of hits is 1 and the energy cut is 0.
class Stack : public FairGenericStack
{
public:
/// Default constructor
/// \param size Estimated track number
Stack(Int_t size = 100);
/// Default destructor
~Stack() override;
/// Add a TParticle to the stack.
/// Declared in TVirtualMCStack
/// \param toBeDone Flag for tracking
/// \param parentID Index of mother particle
/// \param pdgCode Particle type (PDG encoding)
/// \param px,py,pz Momentum components at start vertex [GeV]
/// \param e Total energy at start vertex [GeV]
/// \param vx,vy,vz Coordinates of start vertex [cm]
/// \param time Start time of track [s]
/// \param polx,poly,polz Polarisation vector
/// \param proc Production mechanism (VMC encoding)
/// \param ntr Track number (filled by the stack)
/// \param weight Particle weight
/// \param is Generation status code (whatever that means)
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) override;
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, Int_t secondParentId) override;
// similar function taking a particle
void PushTrack(Int_t toBeDone, TParticle const&);
/// Get next particle for tracking from the stack.
/// Declared in TVirtualMCStack
/// Returns a pointer to the TParticle of the track
/// \param iTrack index of popped track (return)
TParticle* PopNextTrack(Int_t& iTrack) override;
/// Get primary particle by index for tracking from stack
/// Declared in TVirtualMCStack
/// Returns a pointer to the TParticle of the track
/// \param iPrim index of primary particle
TParticle* PopPrimaryForTracking(Int_t iPrim) override;
/// Set the current track number
/// Declared in TVirtualMCStack
/// \param iTrack track number
void SetCurrentTrack(Int_t iTrack) override;
/// Get total number of tracks
/// Declared in TVirtualMCStack
Int_t GetNtrack() const override { return mNumberOfEntriesInParticles; }
/// Get number of primary tracks
/// Declared in TVirtualMCStack
Int_t GetNprimary() const override { return mNumberOfPrimaryParticles; }
/// Get the current track's particle
/// Declared in TVirtualMCStack
TParticle* GetCurrentTrack() const override
{
// the const cast is necessary ... the interface should have been `const TParticle* GetCurrentParticle() const`
return const_cast<TParticle*>(&mCurrentParticle);
}
/// Get the number of the current track
/// Declared in TVirtualMCStack
Int_t GetCurrentTrackNumber() const override { return mIndexOfCurrentTrack; }
/// Get the track number of the parent of the current track
/// Declared in TVirtualMCStack
Int_t GetCurrentParentTrackNumber() const override;
/// Fill the MCTrack output array, applying filter criteria
void FillTrackArray() override;
/// Update the track index in the MCTracks and data produced by detectors
void UpdateTrackIndex(TRefArray* detArray = nullptr) override;
/// Finish primary
void FinishPrimary() override;
/// Resets arrays and stack and deletes particles and tracks
void Reset() override;
/// Register the MCTrack array to the Root Manager
void Register() override;
/// Output to screen
/// \param iVerbose: 0=events summary, 1=track info
virtual void Print(Int_t iVerbose = 0) const;
/// Output to screen (derived from base class)
/// \param option: 0=events summary, non0=track info
void Print(Option_t* option = nullptr) const override;
/// Modifiers
void StoreSecondaries(Bool_t choice = kTRUE) { mStoreSecondaries = choice; }
void pruneKinematics(bool choice = true) { mPruneKinematics = choice; }
void setMinHits(Int_t min) { mMinHits = min; }
void SetEnergyCut(Double_t eMin) { mEnergyCut = eMin; }
void StoreMothers(Bool_t choice = kTRUE) { mStoreMothers = choice; }
/// Increment number of hits for the current track in a given detector
/// \param iDet Detector unique identifier
void addHit(int iDet);
TClonesArray* GetListOfParticles() override;
std::vector<MCTrack> const* const getMCTracks() const { return mTracks; }
/// Clone for worker (used in MT mode only)
FairGenericStack* CloneStack() const override;
// receive notification that primary is finished
void notifyFinishPrimary();
// methods concerning track references
void addTrackReference(const o2::TrackReference& p);
// get primaries
const std::vector<TParticle>& getPrimaries() const { return mPrimaryParticles; }
// initialize Stack from external vector containing primaries
void initFromPrimaries(std::vector<TParticle> const& primaries)
{
Reset();
for (auto p : primaries) {
PushTrack(1, p);
}
mNumberOfPrimaryParticles = primaries.size();
mNumberOfEntriesInParticles = mNumberOfPrimaryParticles;
}
void setExternalMode(bool m) { mIsExternalMode = m; }
/// Allow to query the **direct** mother track ID of an arbitrary trackID managed by stack
int getMotherTrackId(int /*trackid*/) const;
/// query if a track is a direct **or** indirect daughter of a parentID
/// if trackid is same as parentid it returns true
bool isTrackDaughterOf(int /*trackid*/, int /*parentid*/) const;
bool isCurrentTrackDaughterOf(int parentid) const;
// returns the index of the currently transported primary
int getCurrentPrimaryIndex() const;
// Fill container with all parent ids for current track
// The resulting ids will be in strictly monotonously decreasing order
void fillParentIDs(std::vector<int>& ids) const;
private:
/// STL stack (FILO) used to handle the TParticles for tracking
/// stack entries refer to
std::stack<TParticle> mStack; //!
/// Array of TParticles (contains all TParticles put into or created
/// by the transport)
std::vector<o2::MCTrack> mParticles; //!
std::vector<int> mTransportedIDs; //! prim + sec trackIDs transported for "current" primary
std::vector<int> mIndexOfPrimaries; //! index of primaries in mParticles
std::vector<int> mTrackIDtoParticlesEntry; //! an O(1) mapping of trackID to the entry of mParticles
//! where this track is stored
/// the current TParticle object
TParticle mCurrentParticle;
// keep primary particles in its original form
// (mainly for the PopPrimaryParticleInterface
std::vector<TParticle> mPrimaryParticles;
/// vector of reducded tracks written to the output
std::vector<o2::MCTrack>* mTracks;
/// STL map from particle index to persistent track index
std::map<Int_t, Int_t> mIndexMap; //!
/// cache active O2 detectors
std::vector<o2::base::Detector*> mActiveDetectors; //!
/// Some indices and counters
Int_t mIndexOfCurrentTrack; //! Global index of current track
Int_t mNumberOfPrimaryParticles; //! Number of primary particles
Int_t mNumberOfEntriesInParticles; //! Number of entries in mParticles
Int_t mNumberOfEntriesInTracks; //! Number of entries in mTracks
Int_t mIndex; //! Used for merging
/// Variables defining the criteria for output selection
Bool_t mStoreMothers;
Bool_t mStoreSecondaries;
bool mPruneKinematics = false; // whether or not we filter the output kinematics
Int_t mMinHits;
Double32_t mEnergyCut;
// variables for the cleanup / filtering procedure
Int_t mCleanupCounter = 0; //!
Int_t mCleanupThreshold = 1; //! a cleanup is initiated every mCleanupThreshold primaries
Int_t mPrimariesDone = 0; //!
Int_t mTracksDone = 0; //! number of tracks already done
bool mIsG4Like = false; //! flag indicating if the stack is used in a manner done by Geant4
bool mIsExternalMode = false; // is stack an external factory or directly used inside simulation?
// storage for track references
std::vector<o2::TrackReference>* mTrackRefs = nullptr; //!
o2::dataformats::MCTruthContainer<o2::TrackReference>* mIndexedTrackRefs = nullptr; //!
/// Mark tracks for output using selection criteria
/// returns true if all available tracks are selected
/// returns false if some tracks are discarded
bool selectTracks();
Stack(const Stack&);
Stack& operator=(const Stack&);
/// function called after each primary
/// and all its secondaries where transported
/// this allows applying selection criteria at a much finer granularity
/// than done with FillTrackArray which is only called once per event
void finishCurrentPrimary();
/// Increment number of hits for an arbitrary track in a given detector
/// \param iDet Detector unique identifier
/// \param iTrack Track number
void addHit(int iDet, Int_t iTrack);
ClassDefOverride(Stack, 1)
};
inline void Stack::addTrackReference(const o2::TrackReference& ref) { mTrackRefs->push_back(ref); }
inline int Stack::getCurrentPrimaryIndex() const { return mPrimaryParticles.size() - 1 - mPrimariesDone; }
inline int Stack::getMotherTrackId(int trackid) const
{
const auto entryinParticles = mTrackIDtoParticlesEntry[trackid];
return mParticles[entryinParticles].getMotherTrackId();
}
inline bool Stack::isCurrentTrackDaughterOf(int parentid) const
{
// if parentid is current primary the answer is certainly yes
if (parentid == getCurrentPrimaryIndex()) {
return true;
}
// otherwise ...
return isTrackDaughterOf(mIndexOfCurrentTrack, parentid);
}
}
}
#endif