ATLAS Offline Software
Loading...
Searching...
No Matches
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
73class G4VSensitiveDetector;
74
76//
77// Constructor
78
80 : G4VProcess( G4String("QuirkTransportation"), fTransportation ),
82 m_momentumChanged( false ),
83 m_particleIsLooping( false ),
84 m_currentTouchableHandle(), // Points to (G4VTouchable*) 0
85 m_geometryLimitedStep( false ),
86 m_previousSftOrigin (0.,0.,0.),
87 m_previousSafety ( 0.0 ),
88 m_endpointDistance( 0.0 ),
89 m_threshold_Warning_Energy( 100 * CLHEP::MeV ),
91 m_thresholdTrials( 10 ),
94 m_shortStepOptimisation(false), // Old default: true (=fast short steps)
95 m_verboseLevel( verboseLevel )
96{
97 G4TransportationManager* transportMgr ;
98
99 transportMgr = G4TransportationManager::GetTransportationManager() ;
100
101 m_linearNavigator = transportMgr->GetNavigatorForTracking() ;
102
103 // fGlobalFieldMgr = transportMgr->GetFieldManager() ;
104
105 m_fieldPropagator = transportMgr->GetPropagatorInField() ;
106
107 m_safetyHelper = transportMgr->GetSafetyHelper(); // New
108
109 // Cannot determine whether a field exists here, as it would
110 // depend on the relative order of creating the detector's
111 // field and this process. That order is not guaranted.
112 // Instead later the method DoesGlobalFieldExist() is called
113
115}
116
118
120{
121 if( (m_verboseLevel > 0) && (m_sumEnergyKilled > 0.0 ) ){
122 G4cout << " QuirkTransportation: Statistics for looping particles " << G4endl;
123 G4cout << " Sum of energy of loopers killed: " << m_sumEnergyKilled << G4endl;
124 G4cout << " Max energy of loopers killed: " << m_maxEnergyKilled << G4endl;
125 }
126}
127
129//
130// Responsibilities:
131// Find whether the geometry limits the Step, and to what length
132// Calculate the new value of the safety and return it.
133// Store the final time, position and momentum.
134
136AlongStepGetPhysicalInteractionLength( const G4Track& track,
137 G4double, // previousStepSize
138 G4double currentMinimumStep,
139 G4double& currentSafety,
140 G4GPILSelection* selection )
141{
142 G4double geometryStepLength;
143 m_particleIsLooping = false ;
144
145 // Initial actions moved to StartTrack()
146 // --------------------------------------
147 // Note: in case another process changes touchable handle
148 // it will be necessary to add here (for all steps)
149 // m_currentTouchableHandle = aTrack->GetTouchableHandle();
150
151 // GPILSelection is set to defaule value of CandidateForSelection
152 // It is a return value
153 //
154 *selection = CandidateForSelection ;
155
156 // Get initial Energy/Momentum of the track
157 //
158 const G4DynamicParticle* pParticle = track.GetDynamicParticle() ;
159 G4ParticleDefinition* pParticleDef = pParticle->GetDefinition() ;
160 G4ThreeVector startPosition = track.GetPosition() ;
161
162 // G4double theTime = track.GetGlobalTime() ;
163
164 // The Step Point safety can be limited by other geometries and/or the
165 // assumptions of any process - it's not always the geometrical safety.
166 // We calculate the starting point's isotropic safety here.
167 //
168 G4ThreeVector OriginShift = startPosition - m_previousSftOrigin ;
169 G4double MagSqShift = OriginShift.mag2() ;
170 if( MagSqShift >= sqr(m_previousSafety) )
171 {
172 currentSafety = 0.0 ;
173 }
174 else
175 {
176 currentSafety = m_previousSafety - std::sqrt(MagSqShift) ;
177 }
178
179 // Is the particle charged ?
180 //
181 G4double particleCharge = pParticle->GetCharge() ;
182
183 // There is no need to locate the current volume. It is Done elsewhere:
184 // On track construction
185 // By the tracking, after all AlongStepDoIts, in "Relocation"
186
187 // Set up field manager
188 G4FieldManager* fieldMgr = m_fieldPropagator->FindAndSetFieldManager( track.GetVolume() );
189 if (fieldMgr != 0) {
190 // Message the field Manager, to configure it for this track
191 fieldMgr->ConfigureForTrack( &track );
192 } else {
193 G4Exception("QuirkTransportation::AlongStepGetPhysicalInteractionLength", "QuirkNoFieldMgr", RunMustBeAborted, "no field manager");
194 }
195
196 // Set up stepper to calculate quirk trajectory
197 Quirk* quirkDef = dynamic_cast<Quirk*>(pParticleDef);
198 if (quirkDef == 0) {
199 G4Exception("QuirkTransportation::AlongStepGetPhysicalInteractionLength", "NonQuirk", FatalErrorInArgument, "QuirkTransportation run on non-quirk particle");
200 std::abort();
201 }
202 HyperbolaStepper quirkStepper(
203 quirkDef->GetStringIn(),
204 track,
205 fieldMgr->DoesFieldExist() ? fieldMgr->GetDetectorField() : 0
206 );
207
208 // Switch out chord finder with quirk chord finder
209 G4ChordFinder* oldChordFinder = fieldMgr->GetChordFinder();
210 G4ChordFinder quirkChordFinder(
211 new G4MagInt_Driver(0.0, &quirkStepper, quirkStepper.GetNumberOfVariables())
212 );
213 fieldMgr->SetChordFinder(&quirkChordFinder);
214
215 G4double momentumMagnitude = pParticle->GetTotalMomentum() ;
216 G4ThreeVector EndUnitMomentum ;
217 G4double restMass = pParticleDef->GetPDGMass() ;
218
219#if G4VERSION_NUMBER > 1009
220 //FIXME untested!!!
221 G4ChargeState chargeState(particleCharge, // in e+ units
222 quirkDef->GetPDGSpin(),
223 0,
224 0,
225 0); //no magnetic charge?
226 G4EquationOfMotion* equationOfMotion = (m_fieldPropagator->GetChordFinder()->GetIntegrationDriver()->GetStepper())->GetEquationOfMotion();
227 equationOfMotion->SetChargeMomentumMass( chargeState,
228 momentumMagnitude, // in Mev/c
229 restMass ) ;
230#else
231 m_fieldPropagator->SetChargeMomentumMass( particleCharge, // in e+ units
232 momentumMagnitude, // in Mev/c
233 restMass ) ;
234#endif
235
236 G4ThreeVector spin = track.GetPolarization() ;
237 G4FieldTrack aFieldTrack = G4FieldTrack( startPosition,
238 track.GetMomentumDirection(),
239 0.0,
240 track.GetKineticEnergy(),
241 restMass,
242 track.GetVelocity(),
243 track.GetGlobalTime(), // Lab.
244 0.0, // substituting step length for proper time
245 &spin ) ;
246
247 //if (currentMinimumStep <= 0) {
248 // G4cout << "QuirkTransportation: currentMinimumStep = " << currentMinimumStep << G4endl;
249 // G4Exception(
250 // "QuirkTransportation::AlongStepGetPhysicalInteractionLength",
251 // "BadMinimumStep",
252 // EventMustBeAborted,
253 // "QuirkTransportation: currentMinimumStep <= 0"
254 // );
255 //}
256 constexpr G4bool dbg = false; //(track.GetCurrentStepNumber() % 1000000 == 0);
257 quirkStepper.SetDebug(dbg);
258 if (dbg) G4cout << "QuirkTransportation: start = " << aFieldTrack.GetPosition() << G4endl;
259 if (dbg) G4cout << "QuirkTransportation: currentMinimumStep = " << currentMinimumStep << G4endl;
260 if (dbg) G4cout << "QuirkTransportation: maxlength = " << quirkStepper.GetMaxLength() << G4endl;
261 currentMinimumStep = std::min(currentMinimumStep, quirkStepper.GetMaxLength());
262 if (dbg) G4cout << "QuirkTransportation: currentMinimumStep = " << currentMinimumStep << G4endl;
263 if( currentMinimumStep > 0 )
264 {
265 // Call field propagator to handle boundary crossings
266 G4double lengthAlongCurve = m_fieldPropagator->ComputeStep( aFieldTrack,
267 currentMinimumStep,
268 currentSafety,
269 track.GetVolume() ) ;
270 if (dbg) G4cout << "QuirkTransportation: moved " << lengthAlongCurve << G4endl;
271 m_geometryLimitedStep = lengthAlongCurve < 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 m_geometryLimitedStep = false ;
279 }
280 if (dbg) G4cout << "QuirkTransportation: moved " << aFieldTrack.GetCurveLength() << G4endl;
281 if (dbg) G4cout << "QuirkTransportation: end = " << aFieldTrack.GetPosition() << " [" << aFieldTrack.GetProperTimeOfFlight() << "]" << G4endl;
282
283 // Remember last safety origin & value.
284 //
285 m_previousSftOrigin = startPosition ;
286 m_previousSafety = currentSafety ;
287 // m_safetyHelper->SetCurrentSafety( newSafety, startPosition);
288
289 // Get end-of-step quantities
290 //geometryStepLength is set here, overwriting any previous setting
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 =
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
349G4VParticleChange* 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 //
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 //
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
415 }
416 else{
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{
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
460G4VParticleChange* 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
585void
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
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
Scalar mag() const
mag method
double spin(const T &p)
Definition AtlasPID.h:1147
#define sqr(t)
Define macros for attributes used to control the static checker.
#define ATLAS_THREAD_SAFE
void SetDebug(G4bool debug)
void Update(G4FieldTrack &fieldTrack, G4bool forceStep)
G4double GetMaxLength() const
void StartTracking(const G4Track *dest)
G4ThreeVector m_previousSftOrigin
G4PropagatorInField * m_fieldPropagator
G4ThreeVector m_transportEndPosition
G4Navigator * m_linearNavigator
G4ThreeVector m_transportEndSpin
void StartTracking(G4Track *aTrack)
G4ParticleChangeForTransport m_particleChange
G4ThreeVector m_transportEndMomentumDir
G4VParticleChange * PostStepDoIt(const G4Track &track, const G4Step &stepData)
G4SafetyHelper * m_safetyHelper
G4VParticleChange * AlongStepDoIt(const G4Track &track, const G4Step &stepData)
G4TouchableHandle m_currentTouchableHandle
G4double PostStepGetPhysicalInteractionLength(const G4Track &, G4double previousStepSize, G4ForceCondition *pForceCond)
G4double AlongStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4double currentMinimumStep, G4double &currentSafety, G4GPILSelection *selection)
QuirkTransportation(G4int verbosityLevel=1)
Definition Quirk.h:12
const InfracolorForce & GetStringIn() const
Definition Quirk.h:29
const std::string selection