13 #include <simulation/monopoles/G4MonopoleTransportation.h>
14 #include <simulation/monopoles/G4Monopole.h>
16 #include <G4ProductionCutsTable.hh>
17 #include <G4ParticleTable.hh>
18 #include <G4ChordFinder.hh>
19 #include <G4SafetyHelper.hh>
20 #include <G4FieldManagerStore.hh>
21 #include <G4TransportationProcessType.hh>
22 #include <CLHEP/Units/SystemOfUnits.h>
23 #include <framework/logging/Logger.h>
25 class G4VSensitiveDetector;
29 using namespace Belle2::Monopoles;
30 using namespace CLHEP;
32 G4MonopoleTransportation::G4MonopoleTransportation(
const G4Monopole* mpl,
34 : G4VProcess(G4String(
"MonopoleTransportation"), fTransportation),
39 fParticleIsLooping(false),
40 fPreviousSftOrigin(0., 0., 0.),
42 fThreshold_Trap_Energy(10 * MeV),
43 fThreshold_Warning_Energy(100 * MeV),
44 fThreshold_Important_Energy(250 * MeV),
47 fSumEnergyKilled(0.0), fMaxEnergyKilled(0.0),
48 fShortStepOptimisation(false),
54 SetProcessSubType(TRANSPORTATION);
58 G4TransportationManager* transportMgr ;
60 transportMgr = G4TransportationManager::GetTransportationManager() ;
76 static G4TouchableHandle nullTouchableHandle;
86 B2DEBUG(25,
" G4MonopoleTransportation: Statistics for looping particles ");
100 G4double currentMinimumStep,
101 G4double& currentSafety,
102 G4GPILSelection* selection)
107 G4double geometryStepLength, newSafety ;
119 *selection = CandidateForSelection ;
123 const G4DynamicParticle* pParticle = track.GetDynamicParticle() ;
124 G4ThreeVector startMomentumDir = pParticle->GetMomentumDirection() ;
125 G4ThreeVector startPosition = track.GetPosition() ;
134 G4double MagSqShift = OriginShift.mag2() ;
136 currentSafety = 0.0 ;
144 G4double particleElectricCharge = pParticle->GetCharge();
155 G4FieldManager* fieldMgr =
nullptr;
156 G4bool fieldExertsForce = false ;
158 if ((particleMagneticCharge != 0.0)) {
162 fieldMgr->ConfigureForTrack(&track);
168 fieldExertsForce = (fieldMgr->GetDetectorField() != 0);
174 if (!fieldExertsForce) {
175 G4double linearStepLength ;
179 geometryStepLength = currentMinimumStep ;
196 currentSafety = newSafety ;
201 geometryStepLength = linearStepLength ;
204 geometryStepLength = currentMinimumStep ;
222 G4double momentumMagnitude = pParticle->GetTotalMomentum() ;
223 G4ThreeVector EndUnitMomentum ;
224 G4double lengthAlongCurve ;
227 G4ChargeState chargeState(particleElectricCharge,
231 particleMagneticCharge);
233 G4EquationOfMotion* equationOfMotion =
235 ->GetEquationOfMotion();
238 ->SetChargeMomentumMass(chargeState,
243 G4ThreeVector spin = track.GetPolarization() ;
244 G4FieldTrack aFieldTrack = G4FieldTrack(startPosition,
245 track.GetMomentumDirection(),
247 track.GetKineticEnergy(),
250 track.GetGlobalTime(),
251 track.GetProperTime(),
253 if (currentMinimumStep > 0) {
262 geometryStepLength = lengthAlongCurve ;
264 geometryStepLength = currentMinimumStep ;
267 geometryStepLength = lengthAlongCurve = 0.0 ;
299 if (currentMinimumStep == 0.0) {
310 if (particleMagneticCharge != 0.0) {
314 currentSafety = endSafety ;
324 #ifdef G4DEBUG_TRANSPORT
325 G4cout.precision(12) ;
326 G4cout <<
"***G4MonopoleTransportation::AlongStepGPIL ** " << G4endl ;
328 <<
" and it returned safety= " << endSafety << G4endl ;
330 <<
" to obtain pseudo-safety= " << currentSafety << G4endl ;
340 return geometryStepLength ;
348 const G4Step& stepData)
350 static G4int noCalls = 0;
351 static const G4ParticleDefinition* fOpticalPhoton =
352 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();