ATLAS Offline Software
Loading...
Searching...
No Matches
TRTTransitionRadiation Class Reference

#include <TRTTransitionRadiation.h>

Inheritance diagram for TRTTransitionRadiation:
Collaboration diagram for TRTTransitionRadiation:

Public Member Functions

 TRTTransitionRadiation (const G4String &processName="TransitionRadiation", const std::string &xmlfilename="TRgeomodelgeometry.xml")
virtual ~TRTTransitionRadiation ()
void Initialize ()
G4bool IsApplicable (const G4ParticleDefinition &)
G4double GetMeanFreePath (const G4Track &aTrack, G4double, G4ForceCondition *)
G4VParticleChange * PostStepDoIt (const G4Track &aTrack, const G4Step &aStep)
void AddRadiatorParameters (const TRTRadiatorParameters &p)
bool msgLvl (const MSG::Level lvl) const
 Test the output level.
MsgStream & msg () const
 The standard message stream.
MsgStream & msg (const MSG::Level lvl) const
 The standard message stream.
void setLevel (MSG::Level lvl)
 Change the current logging level.

Private Member Functions

 TRTTransitionRadiation (const TRTTransitionRadiation &)
TRTTransitionRadiationoperator= (const TRTTransitionRadiation &)
G4double ComputePhotoAbsCof (const G4Material *Material, const G4double &GammaEnergy) const
G4double XEmitanNevski (const G4double &PhotonEnergy, const G4double &Gamma, const G4double &GasThickness, const G4double &FoilThickness) const
G4double XEmitanArtru (const G4double &PhotonEnergy, const G4double &Gamma, const G4double &GasThickness, const G4double &FoilThickness) const
G4double NeffNevski (const G4double &sigGas, const G4double &sigFoil, const G4double &GasThickness, const G4double &FoilThickness, const G4int &FoilsTraversed) const
G4double NeffArtru (const G4double &sigGas, const G4double &sigFoil, const G4double &GasThickness, const G4double &FoilThickness, const G4int &FoilsTraversed) const
G4double XFinter (const G4double &X, const G4double *A, const G4double *F) const
G4double XInteg (const G4double *yy, G4double *ss) const
void initMessaging () const
 Initialize our message level and MessageSvc.

Private Attributes

TRRegionXMLHandlerm_XMLhandler
const std::string m_xmlfilename
std::vector< TRTRadiatorParametersm_radiators
G4double m_MinEnergyTR
G4double m_MaxEnergyTR
G4int m_NumBins
G4double m_WplasmaGas
G4double m_WplasmaFoil
G4double m_GammaMin
G4double m_EkinMin
G4double * m_Ey
G4double * m_Sr
G4double * m_om
G4double * m_Omg
G4double * m_sigmaGas
G4double * m_sigmaFoil
std::string m_nm
 Message source name.
boost::thread_specific_ptr< MsgStream > m_msg_tls
 MsgStream instance (a std::cout like with print-out levels)
std::atomic< IMessageSvc * > m_imsg { nullptr }
 MessageSvc pointer.
std::atomic< MSG::Level > m_lvl { MSG::NIL }
 Current logging level.
std::atomic_flag m_initialized ATLAS_THREAD_SAFE = ATOMIC_FLAG_INIT
 Messaging initialized (initMessaging)

Detailed Description

Definition at line 20 of file TRTTransitionRadiation.h.

Constructor & Destructor Documentation

◆ TRTTransitionRadiation() [1/2]

TRTTransitionRadiation::TRTTransitionRadiation ( const G4String & processName = "TransitionRadiation",
const std::string & xmlfilename = "TRgeomodelgeometry.xml" )

Definition at line 48 of file TRTTransitionRadiation.cxx.

48 :
49 G4VDiscreteProcess(processName,fElectromagnetic),
50 AthMessaging("TRTTransitionRadiation"),
51 m_XMLhandler(nullptr),m_xmlfilename(xmlfilename),
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}
#define ATH_MSG_DEBUG(x)
AthMessaging()
Default constructor:
std::vector< TRTRadiatorParameters > m_radiators
TRRegionXMLHandler * m_XMLhandler

