33#include "CLHEP/Random/RandFlat.h"
66 const std::string& name,
67 const IInterface* parent )
68: base_class(
type, name, parent)
85 return StatusCode::FAILURE;
90 if (resolvedFileName.empty()) {
92 return StatusCode::FAILURE;
94 ATH_MSG_INFO(
"[ punchthrough ] Parametrisation file found: " << resolvedFileName );
99 ATH_MSG_WARNING(
"[ punchthrough ] unable to open the lookup-table for the punch-through simulation (file does not exist)");
100 return StatusCode::FAILURE;
104 ATH_MSG_WARNING(
"[ punchthrough ] unable to open the lookup-table for the punch-through simulation (wrong or empty file?)");
105 return StatusCode::FAILURE;
111 ATH_MSG_WARNING(
"[ punchthrough ] unable to open or read the inverse CDF config");
112 return StatusCode::FAILURE;
118 ATH_MSG_WARNING(
"[ punchthrough ] unable to open or read the inverse PCA config");
119 return StatusCode::FAILURE;
125 ATH_MSG_WARNING(
"[ punchthrough ] size of infoMap for PCA and CDF differs! Something is wrong with input xml files.");
126 return StatusCode::FAILURE;
134 ATH_MSG_FATAL (
"[ punchthrough ] Could not retrieve GeometryIdentifier Service. Abort");
135 return StatusCode::FAILURE;
142 return StatusCode::FAILURE;
166 ATH_MSG_VERBOSE(
"[ punchthrough ] registering punch-through particle type with pdg = " << pdg );
167 if (
registerParticle( pdg, doAnti, minEnergy, maxNum, numFactor, energyFactor, posAngleFactor, momAngleFactor )
168 != StatusCode::SUCCESS)
170 ATH_MSG_ERROR(
"[ punchthrough ] unable to register punch-through particle type with pdg = " << pdg);
181 ATH_MSG_WARNING(
"[ punchthrough ] more punch-through particle correlations are given, than punch-through particle types are registered (skipping the last ones)");
186 for (
unsigned int num = 0; num < numCorrelations; num++ )
194 if ( ! pdg2)
continue;
196 if (
registerCorrelation(pdg1, pdg2, minCorrEnergy, fullCorrEnergy) != StatusCode::SUCCESS )
198 ATH_MSG_ERROR(
"[ punchthrough ] unable to register punch-through particle correlation for pdg1=" << pdg1 <<
" pdg2=" << pdg2 );
208 found1=
false; found2=
false;
210 for (
size_t i=0; i<rzCalo->size();++i)
212 const double r_tempCalo = rzCalo->at(i).first;
213 const double z_tempCalo = rzCalo->at(i).second;
217 for (
size_t j=0; j<rzMS->size();++j)
219 const double r_tempMS =rzMS->at(j).first;
220 const double z_tempMS =rzMS->at(j).second;
222 if (r_tempCalo==r_tempMS && z_tempCalo==z_tempMS && found1==
false )
225 m_z1=std::fabs(z_tempMS);
229 else if (r_tempCalo==r_tempMS && z_tempCalo==z_tempMS && r_tempCalo!=
m_R1 && std::fabs(z_tempCalo)!=
m_z1)
232 m_z2=std::fabs(z_tempMS);
237 if (found1==
true && found2==
true)
break;
242 if (found1 ==
false)
ATH_MSG_ERROR (
"first coordinate of calo-MS border not found");
243 if (found2 ==
false)
ATH_MSG_ERROR (
"second coordinate of calo-MS border not found; first one is: R1 ="<<
m_R1<<
" z1 ="<<
m_z1);
246 double r_temp, z_temp;
256 ATH_MSG_INFO(
"punchthrough initialization is successful" );
257 return StatusCode::SUCCESS;
274 return StatusCode::SUCCESS;
284 ATH_MSG_DEBUG(
"[ punchthrough ] starting punch-through simulation");
287 auto isfpCont = std::make_unique<ISF::ISFParticleVector>();
295 ATH_MSG_VERBOSE (
"[ GeoIDSvc ] input particle doesn't point to calorimeter"<<
"Next GeoID: "<<
m_geoIDSvc->identifyNextGeoID(isfp) );
307 for ( ; pdgIt != pdgItEnd; ++pdgIt, ++minEnergyIt)
309 if (std::abs(isfp.
pdgCode()) == *pdgIt){
310 if(std::sqrt( isfp.
momentum().mag2() + isfp.
mass()*isfp.
mass() ) < *minEnergyIt){
311 ATH_MSG_DEBUG(
"[ punchthrough ] particle does not meet initiator min energy requirement. Dropping it in the calo.");
319 if (pdgIt == pdgItEnd)
321 ATH_MSG_DEBUG(
"[ punchthrough ] particle is not registered as punch-through initiator. Dropping it in the calo.");
327 ATH_MSG_DEBUG(
"[ punchthrough ] particle does not meet initiator eta range requirement. Dropping it in the calo.");
335 double punchThroughClassifierRand = CLHEP::RandFlat::shoot(rndmEngine);
337 ATH_MSG_DEBUG(
"[ punchthrough ] punchThroughProbability output: " << punchThroughProbability <<
" RandFlat: " << punchThroughClassifierRand );
340 if( punchThroughClassifierRand > punchThroughProbability){
341 ATH_MSG_DEBUG(
"[ punchthrough ] particle not classified to create punch through. Dropping it in the calo.");
355 const double initEnergy = std::sqrt( isfp.
momentum().mag2() + isfp.
mass()*isfp.
mass() );
356 const double initEta = isfp.
position().eta();
362 std::map<int, int> corrPdgNumDone;
368 while(isfpCont->empty() && nTries < maxTries) {
373 int doPdg = currentParticle.first;
375 int corrPdg = currentParticle.second->getCorrelatedPdg();
381 std::map<int,int>::iterator pos = corrPdgNumDone.find(doPdg);
384 if ( pos == corrPdgNumDone.end() ) pos = corrPdgNumDone.find(corrPdg);
388 if ( pos == corrPdgNumDone.end() )
391 if ( CLHEP::RandFlat::shoot(rndmEngine) > 0.5 ) doPdg = corrPdg;
394 corrPdgNumDone[doPdg] =
getAllParticles(isfp, *isfpCont, rndmEngine, doPdg, interpEnergy, interpEta);
403 const int donePdg = pos->first;
404 const int doneNumPart = pos->second;
406 if (donePdg == doPdg) doPdg = corrPdg;
418 else getAllParticles(isfp, *isfpCont, rndmEngine, doPdg, interpEnergy, interpEta);
425 if (!isfpCont->empty())
ATH_MSG_DEBUG(
"[ punchthrough ] returning ISFparticle vector , size: "<<isfpCont->size() );
428 ATH_MSG_DEBUG(
"codes of produced punch through particle: pdg = "<< particle->pdgCode());
430 ATH_MSG_DEBUG(
"position of produced punch-through particle: x = "<< position.x() <<
" y = "<< position.y() <<
" z = "<< position.z());
432 ATH_MSG_DEBUG(
"momentum of produced punch-through particle: px = "<< momentum.x() <<
" py = "<< momentum.x() <<
" pz = "<< momentum.x() <<
" e = "<< particle->ekin() <<
" mass = " << particle->mass());
435 return isfpCont.release();
450 if ( numParticles < 0 )
453 std::vector<int> parameters;
454 parameters.push_back( std::round(interpEnergy) );
455 parameters.push_back( std::round(interpEta*100) );
458 int maxParticles = p->getMaxNumParticles();
464 numParticles = int( p->getNumParticlesPDF()->getRand(rndmEngine, parameters) );
467 numParticles = lround( numParticles *= p->getNumParticlesFactor() );
469 while ( (maxParticles >= 0.) && (numParticles > maxParticles) );
472 ATH_MSG_VERBOSE(
"[ punchthrough ] adding " << numParticles <<
" punch-through particles with pdg " << pdg);
475 double energyRest = std::sqrt( isfp.
momentum().mag2() + isfp.
mass()*isfp.
mass() );
476 double minEnergy = p->getMinEnergy();
479 for ( numCreated = 0; (numCreated < numParticles) && (energyRest > minEnergy); numCreated++ )
487 ATH_MSG_ERROR(
"[ punchthrough ] something went wrong while creating punch-through particles");
492 const double restMass =
m_gendata->particleMass(std::abs(pdg)).value();
493 double curEnergy = std::sqrt(par->momentum().mag2() + restMass*restMass);
497 energyRest -= curEnergy;
500 isfpCont.push_back( par );
517 const double initEnergy = std::sqrt( isfp.
momentum().mag2() + isfp.
mass()*isfp.
mass() );
520 double rand = CLHEP::RandFlat::shoot(rndmEngine)
521 *(p->getFullCorrelationEnergy()-p->getMinCorrelationEnergy())
522 + p->getMinCorrelationEnergy();
523 if ( initEnergy < rand )
526 return getAllParticles(isfp, isfpCont, rndmEngine, pdg, interpEnergy, interpEta);
531 double *histDomains = p->getCorrelationHistDomains();
532 TH2F *hist2d =
nullptr;
535 if ( initEnergy < histDomains[1])
539 hist2d = p->getCorrelationLowEHist();
543 double rand = CLHEP::RandFlat::shoot(rndmEngine)*(histDomains[2]-histDomains[1])
545 hist2d = ( initEnergy < rand) ? p->getCorrelationLowEHist()
546 : p->getCorrelationHighEHist();
553 Int_t xbin = hist2d->GetXaxis()->FindFixBin(corrParticles);
554 int numParticles = 0;
555 int maxParticles = p->getMaxNumParticles();
560 double rand = CLHEP::RandFlat::shoot(rndmEngine);
562 for (
int ybin = 1; ybin <= hist2d->GetNbinsY(); ybin++ )
564 sum += hist2d->GetBinContent(xbin, ybin);
568 numParticles = ybin - 1;
573 numParticles = lround( numParticles * p->getNumParticlesFactor() );
575 while ( (maxParticles >= 0.) && (numParticles > maxParticles) );
578 return getAllParticles(isfp, isfpCont, rndmEngine, pdg, interpEnergy, interpEta, numParticles);
594 ATH_MSG_DEBUG(
"[ punchthrough ] passedPCAIterator ==> pcaCdfIterator = "<< pcaCdfIterator <<
" , pdg = "<< pdg <<
" , interpEnergy = "<< interpEnergy <<
" MeV, interpEta(*100) = "<< interpEta*100);
598 if ( p->getdoAnti() )
601 double rand = CLHEP::RandFlat::shoot(rndmEngine);
603 if (rand > 0.5) anti = -1;
608 std::vector<int> parInitEnergyEta;
609 parInitEnergyEta.push_back( std::round(interpEnergy) );
610 parInitEnergyEta.push_back( std::round(interpEta*100) );
614 double deltaTheta = 0.;
616 double momDeltaTheta = 0.;
617 double momDeltaPhi = 0.;
619 double principal_component_0 = 0.;
620 double principal_component_1 = 0.;
621 double principal_component_2 = 0.;
622 double principal_component_3 = 0.;
623 double principal_component_4 = 0.;
624 std::vector<double> transformed_variables;
627 principal_component_0 = p->getPCA0PDF()->getRand(rndmEngine, parInitEnergyEta);
628 principal_component_1 = p->getPCA1PDF()->getRand(rndmEngine, parInitEnergyEta);
629 principal_component_2 = p->getPCA2PDF()->getRand(rndmEngine, parInitEnergyEta);
630 principal_component_3 = p->getPCA3PDF()->getRand(rndmEngine, parInitEnergyEta);
631 principal_component_4 = p->getPCA4PDF()->getRand(rndmEngine, parInitEnergyEta);
633 ATH_MSG_DEBUG(
"Drawn punch through kinematics PCA components: PCA0 = "<< principal_component_0 <<
" PCA1 = "<< principal_component_1 <<
" PCA2 = "<< principal_component_2 <<
" PCA3 = "<< principal_component_3 <<
" PCA4 = "<< principal_component_4 );
635 std::vector<double> principal_components {
636 principal_component_0,
637 principal_component_1,
638 principal_component_2,
639 principal_component_3,
640 principal_component_4
643 transformed_variables =
inversePCA(pcaCdfIterator,principal_components);
651 ATH_MSG_DEBUG(
"Transformed punch through kinematics: energy = "<< energy <<
" MeV deltaTheta = "<< deltaTheta <<
" deltaPhi = "<<
deltaPhi <<
" momDeltaTheta = "<< momDeltaTheta <<
" momDeltaPhi = "<< momDeltaPhi );
653 energy *= p->getEnergyFactor();
654 if (energy < p->getMinEnergy()) {
655 energy = p->getMinEnergy() + 10;
665 deltaTheta *= ( CLHEP::RandFlat::shoot(rndmEngine) > 0.5 ) ? 1. : -1.;
668 theta = isfp.
position().theta() + deltaTheta*p->getPosAngleFactor();
674 deltaPhi *= ( CLHEP::RandFlat::shoot(rndmEngine) > 0.5 ) ? 1. : -1.;
686 double momTheta = 0.;
690 momDeltaTheta *= ( CLHEP::RandFlat::shoot(rndmEngine) > 0.5 ) ? 1. : -1.;
693 momTheta =
theta + momDeltaTheta*p->getMomAngleFactor();
696 while ( (momTheta >
M_PI) || (momTheta < 0.) );
700 momDeltaPhi *= ( CLHEP::RandFlat::shoot(rndmEngine) > 0.5 ) ? 1. : -1.;
702 double momPhi =
phi + momDeltaPhi*p->getMomAngleFactor();
704 while ( std::fabs(momPhi) > 2*
M_PI) momPhi /= 2.;
705 while (momPhi >
M_PI) momPhi -= 2*
M_PI;
706 while (momPhi < -
M_PI) momPhi += 2*
M_PI;
710 ATH_MSG_DEBUG(
"createExitPs input parameters: doAnti? = "<< pdg*anti <<
" energy = "<< energy <<
" theta = "<<
theta <<
" phi = "<<
phi <<
" momTheta = "<< momTheta <<
" momPhi " << momPhi );
720 return 0.5 * TMath::Erfc(-
x * M_SQRT1_2);
725 std::vector<double> result;
726 result.reserve(m.size());
727 for (
const auto&
r : m){
728 result.push_back(std::inner_product(v.begin(), v.end(),
r.begin(), 0.0));
737 constexpr char delimiters =
',';
738 std::vector<T> tokens;
740 std::string_view::size_type lastPos =
str.find_first_not_of(delimiters, 0);
742 std::string_view::size_type pos =
str.find_first_of(delimiters, lastPos);
744 while (std::string_view::npos != pos || std::string_view::npos != lastPos) {
746 std::string_view numbStr =
str.substr(lastPos, pos - lastPos);
748 std::from_chars(numbStr.data(), numbStr.data() + numbStr.size(), num);
749 tokens.push_back(num);
751 lastPos =
str.find_first_not_of(delimiters, pos);
753 pos =
str.find_first_of(delimiters, lastPos);
761 int pidStrSingle = std::abs(pid);
765 for (
int i = 0;
const InfoMap& m : mapvect) {
767 const std::vector<int>& v = m.pidStr;
768 if(std::find(v.begin(), v.end(),pidStrSingle)==v.end())
continue;
769 assert(m.etaMaxs.size() == m.etaMins.size());
770 for (
unsigned int j = 0; j < m.etaMins.size(); j++){
771 double etaMinToCompare = m.etaMins[j];
772 double etaMaxToCompare = m.etaMaxs[j];
773 if((
eta >= etaMinToCompare) && (
eta < etaMaxToCompare)){
793 std::vector<InfoMap> xml_info;
795 for (
const XMLCoreNode*
node : doc.get_children (mainNode +
"/info/item")) {
796 xml_info.emplace_back(*
node);
806 std::transform (transformed_variables.begin(), transformed_variables.end(),
m_PCA_means[pcaCdfIterator].begin(), transformed_variables.begin(), std::plus<double>());
808 return transformed_variables;
814 std::unique_ptr<XMLCoreNode> doc = p.parse (inversePCAConfigFile);
816 ATH_MSG_INFO(
"[ punchthrough ] Loading inversePCA: " << inversePCAConfigFile);
822 const std::string& attrib,
824 -> std::vector<double>
826 std::vector<double> row;
827 for (
int i = 0; i <=
imax; ++i) {
829 std::string propName = attrib + std::to_string(i);
830 row.push_back (
node->get_double_attrib (propName));
836 std::vector<std::vector<double>> PCA_matrix;
840 PCA_matrix.push_back(getRow(matrix,
"comp_", 4));
850 return StatusCode::SUCCESS;
856 std::unique_ptr<XMLCoreNode> doc = p.parse (inverseCdfConfigFile);
858 ATH_MSG_INFO(
"[ punchthrough ] Loading inverse CDF: " << inverseCdfConfigFile);
875 return StatusCode::SUCCESS;
878std::map<double, double>
881 std::map<double, double> mappings;
885 double ref = child->get_double_attrib (
"ref");
886 double quant = child->get_double_attrib (
"quant");
898 auto upper = inverse_cdf_map.upper_bound(norm_cdf);
899 auto lower =
upper--;
901 double m = (
upper->second - lower->second)/(
upper->first - lower->first);
902 double c = lower->second - m * lower->first;
903 double transformed = m * norm_cdf + c;
911 ATH_MSG_DEBUG(
"[ punchthrough ] interpolating incoming energy: " << energy);
913 std::string energyPointsString;
915 energyPointsString += std::to_string(element) +
" ";
918 ATH_MSG_DEBUG(
"[ punchthrough ] available energy points: " << energyPointsString);
923 ATH_MSG_DEBUG(
"[ punchthrough ] incoming energy > largest energy point, returning greatest energy point: " <<
m_energyPoints.back());
927 ATH_MSG_DEBUG(
"[ punchthrough ] incoming energy < smallest energy point, returning smallest energy point: " << *upperEnergy);
931 ATH_MSG_DEBUG(
"[ punchthrough ] energy points upper_bound: "<< *upperEnergy);
933 double randomShoot = CLHEP::RandFlat::shoot(rndmEngine);
935 ATH_MSG_DEBUG(
"[ punchthrough ] Shooting random number: "<< randomShoot);
937 double midPoint = *std::prev(upperEnergy)*M_SQRT2;
939 if(energy < midPoint){
941 double distance = std::abs(energy - *std::prev(upperEnergy))/((midPoint) - *std::prev(upperEnergy));
943 ATH_MSG_DEBUG(
"[ punchthrough ] incoming energy is closest to prev(upper_bound) in log(energy), distance: " << distance );
945 if(randomShoot < distance){
946 ATH_MSG_DEBUG(
"[ punchthrough ] randomShoot < distance, returning upper_bound " << *upperEnergy );
949 ATH_MSG_DEBUG(
"[ punchthrough ] randomShoot > distance, returning prev(upper_bound) " << *std::prev(upperEnergy) );
951 return *std::prev(upperEnergy);
953 else if(energy > midPoint){
955 double distance = std::abs(energy - *upperEnergy)/((*upperEnergy - midPoint));
957 ATH_MSG_DEBUG(
"[ punchthrough ] incoming energy is closest to upper_bound in log(energy), distance: " << distance );
959 if(randomShoot < distance){
960 ATH_MSG_DEBUG(
"[ punchthrough ] randomShoot < distance, returning prev(upper_bound) " << *std::prev(upperEnergy) );
961 return *std::prev(upperEnergy);
963 ATH_MSG_DEBUG(
"[ punchthrough ] randomShoot > distance, returning upper_bound " << *upperEnergy );
972 double absEta = std::abs(
eta);
974 ATH_MSG_DEBUG(
"[ punchthrough ] interpolating incoming abs(eta): " << absEta);
976 std::string etaPointsString;
978 etaPointsString += std::to_string(element) +
" ";
981 ATH_MSG_DEBUG(
"[ punchthrough ] available eta points: " << etaPointsString);
986 ATH_MSG_DEBUG(
"[ punchthrough ] incoming abs(eta) > largest eta point, returning greatest eta point: " <<
m_etaPoints.back());
991 ATH_MSG_DEBUG(
"[ punchthrough ] eta points upper_bound: "<< *upperEta);
993 double randomShoot = CLHEP::RandFlat::shoot(rndmEngine);
995 ATH_MSG_DEBUG(
"[ punchthrough ] Shooting random number: "<< randomShoot);
997 if(std::abs(absEta - *upperEta) < std::abs(absEta - *std::prev(upperEta))){
999 double distance = std::abs(absEta - *upperEta)/((*upperEta - *std::prev(upperEta))/2);
1001 ATH_MSG_DEBUG(
"[ punchthrough ] abs(eta) is closer to eta points upper_bound, distance: " << distance );
1003 if(randomShoot > distance){
1004 ATH_MSG_DEBUG(
"[ punchthrough ] randomShoot > distance, returning upper_bound " << *upperEta );
1008 ATH_MSG_DEBUG(
"[ punchthrough ] randomShoot < distance, returning prev(upper_bound) " << *std::prev(upperEta) );
1010 return *std::prev(upperEta);
1012 else if(std::abs(absEta - *std::prev(upperEta)) < std::abs(absEta - *upperEta)){
1015 ATH_MSG_DEBUG(
"[ punchthrough ] prev of upper bound is begin, returning that: " << *std::prev(upperEta) );
1016 return *std::prev(upperEta);
1019 double distance = std::abs(absEta - *std::prev(upperEta))/((*std::prev(upperEta) - *std::prev(std::prev(upperEta)))/2);
1021 ATH_MSG_DEBUG(
"[ punchthrough ] abs(eta) is closer to eta points prev(upper_bound), distance: " << distance );
1023 if(randomShoot > distance){
1024 ATH_MSG_DEBUG(
"[ punchthrough ] randomShoot > distance, returning prev(prev(upper_bound)) " << *std::prev(std::prev(upperEta)) );
1026 return *std::prev(std::prev(upperEta));
1028 ATH_MSG_DEBUG(
"[ punchthrough ] randomShoot < distance, returning prev(upper_bound) " << *std::prev(upperEta) );
1030 return *std::prev(upperEta);
1033 return *std::prev(upperEta);
1043 double minEnergy,
int maxNumParticles,
double numParticlesFactor,
1044 double energyFactor,
double posAngleFactor,
double momAngleFactor)
1050 if (!pdf_num )
return StatusCode::FAILURE;
1056 return StatusCode::FAILURE;
1064 return StatusCode::FAILURE;
1072 return StatusCode::FAILURE;
1079 return StatusCode::FAILURE;
1086 return StatusCode::FAILURE;
1091 particle->setNumParticlesPDF(std::move(pdf_num));
1092 particle->setPCA0PDF(std::move(pdf_pca0));
1093 particle->setPCA1PDF(std::move(pdf_pca1));
1094 particle->setPCA2PDF(std::move(pdf_pca2));
1095 particle->setPCA3PDF(std::move(pdf_pca3));
1096 particle->setPCA4PDF(std::move(pdf_pca4));
1099 const double restMass =
m_gendata->particleMass(std::abs(pdg)).value();
1100 minEnergy = ( minEnergy > restMass ) ? minEnergy : restMass;
1101 particle->setMinEnergy(minEnergy);
1102 particle->setMaxNumParticles(maxNumParticles);
1103 particle->setNumParticlesFactor(numParticlesFactor);
1104 particle->setEnergyFactor(energyFactor);
1105 particle->setPosAngleFactor(posAngleFactor);
1106 particle->setMomAngleFactor(momAngleFactor);
1111 return StatusCode::SUCCESS;
1120 double minCorrEnergy,
double fullCorrEnergy)
1123 std::map<int, PunchThroughParticle*>::iterator location1 =
m_particles.find(pdgID1);
1124 std::map<int, PunchThroughParticle*>::iterator location2 =
m_particles.find(pdgID2);
1128 return StatusCode::FAILURE;
1131 std::stringstream name;
1132 name <<
"NumExitCorrelations/x_PDG" << std::abs(pdgID1) <<
"__y_PDG" << std::abs(pdgID2) <<
"__lowE";
1135 name <<
"NumExitCorrelations/x_PDG" << std::abs(pdgID1) <<
"__y_PDG" << std::abs(pdgID2) <<
"__highE";
1138 name <<
"NumExitCorrelations/x_PDG" << std::abs(pdgID2) <<
"__y_PDG" << std::abs(pdgID1) <<
"__lowE";
1141 name <<
"NumExitCorrelations/x_PDG" << std::abs(pdgID2) <<
"__y_PDG" << std::abs(pdgID1) <<
"__highE";
1144 if ( (!hist1_2_lowE) || (!hist2_1_lowE) || (!hist1_2_highE) || (!hist2_1_highE) )
1146 ATH_MSG_ERROR(
"[ punchthrough ] unable to retrieve the correlation data for PDG IDs " << pdgID1 <<
" and " << pdgID2);
1147 return StatusCode::FAILURE;
1159 m_particles[pdgID1]->setCorrelation(pdgID2, hist2_1_lowE, hist2_1_highE,
1160 minCorrEnergy, fullCorrEnergy,
1161 lowE, midE, upperE);
1163 m_particles[pdgID2]->setCorrelation(pdgID1, hist1_2_lowE, hist1_2_highE,
1164 minCorrEnergy, fullCorrEnergy,
1165 lowE, midE, upperE);
1166 return StatusCode::SUCCESS;
1181 std::unique_ptr<ISF::PDFcreator> pdf = std::make_unique<ISF::PDFcreator>();
1184 std::stringstream dirName;
1185 dirName << folderName << pdg;
1186 pdf->setName(dirName.str().c_str());
1191 ATH_MSG_ERROR(
"[ punchthrough ] unable to retrieve directory object ("<< folderName << pdg <<
")" );
1198 TIter keyList(dir->GetListOfKeys());
1201 while ((key = (TKey*)keyList())) {
1204 TH1* hist =
nullptr;
1206 std::string histName;
1207 if(strcmp(key->GetClassName(),
"TH1F") == 0){
1208 hist = (TH1*)key->ReadObj();
1209 histName = hist->GetName();
1213 std::string strEnergy = histName.substr( histName.find_first_of(
'E') + 1, histName.find_first_of(
'_')-histName.find_first_of(
'E') - 1 );
1214 histName.erase(0, histName.find_first_of(
'_') + 1);
1215 std::string strEtaMin = histName.substr( histName.find(
"etaMin") + 6, histName.find_first_of(
'_') - histName.find(
"etaMin") - 6 );
1216 histName.erase(0, histName.find(
'_') + 1);
1217 std::string strEtaMax = histName.substr( histName.find(
"etaMax") + 6, histName.length());
1220 const int energy = std::stoi(strEnergy);
1221 const int etaMin = std::stoi(strEtaMin);
1224 pdf->addToEnergyEtaHist1DMap(energy, etaMin, hist);
1227 const double energyDbl =
static_cast<double>(energy);
1228 const double etaDbl =
static_cast<double>(etaMin)/100.;
1251 double energy,
double theta,
double phi,
double momTheta,
double momPhi)
const
1263 double mass =
m_gendata->particleMass(std::abs(pdg)).value();
1264 Amg::setRThetaPhi( mom, std::sqrt(energy*energy - mass*mass), momTheta, momPhi);
1265 ATH_MSG_DEBUG(
"setRThetaPhi pre input parameters: energy = "<< energy <<
" mass = "<< mass);
1266 ATH_MSG_DEBUG(
"setRThetaPhi input parameters: std::sqrt(energy*energy - mass*mass) = "<< std::sqrt(energy*energy - mass*mass) <<
" momTheta = "<< momTheta <<
" momPhi = "<< momPhi);
1271 charge *= (pdg > 0.) ? 1. : -1.;
1273 const double pTime = 0;
1294 const std::string_view
str( cstr);
1295 const std::string_view pattern( cpattern);
1296 const size_t pos =
str.find(pattern);
1298 if ( pos == std::string::npos)
1300 ATH_MSG_WARNING(
"[ punchthrough ] unable to retrieve floating point number from string");
1301 return -999999999999.;
1303 const std::string_view substring =
str.substr(pos+pattern.length());
1304 std::from_chars(substring.data(), substring.data() + substring.size(), num);
1317 const double theta1 = atan (
m_R1/
m_z1);
1318 const double theta2 = atan (
m_R1/
m_z2);
1319 const double theta3 = atan (
m_R2/
m_z2);
1337 else if (
theta >= theta3 &&
theta < (TMath::Pi()-theta3) )
1342 else if (
theta >= (TMath::Pi()-theta3) &&
theta < (TMath::Pi()-theta2) )
1347 else if (
theta >= (TMath::Pi()-theta2) &&
theta < (TMath::Pi()-theta1) )
1352 else if (
theta >= (TMath::Pi()-theta1) &&
theta <= TMath::Pi() )
1361 ATH_MSG_WARNING (
"Given theta angle is incorrect, setting particle position to (0, 0, 0)");
1362 x = 0.0;
y = 0.0;
z = 0.0;
r = 0.0;
1369 ATH_MSG_DEBUG(
"position of produced punch-through particle: x = "<<
x <<
" y = "<<
y <<
" z = "<<
z<<
" r = "<< pos.perp() <<
"std::sqrt(x^2+y^2) = "<< std::sqrt(
x*
x+
y*
y) );
const std::regex ref(r_ef)
Scalar eta() const
pseudorapidity method
Scalar deltaPhi(const MatrixBase< Derived > &vec) const
Scalar phi() const
phi method
Scalar theta() const
theta method
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
double charge(const T &p)
An STL vector of pointers that by default owns its pointed-to elements.
ATLAS-specific HepMC functions.
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
std::vector< RZPair > RZPairVector
Simple DOM-like node structure to hold the result of XML parsing.
The generic ISF particle definition,.
const Amg::Vector3D & momentum() const
The current momentum vector of the ISFParticle.
void setNextGeoID(AtlasDetDescr::AtlasRegion geoID)
register the next AtlasDetDescr::AtlasRegion
const Amg::Vector3D & position() const
The current position of the ISFParticle.
int pdgCode() const
PDG value.
double mass() const
mass of the particle
This class holds information for different properties of a punch-through particle (energy,...
Simple DOM-like node structure to hold the result of XML parsing.
void setRThetaPhi(Amg::Vector3D &v, double r, double theta, double phi)
sets radius, the theta and phi angle of a vector.
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.
double charge(const T &p)