Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
PunchThroughG4Tool Class Reference

Punch through calculations. More...

#include <PunchThroughG4Tool.h>

Inheritance diagram for PunchThroughG4Tool:
Collaboration diagram for PunchThroughG4Tool:

Public Member Functions

 PunchThroughG4Tool (const std::string &, const std::string &, const IInterface *)
 
virtual ~PunchThroughG4Tool ()=default
 
virtual StatusCode initialize () override
 AlgTool initialize method. More...
 
virtual StatusCode finalize () override
 AlgTool finalize method. More...
 
virtual std::vector< std::map< std::string, double > > computePunchThroughParticles (const G4FastTrack &fastTrack, CLHEP::HepRandomEngine *rndmEngine, double punchThroughProbability, double punchThroughClassifierRand) override
 interface function: fill a vector with the punch-through particles More...
 
virtual void createAllSecondaryTracks (G4ParticleTable &ptable, G4FastStep &fastStep, const G4Track &g4PrimaryTrack, std::vector< std::map< std::string, double >> &secKinematicsMapVect, G4TrackVector &secTrackCont, const std::vector< double > &caloMSVars) override
 create all secondary tracks from kinematics map More...
 
virtual std::vector< double > getCaloMSVars () override
 

Private Member Functions

void checkParticleTable (G4ParticleTable &ptable, int secondarySignedPDG)
 
StatusCode registerPunchThroughParticle (G4ParticleTable &ptable, int pdg, bool doAntiparticle=false, double minEnergy=0., int maxNumParticles=-1, double numParticlesFactor=1., double energyFactor=1., double posAngleFactor=1., double momAngleFactor=1.)
 registers a type of punch-through particles which will be simulated More...
 
StatusCode initializeRegisterPunchThroughParticles ()
 initialize register all the punch-through particles which will be simulated More...
 
StatusCode registerCorrelation (int pdgID1, int pdgID2, double minCorrEnergy=0., double fullCorrEnergy=0.)
 register a correlation for the two given types of punch-through particles with a given energy threshold above which we will have full correlation More...
 
StatusCode initializeRegisterCorrelations ()
 initialize register all correlations between particles More...
 
std::unique_ptr< PunchThroughPDFCreatorreadLookuptablePDF (int pdgID, TFile *fileLookupTable, const std::string &folderName)
 reads out the lookuptable for the given type of particle More...
 
StatusCode checkCaloMSBoundaries (const std::vector< std::pair< double, double >> *rzMS, const std::vector< std::pair< double, double >> *rzCalo)
 Check calo-MS boundaries. More...
 
int getAllParticles (const G4Track &g4PrimaryTrack, std::vector< std::map< std::string, double >> &secKinematicsMapVect, CLHEP::HepRandomEngine *rndmEngine, int pdg, double interpEnergy, double interpEta, int numParticles=-1)
 create the right number of punch-through particles for the given pdg and return the number of particles which was created. More...
 
G4ThreeVector punchTroughPosPropagator (double theta, double phi, double R1, double R2, double z1, double z2) const
 get particle through the calorimeter More...
 
std::vector< std::map< std::string, double > > checkEnergySumFromSecondaries (double mainEnergyInit, std::vector< std::map< std::string, double >> &secKinematicsMapVect)
 check the energies satisfying energy condition More...
 
G4Track * createSecondaryTrack (G4ParticleTable &ptable, G4FastStep &fastStep, double currentTime, int secondarySignedPDG, double energy, double theta, double phi, double momTheta, double momPhi, const std::vector< double > &caloMSVars)
 create secondary track for each given the kinematics More...
 
int getCorrelatedParticles (const G4Track &g4PrimaryTrack, std::vector< std::map< std::string, double >> &secKinematicsMapVect, int pdg, int corrParticles, CLHEP::HepRandomEngine *rndmEngine, double interpEnergy, double interpEta)
 get the right number of particles for the given pdg while considering the correlation to an other particle type, which has already created 'corrParticles' number of particles More...
 
std::map< std::string, double > getOneParticleKinematics (CLHEP::HepRandomEngine *rndmEngine, int secondaryPDG, float initParticleTheta, float initParticlePhi, double interpEnergy, double interpEta) const
 create exactly one punch-through particle with the given pdg and the given max energy More...
 
double getFloatAfterPatternInStr (const char *str, const char *pattern)
 get the floating point number in a string, after the given pattern More...
 
std::vector< double > inversePCA (int pcaCdfIterator, std::vector< double > &variables) const
 
double interpolateEnergy (const double &energy, CLHEP::HepRandomEngine *rndmEngine) const
 
double interpolateEta (const double &eta, CLHEP::HepRandomEngine *rndmEngine) const
 
std::vector< std::map< std::string, std::string > > getInfoMap (const std::string &mainNode, const std::string &xmlFilePath)
 
int passedParamIterator (int pid, double eta, const std::vector< std::map< std::string, std::string >> &mapvect) const
 
StatusCode initializeInverseCDF (const std::string &quantileTransformerConfigFile)
 
StatusCode initializeInversePCA (const std::string &inversePCAConfigFile)
 

Static Private Member Functions

static double inverseCdfTransform (double variable, const std::map< double, double > &inverse_cdf_map)
 
static std::vector< double > dotProduct (const std::vector< std::vector< double >> &m, const std::vector< double > &v)
 
static double normal_cdf (double x)
 
static std::map< double, double > getVariableCDFmappings (xmlNodePtr &nodeParent)
 

Private Attributes

std::vector< double > m_energyPoints
 energy and eta points in param More...
 
std::vector< double > m_etaPoints
 
double m_R1 {0.}
 calo-MS borders More...
 
double m_R2 {0.}
 
double m_z1 {0.}
 
double m_z2 {0.}
 
TFile * m_fileLookupTable {nullptr}
 ROOT objects. More...
 
std::map< int, PunchThroughParticle * > m_particles
 needed to initially create punch-through particles with the right distributions More...
 
StringProperty m_filenameLookupTable {this, "FilenameLookupTable", "CaloPunchThroughParametrisation.root", "holds the filename of the lookup table"}
 
StringProperty m_filenameInverseCDF {this, "FilenameInverseCdf", "", "holds the filename of inverse quantile transformer config"}
 
StringProperty m_filenameInversePCA {this, "FilenameInversePca", "", "holds the filename of inverse PCA config"}
 
IntegerArrayProperty m_pdgInitiators {this, "PunchThroughInitiators", {}, "vector of punch-through initiator pgds"}
 
IntegerArrayProperty m_initiatorsMinEnergy {this, "InitiatorsMinEnergy", {}, "vector of punch-through initiator min energies to create punch through"}
 
DoubleArrayProperty m_initiatorsEtaRange {this, "InitiatorsEtaRange", {}, "vector of min and max abs eta range to allow punch through initiators"}
 
IntegerArrayProperty m_punchThroughParticles {this, "PunchThroughParticles", {}, "vector of pdgs of the particles produced in punch-throughs"}
 
BooleanArrayProperty m_doAntiParticles {this, "DoAntiParticles", {}, "vector of bools to determine if anti-particles are created for each punch-through particle type"}
 
IntegerArrayProperty m_correlatedParticle {this, "CorrelatedParticle", {}, "holds the pdg of the correlated particle for each given pdg"}
 
DoubleArrayProperty m_minCorrEnergy {this, "MinCorrelationEnergy", {}, "holds the energy threshold below which no particle correlation is computed"}
 
DoubleArrayProperty m_fullCorrEnergy {this, "FullCorrelationEnergy", {}, "holds the energy threshold above which a particle correlation is fully developed"}
 
DoubleArrayProperty m_posAngleFactor {this, "ScalePosDeflectionAngles", {}, "tuning parameter to scale the position deflection angles"}
 
DoubleArrayProperty m_momAngleFactor {this, "ScaleMomDeflectionAngles", {}, "tuning parameter to scale the momentum deflection angles"}
 
DoubleArrayProperty m_minEnergy {this, "MinEnergy", {}, "punch-through particles minimum energies"}
 
IntegerArrayProperty m_maxNumParticles {this, "MaxNumParticles", {}, "maximum number of punch-through particles for each particle type"}
 
DoubleArrayProperty m_numParticlesFactor {this, "NumParticlesFactor", {}, "scale the number of punch-through particles"}
 
DoubleArrayProperty m_energyFactor {this, "EnergyFactor", {}, "scale the energy of the punch-through particles"}
 
ServiceHandle< ISF::IGeoIDSvcm_geoIDSvc {this, "GeoIDSvc", "ISF::GeoIDSvc"}
 
ServiceHandle< IEnvelopeDefSvcm_envDefSvc {this, "EnvelopeDefSvc", "AtlasGeometry_EnvelopeDefSvc"}
 
DoubleProperty m_beamPipe {this, "BeamPipeRadius", 500.}
 beam pipe radius More...
 
std::vector< std::vector< std::vector< double > > > m_inverse_PCA_matrix
 pca vectors More...
 
std::vector< std::vector< double > > m_PCA_means
 
std::vector< std::map< std::string, std::string > > m_xml_info_pca
 infoMaps More...
 
std::vector< std::map< std::string, std::string > > m_xml_info_cdf
 
std::vector< std::map< double, double > > m_variable0_inverse_cdf
 (vector of map) for CDF mappings More...
 
std::vector< std::map< double, double > > m_variable1_inverse_cdf
 
std::vector< std::map< double, double > > m_variable2_inverse_cdf
 
std::vector< std::map< double, double > > m_variable3_inverse_cdf
 
std::vector< std::map< double, double > > m_variable4_inverse_cdf
 

Detailed Description

Punch through calculations.

Author
Elmar Ritsch Elmar.nosp@m..Rit.nosp@m.sch@c.nosp@m.ern..nosp@m.ch @maintainer/updater Thomas Carter thoma.nosp@m.s.mi.nosp@m.chael.nosp@m..car.nosp@m.ter@c.nosp@m.ern..nosp@m.ch @maintainer/updater Firdaus Soberi firda.nosp@m.us.s.nosp@m.oberi.nosp@m.@cer.nosp@m.n.ch

Definition at line 49 of file PunchThroughG4Tool.h.

Constructor & Destructor Documentation

◆ PunchThroughG4Tool()

PunchThroughG4Tool::PunchThroughG4Tool ( const std::string &  type,
const std::string &  name,
const IInterface *  parent 
)

Definition at line 39 of file PunchThroughG4Tool.cxx.

40  : base_class(type,name,parent)
41 {
42 }

◆ ~PunchThroughG4Tool()

virtual PunchThroughG4Tool::~PunchThroughG4Tool ( )
virtualdefault

Member Function Documentation

◆ checkCaloMSBoundaries()

StatusCode PunchThroughG4Tool::checkCaloMSBoundaries ( const std::vector< std::pair< double, double >> *  rzMS,
const std::vector< std::pair< double, double >> *  rzCalo 
)
private

Check calo-MS boundaries.

Definition at line 201 of file PunchThroughG4Tool.cxx.

203 {
204  bool found1, found2;
205  found1=false; found2=false;
206 
207  // procedure below is to find intersection of calo and MS boundary (right at the edge of calo and into MS)
208  // at least 2 distinct calo-MS boundary points must be found to proceed
209  for ( const auto & [r_tempCalo , z_tempCalo] : *rzCalo )
210  {
211  // calo point must be more than beampipe radius
212  if (r_tempCalo> m_beamPipe)
213  {
214  for ( const auto & [r_tempMS , z_tempMS] : *rzMS )
215  {
216  // first point, if R and Z of calo matches R and Z of MS
217  if (r_tempCalo==r_tempMS && z_tempCalo==z_tempMS && found1==false )
218  {
219  m_R1=r_tempMS;
220  m_z1=std::fabs(z_tempMS);
221  found1=true;
222  continue;
223  }
224  // second point, if R and Z of calo matches R and Z of MS
225  else if (r_tempCalo==r_tempMS && z_tempCalo==z_tempMS && r_tempCalo!=m_R1 && std::fabs(z_tempCalo)!=m_z1)
226  {
227  m_R2=r_tempMS;
228  m_z2=std::fabs(z_tempMS);
229  found2=true;
230  }
231  }
232 
233  if (found1==true && found2==true) break;
234  }
235  }
236 
237  //in case geometry description changes
238  if (found1 == false){
239  ATH_MSG_ERROR ("[PunchThroughG4Tool] first coordinate of calo-MS border not found");
240  return StatusCode::FAILURE;
241  }
242  if (found2 == false){
243  ATH_MSG_ERROR ("[PunchThroughG4Tool] second coordinate of calo-MS border not found; first one is: R1 ="<<m_R1<<" z1 ="<<m_z1);
244  return StatusCode::FAILURE;
245  }
246 
247  //now order the found values
248  if (m_R1>m_R2) { std::swap(m_R1, m_R2); } //m_R1 - smaller one
249  if (m_z1<m_z2) { std::swap(m_z1, m_z2); } //m_z1 - bigger one
250 
251  if (m_R1==m_R2 || m_z1==m_z2){
252  ATH_MSG_ERROR ("[PunchThroughG4Tool] Bug in propagation calculation! R1="<<m_R1<<" R2 = "<<m_R2<<" z1="<<m_z1<<" z2= "<<m_z2 );
253  return StatusCode::FAILURE;
254  }
255 
256  ATH_MSG_DEBUG ("[PunchThroughG4Tool] calo-MS boundary coordinates: R1="<<m_R1<<" R2 = "<<m_R2<<" z1="<<m_z1<<" z2= "<<m_z2);
257 
258  return StatusCode::SUCCESS;
259 }

◆ checkEnergySumFromSecondaries()

std::vector< std::map< std::string, double > > PunchThroughG4Tool::checkEnergySumFromSecondaries ( double  mainEnergyInit,
std::vector< std::map< std::string, double >> &  secKinematicsMapVect 
)
private

check the energies satisfying energy condition

Definition at line 708 of file PunchThroughG4Tool.cxx.

