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")
83}
84
85//_____________________________________________________________________________
92
93//
94// private methods
95//
96
97//_____________________________________________________________________________
99{
101
102 if (!fTrack)
104 "TG4StepManager", "CheckTrack", "Track is not defined.");
105}
106
107//_____________________________________________________________________________
108void TG4StepManager::CheckStep(const G4String& method) const
109{
111
112 if (!fStep) {
113 TG4Globals::Exception("TG4StepManager", method, "Step is not defined.");
114 }
115}
116
117//_____________________________________________________________________________
118void TG4StepManager::CheckGflashSpot(const G4String& method) const
119{
121
122 if (!fGflashSpot) {
124 "TG4StepManager", method, "Gflash spot is not defined.");
125 }
126}
127
128//_____________________________________________________________________________
130{
132
133 if (!fSteppingManager)
134 TG4Globals::Exception("TG4StepManager", "CheckSteppingManager",
135 "Stepping manager is not defined.");
136}
137
138//_____________________________________________________________________________
140 G4ThreeVector xyz, G4double t, TLorentzVector& lv) const
141{
143
144 lv[0] = xyz.x();
145 lv[1] = xyz.y();
146 lv[2] = xyz.z();
147 lv[3] = t;
148}
149
150//_____________________________________________________________________________
151const G4VTouchable* TG4StepManager::GetCurrentTouchable() const
152{
154
155#ifdef MCDEBUG
156 CheckTrack();
157#endif
158
159 if (fStepStatus == kGflashSpot) {
160 G4ReferenceCountedHandle<G4VTouchable> touchableHandle =
161 fGflashSpot->GetTouchableHandle();
162 return touchableHandle();
163 }
164 else if (fStepStatus != kBoundary)
165 return fTrack->GetTouchable();
166 else
167 return fTrack->GetNextTouchable();
168}
169
170//_____________________________________________________________________________
172 G4int off, G4int& component) const
173{
178
179 const G4VTouchable* touchable = GetCurrentTouchable();
180 G4int remaining = off;
181 G4bool crossedAssembly = false;
182
183 for (G4int level = 0; level <= touchable->GetHistoryDepth(); ++level) {
184 G4VPhysicalVolume* pv = touchable->GetVolume(level);
185 if (pv == 0) break;
186
187 const TG4AssemblyLevels& levels =
189 const G4int nofLevels =
190 levels.fNames.empty() ? 1 : G4int(levels.fNames.size());
191
192 if (remaining < nofLevels) {
193 if (nofLevels == 1 && !crossedAssembly) return 0;
194 component = levels.fNames.empty() ? -1 : nofLevels - 1 - remaining;
195 return pv;
196 }
197 crossedAssembly = crossedAssembly || nofLevels > 1;
198 remaining -= nofLevels;
199 }
200 return 0;
201}
202
203//_____________________________________________________________________________
205 G4int off, G4bool warn) const
206{
209
210 // Get current touchable
211 //
212 const G4VTouchable* touchable = GetCurrentTouchable();
213
214 // Check touchable depth
215 //
216 if (touchable->GetHistoryDepth() < off) {
217 if (warn) {
218 TString text = "level=";
219 text += off;
220 TG4Globals::Warning("TG4StepManager", "GetCurrentOffPhysicalVolume",
221 "Volume " + TString(touchable->GetVolume()->GetName()) +
222 " has not defined mother in " + text + ".");
223 }
224 return 0;
225 }
226
227 return touchable->GetVolume(off);
228}
229
230//
231// public methods
232//
233
234//_____________________________________________________________________________
239
240//_____________________________________________________________________________
242{
250
251 if (fTrack) {
252 fTrack->SetTrackStatus(fStopAndKill);
253 // fTrack->SetTrackStatus(fStopButAlive);
254 // fTrack->SetTrackStatus(fKillTrackAndSecondaries);
255 }
256 else {
257 TG4Globals::Warning("TG4StepManager", "StopTrack()",
258 "There is no current track to be stopped.");
259 }
260}
261
262//_____________________________________________________________________________
264{
266
267 if (fTrack) {
268 fTrack->SetTrackStatus(fStopAndKill);
269 fTrackManager->GetTrackInformation(fTrack)->SetInterrupt(true);
270 }
271 else {
272 TG4Globals::Warning("TG4StepManager", "InterruptTrack()",
273 "There is no current track to be interrupted.");
274 }
275}
276
277//_____________________________________________________________________________
279{
281
282 if (fTrack) {
283 fTrack->SetTrackStatus(fKillTrackAndSecondaries);
284 // StopTrack(); // cannot be used as it keeps secondaries
285 }
286
287 G4UImanager::GetUIpointer()->ApplyCommand("/event/abort");
288}
289
290//_____________________________________________________________________________
292{
294
296
297 StopEvent();
298 G4UImanager::GetUIpointer()->ApplyCommand("/run/abort");
299}
300
301//_____________________________________________________________________________
302void TG4StepManager::SetMaxStep(Double_t step)
303{
307
308 TG4Limits* userLimits = GetCurrentLimits();
309
310 if (!userLimits) return;
311
312 // G4cout << "TG4StepManager::SetMaxStep in "
313 // << GetCurrentPhysicalVolume()->GetLogicalVolume()->GetName() << " "
314 // << userLimits->GetName() << G4endl;
315
316 // set max step
317 userLimits->SetCurrentMaxAllowedStep(step * TG4G3Units::Length());
318 fLimitsModifiedOnFly = userLimits;
319}
320
321//_____________________________________________________________________________
323{
326
329 "TG4StepManager", "SetMaxStepBack", "No limits modified on fly found.");
330 return;
331 }
332
333 // set max step
334 fLimitsModifiedOnFly->SetMaxAllowedStepBack();
336}
337
338//_____________________________________________________________________________
339void TG4StepManager::SetMaxNStep(Int_t maxNofSteps)
340{
342
343 TG4SteppingAction::Instance()->SetMaxNofSteps(TMath::Abs(maxNofSteps));
344}
345
346//_____________________________________________________________________________
347void TG4StepManager::SetCollectTracks(Bool_t collectTracks)
348{
350
352}
353
354//_____________________________________________________________________________
356{
358
359#ifdef MCDEBUG
360 CheckTrack();
361#endif
362
363 G4ParticleDefinition* particle =
364 fTrack->GetDynamicParticle()->GetDefinition();
365
366 // Store the original particle lifetime in track information
367 // (as it has to be set back after track is finished)
368 TG4TrackInformation* trackInformation =
369 fTrackManager->GetTrackInformation(fTrack);
370 trackInformation->SetPDGLifetime(particle->GetPDGLifeTime());
371
372 // Set new lifetime value
373 particle->SetPDGLifeTime(time * TG4G3Units::Time());
374}
375
376//_____________________________________________________________________________
377void TG4StepManager::SetInitialVMCTrackStatus(TMCParticleStatus* status)
378{
381
382 fInitialVMCTrackStatus = status;
383}
384
385//_____________________________________________________________________________
392
393//_____________________________________________________________________________
395{
399
400#ifdef MCDEBUG
401 CheckTrack();
402#endif
403
405 return fGflashSpot->GetTouchableHandle()->GetVolume();
406 else if (fStepStatus != kBoundary)
407 return fTrack->GetVolume();
408 else
409 return fTrack->GetNextVolume();
410}
411
412//_____________________________________________________________________________
414{
416
417#ifdef MCDEBUG
419 GetCurrentPhysicalVolume()->GetLogicalVolume()->GetUserLimits());
420#else
421 TG4Limits* userLimits =
422 (TG4Limits*)GetCurrentPhysicalVolume()->GetLogicalVolume()->GetUserLimits();
423#endif
424
425 if (!userLimits) {
427 "TG4StepManager", "Get current limits", "User limits not defined.");
428 return 0;
429 }
430
431 return userLimits;
432}
433
434//_____________________________________________________________________________
435Int_t TG4StepManager::CurrentVolID(Int_t& copyNo) const
436{
439
440 G4VPhysicalVolume* physVolume = GetCurrentPhysicalVolume();
441 if (!physVolume) {
443 "TG4StepManager", "CurrentVolID", "No current physical volume found");
444 return 0;
445 }
446 copyNo = physVolume->GetCopyNo() + fCopyNoOffset;
447
448 if (physVolume->IsParameterised() || physVolume->IsReplicated())
449 copyNo += fDivisionCopyNoOffset;
450
451 // sensitive detector ID
452 return TG4SDServices::Instance()->GetVolumeID(physVolume->GetLogicalVolume());
453}
454
455//_____________________________________________________________________________
456Int_t TG4StepManager::CurrentVolOffID(Int_t off, Int_t& copyNo) const
457{
460
461 if (off == 0) return CurrentVolID(copyNo);
462
463 G4int component = -1;
464 if (G4VPhysicalVolume* pv = GetOffLevel(off, component)) {
465 const TG4AssemblyLevels& levels =
467 const G4int encoded =
468 (component >= 0 && component < G4int(levels.fCopyNos.size()))
469 ? levels.fCopyNos[component]
470 : -1;
471 copyNo = (encoded >= 0 ? encoded : pv->GetCopyNo()) + fCopyNoOffset;
472 // a collapsed assembly has no Geant4 logical volume of its own, so the id
473 // returned for such a level is the placed volume's; only copyNo is meaningful
474 return TG4SDServices::Instance()->GetVolumeID(pv->GetLogicalVolume());
475 }
476
477#ifdef MCDEBUG
478 G4VPhysicalVolume* mother = GetCurrentOffPhysicalVolume(off, true);
479#else
480 G4VPhysicalVolume* mother = GetCurrentOffPhysicalVolume(off);
481#endif
482
483 if (mother) {
484 copyNo = mother->GetCopyNo() + fCopyNoOffset;
485
486 if (mother->IsParameterised() || mother->IsReplicated())
487 copyNo += fDivisionCopyNoOffset;
488
489 // sensitive detector ID
490 return TG4SDServices::Instance()->GetVolumeID(mother->GetLogicalVolume());
491 }
492 else {
493 copyNo = 0;
494 return 0;
495 }
496}
497
498//_____________________________________________________________________________
500{
502
504 GetCurrentPhysicalVolume()->GetLogicalVolume()->GetName());
505
506 return fNameBuffer.data();
507}
508
509//_____________________________________________________________________________
510const char* TG4StepManager::CurrentVolOffName(Int_t off) const
511{
513
514 if (off == 0) return CurrentVolName();
515
516 G4int component = -1;
517 if (G4VPhysicalVolume* pv = GetOffLevel(off, component)) {
518 const TG4AssemblyLevels& levels =
520 const G4String& name =
521 (component >= 0 && component < G4int(levels.fNames.size()))
522 ? levels.fNames[component]
523 : pv->GetLogicalVolume()->GetName();
525 return fNameBuffer.data();
526 }
527
528 G4VPhysicalVolume* mother = GetCurrentOffPhysicalVolume(off);
529
530 if (mother) {
532 mother->GetLogicalVolume()->GetName());
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