ATLAS Offline Software
TRTTransitionRadiation.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 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  StoreGateSvc *detStore(nullptr);
117  if( StatusCode::SUCCESS != svcLocator->service( "DetectorStore", detStore ) ) {
118  errorMessage = "Can not access Detector Store";
119  ATH_MSG_FATAL (errorMessage);
120  throw std::runtime_error(errorMessage);
121  };
122  StoredMaterialManager* materialManager = detStore->tryRetrieve<StoredMaterialManager>("MATERIALS");
123  if(materialManager) {
124  Geo2G4MaterialFactory geo2g4_material_fact;//Note - this is a very lightweight class!
125  g4mat_Gas = geo2g4_material_fact.Build(materialManager->getMaterial("trt::CO2"));
126  g4mat_FoilMaterial = geo2g4_material_fact.Build(materialManager->getMaterial("trt::CH2"));
127 
128  //Note: One might wonder if we now own g4mat_Gas and
129  //g4mat_FoilMaterial, but since the elementfactory used inside
130  //Geo2G4MaterialFactory is static, we must NOT delete them!!
131  }
132  else {
133  ATH_MSG_INFO("GeoModel Material is not available. Construct TR materials using IRDBAccessSvc interface");
134  IGeoDbTagSvc *geoDbTagSvc{nullptr};
135  if(StatusCode::SUCCESS != svcLocator->service("GeoDbTagSvc",geoDbTagSvc)) {
136  errorMessage = "Can not access GeoDbTagSvc";
137  ATH_MSG_FATAL (errorMessage);
138  throw std::runtime_error(errorMessage);
139 
140  return;
141  };
142  IRDBAccessSvc *pAccessSvc{nullptr};
143  if(StatusCode::SUCCESS != svcLocator->service(geoDbTagSvc->getParamSvcName(),pAccessSvc)) {
144  errorMessage = "Can not access " + geoDbTagSvc->getParamSvcName();
145  ATH_MSG_FATAL (errorMessage);
146  throw std::runtime_error(errorMessage);
147  }
148 
149  std::map<std::string,int> materialComponentsMap; // Number of elements for each material
150  std::map<std::string,G4Material*> materialMap;
151  IRDBRecordset_ptr materialsRec = pAccessSvc->getRecordsetPtr("TRMaterials","","");
152  // Step #1. Count elements per material
153  for(const IRDBRecord_ptr& material : *materialsRec) {
154  std::string key = material->getString("NAME");
155  auto mapIt = materialComponentsMap.find(key);
156  if(mapIt == materialComponentsMap.end()) {
157  materialComponentsMap.emplace(key,1);
158  }
159  else {
160  materialComponentsMap.at(key) = mapIt->second + 1;
161  }
162  }
163  // Step #2. Build materials
164  for(const IRDBRecord_ptr& material :*materialsRec) {
165  std::string key = material->getString("NAME");
166  G4Material* g4Material{nullptr};
167  if(materialMap.find(key)==materialMap.end()) {
168  auto itNElements = materialComponentsMap.find(key);
169  g4Material = new G4Material(key
170  ,material->getDouble("DENSITY")*(CLHEP::gram / CLHEP::cm3)
171  ,itNElements->second);
172  materialMap.emplace(key,g4Material);
173  }
174  else {
175  g4Material = materialMap.at(key);
176  }
177 
178  G4Element* g4Element = G4Element::GetElement(material->getString("ELEMENT_NAME"));
179  if(!g4Element) {
180  errorMessage = "Wrong name for element " + material->getString("ELEMENT_NAME")
181  + " found in the description of material " + key;
182  ATH_MSG_FATAL (errorMessage);
183  throw std::runtime_error(errorMessage);
184  }
185  g4Material->AddElement(g4Element,(G4int)material->getInt("N"));
186  }
187  g4mat_Gas = materialMap.at("CO2");
188  g4mat_FoilMaterial = materialMap.at("CH2");
189  }
190 
192 
193  // Plate and gas indicies
194  m_WplasmaFoil = sqrt( PlasmaCof * g4mat_FoilMaterial->GetElectronDensity() );
195  m_WplasmaGas = sqrt( PlasmaCof * g4mat_Gas->GetElectronDensity() );
196 
197  ATH_MSG_DEBUG("Foil material : " << g4mat_FoilMaterial->GetName()
198  << "; plasma energy : " << m_WplasmaFoil/CLHEP::eV << " eV");
199  ATH_MSG_DEBUG("Gas : " << g4mat_Gas->GetName()
200  << "; plasma energy : " << m_WplasmaGas/CLHEP::eV << " eV");
201 
202  m_Omg = new G4double[m_NumBins];
203  m_om = new G4double[m_NumBins];
204  m_Ey = new G4double[m_NumBins];
205  m_Sr = new G4double[m_NumBins];
206  m_sigmaGas = new G4double[m_NumBins];
207  m_sigmaFoil = new G4double[m_NumBins];
208 
209  for(G4int j(0); j<m_NumBins; ++j) {
210  m_Omg[j] = log( m_MinEnergyTR ) +
212  m_om [j] = exp( m_Omg[j] );
213  m_sigmaGas[j] = ComputePhotoAbsCof( g4mat_Gas, m_om[j] );
214  m_sigmaFoil[j] = ComputePhotoAbsCof( g4mat_FoilMaterial, m_om[j] );
215  }
216 
217  const std::string file=PathResolver::find_file(m_xmlfilename,"DATAPATH");
218  if (!file.empty())
219  {
221  }
222  else ATH_MSG_WARNING("File "<<m_xmlfilename<<" not found! Expect problems.");
223 
224  ATH_MSG_DEBUG ( "Constructor TRTTransitionRadiation::Initialize() DONE!" );
225  return;
226 
227 }
228 
230 //
231 // Returns condition for application of the model depending on particle type
232 
233 
234 G4bool TRTTransitionRadiation::IsApplicable(const G4ParticleDefinition& particle) {
235  //return true if PDG Charge and PDG Mass are non-zero.
236  return ( std::abs(particle.GetPDGCharge())>std::numeric_limits<double>::epsilon() && std::abs(particle.GetPDGMass())>std::numeric_limits<double>::epsilon() ) ;
237 }
238 
240 //
241 // GetContinuousStepLimit
242 //
243 
244 G4double TRTTransitionRadiation::GetMeanFreePath(const G4Track& aTrack,
245  G4double,
246  G4ForceCondition* condition) {
247  const G4DynamicParticle *aParticle(aTrack.GetDynamicParticle());
248  if(std::abs(aParticle->GetDefinition()->GetPDGCharge())< std::numeric_limits<double>::epsilon() ||
249  std::abs(aParticle->GetDefinition()->GetPDGMass())<std::numeric_limits<double>::epsilon() ) {
250  *condition = NotForced;
251  } else {
252  *condition = Forced;
253  }
254  return DBL_MAX;
255 }
256 
258 //
259 //
260 G4VParticleChange* TRTTransitionRadiation::PostStepDoIt( const G4Track& aTrack,
261  const G4Step& aStep ) {
262  aParticleChange.Initialize(aTrack);
263 
264  // Obtain kinetic energy
265  const G4DynamicParticle *aParticle(aTrack.GetDynamicParticle());
266  G4double KineticEnergy(aParticle->GetKineticEnergy());
267 
268  // Kinetic energy too low for TR generation for any kind of particle
269  if ( KineticEnergy < m_EkinMin )
270  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
271 
272  // Particle properties ...
273  G4double ParticleMass(aParticle->GetDefinition()->GetPDGMass());
274  G4double Gamma(1.0 + KineticEnergy/ParticleMass);
275 
276  if( Gamma < m_GammaMin ) {
277  ATH_MSG_VERBOSE ( "Leaving PostStepDoIt(): Gamma < " << m_GammaMin );
278  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
279  }
280 
281  G4double FoilThickness(0.);
282  G4double GasThickness(0.);
283  BEflag BEflag(BARREL); //enum?
284 
285  // Check whether particle is inside radiator
286  std::vector<TRTRadiatorParameters>::const_iterator currentRadiator(m_radiators.begin());
287  const std::vector<TRTRadiatorParameters>::const_iterator endOfRadiators(m_radiators.end());
288  while(currentRadiator!=endOfRadiators) {
289  if ( currentRadiator->GetLogicalVolume() ==
290  aTrack.GetVolume()->GetLogicalVolume() ) {
291  FoilThickness = currentRadiator->GetFoilThickness();
292  GasThickness = currentRadiator->GetGasThickness();
293  BEflag = currentRadiator->GetBEflag();
294  break;
295  }
296  ++currentRadiator;
297  }
298  // Particle not inside radiator - return
299  if ( currentRadiator == endOfRadiators ) {
300  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
301  }
302 
303  ATH_MSG_VERBOSE ( "PostStepDoIt(): Inside radiator "
304  << currentRadiator->GetLogicalVolume()->GetName() );
305 
306  G4ThreeVector ParticleDirection(aParticle->GetMomentumDirection());
307 
308  if ( BEflag == ENDCAP ) {
309  G4double costh(std::abs(ParticleDirection[2]));
310  FoilThickness /= costh;
311  GasThickness /= costh;
312  }
313 
314  G4double StepLength(aStep.GetStepLength());
315  G4int FoilsTraversed(static_cast<G4int>(StepLength/(FoilThickness+GasThickness)+0.5));
316 
317  // Steplength so short, that no foils are crossed.
318  // Forget it...
319  // Actually the treatment we do is only valid for "many" foils.
320  // Should we put this requirement higher?
321  if ( FoilsTraversed == 0 ) {
322  ATH_MSG_VERBOSE ( "Leaving PostStepDoIt(): No foils traversed." );
323  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
324  }
325 
326  G4double Gy(0.), Gmany(0.), Neff(0.);
327 
328  // Generate, in the language of Artru:
329  // 1) G_y
330  // 2) N_{eff}
331  // 3) G_{many}
332  // Divide by photon energy to get photon spectrum (m_Ey)
333 
334  for( G4int i(0); i<m_NumBins; ++i ) {
335 
336 #ifdef ARTRU // Formulas from Artru
337  Gy = XEmitanArtru( m_om[i],
338  Gamma,
339  GasThickness,
340  FoilThickness );
341  Neff = NeffArtru( m_sigmaGas[i],
342  m_sigmaFoil[i],
343  GasThickness,
344  FoilThickness,
345  FoilsTraversed );
346 #else
347  Gy = XEmitanNevski( m_om[i], // Formulas from Cherry via
348  Gamma, // Pavel Nevski in G3
349  GasThickness,
350  FoilThickness );
351  Neff = NeffNevski( m_sigmaGas[i],
352  m_sigmaFoil[i],
353  GasThickness,
354  FoilThickness,
355  FoilsTraversed );
356 #endif
357 
358  Gmany = Neff*Gy; // Energy spectrum
359  m_Ey[i] = Gmany / m_om[i]; // Photon spectrum
360 
361  }
362 
363  // Integrate spectrum
364  G4double Sph(XInteg( m_Ey, m_Sr ));
365  G4double Sph_org(Sph);
366 
367  if ( ( BEflag == BARREL ) && (Gamma > 0.0) ) {
368  G4double tempLog10Gamma(log10(Gamma)); //Hardcoded numbers from TestBeam study (E.Klinkby). Better to move elsewhere.
369  G4double pHT_dEdxData = -0.001 + 0.0005*tempLog10Gamma;
370  G4double pHT_TRData = 0.15/(1.0 + exp(-(tempLog10Gamma - 3.3)/0.27));
371  G4double pHT_dEdxMC = -0.0031 + 0.00016*tempLog10Gamma;
372  G4double pHT_TRMC = 0.1289/(1.0 + exp(-(tempLog10Gamma - 3.01)/0.1253));
373 
374  G4double fudge = std::min(2.0,(pHT_dEdxData+pHT_TRData)/( pHT_dEdxMC+pHT_TRMC));
375 
376  Sph *= fudge;
377  }
378 
379  // Now how many photons are generated?
380  G4long NumberOfPhotonsGenerated(CLHEP::RandPoisson::shoot(Sph));
381 
382  //reset Sph to original value.
383  Sph = Sph_org;
384 
385  ATH_MSG_VERBOSE ( ">>>> FoilsTraversed = " << FoilsTraversed
386  << ", Gamma = " << Gamma
387  << ", Sph = " << Sph
388  << ", Nph = " << NumberOfPhotonsGenerated );
389  // No photons, return
390  if ( NumberOfPhotonsGenerated <= 0 ) {
391  ATH_MSG_VERBOSE ( "Leaving TRTTransitionRadiation::PostStepDoIt: "
392  << "No photons generated." );
393 
394  return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
395  }
396 
397  // Now, generate the photons
398  aParticleChange.SetNumberOfSecondaries( NumberOfPhotonsGenerated );
399  G4StepPoint *pPostStepPoint(aStep.GetPostStepPoint());
400  G4ThreeVector x0(pPostStepPoint->GetPosition());
401 
402  G4double Esum(0.), XRannu(0.), Ephot(0.), Theta(0.), Phi(0.),
403  X(0.), Y(0.), Z(0.);
404 
405  G4ThreeVector pos(0),TRPhotonDirection(0);
406 
407  for( G4int i(0); i<NumberOfPhotonsGenerated; ++i ) {
408  XRannu = CLHEP::RandFlat::shoot();
409  Ephot = exp( XFinter( XRannu*Sph, m_Sr, m_Omg ) );
410 
411  Esum += Ephot;
412 
413  pos = pPostStepPoint->GetPosition();
414 
415  ATH_MSG_VERBOSE ( " Photon generated with energy : " << Ephot/CLHEP::keV
416  << " keV; position: ( " << pos.x()/CLHEP::cm << " cm, "
417  << pos.y()/CLHEP::cm << " cm, " << pos.z()/CLHEP::cm << " cm )" );
418 
419  // Angle w.r.t. electron direction (this is not correct but anyway...)
420  Theta = std::abs( CLHEP::RandGaussZiggurat::shoot( 0.0, M_PI/Gamma ) );
421  if( Theta >= 0.1 ) Theta = 0.1;
422 
423  Phi = (2.*M_PI)*CLHEP::RandFlat::shoot();
424 
425  X = sin(Theta)*cos(Phi);
426  Y = sin(Theta)*sin(Phi);
427  Z = cos(Theta);
428 
429  TRPhotonDirection.set(X,Y,Z);
430  TRPhotonDirection.rotateUz( ParticleDirection );
431  TRPhotonDirection.unit();
432 
433  G4DynamicParticle*
434  TRPhoton = new G4DynamicParticle( G4Gamma::Gamma(),
435  TRPhotonDirection,
436  Ephot );
437  aParticleChange.AddSecondary( TRPhoton );
438 
439  }
440 
441  aParticleChange.ProposeEnergy( KineticEnergy-Esum );
442 
443  ATH_MSG_VERBOSE ( "Leaving TRTTransitionRadiation::PostStepDoIt; "
444  << "Number of TR photons generated: " << NumberOfPhotonsGenerated );
445 
446  return &aParticleChange;
447 }
448 
449 inline G4double TRTTransitionRadiation::NeffNevski( const G4double & sigGas,
450  const G4double & sigFoil,
451  const G4double & GasThickness,
452  const G4double & FoilThickness,
453  const G4int & FoilsTraversed ) const {
454  if ( FoilsTraversed <= 0 )
455  return 0.;
456 
457  G4double C1 = sigGas * GasThickness*FoilsTraversed;
458  G4double C2 = sigFoil*FoilThickness*FoilsTraversed;
459 
460  G4double W1 = exp(-C1);
461  G4double W2 = exp(-C2);
462 
463  return FoilsTraversed * (1-W1*W2)/(C1+C2);
464 }
465 
466 inline G4double TRTTransitionRadiation::NeffArtru( const G4double & sigGas,
467  const G4double & sigFoil,
468  const G4double & GasThickness,
469  const G4double & FoilThickness,
470  const G4int & FoilsTraversed ) const {
471  if ( FoilsTraversed <= 0 )
472  return 0.;
473 
474  G4double sigma = FoilThickness*sigFoil + GasThickness*sigGas;
475  G4double xNF = FoilsTraversed;
476  return (1.-exp(-xNF*sigma))/(1.-exp(-sigma));
477 }
478 
480 //
481 // Nevskis XEmitan-function
482 //
483 //inline G4double max(G4double a, G4double b) {return a>b?a:b;}
484 
485 inline G4double TRTTransitionRadiation::XEmitanNevski( const G4double & PhotonEnergy,
486  const G4double & Gamma,
487  const G4double & Al1,
488  const G4double & Al2 ) const {
489  //FIXME hardcoded numbers are not good.
490  G4double eps = 0.05;
491 
492  G4double Al = Al1 + Al2;
493 
494  G4double CK = 1/(2*M_PI*CLHEP::hbarc);
495 
496  // Plasma frequencies:
497  G4double om1 = m_WplasmaGas;
498  G4double om2 = m_WplasmaFoil;
499 
500  G4double om12 = (om1*om1-om2*om2)/PhotonEnergy;
501  G4double oms = (Al1*om1*om1+Al2*om2*om2)/Al;
502  G4double Ao = 0.5*Al1*om12*CK;
503  G4double Bo = 0.5*Al2*om12*CK;
504  G4double ro = sqrt(oms)/Gamma;
505  G4double co = 0.5*(PhotonEnergy/(Gamma*Gamma)+oms/PhotonEnergy);
506  G4double cc = co*Al*CK;
507  G4double cb = M_PI*Al2/Al;
508  G4int i1 = static_cast<G4int>(1.0+(ro>co?ro:co)*Al*CK);//(G4int)(1.0+max(ro,co)*Al*CK);
509  G4int i2 = static_cast<G4int>(Gamma*ro*Al*CK);
510 
511  G4double Sum = 0.0;
512  G4double Smx = 0.0;
513  G4double Sm1 = 0.0;
514  G4double S = 0.0;
515  G4double So = 0.0;
516 
517  G4double Sx = 0.0;
518 
519  for(G4int i(i1); i<=i2; ++i) {
520  Sx = So;
521  So = S;
522  S = (static_cast<G4double>(i)-cc)*(sin(cb*(static_cast<G4double>(i)-Ao))/((static_cast<G4double>(i)-Ao)*(static_cast<G4double>(i)+Bo)))*
523  (sin(cb*(static_cast<G4double>(i)-Ao))/((static_cast<G4double>(i)-Ao)*(static_cast<G4double>(i)+Bo)));
524  Smx=Smx>S?Smx:S;//max(Smx,S);
525  Sm1=Sm1>S?Sm1:S;//max(Sm1,S);
526  Sum += S;
527 
528  if( (So<Sx)&&(So<=S) ) {
529  if( Sm1<eps*Smx ) break;
530  Sm1 = 0.0;
531  }
532  }
533 
534  return ( CLHEP::fine_structure_const*om12*om12*Al*Al*CK*CK*Sum/M_PI );
535 }
536 
538 //
539 // Same as above but for the Artru way of doing things
540 //
541 inline G4double TRTTransitionRadiation::XEmitanArtru( const G4double & omega,
542  const G4double & Gamma,
543  const G4double & d2,
544  const G4double & d1 ) const {
545  G4double phimax = 4.*M_PI;
546  G4double ginv2 = 1./(Gamma*Gamma);
547  G4double tau = d2/d1;
548 
549  G4double mom = omega/CLHEP::hbarc;
550 
551  G4double xi1 = m_WplasmaFoil/omega;
552  G4double xi2 = m_WplasmaGas/omega;
553 
554  G4double xi1sq = xi1*xi1;
555  G4double xi2sq = xi2*xi2;
556 
557  G4double Z1 = 2./(mom*(ginv2+xi1sq));
558  G4double Z2 = 2./(mom*(ginv2+xi2sq));
559 
560  G4double a = d1/Z2;
561  G4double V = d1*(1./Z1-1./Z2);
562 
563  G4double p0 = mom*d1*(xi1sq-xi2sq)/(4.*M_PI);
564  G4double pmin = p0 + a*(1.+tau)/(2.*M_PI);
565  G4double ymax = tau*phimax;
566  G4double pmax = p0 + ymax*(1.+tau)/(2.*M_PI);
567 
568  G4int ipmin = (int)pmin+1;
569  G4int ipmax = (int)pmax;
570 
571  G4double sum=0.;
572  G4double y0 = -0.5*mom*d1*(xi1sq-xi2sq)/(1+tau);
573  G4double dy = (2.*M_PI)/(1+tau);
574  G4double y;
575 
576  G4double term = 0.;
577  G4double t1 = 0.;
578  G4double t2 = 0.;
579  G4double tx = 0.;
580 
581  for ( G4int ip(ipmin); ip<=ipmax; ++ip ) {
582  t2 = t1;
583  t1 = term;
584 
585  y = y0 + ip*dy;
586  term = (1./y-1./(y+V))*sin(0.5*(y+V));
587  term *= term;
588  term *= y-a;
589  sum += term;
590 
591  //G4double theta2 = 2.*y*tau/(mom*d2) - ginv2 - xi2sq;
592  //G4double theta = sqrt(theta2);
593 
594  tx = (tx>term) ? tx : term;
595 
596  // Locate local maxima (previous term)
597 
598  if ( t2 > 0. && t1 > term && t1 > t2 ) {
599  if ( t1 < 0.0001*sum ) break;
600  }
601  }
602 
603  return ( sum*4.*2.*CLHEP::fine_structure_const/(1.+tau));
604 }
605 
607 //
608 // Nevskis XInteg function
609 // Spectrum integration
610 //
611 
612 inline G4double TRTTransitionRadiation::XInteg( const G4double * yy, G4double * ss ) const {
613  G4double S(0.);
614  ss[0] = 0.;
615 
616  for( G4int i(1); i<m_NumBins; ++i ) {
617  S += 0.5*( m_Omg[i]-m_Omg[i-1] )*( yy[i-1]*m_om[i-1] + yy[i]*m_om[i] );
618  ss[i] = S;
619  }
620 
621  return S;
622 }
623 
625 //
626 // Nevskis XFINTER function
627 
628 G4double TRTTransitionRadiation::XFinter( const G4double & X, const G4double* A, const G4double* F ) const {
629  G4int K1(0);
630  G4int K2(0);
631 
632  if( (K1>=m_NumBins) || ( X < A[K1] ) ) K1 = 0; //FIXME This line has no effect?
633  if( (K2>=m_NumBins) || ( X > A[K2] ) ) K2 = m_NumBins-1;
634 
635  G4int K(0);
636  while( K2-K1>1 ) {
637  K = static_cast<G4int>((K1+K2)/2);
638  if( A[K]<X ) {
639  K1 = K;
640  } else {
641  K2 = K;
642  }
643  }
644 
645  G4double X1(A[K1]);
646  G4double X2(A[K1+1]);
647 
648  G4double xfinter((F[K1]*(X-X2)+F[K1+1]*(X1-X))/(X1-X2));
649  return xfinter;
650 }
651 
653 //
654 // Computes Sandia photo absorption cross section coefficients for Material
655 
657  const G4double & PhotonEnergy ) const {
658 
659  const G4double *SandiaCof(Material->GetSandiaTable()->GetSandiaCofForMaterial(PhotonEnergy));
660 
661  const G4double Energy2(PhotonEnergy*PhotonEnergy);
662  const G4double Energy3(PhotonEnergy*Energy2);
663  const G4double Energy4(Energy2*Energy2);
664 
665  return ( SandiaCof[0]/PhotonEnergy +
666  SandiaCof[1]/Energy2 +
667  SandiaCof[2]/Energy3 +
668  SandiaCof[3]/Energy4 );
669 }
TRTTransitionRadiation::XEmitanArtru
G4double XEmitanArtru(const G4double &PhotonEnergy, const G4double &Gamma, const G4double &GasThickness, const G4double &FoilThickness) const
Definition: TRTTransitionRadiation.cxx:541
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
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
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
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
Monitored::Z
@ Z
Definition: HistogramFillerUtils.h:24
TRTTransitionRadiation::m_NumBins
G4int m_NumBins
Definition: TRTTransitionRadiation.h:89
ALFA_EventTPCnv_Dict::t1
std::vector< ALFA_RawDataCollection_p1 > t1
Definition: ALFA_EventTPCnvDict.h:43
TRTTransitionRadiation::m_MaxEnergyTR
G4double m_MaxEnergyTR
Definition: TRTTransitionRadiation.h:88
cm3
#define cm3
M_PI
#define M_PI
Definition: ActiveFraction.h:11
TRTTransitionRadiation::GetMeanFreePath
G4double GetMeanFreePath(const G4Track &aTrack, G4double, G4ForceCondition *)
Definition: TRTTransitionRadiation.cxx:244
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:83
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:612
Monitored::X
@ X
Definition: HistogramFillerUtils.h:24
python.PhysicalConstants.electron_mass_c2
float electron_mass_c2
Definition: PhysicalConstants.py:86
dqt_zlumi_alleff_HIST.A
A
Definition: dqt_zlumi_alleff_HIST.py:110
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
StoreGateSvc
The Athena Transient Store API.
Definition: StoreGateSvc.h:128
TRTTransitionRadiation::ComputePhotoAbsCof
G4double ComputePhotoAbsCof(const G4Material *Material, const G4double &GammaEnergy) const
Definition: TRTTransitionRadiation.cxx:656
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:95
TRTTransitionRadiation::AddRadiatorParameters
void AddRadiatorParameters(TRTRadiatorParameters p)
Definition: TRTTransitionRadiation.cxx:81
convertTimingResiduals.sum
sum
Definition: convertTimingResiduals.py:55
python.PhysicalConstants.hbarc
float hbarc
Definition: PhysicalConstants.py:73
lumiFormat.i
int i
Definition: lumiFormat.py:92
TRTTransitionRadiation::m_GammaMin
G4double m_GammaMin
Definition: TRTTransitionRadiation.h:94
TRRegionXMLHandler.h
IRDBAccessSvc
IRDBAccessSvc is an abstract interface to the athena service that provides the following functionalit...
Definition: IRDBAccessSvc.h:45
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
file
TFile * file
Definition: tile_monitor.h:29
TRTTransitionRadiation::m_Omg
G4double * m_Omg
Definition: TRTTransitionRadiation.h:100
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:234
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:485
TRRegionXMLHandler
Definition: TRRegionXMLHandler.h:14
IGeoDbTagSvc
Definition: IGeoDbTagSvc.h:26
BEflag
BEflag
Definition: TRTRadiatorParameters.h:10
IRDBRecordset_ptr
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
Definition: IRDBAccessSvc.h:25
min
#define min(a, b)
Definition: cfImp.cxx:40
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:101
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:466
TRTTransitionRadiation.h
TRRegionXMLHandler::Process
void Process(const std::string &name)
Definition: TRRegionXMLHandler.cxx:39
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:92
TRTTransitionRadiation::m_WplasmaGas
G4double m_WplasmaGas
Definition: TRTTransitionRadiation.h:91
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:260
TRTTransitionRadiation::m_sigmaFoil
G4double * m_sigmaFoil
Definition: TRTTransitionRadiation.h:102
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:84
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:449
TRTTransitionRadiation::m_Sr
G4double * m_Sr
Definition: TRTTransitionRadiation.h:98
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:99
TRTTransitionRadiation::m_Ey
G4double * m_Ey
Definition: TRTTransitionRadiation.h:97
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:85
TileDCSDataPlotter.tx
tx
Definition: TileDCSDataPlotter.py:878
IGeoDbTagSvc.h
TRTTransitionRadiation::m_MinEnergyTR
G4double m_MinEnergyTR
Definition: TRTTransitionRadiation.h:87
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:628
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37