Geant4 VMC Version 6.8
Loading...
Searching...
No Matches
TG4StepManager.cxx
Go to the documentation of this file.
1//------------------------------------------------
2// The Geant4 Virtual Monte Carlo package
3// Copyright (C) 2007 - 2015 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 "TG4StepManager.h"
16#include "TG4G3Units.h"
17#include "TG4GeometryServices.h"
18#include "TG4Globals.h"
19#include "TG4Limits.h"
20#include "TG4ParticlesManager.h"
21#include "TG4PhysicsManager.h"
22#include "TG4SDServices.h"
23#include "TG4SteppingAction.h"
24#include "TG4TrackInformation.h"
25#include "TG4TrackManager.h"
26
27#include <G4AffineTransform.hh>
28#include <G4Navigator.hh>
29#include <G4OpticalPhoton.hh>
30#include <G4ProcessManager.hh>
31#include <G4ProcessVector.hh>
32#include <G4SteppingManager.hh>
33#include <G4TransportationManager.hh>
34#include <G4TransportationProcessType.hh>
35#include <G4UImanager.hh>
36#include <G4UserLimits.hh>
37#include <G4VProcess.hh>
38#include <G4VTouchable.hh>
39
40#include <TLorentzVector.h>
41
42#include <TMCParticleStatus.h>
43#include <TMath.h>
44#include <TVector3.h>
45
47
48//_____________________________________________________________________________
49TG4StepManager::TG4StepManager(const TString& userGeometry)
50 : fTrack(0),
51 fStep(0),
52 fGflashSpot(0),
61{
64
65 // G4cout << "TG4StepManager::TG4StepManager " << this << G4endl;
66
67 if (fgInstance) {
68 TG4Globals::Exception("TG4StepManager", "TG4StepManager",
69 "Cannot create two instances of singleton.");
70 }
71
72 fgInstance = this;
73
76 if (userGeometry == "VMCtoGeant4") fCopyNoOffset = 1;
77
81 if (userGeometry == "RootToGeant4" || userGeometry == "Geant4" ||
82 userGeometry == "VMC+RootToGeant4")
84}
85
86//_____________________________________________________________________________
93
94//
95// private methods
96//
97
98//_____________________________________________________________________________
100{
102
103 if (!fTrack)
105 "TG4StepManager", "CheckTrack", "Track is not defined.");
106}
107
108//_____________________________________________________________________________
109void TG4StepManager::CheckStep(const G4String& method) const
110{
112
113 if (!fStep) {
114 TG4Globals::Exception("TG4StepManager", method, "Step is not defined.");
115 }
116}
117
118//_____________________________________________________________________________
119void TG4StepManager::CheckGflashSpot(const G4String& method) const
120{
122
123 if (!fGflashSpot) {
125 "TG4StepManager", method, "Gflash spot is not defined.");
126 }
127}
128
129//_____________________________________________________________________________
131{
133
134 if (!fSteppingManager)
135 TG4Globals::Exception("TG4StepManager", "CheckSteppingManager",
136 "Stepping manager is not defined.");
137}
138
139//_____________________________________________________________________________
141 G4ThreeVector xyz, G4double t, TLorentzVector& lv) const
142{
144
145 lv[0] = xyz.x();
146 lv[1] = xyz.y();
147 lv[2] = xyz.z();
148 lv[3] = t;
149}
150
151//_____________________________________________________________________________
152const G4VTouchable* TG4StepManager::GetCurrentTouchable() const
153{
155
156#ifdef MCDEBUG
157 CheckTrack();
158#endif
159
160 if (fStepStatus == kGflashSpot) {
161 G4ReferenceCountedHandle<G4VTouchable> touchableHandle =
162 fGflashSpot->GetTouchableHandle();
163 return touchableHandle();
164 }
165 else if (fStepStatus != kBoundary)
166 return fTrack->GetTouchable();
167 else
168 return fTrack->GetNextTouchable();
169}
170
171//_____________________________________________________________________________
173 G4int off, G4int& component) const
174{
179
180 const G4VTouchable* touchable = GetCurrentTouchable();
181 G4int remaining = off;
182 G4bool crossedAssembly = false;
183
184 for (G4int level = 0; level <= touchable->GetHistoryDepth(); ++level) {
185 G4VPhysicalVolume* pv = touchable->GetVolume(level);
186 if (pv == 0) break;
187
188 const TG4AssemblyLevels& levels =
190 const G4int nofLevels =
191 levels.fNames.empty() ? 1 : G4int(levels.fNames.size());
192
193 if (remaining < nofLevels) {
194 if (nofLevels == 1 && !crossedAssembly) return 0;
195 component = levels.fNames.empty() ? -1 : nofLevels - 1 - remaining;
196 return pv;
197 }
198 crossedAssembly = crossedAssembly || nofLevels > 1;
199 remaining -= nofLevels;
200 }
201 return 0;
202}
203
204//_____________________________________________________________________________
206 G4int off, G4bool warn) const
207{
210
211 // Get current touchable
212 //
213 const G4VTouchable* touchable = GetCurrentTouchable();
214
215 // Check touchable depth
216 //
217 if (touchable->GetHistoryDepth() < off) {
218 if (warn) {
219 TString text = "level=";
220 text += off;
221 TG4Globals::Warning("TG4StepManager", "GetCurrentOffPhysicalVolume",
222 "Volume " + TString(touchable->GetVolume()->GetName()) +
223 " has not defined mother in " + text + ".");
224 }
225 return 0;
226 }
227
228 return touchable->GetVolume(off);
229}
230
231//
232// public methods
233//
234
235//_____________________________________________________________________________
240
241//_____________________________________________________________________________
243{
251
252 if (fTrack) {
253 fTrack->SetTrackStatus(fStopAndKill);
254 // fTrack->SetTrackStatus(fStopButAlive);
255 // fTrack->SetTrackStatus(fKillTrackAndSecondaries);
256 }
257 else {
258 TG4Globals::Warning("TG4StepManager", "StopTrack()",
259 "There is no current track to be stopped.");
260 }
261}
262
263//_____________________________________________________________________________
265{
267
268 if (fTrack) {
269 fTrack->SetTrackStatus(fStopAndKill);
270 fTrackManager->GetTrackInformation(fTrack)->SetInterrupt(true);
271 }
272 else {
273 TG4Globals::Warning("TG4StepManager", "InterruptTrack()",
274 "There is no current track to be interrupted.");
275 }
276}
277
278//_____________________________________________________________________________
280{
282
283 if (fTrack) {
284 fTrack->SetTrackStatus(fKillTrackAndSecondaries);
285 // StopTrack(); // cannot be used as it keeps secondaries
286 }
287
288 G4UImanager::GetUIpointer()->ApplyCommand("/event/abort");
289}
290
291//_____________________________________________________________________________
293{
295
297
298 StopEvent();
299 G4UImanager::GetUIpointer()->ApplyCommand("/run/abort");
300}
301
302//_____________________________________________________________________________
303void TG4StepManager::SetMaxStep(Double_t step)
304{
308
309 TG4Limits* userLimits = GetCurrentLimits();
310
311 if (!userLimits) return;
312
313 // G4cout << "TG4StepManager::SetMaxStep in "
314 // << GetCurrentPhysicalVolume()->GetLogicalVolume()->GetName() << " "
315 // << userLimits->GetName() << G4endl;
316
317 // set max step
318 userLimits->SetCurrentMaxAllowedStep(step * TG4G3Units::Length());
319 fLimitsModifiedOnFly = userLimits;
320}
321
322//_____________________________________________________________________________
324{
327
330 "TG4StepManager", "SetMaxStepBack", "No limits modified on fly found.");
331 return;
332 }
333
334 // set max step
335 fLimitsModifiedOnFly->SetMaxAllowedStepBack();
337}
338
339//_____________________________________________________________________________
340void TG4StepManager::SetMaxNStep(Int_t maxNofSteps)
341{
343
344 TG4SteppingAction::Instance()->SetMaxNofSteps(TMath::Abs(maxNofSteps));
345}
346
347//_____________________________________________________________________________
348void TG4StepManager::SetCollectTracks(Bool_t collectTracks)
349{
351
353}
354
355//_____________________________________________________________________________
357{
359
360#ifdef MCDEBUG
361 CheckTrack();
362#endif
363
364 G4ParticleDefinition* particle =
365 fTrack->GetDynamicParticle()->GetDefinition();
366
367 // Store the original particle lifetime in track information
368 // (as it has to be set back after track is finished)
369 TG4TrackInformation* trackInformation =
370 fTrackManager->GetTrackInformation(fTrack);
371 trackInformation->SetPDGLifetime(particle->GetPDGLifeTime());
372
373 // Set new lifetime value
374 particle->SetPDGLifeTime(time * TG4G3Units::Time());
375}
376
377//_____________________________________________________________________________
378void TG4StepManager::SetInitialVMCTrackStatus(TMCParticleStatus* status)
379{
382
383 fInitialVMCTrackStatus = status;
384}
385
386//_____________________________________________________________________________
393
394//_____________________________________________________________________________
396{
400
401#ifdef MCDEBUG
402 CheckTrack();
403#endif
404
406 return fGflashSpot->GetTouchableHandle()->GetVolume();
407 else if (fStepStatus != kBoundary)
408 return fTrack->GetVolume();
409 else
410 return fTrack->GetNextVolume();
411}
412
413//_____________________________________________________________________________
415{
417
418#ifdef MCDEBUG
420 GetCurrentPhysicalVolume()->GetLogicalVolume()->GetUserLimits());
421#else
422 TG4Limits* userLimits =
423 (TG4Limits*)GetCurrentPhysicalVolume()->GetLogicalVolume()->GetUserLimits();
424#endif
425
426 if (!userLimits) {
428 "TG4StepManager", "Get current limits", "User limits not defined.");
429 return 0;
430 }
431
432 return userLimits;
433}
434
435//_____________________________________________________________________________
436Int_t TG4StepManager::CurrentVolID(Int_t& copyNo) const
437{
440
441 G4VPhysicalVolume* physVolume = GetCurrentPhysicalVolume();
442 if (!physVolume) {
444 "TG4StepManager", "CurrentVolID", "No current physical volume found");
445 return 0;
446 }
447 copyNo = physVolume->GetCopyNo() + fCopyNoOffset;
448
449 if (physVolume->IsParameterised() || physVolume->IsReplicated())
450 copyNo += fDivisionCopyNoOffset;
451
452 // sensitive detector ID
453 return TG4SDServices::Instance()->GetVolumeID(physVolume->GetLogicalVolume());
454}
455
456//_____________________________________________________________________________
457Int_t TG4StepManager::CurrentVolOffID(Int_t off, Int_t& copyNo) const
458{
461
462 if (off == 0) return CurrentVolID(copyNo);
463
464 G4int component = -1;
465 if (G4VPhysicalVolume* pv = GetOffLevel(off, component)) {
466 const TG4AssemblyLevels& levels =
468 const G4int encoded =
469 (component >= 0 && component < G4int(levels.fCopyNos.size()))
470 ? levels.fCopyNos[component]
471 : -1;
472 copyNo = (encoded >= 0 ? encoded : pv->GetCopyNo()) + fCopyNoOffset;
473 // a collapsed assembly has no Geant4 logical volume of its own, so the id
474 // returned for such a level is the placed volume's; only copyNo is meaningful
475 return TG4SDServices::Instance()->GetVolumeID(pv->GetLogicalVolume());
476 }
477
478#ifdef MCDEBUG
479 G4VPhysicalVolume* mother = GetCurrentOffPhysicalVolume(off, true);
480#else
481 G4VPhysicalVolume* mother = GetCurrentOffPhysicalVolume(off);
482#endif
483
484 if (mother) {
485 copyNo = mother->GetCopyNo() + fCopyNoOffset;
486
487 if (mother->IsParameterised() || mother->IsReplicated())
488 copyNo += fDivisionCopyNoOffset;
489
490 // sensitive detector ID
491 return TG4SDServices::Instance()->GetVolumeID(mother->GetLogicalVolume());
492 }
493 else {
494 copyNo = 0;
495 return 0;
496 }
497}
498
499//_____________________________________________________________________________
501{
503
505 GetCurrentPhysicalVolume()->GetLogicalVolume());
506
507 return fNameBuffer.data();
508}
509
510//_____________________________________________________________________________
511const char* TG4StepManager::CurrentVolOffName(Int_t off) const
512{
514
515 if (off == 0) return CurrentVolName();
516
517 G4int component = -1;
518 if (G4VPhysicalVolume* pv = GetOffLevel(off, component)) {
519 const TG4AssemblyLevels& levels =
521 auto services = TG4GeometryServices::Instance();
522 fNameBuffer = (component >= 0 && component + 1 < G4int(levels.fNames.size()))
523 ? G4String(services->UserVolumeName(levels.fNames[component]))
524 : services->UserVolumeName(pv->GetLogicalVolume());
525 return fNameBuffer.data();
526 }
527
528 G4VPhysicalVolume* mother = GetCurrentOffPhysicalVolume(off);
529
530 if (mother) {
532 mother->GetLogicalVolume());
533 }
534 else {
535 fNameBuffer = "";
536 }
537 return fNameBuffer.data();
538}
539
540//_____________________________________________________________________________
542{
544
546
547 // Get current touchable
548 const G4VTouchable* touchable = GetCurrentTouchable();
549
550 // Check touchable depth
551 //
552 G4int depth = touchable->GetHistoryDepth();
553
554 // Compose the path
555 //
556 fNameBuffer = "";
557 for (G4int i = 0; i < depth; i++) {
558 G4VPhysicalVolume* physVolume = touchable->GetHistory()->GetVolume(i);
559 fNameBuffer += "/";
560 fNameBuffer += geometryServices->UserVolumeName(physVolume->GetName());
561 fNameBuffer += "_";
562 TG4Globals::AppendNumberToString(fNameBuffer, physVolume->GetCopyNo());
563 }
564
565 // Add current volume to the path
566 G4VPhysicalVolume* curPhysVolume = GetCurrentPhysicalVolume();
567 fNameBuffer += "/";
568 fNameBuffer += geometryServices->UserVolumeName(curPhysVolume->GetName());
569 fNameBuffer += "_";
570 TG4Globals::AppendNumberToString(fNameBuffer, curPhysVolume->GetCopyNo());
571
572 return fNameBuffer.data();
573}
574
575//_____________________________________________________________________________
577 Double_t& x, Double_t& y, Double_t& z) const
578{
580
581 G4Navigator* theNavigator =
582 G4TransportationManager::GetTransportationManager()
583 ->GetNavigatorForTracking();
584
585 G4bool valid;
586 G4ThreeVector theLocalNormal = theNavigator->GetLocalExitNormal(&valid);
587 if (!valid) return false;
588
589 G4ThreeVector theGlobalNormal =
590 theNavigator->GetLocalToGlobalTransform().TransformAxis(theLocalNormal);
591
592 x = theGlobalNormal.x();
593 y = theGlobalNormal.y();
594 z = theGlobalNormal.z();
595
596 return true;
597}
598
599//_____________________________________________________________________________
601 Float_t& a, Float_t& z, Float_t& dens, Float_t& radl, Float_t& absl) const
602{
610
611 G4VPhysicalVolume* physVolume = GetCurrentPhysicalVolume();
612
613 G4Material* material = physVolume->GetLogicalVolume()->GetMaterial();
614
615 G4int nofElements = material->GetNumberOfElements();
617 a = geometryServices->GetEffA(material);
618 z = geometryServices->GetEffZ(material);
619
620 // density
621 dens = material->GetDensity();
622 dens /= TG4G3Units::MassDensity();
623
624 // radiation length
625 radl = material->GetRadlen();
626 radl /= TG4G3Units::Length();
627
628 absl = 0.; // this parameter is not defined in Geant4
629 return nofElements;
630}
631
632//_____________________________________________________________________________
634{
636
638 GetCurrentPhysicalVolume()->GetLogicalVolume());
639}
640
641//_____________________________________________________________________________
642void TG4StepManager::Gmtod(Float_t* xm, Float_t* xd, Int_t iflag)
643{
652
653 G4double* dxm = TG4GeometryServices::Instance()->CreateG4doubleArray(xm, 3);
654 G4double* dxd = TG4GeometryServices::Instance()->CreateG4doubleArray(xd, 3, false);
655
656 Gmtod(dxm, dxd, iflag);
657
658 // Fill computed xd coordinates
659 for (G4int i = 0; i < 3; i++) {
660 xd[i] = dxd[i];
661 }
662
663 delete[] dxm;
664 delete[] dxd;
665}
666
667//_____________________________________________________________________________
668void TG4StepManager::Gmtod(Double_t* xm, Double_t* xd, Int_t iflag)
669{
678
679#ifdef MCDEBUG
680 if (iflag != 1 && iflag != 2) {
681 TString text = "iflag=";
682 text += iflag;
684 "TG4StepManager", "Gmtod", text + " is different from 1..2.");
685 return;
686 }
687#endif
688
689 const G4AffineTransform& affineTransform =
690 GetCurrentTouchable()->GetHistory()->GetTopTransform();
691
692 G4ThreeVector theGlobalPoint(xm[0] * TG4G3Units::Length(),
693 xm[1] * TG4G3Units::Length(), xm[2] * TG4G3Units::Length());
694 G4ThreeVector theLocalPoint;
695 if (iflag == 1)
696 theLocalPoint = affineTransform.TransformPoint(theGlobalPoint);
697 else {
698 // if ( iflag == 2)
699 theLocalPoint = affineTransform.TransformAxis(theGlobalPoint);
700 }
701
702 xd[0] = theLocalPoint.x() * TG4G3Units::InverseLength();
703 xd[1] = theLocalPoint.y() * TG4G3Units::InverseLength();
704 xd[2] = theLocalPoint.z() * TG4G3Units::InverseLength();
705}
706
707//_____________________________________________________________________________
708void TG4StepManager::Gdtom(Float_t* xd, Float_t* xm, Int_t iflag)
709{
717
718 G4double* dxd = TG4GeometryServices::Instance()->CreateG4doubleArray(xd, 3);
719 G4double* dxm = TG4GeometryServices::Instance()->CreateG4doubleArray(xm, 3, false);
720
721 Gdtom(dxd, dxm, iflag);
722
723 // Fill computed xm coordinates
724 for (G4int i = 0; i < 3; i++) {
725 xm[i] = dxm[i];
726 }
727
728 delete[] dxd;
729 delete[] dxm;
730}
731
732//_____________________________________________________________________________
733void TG4StepManager::Gdtom(Double_t* xd, Double_t* xm, Int_t iflag)
734{
742
743#ifdef MCDEBUG
744 if (iflag != 1 && iflag != 2) {
745 TString text = "iflag=";
746 text += iflag;
748 "TG4StepManager", "Gmtod", text + " is different from 1..2.");
749 return;
750 }
751#endif
752
753 const G4AffineTransform& affineTransform =
754 GetCurrentTouchable()->GetHistory()->GetTopTransform().Inverse();
755
756 G4ThreeVector theLocalPoint(xd[0] * TG4G3Units::Length(),
757 xd[1] * TG4G3Units::Length(), xd[2] * TG4G3Units::Length());
758 G4ThreeVector theGlobalPoint;
759 if (iflag == 1)
760 theGlobalPoint = affineTransform.TransformPoint(theLocalPoint);
761 else {
762 // if( iflag == 2)
763 theGlobalPoint = affineTransform.TransformAxis(theLocalPoint);
764 }
765
766 xm[0] = theGlobalPoint.x() * TG4G3Units::InverseLength();
767 xm[1] = theGlobalPoint.y() * TG4G3Units::InverseLength();
768 xm[2] = theGlobalPoint.z() * TG4G3Units::InverseLength();
769}
770
771//_____________________________________________________________________________
773{
776
777 G4LogicalVolume* curLogVolume =
778 GetCurrentPhysicalVolume()->GetLogicalVolume();
779
780 // check this
781 G4UserLimits* userLimits = curLogVolume->GetUserLimits();
782
783 G4double maxStep;
784 if (userLimits == 0) {
785 TG4Globals::Warning("TG4StepManager", "MaxStep",
786 "User Limits are not defined for the current logical volume " +
787 TString(curLogVolume->GetName()) + ".");
788 return FLT_MAX;
789 }
790 else {
791 const G4Track& trackRef = *(fTrack);
792 maxStep = userLimits->GetMaxAllowedStep(trackRef);
793 maxStep /= TG4G3Units::Length();
794 return maxStep;
795 }
796}
797
798//_____________________________________________________________________________
800{
802
804}
805
806//_____________________________________________________________________________
807void TG4StepManager::TrackPosition(TLorentzVector& position) const
808{
812
813#ifdef MCDEBUG
814 CheckTrack();
815#endif
816
817 G4ThreeVector positionVector;
818 if (fStepStatus == kGflashSpot) {
819 positionVector = fGflashSpot->GetEnergySpot()->GetPosition();
820 }
821 else {
822 // get position
823 // check if this is == to PostStepPoint position !!
824 positionVector = fTrack->GetPosition();
825 }
826 positionVector *= 1. / (TG4G3Units::Length());
827
828 // global time
829 G4double time = fTrack->GetGlobalTime();
830 time /= TG4G3Units::Time();
831
832 SetTLorentzVector(positionVector, time, position);
833}
834
835//_____________________________________________________________________________
836void TG4StepManager::TrackPosition(Double_t& x, Double_t& y, Double_t& z) const
837{
840
841#ifdef MCDEBUG
842 CheckTrack();
843#endif
844
845 G4ThreeVector positionVector;
846 if (fStepStatus == kGflashSpot) {
847 positionVector = fGflashSpot->GetEnergySpot()->GetPosition();
848 }
849 else {
850 // get position
851 // check if this is == to PostStepPoint position !!
852 positionVector = fTrack->GetPosition();
853 }
854 positionVector *= 1. / (TG4G3Units::Length());
855
856 x = positionVector.x();
857 y = positionVector.y();
858 z = positionVector.z();
859}
860
861//_____________________________________________________________________________
862void TG4StepManager::TrackPosition(Float_t& x, Float_t& y, Float_t& z) const
863{
866
867 Double_t dx, dy, dz;
868 TrackPosition(dx, dy, dz);
869
870 x = static_cast<float>(dx);
871 y = static_cast<float>(dy);
872 z = static_cast<float>(dz);
873}
874
875//_____________________________________________________________________________
876void TG4StepManager::TrackMomentum(TLorentzVector& momentum) const
877{
880
881#ifdef MCDEBUG
882 CheckTrack();
883#endif
884
885 G4ThreeVector momentumVector = fTrack->GetMomentum();
886 momentumVector *= 1. / (TG4G3Units::Energy());
887
888 G4double energy = fTrack->GetDynamicParticle()->GetTotalEnergy();
889 energy /= TG4G3Units::Energy();
890
891 SetTLorentzVector(momentumVector, energy, momentum);
892}
893
894//_____________________________________________________________________________
896 Double_t& px, Double_t& py, Double_t& pz, Double_t& etot) const
897{
900
901#ifdef MCDEBUG
902 CheckTrack();
903#endif
904
905 G4ThreeVector momentumVector = fTrack->GetMomentum();
906 momentumVector *= 1. / (TG4G3Units::Energy());
907
908 px = momentumVector.x();
909 py = momentumVector.y();
910 pz = momentumVector.z();
911
912 etot = fTrack->GetDynamicParticle()->GetTotalEnergy();
913 etot /= TG4G3Units::Energy();
914}
915
916//_____________________________________________________________________________
918 Float_t& px, Float_t& py, Float_t& pz, Float_t& etot) const
919{
922
923 Double_t dpx, dpy, dpz, detot;
924 TrackMomentum(dpx, dpy, dpz, detot);
925
926 px = static_cast<float>(dpx);
927 py = static_cast<float>(dpy);
928 pz = static_cast<float>(dpz);
929 etot = static_cast<float>(detot);
930}
931
932//_____________________________________________________________________________
934{
937
938 if (fStepStatus == kNormalStep) {
939#ifdef MCDEBUG
940 CheckStep("TrackStep");
941#endif
942 return fStep->GetStepLength() * TG4G3Units::InverseLength();
943 }
944 else
945 return 0;
946}
947
948//_____________________________________________________________________________
950{
953
954#ifdef MCDEBUG
955 CheckTrack();
956#endif
958 return fTrack->GetTrackLength() * TG4G3Units::InverseLength();
959 }
960 return fTrack->GetTrackLength() * TG4G3Units::InverseLength() +
961 fInitialVMCTrackStatus->fTrackLength;
962}
963
964//_____________________________________________________________________________
966{
972
973#ifdef MCDEBUG
974 CheckTrack();
975#endif
976
977 return fTrack->GetGlobalTime() * TG4G3Units::InverseTime();
978}
979
980//_____________________________________________________________________________
981Double_t TG4StepManager::Edep() const
982{
984
985 if (fStepStatus == kNormalStep) {
986
987#ifdef MCDEBUG
988 CheckStep("Edep");
989#endif
990
991 return fStep->GetTotalEnergyDeposit() * TG4G3Units::InverseEnergy();
992 }
993
994 if (fStepStatus == kBoundary && fTrack->GetTrackStatus() == fStopAndKill) {
995 G4VProcess* proc = fSteppingManager->GetfCurrentProcess();
997 if (proc && physicsManager->GetMCProcess(proc) == kPLightScattering &&
998 physicsManager->GetOpBoundaryStatus() == kPLightDetection) {
999 return fTrack->GetTotalEnergy() * TG4G3Units::InverseEnergy();
1000 }
1001 }
1002
1003 if (fStepStatus == kGflashSpot) {
1004
1005#ifdef MCDEBUG
1006 CheckGflashSpot("Edep");
1007#endif
1008
1009 return fGflashSpot->GetEnergySpot()->GetEnergy() * TG4G3Units::InverseEnergy();
1010 }
1011
1012 return 0;
1013}
1014
1015//_____________________________________________________________________________
1017{
1019
1020 if (fStepStatus == kNormalStep) {
1021
1022#ifdef MCDEBUG
1023 CheckStep("NIELEdep");
1024#endif
1025
1026 return fStep->GetNonIonizingEnergyDeposit() * TG4G3Units::InverseEnergy();
1027 }
1028
1029 // return 0. in other cases (including kBoundary, kGflashSpot)
1030 return 0;
1031}
1032
1033//_____________________________________________________________________________
1035{
1037
1039 return fTrack->GetCurrentStepNumber();
1040 }
1041 return fTrack->GetCurrentStepNumber() + fInitialVMCTrackStatus->fStepNumber;
1042}
1043
1044//_____________________________________________________________________________
1046{
1048
1049 return fTrack->GetWeight();
1050}
1051
1052//_____________________________________________________________________________
1054 Double_t& polX, Double_t& polY, Double_t& polZ) const
1055{
1057
1058 const G4ThreeVector& pol = fTrack->GetPolarization();
1059 polX = pol.x();
1060 polY = pol.y();
1061 polZ = pol.z();
1062}
1063
1064//_____________________________________________________________________________
1065void TG4StepManager::TrackPolarization(TVector3& pol) const
1066{
1068
1069 const G4ThreeVector& polG4 = fTrack->GetPolarization();
1070 pol[0] = polG4.x();
1071 pol[1] = polG4.y();
1072 pol[2] = polG4.z();
1073}
1074
1075//_____________________________________________________________________________
1077{
1079
1080#ifdef MCDEBUG
1081 CheckTrack();
1082#endif
1083
1084 G4ParticleDefinition* particle =
1085 fTrack->GetDynamicParticle()->GetDefinition();
1086
1087 // Ask TG4ParticlesManager to get PDG encoding
1088 // (in order to get PDG from extended TDatabasePDG
1089 // in case the standard PDG code is not defined)
1090 G4int pdgEncoding = TG4ParticlesManager::Instance()->GetPDGEncoding(particle);
1091
1092 // Make difference between optical photon from Cerenkov and
1093 // feedback photon generated by user
1094 if (pdgEncoding == 50000050) {
1095 TG4TrackInformation* trackInformation =
1096 fTrackManager->GetTrackInformation(fTrack);
1097 if (trackInformation && trackInformation->GetPDGEncoding())
1098 pdgEncoding = trackInformation->GetPDGEncoding();
1099 }
1100
1101 return pdgEncoding;
1102}
1103
1104//_____________________________________________________________________________
1106{
1108
1109#ifdef MCDEBUG
1110 CheckTrack();
1111#endif
1112
1113 return fTrack->GetDynamicParticle()->GetDefinition()->GetPDGCharge() /
1115}
1116
1117//_____________________________________________________________________________
1119{
1121
1122#ifdef MCDEBUG
1123 CheckTrack();
1124#endif
1125
1126 return fTrack->GetDynamicParticle()->GetDefinition()->GetPDGMass() /
1128}
1129
1130//_____________________________________________________________________________
1131Double_t TG4StepManager::Etot() const
1132{
1134
1135#ifdef MCDEBUG
1136 CheckTrack();
1137#endif
1138
1139 return fTrack->GetDynamicParticle()->GetTotalEnergy() * TG4G3Units::InverseEnergy();
1140}
1141
1142// TO DO: revise these with added kGflashSpot status
1143
1144//_____________________________________________________________________________
1146{
1149
1150 if (fStepStatus == kNormalStep && !(IsTrackExiting())) {
1151 // track is always inside during a normal step
1152 return true;
1153 }
1154
1155 return false;
1156}
1157
1158//_____________________________________________________________________________
1160{
1163
1164 if (fStepStatus != kNormalStep) {
1165 // track is entering during a vertex or boundary step
1166 return true;
1167 }
1168
1169 return false;
1170}
1171
1172//_____________________________________________________________________________
1174{
1176
1177 if (fStepStatus == kNormalStep) {
1178
1179#ifdef MCDEBUG
1180 CheckStep("IsTrackExiting");
1181#endif
1182
1183 if (fStep->GetPostStepPoint()->GetStepStatus() == fGeomBoundary)
1184 return true;
1185 }
1186
1187 return false;
1188}
1189
1190//_____________________________________________________________________________
1192{
1195
1196 if (fStepStatus == kVertex) return false;
1197
1198#ifdef MCDEBUG
1199 CheckStep("IsTrackOut");
1200#endif
1201
1202 if (fStep->GetPostStepPoint()->GetStepStatus() == fWorldBoundary)
1203 return true;
1204 else
1205 return false;
1206}
1207
1208//_____________________________________________________________________________
1210{
1225
1226#ifdef MCDEBUG
1227 CheckTrack();
1228#endif
1229
1230 // check
1231 G4TrackStatus status = fTrack->GetTrackStatus();
1232 if ((status == fStopAndKill) || (status == fKillTrackAndSecondaries) ||
1233 (status == fSuspend) || (status == fPostponeToNextEvent)) {
1234 return true;
1235 }
1236 else
1237 return false;
1238}
1239
1240//_____________________________________________________________________________
1242{
1246
1247#ifdef MCDEBUG
1248 CheckTrack();
1249#endif
1250
1251 // check
1252 G4TrackStatus status = fTrack->GetTrackStatus();
1253 if ((status == fStopAndKill) || (status == fKillTrackAndSecondaries) ||
1254 (status == fPostponeToNextEvent)) {
1255 return true;
1256 }
1257 else
1258 return false;
1259}
1260
1261//_____________________________________________________________________________
1263{
1265
1266#ifdef MCDEBUG
1267 CheckTrack();
1268#endif
1269
1270 G4TrackStatus status = fTrack->GetTrackStatus();
1271 if ((status == fAlive) || (status == fStopButAlive))
1272 return true;
1273 else
1274 return false;
1275}
1276
1277//_____________________________________________________________________________
1279{
1281
1282 if (fStepStatus == kVertex)
1283 return true;
1284 else
1285 return false;
1286}
1287
1288//_____________________________________________________________________________
1290{
1293
1294 if (fStepStatus == kVertex || fStepStatus == kGflashSpot) return 0;
1295
1296#ifdef MCDEBUG
1298#endif
1299
1300 G4int nofSecondaries = 0;
1301 nofSecondaries += fSteppingManager->GetfN2ndariesAtRestDoIt();
1302 nofSecondaries += fSteppingManager->GetfN2ndariesAlongStepDoIt();
1303 nofSecondaries += fSteppingManager->GetfN2ndariesPostStepDoIt();
1304
1305 return nofSecondaries;
1306}
1307
1308//_____________________________________________________________________________
1309void TG4StepManager::GetSecondary(Int_t index, Int_t& particleId,
1310 TLorentzVector& position, TLorentzVector& momentum)
1311{
1318
1319#ifdef MCDEBUG
1321#endif
1322
1323 G4int nofSecondaries = NSecondaries();
1324 if (!nofSecondaries) return;
1325
1326 const G4TrackVector* secondaryTracks = fSteppingManager->GetSecondary();
1327#ifdef MCDEBUG
1328 if (!secondaryTracks) {
1330 "TG4StepManager", "GetSecondary", "Secondary tracks vector is empty");
1331 }
1332
1333 if (index >= nofSecondaries) {
1335 "TG4StepManager", "GetSecondary", "Wrong secondary track index.");
1336 }
1337#endif
1338
1339 // the index of the first secondary of this step
1340 G4int startIndex = secondaryTracks->size() - nofSecondaries;
1341 // (the secondaryTracks vector contains secondaries
1342 // produced by the track at previous steps, too)
1343 G4Track* track = (*secondaryTracks)[startIndex + index];
1344
1345 // particle encoding
1346 particleId = track->GetDynamicParticle()->GetDefinition()->GetPDGEncoding();
1347
1348 // position & time
1349 G4ThreeVector positionVector = track->GetPosition();
1350 positionVector *= 1. / (TG4G3Units::Length());
1351 G4double time = track->GetGlobalTime();
1352 time /= TG4G3Units::Time();
1353 SetTLorentzVector(positionVector, time, position);
1354
1355 // momentum & energy
1356 G4ThreeVector momentumVector = track->GetMomentum();
1357 momentumVector *= 1. / (TG4G3Units::Energy());
1358 G4double energy = track->GetDynamicParticle()->GetTotalEnergy();
1359 energy /= TG4G3Units::Energy();
1360 SetTLorentzVector(momentumVector, energy, momentum);
1361}
1362
1363//_____________________________________________________________________________
1364TMCProcess TG4StepManager::ProdProcess(Int_t isec) const
1365{
1368
1369 G4int nofSecondaries = NSecondaries();
1370 if (fStepStatus == kVertex || !nofSecondaries) return kPNoProcess;
1371
1372#ifdef MCDEBUG
1373 CheckStep("ProdProcess");
1374#endif
1375
1377 // If this funcion is called from SD, it is earlier than TG4SteppingAction
1378 // fixes the creator processes
1379
1380 const G4TrackVector* secondaryTracks = fSteppingManager->GetSecondary();
1381
1382#ifdef MCDEBUG
1383 // should never happen
1384 if (!secondaryTracks) {
1386 "TG4StepManager", "ProdProcess", "Secondary tracks vector is empty.");
1387
1388 return kPNoProcess;
1389 }
1390
1391 if (isec >= nofSecondaries) {
1393 "TG4StepManager", "ProdProcess", "Wrong secondary track index.");
1394
1395 return kPNoProcess;
1396 }
1397#endif
1398
1399 // the index of the first secondary of this step
1400 G4int startIndex = secondaryTracks->size() - nofSecondaries;
1401 // the secondaryTracks vector contains secondaries
1402 // produced by the track at previous steps, too
1403
1404 // the secondary track with specified isec index
1405 G4Track* track = (*secondaryTracks)[startIndex + isec];
1406
1407 const G4VProcess* kpProcess = track->GetCreatorProcess();
1408
1409 TMCProcess mcProcess = TG4PhysicsManager::Instance()->GetMCProcess(kpProcess);
1410
1411 // distinguish kPDeltaRay from kPEnergyLoss
1412 if (mcProcess == kPEnergyLoss) mcProcess = kPDeltaRay;
1413
1414 return mcProcess;
1415}
1416
1417//_____________________________________________________________________________
1418Int_t TG4StepManager::StepProcesses(TArrayI& processes) const
1419{
1424
1427 G4int nofProcesses = 1;
1428 processes.Set(nofProcesses);
1429 processes[0] = kPNull;
1430 return nofProcesses;
1431 }
1432
1433#ifdef MCDEBUG
1435 CheckStep("StepProcesses");
1436#endif
1437
1439 // If this funcion is called from SD, it is earlier than TG4SteppingAction
1440 // fixes the creator processes
1441
1442 // along step processes
1443 G4ProcessVector* processVector = fStep->GetTrack()
1444 ->GetDefinition()
1445 ->GetProcessManager()
1446 ->GetAlongStepProcessVector();
1447 G4int nofAlongStep = processVector->entries();
1448
1449 // process defined step
1450 const G4VProcess* kpLastProcess =
1451 fStep->GetPostStepPoint()->GetProcessDefinedStep();
1452
1453 // set array size
1454 processes.Set(nofAlongStep + 2);
1455 // maximum number of processes:
1456 // nofAlongStep (along step) - 1 (transportations) + 1 (post step process)
1457 // + possibly 2 (additional processes if OpBoundary )
1458 // => nofAlongStep + 2
1459
1460 // fill array with (nofAlongStep-1) along step processes
1462 G4int counter = 0;
1463 for (G4int i = 0; i < nofAlongStep; i++) {
1464 G4VProcess* g4Process = (*processVector)[i];
1465 // do not fill transportation along step process
1466 if (g4Process && g4Process->GetProcessSubType() != TRANSPORTATION)
1467 processes[counter++] = physicsManager->GetMCProcess(g4Process);
1468 }
1469
1470 // fill array with optical photon information
1471 if (fStep->GetTrack()->GetDefinition() == G4OpticalPhoton::Definition() &&
1472 kpLastProcess->GetProcessSubType() == TRANSPORTATION &&
1473 physicsManager->IsOpBoundaryProcess()) {
1474
1475 // add light scattering anbd reflection/absorption as additional processes
1476 processes[counter++] = kPLightScattering;
1477 processes[counter++] = physicsManager->GetOpBoundaryStatus();
1478 }
1479
1480 // fill array with last process
1481 processes[counter++] = physicsManager->GetMCProcess(kpLastProcess);
1482
1483 return counter;
1484}
Definition of the TG4G3Units class.
Definition of the TG4GeometryServices class.
Definition of the TG4Globals class and basic container types.
Definition of the TG4Limits class.
Definition of the TG4ParticlesManager class.
Definition of the TG4PhysicsManager class.
Definition of the TG4SDServices class.
Definition of the TG4StepManager class.
@ kGflashSpot
in post step point with Gflash
@ kBoundary
when crossing geometrical boundary
@ kVertex
in track vertex
@ kNormalStep
in post step point
Definition of the TG4SteppingAction class.
Definition of the TG4TrackInformation class.
Definition of the TG4TrackManager class.
static G4double Mass()
Definition TG4G3Units.h:111
static G4double Charge()
Definition TG4G3Units.h:99
static G4double Energy()
Definition TG4G3Units.h:105
static G4double Length()
Definition TG4G3Units.h:81
static G4double InverseLength()
Definition TG4G3Units.h:135
static G4double InverseTime()
Definition TG4G3Units.h:145
static G4double InverseEnergy()
Definition TG4G3Units.h:157
static G4double Time()
Definition TG4G3Units.h:93
static G4double MassDensity()
Definition TG4G3Units.h:117
Services for accessing to Geant4 geometry.
G4double * CreateG4doubleArray(Float_t *array, G4int size, G4bool copyValues=true) const
const G4String & UserVolumeName(const G4String &name) const
static TG4GeometryServices * Instance()
TG4Limits * GetLimits(G4UserLimits *limits) const
G4double GetEffA(G4Material *material) const
const TG4AssemblyLevels & GetAssemblyLevels(const G4VPhysicalVolume *pv) const
G4double GetEffZ(G4Material *material) const
static void AppendNumberToString(G4String &string, G4int number)
static void Warning(const TString &className, const TString &methodName, const TString &text)
static void Exception(const TString &className, const TString &methodName, const TString &text)
Extended G4UserLimits class.
Definition TG4Limits.h:38
void SetCurrentMaxAllowedStep(G4double step)
G4int GetPDGEncoding(G4ParticleDefinition *particle)
static TG4ParticlesManager * Instance()
Geant4 implementation of the TVirtualMC interface methods for building Geant4 physics and access to i...
static TG4PhysicsManager * Instance()
G4bool IsOpBoundaryProcess() const
TMCProcess GetMCProcess(const G4VProcess *process)
TMCProcess GetOpBoundaryStatus()
G4int GetMediumID(G4LogicalVolume *volume) const
void SetIsStopRun(G4bool stopRun)
G4int GetVolumeID(const G4String &volumeName) const
static TG4SDServices * Instance()
Geant4 implementation of the TVirtualMC interface methods for access to Geant4 at step level.
const char * CurrentVolPath()
G4Track * fTrack
current track
Int_t CurrentMaterial(Float_t &a, Float_t &z, Float_t &dens, Float_t &radl, Float_t &absl) const
Double_t Edep() const
Int_t StepProcesses(TArrayI &proc) const
TMCProcess ProdProcess(Int_t isec) const
void CheckTrack() const
G4int fDivisionCopyNoOffset
division copy number offset
Int_t CurrentVolOffID(Int_t off, Int_t &copyNo) const
void TrackMomentum(TLorentzVector &momentum) const
const char * CurrentVolOffName(Int_t off) const
Bool_t IsTrackStop() const
Bool_t IsTrackDisappeared() const
Bool_t IsTrackEntering() const
Double_t TrackStep() const
TG4StepManager(const TString &userGeometry)
Double_t TrackTime() const
void SetMaxNStep(Int_t maxNofSteps)
const char * CurrentVolName() const
G4String fNameBuffer
buffer for current volume name or path
void GetSecondary(Int_t index, Int_t &particleId, TLorentzVector &position, TLorentzVector &momentum)
Double_t MaxStep() const
G4SteppingManager * fSteppingManager
G4SteppingManager.
TG4Limits * GetCurrentLimits() const
G4VPhysicalVolume * GetOffLevel(G4int off, G4int &component) const
Double_t TrackMass() const
Int_t NSecondaries() const
Double_t NIELEdep() const
void CheckGflashSpot(const G4String &method) const
Bool_t CurrentBoundaryNormal(Double_t &x, Double_t &y, Double_t &z) const
Double_t TrackWeight() const
G4GFlashSpot * fGflashSpot
current Gflash spot
TG4TrackManager * fTrackManager
Cached pointer to thread-local track manager.
TG4StepStatus fStepStatus
step status
const G4VTouchable * GetCurrentTouchable() const
Int_t CurrentVolID(Int_t &copyNo) const
Bool_t IsTrackAlive() const
void CheckSteppingManager() const
Double_t TrackCharge() const
Int_t CurrentMedium() const
Double_t TrackLength() const
Bool_t IsTrackInside() const
static G4ThreadLocal TG4StepManager * fgInstance
this instance
Bool_t IsCollectTracks() const
void Gdtom(Double_t *xd, Double_t *xm, Int_t iflag)
G4int fCopyNoOffset
volume copy number offset
Bool_t IsNewTrack() const
Bool_t IsTrackOut() const
void CheckStep(const G4String &method) const
Int_t StepNumber() const
G4VPhysicalVolume * GetCurrentPhysicalVolume() const
TG4Limits * fLimitsModifiedOnFly
limits which step limit was modified during tracking
void SetTLorentzVector(G4ThreeVector xyz, G4double t, TLorentzVector &lv) const
Bool_t IsTrackExiting() const
Int_t TrackPid() const
void Gmtod(Double_t *xm, Double_t *xd, Int_t iflag)
TMCParticleStatus * fInitialVMCTrackStatus
The initial status of a VMC track when it was popped from the VMC stack.
void SetCollectTracks(Bool_t collectTracks)
void ForceDecayTime(Float_t pdg)
G4Step * fStep
current step
void TrackPolarization(Double_t &polX, Double_t &polY, Double_t &polZ) const
Int_t GetMaxNStep() const
G4VPhysicalVolume * GetCurrentOffPhysicalVolume(G4int off, G4bool warn=false) const
Double_t Etot() const
void TrackPosition(TLorentzVector &position) const
void SetInitialVMCTrackStatus(TMCParticleStatus *status)
void SetMaxStep(Double_t step)
void SetMaxNofSteps(G4int number)
void SetCollectTracks(G4bool collectTracks)
void ProcessTrackIfGeneralProcess(const G4Step *step)
G4bool GetCollectTracks() const
static TG4SteppingAction * Instance()
G4int GetMaxNofSteps() const
Defines additional track information.
G4int GetPDGEncoding() const
void SetPDGLifetime(G4double pdgLifetime)
static TG4TrackManager * Instance()
std::vector< G4int > fCopyNos
-1 where the Geant4 copy number applies
std::vector< G4String > fNames
outermost first; last is the placed volume