14#include "GaudiKernel/MsgStream.h"
15#include "GaudiKernel/ServiceHandle.h"
17#include "CLHEP/Units/SystemOfUnits.h"
20#include "CLHEP/Random/RandomEngine.h"
21#include "CLHEP/Random/RandFlat.h"
34 const std::string& name,
35 const IInterface* parent )
36 : base_class(
type, name, parent )
40 declareProperty(
"GasType",
m_gasType,
"Gas Type" );
59 std::string gasType =
"NotSet";
77 <<
"'. Must be one of 'Auto', 'Xenon', 'Argon' or 'Krypton'." );
78 return StatusCode::FAILURE;
81 ATH_MSG_INFO ( name() <<
" will use gas type = " << gasType );
89 const double tempK = 289.;
92 using element_type = std::map<std::string, TRT_PAI_element, std::less<std::string>>;
94 element_type elements;
104 for (element_type::iterator ei=elements.begin(); ei!=elements.end(); ++ei) {
106 <<
", A= " << (*ei).second.getAtomicA()
107 <<
", Z= " << (*ei).second.getAtomicZ()
108 <<
", rho=" << (*ei).second.getDensity(tempK)
109 <<
" (" << tempK <<
" Kelvin)"
116 using component_type = std::map<std::string, TRT_PAI_gasComponent, std::less<std::string>>;
118 component_type components;
121 components[
"Xe"].addElement(&elements[
"Xe"],1);
124 components[
"CO2"].addElement(&elements[
"C"],1);
125 components[
"CO2"].addElement(&elements[
"O"],2);
128 components[
"CF4"].addElement(&elements[
"C"],1);
129 components[
"CF4"].addElement(&elements[
"F"],4);
132 components[
"O2"].addElement(&elements[
"O"],2);
135 components[
"Ar"].addElement(&elements[
"Ar"],1);
138 components[
"Kr"].addElement(&elements[
"Kr"],1);
143 std::vector<std::string> cnam(6);
144 cnam[0] =
"Xe"; cnam[1] =
"CO2"; cnam[2] =
"CF4"; cnam[3] =
"CO2"; cnam[4] =
"Ar"; cnam[5] =
"Kr";
147 for (
int ic=0; ic<6; ++ic ) {
148 n = components[cnam[ic]].getNElementTypes();
149 ATH_MSG_DEBUG (
". Gas component " << components[cnam[ic]].getName() <<
" contains");
150 for (
int ie=0; ie<n; ++ie ) {
151 ATH_MSG_DEBUG (
" - " << components[cnam[ic]].getElementMultiplicity(ie)
152 <<
" atoms " << (components[cnam[ic]].getElement(ie))->getName()
153 <<
" with Z= " << (components[cnam[ic]].getElement(ie))->getAtomicZ()
154 <<
" and A= " << (components[cnam[ic]].getElement(ie))->getAtomicA()
157 ATH_MSG_DEBUG (
" > density: " << components[cnam[ic]].getDensity(tempK) <<
" (" << tempK <<
" Kelvin)" );
162 std::string mixtureName=
"TRT Gas Mixture";
163 mixtureName.insert(4, gasType);
166 if ( gasType ==
"Xenon" ) {
167 ATH_MSG_DEBUG (
"Using new Xenon gas mixture (Xe/CO2/O2 - 70/27/3)." );
168 m_trtgas->addComponent( &components[
"Xe"] , 0.70);
169 m_trtgas->addComponent( &components[
"CO2"], 0.27);
170 m_trtgas->addComponent( &components[
"O2"] , 0.03);
173 if (( gasType ==
"XenonOld" )){
174 ATH_MSG_DEBUG (
"Using old Xenon gas mixture (Xe/CO2/CF4 - 70/10/20)." );
175 m_trtgas->addComponent( &components[
"Xe"] , 0.70);
176 m_trtgas->addComponent( &components[
"CO2"], 0.10);
177 m_trtgas->addComponent( &components[
"CF4"], 0.20);
180 if ( gasType ==
"Argon" ) {
181 ATH_MSG_DEBUG (
"Using Argon gas mixture (Ar/CO2/O2 - 70/27/3)." );
182 m_trtgas->addComponent( &components[
"Ar"] , 0.70);
183 m_trtgas->addComponent( &components[
"CO2"], 0.27);
184 m_trtgas->addComponent( &components[
"O2"] , 0.03);
187 if ( gasType ==
"Krypton" ) {
188 ATH_MSG_DEBUG (
"Using Krypton gas mixture (Kr/CO2/O2 - 70/27/3)." );
189 m_trtgas->addComponent( &components[
"Kr"] , 0.70);
190 m_trtgas->addComponent( &components[
"CO2"], 0.27);
191 m_trtgas->addComponent( &components[
"O2"] , 0.03);
203 const double Emin = 12.0;
204 const double Emax = 1e+07;
207 const double eps = 0.01;
213 ATH_MSG_DEBUG (
"Making tables for various gamma factors." );
216 std::vector<float> lnE;
221 gamvec[ig] = 1. +
pow(10.,gamvar);
230 return StatusCode::SUCCESS;
236 return StatusCode::SUCCESS;
248 double squaredCharge)
const {
250 if ( squaredCharge == 0. )
return 99999.0 * CLHEP::km;
253 unsigned int index = 0;
254 if ( gv > 0 )
index =
static_cast<unsigned int >(gv);
257 if ( gv < 0 ) d =
m_dndx[0];
260 double remain = gv-
index;
264 double freepath = 1./(d*squaredCharge);
267 ATH_MSG_VERBOSE (
"Mean free path for scaledKineticEnergy = " << scaledKineticEnergy
268 <<
" is " << freepath/CLHEP::mm <<
" mm " );
274 return freepath * CLHEP::cm;
281 unsigned int tabIndx = 0;
283 if ( gv>0 ) tabIndx =
static_cast<unsigned int>( gv );
289 double random = CLHEP::RandFlat::shoot(rndmEngine, 0., 1.);
301 Etransf = exp(Etransf);
305 << scaledKineticEnergy <<
" is " << Etransf <<
" eV"
309 return Etransf * CLHEP::eV;
#define ATH_MSG_VERBOSE(x)
constexpr int pow(int base, int exp) noexcept
const double m_deltaGamExp
TRT_PAI_gasMixture * m_trtgas
TRT_PAI_Process(const std::string &type, const std::string &name, const IInterface *parent)
Not much action.
virtual StatusCode finalize() override final
double ScaledEkin2GamVarTab(double scaledKineticEnergy) const
Converting Lorentz gamma to table index (well, double)
virtual double GetEnergyTransfer(double scaledKineticEnergy, CLHEP::HepRandomEngine *rndmEngine) const override final
Get the energy transferred from the charged particle to the gas (CLHEP units).
std::vector< float > m_dndx
std::vector< std::vector< float > > m_fn_array
virtual StatusCode initialize() override final
Initialization of the PAI model:
virtual double GetMeanFreePath(double scaledKineticEnergy, double squaredCharge) const override final
Get the mean free path in gas (CLHEP units)
std::vector< float > m_en_array
const unsigned int m_nTabulatedGammaValues
Effective gas: All quantities necessary to calculate PAI ionisation for gas mixture.
void GasTab(const std::vector< float > &gamvec, std::vector< float > &EArray, std::vector< std::vector< float > > &fnArray, std::vector< float > &dndx)
Tabulate double differential distribution.
Gas mixture = mixture of gas components.
Input data to PAI process:
const float EF[NF]
Energy levels for Fluor.
const float EO[NO]
Energy levels for Oxygen.
const float SO[NO]
Cross sections for Oxygen.
const float EAr[NAr]
Energy levels for Argon.
const float EXe[NXe]
Energy levels for Xenon.
const float EKr[NKr]
Energy levels for Krypton.
const int NC
Number of levels for Carbon.
const float SC[NC]
Cross sections for Carbon.
const int NAr
Number of levels for Argon.
const int NKr
Number of levels for Krypton.
const float SKr[NKr]
Cross sections for Krypton.
const float EC[NC]
Energy levels for Carbon.
const int NF
Number of levels for Fluor.
const float SF[NF]
Cross sections for Fluor.
const float SAr[NAr]
Cross sections for Argon.
const int ZXe
Atommic Z for elements.
const float AXe
Atommic A for elements.
const float SXe[NXe]
Cross sections for Xenon.
const int NO
Number of levels for Oxygen.
const int NXe
Number of levels for Xenon.
const double MProtonMeV
Proton mass in MeV.
const double invlog10
you guess...
float Interpolate(const float &xval, const std::vector< float > &xtabulated, const std::vector< float > &ytabulated)
Interpolation function.