]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TGeant4/TG4StepManager.cxx
corrected copyNo in CurrentVol(Off)ID()
[u/mrichter/AliRoot.git] / TGeant4 / TG4StepManager.cxx
CommitLineData
2817d3e2 1// $Id$
2// Category: event
3//
4// See the class description in the header file.
5
6#include "TG4StepManager.h"
7#include "TG4GeometryManager.h"
8#include "TG4PhysicsManager.h"
9#include "TG4VSensitiveDetector.h"
10#include "TG4Globals.h"
11#include "TG3Units.h"
12
2817d3e2 13#include <G4SteppingManager.hh>
14#include <G4UserLimits.hh>
15#include <G4ParticleTable.hh>
16#include <G4UImanager.hh>
17#include <G4AffineTransform.hh>
f2510df1 18#include <G4TransportationManager.hh>
19#include <G4Navigator.hh>
2817d3e2 20
21#include <Randomize.hh>
22
23#include <TLorentzVector.h>
24
25TG4StepManager* TG4StepManager::fgInstance = 0;
26
27TG4StepManager::TG4StepManager()
f2510df1 28 : fTrack(0),
29 fStep(0),
30 fStepStatus(kNormalStep),
2817d3e2 31 fSteppingManager(0)
32{
33//
34 if (fgInstance) {
35 TG4Globals::Exception(
36 "TG4StepManager: attempt to create two instances of singleton.");
37 }
38
39 fgInstance = this;
40}
41
42TG4StepManager::TG4StepManager(const TG4StepManager& right) {
43//
44 TG4Globals::Exception(
45 "Attempt to copy TG4StepManager singleton.");
46}
47
48TG4StepManager::~TG4StepManager() {
49//
50}
51
52// operators
53
54TG4StepManager& TG4StepManager::operator=(const TG4StepManager& right)
55{
56 // check assignement to self
57 if (this == &right) return *this;
58
59 TG4Globals::Exception(
60 "Attempt to assign TG4StepManager singleton.");
61
62 return *this;
63}
64
65// private methods
66
f2510df1 67void TG4StepManager::CheckTrack() const
68{
69// Gives exception in case the track is not defined.
70// ---
71
72 if (!fTrack)
73 TG4Globals::Exception("TG4StepManager: Track is not defined.");
74}
75
76
77void TG4StepManager::CheckStep() const
78{
79// Gives exception in case the step is not defined.
80// ---
81
82 if (!fStep)
83 TG4Globals::Exception("TG4StepManager: Step is not defined.");
84}
85
86
87void TG4StepManager::CheckSteppingManager() const
88{
89// Gives exception in case the step is not defined.
90// ---
91
92 if (!fSteppingManager)
93 TG4Globals::Exception("TG4StepManager: Stepping manager is not defined.");
94}
95
96
2817d3e2 97void TG4StepManager::SetTLorentzVector(G4ThreeVector xyz, G4double t,
98 TLorentzVector& lv) const
99{
100// Fills TLorentzVector with G4ThreeVector and G4double.
101// ---
102
103 lv[0] = xyz.x();
104 lv[1] = xyz.y();
105 lv[2] = xyz.z();
106 lv[3] = t;
107}
108
f2510df1 109G4VPhysicalVolume* TG4StepManager::GetCurrentOffPhysicalVolume(G4int off) const
110{
111// Returns the physical volume of the off-th mother's
112// of the current volume.
113// ---
114
115 G4VPhysicalVolume* physVolume = GetCurrentPhysicalVolume();
116
117 G4VPhysicalVolume* mother = physVolume;
118 Int_t level = off;
119 while (level > 0) {
120 if (mother) mother = mother->GetMother();
121 level--;
122 }
123
124 if (!mother) {
125 G4String text = "TG4StepManager::CurrentVolOff: \n";
126 text = text + " Volume ";
127 text = text + physVolume->GetName();
128 text = text + " has not defined mother in the required level.";
129 TG4Globals::Warning(text);
130 }
131
132 return mother;
133}
134
135G4int TG4StepManager::GetVolumeID(G4VPhysicalVolume* physVolume) const
136{
137// Returns the sensitive detector ID of the specified
138// physical volume.
139// ---
140
141 // sensitive detector ID
142 G4VSensitiveDetector* sd
143 = physVolume->GetLogicalVolume()->GetSensitiveDetector();
144 if (sd) {
145 TG4VSensitiveDetector* tsd = dynamic_cast<TG4VSensitiveDetector*>(sd);
146 if (tsd)
147 return tsd->GetID();
148 else {
149 TG4Globals::Exception(
150 "TG4StepManager::GetVolumeID: Unknown sensitive detector type");
151 return 0;
152 }
153 }
154 else {
a6461796 155 G4String text = "TG4StepManager::GetVolumeID: \n";
f2510df1 156 text = text + " Volume " + physVolume->GetName();
157 text = text + " has not a sensitive detector.";
a6461796 158 //TG4Globals::Exception(text);
159 TG4Globals::Warning(text);
f2510df1 160 return 0;
161 }
162}
163
164
2817d3e2 165// public methods
166
167void TG4StepManager::StopTrack()
168{
169// Stops the current track and skips to the next.
170// ?? do we want to invoke rest processes?
171// ?? do we want to stop secondaries too?
172// possible "stop" track status from G4:
173// fStopButAlive, // Invoke active rest physics processes and
174// // and kill the current track afterward
175// fStopAndKill, // Kill the current track
176// fKillTrackAndSecondaries,
177// // Kill the current track and also associated
178// // secondaries.
179// ---
180
f2510df1 181 CheckTrack();
182
183 fTrack->SetTrackStatus(fStopAndKill);
184 // fTrack->SetTrackStatus(fStopButAlive);
185 // fTrack->SetTrackStatus(fKillTrackAndSecondaries);
2817d3e2 186}
187
188void TG4StepManager::StopEvent()
189{
190// Aborts the current event processing.
191// ---
192
f2510df1 193 CheckTrack();
194
195 fTrack->SetTrackStatus(fKillTrackAndSecondaries);
196 //StopTrack(); // cannot be used as it keeps secondaries
197 G4UImanager::GetUIpointer()->ApplyCommand("/event/abort");
198 G4UImanager::GetUIpointer()->ApplyCommand("/alStacking/clearStack");
2817d3e2 199}
200
201void TG4StepManager::Rndm(Float_t* array, const Int_t size) const
202{
203// Random numbers array of the specified size.
204// ---
205
5025108a 206 G4double* const kpDoubleArray = new G4double[size];
f2510df1 207 RandFlat::shootArray(size, kpDoubleArray);
2817d3e2 208 for (G4int i=0; i<size; i++) {
5025108a 209 array[i] = kpDoubleArray[i];
2817d3e2 210 }
5025108a 211 delete [] kpDoubleArray;
2817d3e2 212}
213
214void TG4StepManager::SetMaxStep(Float_t step)
215{
216// Maximum step allowed in the current logical volume.
217// The maximum value is kept for following tracks - is it ok ??
218// ---
219
f2510df1 220 // check this
221 G4LogicalVolume* curLogVolume
222 = GetCurrentPhysicalVolume()->GetLogicalVolume();
223 G4UserLimits* userLimits
224 = curLogVolume->GetUserLimits();
225 if (userLimits == 0) {
226 userLimits = new G4UserLimits(step);
227 curLogVolume->SetUserLimits(userLimits);
2817d3e2 228 }
f2510df1 229 else
230 userLimits->SetMaxAllowedStep(step);
2817d3e2 231}
232
233void TG4StepManager::SetMaxNStep(Int_t maxNofSteps)
234{
235// Not yet implemented.
236// ---
237
238 TG4Globals::Warning(
239 "TG4StepManager::SetMaxNStep(..) is not yet implemented.");
240}
241
5025108a 242void TG4StepManager::SetUserDecay(Int_t pdg)
2817d3e2 243{
244// Not yet implemented.
245// ---
246
247 TG4Globals::Exception(
248 "TG4StepManager::SetUserDecay(..) is not yet implemented.");
249}
250
f2510df1 251G4VPhysicalVolume* TG4StepManager::GetCurrentPhysicalVolume() const
252{
253// Returns the current physical volume.
254// According to fStepStatus the volume from track vertex,
255// pre step point or post step point is returned.
256// ---
257
258 G4VPhysicalVolume* physVolume;
259 if (fStepStatus == kNormalStep) {
260 CheckStep();
261 physVolume = fStep->GetPreStepPoint()->GetPhysicalVolume();
262 }
263 else if (fStepStatus == kBoundary) {
264 CheckStep();
265 physVolume = fStep->GetPostStepPoint()->GetPhysicalVolume();
266 }
267 else {
268 CheckTrack();
269 G4ThreeVector position = fTrack->GetPosition();
270 G4Navigator* navigator =
271 G4TransportationManager::GetTransportationManager()->
272 GetNavigatorForTracking();
273 physVolume
274 = navigator->LocateGlobalPointAndSetup(position);
275 }
276
277 return physVolume;
278}
279
2817d3e2 280Int_t TG4StepManager::CurrentVolID(Int_t& copyNo) const
281{
282// Returns the current sensitive detector ID
283// and the copy number of the current physical volume.
284// ---
285
f2510df1 286 G4VPhysicalVolume* physVolume = GetCurrentPhysicalVolume();
feb86ea5 287 copyNo = physVolume->GetCopyNo() + 1;
2817d3e2 288
f2510df1 289 // sensitive detector ID
290 return GetVolumeID(physVolume);
291}
2817d3e2 292
293Int_t TG4StepManager::CurrentVolOffID(Int_t off, Int_t& copyNo) const
294{
295// Returns the off-th mother's of the current volume
296// the sensitive detector ID and the copy number.
297// ---
298
299 if (off == 0) return CurrentVolID(copyNo);
300
f2510df1 301 G4VPhysicalVolume* mother = GetCurrentOffPhysicalVolume(off);
302
303 if (mother) {
feb86ea5 304 copyNo = mother->GetCopyNo() + 1;
f2510df1 305
306 // sensitive detector ID
307 return GetVolumeID(mother);
2817d3e2 308 }
f2510df1 309 else {
310 copyNo = 0;
311 return 0;
312 }
2817d3e2 313}
314
315const char* TG4StepManager::CurrentVolName() const
316{
317// Returns the current physical volume name.
318// ---
319
f2510df1 320 return GetCurrentPhysicalVolume()->GetName();
2817d3e2 321}
322
323const char* TG4StepManager::CurrentVolOffName(Int_t off) const
324{
325// Returns the off-th mother's physical volume name.
326// ---
327
f2510df1 328 if (off == 0) return CurrentVolName();
2817d3e2 329
f2510df1 330 G4VPhysicalVolume* mother = GetCurrentOffPhysicalVolume(off);
331
332 if (mother)
333 return mother->GetName();
334 else
2817d3e2 335 return 0;
2817d3e2 336}
337
338Int_t TG4StepManager::CurrentMaterial(Float_t &a, Float_t &z, Float_t &dens,
339 Float_t &radl, Float_t &absl) const
340{
341// Returns the parameters of the current material during transport
342// the return value is the number of elements in the mixture.
343// ---
344
f2510df1 345 G4VPhysicalVolume* physVolume = GetCurrentPhysicalVolume();
346
347 G4Material* material
348 = physVolume->GetLogicalVolume()->GetMaterial();
349
350 // this if may be redundant - check
351 if (material)
352 {
353 G4int nofElements = material->GetNumberOfElements();
354 TG4GeometryManager* pGeometryManager = TG4GeometryManager::Instance();
355 a = pGeometryManager->GetEffA(material);
356 z = pGeometryManager->GetEffZ(material);
2817d3e2 357
f2510df1 358 // density
359 dens = material->GetDensity();
360 dens /= TG3Units::MassDensity();
2817d3e2 361
f2510df1 362 // radiation length
363 radl = material->GetRadlen();
364 radl /= TG3Units::Length();
2817d3e2 365
f2510df1 366 absl = 0.; // this parameter is not defined in Geant4
367 return nofElements;
368 }
369 else {
370 TG4Globals::Exception(
371 "TG4StepManager::CurrentMaterial(..): material is not defined.");
2817d3e2 372 return 0;
373 }
374}
375
376void TG4StepManager::Gmtod(Float_t* xm, Float_t* xd, Int_t iflag)
377{
378// Transforms a position from the world reference frame
379// to the current volume reference frame.
380//
381// Geant3 desription:
382// ==================
383// Computes coordinates XD (in DRS)
384// from known coordinates XM in MRS
385// The local reference system can be initialized by
386// - the tracking routines and GMTOD used in GUSTEP
387// - a call to GMEDIA(XM,NUMED)
388// - a call to GLVOLU(NLEVEL,NAMES,NUMBER,IER)
389// (inverse routine is GDTOM)
390//
391// If IFLAG=1 convert coordinates
392// IFLAG=2 convert direction cosinus
393//
394// ---
395
f2510df1 396 CheckStep();
2817d3e2 397
f2510df1 398 G4ThreeVector theGlobalPoint(xm[0],xm[1],xm[2]);
399
400 //const G4NavigationHistory* history
401 // = fStep->GetPreStepPoint()->GetTouchable()->GetHistory();
402 G4AffineTransform affineTransform
403 = fStep->GetPreStepPoint()->GetTouchable()->GetHistory()
404 ->GetTopTransform();
405
406 G4ThreeVector theLocalPoint;
407 if(iflag == 1)
408 theLocalPoint = affineTransform.TransformPoint(theGlobalPoint);
409 else if ( iflag == 2)
410 theLocalPoint = affineTransform.TransformAxis(theGlobalPoint);
411 else
412 TG4Globals::Exception(
413 "TG4StepManager::Gmtod(..,iflag): iflag is not in 1..2");
2817d3e2 414
f2510df1 415 xd[0] = theLocalPoint.x();
416 xd[1] = theLocalPoint.y();
417 xd[2] = theLocalPoint.z();
2817d3e2 418
2817d3e2 419}
420
421void TG4StepManager::Gdtom(Float_t* xd, Float_t* xm, Int_t iflag)
422{
423// Transforms a position from the current volume reference frame
424// to the world reference frame.
425//
426// Geant3 desription:
427// ==================
428// Computes coordinates XM (Master Reference System
429// knowing the coordinates XD (Detector Ref System)
430// The local reference system can be initialized by
431// - the tracking routines and GDTOM used in GUSTEP
432// - a call to GSCMED(NLEVEL,NAMES,NUMBER)
433// (inverse routine is GMTOD)
434//
435// If IFLAG=1 convert coordinates
436// IFLAG=2 convert direction cosinus
437//
438// ---
439
f2510df1 440 CheckStep();
441
442 // check this
2817d3e2 443
f2510df1 444 G4ThreeVector theLocalPoint(xd[0],xd[1],xd[2]);
2817d3e2 445
f2510df1 446 G4AffineTransform affineTransform
447 = fStep->GetPreStepPoint()->GetTouchable()->GetHistory()
2817d3e2 448 ->GetTopTransform().Inverse();
449
f2510df1 450 G4ThreeVector theGlobalPoint;
451 if(iflag == 1)
452 theGlobalPoint = affineTransform.TransformPoint(theLocalPoint);
453 else if( iflag == 2)
454 theGlobalPoint = affineTransform.TransformAxis(theLocalPoint);
455 else
456 TG4Globals::Warning(
457 "TG4StepManager::Gdtom(...,iflag): iflag is not in 1..2");
458
459 xm[0] = theGlobalPoint.x();
460 xm[1] = theGlobalPoint.y();
461 xm[2] = theGlobalPoint.z();
2817d3e2 462}
463
464Float_t TG4StepManager::MaxStep() const
465{
466// Returns maximum step allowed in the current logical volume
467// by User Limits.
468// ---
469
f2510df1 470 // check this
471 G4LogicalVolume* curLogVolume
472 = GetCurrentPhysicalVolume()->GetLogicalVolume();
473 G4UserLimits* userLimits
474 = curLogVolume->GetUserLimits();
475
476 G4double maxStep;
477 if (userLimits == 0) {
478 G4String text = "User Limits are not defined for log volume ";
479 text = text + curLogVolume->GetName();
480 TG4Globals::Warning(text);
2acb5b6d 481 return FLT_MAX;
2817d3e2 482 }
f2510df1 483 else {
484 const G4Track& trackRef = *(fTrack);
485 maxStep = userLimits->GetMaxAllowedStep(trackRef);
486 maxStep /= TG3Units::Length();
487 return maxStep;
488 }
2817d3e2 489}
490
491Int_t TG4StepManager::GetMaxNStep() const
492{
493// Not yet implemented.
494// ---
495
496 TG4Globals::Warning(
497 "Method GetMaxNStep is not yet implemented in TG4StepManager.");
498 return 0;
499}
500
501void TG4StepManager::TrackPosition(TLorentzVector& position) const
502{
503// Current particle position (in the world reference frame)
504// and the local time since the current track is created
505// (position of the PostStepPoint).
506// ---
507
f2510df1 508 CheckTrack();
68f491b7 509
f2510df1 510 // get position
511 // check if this is == to PostStepPoint position !!
512 G4ThreeVector positionVector = fTrack->GetPosition();
513 positionVector *= 1./(TG3Units::Length());
2817d3e2 514
f2510df1 515 // local time
516 G4double time = fTrack->GetLocalTime();
517 time /= TG3Units::Time();
518
519 SetTLorentzVector(positionVector, time, position);
2817d3e2 520}
521
522Int_t TG4StepManager::GetMedium() const
523{
524// Returns the second index of the current material (corresponding to
525// G3 tracking medium index).
526// ---
527
f2510df1 528 // current material
529 G4Material* curMaterial
530 = GetCurrentPhysicalVolume()->GetLogicalVolume()->GetMaterial();
2817d3e2 531
f2510df1 532 // medium index
533 TG4GeometryManager* pGeometryManager = TG4GeometryManager::Instance();
534 return pGeometryManager->GetMediumId(curMaterial);
2817d3e2 535}
536
537void TG4StepManager::TrackMomentum(TLorentzVector& momentum) const
538{
539// Current particle "momentum" (px, py, pz, Etot).
540// ---
541
f2510df1 542 CheckTrack();
2817d3e2 543
f2510df1 544 G4ThreeVector momentumVector = fTrack->GetMomentum();
545 momentumVector *= 1./(TG3Units::Energy());
2817d3e2 546
f2510df1 547 G4double energy = fTrack->GetDynamicParticle()->GetTotalEnergy();
548 energy /= TG3Units::Energy();
549
550 SetTLorentzVector(momentumVector, energy, momentum);
2817d3e2 551}
552
553void TG4StepManager::TrackVertexPosition(TLorentzVector& position) const
554{
555// The vertex particle position (in the world reference frame)
556// and the local time since the current track is created.
557// ---
558
f2510df1 559 CheckTrack();
560
561 // position
562 G4ThreeVector positionVector = fTrack->GetVertexPosition();
563 positionVector *= 1./(TG3Units::Length());
2817d3e2 564
f2510df1 565 // local time
566 // to be checked
567 G4double time = fTrack->GetLocalTime();
568 time /= TG3Units::Time();
2817d3e2 569
f2510df1 570 SetTLorentzVector(positionVector, time, position);
2817d3e2 571}
572
573void TG4StepManager::TrackVertexMomentum(TLorentzVector& momentum) const
574{
575// The vertex particle "momentum" (px, py, pz, Ekin)
576// to do: change Ekin -> Etot
577// ---
578
f2510df1 579 CheckTrack();
580 G4ThreeVector momentumVector = fTrack->GetVertexMomentumDirection();
581 momentumVector *= 1./(TG3Units::Energy());
2817d3e2 582
f2510df1 583 G4double energy = fTrack->GetVertexKineticEnergy();
584 energy /= TG3Units::Energy();
2817d3e2 585
f2510df1 586 SetTLorentzVector(momentumVector, energy, momentum);
2817d3e2 587}
588
589Float_t TG4StepManager::TrackStep() const
590{
591// Returns the current step length.
592// ---
593
f2510df1 594 G4double length;
595 if (fStepStatus == kNormalStep) {
596 CheckStep();
597 length = fStep->GetStepLength();
598 length /= TG3Units::Length();
599 }
600 else
601 length = 0;
602
603 return length;
2817d3e2 604}
605
606Float_t TG4StepManager::TrackLength() const
607{
608// Returns the length of the current track from its origin.
609// ---
610
f2510df1 611 CheckTrack();
612
613 G4double length = fTrack->GetTrackLength();
614 length /= TG3Units::Length();
615 return length;
2817d3e2 616}
617
618Float_t TG4StepManager::TrackTime() const
619{
620// Returns the local time since the current track is created.
621// Comment:
622// in Geant4: there is also defined proper time as
623// the proper time of the dynamical particle of the current track.
624// ---
625
f2510df1 626 CheckTrack();
627
628 G4double time = fTrack->GetLocalTime();
629 time /= TG3Units::Time();
630 return time;
2817d3e2 631}
632
633Float_t TG4StepManager::Edep() const
634{
635// Returns total energy deposit in this step.
636// ---
637
f2510df1 638 G4double energyDeposit;
639 if (fStepStatus == kNormalStep) {
640 CheckStep();
641 energyDeposit = fStep->GetTotalEnergyDeposit();
642 energyDeposit /= TG3Units::Energy();
2817d3e2 643 }
f2510df1 644 else
645 energyDeposit = 0;
646
647 return energyDeposit;
2817d3e2 648}
649
650Int_t TG4StepManager::TrackPid() const
651{
652// Returns the current particle PDG encoding.
653// ---
654
f2510df1 655 CheckTrack();
2817d3e2 656
f2510df1 657 G4ParticleDefinition* particle
658 = fTrack->GetDynamicParticle()->GetDefinition();
659
660 // ask TG4PhysicsManager to get PDG encoding
661 // (in order to get PDG from extended TDatabasePDG
662 // in case the standard PDG code is not defined)
663 TG4PhysicsManager* pPhysicsManager = TG4PhysicsManager::Instance();
664 G4int pdgEncoding = pPhysicsManager->GetPDGEncodingFast(particle);
665
666 return pdgEncoding;
2817d3e2 667}
668
669Float_t TG4StepManager::TrackCharge() const
670{
671// Returns the current particle charge.
672// ---
673
f2510df1 674 CheckTrack();
675 G4double charge
676 = fTrack->GetDynamicParticle()->GetDefinition()
677 ->GetPDGCharge();
678 charge /= TG3Units::Charge();
679 return charge;
2817d3e2 680}
681
682Float_t TG4StepManager::TrackMass() const
683{
684// Returns current particle rest mass.
685// ---
686
f2510df1 687 CheckTrack();
688
689 G4double mass
690 = fTrack->GetDynamicParticle()->GetDefinition()
691 ->GetPDGMass();
692 mass /= TG3Units::Mass();
693 return mass;
2817d3e2 694}
695
696Float_t TG4StepManager::Etot() const
697{
698// Returns total energy of the current particle.
699// ---
700
f2510df1 701 CheckTrack();
702
703 G4double energy
704 = fTrack->GetDynamicParticle()->GetTotalEnergy();
705 energy /= TG3Units::Energy();
706 return energy;
2817d3e2 707}
708
709Bool_t TG4StepManager::IsTrackInside() const
710{
711// Returns true if particle does not cross geometrical boundary
f2510df1 712// and is not in vertex.
2817d3e2 713// ---
714
f2510df1 715 if (fStepStatus == kNormalStep && !(IsTrackExiting()) ) {
716 // track is always inside during a normal step
717 return true;
718 }
719
720 return false;
2817d3e2 721}
722
723Bool_t TG4StepManager::IsTrackEntering() const
724{
725// Returns true if particle cross a geometrical boundary
f2510df1 726// or is in vertex.
2817d3e2 727// ---
728
f2510df1 729 if (fStepStatus != kNormalStep) {
730 // track is entering during a vertex or boundary step
731 return true;
732 }
733
734 return false;
2817d3e2 735}
736
737Bool_t TG4StepManager::IsTrackExiting() const
738{
f2510df1 739// Returns true if particle cross a geometrical boundary.
2817d3e2 740// ---
741
f2510df1 742 if (fStepStatus == kNormalStep) {
743 CheckStep();
744
745 if (fStep->GetPostStepPoint()->GetStepStatus() == fGeomBoundary)
746 return true;
2817d3e2 747 }
f2510df1 748
749 return false;
2817d3e2 750}
751
752Bool_t TG4StepManager::IsTrackOut() const
753{
68f491b7 754// Returns true if particle cross the world boundary
2817d3e2 755// at post-step point.
756// ---
757
f2510df1 758 if (fStepStatus == kVertex) return false;
759
760 CheckStep();
761
762 // check
763 G4StepStatus status
764 = fStep->GetPostStepPoint()->GetStepStatus();
765 if (status == fWorldBoundary)
766 return true;
767 else
2817d3e2 768 return false;
2817d3e2 769}
770
771Bool_t TG4StepManager::IsTrackStop() const
772{
773// Returns true if particle has stopped
774// or has been killed, suspended or postponed to next event.
775//
776// Possible track status from G4:
777// fAlive, // Continue the tracking
778// fStopButAlive, // Invoke active rest physics processes and
779// // and kill the current track afterward
780// fStopAndKill, // Kill the current track
781// fKillTrackAndSecondaries,
782// // Kill the current track and also associated
783// // secondaries.
784// fSuspend, // Suspend the current track
785// fPostponeToNextEvent
786// // Postpones the tracking of thecurrent track
787// // to the next event.
788// ---
789
f2510df1 790 CheckTrack();
791
792 // check
793 G4TrackStatus status
794 = fTrack->GetTrackStatus();
795 if ((status == fStopAndKill) ||
796 (status == fKillTrackAndSecondaries) ||
797 (status == fSuspend) ||
798 (status == fPostponeToNextEvent)) {
799 return true;
2817d3e2 800 }
f2510df1 801 else
802 return false;
2817d3e2 803}
804
805Bool_t TG4StepManager::IsTrackDisappeared() const
806{
807// Returns true if particle has disappeared
808// (due to any physical process)
809// or has been killed, suspended or postponed to next event.
810// ---
811
f2510df1 812 CheckTrack();
813
814 // check
815 G4TrackStatus status
816 = fTrack->GetTrackStatus();
817 if ((status == fStopButAlive) ||
818 (status == fKillTrackAndSecondaries) ||
819 (status == fSuspend) ||
820 (status == fPostponeToNextEvent)) {
821 return true;
2817d3e2 822 }
f2510df1 823 else
824 return false;
2817d3e2 825}
826
827Bool_t TG4StepManager::IsTrackAlive() const
828{
829// Returns true if particle continues tracking.
830// ---
831
f2510df1 832 CheckTrack();
833
834 G4TrackStatus status
835 = fTrack->GetTrackStatus();
836 if (status == fAlive)
837 return true;
838 else
839 return false;
2817d3e2 840}
841
842Bool_t TG4StepManager::IsNewTrack() const
843{
844// Returns true when track performs the first step.
845// ---
846
f2510df1 847 if (fStepStatus == kVertex)
2817d3e2 848 return true;
849 else
850 return false;
851}
852
853Int_t TG4StepManager::NSecondaries() const
854{
855// Returns the number of secondary particles generated
856// in the current step.
857// ---
858
f2510df1 859 CheckSteppingManager();
2817d3e2 860
f2510df1 861 G4int nofSecondaries = 0;
862 nofSecondaries += fSteppingManager->GetfN2ndariesAtRestDoIt();
863 nofSecondaries += fSteppingManager->GetfN2ndariesAlongStepDoIt();
864 nofSecondaries += fSteppingManager->GetfN2ndariesPostStepDoIt();
865
866 return nofSecondaries;
2817d3e2 867}
868
869void TG4StepManager::GetSecondary(Int_t index, Int_t& particleId,
870 TLorentzVector& position, TLorentzVector& momentum)
871{
872// Fills the parameters (particle encoding, position, momentum)
873// of the generated secondary particle which is specified by index.
874// !! Check if indexing of secondaries is same !!
875// ---
876
f2510df1 877 CheckSteppingManager();
878
879 G4int nofSecondaries = NSecondaries();
880 G4TrackVector* secondaryTracks = fSteppingManager->GetSecondary();
881
882 if (secondaryTracks){
883 if (index < nofSecondaries) {
884
885 // the index of the first secondary of this step
886 G4int startIndex
887 = secondaryTracks->entries() - nofSecondaries;
888 // (the secondaryTracks vector contains secondaries
889 // produced by the track at previous steps, too)
890 G4Track* track
891 = (*secondaryTracks)[startIndex + index];
2817d3e2 892
f2510df1 893 // particle encoding
894 particleId
895 = track->GetDynamicParticle()->GetDefinition()->GetPDGEncoding();
2817d3e2 896
f2510df1 897 // position & time
898 G4ThreeVector positionVector = track->GetPosition();
899 positionVector *= 1./(TG3Units::Length());
900 G4double time = track->GetLocalTime();
901 time /= TG3Units::Time();
902 SetTLorentzVector(positionVector, time, position);
903
904 // momentum & energy
905 G4ThreeVector momentumVector = track->GetMomentum();
906 G4double energy = track->GetDynamicParticle()->GetTotalEnergy();
907 energy /= TG3Units::Energy();
908 SetTLorentzVector(momentumVector, energy, momentum);
2817d3e2 909 }
910 else {
911 TG4Globals::Exception(
f2510df1 912 "TG4StepManager::GetSecondary(): wrong secondary track index.");
2817d3e2 913 }
914 }
f2510df1 915 else {
916 TG4Globals::Exception(
917 "TG4StepManager::GetSecondary(): secondary tracks vector is empty");
2817d3e2 918 }
919}
920
921const char* TG4StepManager::ProdProcess() const
922{
923// Returns the name of the process that defined current step
924// (and may produce the secondary particles).
925// ---
926
f2510df1 927 CheckStep();
2817d3e2 928
f2510df1 929 const G4VProcess* curProcess
930 = fStep->GetPostStepPoint()->GetProcessDefinedStep();
931
932 G4String g4Name = curProcess->GetProcessName();
933 return g4Name;
2817d3e2 934}