708  {
709  //initialize variables
710  double energy;
711  double totEnergySecondaries = 0;
712 
713  // Check energy conservation
714  // Step 1: sum all of the energies from the vector of secondaries (map) together, to initialize procedure later
715  for (std::size_t i = 0; i < secKinematicsMapVect.size(); i++) {
716  energy = secKinematicsMapVect[i].at("energy");
717  totEnergySecondaries += energy;
718  }
719 
720  // Step 2: Sort the vector based on "energy" in descending order using lambda expression
721  std::sort(
722  secKinematicsMapVect.begin(),
723  secKinematicsMapVect.end(),
724  [](const std::map<std::string, double>& lhs, const std::map<std::string, double>& rhs) {
725  return lhs.at("energy") > rhs.at("energy");
726  }
727  );
728 
729  // Just for printing here
730  if(totEnergySecondaries > mainEnergyInit){
731  ATH_MSG_DEBUG("[PunchThroughG4Tool::checkEnergySumFromSecondaries] Case where energy of created secondaries more than parent track identified! ");
732  ATH_MSG_DEBUG("[PunchThroughG4Tool::checkEnergySumFromSecondaries] ==> TotalSecondariesEnergy = " << totEnergySecondaries << ", ParentEnergy = "<< mainEnergyInit);
733  }
734 
735  // Step 3: Adjust the energy and remove secondary with lowest energy to ensure total energy of secondaries <= mainEnergyInit
736  while (totEnergySecondaries > mainEnergyInit && !secKinematicsMapVect.empty()) {
737  // Get the last map in the vector (which has the lowest energy due to sorting)
738  std::map<std::string, double> lastMap = secKinematicsMapVect.back();
739 
740  // Get the energy value of the last map
741  double lastEnergy = lastMap.at("energy");
742 
743  // Remove the last map from the vector
744  secKinematicsMapVect.pop_back();
745 
746  // Subtract the removed energy from totEnergySecondaries
747  totEnergySecondaries -= lastEnergy;
748  }
749 
750  //finally return the secKinematicsMapVect after the checks
751  return secKinematicsMapVect;
752 }

◆ checkParticleTable()

void PunchThroughG4Tool::checkParticleTable ( G4ParticleTable &  ptable,
int  secondarySignedPDG 
)
private

Definition at line 273 of file PunchThroughG4Tool.cxx.

273  {
274  // Get Geant4 particle definition
275  G4ParticleDefinition* secG4Particle = ptable.FindParticle(secondarySignedPDG);
276  double mass = secG4Particle->GetPDGMass();
277  ATH_MSG_DEBUG("[PunchThroughG4Tool::checkParticleTable] secondarySignedPDG = " << secondarySignedPDG << ", mass = "<< mass);
278 }

◆ computePunchThroughParticles()

std::vector< std::map< std::string, double > > PunchThroughG4Tool::computePunchThroughParticles ( const G4FastTrack &  fastTrack,
CLHEP::HepRandomEngine *  rndmEngine,
double  punchThroughProbability,
double  punchThroughClassifierRand 
)
overridevirtual

interface function: fill a vector with the punch-through particles

Definition at line 280 of file PunchThroughG4Tool.cxx.

281 {
282  ATH_MSG_DEBUG( "[PunchThroughG4Tool] starting punch-through simulation");
283 
284  // holder to all secondary particle kinematics
285  std::vector<std::map<std::string, double>> secKinematicsMapVect;
286 
287  // Get primary Geant4 track (main particle producing punchthrough)
288  const G4Track * g4PrimaryTrack = fastTrack.GetPrimaryTrack();
289 
290  // Get Geant4 particle definition
291  const G4ParticleDefinition * mainG4Particle = g4PrimaryTrack->GetDefinition();
292 
293  // Get primary Geant4 particle properties
294  int pdgID = mainG4Particle->GetPDGEncoding();
295  float mainPartMass = mainG4Particle->GetPDGMass();
296  float mainMomMag2 = g4PrimaryTrack->GetMomentum().mag2();
297  float mainPartEta = g4PrimaryTrack->GetPosition().eta();
298  // get primary track's current position and momentum direction
299  const G4ThreeVector mainMomentumDir = g4PrimaryTrack->GetMomentumDirection();
300  const G4ThreeVector mainMomentum = g4PrimaryTrack->GetMomentum();
301  const G4ThreeVector mainPosition = g4PrimaryTrack->GetPosition();
302 
303  // calculate incoming energy and eta
304  const double initEnergy = std::sqrt( mainMomMag2 + mainPartMass*mainPartMass );
305  const double initEta = mainPartEta;
306 
307  ATH_MSG_DEBUG("[PunchThroughG4Tool] position of the input particle: r"<<mainPosition.perp()<<" z= "<<mainPosition.z() );
308 
309  // check if it points to the calorimeter - if not, don't simulate
310  // first convert to Amg::Vector3D
311  const Amg::Vector3D amg3DPosVec(mainPosition.x(), mainPosition.y(), mainPosition.z());
312  const Amg::Vector3D amg3DMomDirVec(mainMomentumDir.x(), mainMomentumDir.y(), mainMomentumDir.z());
313  const Amg::Vector3D amg3DMomVec(mainMomentum.x(), mainMomentum.y(), mainMomentum.z());
314  // find nextGeoID to get AtlasDetDescr::AtlasRegion
315  AtlasDetDescr::AtlasRegion nextGeoID = m_geoIDSvc->identifyNextGeoID(amg3DPosVec,amg3DMomVec);
316  if ( nextGeoID != AtlasDetDescr::fAtlasCalo)
317  {
318  ATH_MSG_DEBUG("[PunchThroughG4Tool](GeoIDSvc) input particle doesn't point to calorimeter"<< "Next GeoID: "<< nextGeoID );
319  //return nullptr;
320  return {};
321  }
322 
323  // check if the particle's pdg is registered as a punch-through-causing type
324  {
325  std::vector<int>::const_iterator pdgIt = m_pdgInitiators.begin();
326  std::vector<int>::const_iterator pdgItEnd = m_pdgInitiators.end();
327 
328  std::vector<int>::const_iterator minEnergyIt = m_initiatorsMinEnergy.begin();
329  // loop over all known punch-through initiators
330  for ( ; pdgIt != pdgItEnd; ++pdgIt, ++minEnergyIt)
331  {
332  if (std::abs(pdgID) == *pdgIt){
333  if(initEnergy < *minEnergyIt){
334  ATH_MSG_DEBUG("[PunchThroughG4Tool] particle does not meet initiator min energy requirement. Dropping it in the calo.");
335  //return nullptr;
336  return {};
337  }
338  break;
339  }
340  }
341 
342  // particle will not cause punch-through -> bail out
343  if (pdgIt == pdgItEnd)
344  {
345  ATH_MSG_DEBUG("[PunchThroughG4Tool] particle is not registered as punch-through initiator. Dropping it in the calo.");
346  //return nullptr;
347  return {};
348  }
349  }
350 
351  if(initEta < m_initiatorsEtaRange.value().at(0) || initEta > m_initiatorsEtaRange.value().at(1) ){
352  ATH_MSG_DEBUG("[PunchThroughG4Tool] particle does not meet initiator eta range requirement. Dropping it in the calo.");
353  //return nullptr;
354  return {};
355  }
356 
357  ATH_MSG_DEBUG("[PunchThroughG4Tool] punchThroughProbability output: " << punchThroughProbability << " RandFlat: " << punchThroughClassifierRand );
358 
359  //Safety check: If probability < random number then don't simulate punch through
360  if( punchThroughClassifierRand > punchThroughProbability){
361  ATH_MSG_DEBUG("[PunchThroughG4Tool] particle not classified to create punch through. Dropping it in the calo.");
362  //return nullptr;
363  return {};
364  }
365 
366  //if initial particle is on ID surface, points to the calorimeter, is a punch-through initiator, meets initiator min enery and eta range
367 
368  // this is the place where the magic is done:
369  // test for each registered punch-through pdg if a punch-through
370  // occures and create these particles
371  // -> therefore loop over all registered pdg ids
372  // to keep track of the correlated particles which were already simulated:
373  // first int is pdg, second int is number of particles created
374 
375  // interpolate energy and eta
376  const double interpEnergy = interpolateEnergy(initEnergy, rndmEngine);
377  const double interpEta = interpolateEta(initEta, rndmEngine);
378 
379  std::map<int, int> corrPdgNumDone;
380 
381  int maxTries = 10;
382  int nTries = 0;
383 
384  // loop over all particle pdgs
385  while(secKinematicsMapVect.empty() && nTries < maxTries) { //ensure we always create at least one punch through particle, maxTries to catch very rare cases
386  // loop over all particle pdgs
387  for (const auto& currentParticle : m_particles)
388  {
389  // the pdg that is currently treated
390  int doPdg = currentParticle.first;
391  // get the current particle's correlated pdg
392  int corrPdg = currentParticle.second->getCorrelatedPdg();
393 
394  // if there is a correlated particle type to this one
395  if (corrPdg)
396  {
397  // find out if the current pdg was already simulated
398  std::map<int,int>::iterator itPdgPos = corrPdgNumDone.find(doPdg);
399  // if the current pdg was not simulated yet, find out if
400  // it's correlated one was simulated
401  if ( itPdgPos == corrPdgNumDone.end() ) itPdgPos = corrPdgNumDone.find(corrPdg);
402 
403  // neither this nor the correlated particle type was simulated
404  // so far:
405  if ( itPdgPos == corrPdgNumDone.end() )
406  {
407  // -> roll a dice if we create this particle or its correlated one
408  if ( CLHEP::RandFlat::shoot(rndmEngine) > 0.5 ) doPdg = corrPdg;
409  // now create the particles with the given pdg and note how many
410  // particles of this pdg are created
411  corrPdgNumDone[doPdg] = getAllParticles(*g4PrimaryTrack, secKinematicsMapVect, rndmEngine, doPdg, interpEnergy, interpEta);
412  }
413 
414  // one of the two correlated particle types was already simulated
415  // 'itPdgPos' points to the already simulated one
416  else
417  {
418  // get the pdg of the already simulated particle and the number
419  // of these particles that were created
420  const int donePdg = itPdgPos->first;
421  const int doneNumPart = itPdgPos->second;
422  // set the pdg of the particle type that will be done
423  if (donePdg == doPdg) doPdg = corrPdg;
424 
425  // now create the correlated particles
426  getCorrelatedParticles(*g4PrimaryTrack, secKinematicsMapVect, doPdg, doneNumPart, rndmEngine, interpEnergy, interpEta);
427  // note: no need to take note, that this particle type is now simulated,
428  // since this is the second of two correlated particles, which is
429  // simulated and we do not have correlations of more than two particles.
430  }
431 
432  // if no correlation for this particle
433  // -> directly create all particles with the current pdg
434  }
435  else{
436  getAllParticles(*g4PrimaryTrack, secKinematicsMapVect, rndmEngine, doPdg, interpEnergy, interpEta);
437  }
438  } // for-loop over all particle pdgs
439  }
440 
441  return secKinematicsMapVect;
442 }

◆ createAllSecondaryTracks()

void PunchThroughG4Tool::createAllSecondaryTracks ( G4ParticleTable &  ptable,
G4FastStep &  fastStep,
const G4Track &  g4PrimaryTrack,
std::vector< std::map< std::string, double >> &  secKinematicsMapVect,
G4TrackVector &  secTrackCont,
const std::vector< double > &  caloMSVars 
)
overridevirtual

create all secondary tracks from kinematics map

Definition at line 754 of file PunchThroughG4Tool.cxx.

754  {
755  // Get Geant4 particle definition
756  const G4ParticleDefinition* mainG4Particle = g4PrimaryTrack.GetDefinition();
757  float mainMomMag2 = g4PrimaryTrack.GetMomentum().mag2();
758  float mainPartMass = mainG4Particle->GetPDGMass();
759  double mainEnergyInit = std::sqrt(mainMomMag2 + mainPartMass * mainPartMass);
760 
761  // Energy conservation: call checkEnergySumFromSecondaries to check/update secKinematicsMapVect
762  secKinematicsMapVect = checkEnergySumFromSecondaries(mainEnergyInit, secKinematicsMapVect);
763 
764  // set number of secondary tracks to be produced
765  int numSecondaries = secKinematicsMapVect.size();
766 
767  if(numSecondaries>0){ //safety
768  // set number of secondary tracks from numSecondaries above
769  fastStep.SetNumberOfSecondaryTracks(numSecondaries);
770 
771  // Get current (global) time from original main G4Track
772  double currentTime = g4PrimaryTrack.GetGlobalTime();
773 
774  // create the secondaries given the number of secondaries to be created
775  for(int i=0;i < numSecondaries; i++){
776  int anti = (int)(secKinematicsMapVect[i].at("anti"));
777  int secondaryPDG = (int)(secKinematicsMapVect[i].at("secondaryPDG"));
778  int signedPDG = secondaryPDG*anti;
779  double energy = secKinematicsMapVect[i].at("energy");
780  double theta = secKinematicsMapVect[i].at("theta");
781  double phi = secKinematicsMapVect[i].at("phi");
782  double momTheta = secKinematicsMapVect[i].at("momTheta");
783  double momPhi = secKinematicsMapVect[i].at("momPhi");
784 
785  // (**) finally create the punch-through particle as a G4Track (secondary particle track)
786  ATH_MSG_DEBUG("[PunchThroughG4Tool::createAllSecondaryTracks] createSecondaryTrack input parameters: currentTime = " << currentTime << " anti? = "<< anti <<" signedPDG = "<< signedPDG <<" energy = "<< energy <<" theta = "<< theta <<" phi = "<< phi <<" momTheta = "<< momTheta << " momPhi " << momPhi);
787  G4Track* newSecTrack = createSecondaryTrack( ptable, fastStep, currentTime, signedPDG, energy, theta, phi, momTheta, momPhi, caloMSVars);
788 
789  // if something went wrong and the secondary track is simply not created
790  if (!newSecTrack)
791  {
792  G4Exception("[PunchThroughG4Tool::createAllSecondaryTracks]", "ExceptionError", FatalException, "something went wrong while creating punch-through particle tracks");
793  return;
794  }
795 
796  // add this secondary track to the g4trackvector
797  secTrackCont.push_back( newSecTrack );
798  }
799  }
800 
801  //printout: fastStep.DumpInfo()
802 }

◆ createSecondaryTrack()

G4Track * PunchThroughG4Tool::createSecondaryTrack ( G4ParticleTable &  ptable,
G4FastStep &  fastStep,
double  currentTime,
int  secondarySignedPDG,
double  energy,
double  theta,
double  phi,
double  momTheta,
double  momPhi,
const std::vector< double > &  caloMSVars 
)
private

create secondary track for each given the kinematics

Definition at line 804 of file PunchThroughG4Tool.cxx.

