ATLAS Offline Software
QuirkTransportation.cxx
Go to the documentation of this file.
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 //
27 // GEANT4 tag $Name: geant4-09-04-patch-01 $
28 //
29 // ------------------------------------------------------------
30 // GEANT 4 include file implementation
31 //
32 // ------------------------------------------------------------
33 //
34 // This class is a process responsible for the transportation of
35 // a particle, ie the geometrical propagation that encounters the
36 // geometrical sub-volumes of the detectors.
37 //
38 // It is also tasked with the key role of proposing the "isotropic safety",
39 // which will be used to update the post-step point's safety.
40 //
41 // =======================================================================
42 // Modified:
43 // 20 Nov 2008, J.Apostolakis: Push safety to helper - after ComputeSafety
44 // 9 Nov 2007, J.Apostolakis: Flag for short steps, push safety to helper
45 // 19 Jan 2006, P.MoraDeFreitas: Fix for suspended tracks (StartTracking)
46 // 11 Aug 2004, M.Asai: Add G4VSensitiveDetector* for updating stepPoint.
47 // 21 June 2003, J.Apostolakis: Calling field manager with
48 // track, to enable it to configure its accuracy
49 // 13 May 2003, J.Apostolakis: Zero field areas now taken into
50 // account correclty in all cases (thanks to W Pokorski).
51 // 29 June 2001, J.Apostolakis, D.Cote-Ahern, P.Gumplinger:
52 // correction for spin tracking
53 // 20 Febr 2001, J.Apostolakis: update for new FieldTrack
54 // 22 Sept 2000, V.Grichine: update of Kinetic Energy
55 // Created: 19 March 1997, J. Apostolakis
56 // =======================================================================
57 
58 #include "G4ProductionCutsTable.hh"
59 #include "G4ParticleTable.hh"
60 #include "G4ChordFinder.hh"
61 #include "G4SafetyHelper.hh"
62 #include "G4FieldManagerStore.hh"
63 #include "G4MagIntegratorDriver.hh"
64 #include "G4Version.hh"
65 
66 #include "Quirk.h"
67 #include "InfracolorForce.h"
68 #include "HyperbolaStepper.h"
69 #include "QuirkTransportation.h"
70 
72 
73 class G4VSensitiveDetector;
74 
76 //
77 // Constructor
78 
80  : G4VProcess( G4String("QuirkTransportation"), fTransportation ),
81  m_particleIsLooping( false ),
82  m_currentTouchableHandle(), // Points to (G4VTouchable*) 0
83  m_previousSftOrigin (0.,0.,0.),
84  m_previousSafety ( 0.0 ),
85  m_threshold_Warning_Energy( 100 * CLHEP::MeV ),
86  m_threshold_Important_Energy( 250 * CLHEP::MeV ),
87  m_thresholdTrials( 10 ),
88  m_noLooperTrials(0),
89  m_sumEnergyKilled( 0.0 ), m_maxEnergyKilled( 0.0 ),
90  m_shortStepOptimisation(false), // Old default: true (=fast short steps)
91  m_verboseLevel( verboseLevel )
92 {
93  G4TransportationManager* transportMgr ;
94 
95  transportMgr = G4TransportationManager::GetTransportationManager() ;
96 
97  m_linearNavigator = transportMgr->GetNavigatorForTracking() ;
98 
99  // fGlobalFieldMgr = transportMgr->GetFieldManager() ;
100 
101  m_fieldPropagator = transportMgr->GetPropagatorInField() ;
102 
103  m_safetyHelper = transportMgr->GetSafetyHelper(); // New
104 
105  // Cannot determine whether a field exists here, as it would
106  // depend on the relative order of creating the detector's
107  // field and this process. That order is not guaranted.
108  // Instead later the method DoesGlobalFieldExist() is called
109 
111 }
112 
114 
116 {
117  if( (m_verboseLevel > 0) && (m_sumEnergyKilled > 0.0 ) ){
118  G4cout << " QuirkTransportation: Statistics for looping particles " << G4endl;
119  G4cout << " Sum of energy of loopers killed: " << m_sumEnergyKilled << G4endl;
120  G4cout << " Max energy of loopers killed: " << m_maxEnergyKilled << G4endl;
121  }
122 }
123 
125 //
126 // Responsibilities:
127 // Find whether the geometry limits the Step, and to what length
128 // Calculate the new value of the safety and return it.
129 // Store the final time, position and momentum.
130 
133  G4double, // previousStepSize
134  G4double currentMinimumStep,
135  G4double& currentSafety,
136  G4GPILSelection* selection )
137 {
138  G4double geometryStepLength;
139  m_particleIsLooping = false ;
140 
141  // Initial actions moved to StartTrack()
142  // --------------------------------------
143  // Note: in case another process changes touchable handle
144  // it will be necessary to add here (for all steps)
145  // m_currentTouchableHandle = aTrack->GetTouchableHandle();
146 
147  // GPILSelection is set to defaule value of CandidateForSelection
148  // It is a return value
149  //
150  *selection = CandidateForSelection ;
151 
152  // Get initial Energy/Momentum of the track
153  //
154  const G4DynamicParticle* pParticle = track.GetDynamicParticle() ;
155  G4ParticleDefinition* pParticleDef = pParticle->GetDefinition() ;
156  G4ThreeVector startPosition = track.GetPosition() ;
157 
158  // G4double theTime = track.GetGlobalTime() ;
159 
160  // The Step Point safety can be limited by other geometries and/or the
161  // assumptions of any process - it's not always the geometrical safety.
162  // We calculate the starting point's isotropic safety here.
163  //
164  G4ThreeVector OriginShift = startPosition - m_previousSftOrigin ;
165  G4double MagSqShift = OriginShift.mag2() ;
166  if( MagSqShift >= sqr(m_previousSafety) )
167  {
168  currentSafety = 0.0 ;
169  }
170  else
171  {
172  currentSafety = m_previousSafety - std::sqrt(MagSqShift) ;
173  }
174 
175  // Is the particle charged ?
176  //
177  G4double particleCharge = pParticle->GetCharge() ;
178 
179  // There is no need to locate the current volume. It is Done elsewhere:
180  // On track construction
181  // By the tracking, after all AlongStepDoIts, in "Relocation"
182 
183  // Set up field manager
184  G4FieldManager* fieldMgr = m_fieldPropagator->FindAndSetFieldManager( track.GetVolume() );
185  if (fieldMgr != 0) {
186  // Message the field Manager, to configure it for this track
187  fieldMgr->ConfigureForTrack( &track );
188  } else {
189  G4Exception("QuirkTransportation::AlongStepGetPhysicalInteractionLength", "QuirkNoFieldMgr", RunMustBeAborted, "no field manager");
190  }
191 
192  // Set up stepper to calculate quirk trajectory
193  Quirk* quirkDef = dynamic_cast<Quirk*>(pParticleDef);
194  if (quirkDef == 0) {
195  G4Exception("QuirkTransportation::AlongStepGetPhysicalInteractionLength", "NonQuirk", FatalErrorInArgument, "QuirkTransportation run on non-quirk particle");
196  std::abort();
197  }
198  HyperbolaStepper quirkStepper(
199  quirkDef->GetStringIn(),
200  track,
201  fieldMgr->DoesFieldExist() ? fieldMgr->GetDetectorField() : 0
202  );
203 
204  // Switch out chord finder with quirk chord finder
205  G4ChordFinder* oldChordFinder = fieldMgr->GetChordFinder();
206  G4ChordFinder quirkChordFinder(
207  new G4MagInt_Driver(0.0, &quirkStepper, quirkStepper.GetNumberOfVariables())
208  );
209  fieldMgr->SetChordFinder(&quirkChordFinder);
210 
211  G4double momentumMagnitude = pParticle->GetTotalMomentum() ;
212  G4ThreeVector EndUnitMomentum ;
213  G4double restMass = pParticleDef->GetPDGMass() ;
214 
215 #if G4VERSION_NUMBER > 1009
216  //FIXME untested!!!
217  G4ChargeState chargeState(particleCharge, // in e+ units
218  quirkDef->GetPDGSpin(),
219  0,
220  0,
221  0); //no magnetic charge?
222  G4EquationOfMotion* equationOfMotion = (m_fieldPropagator->GetChordFinder()->GetIntegrationDriver()->GetStepper())->GetEquationOfMotion();
223  equationOfMotion->SetChargeMomentumMass( chargeState,
224  momentumMagnitude, // in Mev/c
225  restMass ) ;
226 #else
227  m_fieldPropagator->SetChargeMomentumMass( particleCharge, // in e+ units
228  momentumMagnitude, // in Mev/c
229  restMass ) ;
230 #endif
231 
232  G4ThreeVector spin = track.GetPolarization() ;
233  G4FieldTrack aFieldTrack = G4FieldTrack( startPosition,
234  track.GetMomentumDirection(),
235  0.0,
236  track.GetKineticEnergy(),
237  restMass,
238  track.GetVelocity(),
239  track.GetGlobalTime(), // Lab.
240  0.0, // substituting step length for proper time
241  &spin ) ;
242 
243  //if (currentMinimumStep <= 0) {
244  // G4cout << "QuirkTransportation: currentMinimumStep = " << currentMinimumStep << G4endl;
245  // G4Exception(
246  // "QuirkTransportation::AlongStepGetPhysicalInteractionLength",
247  // "BadMinimumStep",
248  // EventMustBeAborted,
249  // "QuirkTransportation: currentMinimumStep <= 0"
250  // );
251  //}
252  G4bool dbg = false; //(track.GetCurrentStepNumber() % 1000000 == 0);
253  quirkStepper.SetDebug(dbg);
254  if (dbg) G4cout << "QuirkTransportation: start = " << aFieldTrack.GetPosition() << G4endl;
255  if (dbg) G4cout << "QuirkTransportation: currentMinimumStep = " << currentMinimumStep << G4endl;
256  if (dbg) G4cout << "QuirkTransportation: maxlength = " << quirkStepper.GetMaxLength() << G4endl;
257  currentMinimumStep = std::min(currentMinimumStep, quirkStepper.GetMaxLength());
258  if (dbg) G4cout << "QuirkTransportation: currentMinimumStep = " << currentMinimumStep << G4endl;
259  if( currentMinimumStep > 0 )
260  {
261  // Call field propagator to handle boundary crossings
262  G4double lengthAlongCurve = m_fieldPropagator->ComputeStep( aFieldTrack,
263  currentMinimumStep,
264  currentSafety,
265  track.GetVolume() ) ;
266  if (dbg) G4cout << "QuirkTransportation: moved " << lengthAlongCurve << G4endl;
267  m_geometryLimitedStep = lengthAlongCurve < currentMinimumStep;
268  if( m_geometryLimitedStep ) {
269  geometryStepLength = lengthAlongCurve ;
270  } else {
271  geometryStepLength = currentMinimumStep ;
272  }
273  // Update stepper, string vectors with step length from field propagator
274  quirkStepper.Update(aFieldTrack, aFieldTrack.GetCurveLength() == 0 && !m_geometryLimitedStep);
275  }
276  else
277  {
278  geometryStepLength = 0.0 ;
279  m_geometryLimitedStep = false ;
280  }
281  if (dbg) G4cout << "QuirkTransportation: moved " << aFieldTrack.GetCurveLength() << G4endl;
282  if (dbg) G4cout << "QuirkTransportation: end = " << aFieldTrack.GetPosition() << " [" << aFieldTrack.GetProperTimeOfFlight() << "]" << G4endl;
283 
284  // Remember last safety origin & value.
285  //
286  m_previousSftOrigin = startPosition ;
287  m_previousSafety = currentSafety ;
288  // m_safetyHelper->SetCurrentSafety( newSafety, startPosition);
289 
290  // Get end-of-step quantities
291  geometryStepLength = aFieldTrack.GetCurveLength();
292  m_transportEndPosition = aFieldTrack.GetPosition() ;
293  m_momentumChanged = true ;
294  m_transportEndMomentumDir = aFieldTrack.GetMomentumDir() ;
295  m_transportEndKineticEnergy = aFieldTrack.GetKineticEnergy() ;
296  m_candidateEndGlobalTime = aFieldTrack.GetLabTimeOfFlight();
297  m_transportEndSpin = aFieldTrack.GetSpin();
298  m_particleIsLooping = m_fieldPropagator->IsParticleLooping() ;
299  m_endpointDistance = (m_transportEndPosition - startPosition).mag() ;
300 
301  // If we are asked to go a step length of 0, and we are on a boundary
302  // then a boundary will also limit the step -> we must flag this.
303  //
304  if( currentMinimumStep == 0.0 )
305  {
306  if( currentSafety == 0.0 ) m_geometryLimitedStep = true ;
307  }
308 
309  // Update the safety starting from the end-point,
310  // if it will become negative at the end-point.
311  //
312  if( currentSafety < m_endpointDistance )
313  {
314  G4double endSafety =
315  m_linearNavigator->ComputeSafety( m_transportEndPosition) ;
316  currentSafety = endSafety ;
318  m_previousSafety = currentSafety ;
319  m_safetyHelper->SetCurrentSafety( currentSafety, m_transportEndPosition);
320 
321  // Because the Stepping Manager assumes it is from the start point,
322  // add the StepLength
323  //
324  currentSafety += m_endpointDistance ;
325 
326 #ifdef G4DEBUG_TRANSPORT
327  G4cout.precision(12) ;
328  G4cout << "***QuirkTransportation::AlongStepGPIL ** " << G4endl ;
329  G4cout << " Called Navigator->ComputeSafety at " << m_transportEndPosition
330  << " and it returned safety= " << endSafety << G4endl ;
331  G4cout << " Adding endpoint distance " << m_endpointDistance
332  << " to obtain pseudo-safety= " << currentSafety << G4endl ;
333 #endif
334  }
335 
336  m_particleChange.ProposeTrueStepLength(geometryStepLength) ;
337 
338  // Restore original stepper
339  fieldMgr->SetChordFinder(oldChordFinder);
340 
341  return geometryStepLength ;
342 }
343 
345 //
346 // Initialize ParticleChange (by setting all its members equal
347 // to corresponding members in G4Track)
348 
349 G4VParticleChange* QuirkTransportation::AlongStepDoIt( const G4Track& track,
350  const G4Step& /*stepData*/ )
351 {
352 #ifdef G4VERBOSE
353  static std::atomic<G4int> noCalls=0;
354  noCalls++;
355 #endif
356 
357  m_particleChange.Initialize(track) ;
358 
359  // Code for specific process
360  //
361  m_particleChange.ProposePosition(m_transportEndPosition) ;
362  m_particleChange.ProposeMomentumDirection(m_transportEndMomentumDir) ;
364  m_particleChange.SetMomentumChanged(m_momentumChanged) ;
365 
366  m_particleChange.ProposePolarization(m_transportEndSpin);
367 
368  // Calculate Lab Time of Flight (ONLY if field Equations used it!)
369  // G4double endTime = m_candidateEndGlobalTime;
370  // G4double delta_time = endTime - startTime;
371 
372  G4double startTime = track.GetGlobalTime() ;
373  G4double deltaTime = m_candidateEndGlobalTime - startTime ;
374  m_particleChange.ProposeGlobalTime( m_candidateEndGlobalTime ) ;
375 
376  // Now Correct by Lorentz factor to get "proper" deltaTime
377 
378  G4double restMass = track.GetDynamicParticle()->GetMass() ;
379  G4double deltaProperTime = deltaTime*( restMass/track.GetTotalEnergy() ) ;
380 
381  m_particleChange.ProposeProperTime(track.GetProperTime() + deltaProperTime) ;
382  //m_particleChange. ProposeTrueStepLength( track.GetStepLength() ) ;
383 
384  // If the particle is caught looping or is stuck (in very difficult
385  // boundaries) in a magnetic field (doing many steps)
386  // THEN this kills it ...
387  //
388  if ( m_particleIsLooping )
389  {
390  G4double endEnergy= m_transportEndKineticEnergy;
391 
392  if( (endEnergy < m_threshold_Important_Energy)
394  // Kill the looping particle
395  //
396  m_particleChange.ProposeTrackStatus( fStopAndKill ) ;
397 
398  // 'Bare' statistics
399  m_sumEnergyKilled += endEnergy;
400  if( endEnergy > m_maxEnergyKilled) { m_maxEnergyKilled= endEnergy; }
401 
402 #ifdef G4VERBOSE
403  if( (m_verboseLevel > 1) ||
404  ( endEnergy > m_threshold_Warning_Energy ) ) {
405  G4cout << " QuirkTransportation is killing track that is looping or stuck "
406  << G4endl
407  << " This track has " << track.GetKineticEnergy() / CLHEP::MeV
408  << " MeV energy." << G4endl;
409  G4cout << " Number of trials = " << m_noLooperTrials
410  << " No of calls to AlongStepDoIt = " << noCalls
411  << G4endl;
412  }
413 #endif
414  m_noLooperTrials=0;
415  }
416  else{
417  m_noLooperTrials ++;
418 #ifdef G4VERBOSE
419  if( (m_verboseLevel > 2) ){
420  G4cout << " QuirkTransportation::AlongStepDoIt(): Particle looping - "
421  << " Number of trials = " << m_noLooperTrials
422  << " No of calls to = " << noCalls
423  << G4endl;
424  }
425 #endif
426  }
427  }else{
428  m_noLooperTrials=0;
429  }
430 
431  // Another (sometimes better way) is to use a user-limit maximum Step size
432  // to alleviate this problem ..
433 
434  // Introduce smooth curved trajectories to particle-change
435  //
436  m_particleChange.SetPointerToVectorOfAuxiliaryPoints
437  (m_fieldPropagator->GimmeTrajectoryVectorAndForgetIt() );
438 
439  return &m_particleChange ;
440 }
441 
443 //
444 // This ensures that the PostStep action is always called,
445 // so that it can do the relocation if it is needed.
446 //
447 
450  G4double, // previousStepSize
451  G4ForceCondition* pForceCond )
452 {
453  *pForceCond = Forced ;
454  return DBL_MAX ; // was kInfinity ; but convention now is DBL_MAX
455 }
456 
458 //
459 
460 G4VParticleChange* QuirkTransportation::PostStepDoIt( const G4Track& track,
461  const G4Step& )
462 {
463  G4TouchableHandle retCurrentTouchable ; // The one to return
464  G4bool isLastStep= false;
465 
466  // Initialize ParticleChange (by setting all its members equal
467  // to corresponding members in G4Track)
468  // m_particleChange.Initialize(track) ; // To initialise TouchableChange
469 
470  m_particleChange.ProposeTrackStatus(track.GetTrackStatus()) ;
471 
472  // If the Step was determined by the volume boundary,
473  // logically relocate the particle
474 
476  {
477  // fCurrentTouchable will now become the previous touchable,
478  // and what was the previous will be freed.
479  // (Needed because the preStepPoint can point to the previous touchable)
480 
481  m_linearNavigator->SetGeometricallyLimitedStep() ;
483  LocateGlobalPointAndUpdateTouchableHandle( track.GetPosition(),
484  track.GetMomentumDirection(),
486  true ) ;
487  // Check whether the particle is out of the world volume
488  // If so it has exited and must be killed.
489  //
490  if( m_currentTouchableHandle->GetVolume() == 0 )
491  {
492  m_particleChange.ProposeTrackStatus( fStopAndKill ) ;
493  G4cout << "QuirkTransportation: number of steps = " << track.GetCurrentStepNumber() << G4endl;
494  }
495  retCurrentTouchable = m_currentTouchableHandle ;
496  m_particleChange.SetTouchableHandle( m_currentTouchableHandle ) ;
497 
498  // Update the Step flag which identifies the Last Step in a volume
499  isLastStep = m_linearNavigator->ExitedMotherVolume()
500  || m_linearNavigator->EnteredDaughterVolume() ;
501 
502 #ifdef G4DEBUG_TRANSPORT
503  // Checking first implementation of flagging Last Step in Volume
504  G4bool exiting = m_linearNavigator->ExitedMotherVolume();
505  G4bool entering = m_linearNavigator->EnteredDaughterVolume();
506  if( ! (exiting || entering) ) {
507  G4cout << " Transport> : Proposed isLastStep= " << isLastStep
508  << " Exiting " << m_linearNavigator->ExitedMotherVolume()
509  << " Entering " << m_linearNavigator->EnteredDaughterVolume()
510  << G4endl;
511  }
512 #endif
513  }
514  else // m_geometryLimitedStep is false
515  {
516  // This serves only to move the Navigator's location
517  //
518  m_linearNavigator->LocateGlobalPointWithinVolume( track.GetPosition() ) ;
519 
520  // The value of the track's current Touchable is retained.
521  // (and it must be correct because we must use it below to
522  // overwrite the (unset) one in particle change)
523  // It must be fCurrentTouchable too ??
524  //
525  m_particleChange.SetTouchableHandle( track.GetTouchableHandle() ) ;
526  retCurrentTouchable = track.GetTouchableHandle() ;
527 
528  isLastStep= false;
529 #ifdef G4DEBUG_TRANSPORT
530  // Checking first implementation of flagging Last Step in Volume
531  G4cout << " Transport> Proposed isLastStep= " << isLastStep
532  << " Geometry did not limit step. " << G4endl;
533 #endif
534  } // endif ( m_geometryLimitedStep )
535 
536  m_particleChange.ProposeLastStepInVolume(isLastStep);
537 
538  const G4VPhysicalVolume* pNewVol = retCurrentTouchable->GetVolume() ;
539  G4Material* pNewMaterial = 0 ;
540  G4VSensitiveDetector* pNewSensitiveDetector = 0 ;
541 
542  if( pNewVol != 0 )
543  {
544  pNewMaterial= pNewVol->GetLogicalVolume()->GetMaterial();
545  pNewSensitiveDetector= pNewVol->GetLogicalVolume()->GetSensitiveDetector();
546  }
547 
548  // ( <const_cast> pNewMaterial ) ;
549  // ( <const_cast> pNewSensitiveDetector) ;
550 
551  m_particleChange.SetMaterialInTouchable( pNewMaterial ) ;
552  m_particleChange.SetSensitiveDetectorInTouchable( pNewSensitiveDetector ) ;
553 
554  const G4MaterialCutsCouple* pNewMaterialCutsCouple = 0;
555  if( pNewVol != 0 )
556  {
557  pNewMaterialCutsCouple=pNewVol->GetLogicalVolume()->GetMaterialCutsCouple();
558  }
559 
560  if( pNewVol!=0 && pNewMaterialCutsCouple!=0 && pNewMaterialCutsCouple->GetMaterial()!=pNewMaterial )
561  {
562  // for parametrized volume
563  //
564  pNewMaterialCutsCouple =
565  G4ProductionCutsTable::GetProductionCutsTable()
566  ->GetMaterialCutsCouple(pNewMaterial,
567  pNewMaterialCutsCouple->GetProductionCuts());
568  }
569  m_particleChange.SetMaterialCutsCoupleInTouchable( pNewMaterialCutsCouple );
570 
571  // temporarily until Get/Set Material of ParticleChange,
572  // and StepPoint can be made const.
573  // Set the touchable in ParticleChange
574  // this must always be done because the particle change always
575  // uses this value to overwrite the current touchable pointer.
576  //
577  m_particleChange.SetTouchableHandle(retCurrentTouchable) ;
578 
579  return &m_particleChange ;
580 }
581 
582 // New method takes over the responsibility to reset the state of QuirkTransportation
583 // object at the start of a new track or the resumption of a suspended track.
584 
585 void
587 {
588  G4VProcess::StartTracking(aTrack);
589 
590 // The actions here are those that were taken in AlongStepGPIL
591 // when track.GetCurrentStepNumber()==1
592 
593  // reset safety value and center
594  //
595  m_previousSafety = 0.0 ;
596  m_previousSftOrigin = G4ThreeVector(0.,0.,0.) ;
597 
598  // reset looping counter -- for motion in field
599  m_noLooperTrials= 0;
600  // Must clear this state .. else it depends on last track's value
601  // --> a better solution would set this from state of suspended track TODO ?
602  // Was if( aTrack->GetCurrentStepNumber()==1 ) { .. }
603 
604  // ChordFinder reset internal state
605  //
606  m_fieldPropagator->ClearPropagatorState();
607  // Resets all state of field propagator class (ONLY)
608  // including safety values (in case of overlaps and to wipe for first track).
609 
610  // G4ChordFinder* chordF= m_fieldPropagator->GetChordFinder();
611  // if( chordF ) chordF->ResetStepEstimate();
612 
613  // Make sure to clear the chord finders of all fields (ie managers)
614  G4FieldManagerStore::GetInstance()->ClearAllChordFindersState();
615 
616  // Update the current touchable handle (from the track's)
617  //
618  m_currentTouchableHandle = aTrack->GetTouchableHandle();
619 
620  // Initialize infracolor string
621  auto part_nc ATLAS_THREAD_SAFE = // aTrack is non-const but GetParticleDefinition only returns const
622  const_cast<G4ParticleDefinition*>(aTrack->GetParticleDefinition());
623  Quirk* quirkDef = dynamic_cast<Quirk*>(part_nc);
624  if (quirkDef == 0) {
625  G4Exception("QuirkTransportation::StartTracking", "NonQuirk", FatalErrorInArgument, "QuirkTransportation run on non-quirk particle");
626  std::abort();
627  }
628  quirkDef->GetStringIn().StartTracking(aTrack);
629 }
630 
QuirkTransportation::m_threshold_Warning_Energy
G4double m_threshold_Warning_Energy
Definition: QuirkTransportation.h:187
QuirkTransportation::m_endpointDistance
G4double m_endpointDistance
Definition: QuirkTransportation.h:183
QuirkTransportation::m_transportEndPosition
G4ThreeVector m_transportEndPosition
Definition: QuirkTransportation.h:156
QuirkTransportation::StartTracking
void StartTracking(G4Track *aTrack)
Definition: QuirkTransportation.cxx:586
QuirkTransportation::m_transportEndKineticEnergy
G4double m_transportEndKineticEnergy
Definition: QuirkTransportation.h:158
QuirkTransportation.h
QuirkTransportation::m_momentumChanged
G4bool m_momentumChanged
Definition: QuirkTransportation.h:160
python.SystemOfUnits.MeV
int MeV
Definition: SystemOfUnits.py:154
lumiFormat.startTime
startTime
Definition: lumiFormat.py:102
QuirkTransportation::m_particleIsLooping
G4bool m_particleIsLooping
Definition: QuirkTransportation.h:164
Quirk::GetStringIn
const InfracolorForce & GetStringIn() const
Definition: Quirk.h:29
InfracolorForce::StartTracking
void StartTracking(const G4Track *dest)
Definition: InfracolorForce.cxx:28
QuirkTransportation::AlongStepGetPhysicalInteractionLength
G4double AlongStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4double currentMinimumStep, G4double &currentSafety, G4GPILSelection *selection)
Definition: QuirkTransportation.cxx:132
HyperbolaStepper::Update
void Update(G4FieldTrack &fieldTrack, G4bool forceStep)
Definition: HyperbolaStepper.cxx:90
HyperbolaStepper::GetMaxLength
G4double GetMaxLength() const
Definition: HyperbolaStepper.h:77
HyperbolaStepper.h
dbg
bool dbg
Definition: listroot.cxx:36
SUSY::spin
bool spin(const T &p)
Definition: AtlasPID.h:615
QuirkTransportation::m_particleChange
G4ParticleChangeForTransport m_particleChange
Definition: QuirkTransportation.h:180
HyperbolaStepper
Definition: HyperbolaStepper.h:19
QuirkTransportation::m_candidateEndGlobalTime
G4double m_candidateEndGlobalTime
Definition: QuirkTransportation.h:161
Quirk.h
Quirk
Definition: Quirk.h:12
QuirkTransportation::m_fieldPropagator
G4PropagatorInField * m_fieldPropagator
Definition: QuirkTransportation.h:150
sqr
#define sqr(t)
Definition: PolygonTriangulator.cxx:110
QuirkTransportation::m_transportEndMomentumDir
G4ThreeVector m_transportEndMomentumDir
Definition: QuirkTransportation.h:157
QuirkTransportation::PostStepDoIt
G4VParticleChange * PostStepDoIt(const G4Track &track, const G4Step &stepData)
Definition: QuirkTransportation.cxx:460
HyperbolaStepper::SetDebug
void SetDebug(G4bool debug)
Definition: HyperbolaStepper.h:79
CLHEP
STD'S.
Definition: IAtRndmGenSvc.h:19
QuirkTransportation::m_geometryLimitedStep
G4bool m_geometryLimitedStep
Definition: QuirkTransportation.h:173
QuirkTransportation::~QuirkTransportation
~QuirkTransportation()
Definition: QuirkTransportation.cxx:115
QuirkTransportation::m_linearNavigator
G4Navigator * m_linearNavigator
Definition: QuirkTransportation.h:149
QuirkTransportation::m_transportEndSpin
G4ThreeVector m_transportEndSpin
Definition: QuirkTransportation.h:159
selection
std::string selection
Definition: fbtTestBasics.cxx:73
min
#define min(a, b)
Definition: cfImp.cxx:40
InfracolorForce.h
QuirkTransportation::m_currentTouchableHandle
G4TouchableHandle m_currentTouchableHandle
Definition: QuirkTransportation.h:166
QuirkTransportation::m_thresholdTrials
G4int m_thresholdTrials
Definition: QuirkTransportation.h:189
QuirkTransportation::PostStepGetPhysicalInteractionLength
G4double PostStepGetPhysicalInteractionLength(const G4Track &, G4double previousStepSize, G4ForceCondition *pForceCond)
Definition: QuirkTransportation.cxx:449
QuirkTransportation::m_threshold_Important_Energy
G4double m_threshold_Important_Energy
Definition: QuirkTransportation.h:188
QuirkTransportation::QuirkTransportation
QuirkTransportation(G4int verbosityLevel=1)
Definition: QuirkTransportation.cxx:79
QuirkTransportation::AlongStepDoIt
G4VParticleChange * AlongStepDoIt(const G4Track &track, const G4Step &stepData)
Definition: QuirkTransportation.cxx:349
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
QuirkTransportation::m_safetyHelper
G4SafetyHelper * m_safetyHelper
Definition: QuirkTransportation.h:202
QuirkTransportation::m_noLooperTrials
G4int m_noLooperTrials
Definition: QuirkTransportation.h:193
QuirkTransportation::m_previousSafety
G4double m_previousSafety
Definition: QuirkTransportation.h:177
QuirkTransportation::m_verboseLevel
G4int m_verboseLevel
Definition: QuirkTransportation.h:205
checker_macros.h
Define macros for attributes used to control the static checker.
QuirkTransportation::m_maxEnergyKilled
G4double m_maxEnergyKilled
Definition: QuirkTransportation.h:196
QuirkTransportation::m_sumEnergyKilled
G4double m_sumEnergyKilled
Definition: QuirkTransportation.h:195
mag
Scalar mag() const
mag method
Definition: AmgMatrixBasePlugin.h:25
QuirkTransportation::m_previousSftOrigin
G4ThreeVector m_previousSftOrigin
Definition: QuirkTransportation.h:176