Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 /// \file exoticphysics/monopole/src/G4MonopoleTransportation.cc 27 /// \brief Implementation of the G4MonopoleTransportation class 28 // 29 // 30 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 31 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 32 // 33 // This class is a process responsible for the transportation of 34 // magnetic monopoles, ie the geometrical propagation that encounters the 35 // geometrical sub-volumes of the detectors. 36 // 37 // For monopoles, uses a different equation of motion and ignores energy 38 // conservation. 39 // 40 41 // ======================================================================= 42 // Created: 3 May 2010, J. Apostolakis, B. Bozsogi 43 // ======================================================================= 44 45 #include "G4MonopoleTransportation.hh" 46 47 #include "DetectorConstruction.hh" 48 49 #include "G4ChordFinder.hh" 50 #include "G4FieldManagerStore.hh" 51 #include "G4Monopole.hh" 52 #include "G4ParticleTable.hh" 53 #include "G4ProductionCutsTable.hh" 54 #include "G4RunManager.hh" 55 #include "G4SafetyHelper.hh" 56 #include "G4SystemOfUnits.hh" 57 #include "G4TransportationProcessType.hh" 58 59 class G4VSensitiveDetector; 60 61 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 62 63 G4MonopoleTransportation::G4MonopoleTransportation(const G4Monopole* mpl, G4int verb) 64 : G4VProcess(G4String("MonopoleTransportation"), fTransportation), 65 fParticleDef(mpl), 66 fMagSetup(0), 67 fLinearNavigator(0), 68 fFieldPropagator(0), 69 fParticleIsLooping(false), 70 fPreviousSftOrigin(0., 0., 0.), 71 fPreviousSafety(0.0), 72 fThreshold_Warning_Energy(100 * MeV), 73 fThreshold_Important_Energy(250 * MeV), 74 fThresholdTrials(10), 75 // fUnimportant_Energy( 1 * MeV ), 76 fNoLooperTrials(0), 77 fSumEnergyKilled(0.0), 78 fMaxEnergyKilled(0.0), 79 fShortStepOptimisation(false), // Old default: true (=fast short steps) 80 fpSafetyHelper(0), 81 noCalls(0) 82 { 83 verboseLevel = verb; 84 85 // set Process Sub Type 86 SetProcessSubType(TRANSPORTATION); 87 88 // Do not finalize the G4MonopoleTransportation class 89 if (G4Threading::IsMasterThread() && G4Threading::IsMultithreadedApplication()) { 90 return; 91 } 92 93 const DetectorConstruction* detector = static_cast<const DetectorConstruction*>( 94 G4RunManager::GetRunManager()->GetUserDetectorConstruction()); 95 96 fMagSetup = detector->GetMonopoleFieldSetup(); 97 98 G4TransportationManager* transportMgr = G4TransportationManager::GetTransportationManager(); 99 100 fLinearNavigator = transportMgr->GetNavigatorForTracking(); 101 102 fFieldPropagator = transportMgr->GetPropagatorInField(); 103 fpSafetyHelper = transportMgr->GetSafetyHelper(); 104 105 // New 106 107 // Cannot determine whether a field exists here, 108 // because it would only work if the field manager has informed 109 // about the detector's field before this transportation process 110 // is constructed. 111 // Instead later the method DoesGlobalFieldExist() is called 112 fCurrentTouchableHandle = nullptr; 113 114 fEndGlobalTimeComputed = false; 115 fCandidateEndGlobalTime = 0; 116 } 117 118 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 119 120 G4MonopoleTransportation::~G4MonopoleTransportation() 121 { 122 if ((verboseLevel > 0) && (fSumEnergyKilled > 0.0)) { 123 G4cout << " G4MonopoleTransportation: Statistics for looping particles " << G4endl; 124 G4cout << " Sum of energy of loopers killed: " << fSumEnergyKilled << G4endl; 125 G4cout << " Max energy of loopers killed: " << fMaxEnergyKilled << G4endl; 126 } 127 } 128 129 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 130 // 131 // Responsibilities: 132 // Find whether the geometry limits the Step, and to what length 133 // Calculate the new value of the safety and return it. 134 // Store the final time, position and momentum. 135 136 G4double G4MonopoleTransportation::AlongStepGetPhysicalInteractionLength( 137 const G4Track& track, 138 G4double, // previousStepSize 139 G4double currentMinimumStep, G4double& currentSafety, G4GPILSelection* selection) 140 { 141 fMagSetup->SetStepperAndChordFinder(1); 142 // change to monopole equation 143 144 G4double geometryStepLength, newSafety; 145 fParticleIsLooping = false; 146 147 // Initial actions moved to StartTrack() 148 // -------------------------------------- 149 // Note: in case another process changes touchable handle 150 // it will be necessary to add here (for all steps) 151 // fCurrentTouchableHandle = aTrack->GetTouchableHandle(); 152 153 // GPILSelection is set to defaule value of CandidateForSelection 154 // It is a return value 155 // 156 *selection = CandidateForSelection; 157 158 // Get initial Energy/Momentum of the track 159 // 160 const G4DynamicParticle* pParticle = track.GetDynamicParticle(); 161 G4ThreeVector startMomentumDir = pParticle->GetMomentumDirection(); 162 G4ThreeVector startPosition = track.GetPosition(); 163 164 // G4double theTime = track.GetGlobalTime() ; 165 166 // The Step Point safety can be limited by other geometries and/or the 167 // assumptions of any process - it's not always the geometrical safety. 168 // We calculate the starting point's isotropic safety here. 169 // 170 G4ThreeVector OriginShift = startPosition - fPreviousSftOrigin; 171 G4double MagSqShift = OriginShift.mag2(); 172 if (MagSqShift >= sqr(fPreviousSafety)) { 173 currentSafety = 0.0; 174 } 175 else { 176 currentSafety = fPreviousSafety - std::sqrt(MagSqShift); 177 } 178 179 // Is the monopole charged ? 180 // 181 G4double particleMagneticCharge = fParticleDef->MagneticCharge(); 182 G4double particleElectricCharge = pParticle->GetCharge(); 183 184 fGeometryLimitedStep = false; 185 // fEndGlobalTimeComputed = false ; 186 187 // There is no need to locate the current volume. It is Done elsewhere: 188 // On track construction 189 // By the tracking, after all AlongStepDoIts, in "Relocation" 190 191 // Check whether the particle have an (EM) field force exerting upon it 192 // 193 G4FieldManager* fieldMgr = 0; 194 G4bool fieldExertsForce = false; 195 196 if ((particleMagneticCharge != 0.0)) { 197 fieldMgr = fFieldPropagator->FindAndSetFieldManager(track.GetVolume()); 198 if (fieldMgr != 0) { 199 // Message the field Manager, to configure it for this track 200 fieldMgr->ConfigureForTrack(&track); 201 // Moved here, in order to allow a transition 202 // from a zero-field status (with fieldMgr->(field)0 203 // to a finite field status 204 205 // If the field manager has no field, there is no field ! 206 fieldExertsForce = (fieldMgr->GetDetectorField() != 0); 207 } 208 } 209 210 // G4cout << " G4Transport: field exerts force= " << fieldExertsForce 211 // << " fieldMgr= " << fieldMgr << G4endl; 212 213 // Choose the calculation of the transportation: Field or not 214 // 215 if (!fieldExertsForce) { 216 G4double linearStepLength; 217 if (fShortStepOptimisation && (currentMinimumStep <= currentSafety)) { 218 // The Step is guaranteed to be taken 219 // 220 geometryStepLength = currentMinimumStep; 221 fGeometryLimitedStep = false; 222 } 223 else { 224 // Find whether the straight path intersects a volume 225 // 226 linearStepLength = fLinearNavigator->ComputeStep(startPosition, startMomentumDir, 227 currentMinimumStep, newSafety); 228 // Remember last safety origin & value. 229 // 230 fPreviousSftOrigin = startPosition; 231 fPreviousSafety = newSafety; 232 // fpSafetyHelper->SetCurrentSafety( newSafety, startPosition); 233 234 // The safety at the initial point has been re-calculated: 235 // 236 currentSafety = newSafety; 237 238 fGeometryLimitedStep = (linearStepLength <= currentMinimumStep); 239 if (fGeometryLimitedStep) { 240 // The geometry limits the Step size (an intersection was found.) 241 geometryStepLength = linearStepLength; 242 } 243 else { 244 // The full Step is taken. 245 geometryStepLength = currentMinimumStep; 246 } 247 } 248 endpointDistance = geometryStepLength; 249 250 // Calculate final position 251 // 252 fTransportEndPosition = startPosition + geometryStepLength * startMomentumDir; 253 254 // Momentum direction, energy and polarisation are unchanged by transport 255 // 256 fTransportEndMomentumDir = startMomentumDir; 257 fTransportEndKineticEnergy = track.GetKineticEnergy(); 258 fTransportEndSpin = track.GetPolarization(); 259 fParticleIsLooping = false; 260 fMomentumChanged = false; 261 fEndGlobalTimeComputed = false; 262 } 263 else // A field exerts force 264 { 265 G4double momentumMagnitude = pParticle->GetTotalMomentum(); 266 G4ThreeVector EndUnitMomentum; 267 G4double lengthAlongCurve; 268 G4double restMass = fParticleDef->GetPDGMass(); 269 270 G4ChargeState chargeState(particleElectricCharge, // The charge can change 271 fParticleDef->GetPDGSpin(), 272 0, // Magnetic moment: 273 0, // Electric Dipole moment 274 particleMagneticCharge); // in Mev/c 275 276 G4EquationOfMotion* equationOfMotion = 277 fFieldPropagator->GetChordFinder()->GetIntegrationDriver()->GetEquationOfMotion(); 278 279 equationOfMotion->SetChargeMomentumMass(chargeState, momentumMagnitude, restMass); 280 // SetChargeMomentumMass now passes both the electric and magnetic 281 // charge in chargeState 282 283 G4ThreeVector spin = track.GetPolarization(); 284 G4FieldTrack aFieldTrack = G4FieldTrack(startPosition, track.GetMomentumDirection(), 0.0, 285 track.GetKineticEnergy(), restMass, track.GetVelocity(), 286 track.GetGlobalTime(), // Lab. 287 track.GetProperTime(), // Part. 288 &spin); 289 if (currentMinimumStep > 0) { 290 // Do the Transport in the field (non recti-linear) 291 // 292 lengthAlongCurve = fFieldPropagator->ComputeStep(aFieldTrack, currentMinimumStep, 293 currentSafety, track.GetVolume()); 294 fGeometryLimitedStep = lengthAlongCurve < currentMinimumStep; 295 if (fGeometryLimitedStep) { 296 geometryStepLength = lengthAlongCurve; 297 } 298 else { 299 geometryStepLength = currentMinimumStep; 300 } 301 } 302 else { 303 geometryStepLength = lengthAlongCurve = 0.0; 304 fGeometryLimitedStep = false; 305 } 306 307 // Remember last safety origin & value. 308 // 309 fPreviousSftOrigin = startPosition; 310 fPreviousSafety = currentSafety; 311 // fpSafetyHelper->SetCurrentSafety( newSafety, startPosition); 312 313 // Get the End-Position and End-Momentum (Dir-ection) 314 // 315 fTransportEndPosition = aFieldTrack.GetPosition(); 316 317 // Momentum: Magnitude and direction can be changed too now ... 318 // 319 fMomentumChanged = true; 320 fTransportEndMomentumDir = aFieldTrack.GetMomentumDir(); 321 322 fTransportEndKineticEnergy = aFieldTrack.GetKineticEnergy(); 323 324 fCandidateEndGlobalTime = aFieldTrack.GetLabTimeOfFlight(); 325 fEndGlobalTimeComputed = true; 326 327 fTransportEndSpin = aFieldTrack.GetSpin(); 328 fParticleIsLooping = fFieldPropagator->IsParticleLooping(); 329 endpointDistance = (fTransportEndPosition - startPosition).mag(); 330 } 331 332 // If we are asked to go a step length of 0, and we are on a boundary 333 // then a boundary will also limit the step -> we must flag this. 334 // 335 if (currentMinimumStep == 0.0) { 336 if (currentSafety == 0.0) fGeometryLimitedStep = true; 337 } 338 339 // Update the safety starting from the end-point, 340 // if it will become negative at the end-point. 341 // 342 if (currentSafety < endpointDistance) { 343 // if( particleMagneticCharge == 0.0 ) 344 // G4cout << " Avoiding call to ComputeSafety : charge = 0.0 " << G4endl; 345 346 if (particleMagneticCharge != 0.0) { 347 G4double endSafety = fLinearNavigator->ComputeSafety(fTransportEndPosition); 348 currentSafety = endSafety; 349 fPreviousSftOrigin = fTransportEndPosition; 350 fPreviousSafety = currentSafety; 351 fpSafetyHelper->SetCurrentSafety(currentSafety, fTransportEndPosition); 352 353 // Because the Stepping Manager assumes it is from the start point, 354 // add the StepLength 355 // 356 currentSafety += endpointDistance; 357 358 #ifdef G4DEBUG_TRANSPORT 359 G4cout.precision(12); 360 G4cout << "***G4MonopoleTransportation::AlongStepGPIL ** " << G4endl; 361 G4cout << " Called Navigator->ComputeSafety at " << fTransportEndPosition 362 << " and it returned safety= " << endSafety << G4endl; 363 G4cout << " Adding endpoint distance " << endpointDistance 364 << " to obtain pseudo-safety= " << currentSafety << G4endl; 365 #endif 366 } 367 } 368 369 fParticleChange.ProposeTrueStepLength(geometryStepLength); 370 371 fMagSetup->SetStepperAndChordFinder(0); 372 // change back to usual equation 373 374 return geometryStepLength; 375 } 376 377 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 378 // 379 // Initialize ParticleChange (by setting all its members equal 380 // to corresponding members in G4Track) 381 382 G4VParticleChange* G4MonopoleTransportation::AlongStepDoIt(const G4Track& track, 383 const G4Step& stepData) 384 { 385 ++noCalls; 386 387 if (fGeometryLimitedStep) { 388 stepData.GetPostStepPoint()->SetStepStatus(fGeomBoundary); 389 } 390 391 fParticleChange.Initialize(track); 392 393 // Code for specific process 394 // 395 fParticleChange.ProposePosition(fTransportEndPosition); 396 fParticleChange.ProposeMomentumDirection(fTransportEndMomentumDir); 397 fParticleChange.ProposeEnergy(fTransportEndKineticEnergy); 398 fParticleChange.SetMomentumChanged(fMomentumChanged); 399 400 fParticleChange.ProposePolarization(fTransportEndSpin); 401 402 G4double deltaTime = 0.0; 403 404 // Calculate Lab Time of Flight (ONLY if field Equations used it!) 405 406 G4double startTime = track.GetGlobalTime(); 407 408 if (!fEndGlobalTimeComputed) { 409 // The time was not integrated .. make the best estimate possible 410 // 411 G4double finalVelocity = track.GetVelocity(); 412 G4double initialVelocity = stepData.GetPreStepPoint()->GetVelocity(); 413 G4double stepLength = track.GetStepLength(); 414 415 deltaTime = 0.0; // in case initialVelocity = 0 416 if (finalVelocity > 0.0) { 417 G4double meanInverseVelocity; 418 // deltaTime = stepLength/finalVelocity ; 419 meanInverseVelocity = 0.5 * (1.0 / initialVelocity + 1.0 / finalVelocity); 420 deltaTime = stepLength * meanInverseVelocity; 421 } 422 else if (initialVelocity > 0.0) { 423 deltaTime = stepLength / initialVelocity; 424 } 425 fCandidateEndGlobalTime = startTime + deltaTime; 426 } 427 else { 428 deltaTime = fCandidateEndGlobalTime - startTime; 429 } 430 431 fParticleChange.ProposeGlobalTime(fCandidateEndGlobalTime); 432 433 // Now Correct by Lorentz factor to get "proper" deltaTime 434 435 G4double restMass = track.GetDynamicParticle()->GetMass(); 436 G4double deltaProperTime = deltaTime * (restMass / track.GetTotalEnergy()); 437 438 fParticleChange.ProposeProperTime(track.GetProperTime() + deltaProperTime); 439 440 // If the particle is caught looping or is stuck (in very difficult 441 // boundaries) in a magnetic field (doing many steps) 442 // THEN this kills it ... 443 // 444 if (fParticleIsLooping) { 445 G4double endEnergy = fTransportEndKineticEnergy; 446 447 if ((endEnergy < fThreshold_Important_Energy) || (fNoLooperTrials >= fThresholdTrials)) { 448 // Kill the looping particle 449 // 450 fParticleChange.ProposeTrackStatus(fStopAndKill); 451 452 // 'Bare' statistics 453 fSumEnergyKilled += endEnergy; 454 if (endEnergy > fMaxEnergyKilled) { 455 fMaxEnergyKilled = endEnergy; 456 } 457 458 #ifdef G4VERBOSE 459 if ((verboseLevel > 1) || (endEnergy > fThreshold_Warning_Energy)) { 460 G4cout << " G4MonopoleTransportation is killing track " 461 << "that is looping or stuck " << G4endl << " This track has " 462 << track.GetKineticEnergy() / MeV << " MeV energy." << G4endl; 463 G4cout << " Number of trials = " << fNoLooperTrials 464 << " No of calls to AlongStepDoIt = " << noCalls << G4endl; 465 } 466 #endif 467 fNoLooperTrials = 0; 468 } 469 else { 470 fNoLooperTrials++; 471 #ifdef G4VERBOSE 472 if ((verboseLevel > 2)) { 473 G4cout << " G4MonopoleTransportation::AlongStepDoIt(): " 474 << "Particle looping - " 475 << " Number of trials = " << fNoLooperTrials << " No of calls to = " << noCalls 476 << G4endl; 477 } 478 #endif 479 } 480 } 481 else { 482 fNoLooperTrials = 0; 483 } 484 485 // Another (sometimes better way) is to use a user-limit maximum Step size 486 // to alleviate this problem .. 487 488 // Introduce smooth curved trajectories to particle-change 489 // 490 fParticleChange.SetPointerToVectorOfAuxiliaryPoints( 491 fFieldPropagator->GimmeTrajectoryVectorAndForgetIt()); 492 493 return &fParticleChange; 494 } 495 496 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 497 // 498 // This ensures that the PostStep action is always called, 499 // so that it can do the relocation if it is needed. 500 // 501 502 G4double 503 G4MonopoleTransportation::PostStepGetPhysicalInteractionLength(const G4Track&, 504 G4double, // previousStepSize 505 G4ForceCondition* pForceCond) 506 { 507 *pForceCond = Forced; 508 return DBL_MAX; // was kInfinity ; but convention now is DBL_MAX 509 } 510 511 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 512 513 G4VParticleChange* G4MonopoleTransportation::PostStepDoIt(const G4Track& track, const G4Step&) 514 { 515 G4TouchableHandle retCurrentTouchable; // The one to return 516 517 // Initialize ParticleChange (by setting all its members equal 518 // to corresponding members in G4Track) 519 // fParticleChange.Initialize(track) ; // To initialise TouchableChange 520 521 fParticleChange.ProposeTrackStatus(track.GetTrackStatus()); 522 523 // If the Step was determined by the volume boundary, 524 // logically relocate the particle 525 526 if (fGeometryLimitedStep) { 527 // fCurrentTouchable will now become the previous touchable, 528 // and what was the previous will be freed. 529 // (Needed because the preStepPoint can point to the previous touchable) 530 531 fLinearNavigator->SetGeometricallyLimitedStep(); 532 fLinearNavigator->LocateGlobalPointAndUpdateTouchableHandle( 533 track.GetPosition(), track.GetMomentumDirection(), fCurrentTouchableHandle, true); 534 // Check whether the particle is out of the world volume 535 // If so it has exited and must be killed. 536 // 537 if (fCurrentTouchableHandle->GetVolume() == 0) { 538 fParticleChange.ProposeTrackStatus(fStopAndKill); 539 } 540 retCurrentTouchable = fCurrentTouchableHandle; 541 fParticleChange.SetTouchableHandle(fCurrentTouchableHandle); 542 } 543 else // fGeometryLimitedStep is false 544 { 545 // This serves only to move the Navigator's location 546 // 547 fLinearNavigator->LocateGlobalPointWithinVolume(track.GetPosition()); 548 549 // The value of the track's current Touchable is retained. 550 // (and it must be correct because we must use it below to 551 // overwrite the (unset) one in particle change) 552 // It must be fCurrentTouchable too ?? 553 // 554 fParticleChange.SetTouchableHandle(track.GetTouchableHandle()); 555 retCurrentTouchable = track.GetTouchableHandle(); 556 } // endif ( fGeometryLimitedStep ) 557 558 const G4VPhysicalVolume* pNewVol = retCurrentTouchable->GetVolume(); 559 const G4Material* pNewMaterial = 0; 560 G4VSensitiveDetector* pNewSensitiveDetector = 0; 561 if (pNewVol != 0) { 562 pNewMaterial = pNewVol->GetLogicalVolume()->GetMaterial(); 563 pNewSensitiveDetector = pNewVol->GetLogicalVolume()->GetSensitiveDetector(); 564 } 565 566 // ( <const_cast> pNewMaterial ) ; 567 568 fParticleChange.SetMaterialInTouchable((G4Material*)pNewMaterial); 569 fParticleChange.SetSensitiveDetectorInTouchable(pNewSensitiveDetector); 570 571 const G4MaterialCutsCouple* pNewMaterialCutsCouple = 0; 572 if (pNewVol != 0) { 573 pNewMaterialCutsCouple = pNewVol->GetLogicalVolume()->GetMaterialCutsCouple(); 574 } 575 576 if (pNewVol != 0 && pNewMaterialCutsCouple != 0 577 && pNewMaterialCutsCouple->GetMaterial() != pNewMaterial) 578 { 579 // for parametrized volume 580 // 581 pNewMaterialCutsCouple = G4ProductionCutsTable::GetProductionCutsTable()->GetMaterialCutsCouple( 582 pNewMaterial, pNewMaterialCutsCouple->GetProductionCuts()); 583 } 584 fParticleChange.SetMaterialCutsCoupleInTouchable(pNewMaterialCutsCouple); 585 586 // temporarily until Get/Set Material of ParticleChange, 587 // and StepPoint can be made const. 588 // Set the touchable in ParticleChange 589 // this must always be done because the particle change always 590 // uses this value to overwrite the current touchable pointer. 591 // 592 fParticleChange.SetTouchableHandle(retCurrentTouchable); 593 594 return &fParticleChange; 595 } 596 597 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 598 599 // New method takes over the responsibility to reset the state 600 // of G4MonopoleTransportation object at the start of a new track 601 // or the resumption of a suspended track. 602 603 void G4MonopoleTransportation::StartTracking(G4Track* aTrack) 604 { 605 G4VProcess::StartTracking(aTrack); 606 607 // The actions here are those that were taken in AlongStepGPIL 608 // when track.GetCurrentStepNumber()==1 609 610 // reset safety value and center 611 // 612 fPreviousSafety = 0.0; 613 fPreviousSftOrigin = G4ThreeVector(0., 0., 0.); 614 615 // reset looping counter -- for motion in field 616 fNoLooperTrials = 0; 617 // Must clear this state .. else it depends on last track's value 618 // --> a better solution would set this from state of suspended track TODO ? 619 // Was if( aTrack->GetCurrentStepNumber()==1 ) { .. } 620 621 // ChordFinder reset internal state 622 // 623 if (DoesGlobalFieldExist()) { 624 fFieldPropagator->ClearPropagatorState(); 625 // Resets all state of field propagator class (ONLY) 626 // including safety values 627 // in case of overlaps and to wipe for first track). 628 629 // G4ChordFinder* chordF= fFieldPropagator->GetChordFinder(); 630 // if( chordF ) chordF->ResetStepEstimate(); 631 } 632 633 // Make sure to clear the chord finders of all fields (ie managers) 634 G4FieldManagerStore* fieldMgrStore = G4FieldManagerStore::GetInstance(); 635 fieldMgrStore->ClearAllChordFindersState(); 636 637 // Update the current touchable handle (from the track's) 638 // 639 fCurrentTouchableHandle = aTrack->GetTouchableHandle(); 640 } 641 642 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 643