94 ATH_MSG_DEBUG (
"Constructor TRTTransitionRadiation::Initialize()" );
109 G4Material* g4mat_Gas{
nullptr};
110 G4Material* g4mat_FoilMaterial{
nullptr};
111 std::string errorMessage;
114 ISvcLocator *svcLocator = Gaudi::svcLocator();
115 SmartIF<StoreGateSvc> detStore{svcLocator->service(
"DetectorStore")};
117 errorMessage =
"Can not access Detector Store";
119 throw std::runtime_error(errorMessage);
123 if(materialManager) {
125 g4mat_Gas = geo2g4_material_fact.
Build(materialManager->
getMaterial(
"trt::CO2"));
126 g4mat_FoilMaterial = geo2g4_material_fact.
Build(materialManager->
getMaterial(
"trt::CH2"));
133 ATH_MSG_INFO(
"GeoModel Material is not available. Construct TR materials using IRDBAccessSvc interface");
134 SmartIF<IGeoDbTagSvc> geoDbTagSvc{svcLocator->service(
"GeoDbTagSvc")};
136 errorMessage =
"Can not access GeoDbTagSvc";
138 throw std::runtime_error(errorMessage);
142 SmartIF<IRDBAccessSvc> pAccessSvc{svcLocator->service(geoDbTagSvc->getParamSvcName())};
144 errorMessage =
"Can not access " + geoDbTagSvc->getParamSvcName();
146 throw std::runtime_error(errorMessage);
149 std::map<std::string,int> materialComponentsMap;
150 std::map<std::string,G4Material*> materialMap;
151 IRDBRecordset_ptr materialsRec = pAccessSvc->getRecordsetPtr(
"TRMaterials",
"",
"");
154 std::string key = material->getString(
"NAME");
155 auto mapIt = materialComponentsMap.find(key);
156 if (mapIt == materialComponentsMap.end()) {
157 materialComponentsMap.emplace(key,1);
160 materialComponentsMap.at(key) = mapIt->second + 1;
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 if (itNElements==materialComponentsMap.end())
continue;
170 g4Material =
new G4Material(key
171 ,material->getDouble(
"DENSITY")*(CLHEP::gram / CLHEP::cm3)
172 ,itNElements->second);
173 materialMap.emplace(key,g4Material);
176 g4Material = materialMap.at(key);
179 G4Element* g4Element = G4Element::GetElement(material->getString(
"ELEMENT_NAME"));
181 errorMessage =
"Wrong name for element " + material->getString(
"ELEMENT_NAME")
182 +
" found in the description of material " + key;
184 throw std::runtime_error(errorMessage);
186 g4Material->AddElement(g4Element,(G4int)material->getInt(
"N"));
188 g4mat_Gas = materialMap.at(
"CO2");
189 g4mat_FoilMaterial = materialMap.at(
"CH2");
192 G4double PlasmaCof(4.0*
M_PI*CLHEP::fine_structure_const*CLHEP::hbarc*CLHEP::hbarc*CLHEP::hbarc/CLHEP::electron_mass_c2);
195 m_WplasmaFoil = sqrt( PlasmaCof * g4mat_FoilMaterial->GetElectronDensity() );
196 m_WplasmaGas = sqrt( PlasmaCof * g4mat_Gas->GetElectronDensity() );
198 ATH_MSG_DEBUG(
"Foil material : " << g4mat_FoilMaterial->GetName()
199 <<
"; plasma energy : " <<
m_WplasmaFoil/CLHEP::eV <<
" eV");
201 <<
"; plasma energy : " <<
m_WplasmaGas/CLHEP::eV <<
" eV");
225 ATH_MSG_DEBUG (
"Constructor TRTTransitionRadiation::Initialize() DONE!" );
262 const G4Step& aStep ) {
263 aParticleChange.Initialize(aTrack);
266 const G4DynamicParticle *aParticle(aTrack.GetDynamicParticle());
267 G4double KineticEnergy(aParticle->GetKineticEnergy());
271 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
274 G4double ParticleMass(aParticle->GetDefinition()->GetPDGMass());
275 G4double Gamma(1.0 + KineticEnergy/ParticleMass);
279 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
282 G4double FoilThickness(0.);
283 G4double GasThickness(0.);
287 std::vector<TRTRadiatorParameters>::const_iterator currentRadiator(
m_radiators.begin());
288 const std::vector<TRTRadiatorParameters>::const_iterator endOfRadiators(
m_radiators.end());
289 while(currentRadiator!=endOfRadiators) {
290 if ( currentRadiator->GetLogicalVolume() ==
291 aTrack.GetVolume()->GetLogicalVolume() ) {
292 FoilThickness = currentRadiator->GetFoilThickness();
293 GasThickness = currentRadiator->GetGasThickness();
294 BEflag = currentRadiator->GetBEflag();
300 if ( currentRadiator == endOfRadiators ) {
301 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
305 << currentRadiator->GetLogicalVolume()->GetName() );
307 G4ThreeVector ParticleDirection(aParticle->GetMomentumDirection());
310 G4double costh(std::abs(ParticleDirection[2]));
311 FoilThickness /= costh;
312 GasThickness /= costh;
315 G4double StepLength(aStep.GetStepLength());
316 G4int FoilsTraversed(
static_cast<G4int
>(StepLength/(FoilThickness+GasThickness)+0.5));
322 if ( FoilsTraversed == 0 ) {
324 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
327 G4double Gy(0.), Gmany(0.), Neff(0.);
366 G4double Sph_org(Sph);
369 G4double tempLog10Gamma(log10(Gamma));
370 G4double pHT_dEdxData = -0.001 + 0.0005*tempLog10Gamma;
371 G4double pHT_TRData = 0.15/(1.0 + exp(-(tempLog10Gamma - 3.3)/0.27));
372 G4double pHT_dEdxMC = -0.0031 + 0.00016*tempLog10Gamma;
373 G4double pHT_TRMC = 0.1289/(1.0 + exp(-(tempLog10Gamma - 3.01)/0.1253));
375 G4double fudge = std::min(2.0,(pHT_dEdxData+pHT_TRData)/( pHT_dEdxMC+pHT_TRMC));
381 G4long NumberOfPhotonsGenerated(CLHEP::RandPoisson::shoot(Sph));
387 <<
", Gamma = " << Gamma
389 <<
", Nph = " << NumberOfPhotonsGenerated );
391 if ( NumberOfPhotonsGenerated <= 0 ) {
393 <<
"No photons generated." );
395 return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
399 aParticleChange.SetNumberOfSecondaries( NumberOfPhotonsGenerated );
400 G4StepPoint *pPostStepPoint(aStep.GetPostStepPoint());
401 G4ThreeVector x0(pPostStepPoint->GetPosition());
403 G4double Esum(0.), XRannu(0.), Ephot(0.), Theta(0.),
Phi(0.),
406 G4ThreeVector pos(0),TRPhotonDirection(0);
408 for( G4int i(0); i<NumberOfPhotonsGenerated; ++i ) {
409 XRannu = CLHEP::RandFlat::shoot();
414 pos = pPostStepPoint->GetPosition();
416 ATH_MSG_VERBOSE (
" Photon generated with energy : " << Ephot/CLHEP::keV
417 <<
" keV; position: ( " << pos.x()/CLHEP::cm <<
" cm, "
418 << pos.y()/CLHEP::cm <<
" cm, " << pos.z()/CLHEP::cm <<
" cm )" );
421 Theta = std::abs( CLHEP::RandGaussZiggurat::shoot( 0.0,
M_PI/Gamma ) );
422 if( Theta >= 0.1 ) Theta = 0.1;
424 Phi = (2.*
M_PI)*CLHEP::RandFlat::shoot();
426 X = sin(Theta)*cos(Phi);
427 Y = sin(Theta)*sin(Phi);
430 TRPhotonDirection.set(X,Y,Z);
431 TRPhotonDirection.rotateUz( ParticleDirection );
432 TRPhotonDirection.unit();
435 TRPhoton =
new G4DynamicParticle( G4Gamma::Gamma(),
438 aParticleChange.AddSecondary( TRPhoton );
442 aParticleChange.ProposeEnergy( KineticEnergy-Esum );
445 <<
"Number of TR photons generated: " << NumberOfPhotonsGenerated );
447 return &aParticleChange;
543 const G4double & Gamma,
545 const G4double & d1 )
const {
546 G4double phimax = 4.*
M_PI;
547 G4double ginv2 = 1./(Gamma*Gamma);
548 G4double tau = d2/d1;
550 G4double mom = omega/CLHEP::hbarc;
555 G4double xi1sq = xi1*xi1;
556 G4double xi2sq = xi2*xi2;
558 G4double Z1 = 2./(mom*(ginv2+xi1sq));
559 G4double Z2 = 2./(mom*(ginv2+xi2sq));
562 G4double V = d1*(1./Z1-1./Z2);
564 G4double p0 = mom*d1*(xi1sq-xi2sq)/(4.*
M_PI);
565 G4double pmin = p0 +
a*(1.+tau)/(2.*
M_PI);
566 G4double
ymax = tau*phimax;
567 G4double pmax = p0 +
ymax*(1.+tau)/(2.*
M_PI);
569 G4int ipmin = (int)pmin+1;
570 G4int ipmax = (int)pmax;
573 G4double y0 = -0.5*mom*d1*(xi1sq-xi2sq)/(1+tau);
574 G4double dy = (2.*
M_PI)/(1+tau);
582 for ( G4int ip(ipmin); ip<=ipmax; ++ip ) {
587 term = (1./
y-1./(
y+V))*sin(0.5*(
y+V));
595 tx = (tx>term) ? tx : term;
599 if ( t2 > 0. && t1 > term && t1 > t2 ) {
600 if ( t1 < 0.0001*sum )
break;
604 return ( sum*4.*2.*CLHEP::fine_structure_const/(1.+tau));