◆ ~TRTTransitionRadiation()

TRTTransitionRadiation::~TRTTransitionRadiation ( )
virtual

Definition at line 71 of file TRTTransitionRadiation.cxx.

71 {
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}

◆ TRTTransitionRadiation() [2/2]

TRTTransitionRadiation::TRTTransitionRadiation ( const TRTTransitionRadiation & )
private

Member Function Documentation

◆ AddRadiatorParameters()

void TRTTransitionRadiation::AddRadiatorParameters ( const TRTRadiatorParameters & p)

Definition at line 81 of file TRTTransitionRadiation.cxx.

81 {
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}

◆ ComputePhotoAbsCof()

G4double TRTTransitionRadiation::ComputePhotoAbsCof ( const G4Material * Material,
const G4double & GammaEnergy ) const
private

Definition at line 658 of file TRTTransitionRadiation.cxx.

659 {
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}
@ Material

◆ GetMeanFreePath()

G4double TRTTransitionRadiation::GetMeanFreePath ( const G4Track & aTrack,
G4double ,
G4ForceCondition * condition )

Definition at line 246 of file TRTTransitionRadiation.cxx.

248 {
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}

◆ Initialize()

void TRTTransitionRadiation::Initialize ( )

Definition at line 94 of file TRTTransitionRadiation.cxx.

94 {
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
101 m_EkinMin = (m_GammaMin-1.)*CLHEP::electron_mass_c2;
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
193 G4double PlasmaCof(4.0*M_PI*CLHEP::fine_structure_const*CLHEP::hbarc*CLHEP::hbarc*CLHEP::hbarc/CLHEP::electron_mass_c2);
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 {
222 m_XMLhandler->Process(file);
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}
#define M_PI
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
std::shared_ptr< IRDBRecordset > IRDBRecordset_ptr
std::unique_ptr< IRDBRecord > IRDBRecord_ptr
G4Material * Build(const GeoMaterial *)
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)
virtual const GeoMaterial * getMaterial(const std::string &name)=0
G4double ComputePhotoAbsCof(const G4Material *Material, const G4double &GammaEnergy) const
TFile * file

◆ initMessaging()

void AthMessaging::initMessaging ( ) const
privateinherited

Initialize our message level and MessageSvc.

This method should only be called once.

Definition at line 39 of file AthMessaging.cxx.

40{
42 // If user did not set an explicit level, set a default
43 if (m_lvl == MSG::NIL) {
44 m_lvl = m_imsg ?
45 static_cast<MSG::Level>( m_imsg.load()->outputLevel(m_nm) ) :
46 MSG::INFO;
47 }
48}
std::string m_nm
Message source name.
std::atomic< IMessageSvc * > m_imsg
MessageSvc pointer.
std::atomic< MSG::Level > m_lvl
Current logging level.
IMessageSvc * getMessageSvc(bool quiet=false)

◆ IsApplicable()

G4bool TRTTransitionRadiation::IsApplicable ( const G4ParticleDefinition & particle)

Definition at line 236 of file TRTTransitionRadiation.cxx.

236 {
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}
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses

◆ msg() [1/2]

MsgStream & AthMessaging::msg ( ) const
inlineinherited

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 163 of file AthMessaging.h.

164{
165 MsgStream* ms = m_msg_tls.get();
166 if (!ms) {
167 if (!m_initialized.test_and_set()) initMessaging();
168 ms = new MsgStream(m_imsg,m_nm);
169 m_msg_tls.reset( ms );
170 }
171
172 ms->setLevel (m_lvl);
173 return *ms;
174}
boost::thread_specific_ptr< MsgStream > m_msg_tls
MsgStream instance (a std::cout like with print-out levels)
void initMessaging() const
Initialize our message level and MessageSvc.

◆ msg() [2/2]

MsgStream & AthMessaging::msg ( const MSG::Level lvl) const
inlineinherited

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 178 of file AthMessaging.h.

