ATLAS Offline Software
Loading...
Searching...
No Matches
TRT_PAI_Process Class Referencefinal

The Photon Absorption Ionisation model used for the ionisation in the TRT. More...

#include <TRT_PAI_Process.h>

Inheritance diagram for TRT_PAI_Process:
Collaboration diagram for TRT_PAI_Process:

Public Member Functions

 TRT_PAI_Process (const std::string &type, const std::string &name, const IInterface *parent)
 Not much action.
virtual StatusCode initialize () override final
 Initialization of the PAI model:
virtual StatusCode finalize () override final
virtual double GetMeanFreePath (double scaledKineticEnergy, double squaredCharge) const override final
 Get the mean free path in gas (CLHEP units)
virtual double GetEnergyTransfer (double scaledKineticEnergy, CLHEP::HepRandomEngine *rndmEngine) const override final
 Get the energy transferred from the charged particle to the gas (CLHEP units).

Private Member Functions

double ScaledEkin2GamVarTab (double scaledKineticEnergy) const
 Converting Lorentz gamma to table index (well, double)

Private Attributes

const unsigned int m_nTabulatedGammaValues {56}
const double m_gamExpMin {-2.}
const double m_gamExpMax {5.}
const double m_deltaGamExp {}
std::vector< float > m_en_array
std::vector< std::vector< float > > m_fn_array
std::vector< float > m_dndx
TRT_PAI_gasMixturem_trtgas {}
std::string m_gasType {"Auto"}

Detailed Description

The Photon Absorption Ionisation model used for the ionisation in the TRT.

The main reference for this implementation is

  • V.M.Grishin, V.K.Ermilova, and S.K.Kotelnikov, NIM A307 (1991) 273-278.

Other references to the PAI model are

  • V.C.Ermilova, L.P.Kotenko, and G.I.Merzon, NIM145 (1977) 555-563.
  • J.H.Cobb, W.W.M.Allison, and J.N.Bunch, NIM133 (1976) 315-323.
  • W.W.M.Allison and J.H.Cobb, Ann.Rev.Nucl.Part.Sci (1980), 253-98.
Note
Internally this class uses the original units of the fortran version. To external world sees CLHEP units.
Author
Originally implemented in age FORTRAN by Pavel Nevski. Adapted to C++ by T.Kittelmann/Mogens Dam.

Definition at line 42 of file TRT_PAI_Process.h.

Constructor & Destructor Documentation

◆ TRT_PAI_Process()

TRT_PAI_Process::TRT_PAI_Process ( const std::string & type,
const std::string & name,
const IInterface * parent )

Not much action.

Initializes a few variables

Definition at line 33 of file TRT_PAI_Process.cxx.

36 : base_class( type, name, parent )
38{
39 //Properties:
40 declareProperty( "GasType", m_gasType, "Gas Type" );
41}
const double m_deltaGamExp
std::string m_gasType
const double m_gamExpMax
const unsigned int m_nTabulatedGammaValues
const double m_gamExpMin

Member Function Documentation

◆ finalize()

StatusCode TRT_PAI_Process::finalize ( )
finaloverridevirtual

Definition at line 234 of file TRT_PAI_Process.cxx.

234 {
235 delete m_trtgas;
236 return StatusCode::SUCCESS;
237}
TRT_PAI_gasMixture * m_trtgas

◆ GetEnergyTransfer()

double TRT_PAI_Process::GetEnergyTransfer ( double scaledKineticEnergy,
CLHEP::HepRandomEngine * rndmEngine ) const
finaloverridevirtual

Get the energy transferred from the charged particle to the gas (CLHEP units).

The energy transfer is randomly generated according to the distributions calculated based on the input data in gasdata.h

Parameters
scaledKineticEnergyThe kinetic energy a proton would have had, if it had same Lorentz gamma factor as the particle in question.
Returns
Random energy transfer consistent with PAI model calculation.

Definition at line 278 of file TRT_PAI_Process.cxx.

