56G4double G4EnergyLossTables::QQPositron = eplus*eplus ;
57G4double G4EnergyLossTables::Chargesquare ;
58G4int G4EnergyLossTables::oldIndex = -1 ;
59G4double G4EnergyLossTables::rmin = 0. ;
60G4double G4EnergyLossTables::rmax = 0. ;
61G4double G4EnergyLossTables::Thigh = 0. ;
62G4int G4EnergyLossTables::let_counter = 0;
63G4int G4EnergyLossTables::let_max_num_warnings = 100;
64G4bool G4EnergyLossTables::first_loss =
true;
66G4EnergyLossTables::helper_map G4EnergyLossTables::dict;
81 theDEDXTable(aDEDXTable), theRangeTable(aRangeTable),
82 theInverseRangeTable(anInverseRangeTable),
83 theLabTimeTable(aLabTimeTable),
84 theProperTimeTable(aProperTimeTable),
85 theLowestKineticEnergy(aLowestKineticEnergy),
86 theHighestKineticEnergy(aHighestKineticEnergy),
87 theMassRatio(aMassRatio),
88 theNumberOfBins(aNumberOfBins)
95 theLowestKineticEnergy = 0.0;
96 theHighestKineticEnergy= 0.0;
116 tLabTime,tProperTime,lowestKineticEnergy,
117 highestKineticEnergy, massRatio,NumberOfBins);
134 helper_map::iterator it;
135 if((it=dict.find(p))==dict.end())
return 0;
136 return (*it).second.theDEDXTable;
144 helper_map::iterator it;
145 if((it=dict.find(p))==dict.end())
return 0;
146 return (*it).second.theRangeTable;
154 helper_map::iterator it;
155 if((it=dict.find(p))==dict.end())
return 0;
156 return (*it).second.theInverseRangeTable;
164 helper_map::iterator it;
165 if((it=dict.find(p))==dict.end())
return 0;
166 return (*it).second.theLabTimeTable;
174 helper_map::iterator it;
175 if((it=dict.find(p))==dict.end())
return 0;
176 return (*it).second.theProperTimeTable;
184 helper_map::iterator it;
185 if ((it=dict.find(p))==dict.end()) {
202 if(aParticle != lastParticle)
204 t= GetTables(aParticle);
205 lastParticle = aParticle ;
213 ParticleHaveNoLoss(aParticle,
"dEdx");
218 G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
222 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
224 dEdx =(*dEdxTable)(materialIndex)->GetValue(
225 t.theLowestKineticEnergy,isOut)
226 *std::sqrt(scaledKineticEnergy/t.theLowestKineticEnergy);
228 }
else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
230 dEdx = (*dEdxTable)(materialIndex)->GetValue(
231 t.theHighestKineticEnergy,isOut);
235 dEdx = (*dEdxTable)(materialIndex)->GetValue(
236 scaledKineticEnergy,isOut);
240 return dEdx*Chargesquare;
251 if(aParticle != lastParticle)
253 t= GetTables(aParticle);
254 lastParticle = aParticle ;
259 ParticleHaveNoLoss(aParticle,
"LabTime");
263 const G4double parlowen=0.4 , ppar=0.5-parlowen ;
265 G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
269 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
271 time = std::exp(ppar*std::log(scaledKineticEnergy/t.theLowestKineticEnergy))*
272 (*labtimeTable)(materialIndex)->GetValue(
273 t.theLowestKineticEnergy,isOut);
276 }
else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
278 time = (*labtimeTable)(materialIndex)->GetValue(
279 t.theHighestKineticEnergy,isOut);
283 time = (*labtimeTable)(materialIndex)->GetValue(
284 scaledKineticEnergy,isOut);
288 return time/t.theMassRatio ;
300 if(aParticle != lastParticle)
302 t= GetTables(aParticle);
303 lastParticle = aParticle ;
308 ParticleHaveNoLoss(aParticle,
"LabTime");
312 const G4double parlowen=0.4 , ppar=0.5-parlowen ;
313 const G4double dToverT = 0.05 , facT = 1. -dToverT ;
314 G4double timestart,timeend,deltatime,dTT;
318 G4double scaledKineticEnergy = KineticEnergyStart*t.theMassRatio;
320 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
322 timestart = std::exp(ppar*std::log(scaledKineticEnergy/t.theLowestKineticEnergy))*
323 (*labtimeTable)(materialIndex)->GetValue(
324 t.theLowestKineticEnergy,isOut);
327 }
else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
329 timestart = (*labtimeTable)(materialIndex)->GetValue(
330 t.theHighestKineticEnergy,isOut);
334 timestart = (*labtimeTable)(materialIndex)->GetValue(
335 scaledKineticEnergy,isOut);
339 dTT = (KineticEnergyStart - KineticEnergyEnd)/KineticEnergyStart ;
342 scaledKineticEnergy = facT*KineticEnergyStart*t.theMassRatio;
344 scaledKineticEnergy = KineticEnergyEnd*t.theMassRatio;
346 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
348 timeend = std::exp(ppar*std::log(scaledKineticEnergy/t.theLowestKineticEnergy))*
349 (*labtimeTable)(materialIndex)->GetValue(
350 t.theLowestKineticEnergy,isOut);
353 }
else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
355 timeend = (*labtimeTable)(materialIndex)->GetValue(
356 t.theHighestKineticEnergy,isOut);
360 timeend = (*labtimeTable)(materialIndex)->GetValue(
361 scaledKineticEnergy,isOut);
365 deltatime = timestart - timeend ;
368 deltatime *= dTT/dToverT;
370 return deltatime/t.theMassRatio ;
381 if(aParticle != lastParticle)
383 t= GetTables(aParticle);
384 lastParticle = aParticle ;
388 if (!propertimeTable) {
389 ParticleHaveNoLoss(aParticle,
"ProperTime");
393 const G4double parlowen=0.4 , ppar=0.5-parlowen ;
395 G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
399 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
401 time = std::exp(ppar*std::log(scaledKineticEnergy/t.theLowestKineticEnergy))*
402 (*propertimeTable)(materialIndex)->GetValue(
403 t.theLowestKineticEnergy,isOut);
406 }
else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
408 time = (*propertimeTable)(materialIndex)->GetValue(
409 t.theHighestKineticEnergy,isOut);
413 time = (*propertimeTable)(materialIndex)->GetValue(
414 scaledKineticEnergy,isOut);
418 return time/t.theMassRatio ;
430 if(aParticle != lastParticle)
432 t= GetTables(aParticle);
433 lastParticle = aParticle ;
437 if (!propertimeTable) {
438 ParticleHaveNoLoss(aParticle,
"ProperTime");
442 const G4double parlowen=0.4 , ppar=0.5-parlowen ;
443 const G4double dToverT = 0.05 , facT = 1. -dToverT ;
444 G4double timestart,timeend,deltatime,dTT;
448 G4double scaledKineticEnergy = KineticEnergyStart*t.theMassRatio;
450 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
452 timestart = std::exp(ppar*std::log(scaledKineticEnergy/t.theLowestKineticEnergy))*
453 (*propertimeTable)(materialIndex)->GetValue(
454 t.theLowestKineticEnergy,isOut);
457 }
else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
459 timestart = (*propertimeTable)(materialIndex)->GetValue(
460 t.theHighestKineticEnergy,isOut);
464 timestart = (*propertimeTable)(materialIndex)->GetValue(
465 scaledKineticEnergy,isOut);
469 dTT = (KineticEnergyStart - KineticEnergyEnd)/KineticEnergyStart ;
472 scaledKineticEnergy = facT*KineticEnergyStart*t.theMassRatio;
474 scaledKineticEnergy = KineticEnergyEnd*t.theMassRatio;
476 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
478 timeend = std::exp(ppar*std::log(scaledKineticEnergy/t.theLowestKineticEnergy))*
479 (*propertimeTable)(materialIndex)->GetValue(
480 t.theLowestKineticEnergy,isOut);
483 }
else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
485 timeend = (*propertimeTable)(materialIndex)->GetValue(
486 t.theHighestKineticEnergy,isOut);
490 timeend = (*propertimeTable)(materialIndex)->GetValue(
491 scaledKineticEnergy,isOut);
495 deltatime = timestart - timeend ;
498 deltatime *= dTT/dToverT ;
500 return deltatime/t.theMassRatio ;
511 if(aParticle != lastParticle)
513 t= GetTables(aParticle);
514 lastParticle = aParticle ;
523 ParticleHaveNoLoss(aParticle,
"Range");
528 G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
532 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
534 Range = std::sqrt(scaledKineticEnergy/t.theLowestKineticEnergy)*
535 (*rangeTable)(materialIndex)->GetValue(
536 t.theLowestKineticEnergy,isOut);
538 }
else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
540 Range = (*rangeTable)(materialIndex)->GetValue(
541 t.theHighestKineticEnergy,isOut)+
542 (scaledKineticEnergy-t.theHighestKineticEnergy)/
543 (*dEdxTable)(materialIndex)->GetValue(
544 t.theHighestKineticEnergy,isOut);
548 Range = (*rangeTable)(materialIndex)->GetValue(
549 scaledKineticEnergy,isOut);
553 return Range/(Chargesquare*t.theMassRatio);
565 if( aParticle != lastParticle)
567 t= GetTables(aParticle);
568 lastParticle = aParticle;
576 if (!inverseRangeTable) {
577 ParticleHaveNoLoss(aParticle,
"InverseRange");
581 G4double scaledrange,scaledKineticEnergy ;
586 if(materialIndex != oldIndex)
588 oldIndex = materialIndex ;
589 rmin = (*inverseRangeTable)(materialIndex)->
590 GetLowEdgeEnergy(0) ;
591 rmax = (*inverseRangeTable)(materialIndex)->
592 GetLowEdgeEnergy(t.theNumberOfBins-2) ;
593 Thigh = (*inverseRangeTable)(materialIndex)->
594 GetValue(rmax,isOut) ;
597 scaledrange = range*Chargesquare*t.theMassRatio ;
599 if(scaledrange < rmin)
601 scaledKineticEnergy = t.theLowestKineticEnergy*
602 scaledrange*scaledrange/(rmin*rmin) ;
606 if(scaledrange < rmax)
608 scaledKineticEnergy = (*inverseRangeTable)(materialIndex)->
609 GetValue( scaledrange,isOut) ;
613 scaledKineticEnergy = Thigh +
615 (*dEdxTable)(materialIndex)->
616 GetValue(Thigh,isOut) ;
620 return scaledKineticEnergy/t.theMassRatio ;
631 if( aParticle != lastParticle)
633 t= GetTables(aParticle);
634 lastParticle = aParticle;
642 ParticleHaveNoLoss(aParticle,
"dEdx");
647 G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
651 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
653 dEdx = std::sqrt(scaledKineticEnergy/t.theLowestKineticEnergy)
654 *(*dEdxTable)(materialIndex)->GetValue(
655 t.theLowestKineticEnergy,isOut);
657 }
else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
659 dEdx = (*dEdxTable)(materialIndex)->GetValue(
660 t.theHighestKineticEnergy,isOut);
664 dEdx = (*dEdxTable)(materialIndex)->GetValue(
665 scaledKineticEnergy,isOut) ;
669 return dEdx*Chargesquare;
680 if( aParticle != lastParticle)
682 t= GetTables(aParticle);
683 lastParticle = aParticle;
692 ParticleHaveNoLoss(aParticle,
"Range");
697 G4double Thighr = t.theHighestKineticEnergy*t.theLowestKineticEnergy/
698 (*rangeTable)(materialIndex)->
699 GetLowEdgeEnergy(1) ;
701 G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
705 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
707 Range = std::sqrt(scaledKineticEnergy/t.theLowestKineticEnergy)*
708 (*rangeTable)(materialIndex)->GetValue(
709 t.theLowestKineticEnergy,isOut);
711 }
else if (scaledKineticEnergy>Thighr) {
713 Range = (*rangeTable)(materialIndex)->GetValue(
715 (scaledKineticEnergy-Thighr)/
716 (*dEdxTable)(materialIndex)->GetValue(
721 Range = (*rangeTable)(materialIndex)->GetValue(
722 scaledKineticEnergy,isOut) ;
726 return Range/(Chargesquare*t.theMassRatio);
737 if(aParticle != lastParticle)
739 t= GetTables(aParticle);
740 lastParticle = aParticle ;
750 else ParticleHaveNoLoss(aParticle,
"dEdx");
755 G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
759 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
761 dEdx =(*dEdxTable)(materialIndex)->GetValue(
762 t.theLowestKineticEnergy,isOut)
763 *std::sqrt(scaledKineticEnergy/t.theLowestKineticEnergy);
765 }
else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
767 dEdx = (*dEdxTable)(materialIndex)->GetValue(
768 t.theHighestKineticEnergy,isOut);
772 dEdx = (*dEdxTable)(materialIndex)->GetValue(
773 scaledKineticEnergy,isOut);
777 return dEdx*Chargesquare;
788 if(aParticle != lastParticle)
790 t= GetTables(aParticle);
791 lastParticle = aParticle ;
806 G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
810 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
812 Range = std::sqrt(scaledKineticEnergy/t.theLowestKineticEnergy)*
813 (*rangeTable)(materialIndex)->GetValue(
814 t.theLowestKineticEnergy,isOut);
816 }
else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
818 Range = (*rangeTable)(materialIndex)->GetValue(
819 t.theHighestKineticEnergy,isOut)+
820 (scaledKineticEnergy-t.theHighestKineticEnergy)/
821 (*dEdxTable)(materialIndex)->GetValue(
822 t.theHighestKineticEnergy,isOut);
826 Range = (*rangeTable)(materialIndex)->GetValue(
827 scaledKineticEnergy,isOut);
831 return Range/(Chargesquare*t.theMassRatio);
843 if( aParticle != lastParticle)
845 t= GetTables(aParticle);
846 lastParticle = aParticle;
855 if (!inverseRangeTable) {
861 G4double scaledrange,scaledKineticEnergy ;
866 if(materialIndex != oldIndex)
868 oldIndex = materialIndex ;
869 rmin = (*inverseRangeTable)(materialIndex)->
870 GetLowEdgeEnergy(0) ;
871 rmax = (*inverseRangeTable)(materialIndex)->
872 GetLowEdgeEnergy(t.theNumberOfBins-2) ;
873 Thigh = (*inverseRangeTable)(materialIndex)->
874 GetValue(rmax,isOut) ;
877 scaledrange = range*Chargesquare*t.theMassRatio ;
879 if(scaledrange < rmin)
881 scaledKineticEnergy = t.theLowestKineticEnergy*
882 scaledrange*scaledrange/(rmin*rmin) ;
886 if(scaledrange < rmax)
888 scaledKineticEnergy = (*inverseRangeTable)(materialIndex)->
889 GetValue( scaledrange,isOut) ;
893 scaledKineticEnergy = Thigh +
895 (*dEdxTable)(materialIndex)->
896 GetValue(Thigh,isOut) ;
900 return scaledKineticEnergy/t.theMassRatio ;
911 if( aParticle != lastParticle)
913 t= GetTables(aParticle);
914 lastParticle = aParticle;
925 G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
929 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
931 dEdx = std::sqrt(scaledKineticEnergy/t.theLowestKineticEnergy)
932 *(*dEdxTable)(materialIndex)->GetValue(
933 t.theLowestKineticEnergy,isOut);
935 }
else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
937 dEdx = (*dEdxTable)(materialIndex)->GetValue(
938 t.theHighestKineticEnergy,isOut);
942 dEdx = (*dEdxTable)(materialIndex)->GetValue(
943 scaledKineticEnergy,isOut) ;
947 return dEdx*Chargesquare;
957 if( aParticle != lastParticle)
959 t= GetTables(aParticle);
960 lastParticle = aParticle;
968 if ( !dEdxTable || !rangeTable)
973 G4double Thighr = t.theHighestKineticEnergy*t.theLowestKineticEnergy/
974 (*rangeTable)(materialIndex)->
975 GetLowEdgeEnergy(1) ;
977 G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
981 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
983 Range = std::sqrt(scaledKineticEnergy/t.theLowestKineticEnergy)*
984 (*rangeTable)(materialIndex)->GetValue(
985 t.theLowestKineticEnergy,isOut);
987 }
else if (scaledKineticEnergy>Thighr) {
989 Range = (*rangeTable)(materialIndex)->GetValue(
991 (scaledKineticEnergy-Thighr)/
992 (*dEdxTable)(materialIndex)->GetValue(
997 Range = (*rangeTable)(materialIndex)->GetValue(
998 scaledKineticEnergy,isOut) ;
1002 return Range/(Chargesquare*t.theMassRatio);
1007void G4EnergyLossTables::CPRWarning()
1009 if (let_counter < let_max_num_warnings) {
1012 G4cout <<
"##### G4EnergyLossTable WARNING: The obsolete interface is used!" <<
G4endl;
1013 G4cout <<
"##### RESULTS ARE NOT GARANTEED!" <<
G4endl;
1014 G4cout <<
"##### Please, substitute G4Material by G4MaterialCutsCouple" <<
G4endl;
1015 G4cout <<
"##### Obsolete interface will be removed soon" <<
G4endl;
1023 }
else if (let_counter == let_max_num_warnings) {
1025 G4cout <<
"##### G4EnergyLossTable WARNING closed" <<
G4endl;
G4DLLIMPORT std::ostream G4cout
G4EnergyLossTablesHelper()
static G4double GetRange(const G4ParticleDefinition *aParticle, G4double KineticEnergy, const G4Material *aMaterial)
static const G4PhysicsTable * GetLabTimeTable(const G4ParticleDefinition *p)
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 G4double GetDEDX(const G4ParticleDefinition *aParticle, G4double KineticEnergy, const G4Material *aMaterial)
static G4double GetDeltaProperTime(const G4ParticleDefinition *aParticle, G4double KineticEnergyStart, G4double KineticEnergyEnd, const G4Material *aMaterial)
static G4double GetLabTime(const G4ParticleDefinition *aParticle, G4double KineticEnergy, const G4Material *aMaterial)
static G4double GetPreciseDEDX(const G4ParticleDefinition *aParticle, G4double KineticEnergy, const G4Material *aMaterial)
static G4double GetPreciseEnergyFromRange(const G4ParticleDefinition *aParticle, G4double range, const G4Material *aMaterial)
static const G4PhysicsTable * GetDEDXTable(const G4ParticleDefinition *p)
static const G4PhysicsTable * GetRangeTable(const G4ParticleDefinition *p)
static const G4PhysicsTable * GetInverseRangeTable(const G4ParticleDefinition *p)
static G4double GetDeltaLabTime(const G4ParticleDefinition *aParticle, G4double KineticEnergyStart, G4double KineticEnergyEnd, const G4Material *aMaterial)
static G4double GetPreciseRangeFromEnergy(const G4ParticleDefinition *aParticle, G4double KineticEnergy, const G4Material *aMaterial)
static G4double GetProperTime(const G4ParticleDefinition *aParticle, G4double KineticEnergy, const G4Material *aMaterial)
static const G4PhysicsTable * GetProperTimeTable(const G4ParticleDefinition *p)
static G4LossTableManager * Instance()
G4double GetEnergy(const G4ParticleDefinition *aParticle, G4double range, const G4MaterialCutsCouple *couple)
G4double GetRange(const G4ParticleDefinition *aParticle, G4double kineticEnergy, const G4MaterialCutsCouple *couple)
G4double GetDEDX(const G4ParticleDefinition *aParticle, G4double kineticEnergy, const G4MaterialCutsCouple *couple)
G4double GetPDGCharge() const