179{ return msg() << lvl; }
MsgStream & msg() const
The standard message stream.

◆ msgLvl()

bool AthMessaging::msgLvl ( const MSG::Level lvl) const
inlineinherited

Test the output level.

Parameters
lvlThe message level to test against
Returns
boolean Indicating if messages at given level will be printed
Return values
trueMessages at level "lvl" will be printed

Definition at line 151 of file AthMessaging.h.

152{
153 if (m_lvl <= lvl) {
154 msg() << lvl;
155 return true;
156 } else {
157 return false;
158 }
159}

◆ NeffArtru()

G4double TRTTransitionRadiation::NeffArtru ( const G4double & sigGas,
const G4double & sigFoil,
const G4double & GasThickness,
const G4double & FoilThickness,
const G4int & FoilsTraversed ) const
inlineprivate

Definition at line 468 of file TRTTransitionRadiation.cxx.

472 {
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}

◆ NeffNevski()

G4double TRTTransitionRadiation::NeffNevski ( const G4double & sigGas,
const G4double & sigFoil,
const G4double & GasThickness,
const G4double & FoilThickness,
const G4int & FoilsTraversed ) const
inlineprivate

Definition at line 451 of file TRTTransitionRadiation.cxx.

455 {
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}

◆ operator=()

TRTTransitionRadiation & TRTTransitionRadiation::operator= ( const TRTTransitionRadiation & )
private

◆ PostStepDoIt()

G4VParticleChange * TRTTransitionRadiation::PostStepDoIt ( const G4Track & aTrack,
const G4Step & aStep )

Definition at line 262 of file TRTTransitionRadiation.cxx.

263 {
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}
#define ATH_MSG_VERBOSE(x)
@ Phi
Definition RPCdef.h:8
G4double NeffNevski(const G4double &sigGas, const G4double &sigFoil, const G4double &GasThickness, const G4double &FoilThickness, const G4int &FoilsTraversed) const
G4double XFinter(const G4double &X, const G4double *A, const G4double *F) const
G4double XInteg(const G4double *yy, G4double *ss) const
G4double XEmitanNevski(const G4double &PhotonEnergy, const G4double &Gamma, const G4double &GasThickness, const G4double &FoilThickness) const
G4double NeffArtru(const G4double &sigGas, const G4double &sigFoil, const G4double &GasThickness, const G4double &FoilThickness, const G4int &FoilsTraversed) const
G4double XEmitanArtru(const G4double &PhotonEnergy, const G4double &Gamma, const G4double &GasThickness, const G4double &FoilThickness) const

◆ setLevel()

void AthMessaging::setLevel ( MSG::Level lvl)
inherited

Change the current logging level.

Use this rather than msg().setLevel() for proper operation with MT.

Definition at line 28 of file AthMessaging.cxx.

29{
30 m_lvl = lvl;
31}

◆ XEmitanArtru()

G4double TRTTransitionRadiation::XEmitanArtru ( const G4double & PhotonEnergy,
const G4double & Gamma,
const G4double & GasThickness,
const G4double & FoilThickness ) const
inlineprivate

Definition at line 543 of file TRTTransitionRadiation.cxx.

546 {
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}
static Double_t a
#define y
double ymax
Definition listroot.cxx:64
std::vector< ALFA_RawDataContainer_p1 > t2
std::vector< ALFA_RawDataCollection_p1 > t1

◆ XEmitanNevski()

G4double TRTTransitionRadiation::XEmitanNevski ( const G4double & PhotonEnergy,
const G4double & Gamma,
const G4double & GasThickness,
const G4double & FoilThickness ) const
inlineprivate

Definition at line 487 of file TRTTransitionRadiation.cxx.

490 {
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}

◆ XFinter()

G4double TRTTransitionRadiation::XFinter ( const G4double & X,
const G4double * A,
const G4double * F ) const
private

Definition at line 630 of file TRTTransitionRadiation.cxx.

630 {
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}
#define F(x, y, z)
Definition MD5.cxx:112

