Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TMCManagerStack.cxx
Go to the documentation of this file.
1 // @(#)root/vmc:$Id$
2 // Authors: Benedikt Volkel 07/03/2019
3 
4 /*************************************************************************
5  * Copyright (C) 2019, Rene Brun and Fons Rademakers. *
6  * Copyright (C) 2019, ALICE Experiment at CERN. *
7  * All rights reserved. *
8  * *
9  * For the licensing terms see $ROOTSYS/LICENSE. *
10  * For the list of contributors see $ROOTSYS/README/CREDITS. *
11  *************************************************************************/
12 
13 #include "TError.h"
14 #include "TParticle.h"
15 #include "TGeoBranchArray.h"
17 #include "TMCParticleStatus.h"
18 #include "TMCManagerStack.h"
19 
20 /** \class TMCManagerStack
21  \ingroup vmc
22 
23 Concrete implementation of particles stack used by the TMCManager.
24 */
25 
26 ////////////////////////////////////////////////////////////////////////////////
27 ///
28 /// Default constructor
29 ///
30 
31 TMCManagerStack::TMCManagerStack()
32  : TVirtualMCStack(), fCurrentTrackId(-1), fUserStack(nullptr), fTotalNPrimaries(nullptr), fTotalNTracks(nullptr),
33  fParticles(nullptr), fParticlesStatus(nullptr), fBranchArrayContainer(nullptr)
34 {
35 }
36 
37 ////////////////////////////////////////////////////////////////////////////////
38 ///
39 /// This will just forward the call to the fUserStack's PushTrack
40 ///
41 
42 void TMCManagerStack::PushTrack(Int_t toBeDone, Int_t parent, Int_t pdg, Double_t px, Double_t py, Double_t pz,
43  Double_t e, Double_t vx, Double_t vy, Double_t vz, Double_t tof, Double_t polx,
44  Double_t poly, Double_t polz, TMCProcess mech, Int_t &ntr, Double_t weight, Int_t is)
45 {
46  // Just forward to user stack
47  fUserStack->PushTrack(toBeDone, parent, pdg, px, py, pz, e, vx, vy, vz, tof, polx, poly, polz, mech, ntr, weight,
48  is);
49 }
50 
51 ////////////////////////////////////////////////////////////////////////////////
52 ///
53 /// Pop next track
54 ///
55 
56 TParticle *TMCManagerStack::PopNextTrack(Int_t &itrack)
57 {
58 
59  if (fPrimariesStack.empty() && fSecondariesStack.empty()) {
60  itrack = -1;
61  return nullptr;
62  }
63 
64  std::stack<Int_t> *mcStack = &fPrimariesStack;
65 
66  if (fPrimariesStack.empty()) {
67  mcStack = &fSecondariesStack;
68  }
69  itrack = mcStack->top();
70  mcStack->pop();
71  return fParticles->operator[](itrack);
72 }
73 
74 ////////////////////////////////////////////////////////////////////////////////
75 ///
76 /// Pop i'th primary; that does not mean that this primariy has ID==i
77 ///
78 
79 TParticle *TMCManagerStack::PopPrimaryForTracking(Int_t i)
80 {
81  Int_t itrack = -1;
82  return PopPrimaryForTracking(i, itrack);
83 }
84 
85 ////////////////////////////////////////////////////////////////////////////////
86 ///
87 /// Pop i'th primary; that does not mean that this primariy has ID==i.
88 /// including actual index
89 ///
90 
91 TParticle *TMCManagerStack::PopPrimaryForTracking(Int_t i, Int_t &itrack)
92 {
93  // Completely ignore the index i, that is meaningless since the user does not
94  // know how the stack is handled internally.
95  Warning("PopPrimaryForTracking", "Lookup index %i is ignored.", i);
96  if (fPrimariesStack.empty()) {
97  itrack = -1;
98  return nullptr;
99  }
100  itrack = fPrimariesStack.top();
101  fPrimariesStack.pop();
102  return fParticles->operator[](itrack);
103 }
104 
105 ////////////////////////////////////////////////////////////////////////////////
106 ///
107 /// Get number of tracks on current sub-stack
108 ///
109 
110 Int_t TMCManagerStack::GetNtrack() const
111 {
112  return *fTotalNTracks;
113 }
114 
115 ////////////////////////////////////////////////////////////////////////////////
116 ///
117 /// Get only the number of currently stacked tracks
118 ///
119 
120 Int_t TMCManagerStack::GetStackedNtrack() const
121 {
122  return fPrimariesStack.size() + fSecondariesStack.size();
123 }
124 
125 ////////////////////////////////////////////////////////////////////////////////
126 ///
127 /// Get number of primaries on current sub-stack
128 ///
129 
130 Int_t TMCManagerStack::GetNprimary() const
131 {
132  return *fTotalNPrimaries;
133 }
134 
135 ////////////////////////////////////////////////////////////////////////////////
136 ///
137 /// Get number of primaries on current sub-stack
138 ///
139 
140 Int_t TMCManagerStack::GetStackedNprimary() const
141 {
142  return fPrimariesStack.size();
143 }
144 
145 ////////////////////////////////////////////////////////////////////////////////
146 ///
147 /// Current track
148 ///
149 
150 TParticle *TMCManagerStack::GetCurrentTrack() const
151 {
152  if (fCurrentTrackId < 0) {
153  Fatal("GetCurrentTrack", "There is no current track set");
154  }
155  // That is not actually the current track but the user's TParticle at the
156  // vertex.
157  return fParticles->operator[](fCurrentTrackId);
158 }
159 
160 ////////////////////////////////////////////////////////////////////////////////
161 ///
162 /// Current track number
163 ///
164 
165 Int_t TMCManagerStack::GetCurrentTrackNumber() const
166 {
167  return fCurrentTrackId;
168 }
169 
170 ////////////////////////////////////////////////////////////////////////////////
171 ///
172 /// Number of the parent of the current track
173 ///
174 
175 Int_t TMCManagerStack::GetCurrentParentTrackNumber() const
176 {
177  return fParticlesStatus->operator[](fCurrentTrackId)->fParentId;
178 }
179 
180 ////////////////////////////////////////////////////////////////////////////////
181 ///
182 /// Set the current track id from the outside and forward this to the
183 /// user's stack
184 ///
185 
186 void TMCManagerStack::SetCurrentTrack(Int_t trackId)
187 {
188  if (!HasTrackId(trackId)) {
189  Fatal("SetCurrentTrack", "Invalid track ID %i", trackId);
190  }
191  fCurrentTrackId = trackId;
192  fUserStack->SetCurrentTrack(trackId);
193 }
194 
195 ////////////////////////////////////////////////////////////////////////////////
196 ///
197 /// Get TMCParticleStatus by trackId
198 ///
199 
200 const TMCParticleStatus *TMCManagerStack::GetParticleStatus(Int_t trackId) const
201 {
202  if (!HasTrackId(trackId)) {
203  Fatal("GetParticleStatus", "Invalid track ID %i", trackId);
204  }
205  return fParticlesStatus->operator[](trackId).get();
206 }
207 
208 ////////////////////////////////////////////////////////////////////////////////
209 ///
210 /// Get particle's geometry status by trackId
211 ///
212 
213 const TGeoBranchArray *TMCManagerStack::GetGeoState(Int_t trackId) const
214 {
215  if (!HasTrackId(trackId)) {
216  Fatal("GetParticleStatus", "Invalid track ID %i", trackId);
217  }
218  return fBranchArrayContainer->GetGeoState(fParticlesStatus->operator[](trackId)->fGeoStateIndex);
219 }
220 
221 ////////////////////////////////////////////////////////////////////////////////
222 ///
223 /// Get current particle's geometry status
224 ///
225 
226 const TGeoBranchArray *TMCManagerStack::GetCurrentGeoState() const
227 {
228  return fBranchArrayContainer->GetGeoState(fParticlesStatus->operator[](fCurrentTrackId)->fGeoStateIndex);
229 }
230 
231 ////////////////////////////////////////////////////////////////////////////////
232 ///
233 /// Check whether track trackId exists
234 ///
235 
236 Bool_t TMCManagerStack::HasTrackId(Int_t trackId) const
237 {
238  if (trackId >= 0 && trackId < static_cast<Int_t>(fParticles->size()) && fParticles->operator[](trackId)) {
239  return kTRUE;
240  }
241  return kFALSE;
242 }
243 
244 ////////////////////////////////////////////////////////////////////////////////
245 ///
246 /// Set the user stack
247 ///
248 
249 void TMCManagerStack::SetUserStack(TVirtualMCStack *stack)
250 {
251  fUserStack = stack;
252 }
253 
254 ////////////////////////////////////////////////////////////////////////////////
255 ///
256 /// Connect an engine's stack to the centrally managed vectors
257 ///
258 
259 void TMCManagerStack::ConnectTrackContainers(std::vector<TParticle *> *particles,
260  std::vector<std::unique_ptr<TMCParticleStatus>> *tracksStatus,
261  TGeoMCBranchArrayContainer *branchArrayContainer, Int_t *totalNPrimaries,
262  Int_t *totalNTracks)
263 {
264  fParticles = particles;
265  fParticlesStatus = tracksStatus;
266  fBranchArrayContainer = branchArrayContainer;
267  fTotalNPrimaries = totalNPrimaries;
268  fTotalNTracks = totalNTracks;
269 }
270 
271 ////////////////////////////////////////////////////////////////////////////////
272 ///
273 /// Push primary track id to be processed
274 ///
275 
276 void TMCManagerStack::PushPrimaryTrackId(Int_t trackId)
277 {
278  fPrimariesStack.push(trackId);
279 }
280 
281 ////////////////////////////////////////////////////////////////////////////////
282 ///
283 /// Push secondary track id to be processed
284 ///
285 
286 void TMCManagerStack::PushSecondaryTrackId(Int_t trackId)
287 {
288  fSecondariesStack.push(trackId);
289 }
290 
291 ////////////////////////////////////////////////////////////////////////////////
292 ///
293 /// Reset internals, clear engine stack and fParticles and reset buffered values
294 ///
295 
296 void TMCManagerStack::ResetInternals()
297 {
298  // Reset current stack and track IDs
299  fCurrentTrackId = -1;
300  while (!fPrimariesStack.empty()) {
301  fPrimariesStack.pop();
302  }
303  while (!fSecondariesStack.empty()) {
304  fSecondariesStack.pop();
305  }
306 }