9 #include "GaudiKernel/IRndmGenSvc.h"
10 #include "GaudiKernel/RndmGenerators.h"
11 #include "GaudiKernel/DataSvc.h"
12 #include "GaudiKernel/SmartDataPtr.h"
41 #include "CLHEP/Units/SystemOfUnits.h"
42 #include "CLHEP/Matrix/Vector.h"
43 #include "CLHEP/Random/RandFlat.h"
44 #include "CLHEP/Random/RandLandau.h"
45 #include "CLHEP/Random/RandGaussZiggurat.h"
48 #include "GaudiKernel/ITHistSvc.h"
56 m_eLossUpdator(
"iFatras::McEnergyLossUpdator/FatrasEnergyLossUpdator"),
58 m_msUpdator(
"Trk::MultipleScatteringUpdator/AtlasMultipleScatteringUpdator"),
59 m_conversionTool(
"iFatras::McConversionCreator/FatrasConversionCreator"),
63 m_hadIntProcessor(
"iFatras::G4HadIntProcessor/FatrasG4HadIntProcessor"),
66 m_minimumBremPhotonMomentum(50.*
CLHEP::
MeV),
67 m_parametricScattering(false),
68 m_use_msUpdator(false),
69 m_uniformHertzDipoleAngle(false),
70 m_referenceMaterial(true),
71 m_bendingCorrection(false),
72 m_rndGenSvc(
"AtDSFMTGenSvc",
n),
73 m_randomEngine(nullptr),
74 m_randomEngineName(
"FatrasRnd"),
75 m_recordedBremPhotons(0),
77 m_recordEnergyDeposition(false),
78 m_layerIndexCaloSampleMapName(
"LayerIndexCaloSampleMap"),
79 m_layerIndexCaloSampleMap(nullptr),
80 m_projectionFactor(sqrt(2.)),
81 m_validationMode(false),
83 m_validationTreeName(
"FatrasMaterialEffects"),
84 m_validationTreeDescription(
"Validation output from the McMaterialEffectsUpdator"),
85 m_validationTreeFolder(
"/val/FatrasSimulationMaterial"),
86 m_validationTree(nullptr),
94 m_bremValidation(false),
95 m_bremValidationTreeName(
"FatrasBremPhotons"),
96 m_bremValidationTreeDescription(
"Validation output from the McMaterialEffectsUpdator"),
97 m_bremValidationTreeFolder(
"/val/FatrasBremPhotons"),
98 m_bremValidationTree(nullptr),
103 m_bremMotherEnergy(0.),
104 m_bremPhotonEnergy(0.),
105 m_bremPhotonAngle(0.),
106 m_edValidation(false),
107 m_edValidationTreeName(
"FatrasEnergyInCaloDeposit"),
108 m_edValidationTreeDescription(
"Validation output from the McMaterialEffectUpdator"),
109 m_edValidationTreeFolder(
"/val/FatrasEnergyInCaloDeposit"),
110 m_edValidationTree(nullptr),
111 m_edLayerIntersectX(0.),
112 m_edLayerIntersectY(0.),
113 m_edLayerIntersectZ(0.),
114 m_edLayerIntersectR(0.),
115 m_edLayerEnergyDeposit(0.),
117 m_oneOverThree(1./3.),
118 m_particleBroker(
"ISF_ParticleParticleBroker",
n),
119 m_truthRecordSvc(
"ISF_TruthRecordSvc",
n),
125 declareProperty(
"EnergyLoss" ,
m_eLoss);
127 declareProperty(
"MultipleScattering" ,
m_ms);
128 declareProperty(
"MultipleScatteringUpdator" ,
m_msUpdator);
134 declareProperty(
"BremProcessCode" ,
m_processCode,
"MCTruth Physics Process Code");
136 declareProperty(
"HadronicInteraction" ,
m_hadInt);
154 declareProperty(
"RandomNumberService" ,
m_rndGenSvc ,
"Random number generator");
155 declareProperty(
"RandomStreamName" ,
m_randomEngineName ,
"Name of the random number stream");
158 declareProperty(
"ParticleBroker" ,
m_particleBroker ,
"ISF Particle Broker Svc");
159 declareProperty(
"TruthRecordSvc" ,
m_truthRecordSvc ,
"ISF Particle Truth Svc");
174 if (m_samplingTool.retrieve().isFailure()){
176 return StatusCode::FAILURE;
182 if (m_eLossUpdator.retrieve().isFailure()){
184 return StatusCode::FAILURE;
188 m_eLossUpdator.disable();
192 if (m_ms && m_use_msUpdator){
193 if (m_msUpdator.retrieve().isFailure()){
195 return StatusCode::FAILURE;
199 m_msUpdator.disable();
203 if (m_conversionTool.retrieve().isFailure()){
205 return StatusCode::FAILURE;
211 if (m_hadIntProcessor.retrieve().isFailure()){
213 return StatusCode::FAILURE;
217 m_hadIntProcessor.disable();
221 if (m_rndGenSvc.retrieve().isFailure()){
223 return StatusCode::FAILURE;
228 m_randomEngine = m_rndGenSvc->GetEngine(m_randomEngineName);
229 if (!m_randomEngine) {
230 ATH_MSG_FATAL(
"Could not get random engine '" << m_randomEngineName <<
"'" );
231 return StatusCode::FAILURE;
235 m_useConditions=!m_trackingGeometryReadKey.key().empty();
238 if (!m_useConditions) {
239 if (m_trackingGeometrySvc.retrieve().isSuccess()) {
240 ATH_MSG_DEBUG(
"Successfully retrieved " << m_trackingGeometrySvc);
241 m_trackingGeometryName = m_trackingGeometrySvc->trackingGeometryName();
243 ATH_MSG_WARNING(
"Couldn't retrieve " << m_trackingGeometrySvc <<
". ");
245 << m_trackingGeometryName <<
"' from DetectorStore.");
251 ATH_CHECK(m_trackingGeometryReadKey.initialize(m_useConditions));
254 if (m_particleDecayer.retrieve().isFailure()){
256 return StatusCode::FAILURE;
261 if (m_particleBroker.retrieve().isFailure()){
263 return StatusCode::FAILURE;
265 if (m_truthRecordSvc.retrieve().isFailure()){
267 return StatusCode::FAILURE;
273 ATH_CHECK( m_validationTool.retrieve( DisableTool{ m_validationTool.empty() || !m_validationMode } ) );
275 if (m_validationMode || m_bremValidation || m_edValidation) {
276 SmartIF<ITHistSvc> tHistSvc{service(
"THistSvc")};
278 ATH_MSG_ERROR(
"initialize() Could not find Hist Service -> Switching ValidationMode Off !" );
281 if (m_validationMode) {
285 m_validationTree =
new TTree(m_validationTreeName.c_str(), m_validationTreeDescription.c_str());
288 m_validationTree->Branch(
"LayerIndex" , &m_layerIndex,
"layerIdx/I");
289 m_validationTree->Branch(
"PathInX0" , &m_tInX0,
"tInX0/F");
290 m_validationTree->Branch(
"ThetaMS" , &m_thetaMSproj,
"thetaMS/F");
291 m_validationTree->Branch(
"ThetaMSphi" , &m_thetaMSphi,
"thetaMSphi/F");
292 m_validationTree->Branch(
"ThetaMStheta" , &m_thetaMStheta,
"thetaMStheta/F");
293 m_validationTree->Branch(
"DeltaP" , &m_deltaP,
"deltaP/F");
294 m_validationTree->Branch(
"DeltaPsigma" , &m_deltaPsigma,
"deltaPsigma/F");
297 if ((tHistSvc->regTree(m_validationTreeFolder, m_validationTree)).isFailure()) {
298 ATH_MSG_ERROR(
"initialize() Could not register the validation Tree -> Switching ValidationMode Off !" );
299 delete m_validationTree; m_validationTree =
nullptr;
301 ATH_MSG_INFO(
"TTree for MaterialEffects validation booked." );
305 if (m_bremValidation){
310 m_bremValidationTree =
new TTree(m_bremValidationTreeName.c_str(), m_bremValidationTreeDescription.c_str());
313 m_bremValidationTree->Branch(
"BremPositionX" , &m_bremPointX,
"bremX/F");
314 m_bremValidationTree->Branch(
"BremPositionY" , &m_bremPointY,
"bremY/F");
315 m_bremValidationTree->Branch(
"BremPositionR" , &m_bremPointR,
"bremR/F");
316 m_bremValidationTree->Branch(
"BremPositionZ" , &m_bremPointZ,
"bremZ/F");
317 m_bremValidationTree->Branch(
"BremMotherEnergy" , &m_bremMotherEnergy,
"bremMotherE/F");
318 m_bremValidationTree->Branch(
"BremPhotonEnergy" , &m_bremPhotonEnergy,
"bremPhotonE/F");
319 m_bremValidationTree->Branch(
"BremPhotonAngle" , &m_bremPhotonAngle,
"bremPhotondA/F");
321 if ((tHistSvc->regTree(m_bremValidationTreeFolder, m_bremValidationTree)).isFailure()) {
322 ATH_MSG_ERROR(
"initialize() Could not register the validation Tree -> Switching ValidationMode Off !" );
323 delete m_bremValidationTree; m_bremValidationTree =
nullptr;
325 ATH_MSG_INFO(
"TTree for Bremsstrahlung validation booked." );
335 m_edValidationTree =
new TTree(m_edValidationTreeName.c_str(), m_edValidationTreeDescription.c_str());
338 m_edValidationTree->Branch(
"EdepositPositionX" , &m_edLayerIntersectX,
"edX/F");
339 m_edValidationTree->Branch(
"EdepositPositionY" , &m_edLayerIntersectY,
"edY/F");
340 m_edValidationTree->Branch(
"EdepositPositionR" , &m_edLayerIntersectR,
"edR/F");
341 m_edValidationTree->Branch(
"EdepositPositionZ" , &m_edLayerIntersectZ,
"edZ/F");
342 m_edValidationTree->Branch(
"Edeposit" , &m_edLayerEnergyDeposit,
"ed/F");
343 m_edValidationTree->Branch(
"EdepositLayerSample" , &m_edLayerSample,
"edLayerSample/F");
345 if ((tHistSvc->regTree(m_edValidationTreeFolder, m_edValidationTree)).isFailure()) {
346 ATH_MSG_ERROR(
"initialize() Could not register the validation Tree -> Switching ValidationMode Off !" );
347 delete m_edValidationTree; m_edValidationTree =
nullptr;
349 ATH_MSG_INFO(
"TTree for Energy deposition validation booked." );
356 return StatusCode::SUCCESS;
363 ATH_MSG_INFO(
" ---------- Statistics output -------------------------- " );
364 ATH_MSG_INFO(
" Minimum energy cut for brem photons : " << m_minimumBremPhotonMomentum );
365 ATH_MSG_INFO(
" Brem photons (above cut, recorded) : " << m_recordedBremPhotons );
368 return StatusCode::SUCCESS;
371 std::unique_ptr<Trk::TrackParameters>
385 double traversedMatFraction = 0.;
399 if (m_referenceMaterial){
412 return updateInLay(
parent,parm,traversedMatFraction,timeLim, pathLim,
dir,
particle);
415 std::unique_ptr<Trk::TrackParameters>
428 ATH_MSG_WARNING(
"Trk::TrackParameters parm is null -- will not proceed. Returning nullptr.");
432 std::unique_ptr<Trk::TrackParameters> currPar = inParm->
uniqueClone();
434 m_matProp = m_matProp ? m_matProp : m_layer->fullUpdateMaterialProperties(*currPar);
437 ATH_MSG_WARNING(
"Something went wrong -- m_matProp is missing but Trk::TrackParameters is not null! Returning nullptr.");
440 double pathCorrection =
441 m_layer->surfaceRepresentation().normal().dot(currPar->
momentum()) != 0
442 ? std::abs(m_layer->surfaceRepresentation().pathCorrection(currPar->
position(),
dir * (currPar->
momentum())))
446 if (m_bendingCorrection) {
447 ATH_MSG_WARNING(
"BendingCorrection not implemented!! (McMaterialEffectsUpdator.cxx)");
453 std::string volumeName = enclosingVolume ? enclosingVolume->
volumeName() :
"Unknown";
454 double layerR = m_layer->surfaceRepresentation().bounds().r();
455 double layerZ = m_layer->surfaceRepresentation().center().z();
456 ATH_MSG_VERBOSE(
" [M] Material effects update() on layer with index "<< m_layer->layerIndex() );
457 ATH_MSG_VERBOSE(
" -> path/X0 on layer [r/z] = [ " << layerR <<
" / " << layerZ <<
" ] :"
458 << pathCorrection*m_matProp->thicknessInX0() );
464 if (m_validationMode) {
465 m_tInX0 = (1-matFraction)*pathCorrection * m_matProp->thicknessInX0();
466 m_layerIndex = m_layer->layerIndex().value();
467 m_validationTree->Fill();
475 dInL0 = extMatProp ? (1-matFraction)*pathCorrection*extMatProp->
thicknessInL0() :
476 (1-matFraction)*pathCorrection*m_matProp->thicknessInX0()/0.37/m_matProp->averageZ();
480 double dX0 = (1.-matFraction)*pathCorrection*m_matProp->thicknessInX0();
484 pathLim.
updateMat(dX0, m_matProp->averageZ(), dInL0);
525 if (m_validationMode) {
546 ATH_MSG_ERROR(
"Could not retrieve TruthBinding from non-interacting ISFParticle "<< *regisp);
548 m_particleBroker->push(regisp, m_isp);
559 dInL0 *= x0rem > 0 ? x0rem / dX0 : 1.;
563 }
else if (pathLim.
x0Max > 0 && extMatProp && pathLim.
process > 100 &&
566 dX0 *= l0rem > 0 ? l0rem / dInL0 : 1.;
571 pathLim.
updateMat(dX0, m_matProp->averageZ(), dInL0);
579 AmgVector(5) updatedParameters(currPar->parameters());
580 std::unique_ptr<Trk::TrackParameters> updated =
nullptr;
584 double matTot = (1 - matFraction) * pathCorrection * m_matProp->thicknessInX0();
586 radiate(isp, updatedParameters, currPar->
position(), edir, timeLim, dX0, matFraction, matTot,
dir,
particle);
589 updatedParameters[1],
590 updatedParameters[2],
591 updatedParameters[3],
592 updatedParameters[4],
595 currPar = std::move(updated);
597 if (currPar->
momentum().mag() < m_minimumMomentum) {
604 matFraction += dX0 / pathCorrection / m_matProp->thicknessInX0();
607 if (isp->
charge() != 0 && dX0 > 0.) {
609 ionize(*currPar, updatedParameters, dX0,
dir,
particle);
612 if (m_ms && m_matProp->thicknessInX0() > 0.) {
614 (m_use_msUpdator && m_msUpdator)
615 ? sqrt(m_msUpdator->sigmaSquare(*m_matProp,
p, dX0 / m_matProp->thicknessInX0(),
particle))
618 multipleScatteringUpdate(*currPar, updatedParameters, sigmaMSproj);
623 updatedParameters[1],
624 updatedParameters[2],
625 updatedParameters[3],
626 updatedParameters[4],
628 currPar = std::move(updated);
630 if (currPar->
momentum().mag() < m_minimumMomentum) {
638 if (iStatus == 1 || iStatus == 2) {
645 childs = m_hadIntProcessor->doHadIntOnLayer(
648 childs = m_hadIntProcessor->doHadIntOnLayer(
653 if (m_validationMode && m_validationTool.isEnabled() && !childs.empty() && isp != m_isp) {
655 m_validationTool->saveISFParticleInfo(*isp, pathLim.
process, currPar.get(), timeLim.
time, pathLim.
x0Max);
660 for (
unsigned ic = 0;
ic < childs.size();
ic++) {
661 double mom = childs[
ic]->momentum().mag();
663 if (
mom < m_minimumMomentum) {
667 m_pdgToParticleHypothesis.convert(childs[
ic]->pdgCode(), childs[
ic]->
charge());
668 auto cparm = std::make_unique<Trk::CurvilinearParameters>(childs[
ic]->position(), childs[
ic]->
momentum(), childs[
ic]->
charge());
675 double ci = m_layer->surfaceRepresentation().normal().dot(currPar->
momentum().unit());
676 double co = m_layer->surfaceRepresentation().normal().dot(childs[
ic]->
momentum().
unit());
677 double remMat = ci * co < 0 ? (1 - matFraction) : matFraction;
680 std::unique_ptr<Trk::TrackParameters> uPar =
681 updateInLay(childs[
ic], cparm.get(), remMat, timeLim, pLim,
dir, pHypothesis);
684 << uPar->position());
686 if (!childs.empty()) {
734 if (m_validationMode) {
752 ATH_MSG_ERROR(
"Could not retrieve TruthBinding from non-interacting ISFParticle "<< *regisp);
754 m_particleBroker->push(regisp, m_isp);
776 double E = sqrt(
p*
p+
m*
m);
785 double Ionization = 0.;
788 double I = 16.e-6 *
std::pow(m_matProp->averageZ(),0.9);
791 double kaz = 0.5*30.7075*m_matProp->zOverAtimesRho();
796 Ionization = -kaz*(2.*
log(2.*me/
I)+3.*
log(
gamma) - 1.95);
803 double eplasma = 28.816e-6 * sqrt(1000.*m_matProp->zOverAtimesRho());
807 double tMax = 2.*
eta2*me/(1.+2.*
gamma*mfrac+mfrac*mfrac);
813 double energyLoss = Ionization*dInX0*m_matProp->x0();
814 double newP = sqrt(fmax(0.,(
E+energyLoss)*(
E+energyLoss)-
m*
m));
816 newP = newP <= 0.5*m_minimumMomentum ? 0.5*m_minimumMomentum : newP;
825 Trk::TimeLimit timeLim,
double pathLim,
double& matFraction,
double matTot,
833 while ( path < pathLim && p>m_minimumMomentum ) {
835 double rndx = CLHEP::RandFlat::shoot(m_randomEngine);
839 double eps = fmin(10.,m_minimumMomentum)/
p;
850 if (
path+
dx > pathLim ) {
851 double rndp = CLHEP::RandFlat::shoot(m_randomEngine);
852 if (rndp > (pathLim-
path)/
dx){
859 matFraction +=
dx*rndp/matTot;
863 matFraction +=
dx/matTot;
898 if (
p*(1-
z) > m_minimumBremPhotonMomentum ) {
900 double deltaP = (1-
z)*
p;
915 std::unique_ptr<Trk::TrackParameters>
920 double pathCorrection,
931 double E = sqrt(
p*
p+
m*
m);
936 m_hadIntProcessor->hadronicInteraction(parm.
position(),
944 ATH_MSG_VERBOSE(
" [+] Hadronic interaction killed initial hadron ... stop "
945 "simulation, tackle childs.");
954 AmgVector(5) updatedParameters(parm.parameters());
961 double energyLoss = sampledEnergyLoss.
deltaE();
963 if (
E + energyLoss <
m) {
965 " [+] particle momentum fell under momentum cut - stop simulation");
969 newP = sqrt((
E + energyLoss) * (
E + energyLoss) -
m *
m);
971 if (m_recordEnergyDeposition && m_currentSample > 0){
972 if (m_edValidationTree){
974 m_edLayerIntersectX = parm.
position().x();
975 m_edLayerIntersectY = parm.
position().y();
976 m_edLayerIntersectZ = parm.
position().z();
977 m_edLayerIntersectR = parm.
position().perp();
979 m_edLayerSample = m_currentSample;
980 m_edLayerEnergyDeposit = -1*sampledEnergyLoss.
deltaE();
982 m_edValidationTree->Fill();
987 double deltaP = newP -
p;
994 recordBremPhoton(time,
p,-deltaP,
1000 if ( newP < m_minimumMomentum) {
1001 ATH_MSG_VERBOSE(
" [+] particle momentum fell under momentum cut - stop simulation" );
1013 if (m_ms && matprop.
x0()>0 ){
1015 double sigmaMSproj = (m_use_msUpdator && m_msUpdator) ? sqrt(m_msUpdator->sigmaSquare(matprop,
p, pathCorrection,
particle)) :
1018 multipleScatteringUpdate(parm,updatedParameters,sigmaMSproj);
1022 if (m_validationMode) {
1024 m_validationTree->Fill();
1029 (parm.covariance()) ? std::optional<
AmgSymMatrix(5)>(*parm.covariance())
1034 updatedParameters[1],
1035 updatedParameters[2],
1036 updatedParameters[3],
1037 updatedParameters[4],
1041 std::unique_ptr<Trk::TrackParameters>
1052 ATH_MSG_WARNING(
" [ ---- ] Only implemented for muons yet. No parameterisation for other particles." );
1057 AmgVector(5) updatedParameters(parm->parameters());
1060 double pathCorrection = 1.;
1065 double E = sqrt(
p*
p+
m*
m);
1082 double sigmaMSproj = (m_use_msUpdator && m_msUpdator) ? sqrt(m_msUpdator->sigmaSquare(mprop,
p, pathCorrection,
particle)) :
1085 multipleScatteringUpdate(*parm,updatedParameters,sigmaMSproj);
1097 double simulatedEnergyLoss = -1.*(energyLossMPV+energyLossSigma*CLHEP::RandLandau::shoot(m_randomEngine));
1099 if (m_recordEnergyDeposition){
1101 ATH_MSG_VERBOSE(
" [+] try to record deposited energy (if mapped with a calo sample) " );
1102 const EventContext& ctx = Gaudi::Hive::currentContext();
1104 if (pTrackingGeometry) {
1115 Trk::LayerIndexSampleMap::const_iterator layerIndexCaloSample = lism->find(associatedLayer->
layerIndex());
1117 if (layerIndexCaloSample != lism->end()){
1119 if (m_edValidationTree){
1122 m_edLayerIntersectX = edeposition.x();
1123 m_edLayerIntersectY = edeposition.y();
1124 m_edLayerIntersectZ = edeposition.z();
1125 m_edLayerIntersectR = edeposition.perp();
1127 m_edLayerSample = layerIndexCaloSample->second;
1128 m_edLayerEnergyDeposit = -1*simulatedEnergyLoss;
1130 m_edValidationTree->Fill();
1138 double newP = sqrt((
E+simulatedEnergyLoss)*(
E+simulatedEnergyLoss)-
m*
m);
1148 updatedParameters[1],
1149 updatedParameters[2],
1150 updatedParameters[3],
1151 updatedParameters[4],
1158 double E = sqrt(
p*
p+
m*
m);
1163 double sigmaMSproj = 13.6/
beta/
p*sqrt(dInX0)*(1.+0.038*
log(dInX0));
1170 double sigmaMSproj)
const
1174 if (m_parametricScattering){
1178 double sinTheta = (theta*theta > 10
e-10) ?
sin(theta) : 1.;
1181 double deltaTheta = m_projectionFactor*sigmaMSproj*CLHEP::RandGaussZiggurat::shoot(m_randomEngine);
1182 double deltaPhi = m_projectionFactor*sigmaMSproj*CLHEP::RandGaussZiggurat::shoot(m_randomEngine)/sinTheta;
1196 m_thetaMStheta = deltaTheta;
1201 double thetaMs = m_projectionFactor*sigmaMSproj*CLHEP::RandGaussZiggurat::shoot(m_randomEngine);
1202 double psi = 2.*
M_PI*CLHEP::RandFlat::shoot(m_randomEngine);
1204 CLHEP::Hep3Vector parsMomHep(
pars.momentum().x(),
pars.momentum().y(),
pars.momentum().z() );
1205 CLHEP::Hep3Vector newDirectionHep( parsMomHep.unit().x(), parsMomHep.unit().y(), parsMomHep.unit().z());
1206 double x = -newDirectionHep.y();
1207 double y = newDirectionHep.x();
1210 if (newDirectionHep.z()*newDirectionHep.z() > 0.999999) {
1215 CLHEP::Hep3Vector deflector(
x,
y,
z);
1217 newDirectionHep.rotate(thetaMs, deflector);
1219 newDirectionHep.rotate(psi, parsMomHep);
1224 if (m_validationMode){
1247 ++m_recordedBremPhotons;
1255 double psi = 2.*
M_PI*CLHEP::RandFlat::shoot(m_randomEngine);
1260 double E = sqrt(pElectron*pElectron +
m*
m);
1262 if (m_uniformHertzDipoleAngle) {
1264 theta =
m/
E * CLHEP::RandFlat::shoot(m_randomEngine);
1271 double r1 = CLHEP::RandFlat::shoot(m_randomEngine);
1272 double r2 = CLHEP::RandFlat::shoot(m_randomEngine);
1273 double r3 = CLHEP::RandFlat::shoot(m_randomEngine);
1275 double u = -
log(r2*r3)/
a;
1277 theta *= (r1 < 0.25 ) ?
u :
u*m_oneOverThree;
1280 ATH_MSG_VERBOSE(
" [ brem ] Simulated angle to electron = " << theta <<
"." );
1303 double th = particleDir.theta()-theta;
1304 double ph = particleDir.phi();
1305 if (
th<0.) {
th *=-1; ph +=
M_PI; }
1307 CLHEP::Hep3Vector particleDirHep( particleDir.x(), particleDir.y(), particleDir.z() );
1308 newDirectionHep.rotate(psi,particleDirHep);
1309 Amg::Vector3D newDirection( newDirectionHep.x(), newDirectionHep.y(), newDirectionHep.z() );
1313 particleDir = (particleDir*pElectron- gammaE*newDirection).
unit();
1321 gammaE*newDirection,
1332 if (m_validationMode) {
1347 m_truthRecordSvc->registerTruthIncident( truth);
1354 if (!
parent->getTruthBinding()) {
1357 for (
auto *childParticle :
children) {
1358 if (!childParticle->getTruthBinding()) {
1359 ATH_MSG_ERROR(
"Could not retrieve TruthBinding from child ISFParticle "<< *childParticle);
1361 m_particleBroker->push(childParticle,
parent);
1365 if (m_validationMode && m_validationTool.isEnabled()) {
1373 if (m_bremValidationTree){
1375 ATH_MSG_VERBOSE(
" [ brem ] Filling bremsstrahlung validation TTree ..." );
1382 m_bremPhotonEnergy =
float(gammaE);
1383 m_bremPhotonAngle =
float(theta);
1385 m_bremValidationTree->Fill();
1403 ++m_recordedBremPhotons;
1411 double psi = 2.*
M_PI*CLHEP::RandFlat::shoot(m_randomEngine);
1416 double E = sqrt(pElectron*pElectron +
m*
m);
1418 if (m_uniformHertzDipoleAngle) {
1420 theta =
m/
E * CLHEP::RandFlat::shoot(m_randomEngine);
1427 double r1 = CLHEP::RandFlat::shoot(m_randomEngine);
1428 double r2 = CLHEP::RandFlat::shoot(m_randomEngine);
1429 double r3 = CLHEP::RandFlat::shoot(m_randomEngine);
1431 double u = -
log(r2*r3)/
a;
1433 theta *= (r1 < 0.25 ) ?
u :
u*m_oneOverThree;
1436 ATH_MSG_VERBOSE(
" [ brem ] Simulated angle to electron = " << theta <<
"." );
1439 CLHEP::Hep3Vector particleDirHep( particleDir.x(), particleDir.y(), particleDir.z() );
1440 CLHEP::Hep3Vector newDirectionHep( particleDirHep );
1441 double x = -newDirectionHep.y();
1442 double y = newDirectionHep.x();
1445 if (newDirectionHep.z()*newDirectionHep.z() > 0.999999)
1448 CLHEP::Hep3Vector deflectorHep(
x,
y,
z);
1450 newDirectionHep.rotate(theta, deflectorHep);
1452 newDirectionHep.rotate(psi,particleDirHep);
1455 Amg::Vector3D newDirection( newDirectionHep.x(), newDirectionHep.y(), newDirectionHep.z() );
1456 particleDir = (particleDir*pElectron- gammaE*newDirection).
unit();
1462 gammaE*newDirection,
1474 if (m_validationMode) {
1489 m_truthRecordSvc->registerTruthIncident( truth);
1496 if (!
parent->getTruthBinding()) {
1499 for (
auto *childParticle :
children) {
1500 if (!childParticle->getTruthBinding()) {
1501 ATH_MSG_ERROR(
"Could not retrieve TruthBinding from child ISFParticle "<< *childParticle);
1506 if (m_validationMode && m_validationTool.isEnabled()) {
1517 double ci = m_layer->surfaceRepresentation().normal().dot(particleDir);
1518 double co = m_layer->surfaceRepresentation().normal().dot(newDirection);
1520 double remMat = ci*co <0 ? (1-matFraction) : matFraction;
1524 double pathCorrection = m_layer->surfaceRepresentation().normal().dot(bremPhoton->
momentum()) !=0 ?
1525 fabs(m_layer->surfaceRepresentation().pathCorrection(bremPhoton->
position(),bremPhoton->
momentum())) : 1.;
1527 double mTot = m_matProp->thicknessInX0()*pathCorrection*(1.-remMat);
1529 if (mTot < pLim.
x0Max) {
1531 m_particleBroker->push( bremPhoton,
parent);
1536 auto cparm = std::make_unique<Trk::CurvilinearParameters>(bremPhoton->
position(),bremPhoton->
momentum(),bremPhoton->
charge());
1537 std::unique_ptr<Trk::TrackParameters> uPar = updateInLay(bremPhoton,cparm.get(),remMat,timeLim, pLim,
dir,
Trk::photon);
1538 if (uPar) {
ATH_MSG_VERBOSE(
"Check this: parameters should be dummy here (brem.photon) " <<
","<<uPar->
position() ); }
1542 if (m_bremValidationTree){
1544 ATH_MSG_VERBOSE(
" [ brem ] Filling bremsstrahlung validation TTree ..." );
1551 m_bremPhotonEnergy =
float(gammaE);
1552 m_bremPhotonAngle =
float(theta);
1554 m_bremValidationTree->Fill();
1565 if (!m_layerIndexCaloSampleMap){
1567 if ((
detStore()->
retrieve(m_layerIndexCaloSampleMap, m_layerIndexCaloSampleMapName).isFailure())){
1568 ATH_MSG_WARNING(
"Could not retrieve '" << m_layerIndexCaloSampleMapName <<
"' from DetectorStore." );
1572 if (m_layerIndexCaloSampleMap)
1573 ATH_MSG_VERBOSE(
"Successfully retrieved '" << m_layerIndexCaloSampleMapName <<
"' with entries:"
1574 << m_layerIndexCaloSampleMap->size() );
1576 return m_layerIndexCaloSampleMap;
1579 std::unique_ptr<Trk::TrackParameters>
1611 m_truthRecordSvc->registerTruthIncident( truth);
1616 for (
unsigned int i=0;
i<childVector.size();
i++) {
1618 if (m_validationMode) {
1623 childVector[
i]->setUserInformation(validInfo);
1626 childVector[
i]->setNextGeoID(
parent->nextGeoID() );
1628 m_particleBroker->push(childVector[
i],
parent);
1632 if (m_validationMode && m_validationTool.isEnabled()) {
1645 double fmin =
mass/
p;
1647 double fr = 1.-
pow(fmin,CLHEP::RandFlat::shoot(m_randomEngine));
1683 m_truthRecordSvc->registerTruthIncident( truth);
1690 if (!
parent->getTruthBinding()) {
1693 for (
auto *childParticle :
children) {
1694 if (!childParticle->getTruthBinding()) {
1695 ATH_MSG_ERROR(
"Could not retrieve TruthBinding from child ISFParticle "<< *childParticle);
1700 if (m_validationMode) {
1705 children[0]->setUserInformation(validInfo1);
1710 children[1]->setUserInformation(validInfo2);
1718 if (m_validationMode && m_validationTool.isEnabled()) {
1730 auto parm = std::make_unique<Trk::NeutralCurvilinearParameters>(position,
momentum,
parent->charge());
1732 bool cStat = m_conversionTool->doConversion(time, *parm);
1734 if (!cStat)
ATH_MSG_WARNING(
"Conversion failed, killing photon anyway ");
1744 auto parm = std::make_unique<Trk::CurvilinearParameters>(position,
momentum,
parent->charge());
1746 bool recHad = m_hadIntProcessor->doHadronicInteraction(time, position,
momentum, extMatProp,
particle,
true);
1768 if (
process==0 )
return childVector;
1780 double fmin =
mass/
p;
1782 double fr = 1.-
pow(fmin,CLHEP::RandFlat::shoot(m_randomEngine));
1813 if (m_validationMode) {
1818 children[0]->setUserInformation(validInfo1);
1823 children[1]->setUserInformation(validInfo2);
1832 m_truthRecordSvc->registerTruthIncident( truth);
1839 if (m_validationMode && m_validationTool.isEnabled()) {
1846 if (!
parent->getTruthBinding()) {
1849 for (
auto *childParticle :
children) {
1850 if (!childParticle->getTruthBinding()) {
1851 ATH_MSG_ERROR(
"Could not retrieve TruthBinding from child ISFParticle "<< *childParticle);
1861 childVector=m_conversionTool->doConversionOnLayer(
parent, time, neu);
1864 if (m_validationMode && m_validationTool.isEnabled()) {
1867 for (
unsigned int i=0;
i<childVector.size();
i++) {
1872 childVector[
i]->setUserInformation(validInfo);
1881 for (
auto *childParticle : childVector) {
1882 if (!childParticle->getTruthBinding()) {
1883 ATH_MSG_ERROR(
"Could not retrieve TruthBinding from child ISFParticle "<< *childParticle);
1892 return ( m_hadIntProcessor->doHadIntOnLayer(
parent, time, position,
momentum,
1900 if (m_validationMode) {
1901 for (
unsigned int i=0;
i<childVector.size();
i++) {
1906 childVector[
i]->setUserInformation(validInfo);
1916 m_truthRecordSvc->registerTruthIncident( truth);
1922 if (m_validationMode && m_validationTool.isEnabled()) {
1930 for (
auto *childParticle : childVector) {
1931 if (!childParticle->getTruthBinding()) {
1932 ATH_MSG_ERROR(
"Could not retrieve TruthBinding from child ISFParticle "<< *childParticle);
1942 if (m_useConditions) {
1946 "Could not retrieve TrackingGeometry from Conditions Store.");
1949 return handle.
cptr();
1953 ->
retrieve(trackingGeometry, m_trackingGeometryName)
1955 ATH_MSG_FATAL(
"Could not retrieve TrackingGeometry from DetectorStore.");
1958 return trackingGeometry;