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