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 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;
273 geometryStepLength = lengthAlongCurve ;
274 } else {
275 geometryStepLength = currentMinimumStep ;
276 }
277 // Update stepper, string vectors with step length from field propagator
278 quirkStepper.Update(aFieldTrack, aFieldTrack.GetCurveLength() == 0 && !m_geometryLimitedStep);
279 }
280 else
281 {
282 geometryStepLength = 0.0 ;
283 m_geometryLimitedStep = false ;
284 }
285 if (dbg) G4cout << "QuirkTransportation: moved " << aFieldTrack.GetCurveLength() << G4endl;
286 if (dbg) G4cout << "QuirkTransportation: end = " << aFieldTrack.GetPosition() << " [" << aFieldTrack.GetProperTimeOfFlight() << "]" << G4endl;
287
288 // Remember last safety origin & value.
289 //
290 m_previousSftOrigin = startPosition ;
291 m_previousSafety = currentSafety ;
292 // m_safetyHelper->SetCurrentSafety( newSafety, startPosition);
293
294 // Get end-of-step quantities
295 geometryStepLength = aFieldTrack.GetCurveLength();
296 m_transportEndPosition = aFieldTrack.GetPosition() ;
297 m_momentumChanged = true ;
298 m_transportEndMomentumDir = aFieldTrack.GetMomentumDir() ;
299 m_transportEndKineticEnergy = aFieldTrack.GetKineticEnergy() ;
300 m_candidateEndGlobalTime = aFieldTrack.GetLabTimeOfFlight();
301 m_transportEndSpin = aFieldTrack.GetSpin();
302 m_particleIsLooping = m_fieldPropagator->IsParticleLooping() ;
303 m_endpointDistance = (m_transportEndPosition - startPosition).mag() ;
304
305 // If we are asked to go a step length of 0, and we are on a boundary
306 // then a boundary will also limit the step -> we must flag this.
307 //
308 if( currentMinimumStep == 0.0 )
309 {
310 if( currentSafety == 0.0 ) m_geometryLimitedStep = true ;
311 }
312
313 // Update the safety starting from the end-point,
314 // if it will become negative at the end-point.
315 //
316 if( currentSafety < m_endpointDistance )
317 {
318 G4double endSafety =
320 currentSafety = endSafety ;
322 m_previousSafety = currentSafety ;
323 m_safetyHelper->SetCurrentSafety( currentSafety, m_transportEndPosition);
324
325 // Because the Stepping Manager assumes it is from the start point,
326 // add the StepLength
327 //
328 currentSafety += m_endpointDistance ;
329
330#ifdef G4DEBUG_TRANSPORT
331 G4cout.precision(12) ;
332 G4cout << "***QuirkTransportation::AlongStepGPIL ** " << G4endl ;
333 G4cout << " Called Navigator->ComputeSafety at " << m_transportEndPosition
334 << " and it returned safety= " << endSafety << G4endl ;
335 G4cout << " Adding endpoint distance " << m_endpointDistance
336 << " to obtain pseudo-safety= " << currentSafety << G4endl ;
337#endif
338 }
339
340 m_particleChange.ProposeTrueStepLength(geometryStepLength) ;
341
342 // Restore original stepper
343 fieldMgr->SetChordFinder(oldChordFinder);
344
345 return geometryStepLength ;
346}
347
349//
350// Initialize ParticleChange (by setting all its members equal
351// to corresponding members in G4Track)
352
353G4VParticleChange* QuirkTransportation::AlongStepDoIt( const G4Track& track,
354 const G4Step& /*stepData*/ )
355{
356#ifdef G4VERBOSE
357 static std::atomic<G4int> noCalls=0;
358 noCalls++;
359#endif
360
361 m_particleChange.Initialize(track) ;
362
363 // Code for specific process
364 //
366 m_particleChange.ProposeMomentumDirection(m_transportEndMomentumDir) ;
368 m_particleChange.SetMomentumChanged(m_momentumChanged) ;
369
370 m_particleChange.ProposePolarization(m_transportEndSpin);
371
372 // Calculate Lab Time of Flight (ONLY if field Equations used it!)
373 // G4double endTime = m_candidateEndGlobalTime;
374 // G4double delta_time = endTime - startTime;
375
376 G4double startTime = track.GetGlobalTime() ;
377 G4double deltaTime = m_candidateEndGlobalTime - startTime ;
378 m_particleChange.ProposeGlobalTime( m_candidateEndGlobalTime ) ;
379
380 // Now Correct by Lorentz factor to get "proper" deltaTime
381
382 G4double restMass = track.GetDynamicParticle()->GetMass() ;
383 G4double deltaProperTime = deltaTime*( restMass/track.GetTotalEnergy() ) ;
384
385 m_particleChange.ProposeProperTime(track.GetProperTime() + deltaProperTime) ;
386 //m_particleChange. ProposeTrueStepLength( track.GetStepLength() ) ;
387
388 // If the particle is caught looping or is stuck (in very difficult
389 // boundaries) in a magnetic field (doing many steps)
390 // THEN this kills it ...
391 //
393 {
394 G4double endEnergy= m_transportEndKineticEnergy;
395
396 if( (endEnergy < m_threshold_Important_Energy)
398 // Kill the looping particle
399 //
400 m_particleChange.ProposeTrackStatus( fStopAndKill ) ;
401
402 // 'Bare' statistics
403 m_sumEnergyKilled += endEnergy;
404 if( endEnergy > m_maxEnergyKilled) { m_maxEnergyKilled= endEnergy; }
405
406#ifdef G4VERBOSE
407 if( (m_verboseLevel > 1) ||
408 ( endEnergy > m_threshold_Warning_Energy ) ) {
409 G4cout << " QuirkTransportation is killing track that is looping or stuck "
410 << G4endl
411 << " This track has " << track.GetKineticEnergy() / CLHEP::MeV
412 << " MeV energy." << G4endl;
413 G4cout << " Number of trials = " << m_noLooperTrials
414 << " No of calls to AlongStepDoIt = " << noCalls
415 << G4endl;
416 }
417#endif
419 }
420 else{
422#ifdef G4VERBOSE
423 if( (m_verboseLevel > 2) ){
424 G4cout << " QuirkTransportation::AlongStepDoIt(): Particle looping - "
425 << " Number of trials = " << m_noLooperTrials
426 << " No of calls to = " << noCalls
427 << G4endl;
428 }
429#endif
430 }
431 }else{
433 }
434
435 // Another (sometimes better way) is to use a user-limit maximum Step size
436 // to alleviate this problem ..
437
438 // Introduce smooth curved trajectories to particle-change
439 //
440 m_particleChange.SetPointerToVectorOfAuxiliaryPoints
441 (m_fieldPropagator->GimmeTrajectoryVectorAndForgetIt() );
442
443 return &m_particleChange ;
444}
445
447//
448// This ensures that the PostStep action is always called,
449// so that it can do the relocation if it is needed.
450//
451
454 G4double, // previousStepSize
455 G4ForceCondition* pForceCond )
456{
457 *pForceCond = Forced ;
458 return DBL_MAX ; // was kInfinity ; but convention now is DBL_MAX
459}
460
462//
463
464G4VParticleChange* QuirkTransportation::PostStepDoIt( const G4Track& track,
465 const G4Step& )
466{
467 G4TouchableHandle retCurrentTouchable ; // The one to return
468 G4bool isLastStep= false;
469
470 // Initialize ParticleChange (by setting all its members equal
471 // to corresponding members in G4Track)
472 // m_particleChange.Initialize(track) ; // To initialise TouchableChange
473
474 m_particleChange.ProposeTrackStatus(track.GetTrackStatus()) ;
475
476 // If the Step was determined by the volume boundary,
477 // logically relocate the particle
478
480 {
481 // fCurrentTouchable will now become the previous touchable,
482 // and what was the previous will be freed.
483 // (Needed because the preStepPoint can point to the previous touchable)
484
485 m_linearNavigator->SetGeometricallyLimitedStep() ;
487 LocateGlobalPointAndUpdateTouchableHandle( track.GetPosition(),
488 track.GetMomentumDirection(),
490 true ) ;
491 // Check whether the particle is out of the world volume
492 // If so it has exited and must be killed.
493 //
494 if( m_currentTouchableHandle->GetVolume() == 0 )
495 {
496 m_particleChange.ProposeTrackStatus( fStopAndKill ) ;
497 G4cout << "QuirkTransportation: number of steps = " << track.GetCurrentStepNumber() << G4endl;
498 }
499 retCurrentTouchable = m_currentTouchableHandle ;
500 m_particleChange.SetTouchableHandle( m_currentTouchableHandle ) ;
501
502 // Update the Step flag which identifies the Last Step in a volume
503 isLastStep = m_linearNavigator->ExitedMotherVolume()
504 || m_linearNavigator->EnteredDaughterVolume() ;
505
506#ifdef G4DEBUG_TRANSPORT
507 // Checking first implementation of flagging Last Step in Volume
508 G4bool exiting = m_linearNavigator->ExitedMotherVolume();
509 G4bool entering = m_linearNavigator->EnteredDaughterVolume();
510 if( ! (exiting || entering) ) {
511 G4cout << " Transport> : Proposed isLastStep= " << isLastStep
512 << " Exiting " << m_linearNavigator->ExitedMotherVolume()
513 << " Entering " << m_linearNavigator->EnteredDaughterVolume()
514 << G4endl;
515 }
516#endif
517 }
518 else // m_geometryLimitedStep is false
519 {
520 // This serves only to move the Navigator's location
521 //
522 m_linearNavigator->LocateGlobalPointWithinVolume( track.GetPosition() ) ;
523
524 // The value of the track's current Touchable is retained.
525 // (and it must be correct because we must use it below to
526 // overwrite the (unset) one in particle change)
527 // It must be fCurrentTouchable too ??
528 //
529 m_particleChange.SetTouchableHandle( track.GetTouchableHandle() ) ;
530 retCurrentTouchable = track.GetTouchableHandle() ;
531
532 isLastStep= false;
533#ifdef G4DEBUG_TRANSPORT
534 // Checking first implementation of flagging Last Step in Volume
535 G4cout << " Transport> Proposed isLastStep= " << isLastStep
536 << " Geometry did not limit step. " << G4endl;
537#endif
538 } // endif ( m_geometryLimitedStep )
539
540 m_particleChange.ProposeLastStepInVolume(isLastStep);
541
542 const G4VPhysicalVolume* pNewVol = retCurrentTouchable->GetVolume() ;
543 G4Material* pNewMaterial = 0 ;
544 G4VSensitiveDetector* pNewSensitiveDetector = 0 ;
545
546 if( pNewVol != 0 )
547 {
548 pNewMaterial= pNewVol->GetLogicalVolume()->GetMaterial();
549 pNewSensitiveDetector= pNewVol->GetLogicalVolume()->GetSensitiveDetector();
550 }
551
552 // ( <const_cast> pNewMaterial ) ;
553 // ( <const_cast> pNewSensitiveDetector) ;
554
555 m_particleChange.SetMaterialInTouchable( pNewMaterial ) ;
556 m_particleChange.SetSensitiveDetectorInTouchable( pNewSensitiveDetector ) ;
557
558 const G4MaterialCutsCouple* pNewMaterialCutsCouple = 0;
559 if( pNewVol != 0 )
560 {
561 pNewMaterialCutsCouple=pNewVol->GetLogicalVolume()->GetMaterialCutsCouple();
562 }
563
564 if( pNewVol!=0 && pNewMaterialCutsCouple!=0 && pNewMaterialCutsCouple->GetMaterial()!=pNewMaterial )
565 {
566 // for parametrized volume
567 //
568 pNewMaterialCutsCouple =
569 G4ProductionCutsTable::GetProductionCutsTable()
570 ->GetMaterialCutsCouple(pNewMaterial,
571 pNewMaterialCutsCouple->GetProductionCuts());
572 }
573 m_particleChange.SetMaterialCutsCoupleInTouchable( pNewMaterialCutsCouple );
574
575 // temporarily until Get/Set Material of ParticleChange,
576 // and StepPoint can be made const.
577 // Set the touchable in ParticleChange
578 // this must always be done because the particle change always
579 // uses this value to overwrite the current touchable pointer.
580 //
581 m_particleChange.SetTouchableHandle(retCurrentTouchable) ;
582
583 return &m_particleChange ;
584}
585
586// New method takes over the responsibility to reset the state of QuirkTransportation
587// object at the start of a new track or the resumption of a suspended track.
588
589void
591{
592 G4VProcess::StartTracking(aTrack);
593
594// The actions here are those that were taken in AlongStepGPIL
595// when track.GetCurrentStepNumber()==1
596
597 // reset safety value and center
598 //
599 m_previousSafety = 0.0 ;
600 m_previousSftOrigin = G4ThreeVector(0.,0.,0.) ;
601
602 // reset looping counter -- for motion in field
604 // Must clear this state .. else it depends on last track's value
605 // --> a better solution would set this from state of suspended track TODO ?
606 // Was if( aTrack->GetCurrentStepNumber()==1 ) { .. }
607
608 // ChordFinder reset internal state
609 //
610 m_fieldPropagator->ClearPropagatorState();
611 // Resets all state of field propagator class (ONLY)
612 // including safety values (in case of overlaps and to wipe for first track).
613
614 // G4ChordFinder* chordF= m_fieldPropagator->GetChordFinder();
615 // if( chordF ) chordF->ResetStepEstimate();
616
617 // Make sure to clear the chord finders of all fields (ie managers)
618 G4FieldManagerStore::GetInstance()->ClearAllChordFindersState();
619
620 // Update the current touchable handle (from the track's)
621 //
622 m_currentTouchableHandle = aTrack->GetTouchableHandle();
623
624 // Initialize infracolor string
625 auto part_nc ATLAS_THREAD_SAFE = // aTrack is non-const but GetParticleDefinition only returns const
626 const_cast<G4ParticleDefinition*>(aTrack->GetParticleDefinition());
627 Quirk* quirkDef = dynamic_cast<Quirk*>(part_nc);
628 if (quirkDef == 0) {
629 G4Exception("QuirkTransportation::StartTracking", "NonQuirk", FatalErrorInArgument, "QuirkTransportation run on non-quirk particle");
630 std::abort();
631 }
632 quirkDef->GetStringIn().StartTracking(aTrack);
633}
634
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