71 G4double G4EnergyLossTables::QQPositron = 1.0;
72 G4double G4EnergyLossTables::Chargesquare ;
73 G4int G4EnergyLossTables::oldIndex = -1 ;
74 G4double G4EnergyLossTables::rmin = 0. ;
75 G4double G4EnergyLossTables::rmax = 0. ;
76 G4double G4EnergyLossTables::Thigh = 0. ;
77 G4int G4EnergyLossTables::let_counter = 0;
78 G4int G4EnergyLossTables::let_max_num_warnings = 100;
79 G4bool G4EnergyLossTables::first_loss =
true;
81 G4EnergyLossTables::helper_map *G4EnergyLossTables::dict = 0;
96 theDEDXTable(aDEDXTable), theRangeTable(aRangeTable),
97 theInverseRangeTable(anInverseRangeTable),
98 theLabTimeTable(aLabTimeTable),
99 theProperTimeTable(aProperTimeTable),
100 theLowestKineticEnergy(aLowestKineticEnergy),
101 theHighestKineticEnergy(aHighestKineticEnergy),
102 theMassRatio(aMassRatio),
103 theNumberOfBins(aNumberOfBins)
110 theLowestKineticEnergy = 0.0;
111 theHighestKineticEnergy= 0.0;
130 if (!dict) dict =
new G4EnergyLossTables::helper_map;
135 tLabTime,tProperTime,lowestKineticEnergy,
136 highestKineticEnergy, massRatio,NumberOfBins);
153 if (!dict) dict =
new G4EnergyLossTables::helper_map;
154 helper_map::iterator it;
155 if((it=dict->find(p))==dict->end())
return 0;
156 return (*it).second.theDEDXTable;
164 if (!dict) dict =
new G4EnergyLossTables::helper_map;
165 helper_map::iterator it;
166 if((it=dict->find(p))==dict->end())
return 0;
167 return (*it).second.theRangeTable;
175 if (!dict) dict =
new G4EnergyLossTables::helper_map;
176 helper_map::iterator it;
177 if((it=dict->find(p))==dict->end())
return 0;
178 return (*it).second.theInverseRangeTable;
186 if (!dict) dict =
new G4EnergyLossTables::helper_map;
187 helper_map::iterator it;
188 if((it=dict->find(p))==dict->end())
return 0;
189 return (*it).second.theLabTimeTable;
197 if (!dict) dict =
new G4EnergyLossTables::helper_map;
198 helper_map::iterator it;
199 if((it=dict->find(p))==dict->end())
return 0;
200 return (*it).second.theProperTimeTable;
208 if (!dict) dict =
new G4EnergyLossTables::helper_map;
211 helper_map::iterator it;
212 if ((it=dict->find(p))==dict->end()) {
230 *t= GetTables(aParticle);
239 ParticleHaveNoLoss(aParticle,
"dEdx");
244 G4double scaledKineticEnergy = KineticEnergy*t->theMassRatio;
248 if (scaledKineticEnergy<t->theLowestKineticEnergy) {
250 dEdx =(*dEdxTable)(materialIndex)->GetValue(
251 t->theLowestKineticEnergy,isOut)
252 *std::sqrt(scaledKineticEnergy/t->theLowestKineticEnergy);
254 }
else if (scaledKineticEnergy>t->theHighestKineticEnergy) {
256 dEdx = (*dEdxTable)(materialIndex)->GetValue(
257 t->theHighestKineticEnergy,isOut);
261 dEdx = (*dEdxTable)(materialIndex)->GetValue(
262 scaledKineticEnergy,isOut);
266 return dEdx*Chargesquare;
281 *t= GetTables(aParticle);
287 ParticleHaveNoLoss(aParticle,
"LabTime");
291 const G4double parlowen=0.4 , ppar=0.5-parlowen ;
293 G4double scaledKineticEnergy = KineticEnergy*t->theMassRatio;
297 if (scaledKineticEnergy<t->theLowestKineticEnergy) {
299 time = std::exp(ppar*std::log(scaledKineticEnergy/t->theLowestKineticEnergy))*
300 (*labtimeTable)(materialIndex)->GetValue(
301 t->theLowestKineticEnergy,isOut);
304 }
else if (scaledKineticEnergy>t->theHighestKineticEnergy) {
306 time = (*labtimeTable)(materialIndex)->GetValue(
307 t->theHighestKineticEnergy,isOut);
311 time = (*labtimeTable)(materialIndex)->GetValue(
312 scaledKineticEnergy,isOut);
316 return time/t->theMassRatio ;
332 *t= GetTables(aParticle);
338 ParticleHaveNoLoss(aParticle,
"LabTime");
342 const G4double parlowen=0.4 , ppar=0.5-parlowen ;
343 const G4double dToverT = 0.05 , facT = 1. -dToverT ;
344 G4double timestart,timeend,deltatime,dTT;
348 G4double scaledKineticEnergy = KineticEnergyStart*t->theMassRatio;
350 if (scaledKineticEnergy<t->theLowestKineticEnergy) {
352 timestart = std::exp(ppar*std::log(scaledKineticEnergy/t->theLowestKineticEnergy))*
353 (*labtimeTable)(materialIndex)->GetValue(
354 t->theLowestKineticEnergy,isOut);
357 }
else if (scaledKineticEnergy>t->theHighestKineticEnergy) {
359 timestart = (*labtimeTable)(materialIndex)->GetValue(
360 t->theHighestKineticEnergy,isOut);
364 timestart = (*labtimeTable)(materialIndex)->GetValue(
365 scaledKineticEnergy,isOut);
369 dTT = (KineticEnergyStart - KineticEnergyEnd)/KineticEnergyStart ;
372 scaledKineticEnergy = facT*KineticEnergyStart*t->theMassRatio;
374 scaledKineticEnergy = KineticEnergyEnd*t->theMassRatio;
376 if (scaledKineticEnergy<t->theLowestKineticEnergy) {
378 timeend = std::exp(ppar*std::log(scaledKineticEnergy/t->theLowestKineticEnergy))*
379 (*labtimeTable)(materialIndex)->GetValue(
380 t->theLowestKineticEnergy,isOut);
383 }
else if (scaledKineticEnergy>t->theHighestKineticEnergy) {
385 timeend = (*labtimeTable)(materialIndex)->GetValue(
386 t->theHighestKineticEnergy,isOut);
390 timeend = (*labtimeTable)(materialIndex)->GetValue(
391 scaledKineticEnergy,isOut);
395 deltatime = timestart - timeend ;
398 deltatime *= dTT/dToverT;
400 return deltatime/t->theMassRatio ;
415 *t= GetTables(aParticle);
420 if (!propertimeTable) {
421 ParticleHaveNoLoss(aParticle,
"ProperTime");
425 const G4double parlowen=0.4 , ppar=0.5-parlowen ;
427 G4double scaledKineticEnergy = KineticEnergy*t->theMassRatio;
431 if (scaledKineticEnergy<t->theLowestKineticEnergy) {
433 time = std::exp(ppar*std::log(scaledKineticEnergy/t->theLowestKineticEnergy))*
434 (*propertimeTable)(materialIndex)->GetValue(
435 t->theLowestKineticEnergy,isOut);
438 }
else if (scaledKineticEnergy>t->theHighestKineticEnergy) {
440 time = (*propertimeTable)(materialIndex)->GetValue(
441 t->theHighestKineticEnergy,isOut);
445 time = (*propertimeTable)(materialIndex)->GetValue(
446 scaledKineticEnergy,isOut);
450 return time/t->theMassRatio ;
466 *t= GetTables(aParticle);
471 if (!propertimeTable) {
472 ParticleHaveNoLoss(aParticle,
"ProperTime");
476 const G4double parlowen=0.4 , ppar=0.5-parlowen ;
477 const G4double dToverT = 0.05 , facT = 1. -dToverT ;
478 G4double timestart,timeend,deltatime,dTT;
482 G4double scaledKineticEnergy = KineticEnergyStart*t->theMassRatio;
484 if (scaledKineticEnergy<t->theLowestKineticEnergy) {
486 timestart = std::exp(ppar*std::log(scaledKineticEnergy/t->theLowestKineticEnergy))*
487 (*propertimeTable)(materialIndex)->GetValue(
488 t->theLowestKineticEnergy,isOut);
491 }
else if (scaledKineticEnergy>t->theHighestKineticEnergy) {
493 timestart = (*propertimeTable)(materialIndex)->GetValue(
494 t->theHighestKineticEnergy,isOut);
498 timestart = (*propertimeTable)(materialIndex)->GetValue(
499 scaledKineticEnergy,isOut);
503 dTT = (KineticEnergyStart - KineticEnergyEnd)/KineticEnergyStart ;
506 scaledKineticEnergy = facT*KineticEnergyStart*t->theMassRatio;
508 scaledKineticEnergy = KineticEnergyEnd*t->theMassRatio;
510 if (scaledKineticEnergy<t->theLowestKineticEnergy) {
512 timeend = std::exp(ppar*std::log(scaledKineticEnergy/t->theLowestKineticEnergy))*
513 (*propertimeTable)(materialIndex)->GetValue(
514 t->theLowestKineticEnergy,isOut);
517 }
else if (scaledKineticEnergy>t->theHighestKineticEnergy) {
519 timeend = (*propertimeTable)(materialIndex)->GetValue(
520 t->theHighestKineticEnergy,isOut);
524 timeend = (*propertimeTable)(materialIndex)->GetValue(
525 scaledKineticEnergy,isOut);
529 deltatime = timestart - timeend ;
532 deltatime *= dTT/dToverT ;
534 return deltatime/t->theMassRatio ;
549 *t= GetTables(aParticle);
559 ParticleHaveNoLoss(aParticle,
"Range");
564 G4double scaledKineticEnergy = KineticEnergy*t->theMassRatio;
568 if (scaledKineticEnergy<t->theLowestKineticEnergy) {
570 Range = std::sqrt(scaledKineticEnergy/t->theLowestKineticEnergy)*
571 (*rangeTable)(materialIndex)->GetValue(
572 t->theLowestKineticEnergy,isOut);
574 }
else if (scaledKineticEnergy>t->theHighestKineticEnergy) {
576 Range = (*rangeTable)(materialIndex)->GetValue(
577 t->theHighestKineticEnergy,isOut)+
578 (scaledKineticEnergy-t->theHighestKineticEnergy)/
579 (*dEdxTable)(materialIndex)->GetValue(
580 t->theHighestKineticEnergy,isOut);
584 Range = (*rangeTable)(materialIndex)->GetValue(
585 scaledKineticEnergy,isOut);
589 return Range/(Chargesquare*t->theMassRatio);
605 *t= GetTables(aParticle);
614 if (!inverseRangeTable) {
615 ParticleHaveNoLoss(aParticle,
"InverseRange");
619 G4double scaledrange,scaledKineticEnergy ;
624 if(materialIndex != oldIndex)
626 oldIndex = materialIndex ;
627 rmin = (*inverseRangeTable)(materialIndex)->
628 GetLowEdgeEnergy(0) ;
629 rmax = (*inverseRangeTable)(materialIndex)->
630 GetLowEdgeEnergy(t->theNumberOfBins-2) ;
631 Thigh = (*inverseRangeTable)(materialIndex)->
632 GetValue(rmax,isOut) ;
635 scaledrange = range*Chargesquare*t->theMassRatio ;
637 if(scaledrange < rmin)
639 scaledKineticEnergy = t->theLowestKineticEnergy*
640 scaledrange*scaledrange/(rmin*rmin) ;
644 if(scaledrange < rmax)
646 scaledKineticEnergy = (*inverseRangeTable)(materialIndex)->
647 GetValue( scaledrange,isOut) ;
651 scaledKineticEnergy = Thigh +
653 (*dEdxTable)(materialIndex)->
654 GetValue(Thigh,isOut) ;
658 return scaledKineticEnergy/t->theMassRatio ;
673 *t= GetTables(aParticle);
682 ParticleHaveNoLoss(aParticle,
"dEdx");
687 G4double scaledKineticEnergy = KineticEnergy*t->theMassRatio;
691 if (scaledKineticEnergy<t->theLowestKineticEnergy) {
693 dEdx = std::sqrt(scaledKineticEnergy/t->theLowestKineticEnergy)
694 *(*dEdxTable)(materialIndex)->GetValue(
695 t->theLowestKineticEnergy,isOut);
697 }
else if (scaledKineticEnergy>t->theHighestKineticEnergy) {
699 dEdx = (*dEdxTable)(materialIndex)->GetValue(
700 t->theHighestKineticEnergy,isOut);
704 dEdx = (*dEdxTable)(materialIndex)->GetValue(
705 scaledKineticEnergy,isOut) ;
709 return dEdx*Chargesquare;
724 *t= GetTables(aParticle);
734 ParticleHaveNoLoss(aParticle,
"Range");
739 G4double Thighr = t->theHighestKineticEnergy*t->theLowestKineticEnergy/
740 (*rangeTable)(materialIndex)->
741 GetLowEdgeEnergy(1) ;
743 G4double scaledKineticEnergy = KineticEnergy*t->theMassRatio;
747 if (scaledKineticEnergy<t->theLowestKineticEnergy) {
749 Range = std::sqrt(scaledKineticEnergy/t->theLowestKineticEnergy)*
750 (*rangeTable)(materialIndex)->GetValue(
751 t->theLowestKineticEnergy,isOut);
753 }
else if (scaledKineticEnergy>Thighr) {
755 Range = (*rangeTable)(materialIndex)->GetValue(
757 (scaledKineticEnergy-Thighr)/
758 (*dEdxTable)(materialIndex)->GetValue(
763 Range = (*rangeTable)(materialIndex)->GetValue(
764 scaledKineticEnergy,isOut) ;
768 return Range/(Chargesquare*t->theMassRatio);
783 *t= GetTables(aParticle);
794 else ParticleHaveNoLoss(aParticle,
"dEdx");
799 G4double scaledKineticEnergy = KineticEnergy*t->theMassRatio;
803 if (scaledKineticEnergy<t->theLowestKineticEnergy) {
805 dEdx =(*dEdxTable)(materialIndex)->GetValue(
806 t->theLowestKineticEnergy,isOut)
807 *std::sqrt(scaledKineticEnergy/t->theLowestKineticEnergy);
809 }
else if (scaledKineticEnergy>t->theHighestKineticEnergy) {
811 dEdx = (*dEdxTable)(materialIndex)->GetValue(
812 t->theHighestKineticEnergy,isOut);
816 dEdx = (*dEdxTable)(materialIndex)->GetValue(
817 scaledKineticEnergy,isOut);
821 return dEdx*Chargesquare;
836 *t= GetTables(aParticle);
852 G4double scaledKineticEnergy = KineticEnergy*t->theMassRatio;
856 if (scaledKineticEnergy<t->theLowestKineticEnergy) {
858 Range = std::sqrt(scaledKineticEnergy/t->theLowestKineticEnergy)*
859 (*rangeTable)(materialIndex)->GetValue(
860 t->theLowestKineticEnergy,isOut);
862 }
else if (scaledKineticEnergy>t->theHighestKineticEnergy) {
864 Range = (*rangeTable)(materialIndex)->GetValue(
865 t->theHighestKineticEnergy,isOut)+
866 (scaledKineticEnergy-t->theHighestKineticEnergy)/
867 (*dEdxTable)(materialIndex)->GetValue(
868 t->theHighestKineticEnergy,isOut);
872 Range = (*rangeTable)(materialIndex)->GetValue(
873 scaledKineticEnergy,isOut);
877 return Range/(Chargesquare*t->theMassRatio);
893 *t= GetTables(aParticle);
903 if (!inverseRangeTable) {
909 G4double scaledrange,scaledKineticEnergy ;
914 if(materialIndex != oldIndex)
916 oldIndex = materialIndex ;
917 rmin = (*inverseRangeTable)(materialIndex)->
918 GetLowEdgeEnergy(0) ;
919 rmax = (*inverseRangeTable)(materialIndex)->
920 GetLowEdgeEnergy(t->theNumberOfBins-2) ;
921 Thigh = (*inverseRangeTable)(materialIndex)->
922 GetValue(rmax,isOut) ;
925 scaledrange = range*Chargesquare*t->theMassRatio ;
927 if(scaledrange < rmin)
929 scaledKineticEnergy = t->theLowestKineticEnergy*
930 scaledrange*scaledrange/(rmin*rmin) ;
934 if(scaledrange < rmax)
936 scaledKineticEnergy = (*inverseRangeTable)(materialIndex)->
937 GetValue( scaledrange,isOut) ;
941 scaledKineticEnergy = Thigh +
943 (*dEdxTable)(materialIndex)->
944 GetValue(Thigh,isOut) ;
948 return scaledKineticEnergy/t->theMassRatio ;
962 *t= GetTables(aParticle);
974 G4double scaledKineticEnergy = KineticEnergy*t->theMassRatio;
978 if (scaledKineticEnergy<t->theLowestKineticEnergy) {
980 dEdx = std::sqrt(scaledKineticEnergy/t->theLowestKineticEnergy)
981 *(*dEdxTable)(materialIndex)->GetValue(
982 t->theLowestKineticEnergy,isOut);
984 }
else if (scaledKineticEnergy>t->theHighestKineticEnergy) {
986 dEdx = (*dEdxTable)(materialIndex)->GetValue(
987 t->theHighestKineticEnergy,isOut);
991 dEdx = (*dEdxTable)(materialIndex)->GetValue(
992 scaledKineticEnergy,isOut) ;
996 return dEdx*Chargesquare;
1010 *t= GetTables(aParticle);
1019 if ( !dEdxTable || !rangeTable)
1024 G4double Thighr = t->theHighestKineticEnergy*t->theLowestKineticEnergy/
1025 (*rangeTable)(materialIndex)->
1026 GetLowEdgeEnergy(1) ;
1028 G4double scaledKineticEnergy = KineticEnergy*t->theMassRatio;
1032 if (scaledKineticEnergy<t->theLowestKineticEnergy) {
1034 Range = std::sqrt(scaledKineticEnergy/t->theLowestKineticEnergy)*
1035 (*rangeTable)(materialIndex)->GetValue(
1036 t->theLowestKineticEnergy,isOut);
1038 }
else if (scaledKineticEnergy>Thighr) {
1040 Range = (*rangeTable)(materialIndex)->GetValue(
1042 (scaledKineticEnergy-Thighr)/
1043 (*dEdxTable)(materialIndex)->GetValue(
1048 Range = (*rangeTable)(materialIndex)->GetValue(
1049 scaledKineticEnergy,isOut) ;
1053 return Range/(Chargesquare*t->theMassRatio);
1058 void G4EnergyLossTables::CPRWarning()
1060 if (let_counter < let_max_num_warnings) {
1063 G4cout <<
"##### G4EnergyLossTable WARNING: The obsolete interface is used!" <<
G4endl;
1064 G4cout <<
"##### RESULTS ARE NOT GARANTEED!" <<
G4endl;
1065 G4cout <<
"##### Please, substitute G4Material by G4MaterialCutsCouple" <<
G4endl;
1066 G4cout <<
"##### Obsolete interface will be removed soon" <<
G4endl;
1070 }
else if (let_counter == let_max_num_warnings) {
1072 G4cout <<
"##### G4EnergyLossTable WARNING closed" <<
G4endl;
static G4double GetDeltaProperTime(const G4ParticleDefinition *aParticle, G4double KineticEnergyStart, G4double KineticEnergyEnd, const G4Material *aMaterial)
static G4LossTableManager * Instance()
G4double GetDEDX(const G4ParticleDefinition *aParticle, G4double kineticEnergy, const G4MaterialCutsCouple *couple)
static const G4PhysicsTable * GetDEDXTable(const G4ParticleDefinition *p)
static G4double GetDeltaLabTime(const G4ParticleDefinition *aParticle, G4double KineticEnergyStart, G4double KineticEnergyEnd, const G4Material *aMaterial)
G4EnergyLossTablesHelper()
G4GLOB_DLL std::ostream G4cout
const G4ParticleDefinition const G4Material *G4double range
static G4double GetLabTime(const G4ParticleDefinition *aParticle, G4double KineticEnergy, const G4Material *aMaterial)
static G4double GetPreciseRangeFromEnergy(const G4ParticleDefinition *aParticle, G4double KineticEnergy, const G4Material *aMaterial)
G4double GetEnergy(const G4ParticleDefinition *aParticle, G4double range, const G4MaterialCutsCouple *couple)
static const G4PhysicsTable * GetLabTimeTable(const G4ParticleDefinition *p)
static const G4PhysicsTable * GetRangeTable(const G4ParticleDefinition *p)
static G4double GetDEDX(const G4ParticleDefinition *aParticle, G4double KineticEnergy, const G4Material *aMaterial)
static G4double GetProperTime(const G4ParticleDefinition *aParticle, G4double KineticEnergy, const G4Material *aMaterial)
static void Register(const G4ParticleDefinition *p, const G4PhysicsTable *tDEDX, const G4PhysicsTable *tRange, const G4PhysicsTable *tInverseRange, const G4PhysicsTable *tLabTime, const G4PhysicsTable *tProperTime, G4double lowestKineticEnergy, G4double highestKineticEnergy, G4double massRatio, G4int NumberOfBins)
static const G4PhysicsTable * GetInverseRangeTable(const G4ParticleDefinition *p)
G4double GetPDGCharge() const
static G4double GetPreciseEnergyFromRange(const G4ParticleDefinition *aParticle, G4double range, const G4Material *aMaterial)
static G4double GetPreciseDEDX(const G4ParticleDefinition *aParticle, G4double KineticEnergy, const G4Material *aMaterial)
G4double GetRange(const G4ParticleDefinition *aParticle, G4double kineticEnergy, const G4MaterialCutsCouple *couple)
static const G4PhysicsTable * GetProperTimeTable(const G4ParticleDefinition *p)
static G4double GetRange(const G4ParticleDefinition *aParticle, G4double KineticEnergy, const G4Material *aMaterial)