9#include "GaudiKernel/RndmGenerators.h"
10#include "GaudiKernel/DataSvc.h"
11#include "GaudiKernel/SmartDataPtr.h"
35#include "CLHEP/Units/SystemOfUnits.h"
36#include "CLHEP/Matrix/Vector.h"
37#include "CLHEP/Random/RandFlat.h"
38#include "CLHEP/Vector/LorentzVector.h"
41#include "GaudiKernel/ITHistSvc.h"
53 constexpr double s_alpha = 1./137.;
54 constexpr double s_oneOverThree = 1./3.;
89 declareProperty(
"ParticleBroker" ,
m_particleBroker ,
"ISF ParticleBroker Svc" );
90 declareProperty(
"TruthRecordSvc" ,
m_truthRecordSvc ,
"ISF Particle Truth Svc" );
92 declareProperty(
"PhysicsProcessCode" ,
m_processCode ,
"MCTruth Physics Process Code");
99 declareProperty(
"RandomNumberService" ,
m_rndGenSvc ,
"Random number generator");
100 declareProperty(
"RandomStreamName" ,
m_randomEngineName ,
"Name of the random number stream");
119 return StatusCode::FAILURE;
123 return StatusCode::FAILURE;
129 return StatusCode::FAILURE;
135 return StatusCode::FAILURE;
156 SmartIF<ITHistSvc> tHistSvc{Gaudi::svcLocator()->service(
"THistSvc")};
158 ATH_MSG_ERROR(
"initialize() Could not find Hist Service -> Switching ValidationMode Off !" );
162 ATH_MSG_ERROR(
"initialize() Could not register the validation Tree -> Switching ValidationMode Off !" );
169 return StatusCode::SUCCESS;
176 ATH_MSG_INFO(
" ---------- Statistics output -------------------------- " );
182 return StatusCode::SUCCESS;
189 double childEnergy,
double photonEnergy,
203 CLHEP::HepLorentzVector vtmp;
204 CLHEP::Hep3Vector photonDirectionHep( photonDirection.x(), photonDirection.y(), photonDirection.z() );
206 vtmp = CLHEP::HepLorentzVector(photonEnergy*photonDirectionHep, photonEnergy)
207 - CLHEP::HepLorentzVector(p1*childDirectionHep, childEnergy);
209 double p2 = vtmp.vect().mag();
213 double charge1, charge2;
214 charge1 = charge2 = 0.;
226 int pdg1 =
s_pdgToHypo.convert(childType, charge1,
false);
227 int pdg2 =
s_pdgToHypo.convert(childType, charge2,
false);
254 if (parent->getUserInformation()) validInfo->
setGeneration(parent->getUserInformation()->generation()+1);
258 children[ichild] = ch1;
278 if (parent->getUserInformation()) validInfo->
setGeneration(parent->getUserInformation()->generation()+1);
282 children[ichild] = ch2;
297 if (!children.empty() ) {
298 for (
auto *childParticle : children) {
300 if (!childParticle->getTruthBinding()) {
301 ATH_MSG_ERROR(
"Could not retrieve TruthBinding from child ISFParticle "<< *childParticle);
310 m_validationTool->saveISFVertexInfo(14,vertex,*parent,parent->momentum(),nPrim,children);
319 double childEnergy,
double photonEnergy,
328 CLHEP::HepLorentzVector vtmp;
329 CLHEP::Hep3Vector photonDirectionHep( photonDirection.x(), photonDirection.y(), photonDirection.z() );
331 vtmp = CLHEP::HepLorentzVector(photonEnergy*photonDirectionHep, photonEnergy)
332 - CLHEP::HepLorentzVector(p1*childDirectionHep, childEnergy);
334 double p2 = vtmp.vect().mag();
338 double charge1, charge2;
339 charge1 = charge2 = 0.;
350 int pdg1 =
s_pdgToHypo.convert(childType, charge1,
false);
351 int pdg2 =
s_pdgToHypo.convert(childType, charge2,
false);
393 for (
auto *childParticle : children) {
394 if (!childParticle->getTruthBinding()) {
395 ATH_MSG_ERROR(
"Could not retrieve TruthBinding from child ISFParticle "<< *childParticle);
403 double pathCorrection,
421 double p0 = -7.01612e-03;
422 double p1 = 7.69040e-02;
423 double p2 = -6.07682e-01;
425 double xi = p0 + p1*
pow(p/1000.,p2);
427 double attenuation = exp( -7.777e-01*pathCorrection*mprop.
thicknessInX0()*(1.-xi) );
429 ATH_MSG_VERBOSE(
"[ conv ] Propability of conversion = " << (1.-attenuation) * 100. <<
" %." );
450 double gammaMom)
const {
456 double oneOverZpow = 1./
pow(Z,s_oneOverThree);
457 double alphaZsquare = (s_alpha*s_alpha*Z*Z);
459 double fZ = alphaZsquare*(1./(1.+alphaZsquare)+0.20206-0.0369*alphaZsquare+0.0083*alphaZsquare*alphaZsquare);
460 double FZ = (8./3)*log(Z)+8.*fZ;
462 double deltaMax = exp((42.24-FZ)*.1195)-0.952;
464 double deltaMin = 4.*epsilon0*136.*oneOverZpow;
466 double epsilon1 = 0.5-0.5*sqrt(1.-deltaMin/deltaMax);
467 double epsilonMin = epsilon1 > epsilon0 ? epsilon1 : epsilon0;
469 double Phi1 =
phi1(deltaMin);
470 double Phi2 =
phi2(deltaMin);
472 double F10 = 3.*Phi1 - Phi2 - FZ;
473 double F20 = 1.5*Phi1 + 0.5*Phi2 - FZ;
475 double N1 = (0.25-epsilonMin+epsilonMin*epsilonMin)*F10;
481 double epsilon = 0.5 - (0.5 - epsilonMin)*
pow(CLHEP::RandFlat::shoot(
m_randomEngine),s_oneOverThree);
483 double delta = 136.*epsilon0*oneOverZpow/(epsilon-epsilon*epsilon);
484 double F1 = 3.*
phi1(delta)-
phi2(delta)-FZ;
491 double epsilon = epsilonMin + (0.5-epsilonMin)*CLHEP::RandFlat::shoot(
m_randomEngine);
493 double delta = 136.*epsilon0*oneOverZpow/(epsilon-epsilon*epsilon);
494 double F2 = 1.5*
phi1(delta)-0.5*
phi2(delta)-FZ;
511 double oneOverZpow = 1./
pow(Z,s_oneOverThree);
512 double alphaZsquare = (s_alpha*s_alpha*Z*Z);
514 double fZ = alphaZsquare*(1./(1.+alphaZsquare)+0.20206-0.0369*alphaZsquare+0.0083*alphaZsquare*alphaZsquare);
515 double FZ = (8./3)*log(Z)+8.*fZ;
517 double deltaMax = exp((42.24-FZ)*.1195)-0.952;
519 double deltaMin = 4.*epsilon0*136.*oneOverZpow;
521 double epsilon1 = 0.5-0.5*sqrt(1.-deltaMin/deltaMax);
522 double epsilonMin = epsilon1 > epsilon0 ? epsilon1 : epsilon0;
524 double Phi1 =
phi1(deltaMin);
525 double Phi2 =
phi2(deltaMin);
527 double F10 = 3.*Phi1 - Phi2 - FZ;
528 double F20 = 1.5*Phi1 + 0.5*Phi2 - FZ;
530 double N1 = (0.25-epsilonMin+epsilonMin*epsilonMin)*F10;
536 double epsilon = 0.5 - (0.5 - epsilonMin)*
pow(CLHEP::RandFlat::shoot(
m_randomEngine),s_oneOverThree);
538 double delta = 136.*epsilon0*oneOverZpow/(epsilon-epsilon*epsilon);
539 double F1 = 3.*
phi1(delta)-
phi2(delta)-FZ;
546 double epsilon = epsilonMin + (0.5-epsilonMin)*CLHEP::RandFlat::shoot(
m_randomEngine);
548 double delta = 136.*epsilon0*oneOverZpow/(epsilon-epsilon*epsilon);
549 double F2 = 1.5*
phi1(delta)-0.5*
phi2(delta)-FZ;
576 double u = -log(r2*r3)/
a;
578 theta *= (r1 < 0.25 ) ? u : u*s_oneOverThree;
583 CLHEP::Hep3Vector gammaMomHep( gammaMom.x(), gammaMom.y(), gammaMom.z() );
584 CLHEP::Hep3Vector newDirectionHep(gammaMomHep.unit());
585 double x = -newDirectionHep.y();
586 double y = newDirectionHep.x();
589 if (newDirectionHep.z()*newDirectionHep.z() > 0.999999)
592 CLHEP::Hep3Vector deflectorHep(
x,
y,
z);
594 newDirectionHep.rotate(
theta, deflectorHep);
596 newDirectionHep.rotate(psi,gammaMomHep);
606 Amg::Vector3D newDirection( newDirectionHep.x(), newDirectionHep.y(), newDirectionHep.z() );
612 const Trk::ExtendedMaterialProperties* )
const {
619 double childEnergy = p*efrac;
627 ATH_MSG_VERBOSE(
"[ conv ] Child energy simulated as : " << childEnergy <<
" MeV" );
645 const Trk::ExtendedMaterialProperties* )
const {
651 double childEnergy = p*efrac;
659 ATH_MSG_VERBOSE(
"[ conv ] Child energy simulated as : " << childEnergy <<
" MeV" );
Scalar theta() const
theta method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
constexpr int pow(int base, int exp) noexcept
The generic ISF particle definition,.
void setUserInformation(ParticleUserInformation *userInfo)
Interface class for all truth incidents handled by the ISF.
void updateChildParticleProperties()
Update the id and particleLink properties of the child particles (to be called after registerTruthInc...
static ParticleClipboard & getInstance()
get the singleton instance
const ISF::ISFParticle * getParticle() const
get the particle from the clipboard
Each ISFParticle carries a pointer to this class.
void setGeneration(int gen)
void setProcess(int proc)
Material with information about thickness of material.
float thicknessInX0() const
Return the radiationlength fraction.
float averageZ() const
Returns the average Z of the material.
const Amg::Vector3D & momentum() const
Access method for the momentum.
const Amg::Vector3D & position() const
Access method for the position.
small converter from the (abs) PDG code to the particle hypothsis used in Tracking
Eigen::Matrix< double, 3, 1 > Vector3D
constexpr int UNDEFINED_ID
constexpr int SIM_STATUS_THRESHOLD
Constant definiting the status threshold for simulated particles, eg. can be used to separate generat...
std::vector< ISF::ISFParticle * > ISFParticleVector
ISFParticle vector.
constexpr double mass[PARTICLEHYPOTHESES]
the array of masses
ParametersBase< NeutralParametersDim, Neutral > NeutralParameters
ParticleHypothesis
Enumeration for Particle hypothesis respecting the interaction with material.