278 {
279
280 double gv = ScaledEkin2GamVarTab( scaledKineticEnergy );
281 unsigned int tabIndx = 0;
282
283 if ( gv>0 ) tabIndx = static_cast<unsigned int>( gv );
284
285 tabIndx = std::min( tabIndx, m_nTabulatedGammaValues-1 );
286
287 // Generate a random number uniformly in [0,1].
288 // CLHEP::HepRandomEngine* pHRengine = m_pAtRndmGenSvc->GetEngine("TRT_PAI");
289 double random = CLHEP::RandFlat::shoot(rndmEngine, 0., 1.);
290
291 // What we are doing next is actually to select a value of E from
292 // dN^2/dXdE considered as a function of E using the standard Monte
293 // Carlo method. The total area under the function is equal to
294 // dN/dX, and since we can not calculate the inverse antiderivative,
295 // we have tabulated the antiderivative in (m_en_array, m_fn_array)
296 // and taking the inverse is as simple as switching the roles of the
297 // two arrays.
298
299 double Etransf = TRT_PAI_utils::Interpolate (random * m_dndx[tabIndx], m_fn_array[tabIndx], m_en_array ) ;
300
301 Etransf = exp(Etransf);
302
303#ifndef NDEBUG
304 ATH_MSG_VERBOSE ( "Energy transfer for scaledKineticEnergy = "
305 << scaledKineticEnergy << " is " << Etransf << " eV"
306 );
307#endif
308
309 return Etransf * CLHEP::eV;
310}
#define ATH_MSG_VERBOSE(x)
double ScaledEkin2GamVarTab(double scaledKineticEnergy) const
Converting Lorentz gamma to table index (well, double)
std::vector< float > m_dndx
std::vector< std::vector< float > > m_fn_array
std::vector< float > m_en_array
float Interpolate(const float &xval, const std::vector< float > &xtabulated, const std::vector< float > &ytabulated)
Interpolation function.

◆ GetMeanFreePath()

double TRT_PAI_Process::GetMeanFreePath ( double scaledKineticEnergy,
double squaredCharge ) const
finaloverridevirtual

Get the mean free path in gas (CLHEP units)

Parameters
scaledKineticEnergyThe kinetic energy a proton would have had, if it had same Lorentz gamma factor as the particle in question
squaredChargeCharge squared
Returns
Mean free path

Definition at line 247 of file TRT_PAI_Process.cxx.

248 {
249
250 if ( squaredCharge == 0. ) return 99999.0 * CLHEP::km;
251
252 double gv = ScaledEkin2GamVarTab( scaledKineticEnergy );
253 unsigned int index = 0;
254 if ( gv > 0 ) index = static_cast<unsigned int >(gv);
255
256 double d;
257 if ( gv < 0 ) d = m_dndx[0];
258 else if ( index >= m_nTabulatedGammaValues-1 ) d = m_dndx[m_nTabulatedGammaValues-1];
259 else {
260 double remain = gv-index;
261 d = (1.-remain)*m_dndx[index] + remain*m_dndx[index+1];
262 }
263
264 double freepath = 1./(d*squaredCharge);
265
266#ifndef NDEBUG
267 ATH_MSG_VERBOSE ( "Mean free path for scaledKineticEnergy = " << scaledKineticEnergy
268 << " is " << freepath/CLHEP::mm << " mm " );
269#endif
270
271 // All internal calculations are performed without initialization with
272 // CLHEP units, so we put it here instead
273
274 return freepath * CLHEP::cm;
275}
str index
Definition DeMoScan.py:362

◆ initialize()

StatusCode TRT_PAI_Process::initialize ( )
finaloverridevirtual

Initialization of the PAI model:

  1. Construct chemical elements;
  2. Construct gas components (molecules) from elements;
  3. Construct gas mixture from gas components;
  4. Construct "effective gas" from the gas mixture, i.e. calculate everything necessary for the current gas mixture to do the PAI simulation

Definition at line 43 of file TRT_PAI_Process.cxx.

