11#include <simulation/monopoles/G4MonopoleTransportation.h>
12#include <simulation/monopoles/G4Monopole.h>
14#include <G4ProductionCutsTable.hh>
15#include <G4ParticleTable.hh>
16#include <G4ChordFinder.hh>
17#include <G4SafetyHelper.hh>
18#include <G4FieldManagerStore.hh>
19#include <G4TransportationProcessType.hh>
20#include <CLHEP/Units/SystemOfUnits.h>
21#include <framework/logging/Logger.h>
23class G4VSensitiveDetector;
27using namespace Belle2::Monopoles;
32 : G4VProcess(G4String(
"MonopoleTransportation"), fTransportation),
37 fParticleIsLooping(false),
38 fPreviousSftOrigin(0., 0., 0.),
40 fThreshold_Trap_Energy(10 * MeV),
41 fThreshold_Warning_Energy(100 * MeV),
42 fThreshold_Important_Energy(250 * MeV),
45 fSumEnergyKilled(0.0), fMaxEnergyKilled(0.0),
46 fShortStepOptimisation(false),
52 SetProcessSubType(TRANSPORTATION);
56 G4TransportationManager* transportMgr ;
58 transportMgr = G4TransportationManager::GetTransportationManager() ;
74 static G4TouchableHandle nullTouchableHandle;
84 B2DEBUG(25,
" G4MonopoleTransportation: Statistics for looping particles ");
98 G4double currentMinimumStep,
99 G4double& currentSafety,
100 G4GPILSelection* selection)
105 G4double geometryStepLength, newSafety ;
117 *selection = CandidateForSelection ;
121 const G4DynamicParticle* pParticle = track.GetDynamicParticle() ;
122 G4ThreeVector startMomentumDir = pParticle->GetMomentumDirection() ;
123 G4ThreeVector startPosition = track.GetPosition() ;
132 G4double MagSqShift = OriginShift.mag2() ;
134 currentSafety = 0.0 ;
142 G4double particleElectricCharge = pParticle->GetCharge();
153 G4FieldManager* fieldMgr =
nullptr;
154 G4bool fieldExertsForce = false ;
156 if ((particleMagneticCharge != 0.0)) {
160 fieldMgr->ConfigureForTrack(&track);
166 fieldExertsForce = (fieldMgr->GetDetectorField() != 0);
172 if (!fieldExertsForce) {
173 G4double linearStepLength ;
177 geometryStepLength = currentMinimumStep ;
194 currentSafety = newSafety ;
199 geometryStepLength = linearStepLength ;
202 geometryStepLength = currentMinimumStep ;
220 G4double momentumMagnitude = pParticle->GetTotalMomentum() ;
221 G4ThreeVector EndUnitMomentum ;
224 G4ChargeState chargeState(particleElectricCharge,
228 particleMagneticCharge);
230 G4EquationOfMotion* equationOfMotion =
232 ->GetEquationOfMotion();
235 ->SetChargeMomentumMass(chargeState,
240 G4ThreeVector spin = track.GetPolarization() ;
241 G4FieldTrack aFieldTrack = G4FieldTrack(startPosition,
242 track.GetMomentumDirection(),
244 track.GetKineticEnergy(),
247 track.GetGlobalTime(),
248 track.GetProperTime(),
250 if (currentMinimumStep > 0) {
260 geometryStepLength = lengthAlongCurve ;
262 geometryStepLength = currentMinimumStep ;
265 geometryStepLength = 0.0 ;
297 if (currentMinimumStep == 0.0) {
308 if (particleMagneticCharge != 0.0) {
312 currentSafety = endSafety ;
322#ifdef G4DEBUG_TRANSPORT
323 G4cout.precision(12) ;
324 G4cout <<
"***G4MonopoleTransportation::AlongStepGPIL ** " << G4endl ;
326 <<
" and it returned safety= " << endSafety << G4endl ;
328 <<
" to obtain pseudo-safety= " << currentSafety << G4endl ;
338 return geometryStepLength ;
346 const G4Step& stepData)
349 static G4int noCalls = 0;
353 static const G4ParticleDefinition* fOpticalPhoton =
354 G4ParticleTable::GetParticleTable()->FindParticle(
"opticalphoton");
367 G4double deltaTime = 0.0 ;
373 G4double startTime = track.GetGlobalTime() ;
378 G4double finalVelocity = track.GetVelocity() ;
379 G4double initialVelocity = stepData.GetPreStepPoint()->GetVelocity() ;
380 G4double stepLength = track.GetStepLength() ;
383 const G4DynamicParticle* fpDynamicParticle = track.GetDynamicParticle();
384 if (fpDynamicParticle->GetDefinition() == fOpticalPhoton) {
387 deltaTime = stepLength / finalVelocity ;
388 }
else if (finalVelocity > 0.0) {
389 G4double meanInverseVelocity ;
391 meanInverseVelocity = 0.5
392 * (1.0 / initialVelocity + 1.0 / finalVelocity) ;
393 deltaTime = stepLength * meanInverseVelocity ;
394 }
else if (initialVelocity > 0.0) {
395 deltaTime = stepLength / initialVelocity ;
406 G4double restMass = track.GetDynamicParticle()->GetMass() ;
407 G4double deltaProperTime = deltaTime * (restMass / track.GetTotalEnergy()) ;
409 fParticleChange.ProposeProperTime(track.GetProperTime() + deltaProperTime) ;
430 if ((verboseLevel > 1) ||
432 B2DEBUG(25,
" G4MonopoleTransportation is killing track that is looping or stuck ");
433 B2DEBUG(25,
" This track has " << track.GetKineticEnergy() / MeV <<
" MeV energy.");
435 <<
" No of calls to AlongStepDoIt = " << noCalls);
442 if ((verboseLevel > 2)) {
443 B2DEBUG(25,
" G4MonopoleTransportation::AlongStepDoIt(): Particle looping - "
445 <<
" No of calls to = " << noCalls);
478 G4ForceCondition* pForceCond)
480 *pForceCond = Forced ;
487 G4TouchableHandle retCurrentTouchable ;
505 LocateGlobalPointAndUpdateTouchableHandle(track.GetPosition(),
506 track.GetMomentumDirection(),
528 retCurrentTouchable = track.GetTouchableHandle() ;
531 const G4VPhysicalVolume* pNewVol = retCurrentTouchable->GetVolume() ;
532 G4Material* pNewMaterial = nullptr ;
533 G4VSensitiveDetector* pNewSensitiveDetector = nullptr ;
536 pNewMaterial = pNewVol->GetLogicalVolume()->GetMaterial();
537 pNewSensitiveDetector = pNewVol->GetLogicalVolume()->GetSensitiveDetector();
543 pNewSensitiveDetector) ;
545 const G4MaterialCutsCouple* pNewMaterialCutsCouple = 0;
547 pNewMaterialCutsCouple = pNewVol->GetLogicalVolume()->GetMaterialCutsCouple();
550 if (pNewVol != 0 && pNewMaterialCutsCouple != 0 &&
551 pNewMaterialCutsCouple->GetMaterial() != pNewMaterial) {
554 pNewMaterialCutsCouple =
555 G4ProductionCutsTable::GetProductionCutsTable()
556 ->GetMaterialCutsCouple(pNewMaterial,
557 pNewMaterialCutsCouple->GetProductionCuts());
559 fParticleChange.SetMaterialCutsCoupleInTouchable(pNewMaterialCutsCouple);
579 G4VProcess::StartTracking(aTrack);
607 static G4FieldManagerStore* fieldMgrStore = G4FieldManagerStore::GetInstance();
608 fieldMgrStore->ClearAllChordFindersState();
void SwitchChordFinder(G4int val)
Switches chord finder between 1 - basf2 FullSim chord finder 2 - monopole chord finder Since monopole...
static G4MonopoleFieldSetup * GetMonopoleFieldSetup()
Returns G4MonopoleFieldSetup instance.
G4TouchableHandle fCurrentTouchableHandle
Current touchable handle.
G4double endpointDistance
Endpint distance.
virtual G4VParticleChange * PostStepDoIt(const G4Track &track, const G4Step &stepData)
G4VProcess::PostStepDoIt() implementation.
G4double fCandidateEndGlobalTime
The particle's state after this Step, Store for DoIt.
virtual G4double AlongStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4double currentMinimumStep, G4double ¤tSafety, G4GPILSelection *selection)
G4VProcess::AlongStepGetPhysicalInteractionLength() implementation.
G4int fThresholdTrials
Nubmer of trials for looping particles.
G4double fMaxEnergyKilled
Max of abandoned looping tracks energies.
G4bool fGeometryLimitedStep
Flag to determine whether a boundary was reached.
~G4MonopoleTransportation()
Destructor.
G4ThreeVector fTransportEndMomentumDir
The particle's state after this Step, Store for DoIt.
G4double fPreviousSafety
Remember last safety value.
virtual G4VParticleChange * AlongStepDoIt(const G4Track &track, const G4Step &stepData)
G4VProcess::AlongStepDoIt() implementation, Proposes changes during step to fParticleChange of this c...
G4SafetyHelper * fpSafetyHelper
To pass it the safety value obtained.
G4double fSumEnergyKilled
Sum of abandoned looping tracks energies.
G4ThreeVector fPreviousSftOrigin
Remember last safety origin.
virtual G4double PostStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4ForceCondition *pForceCond)
G4VProcess::PostStepGetPhysicalInteractionLength() implementation.
G4ThreeVector fTransportEndSpin
The particle's state after this Step, Store for DoIt.
G4Navigator * fLinearNavigator
Propagator used to transport the particle.
G4double fThreshold_Important_Energy
Hesitate above this about looping particle for a certain no of trials.
G4ThreeVector fTransportEndPosition
The particle's state after this Step, Store for DoIt.
G4bool fEndGlobalTimeComputed
The particle's state after this Step, Store for DoIt.
G4bool fShortStepOptimisation
Whether to avoid calling G4Navigator for short step ( < safety) If using it, the safety estimate for ...
G4int fNoLooperTrials
Counter for steps in which particle reports 'looping', if it is above 'Important' Energy.
G4bool fMomentumChanged
The particle's state after this Step, Store for DoIt.
virtual void StartTracking(G4Track *aTrack)
Reset state for new (potentially resumed) track.
G4ParticleChangeForTransport fParticleChange
New ParticleChange.
G4MonopoleTransportation(const G4Monopole *mpl, G4int verb=1)
Constructor.
G4double fThreshold_Warning_Energy
Warn above this energy about looping particle.
G4bool DoesGlobalFieldExist()
Checks whether a field exists for the "global" field manager.
const G4Monopole * fParticleDef
Monopole definition for charge and mass reference.
G4bool fParticleIsLooping
Is the monopole stuck in looping.
G4double fThreshold_Trap_Energy
Assume monopoles below this can bound to material.
G4PropagatorInField * fFieldPropagator
Propagator used to transport the particle.
G4double fTransportEndKineticEnergy
The particle's state after this Step, Store for DoIt.
G4MonopoleFieldSetup * fMagSetup
Monpole field setup.
A class to hold monopole description as a particle.
G4double MagneticCharge() const
Returns magnetic charge of the monopole.
Abstract base class for different kinds of events.