806 {
807  //initialize to nullptr
808  G4Track *newSecTrack = nullptr;
809 
810  G4ParticleDefinition* secG4Particle = ptable.FindParticle(secondarySignedPDG);
811  double mass = secG4Particle->GetPDGMass();
812 
813  // the intersection point with Calo-MS surface
814  G4ThreeVector posVec = punchTroughPosPropagator(theta, phi, caloMSVars[0], caloMSVars[1], caloMSVars[2], caloMSVars[3]);
815 
816  // set up the real punch-through particle at this position
817  // set up the momentum vector of this particle as a GlobalMomentum
818  // by using the given energy and mass of the particle and also using
819  // the given theta and phi
820  G4ThreeVector momVec;
821  double momMag = std::sqrt(energy*energy - mass*mass);
822  momVec.setRThetaPhi(momMag,momTheta,momPhi);
823  ATH_MSG_DEBUG("[PunchThroughG4Tool]::createSecondaryTrack] setRThetaPhi pre input parameters: energy = " << energy <<" mass = "<< mass);
824  ATH_MSG_DEBUG("[PunchThroughG4Tool]::createSecondaryTrack] setRThetaPhi input parameters: std::sqrt(energy*energy - mass*mass) = " << std::sqrt(energy*energy - mass*mass) << " momTheta = "<< momTheta <<" momPhi = "<< momPhi);
825 
826  // create dynamic particle
827  G4DynamicParticle dynParticle(secG4Particle,momVec);
828  newSecTrack = fastStep.CreateSecondaryTrack(dynParticle, posVec, currentTime, false); // use position in global coordinates instead
829 
830  return newSecTrack;
831 }

◆ dotProduct()

std::vector< double > PunchThroughG4Tool::dotProduct ( const std::vector< std::vector< double >> &  m,
const std::vector< double > &  v 
)
staticprivate

Definition at line 837 of file PunchThroughG4Tool.cxx.

838 {
839  std::vector<double> result;
840  result.reserve(m.size());
841  for (const auto& r : m){
842  result.push_back(std::inner_product(v.begin(), v.end(), r.begin(), 0.0));
843  }
844 
845  return result;
846 }

◆ finalize()

StatusCode PunchThroughG4Tool::finalize ( )
overridevirtual

AlgTool finalize method.

Definition at line 261 of file PunchThroughG4Tool.cxx.

262 {
263  ATH_MSG_DEBUG( "[PunchThroughG4Tool] finalize() starting" );
264  for(auto & each : m_particles) {
265  delete each.second;
266  }
267 
268  ATH_MSG_DEBUG( "[PunchThroughG4Tool] finalize() successful" );
269 
270  return StatusCode::SUCCESS;
271 }

◆ getAllParticles()

int PunchThroughG4Tool::getAllParticles ( const G4Track &  g4PrimaryTrack,
std::vector< std::map< std::string, double >> &  secKinematicsMapVect,
CLHEP::HepRandomEngine *  rndmEngine,
int  pdg,
double  interpEnergy,
double  interpEta,
int  numParticles = -1 
)
private

create the right number of punch-through particles for the given pdg and return the number of particles which was created.

