ATLAS Offline Software
TRT_PAI_Process.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "TRT_PAI_Process.h"
6 #include "TRT_PAI_gasdata.h"
7 #include "TRT_PAI_element.h"
8 #include "TRT_PAI_gasComponent.h"
9 #include "TRT_PAI_gasMixture.h"
10 #include "TRT_PAI_effectiveGas.h"
12 #include "TRT_PAI_utils.h"
13 
14 #include "GaudiKernel/MsgStream.h"
15 #include "GaudiKernel/ServiceHandle.h"
16 
17 #include "CLHEP/Units/SystemOfUnits.h"
18 
19 // For Athena-based random numbers
20 #include "CLHEP/Random/RandomEngine.h"
21 #include "CLHEP/Random/RandFlat.h"
22 
23 // To get TRT dig. settings:
25 
26 #include <vector>
27 #include <map>
28 #include <cmath>
29 #include <iostream>
30 
31 //__________________________________________________________________________
32 
34  const std::string& name,
35  const IInterface* parent )
36  : base_class( type, name, parent )
37  , m_deltaGamExp( (m_gamExpMax-m_gamExpMin)/m_nTabulatedGammaValues )
38 {
39  //Properties:
40  declareProperty( "GasType", m_gasType, "Gas Type" );
41 }
42 //__________________________________________________________________________
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 
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 }
232 
233 //__________________________________________________________________________
235  delete m_trtgas;
236  return StatusCode::SUCCESS;
237 }
238 
239 //__________________________________________________________________________
240 inline double TRT_PAI_Process::ScaledEkin2GamVarTab(double scaledKineticEnergy)
241  const {
242  using namespace TRT_PAI_physicsConstants;
243  return (log(scaledKineticEnergy/MProtonMeV)*invlog10 - m_gamExpMin)/m_deltaGamExp;
244 }
245 
246 //__________________________________________________________________________
247 double TRT_PAI_Process::GetMeanFreePath(double scaledKineticEnergy,
248  double squaredCharge) const {
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];
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 }
276 
277 //__________________________________________________________________________
278 double TRT_PAI_Process::GetEnergyTransfer(double scaledKineticEnergy, CLHEP::HepRandomEngine* rndmEngine) const {
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 }
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
TRT_PAI_Process::m_en_array
std::vector< float > m_en_array
Definition: TRT_PAI_Process.h:95
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
TRT_PAI_gasdata::SO
const float SO[NO]
Cross sections for Oxygen.
Definition: TRT_PAI_gasdata.h:315
TRT_PAI_gasMixture
Gas mixture = mixture of gas components.
Definition: TRT_PAI_gasMixture.h:18
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
TRT_PAI_gasdata::EAr
const float EAr[NAr]
Energy levels for Argon.
Definition: TRT_PAI_gasdata.h:175
TRT_PAI_gasdata::AKr
const float AKr
Definition: TRT_PAI_gasdata.h:27
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
TRT_DetectorManager.h
TRT_PAI_physicsConstants::invlog10
const double invlog10
you guess...
Definition: TRT_PAI_physicsConstants.h:23
index
Definition: index.py:1
TRT_PAI_gasdata::EO
const float EO[NO]
Energy levels for Oxygen.
Definition: TRT_PAI_gasdata.h:301
TRT_PAI_gasdata::AO
const float AO
Definition: TRT_PAI_gasdata.h:27
hist_file_dump.d
d
Definition: hist_file_dump.py:137
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
TRT_PAI_gasdata::AXe
const float AXe
Atommic A for elements.
Definition: TRT_PAI_gasdata.h:27
TRT_PAI_gasdata.h
TRT_PAI_Process::m_trtgas
TRT_PAI_gasMixture * m_trtgas
Definition: TRT_PAI_Process.h:98
TRT_PAI_gasdata::SF
const float SF[NF]
Cross sections for Fluor.
Definition: TRT_PAI_gasdata.h:285
TRT_PAI_gasdata::AC
const float AC
Definition: TRT_PAI_gasdata.h:27
TRT_PAI_gasdata::NC
const int NC
Number of levels for Carbon.
Definition: TRT_PAI_gasdata.h:237
TRT_PAI_Process::ScaledEkin2GamVarTab
double ScaledEkin2GamVarTab(double scaledKineticEnergy) const
Converting Lorentz gamma to table index (well, double)
Definition: TRT_PAI_Process.cxx:240
TRT_PAI_gasdata
Input data to PAI process:
Definition: TRT_PAI_gasdata.h:17
TRT_PAI_gasdata::NAr
const int NAr
Number of levels for Argon.
Definition: TRT_PAI_gasdata.h:171
TRT_PAI_gasdata::EF
const float EF[NF]
Energy levels for Fluor.
Definition: TRT_PAI_gasdata.h:271
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
TRT_PAI_effectiveGas::GasTab
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.
Definition: TRT_PAI_effectiveGas.cxx:262
TRT_PAI_gasdata::AF
const float AF
Definition: TRT_PAI_gasdata.h:27
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
TRT_PAI_gasdata::SAr
const float SAr[NAr]
Cross sections for Argon.
Definition: TRT_PAI_gasdata.h:207
TRT_PAI_gasdata::NF
const int NF
Number of levels for Fluor.
Definition: TRT_PAI_gasdata.h:267
dumpTruth.getName
getName
Definition: dumpTruth.py:34
TRT_PAI_Process::m_gamExpMin
const double m_gamExpMin
Definition: TRT_PAI_Process.h:90
TRT_PAI_gasdata::ZXe
const int ZXe
Atommic Z for elements.
Definition: TRT_PAI_gasdata.h:22
PlotCalibFromCool.ie
ie
Definition: PlotCalibFromCool.py:420
TRT_PAI_gasdata::SXe
const float SXe[NXe]
Cross sections for Xenon.
Definition: TRT_PAI_gasdata.h:56
TRT_PAI_Process::m_nTabulatedGammaValues
const unsigned int m_nTabulatedGammaValues
Definition: TRT_PAI_Process.h:89
cm
const double cm
Definition: Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/tools/FCAL_ChannelMap.cxx:25
TRT_PAI_gasMixture::freezeGas
void freezeGas()
Components can be added to gas mixture before freezeGas is called.
Definition: TRT_PAI_gasMixture.cxx:35
TRT_PAI_gasMixture::addComponent
void addComponent(TRT_PAI_gasComponent *pgc, double frac)
Add gas component to gas mixture.
Definition: TRT_PAI_gasMixture.cxx:21
TRT_PAI_gasdata::EKr
const float EKr[NKr]
Energy levels for Krypton.
Definition: TRT_PAI_gasdata.h:83
TRT_PAI_gasdata::NO
const int NO
Number of levels for Oxygen.
Definition: TRT_PAI_gasdata.h:297
TRT_PAI_physicsConstants
Physics constants.
Definition: TRT_PAI_physicsConstants.h:11
TRT_PAI_gasdata::NXe
const int NXe
Number of levels for Xenon.
Definition: TRT_PAI_gasdata.h:29
GlobalVariables.Emin
Emin
Definition: GlobalVariables.py:184
TRT_PAI_Process::finalize
virtual StatusCode finalize() override final
Definition: TRT_PAI_Process.cxx:234
beamspotman.n
n
Definition: beamspotman.py:731
TRT_PAI_physicsConstants.h
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TRT_PAI_gasComponent.h
TRT_PAI_gasdata::NKr
const int NKr
Number of levels for Krypton.
Definition: TRT_PAI_gasdata.h:79
test_pyathena.parent
parent
Definition: test_pyathena.py:15
TRT_PAI_gasdata::SC
const float SC[NC]
Cross sections for Carbon.
Definition: TRT_PAI_gasdata.h:255
TRT_PAI_gasdata::ZKr
const int ZKr
Definition: TRT_PAI_gasdata.h:22
TRT_PAI_gasMixture::showStructure
void showStructure()
Print out of structure of this gas mixture.
Definition: TRT_PAI_gasMixture.cxx:89
TRT_PAI_effectiveGas
Effective gas: All quantities necessary to calculate PAI ionisation for gas mixture.
Definition: TRT_PAI_effectiveGas.h:18
grepfile.ic
int ic
Definition: grepfile.py:33
TRT_PAI_Process::GetEnergyTransfer
virtual double GetEnergyTransfer(double scaledKineticEnergy, CLHEP::HepRandomEngine *rndmEngine) const override final
Get the energy transferred from the charged particle to the gas (CLHEP units).
Definition: TRT_PAI_Process.cxx:278
TRT_PAI_Process::initialize
virtual StatusCode initialize() override final
Initialization of the PAI model:
Definition: TRT_PAI_Process.cxx:43
TRT_PAI_gasdata::ZC
const int ZC
Definition: TRT_PAI_gasdata.h:22
TRT_PAI_gasdata::ZF
const int ZF
Definition: TRT_PAI_gasdata.h:22
TRT_PAI_effectiveGas.h
TRT_PAI_gasdata::ZAr
const int ZAr
Definition: TRT_PAI_gasdata.h:22
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
python.SystemOfUnits.eV
int eV
Definition: SystemOfUnits.py:155
TRT_PAI_Process.h
TRT_PAI_gasComponent
Gas component (molecule)
Definition: TRT_PAI_gasComponent.h:16
TRT_PAI_element.h
TRT_PAI_Process::m_dndx
std::vector< float > m_dndx
Definition: TRT_PAI_Process.h:97
python.SystemOfUnits.mm
int mm
Definition: SystemOfUnits.py:83
TRT_PAI_gasdata::ZO
const int ZO
Definition: TRT_PAI_gasdata.h:22
DeMoScan.index
string index
Definition: DeMoScan.py:364
TRT_PAI_Process::m_gasType
std::string m_gasType
Definition: TRT_PAI_Process.h:106
GlobalVariables.Emax
Emax
Definition: GlobalVariables.py:185
TRT_PAI_utils.h
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
TRT_PAI_gasdata::SKr
const float SKr[NKr]
Cross sections for Krypton.
Definition: TRT_PAI_gasdata.h:128
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
TRT_PAI_Process::GetMeanFreePath
virtual double GetMeanFreePath(double scaledKineticEnergy, double squaredCharge) const override final
Get the mean free path in gas (CLHEP units)
Definition: TRT_PAI_Process.cxx:247
TRT_PAI_Process::m_fn_array
std::vector< std::vector< float > > m_fn_array
Definition: TRT_PAI_Process.h:96
TRT_PAI_gasMixture.h
TRT_PAI_gasdata::AAr
const float AAr
Definition: TRT_PAI_gasdata.h:27
TRT_PAI_gasdata::EC
const float EC[NC]
Energy levels for Carbon.
Definition: TRT_PAI_gasdata.h:241
TRT_PAI_element
Chemical element.
Definition: TRT_PAI_element.h:14
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15
TRT_PAI_Process::m_deltaGamExp
const double m_deltaGamExp
Definition: TRT_PAI_Process.h:92
python.SystemOfUnits.km
int km
Definition: SystemOfUnits.py:95
TRT_PAI_gasdata::EXe
const float EXe[NXe]
Energy levels for Xenon.
Definition: TRT_PAI_gasdata.h:33
TRT_PAI_utils::Interpolate
float Interpolate(const float &xval, const std::vector< float > &xtabulated, const std::vector< float > &ytabulated)
Interpolation function.
Definition: TRT_PAI_utils.cxx:14
TRT_PAI_physicsConstants::MProtonMeV
const double MProtonMeV
Proton mass in MeV
Definition: TRT_PAI_physicsConstants.h:18
TRT_PAI_Process::TRT_PAI_Process
TRT_PAI_Process(const std::string &type, const std::string &name, const IInterface *parent)
Not much action.
Definition: TRT_PAI_Process.cxx:33