Geant4 VMC Version 6.6
Loading...
Searching...
No Matches
TG4TrackManager.cxx
Go to the documentation of this file.
1//------------------------------------------------
2// The Geant4 Virtual Monte Carlo package
3// Copyright (C) 2007 - 2014 Ivana Hrivnacova
4// All rights reserved.
5//
6// For the licensing terms see geant4_vmc/LICENSE.
7// Contact: root-vmc@cern.ch
8//-------------------------------------------------
9
14
15#include "TG4TrackManager.h"
16#include "TG4G3Units.h"
17#include "TG4Globals.h"
18#include "TG4ParticlesManager.h"
19#include "TG4PhysicsManager.h"
20#include "TG4SDServices.h"
22#include "TG4StackPopper.h"
23#include "TG4StepManager.h"
24#include "TG4TrackInformation.h"
25
26#ifdef USE_G4ROOT
27#include <TMCManager.h>
28#endif
29
30#include <TMCManagerStack.h>
31#include <TMCParticleStatus.h>
32#include <TVirtualMC.h>
33#include <TVirtualMCApplication.h>
34
35#include <G4PrimaryParticle.hh>
36#include <G4PrimaryVertex.hh>
37#include <G4SystemOfUnits.hh>
38#include <G4TrackVector.hh>
39#include <G4TrackingManager.hh>
40#include <G4UImanager.hh>
41
42// static data members
44
45//_____________________________________________________________________________
47 : TG4Verbose("trackManager"),
48 fG4TrackingManager(0),
49 fTrackSaveControl(kSaveInPreTrack),
50 fMCStack(0),
51 fMCManagerStack(0),
52 fStackPopper(0),
53 fSaveDynamicCharge(false),
54 fTrackCounter(0),
55 fCurrentTrackID(0),
56 fNofSavedSecondaries(0)
57#ifdef USE_G4ROOT
58 // - TG4RootNavMgr is instantiated (cloned for worker) during construction
59 // of TG4RunManager
60 // - TG4RunManager obtains its G4RunManager during construction
61 // - TG4ActionInitialization is passed to G4RunManager and used to construct
62 // - TG4TrackingAction instantiates TG4TrackManager
63 // ==> At this point the (thread-local) TG4RootNavMgr exists if geometry is
64 // built via ROOT
65 ,
66 fRootNavMgr(TG4RootNavMgr::GetInstance()),
67 fMCManager(TMCManager::Instance())
68#endif
69{
71
72 if (fgInstance) {
73 TG4Globals::Exception("TG4TrackManager", "TG4TrackManager",
74 "Cannot create two instances of singleton.");
75 }
76
77 fgInstance = this;
78}
79
80//_____________________________________________________________________________
87
88//
89// public methods
90//
91
92//_____________________________________________________________________________
94{
96
98
99#if (defined(USE_G4ROOT) && (!defined(USE_ROOT_VMC) || \
100 (ROOT_VERSION_CODE >= ROOT_VERSION(6, 18, 6))))
101 // Set recovery lambda
102 if (fMCManager && fRootNavMgr) {
103 fRootNavMgr->SetGeometryRestoreFunction([this](Int_t g4TrackId) -> Bool_t {
104 return fMCManager->RestoreGeometryState(
105 fPrimaryParticleIds[g4TrackId - 1]);
106 });
107 }
108#endif
109}
110
111//_____________________________________________________________________________
113{
117
118 fPrimaryParticleIds.push_back(id);
119}
120
121//_____________________________________________________________________________
122void TG4TrackManager::AddParticleStatus(const TMCParticleStatus* particleStatus)
123{
126 fPrimaryParticleIds.push_back(particleStatus->fId);
127 fParticlesStatus.push_back((TMCParticleStatus*)particleStatus);
128}
129
130//_____________________________________________________________________________
132 const G4Track* track, G4bool overWrite)
133{
136
137#ifdef MCDEBUG
138 if (!fG4TrackingManager) {
139 TG4Globals::Exception("TG4TrackManager", "SetParentToTrackInformation",
140 "G4TrackingManager has not been set.");
141 return 0;
142 }
143#endif
144
145 TG4TrackInformation* trackInfo = GetTrackInformation(track);
146
147 if (!trackInfo) {
148 // create track information and set it to G4Track
149 // if it does not yet exist
150 trackInfo = new TG4TrackInformation();
151 fG4TrackingManager->SetUserTrackInformation(trackInfo);
152 // the track information is deleted together with its
153 // G4Track object
154 }
155
156 // track index in the particles array
157 Int_t trackIndex = trackInfo->GetTrackParticleID();
158 if (trackIndex < 0) {
159 // Do not reset particle ID if it is already set
160 G4int trackID = track->GetTrackID();
161 G4int parentID = track->GetParentID();
162 if (parentID == 0) {
163 // in VMC track numbering starts from 0
164 // trackIndex = trackID-1;
165 trackIndex = fPrimaryParticleIds[trackID - 1];
166
167 // Set the initial status e.g. in case the track was transported to the
168 // current point before by another engine
169 // Double check whether there is a valid status
170 if (trackID <= static_cast<Int_t>(fParticlesStatus.size()) &&
171 fParticlesStatus[trackID - 1]) {
172 trackInfo->SetInitialTrackStatus(fParticlesStatus[trackID - 1]);
173 trackInfo->SetParentParticleID(
174 fParticlesStatus[trackID - 1]->fParentId);
175 }
176 }
177 else {
179 // Comment bz Benedikt Volkel
180 // The track has not been pushed to the VMC stack yet. However, the
181 // assumption is made that this track will get the ID
182 // fMCStack->GetNtrack() + 1 although nothing is known about the
183 // track labeling done by the user implementation of VMC stack. If
184 // this was called from TG4TrackingAction::PreUserTrackingAction()
185 // the VMC track ID in the corresponding TG4TrackInformation
186 // will be overwritten by TG4TrackManager::TrackToStack() giving it
187 // the true VMC track ID.
188 trackIndex = fMCStack->GetNtrack();
189 if (overWrite) trackIndex--;
190 }
191 else
192 trackIndex = fTrackCounter;
193 // if secondaries are not stacked in VMC stack
194 // use own counter for setting track index
195 }
196 if (VerboseLevel() > 1)
197 G4cout << "TG4TrackManager::SetTrackInformation: setting " << trackIndex
198 << G4endl;
199
200 trackInfo->SetTrackParticleID(trackIndex);
201 }
202
203 // set current track number
204 // fMCStack->SetCurrentTrack(trackIndex);
206
207 return trackInfo;
208}
209
210//_____________________________________________________________________________
212{
214
215#ifdef MCDEBUG
216 if (!fG4TrackingManager) {
217 TG4Globals::Exception("TG4TrackManager", "SetParentToTrackInformation",
218 "G4TrackingManager has not been set.");
219 return;
220 }
221#endif
222
223 const G4TrackVector* secondaryTracks =
224 fG4TrackingManager->GetSteppingManager()->GetSecondary();
225
226 if (!secondaryTracks) return;
227
228 for (G4int i = fNofSavedSecondaries; i < G4int(secondaryTracks->size());
229 i++) {
230 G4Track* secondary = (*secondaryTracks)[i];
231
232 // get parent track index
233 TG4TrackInformation* parentInfo = GetTrackInformation(track);
234#ifdef MCDEBUG
235 if (!parentInfo) {
236 TG4Globals::Exception("TG4TrackManager", "SetParentToTrackInformation",
237 "Parent track has no TG4TrackInformation set.");
238 return;
239 }
240#endif
241 G4int parentParticleID = parentInfo->GetTrackParticleID();
242
243 // get or create track information and set it to the G4Track
244 TG4TrackInformation* trackInfo = GetTrackInformation(secondary);
245 if (!trackInfo) {
246 trackInfo = new TG4TrackInformation(-1);
247 // G4cout << "TG4TrackManager::SetParentToTrackInformation: new trackInfo"
248 // << trackInfo << G4endl;
249 // the track information is deleted together with its
250 // G4Track object
251 }
252 trackInfo->SetParentParticleID(parentParticleID);
253 secondary->SetUserInformation(trackInfo);
254 }
255}
256
257//_____________________________________________________________________________
258void TG4TrackManager::SetBackPDGLifetime(const G4Track* aTrack)
259{
262
263 TG4TrackInformation* trackInfo = GetTrackInformation(aTrack);
264 if (trackInfo->GetPDGLifetime() > 0.0) {
265
266 G4ParticleDefinition* particle =
267 aTrack->GetDynamicParticle()->GetDefinition();
268 particle->SetPDGLifeTime(trackInfo->GetPDGLifetime());
269 }
270}
271
272#ifdef STACK_WITH_KEEP_FLAG
273//_____________________________________________________________________________
274void TG4TrackManager::TrackToStack(const G4Track* track, G4bool overWrite)
275#else
276//_____________________________________________________________________________
277void TG4TrackManager::TrackToStack(const G4Track* track, G4bool /*overWrite*/)
278#endif
279{
282
283 if (VerboseLevel() > 2) G4cout << "TG4TrackManager::TrackToStack" << G4endl;
284
285 // parent particle index
286 G4int parentID = track->GetParentID();
287 G4int motherIndex;
288 if (parentID == 0) {
289 motherIndex = -1;
290 }
291 else {
292 motherIndex = GetTrackInformation(track)->GetParentParticleID();
293 }
294
295 // PDG code
296 G4int pdg =
297 TG4ParticlesManager::Instance()->GetPDGEncoding(track->GetDefinition());
298
299 // track kinematics
300 G4ThreeVector momentum = track->GetMomentum();
301 momentum *= 1. / (TG4G3Units::Energy());
302
303 G4double px = momentum.x();
304 G4double py = momentum.y();
305 G4double pz = momentum.z();
306 G4double e = track->GetTotalEnergy() * TG4G3Units::InverseEnergy();
307
308 G4ThreeVector position = track->GetPosition();
309 position *= 1. / (TG4G3Units::Length());
310 G4double vx = position.x();
311 G4double vy = position.y();
312 G4double vz = position.z();
313 G4double t = track->GetGlobalTime() * TG4G3Units::InverseTime();
314
315 G4ThreeVector polarization = track->GetPolarization();
316 G4double polX = polarization.x();
317 G4double polY = polarization.y();
318 G4double polZ = polarization.z();
319
320 // production process
321 TMCProcess mcProcess;
322 const G4VProcess* kpProcess = track->GetCreatorProcess();
323 if (!kpProcess) {
324 mcProcess = kPPrimary;
325 }
326 else {
327 mcProcess = TG4PhysicsManager::Instance()->GetMCProcess(kpProcess);
328 // distinguish kPDeltaRay from kPEnergyLoss
329 if (mcProcess == kPEnergyLoss) mcProcess = kPDeltaRay;
330 }
331
332 G4double weight = track->GetWeight();
333
334 G4int status = 0;
335 if (fSaveDynamicCharge) {
336 // Store the dynamic particle charge (which in case of ion may
337 // be different from PDG charge) as status as there is no other
338 // place where we can do it
339 status = G4int(track->GetDynamicParticle()->GetCharge() / eplus);
340 }
341
342 G4int ntr;
343#ifdef STACK_WITH_KEEP_FLAG
344 // create particle
345 fMCStack->PushTrack(0, motherIndex, pdg, px, py, pz, e, vx, vy, vz, t, polX,
346 polY, polZ, mcProcess, ntr, weight, status, overWrite);
347 // Experimental code with flagging tracks in stack for overwrite;
348 // not yet available in distribution
349#else
350 fMCStack->PushTrack(0, motherIndex, pdg, px, py, pz, e, vx, vy, vz, t, polX,
351 polY, polZ, mcProcess, ntr, weight, status);
352#endif
353 // Explicitly set the VMC particle Id in the track info hence not relying
354 // on a certain indexing on the user VMC stack
355 GetTrackInformation(track)->SetTrackParticleID(ntr);
356}
357
358//_____________________________________________________________________________
360 const G4PrimaryVertex* vertex, const G4PrimaryParticle* particle)
361{
363
364 // Mother particle index
365 G4int motherIndex = -1;
366
367 // PDG code
368 G4int pdg =
369 TG4ParticlesManager::Instance()->GetPDGEncoding(particle->GetG4code());
370
371 // track kinematics
372 G4ThreeVector momentum = particle->GetMomentum();
373 momentum *= 1. / (TG4G3Units::Energy());
374 G4double px = momentum.x();
375 G4double py = momentum.y();
376 G4double pz = momentum.z();
377 G4double mass = particle->GetMass();
378 G4double e = sqrt(momentum.mag() * momentum.mag() + mass * mass);
379 e /= (TG4G3Units::Energy());
380
381 G4ThreeVector position = vertex->GetPosition();
382 position *= 1. / (TG4G3Units::Length());
383 G4double vx = position.x();
384 G4double vy = position.y();
385 G4double vz = position.z();
386 G4double t = vertex->GetT0() * TG4G3Units::InverseTime();
387 ;
388
389 G4ThreeVector polarization = particle->GetPolarization();
390 G4double polX = polarization.x();
391 G4double polY = polarization.y();
392 G4double polZ = polarization.z();
393
394 // production process
395 TMCProcess mcProcess = kPPrimary;
396
397 G4double weight = particle->GetWeight();
398
399 G4int status = 1;
400 if (fSaveDynamicCharge) {
401 // Store the dynamic particle charge (which in case of ion may
402 // be different from PDG charge) as status as there is no other
403 // place where we can do it
404 status = G4int(particle->GetCharge() / eplus);
405 }
406
407 G4int ntr;
408 // create particle
409 fMCStack->PushTrack(1, motherIndex, pdg, px, py, pz, e, vx, vy, vz, t, polX,
410 polY, polZ, mcProcess, ntr, weight, status);
411}
412
413//_____________________________________________________________________________
415 const G4Track* track, const G4TrackVector* secondaries)
416{
418
419 if (track->GetTrackID() != fCurrentTrackID) {
420 fCurrentTrackID = track->GetTrackID();
422 }
423
424 // Store parent track Id
426
427 for (G4int i = fNofSavedSecondaries; i < G4int(secondaries->size()); ++i) {
428
429 G4Track* secondary = (*secondaries)[i];
430
431 // G4cout << i << "th secondary to be saved: "
432 // << secondary->GetDefinition()->GetParticleName()
433 // << G4endl;
434
435 if (GetTrackInformation(secondary) &&
436 GetTrackInformation(secondary)->IsUserTrack())
437 return;
438
439 // Set track Id
440 SetTrackInformation(secondary);
441
442 // Save track in stack
443 TrackToStack(secondary);
444
445 // Notify a stack popper (if activated) about saving this secondary
448 }
449}
450
451//_____________________________________________________________________________
458
459//_____________________________________________________________________________
466
467//_____________________________________________________________________________
469 const G4Track* track) const
470{
472
473#ifdef MCDEBUG
474 G4VUserTrackInformation* trackInfo = track->GetUserInformation();
475 if (!trackInfo) return 0;
476
477 // TG4TrackInformation* tg4TrackInfo
478 // = dynamic_cast<TG4TrackInformation*>(trackInfo);
479 TG4TrackInformation* tg4TrackInfo =
480 static_cast<TG4TrackInformation*>(trackInfo);
481 if (!tg4TrackInfo) {
482 TG4Globals::Exception("TG4TrackManager", "GetTrackInformation",
483 "Unknown track information type");
484 }
485
486 return tg4TrackInfo;
487#else
488 return (TG4TrackInformation*)track->GetUserInformation();
489#endif
490}
491
492//_____________________________________________________________________________
493G4bool TG4TrackManager::IsUserTrack(const G4Track* track) const
494{
496
497 return GetTrackInformation(track) != 0x0 &&
499}
Definition of the TG4G3Units class.
Definition of the TG4Globals class and basic container types.
Definition of the TG4ParticlesManager class.
Definition of the TG4PhysicsManager class.
Definition of the TG4SDServices class.
Definition of the TG4SensitiveDetector class.
Definition of the TG4StackPopper class.
Definition of the TG4StepManager class.
Definition of the TG4TrackInformation class.
Definition of the TG4TrackManager class.
static G4double Energy()
Definition TG4G3Units.h:105
static G4double Length()
Definition TG4G3Units.h:81
static G4double InverseTime()
Definition TG4G3Units.h:145
static G4double InverseEnergy()
Definition TG4G3Units.h:157
static void Exception(const TString &className, const TString &methodName, const TString &text)
G4int GetPDGEncoding(G4ParticleDefinition *particle)
static TG4ParticlesManager * Instance()
static TG4PhysicsManager * Instance()
TMCProcess GetMCProcess(const G4VProcess *process)
static TG4StackPopper * Instance()
Defines additional track information.
void SetParentParticleID(G4int parentParticleID)
G4bool IsUserTrack() const
G4int GetTrackParticleID() const
G4double GetPDGLifetime() const
void SetInitialTrackStatus(TMCParticleStatus *status)
void SetTrackParticleID(G4int trackParticleID)
The class for storing G4 tracks in VMC sack.
void SaveSecondaries(const G4Track *track, const G4TrackVector *secondaries)
G4int fTrackCounter
tracks counter
G4int fCurrentTrackID
current track ID
void AddParticleStatus(const TMCParticleStatus *particleStatus)
G4TrackingManager * fG4TrackingManager
G4 tracking manager.
TG4StackPopper * fStackPopper
Cached pointer to thread-local stack popper.
TVirtualMCStack * fMCStack
Cached pointer to thread-local VMC stack.
void SetBackPDGLifetime(const G4Track *aTrack)
TG4TrackInformation * GetTrackInformation(const G4Track *track) const
virtual ~TG4TrackManager()
void SetParentToTrackInformation(const G4Track *aTrack)
std::vector< G4int > fPrimaryParticleIds
G4bool IsUserTrack(const G4Track *track) const
void TrackToStack(const G4Track *track, G4bool overWrite=false)
static G4ThreadLocal TG4TrackManager * fgInstance
this instance
std::vector< TMCParticleStatus * > fParticlesStatus
TG4TrackSaveControl fTrackSaveControl
control of saving secondaries
void AddPrimaryParticleId(G4int id)
void PrimaryToStack(const G4PrimaryVertex *vertex, const G4PrimaryParticle *particle)
TG4TrackInformation * SetTrackInformation(const G4Track *aTrack, G4bool overWrite=false)
G4int fNofSavedSecondaries
number of secondaries already saved
Base class for defining the verbose level and a common messenger.
Definition TG4Verbose.h:36
virtual G4int VerboseLevel() const
Definition TG4Verbose.h:78
@ kSaveInPreTrack
save in pre-track
@ kDoNotSave
do not save
@ fStackPopper