Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
TRTTransitionRadiation.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 //#define ARTRU // Choice of TR generator
6 
7 // class header
9 
10 // package includes
11 #include "TRTRadiatorParameters.h"
12 #include "TRRegionXMLHandler.h"
13 
14 // Athena includes
15 #include "CLHEP/Random/RandGaussZiggurat.h"
16 #include "GeoModelInterfaces/StoredMaterialManager.h" //Material Manager
17 #include "GeoMaterial2G4/Geo2G4MaterialFactory.h" //Converting GeoMaterial -> G4Material
19 #include "StoreGate/DataHandle.h"
20 #include "StoreGate/StoreGateSvc.h" //Detector Store
21 
26 
27 // Geant4 includes
28 #include "G4DynamicParticle.hh"
29 #include "G4Gamma.hh"
30 #include "G4Material.hh"
31 #include "G4Element.hh"
32 #include "G4EmProcessSubType.hh" // for fTransitionRadiation
33 #include "G4ProcessType.hh" // for fElectromagnetic
34 
35 #include "Randomize.hh"
36 
37 // CLHEP includes
38 #include "CLHEP/Random/RandPoisson.h"
39 
40 // STL includes
41 #include <cmath>
42 #include <limits>
43 
45 //
46 // Constructor, destructor
47 
48 TRTTransitionRadiation::TRTTransitionRadiation( const G4String& processName, const std::string & xmlfilename) :
49  G4VDiscreteProcess(processName,fElectromagnetic),
50  AthMessaging("TRTTransitionRadiation"),
51  m_XMLhandler(nullptr),m_xmlfilename(xmlfilename),
52  m_MinEnergyTR(0.0),m_MaxEnergyTR(0.0),m_NumBins(0),m_WplasmaGas(0.0),
53  m_WplasmaFoil(0.0),m_GammaMin(0.0),m_EkinMin(0.0),m_Ey(nullptr),m_Sr(nullptr),
54  m_om(nullptr),m_Omg(nullptr),m_sigmaGas(nullptr),m_sigmaFoil(nullptr)
55 {
56  m_radiators.clear();
57  m_XMLhandler = new TRRegionXMLHandler( this );
58 
59  SetProcessSubType( fTransitionRadiation );
60 
61  ATH_MSG_DEBUG ( "##### Constructor TRTTransitionRadiation" );
62 
63  Initialize();
64 
65  ATH_MSG_DEBUG ( "##### Constructor TRTTransitionRadiation done" );
66 
67 }
68 
70 
72  delete [] m_Ey;
73  delete [] m_Sr;
74  delete [] m_Omg;
75  delete [] m_om;
76  delete [] m_sigmaGas;
77  delete [] m_sigmaFoil;
78 }
79 
82 
83  ATH_MSG_DEBUG(" New Radiator parameters being defined for TR process");
84  ATH_MSG_DEBUG(" Volume " << p.GetLogicalVolume()->GetName());
85  ATH_MSG_DEBUG(" FoilThickness " << p.GetFoilThickness());
86  ATH_MSG_DEBUG(" GasThickness " << p.GetGasThickness());
87 
88  m_radiators.push_back(p);
89 
90  return;
91 }
92 
93 
95  ATH_MSG_DEBUG ( "Constructor TRTTransitionRadiation::Initialize()" );
96  m_NumBins = 100; // Bins for TR generation (Nevski has 25 bins)
97  m_MinEnergyTR = 2.0*CLHEP::keV; // Minimum TR energy
98  m_MaxEnergyTR = 50.0*CLHEP::keV; // Maximum TR energy
99 
100  m_GammaMin = 500.; // Min. value of Lorentz gamma for TR generation
102 
103  //We get the materials from GeoMaterial manager and convert them to G4Materials
104  //
105  //NB: Maybe we should control this from TRT_GeoModel instead?
106  //
107  // On a related note we should get rid of the xml files too -
108  // they are a loophole in the versioning.
109 
110  G4Material* g4mat_Gas{nullptr};
111  G4Material* g4mat_FoilMaterial{nullptr};
112  std::string errorMessage;
113 
114  // Get material information from storegate.
115  ISvcLocator *svcLocator = Gaudi::svcLocator(); // from Bootstrap
116  SmartIF<StoreGateSvc> detStore{svcLocator->service( "DetectorStore")};
117  if (!detStore) {
118  errorMessage = "Can not access Detector Store";
119  ATH_MSG_FATAL (errorMessage);
120  throw std::runtime_error(errorMessage);
121  }
122 
123  StoredMaterialManager* materialManager = detStore->tryRetrieve<StoredMaterialManager>("MATERIALS");
124  if(materialManager) {
125  Geo2G4MaterialFactory geo2g4_material_fact;//Note - this is a very lightweight class!
126  g4mat_Gas = geo2g4_material_fact.Build(materialManager->getMaterial("trt::CO2"));
127  g4mat_FoilMaterial = geo2g4_material_fact.Build(materialManager->getMaterial("trt::CH2"));
128 
129  //Note: One might wonder if we now own g4mat_Gas and
130  //g4mat_FoilMaterial, but since the elementfactory used inside
131  //Geo2G4MaterialFactory is static, we must NOT delete them!!
132  }
133  else {
134  ATH_MSG_INFO("GeoModel Material is not available. Construct TR materials using IRDBAccessSvc interface");
135  SmartIF<IGeoDbTagSvc> geoDbTagSvc{svcLocator->service("GeoDbTagSvc")};
136  if (!geoDbTagSvc) {
137  errorMessage = "Can not access GeoDbTagSvc";
138  ATH_MSG_FATAL (errorMessage);
139  throw std::runtime_error(errorMessage);
140 
141  return;
142  };
143  SmartIF<IRDBAccessSvc> pAccessSvc{svcLocator->service(geoDbTagSvc->getParamSvcName())};
144  if ( !pAccessSvc) {
145  errorMessage = "Can not access " + geoDbTagSvc->getParamSvcName();
146  ATH_MSG_FATAL (errorMessage);
147  throw std::runtime_error(errorMessage);
148  }
149 
150  std::map<std::string,int> materialComponentsMap; // Number of elements for each material
151  std::map<std::string,G4Material*> materialMap;
152  IRDBRecordset_ptr materialsRec = pAccessSvc->getRecordsetPtr("TRMaterials","","");
153  // Step #1. Count elements per material
154  for (const IRDBRecord_ptr& material : *materialsRec) {
155  std::string key = material->getString("NAME");
156  auto mapIt = materialComponentsMap.find(key);
157  if (mapIt == materialComponentsMap.end()) {
158  materialComponentsMap.emplace(key,1);
159  }
160  else {
161  materialComponentsMap.at(key) = mapIt->second + 1;
162  }
163  }
164  // Step #2. Build materials
165  for (const IRDBRecord_ptr& material :*materialsRec) {
166  std::string key = material->getString("NAME");
167  G4Material* g4Material{nullptr};
168  if(materialMap.find(key)==materialMap.end()) {
169  auto itNElements = materialComponentsMap.find(key);
170  if (itNElements==materialComponentsMap.end()) continue;
171  g4Material = new G4Material(key
172  ,material->getDouble("DENSITY")*(CLHEP::gram / CLHEP::cm3)
173  ,itNElements->second);
174  materialMap.emplace(key,g4Material);
175  }
176  else {
177  g4Material = materialMap.at(key);
178  }
179 
180  G4Element* g4Element = G4Element::GetElement(material->getString("ELEMENT_NAME"));
181  if(!g4Element) {
182  errorMessage = "Wrong name for element " + material->getString("ELEMENT_NAME")
183  + " found in the description of material " + key;
184  ATH_MSG_FATAL (errorMessage);
185  throw std::runtime_error(errorMessage);
186  }
187  g4Material->AddElement(g4Element,(G4int)material->getInt("N"));
188  }
189  g4mat_Gas = materialMap.at("CO2");
190  g4mat_FoilMaterial = materialMap.at("CH2");
191  }
192 
194 
195  // Plate and gas indicies
196  m_WplasmaFoil = sqrt( PlasmaCof * g4mat_FoilMaterial->GetElectronDensity() );
197  m_WplasmaGas = sqrt( PlasmaCof * g4mat_Gas->GetElectronDensity() );
198 
199  ATH_MSG_DEBUG("Foil material : " << g4mat_FoilMaterial->GetName()
200  << "; plasma energy : " << m_WplasmaFoil/CLHEP::eV << " eV");
201  ATH_MSG_DEBUG("Gas : " << g4mat_Gas->GetName()
202  << "; plasma energy : " << m_WplasmaGas/CLHEP::eV << " eV");
203 
204  m_Omg = new G4double[m_NumBins];
205  m_om = new G4double[m_NumBins];
206  m_Ey = new G4double[m_NumBins];
207  m_Sr = new G4double[m_NumBins];
208  m_sigmaGas = new G4double[m_NumBins];
209  m_sigmaFoil = new G4double[m_NumBins];
210 
211  for(G4int j(0); j<m_NumBins; ++j) {
212  m_Omg[j] = log( m_MinEnergyTR ) +
214  m_om [j] = exp( m_Omg[j] );
215  m_sigmaGas[j] = ComputePhotoAbsCof( g4mat_Gas, m_om[j] );
216  m_sigmaFoil[j] = ComputePhotoAbsCof( g4mat_FoilMaterial, m_om[j] );
217  }
218 
219  const std::string file=PathResolver::find_file(m_xmlfilename,"DATAPATH");
220  if (!file.empty())
221  {
223  }
224  else ATH_MSG_WARNING("File "<<m_xmlfilename<<" not found! Expect problems.");
225 
226  ATH_MSG_DEBUG ( "Constructor TRTTransitionRadiation::Initialize() DONE!" );
227  return;
228 
229 }
230 
232 //
233 // Returns condition for application of the model depending on particle type
234 
235 
236 G4bool TRTTransitionRadiation::IsApplicable(const G4ParticleDefinition& particle) {
237  //return true if PDG Charge and PDG Mass are non-zero.
238  return ( std::abs(particle.GetPDGCharge())>std::numeric_limits<double>::epsilon() && std::abs(particle.GetPDGMass())>std::numeric_limits<double>::epsilon() ) ;
239 }
240 
242 //
243 // GetContinuousStepLimit
244 //
245 
246 G4double TRTTransitionRadiation::GetMeanFreePath(const G4Track& aTrack,
247  G4double,
248  G4ForceCondition* condition) {
249  const G4DynamicParticle *aParticle(aTrack.GetDynamicParticle());
250  if(std::abs(aParticle->GetDefinition()->GetPDGCharge())< std::numeric_limits<double>::epsilon() ||
251  std::abs(aParticle->GetDefinition()->GetPDGMass())<std::numeric_limits<double>::epsilon() ) {
252  *condition = NotForced;
253  } else {
254  *condition = Forced;
255  }
256  return DBL_MAX;
257 }
258 
260 //
261 //
262 G4VParticleChange* TRTTransitionRadiation::PostStepDoIt( const G4Track& aTrack,
263  const G4Step& aStep ) {
264  aParticleChange.Initialize(aTrack);
265 
266  // Obtain kinetic energy
267  const G4DynamicParticle *aParticle(aTrack.GetDynamicParticle());
268  G4double KineticEnergy(aParticle->GetKineticEnergy());
269 
270  // Kinetic energy too low for TR generation for any kind of particle
271  if ( KineticEnergy < m_EkinMin )
272  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
273 
274  // Particle properties ...
275  G4double ParticleMass(aParticle->GetDefinition()->GetPDGMass());
276  G4double Gamma(1.0 + KineticEnergy/ParticleMass);
277 
278  if( Gamma < m_GammaMin ) {
279  ATH_MSG_VERBOSE ( "Leaving PostStepDoIt(): Gamma < " << m_GammaMin );
280  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
281  }
282 
283  G4double FoilThickness(0.);
284  G4double GasThickness(0.);
285  BEflag BEflag(BARREL); //enum?
286 
287  // Check whether particle is inside radiator
288  std::vector<TRTRadiatorParameters>::const_iterator currentRadiator(m_radiators.begin());
289  const std::vector<TRTRadiatorParameters>::const_iterator endOfRadiators(m_radiators.end());
290  while(currentRadiator!=endOfRadiators) {
291  if ( currentRadiator->GetLogicalVolume() ==
292  aTrack.GetVolume()->GetLogicalVolume() ) {
293  FoilThickness = currentRadiator->GetFoilThickness();
294  GasThickness = currentRadiator->GetGasThickness();
295  BEflag = currentRadiator->GetBEflag();
296  break;
297  }
298  ++currentRadiator;
299  }
300  // Particle not inside radiator - return
301  if ( currentRadiator == endOfRadiators ) {
302  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
303  }
304 
305  ATH_MSG_VERBOSE ( "PostStepDoIt(): Inside radiator "
306  << currentRadiator->GetLogicalVolume()->GetName() );
307 
308  G4ThreeVector ParticleDirection(aParticle->GetMomentumDirection());
309 
310  if ( BEflag == ENDCAP ) {
311  G4double costh(std::abs(ParticleDirection[2]));
312  FoilThickness /= costh;
313  GasThickness /= costh;
314  }
315 
316  G4double StepLength(aStep.GetStepLength());
317  G4int FoilsTraversed(static_cast<G4int>(StepLength/(FoilThickness+GasThickness)+0.5));
318 
319  // Steplength so short, that no foils are crossed.
320  // Forget it...
321  // Actually the treatment we do is only valid for "many" foils.
322  // Should we put this requirement higher?
323  if ( FoilsTraversed == 0 ) {
324  ATH_MSG_VERBOSE ( "Leaving PostStepDoIt(): No foils traversed." );
325  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
326  }
327 
328  G4double Gy(0.), Gmany(0.), Neff(0.);
329 
330  // Generate, in the language of Artru:
331  // 1) G_y
332  // 2) N_{eff}
333  // 3) G_{many}
334  // Divide by photon energy to get photon spectrum (m_Ey)
335 
336  for( G4int i(0); i<m_NumBins; ++i ) {
337 
338 #ifdef ARTRU // Formulas from Artru
339  Gy = XEmitanArtru( m_om[i],
340  Gamma,
341  GasThickness,
342  FoilThickness );
343  Neff = NeffArtru( m_sigmaGas[i],
344  m_sigmaFoil[i],
345  GasThickness,
346  FoilThickness,
347  FoilsTraversed );
348 #else
349  Gy = XEmitanNevski( m_om[i], // Formulas from Cherry via
350  Gamma, // Pavel Nevski in G3
351  GasThickness,
352  FoilThickness );
353  Neff = NeffNevski( m_sigmaGas[i],
354  m_sigmaFoil[i],
355  GasThickness,
356  FoilThickness,
357  FoilsTraversed );
358 #endif
359 
360  Gmany = Neff*Gy; // Energy spectrum
361  m_Ey[i] = Gmany / m_om[i]; // Photon spectrum
362 
363  }
364 
365  // Integrate spectrum
366  G4double Sph(XInteg( m_Ey, m_Sr ));
367  G4double Sph_org(Sph);
368 
369  if ( ( BEflag == BARREL ) && (Gamma > 0.0) ) {
370  G4double tempLog10Gamma(log10(Gamma)); //Hardcoded numbers from TestBeam study (E.Klinkby). Better to move elsewhere.
371  G4double pHT_dEdxData = -0.001 + 0.0005*tempLog10Gamma;
372  G4double pHT_TRData = 0.15/(1.0 + exp(-(tempLog10Gamma - 3.3)/0.27));
373  G4double pHT_dEdxMC = -0.0031 + 0.00016*tempLog10Gamma;
374  G4double pHT_TRMC = 0.1289/(1.0 + exp(-(tempLog10Gamma - 3.01)/0.1253));
375 
376  G4double fudge = std::min(2.0,(pHT_dEdxData+pHT_TRData)/( pHT_dEdxMC+pHT_TRMC));
377 
378  Sph *= fudge;
379  }
380 
381  // Now how many photons are generated?
382  G4long NumberOfPhotonsGenerated(CLHEP::RandPoisson::shoot(Sph));
383 
384  //reset Sph to original value.
385  Sph = Sph_org;
386 
387  ATH_MSG_VERBOSE ( ">>>> FoilsTraversed = " << FoilsTraversed
388  << ", Gamma = " << Gamma
389  << ", Sph = " << Sph
390  << ", Nph = " << NumberOfPhotonsGenerated );
391  // No photons, return
392  if ( NumberOfPhotonsGenerated <= 0 ) {
393  ATH_MSG_VERBOSE ( "Leaving TRTTransitionRadiation::PostStepDoIt: "
394  << "No photons generated." );
395 
396  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
397  }
398 
399  // Now, generate the photons
400  aParticleChange.SetNumberOfSecondaries( NumberOfPhotonsGenerated );
401  G4StepPoint *pPostStepPoint(aStep.GetPostStepPoint());
402  G4ThreeVector x0(pPostStepPoint->GetPosition());
403 
404  G4double Esum(0.), XRannu(0.), Ephot(0.), Theta(0.), Phi(0.),
405  X(0.), Y(0.), Z(0.);
406 
407  G4ThreeVector pos(0),TRPhotonDirection(0);
408 
409  for( G4int i(0); i<NumberOfPhotonsGenerated; ++i ) {
410  XRannu = CLHEP::RandFlat::shoot();
411  Ephot = exp( XFinter( XRannu*Sph, m_Sr, m_Omg ) );
412 
413  Esum += Ephot;
414 
415  pos = pPostStepPoint->GetPosition();
416 
417  ATH_MSG_VERBOSE ( " Photon generated with energy : " << Ephot/CLHEP::keV
418  << " keV; position: ( " << pos.x()/CLHEP::cm << " cm, "
419  << pos.y()/CLHEP::cm << " cm, " << pos.z()/CLHEP::cm << " cm )" );
420 
421  // Angle w.r.t. electron direction (this is not correct but anyway...)
422  Theta = std::abs( CLHEP::RandGaussZiggurat::shoot( 0.0, M_PI/Gamma ) );
423  if( Theta >= 0.1 ) Theta = 0.1;
424 
425  Phi = (2.*M_PI)*CLHEP::RandFlat::shoot();
426 
427  X = sin(Theta)*cos(Phi);
428  Y = sin(Theta)*sin(Phi);
429  Z = cos(Theta);
430 
431  TRPhotonDirection.set(X,Y,Z);
432  TRPhotonDirection.rotateUz( ParticleDirection );
433  TRPhotonDirection.unit();
434 
435  G4DynamicParticle*
436  TRPhoton = new G4DynamicParticle( G4Gamma::Gamma(),
437  TRPhotonDirection,
438  Ephot );
439  aParticleChange.AddSecondary( TRPhoton );
440 
441  }
442 
443  aParticleChange.ProposeEnergy( KineticEnergy-Esum );
444 
445  ATH_MSG_VERBOSE ( "Leaving TRTTransitionRadiation::PostStepDoIt; "
446  << "Number of TR photons generated: " << NumberOfPhotonsGenerated );
447 
448  return &aParticleChange;
449 }
450 
451 inline G4double TRTTransitionRadiation::NeffNevski( const G4double & sigGas,
452  const G4double & sigFoil,
453  const G4double & GasThickness,
454  const G4double & FoilThickness,
455  const G4int & FoilsTraversed ) const {
456  if ( FoilsTraversed <= 0 )
457  return 0.;
458 
459  G4double C1 = sigGas * GasThickness*FoilsTraversed;
460  G4double C2 = sigFoil*FoilThickness*FoilsTraversed;
461 
462  G4double W1 = exp(-C1);
463  G4double W2 = exp(-C2);
464 
465  return FoilsTraversed * (1-W1*W2)/(C1+C2);
466 }
467 
468 inline G4double TRTTransitionRadiation::NeffArtru( const G4double & sigGas,
469  const G4double & sigFoil,
470  const G4double & GasThickness,
471  const G4double & FoilThickness,
472  const G4int & FoilsTraversed ) const {
473  if ( FoilsTraversed <= 0 )
474  return 0.;
475 
476  G4double sigma = FoilThickness*sigFoil + GasThickness*sigGas;
477  G4double xNF = FoilsTraversed;
478  return (1.-exp(-xNF*sigma))/(1.-exp(-sigma));
479 }
480 
482 //
483 // Nevskis XEmitan-function
484 //
485 //inline G4double max(G4double a, G4double b) {return a>b?a:b;}
486 
487 inline G4double TRTTransitionRadiation::XEmitanNevski( const G4double & PhotonEnergy,
488  const G4double & Gamma,
489  const G4double & Al1,
490  const G4double & Al2 ) const {
491  //FIXME hardcoded numbers are not good.
492  G4double eps = 0.05;
493 
494  G4double Al = Al1 + Al2;
495 
496  G4double CK = 1/(2*M_PI*CLHEP::hbarc);
497 
498  // Plasma frequencies:
499  G4double om1 = m_WplasmaGas;
500  G4double om2 = m_WplasmaFoil;
501 
502  G4double om12 = (om1*om1-om2*om2)/PhotonEnergy;
503  G4double oms = (Al1*om1*om1+Al2*om2*om2)/Al;
504  G4double Ao = 0.5*Al1*om12*CK;
505  G4double Bo = 0.5*Al2*om12*CK;
506  G4double ro = sqrt(oms)/Gamma;
507  G4double co = 0.5*(PhotonEnergy/(Gamma*Gamma)+oms/PhotonEnergy);
508  G4double cc = co*Al*CK;
509  G4double cb = M_PI*Al2/Al;
510  G4int i1 = static_cast<G4int>(1.0+(ro>co?ro:co)*Al*CK);//(G4int)(1.0+max(ro,co)*Al*CK);
511  G4int i2 = static_cast<G4int>(Gamma*ro*Al*CK);
512 
513  G4double Sum = 0.0;
514  G4double Smx = 0.0;
515  G4double Sm1 = 0.0;
516  G4double S = 0.0;
517  G4double So = 0.0;
518 
519  G4double Sx = 0.0;
520 
521  for(G4int i(i1); i<=i2; ++i) {
522  Sx = So;
523  So = S;
524  S = (static_cast<G4double>(i)-cc)*(sin(cb*(static_cast<G4double>(i)-Ao))/((static_cast<G4double>(i)-Ao)*(static_cast<G4double>(i)+Bo)))*
525  (sin(cb*(static_cast<G4double>(i)-Ao))/((static_cast<G4double>(i)-Ao)*(static_cast<G4double>(i)+Bo)));
526  Smx=Smx>S?Smx:S;//max(Smx,S);
527  Sm1=Sm1>S?Sm1:S;//max(Sm1,S);
528  Sum += S;
529 
530  if( (So<Sx)&&(So<=S) ) {
531  if( Sm1<eps*Smx ) break;
532  Sm1 = 0.0;
533  }
534  }
535 
536  return ( CLHEP::fine_structure_const*om12*om12*Al*Al*CK*CK*Sum/M_PI );
537 }
538 
540 //
541 // Same as above but for the Artru way of doing things
542 //
543 inline G4double TRTTransitionRadiation::XEmitanArtru( const G4double & omega,
544  const G4double & Gamma,
545  const G4double & d2,
546  const G4double & d1 ) const {
547  G4double phimax = 4.*M_PI;
548  G4double ginv2 = 1./(Gamma*Gamma);
549  G4double tau = d2/d1;
550 
551  G4double mom = omega/CLHEP::hbarc;
552 
553  G4double xi1 = m_WplasmaFoil/omega;
554  G4double xi2 = m_WplasmaGas/omega;
555 
556  G4double xi1sq = xi1*xi1;
557  G4double xi2sq = xi2*xi2;
558 
559  G4double Z1 = 2./(mom*(ginv2+xi1sq));
560  G4double Z2 = 2./(mom*(ginv2+xi2sq));
561 
562  G4double a = d1/Z2;
563  G4double V = d1*(1./Z1-1./Z2);
564 
565  G4double p0 = mom*d1*(xi1sq-xi2sq)/(4.*M_PI);
566  G4double pmin = p0 + a*(1.+tau)/(2.*M_PI);
567  G4double ymax = tau*phimax;
568  G4double pmax = p0 + ymax*(1.+tau)/(2.*M_PI);
569 
570  G4int ipmin = (int)pmin+1;
571  G4int ipmax = (int)pmax;
572 
573  G4double sum=0.;
574  G4double y0 = -0.5*mom*d1*(xi1sq-xi2sq)/(1+tau);
575  G4double dy = (2.*M_PI)/(1+tau);
576  G4double y;
577 
578  G4double term = 0.;
579  G4double t1 = 0.;
580  G4double t2 = 0.;
581  G4double tx = 0.;
582 
583  for ( G4int ip(ipmin); ip<=ipmax; ++ip ) {
584  t2 = t1;
585  t1 = term;
586 
587  y = y0 + ip*dy;
588  term = (1./y-1./(y+V))*sin(0.5*(y+V));
589  term *= term;
590  term *= y-a;
591  sum += term;
592 
593  //G4double theta2 = 2.*y*tau/(mom*d2) - ginv2 - xi2sq;
594  //G4double theta = sqrt(theta2);
595 
596  tx = (tx>term) ? tx : term;
597 
598  // Locate local maxima (previous term)
599 
600  if ( t2 > 0. && t1 > term && t1 > t2 ) {
601  if ( t1 < 0.0001*sum ) break;
602  }
603  }
604 
605  return ( sum*4.*2.*CLHEP::fine_structure_const/(1.+tau));
606 }
607 
609 //
610 // Nevskis XInteg function
611 // Spectrum integration
612 //
613 
614 inline G4double TRTTransitionRadiation::XInteg( const G4double * yy, G4double * ss ) const {
615  G4double S(0.);
616  ss[0] = 0.;
617 
618  for( G4int i(1); i<m_NumBins; ++i ) {
619  S += 0.5*( m_Omg[i]-m_Omg[i-1] )*( yy[i-1]*m_om[i-1] + yy[i]*m_om[i] );
620  ss[i] = S;
621  }
622 
623  return S;
624 }
625 
627 //
628 // Nevskis XFINTER function
629 
630 G4double TRTTransitionRadiation::XFinter( const G4double & X, const G4double* A, const G4double* F ) const {
631  G4int K1(0);
632  G4int K2(0);
633 
634  if( (K1>=m_NumBins) || ( X < A[K1] ) ) K1 = 0; //FIXME This line has no effect?
635  if( (K2>=m_NumBins) || ( X > A[K2] ) ) K2 = m_NumBins-1;
636 
637  G4int K(0);
638  while( K2-K1>1 ) {
639  K = static_cast<G4int>((K1+K2)/2);
640  if( A[K]<X ) {
641  K1 = K;
642  } else {
643  K2 = K;
644  }
645  }
646 
647  G4double X1(A[K1]);
648  G4double X2(A[K1+1]);
649 
650  G4double xfinter((F[K1]*(X-X2)+F[K1+1]*(X1-X))/(X1-X2));
651  return xfinter;
652 }
653 
655 //
656 // Computes Sandia photo absorption cross section coefficients for Material
657 
659  const G4double & PhotonEnergy ) const {
660 
661  const G4double *SandiaCof(Material->GetSandiaTable()->GetSandiaCofForMaterial(PhotonEnergy));
662 
663  const G4double Energy2(PhotonEnergy*PhotonEnergy);
664  const G4double Energy3(PhotonEnergy*Energy2);
665  const G4double Energy4(Energy2*Energy2);
666 
667  return ( SandiaCof[0]/PhotonEnergy +
668  SandiaCof[1]/Energy2 +
669  SandiaCof[2]/Energy3 +
670  SandiaCof[3]/Energy4 );
671 }
TRTTransitionRadiation::XEmitanArtru
G4double XEmitanArtru(const G4double &PhotonEnergy, const G4double &Gamma, const G4double &GasThickness, const G4double &FoilThickness) const
Definition: TRTTransitionRadiation.cxx:543
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
Trk::ParticleSwitcher::particle
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses
Definition: ParticleHypothesis.h:76
pdg_comparison.sigma
sigma
Definition: pdg_comparison.py:324
TRTTransitionRadiation::AddRadiatorParameters
void AddRadiatorParameters(const TRTRadiatorParameters &p)
Definition: TRTTransitionRadiation.cxx:81
PowhegControl_ttHplus_NLO.ss
ss
Definition: PowhegControl_ttHplus_NLO.py:83
python.PhysicalConstants.fine_structure_const
float fine_structure_const
Definition: PhysicalConstants.py:103
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
PlotCalibFromCool.yy
yy
Definition: PlotCalibFromCool.py:714
PathResolver::find_file
static std::string find_file(const std::string &logical_file_name, const std::string &search_path, SearchType search_type=LocalSearch)
Definition: PathResolver.cxx:251
Monitored::Z
@ Z
Definition: HistogramFillerUtils.h:24
TRTTransitionRadiation::m_NumBins
G4int m_NumBins
Definition: TRTTransitionRadiation.h:85
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
ALFA_EventTPCnv_Dict::t1
std::vector< ALFA_RawDataCollection_p1 > t1
Definition: ALFA_EventTPCnvDict.h:43
TRTTransitionRadiation::m_MaxEnergyTR
G4double m_MaxEnergyTR
Definition: TRTTransitionRadiation.h:84
cm3
#define cm3
M_PI
#define M_PI
Definition: ActiveFraction.h:11
TRTTransitionRadiation::GetMeanFreePath
G4double GetMeanFreePath(const G4Track &aTrack, G4double, G4ForceCondition *)
Definition: TRTTransitionRadiation.cxx:246
dq_defect_virtual_defect_validation.d1
d1
Definition: dq_defect_virtual_defect_validation.py:79
LArG4GenerateShowerLib.condition
condition
Definition: LArG4GenerateShowerLib.py:19
VP1PartSpect::Gamma
@ Gamma
Definition: VP1PartSpectFlags.h:22
Phi
@ Phi
Definition: RPCdef.h:8
python.SystemOfUnits.gram
int gram
Definition: SystemOfUnits.py:165
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
TRTTransitionRadiation::m_XMLhandler
TRRegionXMLHandler * m_XMLhandler
Definition: TRTTransitionRadiation.h:79
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
JetTiledMap::S
@ S
Definition: TiledEtaPhiMap.h:44
DataHandle.h
TRTTransitionRadiation::XInteg
G4double XInteg(const G4double *yy, G4double *ss) const
Definition: TRTTransitionRadiation.cxx:614
Monitored::X
@ X
Definition: HistogramFillerUtils.h:24
python.PhysicalConstants.electron_mass_c2
float electron_mass_c2
Definition: PhysicalConstants.py:86
python.SystemOfUnits.keV
int keV
Definition: SystemOfUnits.py:156
cm
const double cm
Definition: Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/tools/FCAL_ChannelMap.cxx:25
Geo2G4MaterialFactory.h
ENDCAP
@ ENDCAP
Definition: TRTRadiatorParameters.h:10
A
TRTTransitionRadiation::ComputePhotoAbsCof
G4double ComputePhotoAbsCof(const G4Material *Material, const G4double &GammaEnergy) const
Definition: TRTTransitionRadiation.cxx:658
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
ParticleGun_EoverP_Config.mom
mom
Definition: ParticleGun_EoverP_Config.py:63
IRDBAccessSvc.h
Definition of the abstract IRDBAccessSvc interface.
TRTTransitionRadiation::m_EkinMin
G4double m_EkinMin
Definition: TRTTransitionRadiation.h:91
convertTimingResiduals.sum
sum
Definition: convertTimingResiduals.py:55
python.PhysicalConstants.hbarc
float hbarc
Definition: PhysicalConstants.py:73
lumiFormat.i
int i
Definition: lumiFormat.py:85
TRTTransitionRadiation::m_GammaMin
G4double m_GammaMin
Definition: TRTTransitionRadiation.h:90
TRRegionXMLHandler.h
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
python.LArMinBiasAlgConfig.int
int
Definition: LArMinBiasAlgConfig.py:59
file
TFile * file
Definition: tile_monitor.h:29
TRTTransitionRadiation::m_Omg
G4double * m_Omg
Definition: TRTTransitionRadiation.h:96
AthMessaging
Class to provide easy MsgStream access and capabilities.
Definition: AthMessaging.h:55
find_tgc_unfilled_channelids.ip
ip
Definition: find_tgc_unfilled_channelids.py:3
TRTTransitionRadiation::IsApplicable
G4bool IsApplicable(const G4ParticleDefinition &)
Definition: TRTTransitionRadiation.cxx:236
TRTTransitionRadiation::Initialize
void Initialize()
Definition: TRTTransitionRadiation.cxx:94
TRTTransitionRadiation::XEmitanNevski
G4double XEmitanNevski(const G4double &PhotonEnergy, const G4double &Gamma, const G4double &GasThickness, const G4double &FoilThickness) const
Definition: TRTTransitionRadiation.cxx:487
TRRegionXMLHandler
Definition: TRRegionXMLHandler.h:14
BEflag
BEflag
Definition: TRTRadiatorParameters.h:10
IRDBRecordset_ptr
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
Definition: IRDBAccessSvc.h:25
Monitored::Y
@ Y
Definition: HistogramFillerUtils.h:24
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
PathResolver.h
TRTRadiatorParameters.h
TRTTransitionRadiation::m_sigmaGas
G4double * m_sigmaGas
Definition: TRTTransitionRadiation.h:97
python.SystemOfUnits.eV
int eV
Definition: SystemOfUnits.py:155
StoredMaterialManager.h
TRTTransitionRadiation::NeffArtru
G4double NeffArtru(const G4double &sigGas, const G4double &sigFoil, const G4double &GasThickness, const G4double &FoilThickness, const G4int &FoilsTraversed) const
Definition: TRTTransitionRadiation.cxx:468
TRTTransitionRadiation.h
TRRegionXMLHandler::Process
void Process(const std::string &name)
Definition: TRRegionXMLHandler.cxx:37
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
TRTRadiatorParameters
Definition: TRTRadiatorParameters.h:12
makeTRTBarrelCans.dy
tuple dy
Definition: makeTRTBarrelCans.py:21
ALFA_EventTPCnv_Dict::t2
std::vector< ALFA_RawDataContainer_p1 > t2
Definition: ALFA_EventTPCnvDict.h:44
a
TList * a
Definition: liststreamerinfos.cxx:10
IRDBRecord.h
Definition of the abstract IRDBRecord interface.
y
#define y
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
TRTTransitionRadiation::m_WplasmaFoil
G4double m_WplasmaFoil
Definition: TRTTransitionRadiation.h:88
TRTTransitionRadiation::m_WplasmaGas
G4double m_WplasmaGas
Definition: TRTTransitionRadiation.h:87
dq_defect_virtual_defect_validation.d2
d2
Definition: dq_defect_virtual_defect_validation.py:81
F
#define F(x, y, z)
Definition: MD5.cxx:112
IRDBRecord_ptr
std::unique_ptr< IRDBRecord > IRDBRecord_ptr
Definition: IRDBRecordset.h:23
TRTTransitionRadiation::PostStepDoIt
G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep)
Definition: TRTTransitionRadiation.cxx:262
TRTTransitionRadiation::m_sigmaFoil
G4double * m_sigmaFoil
Definition: TRTTransitionRadiation.h:98
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
StoredMaterialManager::getMaterial
virtual const GeoMaterial * getMaterial(const std::string &name)=0
TRTTransitionRadiation::m_xmlfilename
const std::string m_xmlfilename
Definition: TRTTransitionRadiation.h:80
BARREL
@ BARREL
Definition: TRTRadiatorParameters.h:10
StoredMaterialManager
This class holds one or more material managers and makes them storeable, under StoreGate.
Definition: StoredMaterialManager.h:28
TRTTransitionRadiation::NeffNevski
G4double NeffNevski(const G4double &sigGas, const G4double &sigFoil, const G4double &GasThickness, const G4double &FoilThickness, const G4int &FoilsTraversed) const
Definition: TRTTransitionRadiation.cxx:451
TRTTransitionRadiation::m_Sr
G4double * m_Sr
Definition: TRTTransitionRadiation.h:94
TRTTransitionRadiation::~TRTTransitionRadiation
virtual ~TRTTransitionRadiation()
Definition: TRTTransitionRadiation.cxx:71
TRTTransitionRadiation::TRTTransitionRadiation
TRTTransitionRadiation(const G4String &processName="TransitionRadiation", const std::string &xmlfilename="TRgeomodelgeometry.xml")
Definition: TRTTransitionRadiation.cxx:48
TRTTransitionRadiation::m_om
G4double * m_om
Definition: TRTTransitionRadiation.h:95
TRTTransitionRadiation::m_Ey
G4double * m_Ey
Definition: TRTTransitionRadiation.h:93
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
IRDBRecordset.h
Definition of the abstract IRDBRecordset interface.
Trk::StepLength
@ StepLength
Definition: MaterialAssociationType.h:17
Geo2G4MaterialFactory
Definition: Geo2G4MaterialFactory.h:15
Material
@ Material
Definition: MaterialTypes.h:8
StoreGateSvc.h
TRTTransitionRadiation::m_radiators
std::vector< TRTRadiatorParameters > m_radiators
Definition: TRTTransitionRadiation.h:81
TileDCSDataPlotter.tx
tx
Definition: TileDCSDataPlotter.py:878
IGeoDbTagSvc.h
TRTTransitionRadiation::m_MinEnergyTR
G4double m_MinEnergyTR
Definition: TRTTransitionRadiation.h:83
TRTCalib_cfilter.p0
p0
Definition: TRTCalib_cfilter.py:129
jobOptions.ParticleMass
ParticleMass
Definition: jobOptions.decayer.py:86
python.handimod.cc
int cc
Definition: handimod.py:523
Geo2G4MaterialFactory::Build
G4Material * Build(const GeoMaterial *)
Definition: Geo2G4MaterialFactory.cxx:29
ymax
double ymax
Definition: listroot.cxx:64
TRTTransitionRadiation::XFinter
G4double XFinter(const G4double &X, const G4double *A, const G4double *F) const
Definition: TRTTransitionRadiation.cxx:630
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37