// This code implementation is the intellectual property of // the GEANT4 collaboration. // // By copying, distributing or modifying the Program (or any work // based on the Program) you indicate your acceptance of this statement, // and all its terms. // // $Id: G4EnergyLossTables.icc,v 1.11 2000/05/23 14:24:47 urban Exp $ // GEANT4 tag $Name: geant4-02-00 $ // // $Id: // Inline members of the G4EnergyLossTables class // // ------------------------------------------------------------------- // first version created by P.Urban , 06/04/1998 // modified by L.Urban , 27/05/98 // cache mechanism , L.Urban , 11/02/99 // bug fixed , L.Urban , 12/04/99 // 10/11/99: moved from RWT hash dictionary to STL map, G.Barrand, M.Maire // // ------------------------------------------------------------------- //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... inline G4EnergyLossTablesHelper::G4EnergyLossTablesHelper( const G4PhysicsTable* aDEDXTable, const G4PhysicsTable* aRangeTable, const G4PhysicsTable* anInverseRangeTable, const G4PhysicsTable* aLabTimeTable, const G4PhysicsTable* aProperTimeTable, G4double aLowestKineticEnergy, G4double aHighestKineticEnergy, G4double aMassRatio, G4int aNumberOfBins) : theDEDXTable(aDEDXTable), theRangeTable(aRangeTable), theInverseRangeTable(anInverseRangeTable), theLabTimeTable(aLabTimeTable), theProperTimeTable(aProperTimeTable), theLowestKineticEnergy(aLowestKineticEnergy), theHighestKineticEnergy(aHighestKineticEnergy), theMassRatio(aMassRatio), theNumberOfBins(aNumberOfBins) { } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... inline G4EnergyLossTablesHelper::G4EnergyLossTablesHelper() { } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... inline const G4PhysicsTable* G4EnergyLossTables::GetDEDXTable( const G4ParticleDefinition* p) { helper_map::iterator it; if((it=dict.find(p))==dict.end()) return 0; return (*it).second.theDEDXTable; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... inline const G4PhysicsTable* G4EnergyLossTables::GetRangeTable( const G4ParticleDefinition* p) { helper_map::iterator it; if((it=dict.find(p))==dict.end()) return 0; return (*it).second.theRangeTable; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... inline const G4PhysicsTable* G4EnergyLossTables::GetInverseRangeTable( const G4ParticleDefinition* p) { helper_map::iterator it; if((it=dict.find(p))==dict.end()) return 0; return (*it).second.theInverseRangeTable; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... inline const G4PhysicsTable* G4EnergyLossTables::GetLabTimeTable( const G4ParticleDefinition* p) { helper_map::iterator it; if((it=dict.find(p))==dict.end()) return 0; return (*it).second.theLabTimeTable; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... inline const G4PhysicsTable* G4EnergyLossTables::GetProperTimeTable( const G4ParticleDefinition* p) { helper_map::iterator it; if((it=dict.find(p))==dict.end()) return 0; return (*it).second.theProperTimeTable; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... inline G4EnergyLossTablesHelper G4EnergyLossTables::GetTables( const G4ParticleDefinition* p) { helper_map::iterator it; if((it=dict.find(p))==dict.end()) { G4Exception("G4EnergyLossTables::GetTables: table not found!"); exit(1); } return (*it).second; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... inline G4double G4EnergyLossTables::GetDEDX( const G4ParticleDefinition *aParticle, G4double KineticEnergy, G4Material *aMaterial) { if(aParticle != lastParticle) { t= GetTables(aParticle); lastParticle = aParticle ; Chargesquare = (aParticle->GetPDGCharge())* (aParticle->GetPDGCharge())/ QQPositron ; } const G4PhysicsTable* dEdxTable= t.theDEDXTable; G4int materialIndex = aMaterial->GetIndex(); G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio; G4double dEdx; G4bool isOut; if (scaledKineticEnergyGetValue( t.theLowestKineticEnergy,isOut) *sqrt(scaledKineticEnergy/t.theLowestKineticEnergy); } else if (scaledKineticEnergy>t.theHighestKineticEnergy) { dEdx = (*dEdxTable)(materialIndex)->GetValue( t.theHighestKineticEnergy,isOut); } else { dEdx = (*dEdxTable)(materialIndex)->GetValue( scaledKineticEnergy,isOut); } return dEdx*Chargesquare; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... inline G4double G4EnergyLossTables::GetLabTime( const G4ParticleDefinition *aParticle, G4double KineticEnergy, G4Material *aMaterial) { if(aParticle != lastParticle) { t= GetTables(aParticle); lastParticle = aParticle ; } const G4PhysicsTable* labtimeTable= t.theLabTimeTable; const G4double parlowen=0.4 , ppar=0.5-parlowen ; G4int materialIndex = aMaterial->GetIndex(); G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio; G4double time; G4bool isOut; if (scaledKineticEnergyGetValue( t.theLowestKineticEnergy,isOut); } else if (scaledKineticEnergy>t.theHighestKineticEnergy) { time = (*labtimeTable)(materialIndex)->GetValue( t.theHighestKineticEnergy,isOut); } else { time = (*labtimeTable)(materialIndex)->GetValue( scaledKineticEnergy,isOut); } return time/t.theMassRatio ; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... inline G4double G4EnergyLossTables::GetDeltaLabTime( const G4ParticleDefinition *aParticle, G4double KineticEnergyStart, G4double KineticEnergyEnd, G4Material *aMaterial) { if(aParticle != lastParticle) { t= GetTables(aParticle); lastParticle = aParticle ; } const G4PhysicsTable* labtimeTable= t.theLabTimeTable; const G4double parlowen=0.4 , ppar=0.5-parlowen ; const G4double dToverT = 0.05 , facT = 1. -dToverT ; G4double timestart,timeend,deltatime,dTT; G4bool isOut; G4int materialIndex = aMaterial->GetIndex(); G4double scaledKineticEnergy = KineticEnergyStart*t.theMassRatio; if (scaledKineticEnergyGetValue( t.theLowestKineticEnergy,isOut); } else if (scaledKineticEnergy>t.theHighestKineticEnergy) { timestart = (*labtimeTable)(materialIndex)->GetValue( t.theHighestKineticEnergy,isOut); } else { timestart = (*labtimeTable)(materialIndex)->GetValue( scaledKineticEnergy,isOut); } dTT = (KineticEnergyStart - KineticEnergyEnd)/KineticEnergyStart ; if( dTT < dToverT ) scaledKineticEnergy = facT*KineticEnergyStart*t.theMassRatio; else scaledKineticEnergy = KineticEnergyEnd*t.theMassRatio; if (scaledKineticEnergyGetValue( t.theLowestKineticEnergy,isOut); } else if (scaledKineticEnergy>t.theHighestKineticEnergy) { timeend = (*labtimeTable)(materialIndex)->GetValue( t.theHighestKineticEnergy,isOut); } else { timeend = (*labtimeTable)(materialIndex)->GetValue( scaledKineticEnergy,isOut); } deltatime = timestart - timeend ; if( dTT < dToverT ) deltatime *= dTT/dToverT; return deltatime/t.theMassRatio ; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... inline G4double G4EnergyLossTables::GetProperTime( const G4ParticleDefinition *aParticle, G4double KineticEnergy, G4Material *aMaterial) { if(aParticle != lastParticle) { t= GetTables(aParticle); lastParticle = aParticle ; } const G4PhysicsTable* propertimeTable= t.theProperTimeTable; const G4double parlowen=0.4 , ppar=0.5-parlowen ; G4int materialIndex = aMaterial->GetIndex(); G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio; G4double time; G4bool isOut; if (scaledKineticEnergyGetValue( t.theLowestKineticEnergy,isOut); } else if (scaledKineticEnergy>t.theHighestKineticEnergy) { time = (*propertimeTable)(materialIndex)->GetValue( t.theHighestKineticEnergy,isOut); } else { time = (*propertimeTable)(materialIndex)->GetValue( scaledKineticEnergy,isOut); } return time/t.theMassRatio ; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... inline G4double G4EnergyLossTables::GetDeltaProperTime( const G4ParticleDefinition *aParticle, G4double KineticEnergyStart, G4double KineticEnergyEnd, G4Material *aMaterial) { if(aParticle != lastParticle) { t= GetTables(aParticle); lastParticle = aParticle ; } const G4PhysicsTable* propertimeTable= t.theProperTimeTable; const G4double parlowen=0.4 , ppar=0.5-parlowen ; const G4double dToverT = 0.05 , facT = 1. -dToverT ; G4double timestart,timeend,deltatime,dTT; G4bool isOut; G4int materialIndex = aMaterial->GetIndex(); G4double scaledKineticEnergy = KineticEnergyStart*t.theMassRatio; if (scaledKineticEnergyGetValue( t.theLowestKineticEnergy,isOut); } else if (scaledKineticEnergy>t.theHighestKineticEnergy) { timestart = (*propertimeTable)(materialIndex)->GetValue( t.theHighestKineticEnergy,isOut); } else { timestart = (*propertimeTable)(materialIndex)->GetValue( scaledKineticEnergy,isOut); } dTT = (KineticEnergyStart - KineticEnergyEnd)/KineticEnergyStart ; if( dTT < dToverT ) scaledKineticEnergy = facT*KineticEnergyStart*t.theMassRatio; else scaledKineticEnergy = KineticEnergyEnd*t.theMassRatio; if (scaledKineticEnergyGetValue( t.theLowestKineticEnergy,isOut); } else if (scaledKineticEnergy>t.theHighestKineticEnergy) { timeend = (*propertimeTable)(materialIndex)->GetValue( t.theHighestKineticEnergy,isOut); } else { timeend = (*propertimeTable)(materialIndex)->GetValue( scaledKineticEnergy,isOut); } deltatime = timestart - timeend ; if( dTT < dToverT ) deltatime *= dTT/dToverT ; return deltatime/t.theMassRatio ; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... inline G4double G4EnergyLossTables::GetRange( const G4ParticleDefinition *aParticle, G4double KineticEnergy, G4Material *aMaterial) { if(aParticle != lastParticle) { t= GetTables(aParticle); lastParticle = aParticle ; Chargesquare = (aParticle->GetPDGCharge())* (aParticle->GetPDGCharge())/ QQPositron ; } const G4PhysicsTable* rangeTable= t.theRangeTable; const G4PhysicsTable* dEdxTable= t.theDEDXTable; G4int materialIndex = aMaterial->GetIndex(); G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio; G4double Range; G4bool isOut; if (scaledKineticEnergyGetValue( t.theLowestKineticEnergy,isOut); } else if (scaledKineticEnergy>t.theHighestKineticEnergy) { Range = (*rangeTable)(materialIndex)->GetValue( t.theHighestKineticEnergy,isOut)+ (scaledKineticEnergy-t.theHighestKineticEnergy)/ (*dEdxTable)(materialIndex)->GetValue( t.theHighestKineticEnergy,isOut); } else { Range = (*rangeTable)(materialIndex)->GetValue( scaledKineticEnergy,isOut); } return Range/(Chargesquare*t.theMassRatio); } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... inline G4double G4EnergyLossTables::GetPreciseEnergyFromRange( const G4ParticleDefinition *aParticle, G4double range, G4Material *aMaterial) // it returns the value of the kinetic energy for a given range { if( aParticle != lastParticle) { t= GetTables(aParticle); lastParticle = aParticle; Chargesquare = (aParticle->GetPDGCharge())* (aParticle->GetPDGCharge())/ QQPositron ; oldIndex = -1 ; } const G4PhysicsTable* rangeTable= t.theRangeTable; const G4PhysicsTable* dEdxTable= t.theDEDXTable; const G4PhysicsTable* inverseRangeTable= t.theInverseRangeTable; G4double scaledrange,scaledKineticEnergy ; G4bool isOut ; G4int materialIndex = aMaterial->GetIndex() ; if(materialIndex != oldIndex) { oldIndex = materialIndex ; rmin = (*inverseRangeTable)(materialIndex)-> GetLowEdgeEnergy(0) ; rmax = (*inverseRangeTable)(materialIndex)-> GetLowEdgeEnergy(t.theNumberOfBins-2) ; Thigh = (*inverseRangeTable)(materialIndex)-> GetValue(rmax,isOut) ; } scaledrange = range*Chargesquare*t.theMassRatio ; if(scaledrange < rmin) { scaledKineticEnergy = t.theLowestKineticEnergy* scaledrange*scaledrange/(rmin*rmin) ; } else { if(scaledrange < rmax) { scaledKineticEnergy = (*inverseRangeTable)(materialIndex)-> GetValue( scaledrange,isOut) ; } else { scaledKineticEnergy = Thigh + (scaledrange-rmax)* (*dEdxTable)(materialIndex)-> GetValue(Thigh,isOut) ; } } return scaledKineticEnergy/t.theMassRatio ; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......