43 {
44
45 using namespace TRT_PAI_gasdata;
46 using namespace TRT_PAI_physicsConstants;
47
48 ATH_MSG_VERBOSE ( "TRT_PAI_Process::initialize()" );
49
50 // Supported gasType's are 70%/27%/03%:
51 // 1) "Xenon" - Xe/CO2/O2
52 // 2) "Argon" - Ar/CO2/O2
53 // 3) "Kryton" - Kr/CO2/O2
54 //
55 // Figure out which type of gas we are having:
56
57 ATH_MSG_DEBUG ( "Gastype read as " << m_gasType );
58
59 std::string gasType = "NotSet";
60 // Here m_gasType="Auto" was previously used to prompt a
61 // check of InDetDD::TRT_DetectorManager for whether we want
62 // the old Xenon mix: Xe/CO2/CF4 or the new one: Xe/CO2/O2
63 // Nowadays, it is always the new one, so we don't check this anymore.
64
65 if ( m_gasType == "Auto" )
66 {
67 gasType = "Xenon";
68 }
69 else if ( m_gasType == "Xenon" || m_gasType == "Argon" || m_gasType == "Krypton" )
70 {
71 ATH_MSG_DEBUG ( "Gastype is overriden from joboptions to be " << m_gasType );
72 gasType = m_gasType;
73 }
74 else
75 {
76 ATH_MSG_FATAL ( "GasType property set to '" << m_gasType
77 << "'. Must be one of 'Auto', 'Xenon', 'Argon' or 'Krypton'." );
78 return StatusCode::FAILURE;
79 };
80
81 ATH_MSG_INFO ( name() << " will use gas type = " << gasType );
82
83 // Done with "trivial" initialization.
84 // Finally we can start to construct gas
85
86 ATH_MSG_VERBOSE ( "Constructing gas mixture." );
87
88 // Need the gas temperature
89 const double tempK = 289.; // At 289. degrees, we get same densities as Nevski had
90
91 // Define elements
92 using element_type = std::map<std::string, TRT_PAI_element, std::less<std::string>>;
93
94 element_type elements;
95 elements["Xe"] = TRT_PAI_element( "Xe", EXe , SXe , NXe , ZXe, AXe);
96 elements["C"] = TRT_PAI_element( "C" , EC , SC , NC , ZC , AC );
97 elements["F"] = TRT_PAI_element( "F" , EF , SF , NF , ZF , AF );
98 elements["O"] = TRT_PAI_element( "O" , EO , SO , NO , ZO , AO );
99 elements["Ar"] = TRT_PAI_element( "Ar", EAr , SAr , NAr , ZAr, AAr);
100 elements["Kr"] = TRT_PAI_element( "Kr", EKr , SKr , NKr , ZKr, AKr);
101
102 // Print out elements
103 {
104 for (element_type::iterator ei=elements.begin(); ei!=elements.end(); ++ei) {
105 ATH_MSG_DEBUG ( ". Element " << (*ei).second.getName()
106 << ", A= " << (*ei).second.getAtomicA()
107 << ", Z= " << (*ei).second.getAtomicZ()
108 << ", rho=" << (*ei).second.getDensity(tempK)
109 << " (" << tempK << " Kelvin)"
110 );
111 }
112 }
113
114 // Define gas components
115
116 using component_type = std::map<std::string, TRT_PAI_gasComponent, std::less<std::string>>;
117
118 component_type components;
119
120 components["Xe"] = TRT_PAI_gasComponent("Xe");
121 components["Xe"].addElement(&elements["Xe"],1);
122
123 components["CO2"] = TRT_PAI_gasComponent("CO2");
124 components["CO2"].addElement(&elements["C"],1);
125 components["CO2"].addElement(&elements["O"],2);
126
127 components["CF4"] = TRT_PAI_gasComponent("CF4");
128 components["CF4"].addElement(&elements["C"],1);
129 components["CF4"].addElement(&elements["F"],4);
130
131 components["O2"] = TRT_PAI_gasComponent("O2");
132 components["O2"].addElement(&elements["O"],2);
133
134 components["Ar"] = TRT_PAI_gasComponent("Ar");
135 components["Ar"].addElement(&elements["Ar"],1);
136
137 components["Kr"] = TRT_PAI_gasComponent("Kr");
138 components["Kr"].addElement(&elements["Kr"],1);
139
140 // Print out gas components
141
142 {
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";
145
146 int n;
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()
155 );
156 }
157 ATH_MSG_DEBUG ( " > density: " << components[cnam[ic]].getDensity(tempK) << " (" << tempK << " Kelvin)" );
158 }
159 }
160
161 // Construct TRT gas mixture
162 std::string mixtureName="TRT Gas Mixture";
163 mixtureName.insert(4, gasType);
164 m_trtgas = new TRT_PAI_gasMixture(mixtureName);
165
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);
171 }
172
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);
178 }
179
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);
185 }
186
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);
192 }
193
194 m_trtgas->freezeGas();
195
196 m_trtgas->showStructure();
197
198 // Create and initialize effective gas
199 // Sasha: to check: does Emin depends from Energy levels of active gas?
200 // for Xenon lowest energetic level is 12.08 eV
201 // for Argon - 15.83 eV. Does Emin should be different for Argon???
202
203 const double Emin = 12.0; // [eV]
204 const double Emax = 1e+07; // [eV]
205 // Don't change Emax from 10 MeV without
206 // talking to Pavel Nevski!
207 const double eps = 0.01; // Epsilon for numeric integration
208
209 TRT_PAI_effectiveGas effectiveGas(m_trtgas, Emin, Emax, tempK, eps);
210
211 // Now tabulate...
212
213 ATH_MSG_DEBUG ( "Making tables for various gamma factors." );
214
215 std::vector<float> gamvec(m_nTabulatedGammaValues);
216 std::vector<float> lnE;
217
218 double gamvar = m_gamExpMin - 0.5*m_deltaGamExp;
219 for ( unsigned int ig = 0; ig < m_nTabulatedGammaValues; ++ig ) {
220 gamvar += m_deltaGamExp;
221 gamvec[ig] = 1. + pow(10.,gamvar);
222 }
223
224 // Here is the real action!
225
226 effectiveGas.GasTab(gamvec, m_en_array, m_fn_array, m_dndx );
227
228 ATH_MSG_DEBUG ( "Initialization completed." );
229
230 return StatusCode::SUCCESS;
231}
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
constexpr int pow(int base, int exp) noexcept
int ic
Definition grepfile.py:33

