Geant4 Processes ================= Modelling Processes -------------------- * http://geant4.web.cern.ch/geant4/G4UsersDocuments/UsersGuides/ForApplicationDeveloper/html/TrackingAndPhysics/physicsProcess.html Each process has two groups of methods which play an important role in tracking, `GetPhysicalInteractionLength (GPIL)` Get step length from the current space-time point to the next space-time point. It does this by calculating the probability of interaction based on the process's cross section information. At the end of this step the DoIt method should be invoked. `DoIt`. The DoIt method implements the details of the interaction, changing the particle's energy, momentum, direction and position, and producing secondary tracks if required. These changes are recorded as G4VParticleChange objects(see Particle Change). `G4VRestProcess` processes using only the `AtRestDoIt` method, example: neutron capture `G4VContinuousProcess` processes using only the `AlongStepDoIt` method, example: cerenkov `G4VDiscreteProcess` processes using only the `PostStepDoIt` method, example: compton scattering, hadron inelastic interaction OR for more complex processes which implement 2 or 3 of those 3 methods: `G4VContinuousDiscreteProcess`, `G4VRestDiscreteProcess`, `G4VRestContinuousProcess`, `G4VRestContinuousDiscreteProcess` Tracking of Photons in processes/optical ------------------------------------------ * http://geant4.web.cern.ch/geant4/G4UsersDocuments/UsersGuides/ForApplicationDeveloper/html/TrackingAndPhysics/physicsProcess.html Absorption ~~~~~~~~~~~~ The implementation of optical photon bulk absorption, `G4OpAbsorption`, is trivial in that the process merely kills the particle. The procedure requires the user to fill the relevant `G4MaterialPropertiesTable` with empirical data for the absorption length, using `ABSLENGTH` as the property key in the public method AddProperty. The absorption length is the average distance traveled by a photon before being absorpted by the medium; i.e. it is the mean free path returned by the `GetMeanFreePath` method. ABSLENGTH ^^^^^^^^^^ :: [blyth@cms01 source]$ find . -name '*.cc' -exec grep -H 'ABSLENGTH' {} \; ./processes/optical/src/G4OpWLS.cc: GetProperty("WLSABSLENGTH"); ./processes/optical/src/G4OpAbsorption.cc: GetProperty("ABSLENGTH"); G4OpAbsorption::PostStepDoIt ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: 101 G4VParticleChange* 102 G4OpAbsorption::PostStepDoIt(const G4Track& aTrack, const G4Step& aStep) 103 { 104 aParticleChange.Initialize(aTrack); 105 106 aParticleChange.ProposeTrackStatus(fStopAndKill); 107 108 if (verboseLevel>0) { 109 G4cout << "\n** Photon absorbed! **" << G4endl; 110 } 111 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep); 112 } G4OpAbsorption::GetMeanFreePath ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: 118 G4double G4OpAbsorption::GetMeanFreePath(const G4Track& aTrack, 119 G4double , 120 G4ForceCondition* ) 121 { 122 const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle(); 123 const G4Material* aMaterial = aTrack.GetMaterial(); 124 125 G4double thePhotonMomentum = aParticle->GetTotalMomentum(); 126 127 G4MaterialPropertiesTable* aMaterialPropertyTable; 128 G4MaterialPropertyVector* AttenuationLengthVector; 129 130 G4double AttenuationLength = DBL_MAX; 131 132 aMaterialPropertyTable = aMaterial->GetMaterialPropertiesTable(); 133 134 if ( aMaterialPropertyTable ) { 135 AttenuationLengthVector = aMaterialPropertyTable-> 136 GetProperty("ABSLENGTH"); 137 if ( AttenuationLengthVector ){ 138 AttenuationLength = AttenuationLengthVector-> 139 GetProperty (thePhotonMomentum); G4VDiscreteProcess::PostStepGetPhysicalInteractionLength ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: (gdb) b 'G4VDiscreteProcess::PostStepGetPhysicalInteractionLength(G4Track const&, double, G4ForceCondition*)' Breakpoint 1 at 0x68f34ed: file /data1/env/local/dyb/NuWa-trunk/../external/build/LCG/geant4.9.2.p01/source/processes/management/include/G4VDiscreteProcess.hh, line 137. (gdb) bt #0 G4VDiscreteProcess::PostStepGetPhysicalInteractionLength (this=0xd37b178, track=@0x10c8cd90, previousStepSize=0, condition=0xc481da0) at /data1/env/local/dyb/NuWa-trunk/../external/build/LCG/geant4.9.2.p01/source/processes/management/include/G4VDiscreteProcess.hh:137 #1 0x07247e95 in G4VProcess::PostStepGPIL (this=0xd37b178, track=@0x10c8cd90, previousStepSize=0, condition=0xc481da0) at /data1/env/local/dyb/NuWa-trunk/../external/build/LCG/geant4.9.2.p01/source/processes/management/include/G4VProcess.hh:464 #2 0x0724655a in G4SteppingManager::DefinePhysicalStepLength (this=0xc481c98) at src/G4SteppingManager2.cc:165 #3 0x07242e2c in G4SteppingManager::Stepping (this=0xc481c98) at src/G4SteppingManager.cc:181 #4 0x0725150a in G4TrackingManager::ProcessOneTrack (this=0xc481c70, apValueG4Track=0x10c8cd90) at src/G4TrackingManager.cc:126 #5 0xb666c24f in G4EventManager::DoProcessing (this=0xc481480, anEvent=0x10832350) at src/G4EventManager.cc:185 #6 0xb666c9e6 in G4EventManager::ProcessOneEvent (this=0xc481480, anEvent=0x10832350) at src/G4EventManager.cc:335 #7 0xb4e605e8 in GiGaRunManager::processTheEvent (this=0xc480c18) at ../src/component/GiGaRunManager.cpp:207 #8 0xb4e5f522 in GiGaRunManager::retrieveTheEvent (this=0xc480c18, event=@0xbfa6c9d8) at ../src/component/GiGaRunManager.cpp:158 #9 0xb4e3b64f in GiGa::retrieveTheEvent (this=0xc480220, event=@0xbfa6c9d8) at ../src/component/GiGa.cpp:469 #10 0xb4e38564 in GiGa::operator>> (this=0xc480220, event=@0xbfa6c9d8) at ../src/component/GiGaIGiGaSvc.cpp:73 #11 0xb4e362fa in GiGa::retrieveEvent (this=0xc480220, event=@0xbfa6c9d8) at ../src/component/GiGaIGiGaSvc.cpp:211 #12 0xb507fcd3 in DsPullEvent::execute (this=0xc473470) at ../src/DsPullEvent.cc:54 #13 0x046d6408 in Algorithm::sysExecute (this=0xc473470) at ../src/Lib/Algorithm.cpp:558 #14 0x03a61d4e in DybBaseAlg::sysExecute (this=0xc473470) at ../src/lib/DybBaseAlg.cc:53 #15 0x01cf0fd4 in GaudiSequencer::execute (this=0xbf36020) at ../src/lib/GaudiSequencer.cpp:100 #16 0x046d6408 in Algorithm::sysExecute (this=0xbf36020) at ../src/Lib/Algorithm.cpp:558 #17 0x01c8868f in GaudiAlgorithm::sysExecute (this=0xbf36020) at ../src/lib/GaudiAlgorithm.cpp:161 #18 0x0475241a in MinimalEventLoopMgr::executeEvent (this=0xbaf2f98) at ../src/Lib/MinimalEventLoopMgr.cpp:450 #19 0x03b20956 in DybEventLoopMgr::executeEvent (this=0xbaf2f98, par=0x0) at ../src/DybEventLoopMgr.cpp:125 #20 0x03b2118a in DybEventLoopMgr::nextEvent (this=0xbaf2f98, maxevt=10) at ../src/DybEventLoopMgr.cpp:188 #21 0x04750dbd in MinimalEventLoopMgr::executeRun (this=0xbaf2f98, maxevt=10) at ../src/Lib/MinimalEventLoopMgr.cpp:400 #22 0x08c086d9 in ApplicationMgr::executeRun (this=0xb7b9ad0, evtmax=10) at ../src/ApplicationMgr/ApplicationMgr.cpp:867 #23 0x0239af57 in method_3426 (retaddr=0xc5821b0, o=0xb7b9efc, arg=@0xb825c50) at ../i686-slc5-gcc41-dbg/dict/GaudiKernel/dictionary_dict.cpp:4375 #24 0x0030cadd in ROOT::Cintex::Method_stub_with_context (context=0xb825c48, result=0xc5cafe4, libp=0xc5cb03c) at cint/cintex/src/CINTFunctional.cxx:319 G4VProcess::PostStepGPIL ^^^^^^^^^^^^^^^^^^^^^^^^^ :: (gdb) frame 1 #1 0x07247e95 in G4VProcess::PostStepGPIL (this=0xd37b178, track=@0x10c8cd90, previousStepSize=0, condition=0xc481da0) at /data1/env/local/dyb/NuWa-trunk/../external/build/LCG/geant4.9.2.p01/source/processes/management/include/G4VProcess.hh:464 464 =PostStepGetPhysicalInteractionLength(track, previousStepSize, condition); (gdb) list 459 inline G4double G4VProcess::PostStepGPIL( const G4Track& track, 460 G4double previousStepSize, 461 G4ForceCondition* condition ) 462 { 463 G4double value 464 =PostStepGetPhysicalInteractionLength(track, previousStepSize, condition); 465 return thePILfactor*value; 466 } G4VDiscreteProcess::PostStepGetPhysicalInteractionLength ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: 131 inline G4double G4VDiscreteProcess::PostStepGetPhysicalInteractionLength( 132 const G4Track& track, 133 G4double previousStepSize, 134 G4ForceCondition* condition 135 ) 136 { 137 if ( (previousStepSize < 0.0) || (theNumberOfInteractionLengthLeft<=0.0)) { 138 // beggining of tracking (or just after DoIt of this process) 139 ResetNumberOfInteractionLengthLeft(); 140 } else if ( previousStepSize > 0.0) { 141 // subtract NumberOfInteractionLengthLeft 142 SubtractNumberOfInteractionLengthLeft(previousStepSize); 143 } else { 144 // zero step 145 // DO NOTHING 146 } 147 148 // condition is set to "Not Forced" 149 *condition = NotForced; 150 151 // get mean free path 152 currentInteractionLength = GetMeanFreePath(track, previousStepSize, condition); 153 154 G4double value; 155 if (currentInteractionLength <DBL_MAX) { 156 value = theNumberOfInteractionLengthLeft * currentInteractionLength; 157 } else { 158 value = DBL_MAX; 159 } 160 #ifdef G4VERBOSE 161 if (verboseLevel>1){ 162 G4cout << "G4VDiscreteProcess::PostStepGetPhysicalInteractionLength "; 163 G4cout << "[ " << GetProcessName() << "]" <<G4endl; 164 track.GetDynamicParticle()->DumpInfo(); 165 G4cout << " in Material " << track.GetMaterial()->GetName() <<G4endl; 166 G4cout << "InteractionLength= " << value/cm <<"[cm] " <<G4endl; 167 } 168 #endif 169 return value; 170 } processes/management/include/G4VProcess.hh ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ :: 076 class G4VProcess 077 { 078 // A virtual class for physics process objects. It defines 079 // public methods which describe the behavior of a 080 // physics process. 081 ... 147 virtual G4double PostStepGetPhysicalInteractionLength( 148 const G4Track& track, 149 G4double previousStepSize, 150 G4ForceCondition* condition 151 ) = 0; 152 153 // Returns the Step-size (actual length) which is allowed 154 // by "this" process. (for AtRestGetPhysicalInteractionLength, 155 // return value is Step-time) The NumberOfInteractionLengthLeft is 156 // recalculated by using previousStepSize and the Step-size is 157 // calucalted accoding to the resultant NumberOfInteractionLengthLeft. 158 // using NumberOfInteractionLengthLeft, which is recalculated at 159 // arguments 160 // const G4Track& track: 161 // reference to the current G4Track information 162 // G4double* previousStepSize: 163 // the Step-size (actual length) of the previous Step 164 // of this track. Negative calue indicates that 165 // NumberOfInteractionLengthLeft must be reset. 166 // the current physical interaction legth of this process 167 // G4ForceCondition* condition: 168 // the flag indicates DoIt of this process is forced 169 // to be called 170 // Forced: Corresponding DoIt is forced 171 // NotForced: Corresponding DoIt is called 172 // if the Step size of this Step is determined 173 // by this process 174 // !! AlongStepDoIt is always called !! 175 // G4double& currentMinimumStep: 176 // this value is used for transformation of 177 // true path length to geometrical path length 178 179 G4double GetCurrentInteractionLength() const; 180 // Returns currentInteractionLength 181 182 ////////// PIL factor //////// 183 void SetPILfactor(G4double value); 184 G4double GetPILfactor() const; 185 // Set/Get factor for PhysicsInteractionLength 186 // which is passed to G4SteppingManager for both AtRest and PostStep 187 188 // These three GPIL methods are used by Stepping Manager. 189 // They invoke virtual GPIL methods listed above. 190 // As for AtRest and PostStep the returned value is multipled by thePILfactor 191 // ... 287 protected: 288 G4VParticleChange* pParticleChange; 289 // The pointer to G4VParticleChange object 290 // which is modified and returned by address by the DoIt() method. 291 // This pointer should be set in each physics process 292 // after construction of derived class object. 293 294 G4ParticleChange aParticleChange; 295 // This object is kept for compatibility with old scheme 296 // This will be removed in future 297 298 G4double theNumberOfInteractionLengthLeft; 299 // The flight length left for the current tracking particle 300 // in unit of "Interaction length". 301 302 G4double currentInteractionLength; 303 // The InteractionLength in the current material 304 305 public: // with description 306 virtual void ResetNumberOfInteractionLengthLeft(); 307 // reset (determine the value of)NumberOfInteractionLengthLeft 308 309 protected: // with description 310 virtual void SubtractNumberOfInteractionLengthLeft( 311 G4double previousStepSize 312 ); 313 // subtract NumberOfInteractionLengthLeft by the value corresponding to 314 // previousStepSize Rayleigh Scattering ~~~~~~~~~~~~~~~~~~~~ The differential cross section in Rayleigh scattering, `sigma/omega` , is proportional to `cos2(theta)`, where `theta` is the polar angle of the new polarization vector with respect to the old polarization vector. The `G4OpRayleigh` scattering process samples this angle accordingly and then calculates the scattered photon's new direction by requiring that it be perpendicular to the photon's new polarization in such a way that the final direction, initial and final polarizations are all in one plane. This process thus depends on the particle's polarization (spin). The photon's polarization is a data member of the `G4DynamicParticle` class. A photon which is not assigned a polarization at production, either via the `SetPolarization` method of the `G4PrimaryParticle` class, or indirectly with the `SetParticlePolarization` method of the `G4ParticleGun` class, may not be Rayleigh scattered. Optical photons produced by the `G4Cerenkov` process have inherently a polarization perpendicular to the cone's surface at production. Scintillation photons have a random linear polarization perpendicular to their direction. The process requires a `G4MaterialPropertiesTable` to be filled by the user with Rayleigh scattering length data. The Rayleigh scattering attenuation length is the average distance traveled by a photon before it is Rayleigh scattered in the medium and it is the distance returned by the `GetMeanFreePath` method. The `G4OpRayleigh` class provides a `RayleighAttenuationLengthGenerator` method which calculates the attenuation coefficient of a medium following the Einstein-Smoluchowski formula whose derivation requires the use of statistical mechanics, includes temperature, and depends on the isothermal compressibility of the medium. This generator is convenient when the Rayleigh attenuation length is not known from measurement but may be calculated from first principles using the above material constants. For a medium named Water and no Rayleigh scattering attenutation length specified by the user, the program automatically calls the RayleighAttenuationLengthGenerator which calculates it for 10 degrees Celsius liquid water. G4SteppingManager::GetProcessNumber -------------------------------------- Three categories of DoIt: `AtRestDoIt` eg decays `AlongStepDoIt` relevant for `G4VContinuousProcess` `PostStepDoIt` relevant for `G4VDiscreteProcess` like those that optical photons undergo: Absorption, Scattering, Boundaries :: 56 ///////////////////////////////////////////////// 57 void G4SteppingManager::GetProcessNumber() 58 ///////////////////////////////////////////////// 59 { 60 #ifdef debug 61 G4cout<<"G4SteppingManager::GetProcessNumber: is called track="<<fTrack<<G4endl; 62 #endif 63 64 G4ProcessManager* pm= fTrack->GetDefinition()->GetProcessManager(); 65 if(!pm) 66 { 67 G4cout<<"G4SteppingManager::GetProcessNumber: ProcessManager=0 for particle=" 68 <<fTrack->GetDefinition()->GetParticleName()<<", PDG_code=" 69 <<fTrack->GetDefinition()->GetPDGEncoding()<<G4endl; 70 G4Exception("G4SteppingManager::GetProcessNumber: Process Manager is not found."); 71 } 72 73 // AtRestDoits 74 MAXofAtRestLoops = pm->GetAtRestProcessVector()->entries(); 75 fAtRestDoItVector = pm->GetAtRestProcessVector(typeDoIt); 76 fAtRestGetPhysIntVector = pm->GetAtRestProcessVector(typeGPIL); 77 #ifdef debug 78 G4cout<<"G4SteppingManager::GetProcessNumber: #ofAtRest="<<MAXofAtRestLoops<<G4endl; 79 #endif 80 81 // AlongStepDoits 82 MAXofAlongStepLoops = pm->GetAlongStepProcessVector()->entries(); 83 fAlongStepDoItVector = pm->GetAlongStepProcessVector(typeDoIt); 84 fAlongStepGetPhysIntVector = pm->GetAlongStepProcessVector(typeGPIL); 85 #ifdef debug 86 G4cout<<"G4SteppingManager::GetProcessNumber:#ofAlongStp="<<MAXofAlongStepLoops<<G4endl; 87 #endif 88 89 // PostStepDoits 90 MAXofPostStepLoops = pm->GetPostStepProcessVector()->entries(); 91 fPostStepDoItVector = pm->GetPostStepProcessVector(typeDoIt); 92 fPostStepGetPhysIntVector = pm->GetPostStepProcessVector(typeGPIL); 93 #ifdef debug 94 G4cout<<"G4SteppingManager::GetProcessNumber: #ofPostStep="<<MAXofPostStepLoops<<G4endl; 95 #endif 96 97 if (SizeOfSelectedDoItVector<MAXofAtRestLoops || 98 SizeOfSelectedDoItVector<MAXofAlongStepLoops || 99 SizeOfSelectedDoItVector<MAXofPostStepLoops ) 100 { 101 G4cout<<"G4SteppingManager::GetProcessNumber: SizeOfSelectedDoItVector=" 102 <<SizeOfSelectedDoItVector<<" is smaller then one of MAXofAtRestLoops=" 103 <<MAXofAtRestLoops<<" or MAXofAlongStepLoops="<<MAXofAlongStepLoops 104 <<" or MAXofPostStepLoops="<<MAXofPostStepLoops<<G4endl; 105 G4Exception("G4SteppingManager::GetProcessNumber: The array size is smaller than the actutal number of processes. Chnage G4SteppingManager.hh and recompile is needed."); 106 } 107 } How are the relevant processes determined ? ---------------------------------------------- :: [blyth@cms01 source]$ find . -name '*.cc' -exec grep -H fPostStepDoItVector {} \; ./tracking/src/G4SteppingManager2.cc: fPostStepDoItVector = pm->GetPostStepProcessVector(typeDoIt); ./tracking/src/G4SteppingManager2.cc: fCurrentProcess = (*fPostStepDoItVector)[np]; ./tracking/src/G4SteppingVerbose.cc: ptProcManager = (*fPostStepDoItVector)[np]; ./tracking/src/G4SteppingVerbose.cc: ptProcManager = (*fPostStepDoItVector)[np]; ./tracking/src/G4VSteppingVerbose.cc: fPostStepDoItVector = fManager->GetfPostStepDoItVector(); [blyth@cms01 source]$ What distribution is used for OP times, energy ---------------------------------------------------- DsPmtSensDet::ProcessHits ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From the G4Step, energies and times feed into creating hits. For OP, wavelength is more relevant than energy. From http://geant4.web.cern.ch/geant4/G4UsersDocuments/UsersGuides/ForApplicationDeveloper/html/TrackingAndPhysics/physicsProcess.html * Optical photons are generated in GEANT4 without energy conservation and their energy must therefore not be tallied as part of the energy balance of an event. :: 318 bool DsPmtSensDet::ProcessHits(G4Step* step, 319 G4TouchableHistory* /*history*/) 320 { 321 //if (!step) return false; just crash for now if not defined 322 323 // Find out what detector we are in (ADx, IWS or OWS) 324 G4StepPoint* preStepPoint = step->GetPreStepPoint(); 325 326 double energyDep = step->GetTotalEnergyDeposit(); ... ... ... 434 double wavelength = CLHEP::twopi*CLHEP::hbarc/energyDep; ... ... ... 459 DayaBay::SimPmtHit* sphit = new DayaBay::SimPmtHit(); 460 461 // base hit 462 463 // Time since event created 464 sphit->setHitTime(preStepPoint->GetGlobalTime()); 465 466 //#include "G4NavigationHistory.hh" 467 468 const G4AffineTransform& trans = hist->GetHistory()->GetTopTransform(); 469 const G4ThreeVector& global_pos = preStepPoint->GetPosition(); 470 G4ThreeVector pos = trans.TransformPoint(global_pos); 471 sphit->setLocalPos(pos); 472 sphit->setSensDetId(pmtid); 473 474 // pmt hit 475 // sphit->setDir(...); // for now 476 G4ThreeVector pol = trans.TransformAxis(track->GetPolarization()); 477 pol = pol.unit(); 478 G4ThreeVector dir = trans.TransformAxis(track->GetMomentum()); 479 dir = dir.unit(); 480 sphit->setPol(pol); 481 sphit->setDir(dir); 482 sphit->setWavelength(wavelength); 483 sphit->setType(0); 484 // G4cerr<<"PMT: set hit weight "<<weight<<G4endl; //gonchar 485 sphit->setWeight(weight); Where do the times come from ? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :: [blyth@cms01 source]$ find . -name '*.cc' -exec grep -H SetGlobalTime {} \; ./track/src/G4ParticleChangeForDecay.cc: pPostStepPoint->SetGlobalTime( theTimeChange ); ./track/src/G4ParticleChange.cc: pPostStepPoint->SetGlobalTime( theTimeChange ); ./track/src/G4ParticleChange.cc: pPostStepPoint->SetGlobalTime( theTimeChange ); ./processes/hadronic/models/lll_fission/src/G4FissionLibrary.cc:// it->SetGlobalTime(getnage_(&i)*second); ./processes/hadronic/models/lll_fission/src/G4FissionLibrary.cc:// it->SetGlobalTime(getpage_(&i)*second); ./processes/parameterisation/src/G4FastStep.cc: pPostStepPoint->SetGlobalTime( theTimeChange ); ./processes/parameterisation/src/G4FastStep.cc: pPostStepPoint->SetGlobalTime( theTimeChange ); [blyth@cms01 source]$ :: [blyth@cms01 source]$ find . -name '*.cc' -exec grep -H ProposeGlobalTime {} \; ./processes/hadronic/models/radioactive_decay/src/G4RadioactiveDecay.cc: fParticleChangeForRadDecay.ProposeGlobalTime( finalGlobalTime ); ./processes/transportation/src/G4Transportation.cc: fParticleChange.ProposeGlobalTime( fCandidateEndGlobalTime ) ; ./processes/transportation/src/G4CoupledTransportation.cc: fParticleChange.ProposeGlobalTime( fCandidateEndGlobalTime ) ; ./processes/decay/src/G4UnknownDecay.cc: fParticleChangeForDecay.ProposeGlobalTime( finalGlobalTime ); ./processes/decay/src/G4Decay.cc: fParticleChangeForDecay.ProposeGlobalTime( finalGlobalTime ); [blyth@cms01 source]$ G4Transportation::AlongStepDoIt ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For OP, what determines the GlobalTime is * `startTime + (stepLength/finalVelocity)` So question becomes: where is stepLength distribution implemented ? Each process provides a MeanFreePath, where is the dice rolled ? :: 450 G4VParticleChange* G4Transportation::AlongStepDoIt( const G4Track& track, 451 const G4Step& stepData ) 452 { 453 static G4int noCalls=0; 454 static const G4ParticleDefinition* fOpticalPhoton = 455 G4ParticleTable::GetParticleTable()->FindParticle("opticalphoton"); 456 457 noCalls++; 458 459 fParticleChange.Initialize(track) ; 460 461 // Code for specific process 462 // 463 fParticleChange.ProposePosition(fTransportEndPosition) ; 464 fParticleChange.ProposeMomentumDirection(fTransportEndMomentumDir) ; 465 fParticleChange.ProposeEnergy(fTransportEndKineticEnergy) ; 466 fParticleChange.SetMomentumChanged(fMomentumChanged) ; 467 468 fParticleChange.ProposePolarization(fTransportEndSpin); 469 470 G4double deltaTime = 0.0 ; 471 472 // Calculate Lab Time of Flight (ONLY if field Equations used it!) 473 // G4double endTime = fCandidateEndGlobalTime; 474 // G4double delta_time = endTime - startTime; 475 476 G4double startTime = track.GetGlobalTime() ; 477 478 if (!fEndGlobalTimeComputed) 479 { 480 // The time was not integrated .. make the best estimate possible 481 // 482 G4double finalVelocity = track.GetVelocity() ; 483 G4double initialVelocity = stepData.GetPreStepPoint()->GetVelocity() ; 484 G4double stepLength = track.GetStepLength() ; 485 486 deltaTime= 0.0; // in case initialVelocity = 0 487 const G4DynamicParticle* fpDynamicParticle = track.GetDynamicParticle(); 488 if (fpDynamicParticle->GetDefinition()== fOpticalPhoton) 489 { 490 // A photon is in the medium of the final point 491 // during the step, so it has the final velocity. 492 deltaTime = stepLength/finalVelocity ; 493 } 494 else if (finalVelocity > 0.0) 495 { 496 G4double meanInverseVelocity ; 497 // deltaTime = stepLength/finalVelocity ; 498 meanInverseVelocity = 0.5 499 * ( 1.0 / initialVelocity + 1.0 / finalVelocity ) ; 500 deltaTime = stepLength * meanInverseVelocity ; 501 } 502 else if( initialVelocity > 0.0 ) 503 { 504 deltaTime = stepLength/initialVelocity ; 505 } 506 fCandidateEndGlobalTime = startTime + deltaTime ; 507 } 508 else 509 { 510 deltaTime = fCandidateEndGlobalTime - startTime ; 511 } 512 513 fParticleChange.ProposeGlobalTime( fCandidateEndGlobalTime ) ; G4SteppingManager::DefinePhysicalStepLength ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :: [blyth@cms01 source]$ find . -name '*.cc' -exec grep -H DefinePhysicalStepLength {} \; ./tracking/src/G4SteppingManager.cc: DefinePhysicalStepLength(); ./tracking/src/G4SteppingManager2.cc: void G4SteppingManager::DefinePhysicalStepLength() ./tracking/src/G4SteppingManager2.cc:} // void G4SteppingManager::DefinePhysicalStepLength() // ./tracking/src/G4SteppingVerbose.cc: G4cout << G4endl << " >>DefinePhysicalStepLength (List of proposed StepLengths): " << G4endl; :: 118 void G4SteppingManager::DefinePhysicalStepLength() 119 ///////////////////////////////////////////////////////// 120 { 121 122 // ReSet the counter etc. 123 PhysicalStep = DBL_MAX; // Initialize by a huge number 124 physIntLength = DBL_MAX; // Initialize by a huge number 125 #ifdef G4VERBOSE 126 // !!!!! Verbose 127 if(verboseLevel>0) fVerbose->DPSLStarted(); 128 #endif 129 130 // Obtain the user defined maximum allowed Step in the volume 131 // 1997.12.13 adds argument for GetMaxAllowedStep by K.Kurashige 132 // 2004.01.20 This block will be removed by Geant4 7.0 133 // G4UserLimits* ul= fCurrentVolume->GetLogicalVolume()->GetUserLimits(); 134 // if (ul) { 135 // physIntLength = ul->GetMaxAllowedStep(*fTrack); 136 //#ifdef G4VERBOSE 137 // // !!!!! Verbose 138 // if(verboseLevel>0) fVerbose->DPSLUserLimit(); 139 //#endif 140 // } 141 // 142 // if(physIntLength < PhysicalStep ){ 143 // PhysicalStep = physIntLength; 144 // fStepStatus = fUserDefinedLimit; 145 // fStep->GetPostStepPoint() 146 // ->SetProcessDefinedStep(NULL); 147 // // Take note that the process pointer is 'NULL' if the Step 148 // // is defined by the user defined limit. 149 // } 150 // 2004.01.20 This block will be removed by Geant4 7.0 151 152 // GPIL for PostStep 153 fPostStepDoItProcTriggered = MAXofPostStepLoops; 154 155 for(size_t np=0; np < MAXofPostStepLoops; np++){ 156 fCurrentProcess = (*fPostStepGetPhysIntVector)(np); 157 if (fCurrentProcess== NULL) { 158 (*fSelectedPostStepDoItVector)[np] = InActivated; 159 continue; 160 } // NULL means the process is inactivated by a user on fly. 161 162 physIntLength = fCurrentProcess-> 163 PostStepGPIL( *fTrack, 164 fPreviousStepSize, 165 &fCondition ); 166 #ifdef G4VERBOSE 167 // !!!!! Verbose 168 if(verboseLevel>0) fVerbose->DPSLPostStep(); 169 #endif 170 171 switch (fCondition) { 172 case ExclusivelyForced: 173 (*fSelectedPostStepDoItVector)[np] = ExclusivelyForced; 174 fStepStatus = fExclusivelyForcedProc; 175 fStep->GetPostStepPoint() 176 ->SetProcessDefinedStep(fCurrentProcess); 177 break; 178 case Conditionally: 179 (*fSelectedPostStepDoItVector)[np] = Conditionally; 180 break; 181 case Forced: G4SteppingManager::DefinePhysicalStepLength ---------------------------------------------- Only 6 processes ? ~~~~~~~~~~~~~~~~~~~~~ :: (gdb) p fCurrentProcess->GetProcessName() $9 = (const G4String &) @0xc094a20: {<std::basic_string<char,std::char_traits<char>,std::allocator<char> >> = {static npos = 4294967295, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0xc094c04 "Transportation"}}, <No data fields>} (gdb) c Continuing. 1 -1.43e+04 -8e+05 -1.14e+03 2.31e-06 0 3.3e+03 3.3e+03 /dd/Geometry/Sites/lvNearHallTop#pvNearRPCRoof Transportation Breakpoint 2, G4SteppingManager::DefinePhysicalStepLength (this=0xc481c98) at src/G4SteppingManager2.cc:168 168 if(verboseLevel>0) fVerbose->DPSLPostStep(); (gdb) p fCurrentProcess->GetProcessName() $10 = (const G4String &) @0xce5a190: {<std::basic_string<char,std::char_traits<char>,std::allocator<char> >> = {static npos = 4294967295, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0xc484aec "Scintillation"}}, <No data fields>} (gdb) c Continuing. Breakpoint 2, G4SteppingManager::DefinePhysicalStepLength (this=0xc481c98) at src/G4SteppingManager2.cc:168 168 if(verboseLevel>0) fVerbose->DPSLPostStep(); (gdb) p fCurrentProcess->GetProcessName() $11 = (const G4String &) @0xd37bc80: {<std::basic_string<char,std::char_traits<char>,std::allocator<char> >> = {static npos = 4294967295, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0xd379024 "fast_sim_man"}}, <No data fields>} (gdb) c Continuing. Breakpoint 2, G4SteppingManager::DefinePhysicalStepLength (this=0xc481c98) at src/G4SteppingManager2.cc:168 168 if(verboseLevel>0) fVerbose->DPSLPostStep(); (gdb) p fCurrentProcess->GetProcessName() $12 = (const G4String &) @0xd37b258: {<std::basic_string<char,std::char_traits<char>,std::allocator<char> >> = {static npos = 4294967295, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0xd37b164 "OpBoundary"}}, <No data fields>} (gdb) c Continuing. Breakpoint 2, G4SteppingManager::DefinePhysicalStepLength (this=0xc481c98) at src/G4SteppingManager2.cc:168 168 if(verboseLevel>0) fVerbose->DPSLPostStep(); (gdb) p fCurrentProcess->GetProcessName() $13 = (const G4String &) @0xd3782f8: {<std::basic_string<char,std::char_traits<char>,std::allocator<char> >> = {static npos = 4294967295, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0xce5eb2c "OpRayleigh"}}, <No data fields>} (gdb) c Continuing. Breakpoint 2, G4SteppingManager::DefinePhysicalStepLength (this=0xc481c98) at src/G4SteppingManager2.cc:168 168 if(verboseLevel>0) fVerbose->DPSLPostStep(); (gdb) p fCurrentProcess->GetProcessName() $14 = (const G4String &) @0xd3779e8: {<std::basic_string<char,std::char_traits<char>,std::allocator<char> >> = {static npos = 4294967295, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0xce6044c "OpAbsorption"}}, <No data fields>} (gdb) c Continuing. Breakpoint 2, G4SteppingManager::DefinePhysicalStepLength (this=0xc481c98) at src/G4SteppingManager2.cc:168 168 if(verboseLevel>0) fVerbose->DPSLPostStep(); (gdb) p fCurrentProcess->GetProcessName() $15 = (const G4String &) @0xc094a20: {<std::basic_string<char,std::char_traits<char>,std::allocator<char> >> = {static npos = 4294967295, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0xc094c04 "Transportation"}}, <No data fields>} (gdb) c Continuing. 2 -1.45e+04 -8e+05 -1.31e+03 2.31e-06 0 208 3.51e+03 /dd/Geometry/RPC/lvNearRPCRoof#pvNearUnSlopModArray#pvNearUnSlopModOne:3#pvNearUnSlopMod:2#pvNearSlopModUnit Transportation Step# X(mm) Y(mm) Z(mm) KinE(MeV) dE(MeV) StepLeng TrackLeng NextVolume ProcName 0 -1.23e+04 -8e+05 1.56e+03 5.77e-06 0 0 0 /dd/Geometry/Sites/lvNearSiteRock#pvNearHallTop initStep Breakpoint 2, G4SteppingManager::DefinePhysicalStepLength (this=0xc481c98) at src/G4SteppingManager2.cc:168 168 if(verboseLevel>0) fVerbose->DPSLPostStep(); 2.4.4. Interaction with Physics Processes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * http://geant4.web.cern.ch/geant4/UserDocumentation/UsersGuides/ForToolkitDeveloper/html/ch02s04.html The interaction of the tracking category with the physics processes is done in two ways. First each process can limit the step length through one of its three `GetPhysicalInteractionLength()` methods, `AtRest`, `AlongStep`, or `PostStep`. Second, for the selected processes the `DoIt` (`AtRest`, `AlongStep` or `PostStep`) methods are invoked. All this interaction is managed by the `Stepping` method of `G4SteppingManager`. To calculate the step length, the `DefinePhysicalStepLength()` method is called. The flow of this method is the following: Obtain maximum allowed Step in the volume define by the user through G4UserLimits. #. The `PostStepGetPhysicalInteractionLength` of all active processes is called. #. Each process returns a step length and the minimum one is chosen. #. This method also returns a `G4ForceCondition` flag, to indicate if the process is forced or not: `Forced` Corresponding `PostStepDoIt` is forced. `NotForced` Corresponding `PostStepDoIt` is not forced unless this process limits the step. `Conditionally` Only when `AlongStepDoIt` limits the step, corresponding `PoststepDoIt` is invoked. `ExclusivelyForced` Corresponding `PostStepDoIt` is exclusively forced. All other `DoIt` including `AlongStepDoIts` are ignored. The `AlongStepGetPhysicalInteractionLength` method of all active processes is called. Each process returns a step length and the minimum of these and the This method also returns a `fGPILSelection` flag, to indicate if the process is the selected one can be is forced or not. `CandidateForSelection` this process can be the winner. If its step length is the smallest, it will be the process defining the step (the process = `NotCandidateForSelection` this process cannot be the winner. Even if its step length is taken as the smallest, it will not be the process defining the step