also create these particles with the right distributions (energy, theta, phi). if a second argument is given, create exactly this number of particles (also with the right energy,theta,phi distributions

Definition at line 444 of file PunchThroughG4Tool.cxx.

445 {
446  // Get initial Geant4 position theta and phi
447  float initParticleTheta = g4PrimaryTrack.GetPosition().theta();
448  float initParticlePhi = g4PrimaryTrack.GetPosition().phi();
449 
450  // get the current particle
452  double minAllowedEnergy = p->getMinEnergy();
453 
454  // if no number of particles (=-1) was handed over as an argument
455  // -> get the number of particles from the pdf
456  if ( numParticles < 0 )
457  {
458  // prepare the function arguments for the PunchThroughPDFCreator class
459  std::vector<int> parameters;
460  parameters.push_back( std::round(interpEnergy) );
461  parameters.push_back( std::round(interpEta*100) );
462  // the maximum number of particles which should be produced
463  // if no maximum number is given, this is -1
464  int maxParticles = p->getMaxNumParticles();
465 
466  // get the right number of punch-through particles
467  // and ensure that we do not create too many particles
468  do
469  {
470  numParticles = int( p->getNumParticlesPDF()->getRand(rndmEngine, parameters) );
471 
472  // scale the number of particles if requested
473  numParticles = lround( numParticles *= p->getNumParticlesFactor() );
474  }
475  while ( (maxParticles >= 0.) && (numParticles > maxParticles) );
476  }
477 
478  ATH_MSG_DEBUG("[PunchThroughG4Tool] adding " << numParticles << " punch-through particles with pdg code: " << pdg);
479 
480  // get how many secondary particles to be created
481  for ( int numCreated = 0; numCreated < numParticles; numCreated++ )
482  {
483  // create one particle which fullfills the right energy distribution
484  std::map<std::string, double> secondaryKinematicsMap = getOneParticleKinematics(rndmEngine, pdg, initParticleTheta, initParticlePhi, interpEnergy, interpEta);
485 
486  //safety to cater minimum energy as rest mass
487  double energy = secondaryKinematicsMap.at("energy");
488  if(energy > minAllowedEnergy){
489  // push to the vector of maps
490  secKinematicsMapVect.push_back(secondaryKinematicsMap);
491  }
492  }
493 
494  // Get the size of the vector
495  std::size_t numSecondaries = secKinematicsMapVect.size();
496 
497  // the actual (pre) number of particles which was created is numSecondaries, which is incremented in the loop
498  return (numSecondaries);
499 }

◆ getCaloMSVars()

std::vector< double > PunchThroughG4Tool::getCaloMSVars ( )
overridevirtual

Definition at line 193 of file PunchThroughG4Tool.cxx.

193  {
194  //m_R1, m_R2, m_z1, m_z2
195  std::vector<double> caloMSVarsVect = {m_R1, m_R2, m_z1, m_z2};
196  ATH_MSG_DEBUG("[PunchThroughG4Tool] getCaloMSVars()==> m_R1 = "<< caloMSVarsVect[0] << ", m_R2 = " << caloMSVarsVect[1] << ", m_z1 = " << caloMSVarsVect[2] << ", m_z2 = " << caloMSVarsVect[3]);
197 
198  return caloMSVarsVect;
199 }

◆ getCorrelatedParticles()

int PunchThroughG4Tool::getCorrelatedParticles ( const G4Track &  g4PrimaryTrack,
std::vector< std::map< std::string, double >> &  secKinematicsMapVect,
int  pdg,
int  corrParticles,
CLHEP::HepRandomEngine *  rndmEngine,
double  interpEnergy,
double  interpEta 
)
private

get the right number of particles for the given pdg while considering the correlation to an other particle type, which has already created 'corrParticles' number of particles

Definition at line 501 of file PunchThroughG4Tool.cxx.

502 {
503  // Get Geant4 particle definition
504  const G4ParticleDefinition * mainG4Particle = g4PrimaryTrack.GetDefinition();
505  // Get Geant4 particle pdgID
506  float mainMomMag2 = g4PrimaryTrack.GetMomentum().mag2();
507  float mainPartMass = mainG4Particle->GetPDGMass();
508 
509  // get the PunchThroughParticle class
511 
512  const double initEnergy = std::sqrt( mainMomMag2 + mainPartMass*mainPartMass );
513 
514  // (1.) decide if we do correlation or not
515  double rand = CLHEP::RandFlat::shoot(rndmEngine)
516  *(p->getFullCorrelationEnergy() - p->getMinCorrelationEnergy())
517  + p->getMinCorrelationEnergy();
518 
519  // if initEnergy less than random corr energy (meaning threshold for min energy for doing correlation not passed)
520  if ( initEnergy < rand )
521  {
522  // here we do not do correlation
523  return getAllParticles(g4PrimaryTrack, secKinematicsMapVect, rndmEngine, pdg, interpEnergy, interpEta);
524  }
525 
526  // (2.) if this point is reached, we do correlation
527  // decide which 2d correlation histogram to use
528  double *histDomains = p->getCorrelationHistDomains();
529  TH2F *hist2d = nullptr;
530  // compute the center values of the lowE and highE
531  // correlation histogram domains
532  if ( initEnergy < histDomains[1])
533  {
534  // initial energy lower than border between lowEnergy and highEnergy histogram domain
535  // --> choose lowEnergy correlation histogram
536  hist2d = p->getCorrelationLowEHist();
537  }
538  else
539  {
540  double rand = CLHEP::RandFlat::shoot(rndmEngine)*(histDomains[2]-histDomains[1]) + histDomains[1];
541  hist2d = ( initEnergy < rand) ? p->getCorrelationLowEHist() : p->getCorrelationHighEHist();
542  }
543 
544  // get the correlation 2d histogram
545  // now find out where on the x-axis the the bin for number of
546  // correlated particles is
547  Int_t xbin = hist2d->GetXaxis()->FindFixBin(corrParticles);
548  int numParticles = 0;
549  int maxParticles = p->getMaxNumParticles();
550  // now the distribution along the y-axis is a PDF for the number
551  // of 'pdg' particles
552  do
553  {
554  double rand = CLHEP::RandFlat::shoot(rndmEngine);
555  double sum = 0.;
556  for ( int ybin = 1; ybin <= hist2d->GetNbinsY(); ybin++ )
557  {
558  sum += hist2d->GetBinContent(xbin, ybin);
559  // check if we choose the current bin or not
560  if ( sum >= rand )
561  {
562  numParticles = ybin - 1;
563  break;
564  }
565  }
566  // scale the number of particles is requested
567  numParticles = lround( numParticles * p->getNumParticlesFactor() );
568  }
569  while ( (maxParticles >= 0.) && (numParticles > maxParticles) );
570 
571  // finally create this exact number of particles
572  return getAllParticles(g4PrimaryTrack, secKinematicsMapVect, rndmEngine, pdg, interpEnergy, interpEta, numParticles);
573 }

◆ getFloatAfterPatternInStr()

double PunchThroughG4Tool::getFloatAfterPatternInStr ( const char *  str,
const char *  pattern 
)
private

get the floating point number in a string, after the given pattern

Definition at line 1436 of file PunchThroughG4Tool.cxx.

1437 {
1438  double num = 0.;
1439 
1440  const std::string_view str( cstr);
1441  const std::string_view pattern( cpattern);
1442  const size_t pos = str.find(pattern);
1443 
1444  if ( pos == std::string::npos)
1445  {
1446  ATH_MSG_WARNING("[PunchThroughG4Tool] unable to retrieve floating point number from string");
1447  return -999999999999.;
1448  }
1449  const std::string_view substring = str.substr(pos+pattern.length());
1450  std::from_chars(substring.data(), substring.data() + substring.size(), num);
1451  return num;
1452 }

◆ getInfoMap()

std::vector< std::map< std::string, std::string > > PunchThroughG4Tool::getInfoMap ( const std::string &  mainNode,
const std::string &  xmlFilePath 
)
private

Definition at line 901 of file PunchThroughG4Tool.cxx.

901  {
902  // Initialize pointers
903  xmlDocPtr doc;
904  xmlChar* xmlBuff = nullptr;
905 
906  std::vector<std::map<std::string, std::string>> xml_info;
907  doc = xmlParseFile( xmlFilePath.c_str() );
908 
909  //check info first
910  for( xmlNodePtr nodeRoot = doc->children; nodeRoot != nullptr; nodeRoot = nodeRoot->next) {
911  if (xmlStrEqual( nodeRoot->name, BAD_CAST mainNode.c_str() )) {
912  for( xmlNodePtr nodeRootChild = nodeRoot->children; nodeRootChild != nullptr; nodeRootChild = nodeRootChild->next ) {
913  if (xmlStrEqual( nodeRootChild->name, BAD_CAST "info" )) {
914  if (nodeRootChild->children != NULL) {
915  for( xmlNodePtr infoNode = nodeRootChild->children; infoNode != nullptr; infoNode = infoNode->next) {
916  if(xmlStrEqual( infoNode->name, BAD_CAST "item" )){
917  std::map<std::string, std::string> xml_info_item;
918 
919  if ((xmlBuff = xmlGetProp(infoNode, BAD_CAST "name")) != nullptr) {
920  xml_info_item.insert({"name", (const char*)xmlBuff});
921  }
922  if ((xmlBuff = xmlGetProp(infoNode, BAD_CAST "etaMins")) != nullptr) {
923  xml_info_item.insert({"etaMins", (const char*)xmlBuff});
924  }
925  if ((xmlBuff = xmlGetProp(infoNode, BAD_CAST "etaMaxs")) != nullptr) {
926  xml_info_item.insert({"etaMaxs", (const char*)xmlBuff});
927  }
928  if ((xmlBuff = xmlGetProp(infoNode, BAD_CAST "pidStr")) != nullptr) {
929  xml_info_item.insert({"pidStr", (const char*)xmlBuff});
930  }
931 
932  xml_info.push_back(xml_info_item);
933  }
934  }
935  }
936  }
937  }
938  }
939  }
940 
941  // free memory when done
942  xmlFreeDoc(doc);
943 
944  return xml_info;
945 }

◆ getOneParticleKinematics()

std::map< std::string, double > PunchThroughG4Tool::getOneParticleKinematics ( CLHEP::HepRandomEngine *  rndmEngine,
int  secondaryPDG,
float  initParticleTheta,
float  initParticlePhi,
double  interpEnergy,
double  interpEta 
) const
private

create exactly one punch-through particle with the given pdg and the given max energy

Definition at line 575 of file PunchThroughG4Tool.cxx.

576 {
577  // get a local copy of the needed punch-through particle class
578  PunchThroughParticle *p = m_particles.at(secondaryPDG);
579 
580  // (0.) get the pca / cdf group based on pdgId and eta, eta times 100, e.g eta -4 to 4 is from eta -400 to 400
581  int pcaCdfIterator = passedParamIterator(secondaryPDG, interpEta*100, m_xml_info_pca); //pca and cdf info should be of same size
582 
583  ATH_MSG_DEBUG("[PunchThroughG4Tool] passedPCAIterator ==> pcaCdfIterator = "<< pcaCdfIterator <<" , pdg = "<< secondaryPDG <<" , interpEnergy = "<< interpEnergy <<" MeV, interpEta(*100) = "<< interpEta*100);
584 
585  // (1.) decide if we create a particle or an anti-particle,
586  // this is from m_doAntiParticles properties
587  int anti = 1;
588  if ( p->getdoAnti() )
589  {
590  // get a random-value
591  double rand = CLHEP::RandFlat::shoot(rndmEngine);
592  // 50/50 chance to be a particle or its anti-particle
593  if (rand > 0.5) anti = -1;
594  }
595 
596  // (2.) get the right punch-through distributions
597  // prepare the function arguments for the PunchThroughPDFCreator class
598  std::vector<int> parInitEnergyEta;
599  parInitEnergyEta.push_back( std::round(interpEnergy) );
600  parInitEnergyEta.push_back( std::round(interpEta*100) );
601 
602  //initialise variables to store punch through particle kinematics
603  double energy = 0.;
604  double deltaTheta = 0.;
605  double deltaPhi = 0.;
606  double momDeltaTheta = 0.;
607  double momDeltaPhi = 0.;
608 
609  double principal_component_0 = 0.;
610  double principal_component_1 = 0.;
611  double principal_component_2 = 0.;
612  double principal_component_3 = 0.;
613  double principal_component_4 = 0.;
614  std::vector<double> transformed_variables;
615 
616  principal_component_0 = p->getPCA0PDF()->getRand(rndmEngine, parInitEnergyEta);
617  principal_component_1 = p->getPCA1PDF()->getRand(rndmEngine, parInitEnergyEta);
618  principal_component_2 = p->getPCA2PDF()->getRand(rndmEngine, parInitEnergyEta);
619  principal_component_3 = p->getPCA3PDF()->getRand(rndmEngine, parInitEnergyEta);
620  principal_component_4 = p->getPCA4PDF()->getRand(rndmEngine, parInitEnergyEta);
621 
622  ATH_MSG_DEBUG("[PunchThroughG4Tool] 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 );
623 
624  std::vector<double> principal_components {
625  principal_component_0,
626  principal_component_1,
627  principal_component_2,
628  principal_component_3,
629  principal_component_4
630  };
631 
632  transformed_variables = inversePCA(pcaCdfIterator,principal_components);
633 
634  energy = inverseCdfTransform(transformed_variables.at(0), m_variable0_inverse_cdf[pcaCdfIterator]);
635  deltaTheta = inverseCdfTransform(transformed_variables.at(1), m_variable1_inverse_cdf[pcaCdfIterator]);
636  deltaPhi = inverseCdfTransform(transformed_variables.at(2), m_variable2_inverse_cdf[pcaCdfIterator]);
637  momDeltaTheta = inverseCdfTransform(transformed_variables.at(3), m_variable3_inverse_cdf[pcaCdfIterator]);
638  momDeltaPhi = inverseCdfTransform(transformed_variables.at(4), m_variable4_inverse_cdf[pcaCdfIterator]);
639 
640  ATH_MSG_DEBUG("[PunchThroughG4Tool] Transformed punch through kinematics: energy = "<< energy <<" MeV deltaTheta = "<< deltaTheta <<" deltaPhi = "<< deltaPhi <<" momDeltaTheta = "<< momDeltaTheta <<" momDeltaPhi = "<< momDeltaPhi );
641 
642  energy *= p->getEnergyFactor(); // scale the energy if requested
643 
644  // safety: if energy less than minimum energy, add a small energy (10MeV to it to continue)
645  if (energy < p->getMinEnergy()) {
646  energy = p->getMinEnergy() + 10;
647  }
648 
649  // (2.2) get the particles DeltaTheta relative to the incoming particle
650  double theta = 0;
651  // loop to keep theta within range [0,PI]
652  do
653  {
654  // decide if delta positive/negative
655  deltaTheta *= ( CLHEP::RandFlat::shoot(rndmEngine) > 0.5 ) ? 1. : -1.;
656 
657  // calculate the exact theta value of the later created
658  // punch-through particle
659  theta = initParticleTheta + deltaTheta*p->getPosAngleFactor();
660  }
661  while ( (theta > M_PI) || (theta < 0.) );
662 
663  // (2.3) get the particle's delta phi relative to the incoming particle
664  deltaPhi *= ( CLHEP::RandFlat::shoot(rndmEngine) > 0.5 ) ? 1. : -1.;
665 
666  // keep phi within range [-PI,PI]
667  double phi = initParticlePhi + deltaPhi*p->getPosAngleFactor();
668  while ( std::fabs(phi) > 2*M_PI) phi /= 2.;
669  while (phi > M_PI) phi -= 2*M_PI;
670  while (phi < -M_PI) phi += 2*M_PI;
671 
672  // (2.4) get the particle momentum delta theta, relative to its position
673  //
674  // loop to keep momTheta within range [0,PI]
675  double momTheta = 0.;
676  do
677  {
678  // decide if delta positive/negative
679  momDeltaTheta *= ( CLHEP::RandFlat::shoot(rndmEngine) > 0.5 ) ? 1. : -1.;
680  // calculate the exact momentum theta value of the later created
681  // punch-through particle
682  momTheta = theta + momDeltaTheta*p->getMomAngleFactor();
683  }
684  while ( (momTheta > M_PI) || (momTheta < 0.) );
685 
686  // (2.5) get the particle momentum delta phi, relative to its position
687  momDeltaPhi *= ( CLHEP::RandFlat::shoot(rndmEngine) > 0.5 ) ? 1. : -1.;
688 
689  double momPhi = phi + momDeltaPhi*p->getMomAngleFactor();
690  // keep momPhi within range [-PI,PI]
691  while ( std::fabs(momPhi) > 2*M_PI) momPhi /= 2.;
692  while (momPhi > M_PI) momPhi -= 2*M_PI;
693  while (momPhi < -M_PI) momPhi += 2*M_PI;
694 
695  // store the kinematics in a map and return it
696  std::map<std::string, double> secondaryKinematicsMap;
697  secondaryKinematicsMap.insert({ "anti" , anti });
698  secondaryKinematicsMap.insert({ "secondaryPDG" , secondaryPDG });
699  secondaryKinematicsMap.insert({ "energy" , energy });
700  secondaryKinematicsMap.insert({ "theta" , theta });
701  secondaryKinematicsMap.insert({ "phi" , phi });
702  secondaryKinematicsMap.insert({ "momTheta" , momTheta });
703  secondaryKinematicsMap.insert({ "momPhi" , momPhi });
704 
705  return secondaryKinematicsMap;
706 }

◆ getVariableCDFmappings()

std::map< double, double > PunchThroughG4Tool::getVariableCDFmappings ( xmlNodePtr &  nodeParent)
staticprivate

Definition at line 1084 of file PunchThroughG4Tool.cxx.

1084  {
1085  std::map<double, double> mappings;
1086  xmlChar* xmlBuff = nullptr;
1087  double ref = -1;
1088  double quant = -1;
1089  for( xmlNodePtr node = nodeParent->children; node != nullptr; node = node->next ) {
1090  //Get min and max values that we normalise values to
1091  if (xmlStrEqual( node->name, BAD_CAST "CDFmap" )) {
1092  if ((xmlBuff = xmlGetProp(node, BAD_CAST "ref")) != nullptr) {
1093  ref = atof( (const char*) xmlBuff );
1094  }
1095  if ((xmlBuff = xmlGetProp(node, BAD_CAST "quant")) != nullptr) {
1096  quant = atof( (const char*) xmlBuff );
1097  }
1098  mappings.insert(std::pair<double, double>(ref, quant) );
1099  }
1100  }
1101 
1102  return mappings;
1103 }

◆ initialize()

StatusCode PunchThroughG4Tool::initialize ( )
overridevirtual

AlgTool initialize method.

Definition at line 45 of file PunchThroughG4Tool.cxx.

45  {
46  ATH_MSG_DEBUG("[PunchThroughG4Tool] ==>" << name() << "::initialize()");
47 
48  // resolving lookuptable file
49  std::string resolvedFileName = PathResolverFindCalibFile (m_filenameLookupTable);
50  if (resolvedFileName.empty()) {
51  ATH_MSG_ERROR( "[PunchThroughG4Tool] Parametrisation file '" << m_filenameLookupTable << "' not found" );
52  return StatusCode::FAILURE;
53  }
54  ATH_MSG_DEBUG( "[PunchThroughG4Tool] Parametrisation file found: " << resolvedFileName );
55 
56  //retrieve inverse CDF config file
58  {
59  ATH_MSG_WARNING("[PunchThroughG4Tool] unable to open or read the inverse CDF config");
60  return StatusCode::FAILURE;
61  }
62 
63  //retrieve inverse PCA config file
65  {
66  ATH_MSG_WARNING("[PunchThroughG4Tool] unable to open or read the inverse PCA config");
67  return StatusCode::FAILURE;
68  }
69 
70  //check first the size of infoMap for both PCA and CDF, they should be equal
71  if (!(m_xml_info_pca.size() == m_xml_info_cdf.size()))
72  {
73  ATH_MSG_WARNING("[PunchThroughG4Tool] size of infoMap for PCA and CDF differs! Something is wrong with input xml files.");
74  return StatusCode::FAILURE;
75  }
76 
77  // open the LookupTable file
78  m_fileLookupTable = new TFile( resolvedFileName.c_str(), "READ");
79  if (!m_fileLookupTable) {
80  ATH_MSG_WARNING("[PunchThroughG4Tool] unable to open the lookup-table for the punch-through simulation (file does not exist)");
81  return StatusCode::FAILURE;
82  }
83 
84  if (!m_fileLookupTable->IsOpen()) {
85  ATH_MSG_WARNING("[PunchThroughG4Tool] unable to open the lookup-table for the punch-through simulation (wrong or empty file?)");
86  return StatusCode::FAILURE;
87  }
88 
89  //--------------------------------------------------------------------------------
90  // register all the punch-through particles which will be simulated
92 
93  //--------------------------------------------------------------------------------
94  // register all the punch-through correlations between particles to be simulated
96 
97  //--------------------------------------------------------------------------------
98  // close the file with the lookuptable
99  m_fileLookupTable->Close();
100 
101  // Geometry identifier service
102  if ( !m_geoIDSvc.empty() && m_geoIDSvc.retrieve().isFailure())
103  {
104  ATH_MSG_FATAL ( "[PunchThroughG4Tool] Could not retrieve GeometryIdentifier Service. Abort");
105  return StatusCode::FAILURE;
106  }
107 
108  //envelope definition service
109  if (m_envDefSvc.retrieve().isFailure() )
110  {
111  ATH_MSG_ERROR( "[PunchThroughG4Tool] Could not retrieve " << m_envDefSvc );
112  return StatusCode::FAILURE;
113  }
114 
115  // direct-initialization of the Muon and Calo boundaries (giving R, Z coordinates)
116  // can also do like below (RZPairVector is vector<pair<double, double>>)
117  // const RZPairVector* rzMS = &(m_envDefSvc->getMuonRZBoundary());
118  const std::vector<std::pair<double, double>>* rzMS = &(m_envDefSvc->getMuonRZBoundary());
119  const std::vector<std::pair<double, double>>* rzCalo = &(m_envDefSvc->getCaloRZBoundary());
120  ATH_CHECK(checkCaloMSBoundaries(rzMS, rzCalo));
121 
122  ATH_MSG_INFO( "[PunchThroughG4Tool] initialization is successful" );
123  return StatusCode::SUCCESS;
124 }

◆ initializeInverseCDF()

StatusCode PunchThroughG4Tool::initializeInverseCDF ( const std::string &  quantileTransformerConfigFile)
private

Definition at line 1019 of file PunchThroughG4Tool.cxx.

1019  {
1020  std::map<double, double> variable0_inverse_cdf_row;
1021  std::map<double, double> variable1_inverse_cdf_row;
1022  std::map<double, double> variable2_inverse_cdf_row;
1023  std::map<double, double> variable3_inverse_cdf_row;
1024  std::map<double, double> variable4_inverse_cdf_row;
1025 
1026  // Initialize pointers
1027  xmlDocPtr doc;
1028 
1029  //parse xml that contains config for inverse CDF for each of punch through particle kinematics
1030 
1031  doc = xmlParseFile( inverseCdfConfigFile.c_str() );
1032 
1033  ATH_MSG_DEBUG( "[PunchThroughG4Tool] Loading inverse CDF: " << inverseCdfConfigFile);
1034 
1035  //check info first
1036  m_xml_info_cdf = getInfoMap("CDFMappings",inverseCdfConfigFile);
1037 
1038  //do the saving
1039  for (unsigned int i = 0; i < m_xml_info_cdf.size(); i++) {
1040  ATH_MSG_DEBUG( "[PunchThroughG4Tool] m_xml_info_cdf[" << i << "].at('name') = " << m_xml_info_cdf[i].at("name"));
1041 
1042  for( xmlNodePtr nodeRoot = doc->children; nodeRoot != nullptr; nodeRoot = nodeRoot->next) {
1043  if (xmlStrEqual( nodeRoot->name, BAD_CAST "CDFMappings" )) {
1044  for( xmlNodePtr typeMappings = nodeRoot->children; typeMappings != nullptr; typeMappings = typeMappings->next ) {
1045  if (xmlStrEqual( typeMappings->name, BAD_CAST m_xml_info_cdf[i].at("name").c_str() )) {
1046  if (typeMappings->children != NULL) {
1047  for( xmlNodePtr nodeMappings = typeMappings->children; nodeMappings != nullptr; nodeMappings = nodeMappings->next) {
1048 
1049  if (xmlStrEqual( nodeMappings->name, BAD_CAST "variable0" )) {
1050  variable0_inverse_cdf_row = getVariableCDFmappings(nodeMappings);
1051  }
1052  else if (xmlStrEqual( nodeMappings->name, BAD_CAST "variable1" )) {
1053  variable1_inverse_cdf_row = getVariableCDFmappings(nodeMappings);
1054  }
1055  else if (xmlStrEqual( nodeMappings->name, BAD_CAST "variable2" )) {
1056  variable2_inverse_cdf_row = getVariableCDFmappings(nodeMappings);
1057  }
1058  else if (xmlStrEqual( nodeMappings->name, BAD_CAST "variable3" )) {
1059  variable3_inverse_cdf_row = getVariableCDFmappings(nodeMappings);
1060  }
1061  else if (xmlStrEqual( nodeMappings->name, BAD_CAST "variable4" )) {
1062  variable4_inverse_cdf_row = getVariableCDFmappings(nodeMappings);
1063  }
1064  }
1065 
1066  }
1067  }
1068  }
1069  }
1070  }
1071  m_variable0_inverse_cdf.push_back(variable0_inverse_cdf_row);
1072  m_variable1_inverse_cdf.push_back(variable1_inverse_cdf_row);
1073  m_variable2_inverse_cdf.push_back(variable2_inverse_cdf_row);
1074  m_variable3_inverse_cdf.push_back(variable3_inverse_cdf_row);
1075  m_variable4_inverse_cdf.push_back(variable4_inverse_cdf_row);
1076  }
1077 
1078  // free memory when done
1079  xmlFreeDoc(doc);
1080 
1081  return StatusCode::SUCCESS;
1082 }

◆ initializeInversePCA()

StatusCode PunchThroughG4Tool::initializeInversePCA ( const std::string &  inversePCAConfigFile)
private

Definition at line 956 of file PunchThroughG4Tool.cxx.

956  {
957  // Initialize pointers
958  xmlDocPtr doc;
959  xmlChar* xmlBuff = nullptr;
960 
961  doc = xmlParseFile( inversePCAConfigFile.c_str() );
962 
963  ATH_MSG_DEBUG( "[PunchThroughG4Tool] Loading inversePCA: " << inversePCAConfigFile);
964 
965  //check info first
966  m_xml_info_pca = getInfoMap("PCAinverse",inversePCAConfigFile);
967 
968  //do the saving
969  for (unsigned int i = 0; i < m_xml_info_pca.size(); i++) {
970  std::vector<std::vector<double>> PCA_matrix;
971  ATH_MSG_DEBUG( "[PunchThroughG4Tool] m_xml_info_pca[" << i << "].at('name') = " << m_xml_info_pca[i].at("name"));
972 
973  for( xmlNodePtr nodeRoot = doc->children; nodeRoot != nullptr; nodeRoot = nodeRoot->next) {
974  if (xmlStrEqual( nodeRoot->name, BAD_CAST "PCAinverse" )) {
975  for( xmlNodePtr nodePCAinverse = nodeRoot->children; nodePCAinverse != nullptr; nodePCAinverse = nodePCAinverse->next ) {
976 
977  if (xmlStrEqual( nodePCAinverse->name, BAD_CAST m_xml_info_pca[i].at("name").c_str() )) {
978  if (nodePCAinverse->children != NULL) {
979  for( xmlNodePtr pcaNode = nodePCAinverse->children; pcaNode != nullptr; pcaNode = pcaNode->next) {
980 
981  if (xmlStrEqual( pcaNode->name, BAD_CAST "PCAmatrix" )) {
982  std::vector<double> PCA_matrix_row;
983  for (int i = 0; i <= 4; ++i) {
984  std::string propName = "comp_" + std::to_string(i); // Dynamically create property name
985  if ((xmlBuff = xmlGetProp(pcaNode, BAD_CAST propName.c_str())) != nullptr) {
986  PCA_matrix_row.push_back(atof((const char*)xmlBuff)); // Convert and push to the row
987  }
988  }
989  PCA_matrix.push_back(PCA_matrix_row);
990  }
991  else if (xmlStrEqual( pcaNode->name, BAD_CAST "PCAmeans" )) {
992  std::vector<double> PCA_means_row;
993  for (int i = 0; i <= 4; ++i) {
994  std::string propName = "mean_" + std::to_string(i); // Dynamically create property name
995  if ((xmlBuff = xmlGetProp(pcaNode, BAD_CAST propName.c_str())) != nullptr) {
996  PCA_means_row.push_back(atof((const char*)xmlBuff)); // Convert and push to the row
997  }
998  }
999  m_PCA_means.push_back(PCA_means_row);
1000  }
1001 
1002  }
1003 
1004  }
1005  }
1006 
1007  }
1008  }
1009  }
1010  m_inverse_PCA_matrix.push_back(PCA_matrix);
1011  }
1012 
1013  // free memory when done
1014  xmlFreeDoc(doc);
1015 
1016  return StatusCode::SUCCESS;
1017 }

◆ initializeRegisterCorrelations()

StatusCode PunchThroughG4Tool::initializeRegisterCorrelations ( )
private

initialize register all correlations between particles

Definition at line 158 of file PunchThroughG4Tool.cxx.

158  {
159  //--------------------------------------------------------------------------------
160  // TODO: implement punch-through parameters for different m_pdgInitiators
161  // currently m_pdgInitiators is only used to filter out particles,
162  // inside computePunchThroughParticles
163 
164  // check if more correlations were given than particle types were registered
165  unsigned int numCorrelations = m_correlatedParticle.size();
166  if ( numCorrelations > m_punchThroughParticles.size() )
167  {
168  ATH_MSG_WARNING("[PunchThroughG4Tool] more punch-through particle correlations are given, than punch-through particle types are registered (skipping the last ones)");
169  numCorrelations = m_punchThroughParticles.size();
170  }
171 
172  // now register correlation between particles
173  for ( unsigned int num = 0; num < numCorrelations; num++ )
174  {
175  const int pdg1 = m_punchThroughParticles[num];
176  const int pdg2 = m_correlatedParticle[num];
177  const double fullCorrEnergy = ( num < m_fullCorrEnergy.size() ) ? m_fullCorrEnergy[num] : 0.;
178  const double minCorrEnergy = ( num < m_minCorrEnergy.size() ) ? m_minCorrEnergy[num] : 0.;
179 
180  // if correlatedParticle==0 is given -> no correlation
181  if ( ! pdg2) continue;
182  // register it
183  if ( registerCorrelation(pdg1, pdg2, minCorrEnergy, fullCorrEnergy) != StatusCode::SUCCESS )
184  {
185  ATH_MSG_ERROR("[PunchThroughG4Tool] unable to register punch-through particle correlation for pdg1=" << pdg1 << " pdg2=" << pdg2 );
186  return StatusCode::FAILURE;
187  }
188  }
189  // if all goes well
190  return StatusCode::SUCCESS;
191 }

◆ initializeRegisterPunchThroughParticles()

StatusCode PunchThroughG4Tool::initializeRegisterPunchThroughParticles ( )
private

initialize register all the punch-through particles which will be simulated

Definition at line 126 of file PunchThroughG4Tool.cxx.

126  {
127  G4ParticleTable *ptable = G4ParticleTable::GetParticleTable();
128  for ( unsigned int num = 0; num < m_punchThroughParticles.size(); num++ )
129  {
130  const int pdg = m_punchThroughParticles[num];
131  // if no information is given on the creation of anti-particles -> do not simulate anti-particles
132  const bool doAnti = ( num < m_doAntiParticles.size() ) ? m_doAntiParticles[num] : false;
133  // if no information is given on the minimum energy -> take 50. MeV as default
134  const double minEnergy = ( num < m_minEnergy.size() ) ? m_minEnergy[num] : 50.;
135  // if no information is given on the maximum number of punch-through particles -> take -1 as default
136  const int maxNum = ( num < m_minEnergy.size() ) ? m_maxNumParticles[num] : -1;
137  // if no information is given on the scale factor for the number of particles -> take 1. as defaulft
138  const double numFactor = ( num < m_numParticlesFactor.size() ) ? m_numParticlesFactor[num] : 1.;
139  // if no information is given on the position angle factor -> take 1.
140  const double posAngleFactor = ( num < m_posAngleFactor.size() ) ? m_posAngleFactor[num] : 1.;
141  // if no information is given on the momentum angle factor -> take 1.
142  const double momAngleFactor = ( num < m_momAngleFactor.size() ) ? m_momAngleFactor[num] : 1.;
143  // if no information is given on the scale factor for the energy -> take 1. as default
144  const double energyFactor = ( num < m_energyFactor.size() ) ? m_energyFactor[num] : 1.;
145 
146  // register the particle
147  ATH_MSG_VERBOSE("VERBOSE: [PunchThroughG4Tool] registering punch-through particle type with pdg = " << pdg );
148  if (registerPunchThroughParticle( *ptable, pdg, doAnti, minEnergy, maxNum, numFactor, energyFactor, posAngleFactor, momAngleFactor ) != StatusCode::SUCCESS)
149  {
150  ATH_MSG_ERROR("[PunchThroughG4Tool] unable to register punch-through particle type with pdg = " << pdg);
151  return StatusCode::FAILURE;
152  }
153  }
154  // if all goes well
155  return StatusCode::SUCCESS;
156 }

◆ interpolateEnergy()

double PunchThroughG4Tool::interpolateEnergy ( const double &  energy,
CLHEP::HepRandomEngine *  rndmEngine 
) const
private

Definition at line 1120 of file PunchThroughG4Tool.cxx.

1120  {
1121 
1122  ATH_MSG_DEBUG("[PunchThroughG4Tool] interpolating incoming energy: " << energy);
1123 
1124  std::string energyPointsString;
1125  for (auto element:m_energyPoints){
1126  energyPointsString += std::to_string(element) + " ";
1127  }
1128 
1129  ATH_MSG_DEBUG("[PunchThroughG4Tool] available energy points: " << energyPointsString);
1130 
1131  auto const upperEnergy = std::upper_bound(m_energyPoints.begin(), m_energyPoints.end(), energy);
1132 
1133  if(upperEnergy == m_etaPoints.end()){ //if no energy greater than input energy, choose greatest energy
1134  ATH_MSG_DEBUG("[PunchThroughG4Tool] incoming energy > largest energy point, returning greatest energy point: " << m_energyPoints.back());
1135  return m_energyPoints.back();
1136  }
1137  else if(upperEnergy == m_etaPoints.begin()){ //if smallest energy greater than input energy, choose smallest energy
1138  ATH_MSG_DEBUG("[PunchThroughG4Tool] incoming energy < smallest energy point, returning smallest energy point: " << *upperEnergy);
1139  return *upperEnergy;
1140  }
1141 
1142  ATH_MSG_DEBUG("[PunchThroughG4Tool] energy points upper_bound: "<< *upperEnergy);
1143 
1144  double randomShoot = CLHEP::RandFlat::shoot(rndmEngine);
1145 
1146  ATH_MSG_DEBUG("[PunchThroughG4Tool] Shooting random number: "<< randomShoot);
1147 
1148  double midPoint = *std::prev(upperEnergy)*M_SQRT2;
1149 
1150  if(energy < midPoint){ //if energy smaller than mid point in log(energy)
1151 
1152  double distance = std::abs(energy - *std::prev(upperEnergy))/((midPoint) - *std::prev(upperEnergy));
1153 
1154  ATH_MSG_DEBUG( "[PunchThroughG4Tool] incoming energy is closest to prev(upper_bound) in log(energy), distance: " << distance );
1155 
1156  if(randomShoot < distance){
1157  ATH_MSG_DEBUG( "[PunchThroughG4Tool] randomShoot < distance, returning upper_bound " << *upperEnergy );
1158  return *upperEnergy;
1159  }
1160  ATH_MSG_DEBUG( "[PunchThroughG4Tool] randomShoot > distance, returning prev(upper_bound) " << *std::prev(upperEnergy) );
1161 
1162  return *std::prev(upperEnergy);
1163  }
1164  else if(energy > midPoint){ //if energy greater than mid point in log(energy)
1165 
1166  double distance = std::abs(energy - *upperEnergy)/((*upperEnergy - midPoint));
1167 
1168  ATH_MSG_DEBUG( "[PunchThroughG4Tool] incoming energy is closest to upper_bound in log(energy), distance: " << distance );
1169 
1170  if(randomShoot < distance){
1171  ATH_MSG_DEBUG( "[PunchThroughG4Tool] randomShoot < distance, returning prev(upper_bound) " << *std::prev(upperEnergy) );
1172  return *std::prev(upperEnergy);
1173  }
1174  ATH_MSG_DEBUG( "[PunchThroughG4Tool] randomShoot > distance, returning upper_bound " << *upperEnergy );
1175  return *upperEnergy;
1176  }
1177 
1178  return *upperEnergy;
1179 }

◆ interpolateEta()

double PunchThroughG4Tool::interpolateEta ( const double &  eta,
CLHEP::HepRandomEngine *  rndmEngine 
) const
private

Definition at line 1181 of file PunchThroughG4Tool.cxx.

1181  {
1182 
1183  double absEta = std::abs(eta);
1184 
1185  ATH_MSG_DEBUG("[PunchThroughG4Tool] interpolating incoming abs(eta): " << absEta);
1186 
1187  std::string etaPointsString;
1188  for (auto element:m_etaPoints){
1189  etaPointsString += std::to_string(element) + " ";
1190  }
1191 
1192  ATH_MSG_DEBUG("[PunchThroughG4Tool] available eta points: " << etaPointsString);
1193 
1194  auto const upperEta = std::upper_bound(m_etaPoints.begin(), m_etaPoints.end(), absEta);
1195 
1196  if(upperEta == m_etaPoints.end()){
1197  ATH_MSG_DEBUG("[PunchThroughG4Tool] incoming abs(eta) > largest eta point, returning greatest eta point: " << m_etaPoints.back());
1198  return m_etaPoints.back();
1199  }
1200 
1201 
1202  ATH_MSG_DEBUG("[PunchThroughG4Tool] eta points upper_bound: "<< *upperEta);
1203 
1204  double randomShoot = CLHEP::RandFlat::shoot(rndmEngine);
1205 
1206  ATH_MSG_DEBUG("[PunchThroughG4Tool] Shooting random number: "<< randomShoot);
1207 
1208  if(std::abs(absEta - *upperEta) < std::abs(absEta - *std::prev(upperEta))){
1209 
1210  double distance = std::abs(absEta - *upperEta)/((*upperEta - *std::prev(upperEta))/2);
1211 
1212  ATH_MSG_DEBUG( "[PunchThroughG4Tool] abs(eta) is closer to eta points upper_bound, distance: " << distance );
1213 
1214  if(randomShoot > distance){
1215  ATH_MSG_DEBUG( "[PunchThroughG4Tool] randomShoot > distance, returning upper_bound " << *upperEta );
1216  return *upperEta;
1217  }
1218 
1219  ATH_MSG_DEBUG( "[PunchThroughG4Tool] randomShoot < distance, returning prev(upper_bound) " << *std::prev(upperEta) );
1220 
1221  return *std::prev(upperEta);
1222  }
1223  else if(std::abs(absEta - *std::prev(upperEta)) < std::abs(absEta - *upperEta)){
1224 
1225  if(std::prev(upperEta) == m_etaPoints.begin()){
1226  ATH_MSG_DEBUG( "[PunchThroughG4Tool] prev of upper bound is begin, returning that: " << *std::prev(upperEta) );
1227  return *std::prev(upperEta);
1228  }
1229 
1230  double distance = std::abs(absEta - *std::prev(upperEta))/((*std::prev(upperEta) - *std::prev(std::prev(upperEta)))/2);
1231 
1232  ATH_MSG_DEBUG( "[PunchThroughG4Tool] abs(eta) is closer to eta points prev(upper_bound), distance: " << distance );
1233 
1234  if(randomShoot > distance){
1235  ATH_MSG_DEBUG( "[PunchThroughG4Tool] randomShoot > distance, returning prev(prev(upper_bound)) " << *std::prev(std::prev(upperEta)) );
1236 
1237  return *std::prev(std::prev(upperEta));
1238  }
1239  ATH_MSG_DEBUG( "[PunchThroughG4Tool] randomShoot < distance, returning prev(upper_bound) " << *std::prev(upperEta) );
1240 
1241  return *std::prev(upperEta);
1242  }
1243 
1244  return *std::prev(upperEta);
1245 }

◆ inverseCdfTransform()

double PunchThroughG4Tool::inverseCdfTransform ( double  variable,
const std::map< double, double > &  inverse_cdf_map 
)
staticprivate

Definition at line 1105 of file PunchThroughG4Tool.cxx.

1105  {
1106 
1107  double norm_cdf = normal_cdf(variable);
1108 
1109  auto upper = inverse_cdf_map.upper_bound(norm_cdf);
1110  auto lower = upper--;
1111 
1112  double m = (upper->second - lower->second)/(upper->first - lower->first);
1113  double c = lower->second - m * lower->first;
1114  double transformed = m * norm_cdf + c;
1115 
1116  return transformed;
1117 
1118 }

◆ inversePCA()

std::vector< double > PunchThroughG4Tool::inversePCA ( int  pcaCdfIterator,
std::vector< double > &  variables 
) const
private

Definition at line 947 of file PunchThroughG4Tool.cxx.

948 {
949  std::vector<double> transformed_variables = dotProduct(m_inverse_PCA_matrix[pcaCdfIterator], variables);
950 
951  std::transform (transformed_variables.begin(), transformed_variables.end(), m_PCA_means[pcaCdfIterator].begin(), transformed_variables.begin(), std::plus<double>()); // + means
952 
953  return transformed_variables;
954 }

◆ normal_cdf()

double PunchThroughG4Tool::normal_cdf ( double  x)
staticprivate

Definition at line 833 of file PunchThroughG4Tool.cxx.

833  {
834  return 0.5 * TMath::Erfc(-x * M_SQRT1_2);
835 }

◆ passedParamIterator()

int PunchThroughG4Tool::passedParamIterator ( int  pid,
double  eta,
const std::vector< std::map< std::string, std::string >> &  mapvect 
) const
private

Definition at line 872 of file PunchThroughG4Tool.cxx.

873 {
874  //convert the pid to absolute value and string for query
875  int pidStrSingle = std::abs(pid);
876  //STEP 1
877  //filter items matching pid first
878 
879  for (unsigned int i = 0; i < mapvect.size(); i++){
880  const std::string &pidStr = mapvect[i].at("pidStr");
881  auto v = str_to_list<int>(pidStr);
882  if(std::find(v.begin(), v.end(),pidStrSingle)==v.end()) continue;
883  const std::string &etaMinsStr = mapvect[i].at("etaMins");
884  const std::string &etaMaxsStr = mapvect[i].at("etaMaxs");
885  std::vector<double> etaMinsVect = str_to_list<double>(etaMinsStr);
886  std::vector<double> etaMaxsVect = str_to_list<double>(etaMaxsStr);
887  assert(etaMaxsVect.size() == etaMinsVect.size());
888  for (unsigned int j = 0; j < etaMinsVect.size(); j++){ // assume size etaMinsVect == etaMaxsVect
889  double etaMinToCompare = etaMinsVect[j];
890  double etaMaxToCompare = etaMaxsVect[j];
891  if((eta >= etaMinToCompare) && (eta < etaMaxToCompare)){
892  //PASS CONDITION
893  //then choose the passing one and note it's iterator
894  return (i); //in case more than 1 match (ambiguous case)
895  }
896  }
897  }
898  return 0;
899 }

◆ punchTroughPosPropagator()

G4ThreeVector PunchThroughG4Tool::punchTroughPosPropagator ( double  theta,
double  phi,
double  R1,
double  R2,
double  z1,
double  z2 
) const
private

get particle through the calorimeter

Definition at line 1455 of file PunchThroughG4Tool.cxx.

1456 {
1457  // phi, theta - direction of the punch-through particle coming into calo
1458  // particle propagates inside the calorimeter along the straight line
1459  // coordinates of this particles when exiting the calo (on calo-MS boundary)
1460 
1461  double x, y, z, r;
1462 
1463  // cylinders border angles
1464  const double theta1 = atan (R1 / z1);
1465  const double theta2 = atan (R1 / z2);
1466  const double theta3 = atan (R2 / z2);
1467  //where is the particle
1468 
1469  if (theta >= 0 && theta < theta1)
1470  {
1471  z = z1;
1472  r = std::fabs (z1 * tan(theta));
1473  }
1474  else if (theta >= theta1 && theta < theta2)
1475  {
1476  z = R1 / tan(theta);
1477  r = R1;
1478  }
1479  else if (theta >= theta2 && theta < theta3)
1480  {
1481  z = z2;
1482  r = std::fabs(z2 * tan(theta));;
1483  }
1484  else if (theta >= theta3 && theta < (TMath::Pi() - theta3) )
1485  {
1486  z = R2 / tan(theta);
1487  r = R2;
1488  }
1489  else if (theta >= (TMath::Pi() - theta3) && theta < (TMath::Pi() - theta2) )
1490  {
1491  z = -z2;
1492  r = std::fabs(z2 * tan(theta));
1493  }
1494  else if (theta >= (TMath::Pi() - theta2) && theta < (TMath::Pi() - theta1) )
1495  {
1496  z = R1 / tan(theta);
1497  r = R1;
1498  }
1499  else if (theta >= (TMath::Pi() - theta1) && theta <= TMath::Pi() )
1500  {
1501  z = -z1;
1502  r = std::fabs(z1 * tan(theta));
1503  }
1504 
1505  //parallel universe
1506  else
1507  {
1508  ATH_MSG_WARNING("[PunchThroughG4Tool::punchTroughPosPropagator] Given theta angle is incorrect, setting particle position to (0, 0, 0)");
1509  x = 0.0; y = 0.0; z = 0.0; r = 0.0;
1510  }
1511 
1512  x = r * cos(phi);
1513  y = r * sin(phi);
1514  G4ThreeVector posVec(x, y, z);
1515 
1516  ATH_MSG_DEBUG("[PunchThroughG4Tool::punchTroughPosPropagator] position of produced punch-through particle: x = " << x <<" y = "<< y <<" z = "<< z<<" r = "<< posVec.perp() <<"std::sqrt(x^2+y^2) = "<< std::sqrt(x * x + y * y));
1517 
1518  return posVec;
1519 }

◆ readLookuptablePDF()

std::unique_ptr< PunchThroughPDFCreator > PunchThroughG4Tool::readLookuptablePDF ( int  pdgID,
TFile *  fileLookupTable,
const std::string &  folderName 
)
private

reads out the lookuptable for the given type of particle

Definition at line 1369 of file PunchThroughG4Tool.cxx.

1370 {
1371 
1372  // will hold the PDFcreator class which will be returned at the end
1373  // this will store the distributions for the punch through particles
1374  // (as map of energy & eta of the incoming particle)
1375  //PunchThroughPDFCreator *pdf = new PunchThroughPDFCreator();
1376  std::unique_ptr<PunchThroughPDFCreator> pdf = std::make_unique<PunchThroughPDFCreator>();
1377 
1378  //Get directory object
1379  std::stringstream dirName;
1380  dirName << folderName << pdg;
1381  pdf->setName(dirName.str());
1382 
1383  TDirectory * dir = (TDirectory*)fileLookupTable->Get(dirName.str().c_str());
1384  if(! dir)
1385  {
1386  ATH_MSG_ERROR( "[PunchThroughG4Tool] unable to retrieve directory object ("<< folderName << pdg << ")" );
1387  return nullptr;
1388  }
1389 
1390  //Get list of all objects in directory
1391  TIter keyList(dir->GetListOfKeys());
1392  TKey *key;
1393 
1394  while ((key = (TKey*)keyList())) {
1395 
1396  //Get histogram object from key and its name
1397  TH1* hist = nullptr;
1398 
1399  std::string histName;
1400  if(strcmp(key->GetClassName(), "TH1F") == 0){
1401  hist = (TH1*)key->ReadObj();
1402  histName = hist->GetName();
1403  }
1404 
1405  //extract energy and eta from hist name 6 and 1 to position delimeters correctly
1406  std::string strEnergy = histName.substr( histName.find_first_of('E') + 1, histName.find_first_of('_')-histName.find_first_of('E') - 1 );
1407  histName.erase(0, histName.find_first_of('_') + 1);
1408  std::string strEtaMin = histName.substr( histName.find("etaMin") + 6, histName.find_first_of('_') - histName.find("etaMin") - 6 );
1409  histName.erase(0, histName.find('_') + 1);
1410  std::string strEtaMax = histName.substr( histName.find("etaMax") + 6, histName.length());
1411 
1412  //create integers to store in map
1413  const int energy = std::stoi(strEnergy);
1414  const int etaMin = std::stoi(strEtaMin);
1415 
1416  //Add entry to pdf map
1417  pdf->addToEnergyEtaHist1DMap(energy, etaMin, hist);
1418 
1419  //create doubles to store energy and eta points for interpolation
1420  const double energyDbl = static_cast<double>(energy);
1421  const double etaDbl = static_cast<double>(etaMin)/100.;
1422 
1423  //create vectors to store the eta and energy points, this allows us to interpolate
1424  if (std::find(m_energyPoints.begin(), m_energyPoints.end(), energyDbl) == m_energyPoints.end()) {
1425  m_energyPoints.push_back(energyDbl);
1426  }
1427  if (std::find(m_etaPoints.begin(), m_etaPoints.end(), etaDbl) == m_etaPoints.end()) {
1428  m_etaPoints.push_back(etaDbl);
1429  }
1430 
1431  }
1432 
1433  return pdf;
1434 }

◆ registerCorrelation()

StatusCode PunchThroughG4Tool::registerCorrelation ( int  pdgID1,
int  pdgID2,
double  minCorrEnergy = 0.,
double  fullCorrEnergy = 0. 
)
private

register a correlation for the two given types of punch-through particles with a given energy threshold above which we will have full correlation

Definition at line 1321 of file PunchThroughG4Tool.cxx.

1323 {
1324  // find the given pdgs in the registered particle ids
1327 
1328  // if at least one of the given pdgs was not registered yet -> return an error
1329  if ( (location1 == m_particles.end()) || (location2 == m_particles.end()) )
1330  return StatusCode::FAILURE;
1331 
1332  // now look for the correlation histograms
1333  std::stringstream name;
1334  name << "NumExitCorrelations/x_PDG" << std::abs(pdgID1) << "__y_PDG" << std::abs(pdgID2) << "__lowE";
1335  TH2F *hist1_2_lowE = (TH2F*)m_fileLookupTable->Get(name.str().c_str());
1336  name.str("");
1337  name << "NumExitCorrelations/x_PDG" << std::abs(pdgID1) << "__y_PDG" << std::abs(pdgID2) << "__highE";
1338  TH2F *hist1_2_highE = (TH2F*)m_fileLookupTable->Get(name.str().c_str());
1339  name.str("");
1340  name << "NumExitCorrelations/x_PDG" << std::abs(pdgID2) << "__y_PDG" << std::abs(pdgID1) << "__lowE";
1341  TH2F *hist2_1_lowE = (TH2F*)m_fileLookupTable->Get(name.str().c_str());
1342  name.str("");
1343  name << "NumExitCorrelations/x_PDG" << std::abs(pdgID2) << "__y_PDG" << std::abs(pdgID1) << "__highE";
1344  TH2F *hist2_1_highE = (TH2F*)m_fileLookupTable->Get(name.str().c_str());
1345  // check if the histograms exist
1346  if ( (!hist1_2_lowE) || (!hist2_1_lowE) || (!hist1_2_highE) || (!hist2_1_highE) )
1347  {
1348  ATH_MSG_ERROR("[PunchThroughG4Tool] unable to retrieve the correlation data for PDG IDs " << pdgID1 << " and " << pdgID2);
1349  return StatusCode::FAILURE;
1350  }
1351 
1352  // TODO: if only one of the two histograms exists, create the other one
1353  // by mirroring the data
1354  const double lowE = getFloatAfterPatternInStr( hist1_2_lowE->GetTitle(), "elow_");
1355  const double midE = getFloatAfterPatternInStr( hist1_2_lowE->GetTitle(), "ehigh_");
1356  //TODO: check if the same:
1357  // double midE = getFloatAfterPatternInStr( hist1_2_lowE->GetTitle(), "elow_");
1358  const double upperE = getFloatAfterPatternInStr( hist1_2_highE->GetTitle(), "ehigh_");
1359  // now store the correlation either way id1->id2 and id2->id1
1360  m_particles[pdgID1]->setCorrelation(pdgID2, hist2_1_lowE, hist2_1_highE,
1361  minCorrEnergy, fullCorrEnergy,
1362  lowE, midE, upperE);
1363  m_particles[pdgID2]->setCorrelation(pdgID1, hist1_2_lowE, hist1_2_highE,
1364  minCorrEnergy, fullCorrEnergy,
1365  lowE, midE, upperE);
1366  return StatusCode::SUCCESS;
1367 }

◆ registerPunchThroughParticle()

StatusCode PunchThroughG4Tool::registerPunchThroughParticle ( G4ParticleTable &  ptable,
int  pdg,
bool  doAntiparticle = false,
double  minEnergy = 0.,
int  maxNumParticles = -1,
double  numParticlesFactor = 1.,
double  energyFactor = 1.,
double  posAngleFactor = 1.,
double  momAngleFactor = 1. 
)
private

registers a type of punch-through particles which will be simulated

Definition at line 1248 of file PunchThroughG4Tool.cxx.

1251 {
1252  G4ParticleDefinition* secG4Particle = ptable.FindParticle(std::abs(pdg));
1253  double restMass = secG4Particle->GetPDGMass();
1254 
1255  // read in the data needed to construct the distributions for the number of punch-through particles
1256  // (1.) get the distribution function for the number of punch-through particles
1257  std::unique_ptr<PunchThroughPDFCreator> pdf_num(readLookuptablePDF(pdg, m_fileLookupTable, "FREQ_PDG"));
1258  if (!pdf_num ) return StatusCode::FAILURE; // return error if something went wrong
1259 
1260  // (2.) get the PDF for the punch-through energy
1261  std::unique_ptr<PunchThroughPDFCreator> pdf_pca0 (readLookuptablePDF(pdg, m_fileLookupTable, "PCA0_PDG"));
1262  if (!pdf_pca0)
1263  {
1264  return StatusCode::FAILURE; // return error if something went wrong
1265  }
1266 
1267  // (3.) get the PDF for the punch-through particles difference in
1268  // theta compared to the incoming particle
1269  std::unique_ptr<PunchThroughPDFCreator> pdf_pca1 (readLookuptablePDF(pdg, m_fileLookupTable, "PCA1_PDG"));
1270  if (!pdf_pca1)
1271  {
1272  return StatusCode::FAILURE;
1273  }
1274 
1275  // (4.) get the PDF for the punch-through particles difference in
1276  // phi compared to the incoming particle
1277  std::unique_ptr<PunchThroughPDFCreator> pdf_pca2 (readLookuptablePDF(pdg, m_fileLookupTable, "PCA2_PDG"));
1278  if (!pdf_pca2)
1279  {
1280  return StatusCode::FAILURE;
1281  }
1282 
1283  // (5.) get the PDF for the punch-through particle momentum delta theta angle
1284  std::unique_ptr<PunchThroughPDFCreator> pdf_pca3 (readLookuptablePDF(pdg, m_fileLookupTable, "PCA3_PDG"));
1285  if (!pdf_pca3)
1286  {
1287  return StatusCode::FAILURE;
1288  }
1289 
1290  // (6.) get the PDF for the punch-through particle momentum delta phi angle
1291  std::unique_ptr<PunchThroughPDFCreator> pdf_pca4 (readLookuptablePDF(pdg, m_fileLookupTable, "PCA4_PDG"));
1292  if (!pdf_pca4)
1293  {
1294  return StatusCode::FAILURE;
1295  }
1296 
1297  // (7.) now finally store all this in the right std::map
1298  PunchThroughParticle *particle = new PunchThroughParticle(pdg, doAntiparticle);
1299  particle->setNumParticlesPDF(std::move(pdf_num));
1300  particle->setPCA0PDF(std::move(pdf_pca0));
1301  particle->setPCA1PDF(std::move(pdf_pca1));
1302  particle->setPCA2PDF(std::move(pdf_pca2));
1303  particle->setPCA3PDF(std::move(pdf_pca3));
1304  particle->setPCA4PDF(std::move(pdf_pca4));
1305 
1306  // (8.) set some additional particle and simulation properties
1307  minEnergy = ( minEnergy > restMass ) ? minEnergy : restMass;
1308  particle->setMinEnergy(minEnergy);
1309  particle->setMaxNumParticles(maxNumParticles);
1310  particle->setNumParticlesFactor(numParticlesFactor);
1311  particle->setEnergyFactor(energyFactor);
1312  particle->setPosAngleFactor(posAngleFactor);
1313  particle->setMomAngleFactor(momAngleFactor);
1314 
1315  // (9.) insert this PunchThroughParticle instance into the std::map class member
1316  m_particles[pdg] = particle;
1317 
1318  return StatusCode::SUCCESS;
1319 }

Member Data Documentation

◆ m_beamPipe

DoubleProperty PunchThroughG4Tool::m_beamPipe {this, "BeamPipeRadius", 500.}
private

beam pipe radius

Definition at line 217 of file PunchThroughG4Tool.h.

◆ m_correlatedParticle

IntegerArrayProperty PunchThroughG4Tool::m_correlatedParticle {this, "CorrelatedParticle", {}, "holds the pdg of the correlated particle for each given pdg"}
private

Definition at line 200 of file PunchThroughG4Tool.h.

◆ m_doAntiParticles

BooleanArrayProperty PunchThroughG4Tool::m_doAntiParticles {this, "DoAntiParticles", {}, "vector of bools to determine if anti-particles are created for each punch-through particle type"}
private

Definition at line 199 of file PunchThroughG4Tool.h.

◆ m_energyFactor

DoubleArrayProperty PunchThroughG4Tool::m_energyFactor {this, "EnergyFactor", {}, "scale the energy of the punch-through particles"}
private

Definition at line 208 of file PunchThroughG4Tool.h.

◆ m_energyPoints

std::vector<double> PunchThroughG4Tool::m_energyPoints
private

energy and eta points in param

Definition at line 173 of file PunchThroughG4Tool.h.

◆ m_envDefSvc

ServiceHandle<IEnvelopeDefSvc> PunchThroughG4Tool::m_envDefSvc {this, "EnvelopeDefSvc", "AtlasGeometry_EnvelopeDefSvc"}
private

Definition at line 214 of file PunchThroughG4Tool.h.

◆ m_etaPoints

std::vector<double> PunchThroughG4Tool::m_etaPoints
private

Definition at line 174 of file PunchThroughG4Tool.h.

◆ m_fileLookupTable

TFile* PunchThroughG4Tool::m_fileLookupTable {nullptr}
private

ROOT objects.

the punch-through lookup table file

Definition at line 183 of file PunchThroughG4Tool.h.

◆ m_filenameInverseCDF

StringProperty PunchThroughG4Tool::m_filenameInverseCDF {this, "FilenameInverseCdf", "", "holds the filename of inverse quantile transformer config"}
private

Definition at line 192 of file PunchThroughG4Tool.h.

◆ m_filenameInversePCA

StringProperty PunchThroughG4Tool::m_filenameInversePCA {this, "FilenameInversePca", "", "holds the filename of inverse PCA config"}
private

Definition at line 193 of file PunchThroughG4Tool.h.

◆ m_filenameLookupTable

StringProperty PunchThroughG4Tool::m_filenameLookupTable {this, "FilenameLookupTable", "CaloPunchThroughParametrisation.root", "holds the filename of the lookup table"}
private

Definition at line 191 of file PunchThroughG4Tool.h.

◆ m_fullCorrEnergy

DoubleArrayProperty PunchThroughG4Tool::m_fullCorrEnergy {this, "FullCorrelationEnergy", {}, "holds the energy threshold above which a particle correlation is fully developed"}
private

Definition at line 202 of file PunchThroughG4Tool.h.

◆ m_geoIDSvc

ServiceHandle<ISF::IGeoIDSvc> PunchThroughG4Tool::m_geoIDSvc {this, "GeoIDSvc", "ISF::GeoIDSvc"}
private

Definition at line 213 of file PunchThroughG4Tool.h.

◆ m_initiatorsEtaRange

DoubleArrayProperty PunchThroughG4Tool::m_initiatorsEtaRange {this, "InitiatorsEtaRange", {}, "vector of min and max abs eta range to allow punch through initiators"}
private

Definition at line 197 of file PunchThroughG4Tool.h.

◆ m_initiatorsMinEnergy

IntegerArrayProperty PunchThroughG4Tool::m_initiatorsMinEnergy {this, "InitiatorsMinEnergy", {}, "vector of punch-through initiator min energies to create punch through"}
private

Definition at line 196 of file PunchThroughG4Tool.h.

◆ m_inverse_PCA_matrix

std::vector<std::vector<std::vector<double> > > PunchThroughG4Tool::m_inverse_PCA_matrix
private

pca vectors

Definition at line 220 of file PunchThroughG4Tool.h.

◆ m_maxNumParticles

IntegerArrayProperty PunchThroughG4Tool::m_maxNumParticles {this, "MaxNumParticles", {}, "maximum number of punch-through particles for each particle type"}
private

Definition at line 206 of file PunchThroughG4Tool.h.

◆ m_minCorrEnergy

DoubleArrayProperty PunchThroughG4Tool::m_minCorrEnergy {this, "MinCorrelationEnergy", {}, "holds the energy threshold below which no particle correlation is computed"}
private

Definition at line 201 of file PunchThroughG4Tool.h.

◆ m_minEnergy

DoubleArrayProperty PunchThroughG4Tool::m_minEnergy {this, "MinEnergy", {}, "punch-through particles minimum energies"}
private

Definition at line 205 of file PunchThroughG4Tool.h.

◆ m_momAngleFactor

DoubleArrayProperty PunchThroughG4Tool::m_momAngleFactor {this, "ScaleMomDeflectionAngles", {}, "tuning parameter to scale the momentum deflection angles"}
private

Definition at line 204 of file PunchThroughG4Tool.h.

◆ m_numParticlesFactor

DoubleArrayProperty PunchThroughG4Tool::m_numParticlesFactor {this, "NumParticlesFactor", {}, "scale the number of punch-through particles"}
private

Definition at line 207 of file PunchThroughG4Tool.h.

◆ m_particles

std::map<int, PunchThroughParticle*> PunchThroughG4Tool::m_particles
private

needed to initially create punch-through particles with the right distributions

store all punch-through information for each particle id

Definition at line 186 of file PunchThroughG4Tool.h.

◆ m_PCA_means

std::vector<std::vector<double> > PunchThroughG4Tool::m_PCA_means
private

Definition at line 221 of file PunchThroughG4Tool.h.

◆ m_pdgInitiators

IntegerArrayProperty PunchThroughG4Tool::m_pdgInitiators {this, "PunchThroughInitiators", {}, "vector of punch-through initiator pgds"}
private

Definition at line 195 of file PunchThroughG4Tool.h.

◆ m_posAngleFactor

DoubleArrayProperty PunchThroughG4Tool::m_posAngleFactor {this, "ScalePosDeflectionAngles", {}, "tuning parameter to scale the position deflection angles"}
private

Definition at line 203 of file PunchThroughG4Tool.h.

◆ m_punchThroughParticles

IntegerArrayProperty PunchThroughG4Tool::m_punchThroughParticles {this, "PunchThroughParticles", {}, "vector of pdgs of the particles produced in punch-throughs"}
private

Definition at line 198 of file PunchThroughG4Tool.h.

◆ m_R1

double PunchThroughG4Tool::m_R1 {0.}
private

calo-MS borders

Definition at line 177 of file PunchThroughG4Tool.h.

◆ m_R2

double PunchThroughG4Tool::m_R2 {0.}
private

Definition at line 178 of file PunchThroughG4Tool.h.

◆ m_variable0_inverse_cdf

std::vector<std::map<double, double> > PunchThroughG4Tool::m_variable0_inverse_cdf
private

(vector of map) for CDF mappings

Definition at line 228 of file PunchThroughG4Tool.h.

◆ m_variable1_inverse_cdf

std::vector<std::map<double, double> > PunchThroughG4Tool::m_variable1_inverse_cdf
private

Definition at line 229 of file PunchThroughG4Tool.h.

◆ m_variable2_inverse_cdf

std::vector<std::map<double, double> > PunchThroughG4Tool::m_variable2_inverse_cdf
private

Definition at line 230 of file PunchThroughG4Tool.h.

◆ m_variable3_inverse_cdf

std::vector<std::map<double, double> > PunchThroughG4Tool::m_variable3_inverse_cdf
private

Definition at line 231 of file PunchThroughG4Tool.h.

◆ m_variable4_inverse_cdf

std::vector<std::map<double, double> > PunchThroughG4Tool::m_variable4_inverse_cdf
private

Definition at line 232 of file PunchThroughG4Tool.h.

◆ m_xml_info_cdf

std::vector<std::map<std::string, std::string> > PunchThroughG4Tool::m_xml_info_cdf
private

Definition at line 225 of file PunchThroughG4Tool.h.

◆ m_xml_info_pca

std::vector<std::map<std::string, std::string> > PunchThroughG4Tool::m_xml_info_pca
private

infoMaps

Definition at line 224 of file PunchThroughG4Tool.h.

◆ m_z1

double PunchThroughG4Tool::m_z1 {0.}
private

Definition at line 179 of file PunchThroughG4Tool.h.

◆ m_z2

double PunchThroughG4Tool::m_z2 {0.}
private

Definition at line 180 of file PunchThroughG4Tool.h.


The documentation for this class was generated from the following files:
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
xmlChar
unsigned char xmlChar
Definition: TGoodRunsListWriter.h:28
PunchThroughParticle
Definition: G4Atlas/G4AtlasTools/src/PunchThroughParticle.h:31
mergePhysValFiles.pattern
pattern
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:26
beamspotman.r
def r
Definition: beamspotman.py:676
PunchThroughG4Tool::m_correlatedParticle
IntegerArrayProperty m_correlatedParticle
Definition: PunchThroughG4Tool.h:200
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
Trk::ParticleSwitcher::particle
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses
Definition: ParticleHypothesis.h:76
get_generator_info.result
result
Definition: get_generator_info.py:21
python.SystemOfUnits.m
int m
Definition: SystemOfUnits.py:91
checkCoolLatestUpdate.variables
variables
Definition: checkCoolLatestUpdate.py:13
AddEmptyComponent.histName
string histName
Definition: AddEmptyComponent.py:64
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:67
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
PunchThroughG4Tool::m_filenameLookupTable
StringProperty m_filenameLookupTable
Definition: PunchThroughG4Tool.h:191
Base_Fragment.mass
mass
Definition: Sherpa_i/share/common/Base_Fragment.py:59
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:83
PunchThroughG4Tool::initializeInverseCDF
StatusCode initializeInverseCDF(const std::string &quantileTransformerConfigFile)
Definition: PunchThroughG4Tool.cxx:1019
xAOD::deltaPhi
setSAddress setEtaMS setDirPhiMS setDirZMS setBarrelRadius setEndcapAlpha setEndcapRadius setInterceptInner setEtaMap setEtaBin setIsTgcFailure setDeltaPt deltaPhi
Definition: L2StandAloneMuon_v1.cxx:160
PunchThroughG4Tool::m_fullCorrEnergy
DoubleArrayProperty m_fullCorrEnergy
Definition: PunchThroughG4Tool.h:202
plotmaker.hist
hist
Definition: plotmaker.py:148
PunchThroughG4Tool::inversePCA
std::vector< double > inversePCA(int pcaCdfIterator, std::vector< double > &variables) const
Definition: PunchThroughG4Tool.cxx:947
AtlasDetDescr::AtlasRegion
AtlasRegion
Definition: AtlasRegion.h:21
theta
Scalar theta() const
theta method
Definition: AmgMatrixBasePlugin.h:75
MuonGM::round
float round(const float toRound, const unsigned int decimals)
Definition: Mdt.cxx:27
PunchThroughG4Tool::initializeRegisterPunchThroughParticles
StatusCode initializeRegisterPunchThroughParticles()
initialize register all the punch-through particles which will be simulated
Definition: PunchThroughG4Tool.cxx:126
M_PI
#define M_PI
Definition: ActiveFraction.h:11
PunchThroughG4Tool::interpolateEnergy
double interpolateEnergy(const double &energy, CLHEP::HepRandomEngine *rndmEngine) const
Definition: PunchThroughG4Tool.cxx:1120
PunchThroughG4Tool::checkCaloMSBoundaries
StatusCode checkCaloMSBoundaries(const std::vector< std::pair< double, double >> *rzMS, const std::vector< std::pair< double, double >> *rzCalo)
Check calo-MS boundaries.
Definition: PunchThroughG4Tool.cxx:201
PunchThroughG4Tool::dotProduct
static std::vector< double > dotProduct(const std::vector< std::vector< double >> &m, const std::vector< double > &v)
Definition: PunchThroughG4Tool.cxx:837
upper
int upper(int c)
Definition: LArBadChannelParser.cxx:49
PunchThroughG4Tool::registerPunchThroughParticle
StatusCode registerPunchThroughParticle(G4ParticleTable &ptable, int pdg, bool doAntiparticle=false, double minEnergy=0., int maxNumParticles=-1, double numParticlesFactor=1., double energyFactor=1., double posAngleFactor=1., double momAngleFactor=1.)
registers a type of punch-through particles which will be simulated
Definition: PunchThroughG4Tool.cxx:1248
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
PrintTrkAnaSummary.dirName
dirName
Definition: PrintTrkAnaSummary.py:126
PunchThroughG4Tool::m_numParticlesFactor
DoubleArrayProperty m_numParticlesFactor
Definition: PunchThroughG4Tool.h:207
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
PunchThroughG4Tool::m_inverse_PCA_matrix
std::vector< std::vector< std::vector< double > > > m_inverse_PCA_matrix
pca vectors
Definition: PunchThroughG4Tool.h:220
python.TrigEgammaMonitorHelper.TH2F
def TH2F(name, title, nxbins, bins_par2, bins_par3, bins_par4, bins_par5=None, bins_par6=None, path='', **kwargs)
Definition: TrigEgammaMonitorHelper.py:45
PunchThroughG4Tool::m_R1
double m_R1
calo-MS borders
Definition: PunchThroughG4Tool.h:177
x
#define x
PunchThroughG4Tool::getFloatAfterPatternInStr
double getFloatAfterPatternInStr(const char *str, const char *pattern)
get the floating point number in a string, after the given pattern
Definition: PunchThroughG4Tool.cxx:1436
PunchThroughG4Tool::getCorrelatedParticles
int getCorrelatedParticles(const G4Track &g4PrimaryTrack, std::vector< std::map< std::string, double >> &secKinematicsMapVect, int pdg, int corrParticles, CLHEP::HepRandomEngine *rndmEngine, double interpEnergy, double interpEta)
get the right number of particles for the given pdg while considering the correlation to an other par...
Definition: PunchThroughG4Tool.cxx:501
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
PunchThroughG4Tool::m_geoIDSvc
ServiceHandle< ISF::IGeoIDSvc > m_geoIDSvc
Definition: PunchThroughG4Tool.h:213
drawFromPickle.atan
atan
Definition: drawFromPickle.py:36
PunchThroughG4Tool::normal_cdf
static double normal_cdf(double x)
Definition: PunchThroughG4Tool.cxx:833
PunchThroughG4Tool::m_variable0_inverse_cdf
std::vector< std::map< double, double > > m_variable0_inverse_cdf
(vector of map) for CDF mappings
Definition: PunchThroughG4Tool.h:228
PunchThroughG4Tool::m_z1
double m_z1
Definition: PunchThroughG4Tool.h:179
PunchThroughG4Tool::registerCorrelation
StatusCode registerCorrelation(int pdgID1, int pdgID2, double minCorrEnergy=0., double fullCorrEnergy=0.)
register a correlation for the two given types of punch-through particles with a given energy thresho...
Definition: PunchThroughG4Tool.cxx:1321
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
PunchThroughG4Tool::m_doAntiParticles
BooleanArrayProperty m_doAntiParticles
Definition: PunchThroughG4Tool.h:199
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
convertTimingResiduals.sum
sum
Definition: convertTimingResiduals.py:55
LArG4FSStartPointFilter.rand
rand
Definition: LArG4FSStartPointFilter.py:80
ParticleGun_FastCalo_ChargeFlip_Config.energy
energy
Definition: ParticleGun_FastCalo_ChargeFlip_Config.py:78
lumiFormat.i
int i
Definition: lumiFormat.py:85
z
#define z
PunchThroughG4Tool::createSecondaryTrack
G4Track * createSecondaryTrack(G4ParticleTable &ptable, G4FastStep &fastStep, double currentTime, int secondarySignedPDG, double energy, double theta, double phi, double momTheta, double momPhi, const std::vector< double > &caloMSVars)
create secondary track for each given the kinematics
Definition: PunchThroughG4Tool.cxx:804
PunchThroughG4Tool::punchTroughPosPropagator
G4ThreeVector punchTroughPosPropagator(double theta, double phi, double R1, double R2, double z1, double z2) const
get particle through the calorimeter
Definition: PunchThroughG4Tool.cxx:1455
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
python.CaloAddPedShiftConfig.str
str
Definition: CaloAddPedShiftConfig.py:42
python.LArMinBiasAlgConfig.int
int
Definition: LArMinBiasAlgConfig.py:59
Amg::transform
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Definition: GeoPrimitivesHelpers.h:156
ParticleGun_EoverP_Config.pid
pid
Definition: ParticleGun_EoverP_Config.py:62
test_pyathena.parent
parent
Definition: test_pyathena.py:15
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
PunchThroughG4Tool::m_initiatorsEtaRange
DoubleArrayProperty m_initiatorsEtaRange
Definition: PunchThroughG4Tool.h:197
python.selection.variable
variable
Definition: selection.py:33
PunchThroughG4Tool::m_filenameInversePCA
StringProperty m_filenameInversePCA
Definition: PunchThroughG4Tool.h:193
PunchThroughG4Tool::m_xml_info_cdf
std::vector< std::map< std::string, std::string > > m_xml_info_cdf
Definition: PunchThroughG4Tool.h:225
drawFromPickle.tan
tan
Definition: drawFromPickle.py:36
PunchThroughG4Tool::m_beamPipe
DoubleProperty m_beamPipe
beam pipe radius
Definition: PunchThroughG4Tool.h:217
WriteCalibToCool.swap
swap
Definition: WriteCalibToCool.py:94
PunchThroughG4Tool::initializeInversePCA
StatusCode initializeInversePCA(const std::string &inversePCAConfigFile)
Definition: PunchThroughG4Tool.cxx:956
beamspotman.dir
string dir
Definition: beamspotman.py:623
CxxUtils::atof
double atof(std::string_view str)
Converts a string into a double / float.
Definition: Control/CxxUtils/Root/StringUtils.cxx:91
trigbs_pickEvents.num
num
Definition: trigbs_pickEvents.py:76
PunchThroughG4Tool::m_initiatorsMinEnergy
IntegerArrayProperty m_initiatorsMinEnergy
Definition: PunchThroughG4Tool.h:196
PunchThroughG4Tool::m_PCA_means
std::vector< std::vector< double > > m_PCA_means
Definition: PunchThroughG4Tool.h:221
node::name
void name(const std::string &n)
Definition: node.h:37
CaloCellTimeCorrFiller.folderName
string folderName
Definition: CaloCellTimeCorrFiller.py:20
merge_scale_histograms.doc
string doc
Definition: merge_scale_histograms.py:9
PunchThroughG4Tool::m_variable3_inverse_cdf
std::vector< std::map< double, double > > m_variable3_inverse_cdf
Definition: PunchThroughG4Tool.h:231
PunchThroughG4Tool::getInfoMap
std::vector< std::map< std::string, std::string > > getInfoMap(const std::string &mainNode, const std::string &xmlFilePath)
Definition: PunchThroughG4Tool.cxx:901
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
PunchThroughG4Tool::m_minEnergy
DoubleArrayProperty m_minEnergy
Definition: PunchThroughG4Tool.h:205
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
L1CaloPhase1Monitoring.propName
propName
Definition: L1CaloPhase1Monitoring.py:518
PunchThroughG4Tool::interpolateEta
double interpolateEta(const double &eta, CLHEP::HepRandomEngine *rndmEngine) const
Definition: PunchThroughG4Tool.cxx:1181
FakeBkgTools::maxParticles
constexpr uint8_t maxParticles()
Definition: FakeBkgInternals.h:93
PunchThroughG4Tool::inverseCdfTransform
static double inverseCdfTransform(double variable, const std::map< double, double > &inverse_cdf_map)
Definition: PunchThroughG4Tool.cxx:1105
PunchThroughG4Tool::initializeRegisterCorrelations
StatusCode initializeRegisterCorrelations()
initialize register all correlations between particles
Definition: PunchThroughG4Tool.cxx:158
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
PunchThroughG4Tool::m_pdgInitiators
IntegerArrayProperty m_pdgInitiators
Definition: PunchThroughG4Tool.h:195
PunchThroughG4Tool::checkEnergySumFromSecondaries
std::vector< std::map< std::string, double > > checkEnergySumFromSecondaries(double mainEnergyInit, std::vector< std::map< std::string, double >> &secKinematicsMapVect)
check the energies satisfying energy condition
Definition: PunchThroughG4Tool.cxx:708
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
PathResolverFindCalibFile
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Definition: PathResolver.cxx:431
AtlasDetDescr::fAtlasCalo
@ fAtlasCalo
Definition: AtlasRegion.h:29
python.PyAthena.v
v
Definition: PyAthena.py:154
PunchThroughG4Tool::m_minCorrEnergy
DoubleArrayProperty m_minCorrEnergy
Definition: PunchThroughG4Tool.h:201
PunchThroughG4Tool::m_filenameInverseCDF
StringProperty m_filenameInverseCDF
Definition: PunchThroughG4Tool.h:192
PunchThroughG4Tool::getOneParticleKinematics
std::map< std::string, double > getOneParticleKinematics(CLHEP::HepRandomEngine *rndmEngine, int secondaryPDG, float initParticleTheta, float initParticlePhi, double interpEnergy, double interpEta) const
create exactly one punch-through particle with the given pdg and the given max energy
Definition: PunchThroughG4Tool.cxx:575
LArCellBinning.etaMin
etaMin
Definition: LArCellBinning.py:84
PunchThroughG4Tool::m_xml_info_pca
std::vector< std::map< std::string, std::string > > m_xml_info_pca
infoMaps
Definition: PunchThroughG4Tool.h:224
PunchThroughG4Tool::m_energyFactor
DoubleArrayProperty m_energyFactor
Definition: PunchThroughG4Tool.h:208
y
#define y
PunchThroughG4Tool::m_variable2_inverse_cdf
std::vector< std::map< double, double > > m_variable2_inverse_cdf
Definition: PunchThroughG4Tool.h:230
PunchThroughG4Tool::m_punchThroughParticles
IntegerArrayProperty m_punchThroughParticles
Definition: PunchThroughG4Tool.h:198
std::sort
void sort(typename std::reverse_iterator< DataModel_detail::iterator< DVL > > beg, typename std::reverse_iterator< DataModel_detail::iterator< DVL > > end, const Compare &comp)
Specialization of sort for DataVector/List.
Definition: DVL_algorithms.h:623
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
PunchThroughG4Tool::passedParamIterator
int passedParamIterator(int pid, double eta, const std::vector< std::map< std::string, std::string >> &mapvect) const
Definition: PunchThroughG4Tool.cxx:872
ref
const boost::regex ref(r_ef)
PunchThroughG4Tool::getVariableCDFmappings
static std::map< double, double > getVariableCDFmappings(xmlNodePtr &nodeParent)
Definition: PunchThroughG4Tool.cxx:1084
PunchThroughG4Tool::m_maxNumParticles
IntegerArrayProperty m_maxNumParticles
Definition: PunchThroughG4Tool.h:206
PunchThroughG4Tool::m_fileLookupTable
TFile * m_fileLookupTable
ROOT objects.
Definition: PunchThroughG4Tool.h:183
PunchThroughG4Tool::m_envDefSvc
ServiceHandle< IEnvelopeDefSvc > m_envDefSvc
Definition: PunchThroughG4Tool.h:214
PowhegPythia8EvtGen_jetjet.pdf
pdf
Definition: PowhegPythia8EvtGen_jetjet.py:4
TauGNNUtils::Variables::absEta
bool absEta(const xAOD::TauJet &tau, double &out)
Definition: TauGNNUtils.cxx:244
PunchThroughG4Tool::readLookuptablePDF
std::unique_ptr< PunchThroughPDFCreator > readLookuptablePDF(int pdgID, TFile *fileLookupTable, const std::string &folderName)
reads out the lookuptable for the given type of particle
Definition: PunchThroughG4Tool.cxx:1369
physics_parameters.parameters
parameters
Definition: physics_parameters.py:144
str
Definition: BTagTrackIpAccessor.cxx:11
PunchThroughG4Tool::m_momAngleFactor
DoubleArrayProperty m_momAngleFactor
Definition: PunchThroughG4Tool.h:204
PunchThroughG4Tool::m_R2
double m_R2
Definition: PunchThroughG4Tool.h:178
PunchThroughG4Tool::m_energyPoints
std::vector< double > m_energyPoints
energy and eta points in param
Definition: PunchThroughG4Tool.h:173
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
PunchThroughG4Tool::getAllParticles
int getAllParticles(const G4Track &g4PrimaryTrack, std::vector< std::map< std::string, double >> &secKinematicsMapVect, CLHEP::HepRandomEngine *rndmEngine, int pdg, double interpEnergy, double interpEta, int numParticles=-1)
create the right number of punch-through particles for the given pdg and return the number of particl...
Definition: PunchThroughG4Tool.cxx:444
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
python.compressB64.c
def c
Definition: compressB64.py:93
PunchThroughG4Tool::m_posAngleFactor
DoubleArrayProperty m_posAngleFactor
Definition: PunchThroughG4Tool.h:203
PunchThroughG4Tool::m_variable1_inverse_cdf
std::vector< std::map< double, double > > m_variable1_inverse_cdf
Definition: PunchThroughG4Tool.h:229
PunchThroughG4Tool::m_variable4_inverse_cdf
std::vector< std::map< double, double > > m_variable4_inverse_cdf
Definition: PunchThroughG4Tool.h:232
PunchThroughG4Tool::m_particles
std::map< int, PunchThroughParticle * > m_particles
needed to initially create punch-through particles with the right distributions
Definition: PunchThroughG4Tool.h:186
PunchThroughG4Tool::m_etaPoints
std::vector< double > m_etaPoints
Definition: PunchThroughG4Tool.h:174
node
Definition: node.h:21
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
PunchThroughG4Tool::m_z2
double m_z2
Definition: PunchThroughG4Tool.h:180