◆ XInteg()

G4double TRTTransitionRadiation::XInteg ( const G4double * yy,
G4double * ss ) const
inlineprivate

Definition at line 614 of file TRTTransitionRadiation.cxx.

614 {
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}
static Double_t ss

Member Data Documentation

◆ ATLAS_THREAD_SAFE

std::atomic_flag m_initialized AthMessaging::ATLAS_THREAD_SAFE = ATOMIC_FLAG_INIT
mutableprivateinherited

Messaging initialized (initMessaging)

Definition at line 141 of file AthMessaging.h.

◆ m_EkinMin

G4double TRTTransitionRadiation::m_EkinMin
private

Definition at line 91 of file TRTTransitionRadiation.h.

◆ m_Ey

G4double* TRTTransitionRadiation::m_Ey
private

Definition at line 93 of file TRTTransitionRadiation.h.

◆ m_GammaMin

G4double TRTTransitionRadiation::m_GammaMin
private

Definition at line 90 of file TRTTransitionRadiation.h.

◆ m_imsg

std::atomic<IMessageSvc*> AthMessaging::m_imsg { nullptr }
mutableprivateinherited

MessageSvc pointer.

Definition at line 135 of file AthMessaging.h.

135{ nullptr };

◆ m_lvl

std::atomic<MSG::Level> AthMessaging::m_lvl { MSG::NIL }
mutableprivateinherited

Current logging level.

Definition at line 138 of file AthMessaging.h.

138{ MSG::NIL };

◆ m_MaxEnergyTR

G4double TRTTransitionRadiation::m_MaxEnergyTR
private

Definition at line 84 of file TRTTransitionRadiation.h.

◆ m_MinEnergyTR

G4double TRTTransitionRadiation::m_MinEnergyTR
private

Definition at line 83 of file TRTTransitionRadiation.h.

◆ m_msg_tls

boost::thread_specific_ptr<MsgStream> AthMessaging::m_msg_tls
mutableprivateinherited

MsgStream instance (a std::cout like with print-out levels)

Definition at line 132 of file AthMessaging.h.

◆ m_nm

std::string AthMessaging::m_nm
privateinherited

Message source name.

Definition at line 129 of file AthMessaging.h.

◆ m_NumBins

G4int TRTTransitionRadiation::m_NumBins
private

Definition at line 85 of file TRTTransitionRadiation.h.

◆ m_om

G4double* TRTTransitionRadiation::m_om
private

Definition at line 95 of file TRTTransitionRadiation.h.

◆ m_Omg

G4double* TRTTransitionRadiation::m_Omg
private

Definition at line 96 of file TRTTransitionRadiation.h.

◆ m_radiators

std::vector<TRTRadiatorParameters> TRTTransitionRadiation::m_radiators
private

Definition at line 81 of file TRTTransitionRadiation.h.

◆ m_sigmaFoil

G4double* TRTTransitionRadiation::m_sigmaFoil
private

Definition at line 98 of file TRTTransitionRadiation.h.

◆ m_sigmaGas

G4double* TRTTransitionRadiation::m_sigmaGas
private

Definition at line 97 of file TRTTransitionRadiation.h.

◆ m_Sr

G4double* TRTTransitionRadiation::m_Sr
private

Definition at line 94 of file TRTTransitionRadiation.h.

◆ m_WplasmaFoil

G4double TRTTransitionRadiation::m_WplasmaFoil
private

Definition at line 88 of file TRTTransitionRadiation.h.

◆ m_WplasmaGas

G4double TRTTransitionRadiation::m_WplasmaGas
private

Definition at line 87 of file TRTTransitionRadiation.h.

◆ m_xmlfilename

const std::string TRTTransitionRadiation::m_xmlfilename
private

Definition at line 80 of file TRTTransitionRadiation.h.

◆ m_XMLhandler

TRRegionXMLHandler* TRTTransitionRadiation::m_XMLhandler
private

Definition at line 79 of file TRTTransitionRadiation.h.


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