4 // See the class description in the header file.
6 #include "TG4StepManager.h"
7 #include "TG4GeometryManager.h"
8 #include "TG4PhysicsManager.h"
9 #include "TG4VSensitiveDetector.h"
10 #include "TG4Globals.h"
14 #include <G4SteppingManager.hh>
15 #include <G4UserLimits.hh>
16 #include <G4ParticleTable.hh>
17 #include <G4UImanager.hh>
18 #include <G4AffineTransform.hh>
19 //#include <G4TransportationManager.hh>
20 //#include <G4Navigator.hh>
22 #include <Randomize.hh>
24 #include <TLorentzVector.h>
26 TG4StepManager* TG4StepManager::fgInstance = 0;
28 TG4StepManager::TG4StepManager()
30 fStepStatus(kPreStepPoint),
35 TG4Globals::Exception(
36 "TG4StepManager: attempt to create two instances of singleton.");
42 TG4StepManager::TG4StepManager(const TG4StepManager& right) {
44 TG4Globals::Exception(
45 "Attempt to copy TG4StepManager singleton.");
48 TG4StepManager::~TG4StepManager() {
54 TG4StepManager& TG4StepManager::operator=(const TG4StepManager& right)
56 // check assignement to self
57 if (this == &right) return *this;
59 TG4Globals::Exception(
60 "Attempt to assign TG4StepManager singleton.");
67 void TG4StepManager::SetTLorentzVector(G4ThreeVector xyz, G4double t,
68 TLorentzVector& lv) const
70 // Fills TLorentzVector with G4ThreeVector and G4double.
81 void TG4StepManager::StopTrack()
83 // Stops the current track and skips to the next.
84 // ?? do we want to invoke rest processes?
85 // ?? do we want to stop secondaries too?
86 // possible "stop" track status from G4:
87 // fStopButAlive, // Invoke active rest physics processes and
88 // // and kill the current track afterward
89 // fStopAndKill, // Kill the current track
90 // fKillTrackAndSecondaries,
91 // // Kill the current track and also associated
97 fStep->GetTrack()->SetTrackStatus(fStopAndKill);
98 // fStep->GetTrack()->SetTrackStatus(fStopButAlive);
99 // fStep->GetTrack()->SetTrackStatus(fKillTrackAndSecondaries);
102 TG4Globals::Exception("TG4StepManager: Step is not defined.");
106 void TG4StepManager::StopEvent()
108 // Aborts the current event processing.
112 fStep->GetTrack()->SetTrackStatus(fKillTrackAndSecondaries);
113 //StopTrack(); // cannot be used as it keeps secondaries
114 G4UImanager::GetUIpointer()->ApplyCommand("/event/abort");
115 G4UImanager::GetUIpointer()->ApplyCommand("/alStacking/clearStack");
118 TG4Globals::Exception("TG4StepManager: Step is not defined.");
122 void TG4StepManager::Rndm(Float_t* array, const Int_t size) const
124 // Random numbers array of the specified size.
127 G4double* const kpDoubleArray = new G4double[size];
128 RandFlat::shootArray(size,kpDoubleArray);
129 for (G4int i=0; i<size; i++) {
130 array[i] = kpDoubleArray[i];
132 delete [] kpDoubleArray;
135 void TG4StepManager::SetMaxStep(Float_t step)
137 // Maximum step allowed in the current logical volume.
138 // The maximum value is kept for following tracks - is it ok ??
143 G4LogicalVolume* curLogVolume
144 = fStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume();
145 G4UserLimits* userLimits
146 = curLogVolume->GetUserLimits();
149 userLimits = new G4UserLimits(step);
150 curLogVolume->SetUserLimits(userLimits);
153 { userLimits->SetMaxAllowedStep(step); }
156 TG4Globals::Exception("TG4StepManager: Step is not defined.");
160 void TG4StepManager::SetMaxNStep(Int_t maxNofSteps)
162 // Not yet implemented.
166 "TG4StepManager::SetMaxNStep(..) is not yet implemented.");
169 void TG4StepManager::SetUserDecay(Int_t pdg)
171 // Not yet implemented.
174 TG4Globals::Exception(
175 "TG4StepManager::SetUserDecay(..) is not yet implemented.");
178 Int_t TG4StepManager::CurrentVolID(Int_t& copyNo) const
180 // Returns the current sensitive detector ID
181 // and the copy number of the current physical volume.
186 G4VPhysicalVolume* physVolume
187 = fStep->GetPreStepPoint()->GetPhysicalVolume();
188 copyNo = physVolume->GetCopyNo();
190 // sensitive detector ID
191 G4VSensitiveDetector* sd
192 = physVolume->GetLogicalVolume()->GetSensitiveDetector();
194 TG4VSensitiveDetector* tsd = dynamic_cast<TG4VSensitiveDetector*>(sd);
198 TG4Globals::Exception(
199 "TG4StepManager::CurrentVol: Unknown sensitive detector type");
204 G4String text = "TG4StepManager::CurrentVol: \n";
205 text = text + " Volume " + physVolume->GetName();
206 text = text + " has not a sensitive detector.";
207 TG4Globals::Exception(text);
212 TG4Globals::Exception("TG4StepManager: Step is not defined.");
217 Int_t TG4StepManager::CurrentVolOffID(Int_t off, Int_t& copyNo) const
219 // Returns the off-th mother's of the current volume
220 // the sensitive detector ID and the copy number.
223 if (off == 0) return CurrentVolID(copyNo);
227 // mother of physical volume may not be set ?!!
229 G4VPhysicalVolume* physVolume
230 = fStep->GetPreStepPoint()->GetPhysicalVolume();
232 G4VPhysicalVolume* mother = 0;
235 mother = physVolume->GetMother();
240 copyNo = mother->GetCopyNo();
242 // sensitive detector ID
243 G4VSensitiveDetector* sd
244 = mother->GetLogicalVolume()->GetSensitiveDetector();
246 TG4VSensitiveDetector* tsd = dynamic_cast<TG4VSensitiveDetector*>(sd);
250 TG4Globals::Exception(
251 "TG4StepManager::CurrentVolOff: Unknown sensitive detector type");
256 G4String text = "TG4StepManager::CurrentVolOff: \n";
257 text = text + " Volume " + mother->GetName();
258 text = text + " has not a sensitive detector.";
259 TG4Globals::Exception(text);
264 G4String text = "TG4StepManager::CurrentVolOff: Volume ";
265 text = text + physVolume->GetName();
266 text = text + " has not defined mother in required level.";
267 TG4Globals::Exception(text);
272 TG4Globals::Exception("TG4StepManager: Step is not defined.");
277 const char* TG4StepManager::CurrentVolName() const
279 // Returns the current physical volume name.
283 G4VPhysicalVolume* physVolume
284 = fStep->GetPreStepPoint()->GetPhysicalVolume();
285 return physVolume->GetName();
288 TG4Globals::Exception("TG4StepManager: Step is not defined.");
293 const char* TG4StepManager::CurrentVolOffName(Int_t off) const
295 // Returns the off-th mother's physical volume name.
299 G4VPhysicalVolume* physVolume
300 = fStep->GetPreStepPoint()->GetPhysicalVolume();
302 G4VPhysicalVolume* mother = 0;
305 mother = physVolume->GetMother();
310 return mother->GetName();
313 TG4Globals::Exception("TG4StepManager::CurrentVolOff: wrong usage.");
318 TG4Globals::Exception("TG4StepManager: Step is not defined.");
323 Int_t TG4StepManager::CurrentMaterial(Float_t &a, Float_t &z, Float_t &dens,
324 Float_t &radl, Float_t &absl) const
326 // Returns the parameters of the current material during transport
327 // the return value is the number of elements in the mixture.
332 G4LogicalVolume* curLogVolume
333 = fStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume();
335 = curLogVolume->GetMaterial();
337 // this if may be redundant - check
340 G4int nofElements = material->GetNumberOfElements();
341 TG4GeometryManager* pGeometryManager = TG4GeometryManager::Instance();
342 a = pGeometryManager->GetEffA(material);
343 z = pGeometryManager->GetEffZ(material);
346 dens = material->GetDensity();
347 dens /= TG3Units::MassDensity();
350 radl = material->GetRadlen();
351 radl /= TG3Units::Length();
353 absl = 0.; // this parameter is not defined in Geant4
357 TG4Globals::Exception(
358 "TG4StepManager::CurrentMaterial(..): material is not defined.");
363 TG4Globals::Exception("TG4StepManager: Step is not defined.");
368 void TG4StepManager::Gmtod(Float_t* xm, Float_t* xd, Int_t iflag)
370 // Transforms a position from the world reference frame
371 // to the current volume reference frame.
373 // Geant3 desription:
374 // ==================
375 // Computes coordinates XD (in DRS)
376 // from known coordinates XM in MRS
377 // The local reference system can be initialized by
378 // - the tracking routines and GMTOD used in GUSTEP
379 // - a call to GMEDIA(XM,NUMED)
380 // - a call to GLVOLU(NLEVEL,NAMES,NUMBER,IER)
381 // (inverse routine is GDTOM)
383 // If IFLAG=1 convert coordinates
384 // IFLAG=2 convert direction cosinus
390 G4ThreeVector theGlobalPoint(xm[0],xm[1],xm[2]);
392 //const G4NavigationHistory* history
393 // = fStep->GetPreStepPoint()->GetTouchable()->GetHistory();
394 G4AffineTransform affineTransform
395 = fStep->GetPreStepPoint()->GetTouchable()->GetHistory()
398 G4ThreeVector theLocalPoint;
400 theLocalPoint = affineTransform.TransformPoint(theGlobalPoint);
401 else if ( iflag == 2)
402 theLocalPoint = affineTransform.TransformAxis(theGlobalPoint);
404 TG4Globals::Exception(
405 "TG4StepManager::Gmtod(..,iflag): iflag is not in 1..2");
407 xd[0] = theLocalPoint.x();
408 xd[1] = theLocalPoint.y();
409 xd[2] = theLocalPoint.z();
413 G4ThreeVector direction(0,0,0);
414 G4bool RelativeSearch = true;
415 G4Navigator* theNavigator =
416 G4TransportationManager::GetTransportationManager()->
417 GetNavigatorForTracking();
419 G4VPhysicalVolume* pPhysVol;
421 = LocateGlobalPointAndSetup(theGlobalPoint, &direction, RelativeSearch);
422 //LocateGlobalPointWithinVolume(theGlobalPoint);
425 = theNavigator->GetGlobalToLocalTransform();
429 TG4Globals::Exception("TG4StepManager: Step is not defined.");
433 void TG4StepManager::Gdtom(Float_t* xd, Float_t* xm, Int_t iflag)
435 // Transforms a position from the current volume reference frame
436 // to the world reference frame.
438 // Geant3 desription:
439 // ==================
440 // Computes coordinates XM (Master Reference System
441 // knowing the coordinates XD (Detector Ref System)
442 // The local reference system can be initialized by
443 // - the tracking routines and GDTOM used in GUSTEP
444 // - a call to GSCMED(NLEVEL,NAMES,NUMBER)
445 // (inverse routine is GMTOD)
447 // If IFLAG=1 convert coordinates
448 // IFLAG=2 convert direction cosinus
455 G4ThreeVector theLocalPoint(xd[0],xd[1],xd[2]);
457 G4AffineTransform affineTransform
458 = fStep->GetPreStepPoint()->GetTouchable()->GetHistory()
459 ->GetTopTransform().Inverse();
461 G4ThreeVector theGlobalPoint;
463 theGlobalPoint = affineTransform.TransformPoint(theLocalPoint);
465 theGlobalPoint = affineTransform.TransformAxis(theLocalPoint);
468 "TG4StepManager::Gdtom(...,iflag): iflag is not in 1..2");
470 xm[0] = theGlobalPoint.x();
471 xm[1] = theGlobalPoint.y();
472 xm[2] = theGlobalPoint.z();
475 TG4Globals::Exception("TG4StepManager: Step is not defined.");
479 Float_t TG4StepManager::MaxStep() const
481 // Returns maximum step allowed in the current logical volume
487 G4LogicalVolume* curLogVolume
488 = fStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume();
489 G4UserLimits* userLimits
490 = curLogVolume->GetUserLimits();
494 G4String text = "User Limits are not defined for log volume ";
495 text = text + curLogVolume->GetName();
496 TG4Globals::Warning(text);
501 const G4Track& trackRef = *(fStep->GetTrack());
502 maxStep = userLimits->GetMaxAllowedStep(trackRef);
503 maxStep /= TG3Units::Length();
508 TG4Globals::Exception("TG4StepManager: Step is not defined.");
513 Int_t TG4StepManager::GetMaxNStep() const
515 // Not yet implemented.
519 "Method GetMaxNStep is not yet implemented in TG4StepManager.");
523 void TG4StepManager::TrackPosition(TLorentzVector& position) const
525 // Current particle position (in the world reference frame)
526 // and the local time since the current track is created
527 // (position of the PostStepPoint).
533 G4StepPoint* stepPoint;
534 if (fStepStatus == kPreStepPoint)
535 stepPoint = fStep->GetPreStepPoint();
537 stepPoint = fStep->GetPostStepPoint();
540 G4ThreeVector positionVector
541 = stepPoint->GetPosition();
542 positionVector *= 1./(TG3Units::Length());
546 = fStep->GetTrack()->GetLocalTime();
547 time /= TG3Units::Time();
549 SetTLorentzVector(positionVector, time, position);
552 TG4Globals::Exception("TG4StepManager: Step is not defined.");
556 Int_t TG4StepManager::GetMedium() const
558 // Returns the second index of the current material (corresponding to
559 // G3 tracking medium index).
564 G4Material* curMaterial
565 = fStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume()->GetMaterial();
568 TG4GeometryManager* pGeometryManager = TG4GeometryManager::Instance();
569 return pGeometryManager->GetMediumId(curMaterial);
572 TG4Globals::Exception("TG4StepManager: Step is not defined.");
577 void TG4StepManager::TrackMomentum(TLorentzVector& momentum) const
579 // Current particle "momentum" (px, py, pz, Etot).
583 G4ThreeVector momentumVector
584 = fStep->GetTrack()->GetMomentum();
587 = fStep->GetTrack()->GetDynamicParticle()->GetTotalEnergy();
588 energy /= TG3Units::Energy();
590 SetTLorentzVector(momentumVector, energy, momentum);
593 TG4Globals::Exception("TG4StepManager: Step is not defined.");
597 void TG4StepManager::TrackVertexPosition(TLorentzVector& position) const
599 // The vertex particle position (in the world reference frame)
600 // and the local time since the current track is created.
605 G4ThreeVector positionVector
606 = fStep->GetTrack()->GetVertexPosition();
607 positionVector *= 1./(TG3Units::Length());
612 = fStep->GetTrack()->GetLocalTime();
613 time /= TG3Units::Time();
615 SetTLorentzVector(positionVector, time, position);
618 TG4Globals::Exception("TG4StepManager: Step is not defined.");
622 void TG4StepManager::TrackVertexMomentum(TLorentzVector& momentum) const
624 // The vertex particle "momentum" (px, py, pz, Ekin)
625 // to do: change Ekin -> Etot
629 G4ThreeVector momentumVector
630 = fStep->GetTrack()->GetVertexMomentumDirection();
633 = fStep->GetTrack()->GetVertexKineticEnergy();
634 energy /= TG3Units::Energy();
636 SetTLorentzVector(momentumVector, energy, momentum);
639 TG4Globals::Exception("TG4StepManager: Step is not defined.");
643 Float_t TG4StepManager::TrackStep() const
645 // Returns the current step length.
650 if (fStepStatus == kPreStepPoint)
653 length = fStep->GetStepLength();
654 length /= TG3Units::Length();
659 TG4Globals::Exception("TG4StepManager: Step is not defined.");
664 Float_t TG4StepManager::TrackLength() const
666 // Returns the length of the current track from its origin.
671 = fStep->GetTrack()->GetTrackLength();
672 length /= TG3Units::Length();
676 TG4Globals::Exception("TG4StepManager: Step is not defined.");
681 Float_t TG4StepManager::TrackTime() const
683 // Returns the local time since the current track is created.
685 // in Geant4: there is also defined proper time as
686 // the proper time of the dynamical particle of the current track.
691 = fStep->GetTrack()->GetLocalTime();
692 time /= TG3Units::Time();
696 TG4Globals::Exception("TG4StepManager: Step is not defined.");
701 Float_t TG4StepManager::Edep() const
703 // Returns total energy deposit in this step.
707 G4double energyDeposit;
708 if (fStepStatus == kPreStepPoint)
711 energyDeposit = fStep->GetTotalEnergyDeposit();
712 energyDeposit /= TG3Units::Energy();
714 return energyDeposit;
717 TG4Globals::Exception("TG4StepManager: Step is not defined.");
722 Int_t TG4StepManager::TrackPid() const
724 // Returns the current particle PDG encoding.
728 G4ParticleDefinition* particle
729 = fStep->GetTrack()->GetDynamicParticle()->GetDefinition();
731 // ask TG4PhysicsManager to get PDG encoding
732 // (in order to get PDG from extended TDatabasePDG
733 // in case the standard PDG code is not defined)
734 TG4PhysicsManager* pPhysicsManager = TG4PhysicsManager::Instance();
735 G4int pdgEncoding = pPhysicsManager->GetPDGEncodingFast(particle);
740 TG4Globals::Exception("TG4StepManager: Step is not defined.");
745 Float_t TG4StepManager::TrackCharge() const
747 // Returns the current particle charge.
752 = fStep->GetTrack()->GetDynamicParticle()->GetDefinition()
754 charge /= TG3Units::Charge();
758 TG4Globals::Exception("TG4StepManager: Step is not defined.");
763 Float_t TG4StepManager::TrackMass() const
765 // Returns current particle rest mass.
770 = fStep->GetTrack()->GetDynamicParticle()->GetDefinition()
772 mass /= TG3Units::Mass();
776 TG4Globals::Exception("TG4StepManager: Step is not defined.");
781 Float_t TG4StepManager::Etot() const
783 // Returns total energy of the current particle.
788 = fStep->GetTrack()->GetDynamicParticle()->GetTotalEnergy();
789 energy /= TG3Units::Energy();
793 TG4Globals::Exception("TG4StepManager: Step is not defined.");
798 Bool_t TG4StepManager::IsTrackInside() const
800 // Returns true if particle does not cross geometrical boundary
801 // at both pre-step and post-step points.
805 if (fStepStatus == kPreStepPoint) {
809 if ( !(IsTrackEntering()) && !(IsTrackExiting()) )
817 Bool_t TG4StepManager::IsTrackEntering() const
819 // Returns true if particle cross a geometrical boundary
820 // at pre-step point.
823 if (fStepStatus == kPreStepPoint)
829 Bool_t TG4StepManager::IsTrackExiting() const
831 // Returns true if particle cross a geometrical boundary
832 // at post-step point.
836 if (fStepStatus == kPreStepPoint)
840 = fStep->GetPostStepPoint()->GetStepStatus();
841 if (status == fGeomBoundary)
847 TG4Globals::Exception("TG4StepManager: Step is not defined.");
852 Bool_t TG4StepManager::IsTrackOut() const
854 // Returns true if particle cross the world boundary
855 // at post-step point.
861 = fStep->GetPostStepPoint()->GetStepStatus();
862 if (status == fWorldBoundary)
868 TG4Globals::Exception("TG4StepManager: Step is not defined.");
873 Bool_t TG4StepManager::IsTrackStop() const
875 // Returns true if particle has stopped
876 // or has been killed, suspended or postponed to next event.
878 // Possible track status from G4:
879 // fAlive, // Continue the tracking
880 // fStopButAlive, // Invoke active rest physics processes and
881 // // and kill the current track afterward
882 // fStopAndKill, // Kill the current track
883 // fKillTrackAndSecondaries,
884 // // Kill the current track and also associated
886 // fSuspend, // Suspend the current track
887 // fPostponeToNextEvent
888 // // Postpones the tracking of thecurrent track
889 // // to the next event.
895 = fStep->GetTrack()->GetTrackStatus();
896 if ((status == fStopAndKill) ||
897 (status == fKillTrackAndSecondaries) ||
898 (status == fSuspend) ||
899 (status == fPostponeToNextEvent))
905 TG4Globals::Exception("TG4StepManager: Step is not defined.");
910 Bool_t TG4StepManager::IsTrackDisappeared() const
912 // Returns true if particle has disappeared
913 // (due to any physical process)
914 // or has been killed, suspended or postponed to next event.
920 = fStep->GetTrack()->GetTrackStatus();
921 if ((status == fStopButAlive) ||
922 (status == fKillTrackAndSecondaries) ||
923 (status == fSuspend) ||
924 (status == fPostponeToNextEvent))
930 TG4Globals::Exception("TG4StepManager: Step is not defined.");
935 Bool_t TG4StepManager::IsTrackAlive() const
937 // Returns true if particle continues tracking.
942 = fStep->GetTrack()->GetTrackStatus();
943 if (status == fAlive)
949 TG4Globals::Exception("TG4StepManager: Step is not defined.");
954 Bool_t TG4StepManager::IsNewTrack() const
956 // Returns true when track performs the first step.
959 if ((fStep->GetTrack()->GetCurrentStepNumber() == 1) &&
960 (fStepStatus == kPreStepPoint))
966 Int_t TG4StepManager::NSecondaries() const
968 // Returns the number of secondary particles generated
969 // in the current step.
972 if (fSteppingManager)
974 G4int nofSecondaries = 0;
975 nofSecondaries += fSteppingManager->GetfN2ndariesAtRestDoIt();
976 nofSecondaries += fSteppingManager->GetfN2ndariesAlongStepDoIt();
977 nofSecondaries += fSteppingManager->GetfN2ndariesPostStepDoIt();
979 return nofSecondaries;
982 TG4Globals::Exception("TG4StepManager: SteppingManager is not defined.");
987 void TG4StepManager::GetSecondary(Int_t index, Int_t& particleId,
988 TLorentzVector& position, TLorentzVector& momentum)
990 // Fills the parameters (particle encoding, position, momentum)
991 // of the generated secondary particle which is specified by index.
992 // !! Check if indexing of secondaries is same !!
995 if (fSteppingManager)
997 G4int nofSecondaries = NSecondaries();
998 G4TrackVector* secondaryTracks = fSteppingManager->GetSecondary();
1000 if (secondaryTracks)
1002 if (index < nofSecondaries)
1004 // the index of the first secondary of this step
1006 = secondaryTracks->entries() - nofSecondaries;
1007 // (the secondaryTracks vector contains secondaries
1008 // produced by the track at previous steps, too)
1010 = (*secondaryTracks)[startIndex + index];
1012 // particle encoding
1014 = track->GetDynamicParticle()->GetDefinition()->GetPDGEncoding();
1017 G4ThreeVector positionVector = track->GetPosition();
1018 positionVector *= 1./(TG3Units::Length());
1019 G4double time = track->GetLocalTime();
1020 time /= TG3Units::Time();
1021 SetTLorentzVector(positionVector, time, position);
1023 // momentum & energy
1024 G4ThreeVector momentumVector = track->GetMomentum();
1025 G4double energy = track->GetDynamicParticle()->GetTotalEnergy();
1026 energy /= TG3Units::Energy();
1027 SetTLorentzVector(momentumVector, energy, momentum);
1030 TG4Globals::Exception(
1031 "TG4StepManager::GetSecondary(): wrong secondary track index.");
1035 TG4Globals::Exception(
1036 "TG4StepManager::GetSecondary(): secondary tracks vector is empty");
1040 TG4Globals::Exception("TG4StepManager: SteppingManager is not defined.");
1044 const char* TG4StepManager::ProdProcess() const
1046 // Returns the name of the process that defined current step
1047 // (and may produce the secondary particles).
1052 const G4VProcess* curProcess
1053 = fStep->GetPostStepPoint()->GetProcessDefinedStep();
1055 G4String g4Name = curProcess->GetProcessName();
1059 TG4Globals::Exception("TG4StepManager: Step is not defined.");