◆ ScaledEkin2GamVarTab()

double TRT_PAI_Process::ScaledEkin2GamVarTab ( double scaledKineticEnergy) const
inlineprivate

Converting Lorentz gamma to table index (well, double)

Definition at line 240 of file TRT_PAI_Process.cxx.

241 {
242 using namespace TRT_PAI_physicsConstants;
243 return (log(scaledKineticEnergy/MProtonMeV)*invlog10 - m_gamExpMin)/m_deltaGamExp;
244}

Member Data Documentation

◆ m_deltaGamExp

const double TRT_PAI_Process::m_deltaGamExp {}
private

Definition at line 92 of file TRT_PAI_Process.h.

92{};

◆ m_dndx

std::vector<float> TRT_PAI_Process::m_dndx
private

Definition at line 97 of file TRT_PAI_Process.h.

◆ m_en_array

std::vector<float> TRT_PAI_Process::m_en_array
private

Definition at line 95 of file TRT_PAI_Process.h.

◆ m_fn_array

std::vector< std::vector<float> > TRT_PAI_Process::m_fn_array
private

Definition at line 96 of file TRT_PAI_Process.h.

◆ m_gamExpMax

const double TRT_PAI_Process::m_gamExpMax {5.}
private

Definition at line 91 of file TRT_PAI_Process.h.

91{5.}; // Max Lorentz gamma: 1+10^(m_gamExpMax)

◆ m_gamExpMin

const double TRT_PAI_Process::m_gamExpMin {-2.}
private

Definition at line 90 of file TRT_PAI_Process.h.

90{-2.}; // Min Lorentz gamma: 1+10^(m_gamExpMin)

◆ m_gasType

std::string TRT_PAI_Process::m_gasType {"Auto"}
private

Definition at line 106 of file TRT_PAI_Process.h.

106{"Auto"};

◆ m_nTabulatedGammaValues

const unsigned int TRT_PAI_Process::m_nTabulatedGammaValues {56}
private

Definition at line 89 of file TRT_PAI_Process.h.

89{56};

◆ m_trtgas

TRT_PAI_gasMixture* TRT_PAI_Process::m_trtgas {}
private

Definition at line 98 of file TRT_PAI_Process.h.

98{};

The documentation for this class was generated from the following files: