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