ATLAS Offline Software
TRT_PAI_effectiveGas.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "TRT_PAI_Process.h"
6 #include "TRT_PAI_effectiveGas.h"
7 #include "TRT_PAI_gasMixture.h"
8 #include "TRT_PAI_gasComponent.h"
9 #include "TRT_PAI_element.h"
10 #include "TRT_PAI_utils.h"
12 
13 #include <vector>
14 #include <iostream>
15 #include <complex>
16 #include <cmath>
17 #include <algorithm> //for std::max, std::clamp
18 
19 #include "CLHEP/Units/SystemOfUnits.h"
20 
21 //____________________________________________________________________________
22 
24  double Emin,
25  double Emax,
26  double tempK,
27  double eps)
28  : AthMessaging("TRT_PAI_effectiveGas"),
29  m_lnEmin(std::log(Emin)),
30  m_lnEmax(std::log(Emax)),
31  m_eps(eps)
32 {
33  using namespace TRT_PAI_physicsConstants;
34 
36  double rho = 0.;
37  double Zeff = 0.;
38  double Aeff = 0.;
39  double w = 0.;
40  double wtot = 0.;
41  int Nelem = gm->getNElements();
42 
43  for ( int k=0; k<Nelem; k++ ) {
44  pe = gm->getElement(k);
45  w = gm->getElemWeight(k);
46  wtot += w;
47  rho += w * pe->getDensity(tempK);
48  Aeff += w * pe->getAtomicA();
49  Zeff += w * pe->getAtomicZ();
50  }
51 
52  Aeff /= wtot;
53  Zeff /= wtot;
54 
55  m_ne = Nav*rho*Zeff/Aeff; // Electron density
56  m_Wp2 = 4.*M_PI*r0*m_ne*he*he; // plasma freq**2 {ev}
57  m_S1 = mb/(2.*M_PI*M_PI*r0*he*Zeff); // x-section to F.osc
58  m_S2 = 2.*M_PI*r0*m_ne*Qe*Qe/erg; // dN/dx scale
59 
60  ATH_MSG_DEBUG ( "effectiveGas: Electron density " << m_ne );
61  ATH_MSG_DEBUG ( "effectiveGas: Plasma freq**2 {eV} " << m_Wp2 );
62  ATH_MSG_DEBUG ( "effectiveGas: x-section to F.osc " << m_S1 );
63  ATH_MSG_DEBUG ( "effectiveGas: dN/dx scale " << m_S2 );
64 
65  // Merge all energy levels into ELvls
66  std::vector<float> tempv;
67  for ( int k=0; k<Nelem; k++ ) {
68  pe = gm->getElement(k);
69  tempv = pe->getLnELvls();
70  m_lnELvls.insert( m_lnELvls.end(), tempv.begin(), tempv.end() );
71  }
72 
73  // Insert also Emin and Emax into ELvls, then sort
74  m_lnELvls.push_back(m_lnEmin);
75  m_lnELvls.push_back(m_lnEmax);
76  sort(m_lnELvls.begin(),m_lnELvls.end());
77 
79 
80  // Remove duplicate energies
81  vit = unique(m_lnELvls.begin(), m_lnELvls.end());
82  m_lnELvls.erase(vit, m_lnELvls.end());
83 
84  // Remove everything below Emin
85  vit = lower_bound(m_lnELvls.begin(), m_lnELvls.end(), m_lnEmin);
86  m_lnELvls.erase(m_lnELvls.begin(), vit);
87 
88  // Remove everything above Emax
89  vit = upper_bound(m_lnELvls.begin(), m_lnELvls.end(), m_lnEmax)-1;
90  m_lnELvls.erase(vit, m_lnELvls.end());
91 
92  int NLvls = m_lnELvls.size();
93 
94 
95  // Expand vectors to correct dimension
96  m_lnFosc.resize(NLvls);
97  m_lnIntegratedSigmas.resize(NLvls);
98  m_lnEpsI.resize(NLvls);
99  m_lnEpsR.resize(NLvls);
100 
101  // create array of effective cross sections (Fosc).
102 
103  for ( int i=0; i<NLvls; i++ ) {
104  double fosc = 0.;
105  // all atoms with an absorbtion energylevel low enough contribute.
106  for ( int k=0; k<Nelem; k++ ) {
107  pe = gm->getElement(k);
108  if ( m_lnELvls[i] >= pe->getLnELvls()[0] ) {
109  double lnSig = TRT_PAI_utils::Interpolate( m_lnELvls[i],
110  pe->getLnELvls(),
111  pe->getLnSigmas() );
112  fosc += std::exp(lnSig) * gm->getElemWeight(k);
113  }
114  }
115  //clamp, just in case
116  fosc = std::clamp(fosc, 1e-300,1e+300);
117  m_lnFosc[i] = std::log(fosc);
118  }
119 
120  // Create array of integrated cross-sections
121  double sigma = 0.;
122  double lnSigma = 0.;
123  double lnEHigh;
124  double lnELow = m_lnEmax;
125  double dsigma;
126 
127  for ( int i=NLvls-1; i>=0; --i) {
128  lnEHigh = lnELow;
129  lnELow = m_lnELvls[i];
131  lnELow,
132  lnEHigh,
133  m_eps,
134  0.);
135  sigma += dsigma;
136  lnSigma = std::log(sigma);
137  m_lnIntegratedSigmas[i] = lnSigma;
138  }
139 
140  // Normalize
141  for ( int i=0; i<NLvls; i++) {
142  m_lnFosc[i] -= lnSigma;
143  m_lnIntegratedSigmas[i] -= lnSigma;
144  }
145 
146  double cnst = std::log(M_PI_2*m_Wp2);
147  for (int i=0; i<NLvls; i++) {
148  m_lnEpsI[i] = cnst - m_lnELvls[i] + m_lnFosc[i];
149  float xint = XGInt(&TRT_PAI_effectiveGas::XFReal,
150  0.,
151  m_lnEmax,
152  m_eps,
153  m_lnELvls[i] );
154  m_lnEpsR[i] = m_Wp2 * std::exp(m_lnELvls[i]) * xint;
155  }
156  return;
157 }
158 
159 //____________________________________________________________________________
160 
161 double TRT_PAI_effectiveGas::XSigma (double lnE, double dummy) {
162  double xsig = dummy;
164  m_lnELvls,
165  m_lnFosc);
166  xsig = std::max(xsig,-99.);
167  xsig = std::exp( xsig + lnE );
168  return xsig;
169 }
170 
171 //____________________________________________________________________________
172 
173 double TRT_PAI_effectiveGas::XFReal (double lnD, double lnE) {
174 
175  double fp = 0.;
176  if ( lnE+lnD > m_lnEmin ) {
178  fp = std::exp(std::max(fp, -99.0));
179  }
180 
181  double fm = 0.;
182  if (lnE-lnD > m_lnEmin ) {
184  fm = std::exp(std::max(fm, -99.0));
185  }
186 
187  double x = std::exp(lnD);
188  return x/(x*x-1.)*(fp-fm);
189 }
190 
191 //____________________________________________________________________________
192 
193 double TRT_PAI_effectiveGas::XGInt( double (TRT_PAI_effectiveGas::*pt2Func)(double,double),
194  double lnLo,
195  double lnHi,
196  const double eps,
197  double extraParameter ) {
198  //
199  // Pavel Nevskis "famous integration procedure"
200  //
201  // Applies the Gauss-Legendre Quadrature method with n=4
202 
203  // These constants belong to the Gauss-Legendre quadrature method:
204  const int M = 4; // 4 points
205  const double U[M]={-.8611363,-.3399810, .3399810 ,.8611363}; // abscissas
206  const double W[M]={ .3478548, .6521452, .6521452, .3478548}; // weights
207 
208  int N=10;
209  double OTB=0,Y,D,result;
210 
211  double Dt = 0.5*(lnHi-lnLo);
212 
213  do {
214  Y = OTB;
215  OTB = 0.;
216  D = Dt/N;
217  for (int i=1; i<=N; i++) {
218  for (int k=0; k<M; k++) {
219  double arg = lnLo + D*(2*i-1+U[k]);
220  OTB += W[k] * (this->*pt2Func)(arg, extraParameter );
221  }
222  }
223  OTB *= D;
224  result = OTB;
225  N *= 2;
226  if ( N>100000 ) {
227  ATH_MSG_WARNING( "effectiveGas::XGInt: integrate Divergence! " << std::abs(OTB-Y) << " " << std::abs(eps*OTB) );
228  break;
229  }
230  } while ( (std::abs(OTB-Y) > std::abs(eps*OTB)) && (eps>0) );
231 
232  return result;
233 }
234 
235 //____________________________________________________________________________
236 
237 double TRT_PAI_effectiveGas::dndedx(double lnE, double gamma) {
238 
239  using namespace TRT_PAI_physicsConstants;
240  using namespace TRT_PAI_utils;
241 
242  double E = std::exp(lnE);
243  double gammaSq = gamma*gamma;
244  double betaSq = 1.-1./gammaSq;
245 
246  double er = Interpolate(lnE, m_lnELvls, m_lnEpsR);
247  double ei = Interpolate(lnE, m_lnELvls, m_lnEpsI);
248 
249  std::complex<double> Ceps1(er/(E*E), std::exp(ei));
250  std::complex<double> C1 = 1./gammaSq - Ceps1*betaSq;
251  std::complex<double> C2 = C1/(1.+Ceps1) * std::log(2.*betaSq*MeeV/(E*C1));
252 
253  double x;
255  x = m_S2/betaSq * E * ( -2.*imag(C2)/(m_Wp2*M_PI) + (1.-std::exp(x))/(E*E) );
256 
257  return x;
258 }
259 
260 //____________________________________________________________________________
261 
262 void TRT_PAI_effectiveGas::GasTab(const std::vector<float> & gamvec,
263  std::vector<float>& lnEarray,
264  std::vector< std::vector<float> >& fnArray,
265  std::vector<float>& dndx)
266 {
267  // For a given gamma factor, return dn/dx
268  // (by integrating dn^2/dEdx with respect to E)
269  // and tabulated values of dn^2/dEdx(?)....
270 
271  double Rener = 0.05;
272 
273  int NLvls = m_lnELvls.size();
274  int nGamVals = gamvec.size();
275 
276  double lnEi = m_lnEmax;
277  double lnEo;
278  double lnEs = -99999999.;
279 
280  fnArray.resize(nGamVals);
281  int nEVals = 0;
282 
283  // Initialize
284  for ( int ig=0; ig<nGamVals; ++ig ) {
285  fnArray[ig].push_back(0.);
286  }
287 
288  // Calculate integral from above and store the cumulative values in fnArray
289 
290  for ( int ie=NLvls-1; ie>=0; --ie ) {
291  lnEo = lnEi;
292  lnEi = m_lnELvls[ie];
293  for ( int ig=0; ig<nGamVals; ++ig ) {
294  double ds =
295  XGInt( &TRT_PAI_effectiveGas::dndedx, lnEi, lnEo, m_eps, gamvec[ig]);
296  fnArray[ig][nEVals] += ds;
297  }
298  if ( std::abs(lnEs-lnEi) > Rener || ie==0 ) {
299  lnEs = lnEi;
300  lnEarray.push_back( lnEs );
301  if ( ie>0 ) {
302  for ( int ig=0; ig<nGamVals; ++ig ) {
303  fnArray[ig].push_back( fnArray[ig][nEVals] );
304  }
305  }
306  nEVals++;
307  }
308  }
309 
310  // Copy the total integral into auxillary vector
311  dndx.resize(nGamVals);
312  for ( int ig = 0; ig < nGamVals; ++ig ) {
313  dndx[ig] = fnArray[ig][nEVals-1];
314  }
315 
316  return;
317 }
318 
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
TRT_PAI_effectiveGas::m_lnEmin
const double m_lnEmin
Definition: TRT_PAI_effectiveGas.h:60
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
TRT_PAI_effectiveGas::m_lnELvls
std::vector< float > m_lnELvls
Definition: TRT_PAI_effectiveGas.h:55
TRT_PAI_utils
Utilities.
Definition: TRT_PAI_utils.h:13
TRT_PAI_gasMixture::getElement
TRT_PAI_element * getElement(unsigned int n)
Get element no.
Definition: TRT_PAI_gasMixture.cxx:136
TRT_PAI_physicsConstants::Nav
const double Nav
Avagadro constant
Definition: TRT_PAI_physicsConstants.h:13
checkxAOD.ds
ds
Definition: Tools/PyUtils/bin/checkxAOD.py:258
TRT_PAI_gasMixture
Gas mixture = mixture of gas components.
Definition: TRT_PAI_gasMixture.h:18
pdg_comparison.sigma
sigma
Definition: pdg_comparison.py:324
get_generator_info.result
result
Definition: get_generator_info.py:21
TRT_PAI_effectiveGas::XFReal
double XFReal(double lnD, double lnE)
Definition: TRT_PAI_effectiveGas.cxx:173
max
#define max(a, b)
Definition: cfImp.cxx:41
JetTiledMap::W
@ W
Definition: TiledEtaPhiMap.h:44
TRT_PAI_effectiveGas::m_lnEpsI
std::vector< float > m_lnEpsI
Definition: TRT_PAI_effectiveGas.h:59
M_PI
#define M_PI
Definition: ActiveFraction.h:11
TRT_PAI_effectiveGas::m_lnIntegratedSigmas
std::vector< float > m_lnIntegratedSigmas
Definition: TRT_PAI_effectiveGas.h:57
TRT_PAI_effectiveGas::m_S1
double m_S1
Definition: TRT_PAI_effectiveGas.h:63
JetTiledMap::N
@ N
Definition: TiledEtaPhiMap.h:44
TRT_PAI_effectiveGas::TRT_PAI_effectiveGas
TRT_PAI_effectiveGas(TRT_PAI_gasMixture *gm, double Emin, double Emax, double tempK, double eps)
Definition: TRT_PAI_effectiveGas.cxx:23
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
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
x
#define x
LArG4AODNtuplePlotter.pe
pe
Definition: LArG4AODNtuplePlotter.py:116
PlotCalibFromCool.ie
ie
Definition: PlotCalibFromCool.py:420
TRT_PAI_effectiveGas::m_ne
double m_ne
Definition: TRT_PAI_effectiveGas.h:66
TRT_PAI_effectiveGas::dndedx
double dndedx(double lgE, double gamma)
Definition: TRT_PAI_effectiveGas.cxx:237
TRT_PAI_physicsConstants
Physics constants.
Definition: TRT_PAI_physicsConstants.h:11
TrigVtx::gamma
@ gamma
Definition: TrigParticleTable.h:26
GlobalVariables.Emin
Emin
Definition: GlobalVariables.py:184
lumiFormat.i
int i
Definition: lumiFormat.py:85
trigmenu_modify_prescale_json.fp
fp
Definition: trigmenu_modify_prescale_json.py:53
TRT_PAI_physicsConstants.h
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TRT_PAI_gasComponent.h
TRT_PAI_physicsConstants::Qe
const double Qe
Electron charge{ESU}.
Definition: TRT_PAI_physicsConstants.h:19
TRT_PAI_physicsConstants::r0
const double r0
electron radius{cm}
Definition: TRT_PAI_physicsConstants.h:20
AthMessaging
Class to provide easy MsgStream access and capabilities.
Definition: AthMessaging.h:55
python.xAODType.dummy
dummy
Definition: xAODType.py:4
TRT_PAI_effectiveGas::m_Wp2
double m_Wp2
Definition: TRT_PAI_effectiveGas.h:64
TRT_PAI_effectiveGas::m_eps
const double m_eps
Definition: TRT_PAI_effectiveGas.h:62
TRT_PAI_physicsConstants::erg
const double erg
1 ev to erg {erg}
Definition: TRT_PAI_physicsConstants.h:14
TRT_PAI_effectiveGas
Effective gas: All quantities necessary to calculate PAI ionisation for gas mixture.
Definition: TRT_PAI_effectiveGas.h:18
create_dcsc_inputs_sqlite.arg
list arg
Definition: create_dcsc_inputs_sqlite.py:48
Monitored::Y
@ Y
Definition: HistogramFillerUtils.h:24
TRT_PAI_gasMixture::getNElements
int getNElements()
Get number of different element in this gas mixture.
Definition: TRT_PAI_gasMixture.h:60
TRT_PAI_effectiveGas.h
VP1PartSpect::E
@ E
Definition: VP1PartSpectFlags.h:21
TRT_PAI_effectiveGas::XGInt
double XGInt(double(TRT_PAI_effectiveGas::*pt2Func)(double, double), double lnLo, double lnHi, const double eps, double extraParameter)
Definition: TRT_PAI_effectiveGas.cxx:193
TRT_PAI_Process.h
TRT_PAI_effectiveGas::m_lnFosc
std::vector< float > m_lnFosc
Definition: TRT_PAI_effectiveGas.h:56
TRT_PAI_element.h
TRT_PAI_physicsConstants::he
const double he
same in ev
Definition: TRT_PAI_physicsConstants.h:22
TRT_PAI_effectiveGas::m_lnEmax
const double m_lnEmax
Definition: TRT_PAI_effectiveGas.h:61
TRT_PAI_physicsConstants::MeeV
const double MeeV
same in ev
Definition: TRT_PAI_physicsConstants.h:17
GlobalVariables.Emax
Emax
Definition: GlobalVariables.py:185
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
TRT_PAI_utils.h
TRT_PAI_physicsConstants::mb
const double mb
1mb to cm2
Definition: TRT_PAI_physicsConstants.h:15
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
TRT_PAI_effectiveGas::m_S2
double m_S2
Definition: TRT_PAI_effectiveGas.h:65
TRT_PAI_gasMixture.h
TRT_PAI_effectiveGas::m_lnEpsR
std::vector< float > m_lnEpsR
Definition: TRT_PAI_effectiveGas.h:58
TRT_PAI_effectiveGas::XSigma
double XSigma(double lnE, double dummy)
Definition: TRT_PAI_effectiveGas.cxx:161
TRT_PAI_element
Chemical element.
Definition: TRT_PAI_element.h:14
python.IoTestsLib.w
def w
Definition: IoTestsLib.py:200
TRT_PAI_gasMixture::getElemWeight
double getElemWeight(unsigned int n)
Get weight of element no.
Definition: TRT_PAI_gasMixture.cxx:148
fitman.rho
rho
Definition: fitman.py:532
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
fitman.k
k
Definition: fitman.py:528