ATLAS Offline Software
Loading...
Searching...
No Matches
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.
virtual StatusCode finalize () override
 AlgTool finalize method.
StatusCode initializePhysics () override
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
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
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
StatusCode initializeRegisterPunchThroughParticles ()
 initialize register all the punch-through particles which will be simulated
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
StatusCode initializeRegisterCorrelations ()
 initialize register all correlations between particles
std::unique_ptr< PunchThroughPDFCreatorreadLookuptablePDF (int pdgID, TFile *fileLookupTable, const std::string &folderName)
 reads out the lookuptable for the given type of particle
StatusCode checkCaloMSBoundaries (const std::vector< std::pair< double, double > > *rzMS, const std::vector< std::pair< double, double > > *rzCalo)
 Check calo-MS boundaries.
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.
G4ThreeVector punchTroughPosPropagator (double theta, double phi, double R1, double R2, double z1, double z2) const
 get particle through the calorimeter
std::vector< std::map< std::string, double > > checkEnergySumFromSecondaries (double mainEnergyInit, std::vector< std::map< std::string, double > > &secKinematicsMapVect)
 check the energies satisfying energy condition
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
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
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
double getFloatAfterPatternInStr (const char *str, const char *pattern)
 get the floating point number in a string, after the given pattern
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
std::vector< double > m_etaPoints
double m_R1 {0.}
 calo-MS borders
double m_R2 {0.}
double m_z1 {0.}
double m_z2 {0.}
TFile * m_fileLookupTable {nullptr}
 ROOT objects.
std::map< int, PunchThroughParticle * > m_particles
 needed to initially create punch-through particles with the right distributions
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
std::vector< std::vector< std::vector< double > > > m_inverse_PCA_matrix
 pca vectors
std::vector< std::vector< double > > m_PCA_means
std::vector< std::map< std::string, std::string > > m_xml_info_pca
 infoMaps
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
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 50 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 205 of file PunchThroughG4Tool.cxx.

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

◆ 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 736 of file PunchThroughG4Tool.cxx.

736 {
737 //initialize variables
738 double energy;
739 double totEnergySecondaries = 0;
740
741 // Check energy conservation
742 // Step 1: sum all of the energies from the vector of secondaries (map) together, to initialize procedure later
743 for (std::size_t i = 0; i < secKinematicsMapVect.size(); i++) {
744 energy = secKinematicsMapVect[i].at("energy");
745 totEnergySecondaries += energy;
746 }
747
748 // Step 2: Sort the vector based on "energy" in descending order using lambda expression
749 std::sort(
750 secKinematicsMapVect.begin(),
751 secKinematicsMapVect.end(),
752 [](const std::map<std::string, double>& lhs, const std::map<std::string, double>& rhs) {
753 return lhs.at("energy") > rhs.at("energy");
754 }
755 );
756
757 // Just for printing here
758 if(totEnergySecondaries > mainEnergyInit){
759 ATH_MSG_DEBUG("[PunchThroughG4Tool::checkEnergySumFromSecondaries] Case where energy of created secondaries more than parent track identified! ");
760 ATH_MSG_DEBUG("[PunchThroughG4Tool::checkEnergySumFromSecondaries] ==> TotalSecondariesEnergy = " << totEnergySecondaries << ", ParentEnergy = "<< mainEnergyInit);
761 }
762
763 // Step 3: Adjust the energy and remove secondary with lowest energy to ensure total energy of secondaries <= mainEnergyInit
764 while (totEnergySecondaries > mainEnergyInit && !secKinematicsMapVect.empty()) {
765 // Get the last map in the vector (which has the lowest energy due to sorting)
766 std::map<std::string, double> lastMap = secKinematicsMapVect.back();
767
768 // Get the energy value of the last map
769 double lastEnergy = lastMap.at("energy");
770
771 // Remove the last map from the vector
772 secKinematicsMapVect.pop_back();
773
774 // Subtract the removed energy from totEnergySecondaries
775 totEnergySecondaries -= lastEnergy;
776 }
777
778 //finally return the secKinematicsMapVect after the checks
779 return secKinematicsMapVect;
780}
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.

◆ checkParticleTable()

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

Definition at line 277 of file PunchThroughG4Tool.cxx.

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

◆ 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 284 of file PunchThroughG4Tool.cxx.

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

◆ 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 782 of file PunchThroughG4Tool.cxx.

782 {
783 // Get Geant4 particle definition
784 const G4ParticleDefinition* mainG4Particle = g4PrimaryTrack.GetDefinition();
785 float mainMomMag2 = g4PrimaryTrack.GetMomentum().mag2();
786 float mainPartMass = mainG4Particle->GetPDGMass();
787 double mainEnergyInit = std::sqrt(mainMomMag2 + mainPartMass * mainPartMass);
788
789 // Energy conservation: call checkEnergySumFromSecondaries to check/update secKinematicsMapVect
790 secKinematicsMapVect = checkEnergySumFromSecondaries(mainEnergyInit, secKinematicsMapVect);
791
792 // set number of secondary tracks to be produced
793 int numSecondaries = secKinematicsMapVect.size();
794
795 if(numSecondaries>0){ //safety
796 // set number of secondary tracks from numSecondaries above
797 fastStep.SetNumberOfSecondaryTracks(numSecondaries);
798
799 // Get current (global) time from original main G4Track
800 double currentTime = g4PrimaryTrack.GetGlobalTime();
801
802 // create the secondaries given the number of secondaries to be created
803 for(int i=0;i < numSecondaries; i++){
804 int anti = (int)(secKinematicsMapVect[i].at("anti"));
805 int secondaryPDG = (int)(secKinematicsMapVect[i].at("secondaryPDG"));
806 int signedPDG = secondaryPDG*anti;
807 double energy = secKinematicsMapVect[i].at("energy");
808 double theta = secKinematicsMapVect[i].at("theta");
809 double phi = secKinematicsMapVect[i].at("phi");
810 double momTheta = secKinematicsMapVect[i].at("momTheta");
811 double momPhi = secKinematicsMapVect[i].at("momPhi");
812
813 // (**) finally create the punch-through particle as a G4Track (secondary particle track)
814 ATH_MSG_DEBUG("[PunchThroughG4Tool::createAllSecondaryTracks] createSecondaryTrack input parameters: currentTime = " << currentTime << " anti? = "<< anti <<" signedPDG = "<< signedPDG <<" energy = "<< energy <<" theta = "<< theta <<" phi = "<< phi <<" momTheta = "<< momTheta << " momPhi " << momPhi);
815 G4Track* newSecTrack = createSecondaryTrack( ptable, fastStep, currentTime, signedPDG, energy, theta, phi, momTheta, momPhi, caloMSVars);
816
817 // if something went wrong and the secondary track is simply not created
818 if (!newSecTrack)
819 {
820 G4Exception("[PunchThroughG4Tool::createAllSecondaryTracks]", "ExceptionError", FatalException, "something went wrong while creating punch-through particle tracks");
821 return;
822 }
823
824 // add this secondary track to the g4trackvector
825 secTrackCont.push_back( newSecTrack );
826 }
827 }
828
829 //printout: fastStep.DumpInfo()
830}
Scalar phi() const
phi method
Scalar theta() const
theta method
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
std::vector< std::map< std::string, double > > checkEnergySumFromSecondaries(double mainEnergyInit, std::vector< std::map< std::string, double > > &secKinematicsMapVect)
check the energies satisfying energy condition

◆ 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 832 of file PunchThroughG4Tool.cxx.

834{
835 //initialize to nullptr
836 G4Track *newSecTrack = nullptr;
837
838 G4ParticleDefinition* secG4Particle = ptable.FindParticle(secondarySignedPDG);
839 double mass = secG4Particle->GetPDGMass();
840
841 // the intersection point with Calo-MS surface
842 G4ThreeVector posVec = punchTroughPosPropagator(theta, phi, caloMSVars[0], caloMSVars[1], caloMSVars[2], caloMSVars[3]);
843
844 // set up the real punch-through particle at this position
845 // set up the momentum vector of this particle as a GlobalMomentum
846 // by using the given energy and mass of the particle and also using
847 // the given theta and phi
848 G4ThreeVector momVec;
849 double momMag = std::sqrt(energy*energy - mass*mass);
850 momVec.setRThetaPhi(momMag,momTheta,momPhi);
851 ATH_MSG_DEBUG("[PunchThroughG4Tool]::createSecondaryTrack] setRThetaPhi pre input parameters: energy = " << energy <<" mass = "<< mass);
852 ATH_MSG_DEBUG("[PunchThroughG4Tool]::createSecondaryTrack] setRThetaPhi input parameters: std::sqrt(energy*energy - mass*mass) = " << std::sqrt(energy*energy - mass*mass) << " momTheta = "<< momTheta <<" momPhi = "<< momPhi);
853
854 // create dynamic particle
855 G4DynamicParticle dynParticle(secG4Particle,momVec);
856 newSecTrack = fastStep.CreateSecondaryTrack(dynParticle, posVec, currentTime, false); // use position in global coordinates instead
857
858 return newSecTrack;
859}
G4ThreeVector punchTroughPosPropagator(double theta, double phi, double R1, double R2, double z1, double z2) const
get particle through the calorimeter

◆ dotProduct()

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

Definition at line 865 of file PunchThroughG4Tool.cxx.

866{
867 std::vector<double> result;
868 result.reserve(m.size());
869 for (const auto& r : m){
870 result.push_back(std::inner_product(v.begin(), v.end(), r.begin(), 0.0));
871 }
872
873 return result;
874}
int r
Definition globals.cxx:22

◆ finalize()

StatusCode PunchThroughG4Tool::finalize ( )
overridevirtual

AlgTool finalize method.

Definition at line 265 of file PunchThroughG4Tool.cxx.

266{
267 ATH_MSG_DEBUG( "[PunchThroughG4Tool] finalize() starting" );
268 for(auto & each : m_particles) {
269 delete each.second;
270 }
271
272 ATH_MSG_DEBUG( "[PunchThroughG4Tool] finalize() successful" );
273
274 return StatusCode::SUCCESS;
275}

◆ 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 472 of file PunchThroughG4Tool.cxx.

473{
474 // Get initial Geant4 position theta and phi
475 float initParticleTheta = g4PrimaryTrack.GetPosition().theta();
476 float initParticlePhi = g4PrimaryTrack.GetPosition().phi();
477
478 // get the current particle
479 PunchThroughParticle *p = m_particles.at(pdg);
480 double minAllowedEnergy = p->getMinEnergy();
481
482 // if no number of particles (=-1) was handed over as an argument
483 // -> get the number of particles from the pdf
484 if ( numParticles < 0 )
485 {
486 // prepare the function arguments for the PunchThroughPDFCreator class
487 std::vector<int> parameters;
488 parameters.push_back( std::round(interpEnergy) );
489 parameters.push_back( std::round(interpEta*100) );
490 // the maximum number of particles which should be produced
491 // if no maximum number is given, this is -1
492 int maxParticles = p->getMaxNumParticles();
493
494 // get the right number of punch-through particles
495 // and ensure that we do not create too many particles
496 do
497 {
498 numParticles = int( p->getNumParticlesPDF()->getRand(rndmEngine, parameters) );
499
500 // scale the number of particles if requested
501 numParticles = lround( numParticles *= p->getNumParticlesFactor() );
502 }
503 while ( (maxParticles >= 0.) && (numParticles > maxParticles) );
504 }
505
506 ATH_MSG_DEBUG("[PunchThroughG4Tool] adding " << numParticles << " punch-through particles with pdg code: " << pdg);
507
508 // get how many secondary particles to be created
509 for ( int numCreated = 0; numCreated < numParticles; numCreated++ )
510 {
511 // create one particle which fullfills the right energy distribution
512 std::map<std::string, double> secondaryKinematicsMap = getOneParticleKinematics(rndmEngine, pdg, initParticleTheta, initParticlePhi, interpEnergy, interpEta);
513
514 //safety to cater minimum energy as rest mass
515 double energy = secondaryKinematicsMap.at("energy");
516 if(energy > minAllowedEnergy){
517 // push to the vector of maps
518 secKinematicsMapVect.push_back(secondaryKinematicsMap);
519 }
520 }
521
522 // Get the size of the vector
523 std::size_t numSecondaries = secKinematicsMapVect.size();
524
525 // the actual (pre) number of particles which was created is numSecondaries, which is incremented in the loop
526 return (numSecondaries);
527}
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
constexpr uint8_t maxParticles()

◆ getCaloMSVars()

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

Definition at line 197 of file PunchThroughG4Tool.cxx.

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

◆ 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 529 of file PunchThroughG4Tool.cxx.

530{
531 // Get Geant4 particle definition
532 const G4ParticleDefinition * mainG4Particle = g4PrimaryTrack.GetDefinition();
533 // Get Geant4 particle pdgID
534 float mainMomMag2 = g4PrimaryTrack.GetMomentum().mag2();
535 float mainPartMass = mainG4Particle->GetPDGMass();
536
537 // get the PunchThroughParticle class
538 PunchThroughParticle *p = m_particles.at(pdg);
539
540 const double initEnergy = std::sqrt( mainMomMag2 + mainPartMass*mainPartMass );
541
542 // (1.) decide if we do correlation or not
543 double rand = CLHEP::RandFlat::shoot(rndmEngine)
544 *(p->getFullCorrelationEnergy() - p->getMinCorrelationEnergy())
545 + p->getMinCorrelationEnergy();
546
547 // if initEnergy less than random corr energy (meaning threshold for min energy for doing correlation not passed)
548 if ( initEnergy < rand )
549 {
550 // here we do not do correlation
551 return getAllParticles(g4PrimaryTrack, secKinematicsMapVect, rndmEngine, pdg, interpEnergy, interpEta);
552 }
553
554 // (2.) if this point is reached, we do correlation
555 // decide which 2d correlation histogram to use
556 double *histDomains = p->getCorrelationHistDomains();
557 TH2F *hist2d = nullptr;
558 // compute the center values of the lowE and highE
559 // correlation histogram domains
560 if ( initEnergy < histDomains[1])
561 {
562 // initial energy lower than border between lowEnergy and highEnergy histogram domain
563 // --> choose lowEnergy correlation histogram
564 hist2d = p->getCorrelationLowEHist();
565 }
566 else
567 {
568 double rand = CLHEP::RandFlat::shoot(rndmEngine)*(histDomains[2]-histDomains[1]) + histDomains[1];
569 hist2d = ( initEnergy < rand) ? p->getCorrelationLowEHist() : p->getCorrelationHighEHist();
570 }
571
572 // get the correlation 2d histogram
573 // now find out where on the x-axis the the bin for number of
574 // correlated particles is
575 Int_t xbin = hist2d->GetXaxis()->FindFixBin(corrParticles);
576 int numParticles = 0;
577 int maxParticles = p->getMaxNumParticles();
578 // now the distribution along the y-axis is a PDF for the number
579 // of 'pdg' particles
580 do
581 {
582 double rand = CLHEP::RandFlat::shoot(rndmEngine);
583 double sum = 0.;
584 for ( int ybin = 1; ybin <= hist2d->GetNbinsY(); ybin++ )
585 {
586 sum += hist2d->GetBinContent(xbin, ybin);
587 // check if we choose the current bin or not
588 if ( sum >= rand )
589 {
590 numParticles = ybin - 1;
591 break;
592 }
593 }
594 // scale the number of particles is requested
595 numParticles = lround( numParticles * p->getNumParticlesFactor() );
596 }
597 while ( (maxParticles >= 0.) && (numParticles > maxParticles) );
598
599 // finally create this exact number of particles
600 return getAllParticles(g4PrimaryTrack, secKinematicsMapVect, rndmEngine, pdg, interpEnergy, interpEta, numParticles);
601}
TH2F(name, title, nxbins, bins_par2, bins_par3, bins_par4, bins_par5=None, bins_par6=None, path='', **kwargs)

◆ 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 1464 of file PunchThroughG4Tool.cxx.

1465{
1466 double num = 0.;
1467
1468 const std::string_view str( cstr);
1469 const std::string_view pattern( cpattern);
1470 const size_t pos = str.find(pattern);
1471
1472 if ( pos == std::string::npos)
1473 {
1474 ATH_MSG_WARNING("[PunchThroughG4Tool] unable to retrieve floating point number from string");
1475 return -999999999999.;
1476 }
1477 const std::string_view substring = str.substr(pos+pattern.length());
1478 std::from_chars(substring.data(), substring.data() + substring.size(), num);
1479 return num;
1480}
#define ATH_MSG_WARNING(x)

◆ getInfoMap()

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

Definition at line 929 of file PunchThroughG4Tool.cxx.

929 {
930 // Initialize pointers
931 xmlDocPtr doc;
932 xmlChar* xmlBuff = nullptr;
933
934 std::vector<std::map<std::string, std::string>> xml_info;
935 doc = xmlParseFile( xmlFilePath.c_str() );
936
937 //check info first
938 for( xmlNodePtr nodeRoot = doc->children; nodeRoot != nullptr; nodeRoot = nodeRoot->next) {
939 if (xmlStrEqual( nodeRoot->name, BAD_CAST mainNode.c_str() )) {
940 for( xmlNodePtr nodeRootChild = nodeRoot->children; nodeRootChild != nullptr; nodeRootChild = nodeRootChild->next ) {
941 if (xmlStrEqual( nodeRootChild->name, BAD_CAST "info" )) {
942 if (nodeRootChild->children != NULL) {
943 for( xmlNodePtr infoNode = nodeRootChild->children; infoNode != nullptr; infoNode = infoNode->next) {
944 if(xmlStrEqual( infoNode->name, BAD_CAST "item" )){
945 std::map<std::string, std::string> xml_info_item;
946
947 if ((xmlBuff = xmlGetProp(infoNode, BAD_CAST "name")) != nullptr) {
948 xml_info_item.insert({"name", reinterpret_cast<const char*>(xmlBuff)});
949 }
950 if ((xmlBuff = xmlGetProp(infoNode, BAD_CAST "etaMins")) != nullptr) {
951 xml_info_item.insert({"etaMins", reinterpret_cast<const char*>(xmlBuff)});
952 }
953 if ((xmlBuff = xmlGetProp(infoNode, BAD_CAST "etaMaxs")) != nullptr) {
954 xml_info_item.insert({"etaMaxs", reinterpret_cast<const char*>(xmlBuff)});
955 }
956 if ((xmlBuff = xmlGetProp(infoNode, BAD_CAST "pidStr")) != nullptr) {
957 xml_info_item.insert({"pidStr", reinterpret_cast<const char*>(xmlBuff)});
958 }
959
960 xml_info.push_back(xml_info_item);
961 }
962 }
963 }
964 }
965 }
966 }
967 }
968
969 // free memory when done
970 xmlFreeDoc(doc);
971
972 return xml_info;
973}
unsigned char xmlChar

◆ 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 603 of file PunchThroughG4Tool.cxx.

604{
605 // get a local copy of the needed punch-through particle class
606 PunchThroughParticle *p = m_particles.at(secondaryPDG);
607
608 // (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
609 int pcaCdfIterator = passedParamIterator(secondaryPDG, interpEta*100, m_xml_info_pca); //pca and cdf info should be of same size
610
611 ATH_MSG_DEBUG("[PunchThroughG4Tool] passedPCAIterator ==> pcaCdfIterator = "<< pcaCdfIterator <<" , pdg = "<< secondaryPDG <<" , interpEnergy = "<< interpEnergy <<" MeV, interpEta(*100) = "<< interpEta*100);
612
613 // (1.) decide if we create a particle or an anti-particle,
614 // this is from m_doAntiParticles properties
615 int anti = 1;
616 if ( p->getdoAnti() )
617 {
618 // get a random-value
619 double rand = CLHEP::RandFlat::shoot(rndmEngine);
620 // 50/50 chance to be a particle or its anti-particle
621 if (rand > 0.5) anti = -1;
622 }
623
624 // (2.) get the right punch-through distributions
625 // prepare the function arguments for the PunchThroughPDFCreator class
626 std::vector<int> parInitEnergyEta;
627 parInitEnergyEta.push_back( std::round(interpEnergy) );
628 parInitEnergyEta.push_back( std::round(interpEta*100) );
629
630 //initialise variables to store punch through particle kinematics
631 double energy = 0.;
632 double deltaTheta = 0.;
633 double deltaPhi = 0.;
634 double momDeltaTheta = 0.;
635 double momDeltaPhi = 0.;
636
637 double principal_component_0 = 0.;
638 double principal_component_1 = 0.;
639 double principal_component_2 = 0.;
640 double principal_component_3 = 0.;
641 double principal_component_4 = 0.;
642 std::vector<double> transformed_variables;
643
644 principal_component_0 = p->getPCA0PDF()->getRand(rndmEngine, parInitEnergyEta);
645 principal_component_1 = p->getPCA1PDF()->getRand(rndmEngine, parInitEnergyEta);
646 principal_component_2 = p->getPCA2PDF()->getRand(rndmEngine, parInitEnergyEta);
647 principal_component_3 = p->getPCA3PDF()->getRand(rndmEngine, parInitEnergyEta);
648 principal_component_4 = p->getPCA4PDF()->getRand(rndmEngine, parInitEnergyEta);
649
650 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 );
651
652 std::vector<double> principal_components {
653 principal_component_0,
654 principal_component_1,
655 principal_component_2,
656 principal_component_3,
657 principal_component_4
658 };
659
660 transformed_variables = inversePCA(pcaCdfIterator,principal_components);
661
662 energy = inverseCdfTransform(transformed_variables.at(0), m_variable0_inverse_cdf[pcaCdfIterator]);
663 deltaTheta = inverseCdfTransform(transformed_variables.at(1), m_variable1_inverse_cdf[pcaCdfIterator]);
664 deltaPhi = inverseCdfTransform(transformed_variables.at(2), m_variable2_inverse_cdf[pcaCdfIterator]);
665 momDeltaTheta = inverseCdfTransform(transformed_variables.at(3), m_variable3_inverse_cdf[pcaCdfIterator]);
666 momDeltaPhi = inverseCdfTransform(transformed_variables.at(4), m_variable4_inverse_cdf[pcaCdfIterator]);
667
668 ATH_MSG_DEBUG("[PunchThroughG4Tool] Transformed punch through kinematics: energy = "<< energy <<" MeV deltaTheta = "<< deltaTheta <<" deltaPhi = "<< deltaPhi <<" momDeltaTheta = "<< momDeltaTheta <<" momDeltaPhi = "<< momDeltaPhi );
669
670 energy *= p->getEnergyFactor(); // scale the energy if requested
671
672 // safety: if energy less than minimum energy, add a small energy (10MeV to it to continue)
673 if (energy < p->getMinEnergy()) {
674 energy = p->getMinEnergy() + 10;
675 }
676
677 // (2.2) get the particles DeltaTheta relative to the incoming particle
678 double theta = 0;
679 // loop to keep theta within range [0,PI]
680 do
681 {
682 // decide if delta positive/negative
683 deltaTheta *= ( CLHEP::RandFlat::shoot(rndmEngine) > 0.5 ) ? 1. : -1.;
684
685 // calculate the exact theta value of the later created
686 // punch-through particle
687 theta = initParticleTheta + deltaTheta*p->getPosAngleFactor();
688 }
689 while ( (theta > M_PI) || (theta < 0.) );
690
691 // (2.3) get the particle's delta phi relative to the incoming particle
692 deltaPhi *= ( CLHEP::RandFlat::shoot(rndmEngine) > 0.5 ) ? 1. : -1.;
693
694 // keep phi within range [-PI,PI]
695 double phi = initParticlePhi + deltaPhi*p->getPosAngleFactor();
696 while ( std::fabs(phi) > 2*M_PI) phi /= 2.;
697 while (phi > M_PI) phi -= 2*M_PI;
698 while (phi < -M_PI) phi += 2*M_PI;
699
700 // (2.4) get the particle momentum delta theta, relative to its position
701 //
702 // loop to keep momTheta within range [0,PI]
703 double momTheta = 0.;
704 do
705 {
706 // decide if delta positive/negative
707 momDeltaTheta *= ( CLHEP::RandFlat::shoot(rndmEngine) > 0.5 ) ? 1. : -1.;
708 // calculate the exact momentum theta value of the later created
709 // punch-through particle
710 momTheta = theta + momDeltaTheta*p->getMomAngleFactor();
711 }
712 while ( (momTheta > M_PI) || (momTheta < 0.) );
713
714 // (2.5) get the particle momentum delta phi, relative to its position
715 momDeltaPhi *= ( CLHEP::RandFlat::shoot(rndmEngine) > 0.5 ) ? 1. : -1.;
716
717 double momPhi = phi + momDeltaPhi*p->getMomAngleFactor();
718 // keep momPhi within range [-PI,PI]
719 while ( std::fabs(momPhi) > 2*M_PI) momPhi /= 2.;
720 while (momPhi > M_PI) momPhi -= 2*M_PI;
721 while (momPhi < -M_PI) momPhi += 2*M_PI;
722
723 // store the kinematics in a map and return it
724 std::map<std::string, double> secondaryKinematicsMap;
725 secondaryKinematicsMap.insert({ "anti" , anti });
726 secondaryKinematicsMap.insert({ "secondaryPDG" , secondaryPDG });
727 secondaryKinematicsMap.insert({ "energy" , energy });
728 secondaryKinematicsMap.insert({ "theta" , theta });
729 secondaryKinematicsMap.insert({ "phi" , phi });
730 secondaryKinematicsMap.insert({ "momTheta" , momTheta });
731 secondaryKinematicsMap.insert({ "momPhi" , momPhi });
732
733 return secondaryKinematicsMap;
734}
#define M_PI
Scalar deltaPhi(const MatrixBase< Derived > &vec) const
std::vector< std::map< double, double > > m_variable2_inverse_cdf
static double inverseCdfTransform(double variable, const std::map< double, double > &inverse_cdf_map)
int passedParamIterator(int pid, double eta, const std::vector< std::map< std::string, std::string > > &mapvect) const
std::vector< std::map< double, double > > m_variable0_inverse_cdf
(vector of map) for CDF mappings
std::vector< std::map< std::string, std::string > > m_xml_info_pca
infoMaps
std::vector< std::map< double, double > > m_variable4_inverse_cdf
std::vector< double > inversePCA(int pcaCdfIterator, std::vector< double > &variables) const
std::vector< std::map< double, double > > m_variable3_inverse_cdf
std::vector< std::map< double, double > > m_variable1_inverse_cdf

◆ getVariableCDFmappings()

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

Definition at line 1112 of file PunchThroughG4Tool.cxx.

1112 {
1113 std::map<double, double> mappings;
1114 xmlChar* xmlBuff = nullptr;
1115 double ref = -1;
1116 double quant = -1;
1117 for( xmlNodePtr node = nodeParent->children; node != nullptr; node = node->next ) {
1118 //Get min and max values that we normalise values to
1119 if (xmlStrEqual( node->name, BAD_CAST "CDFmap" )) {
1120 if ((xmlBuff = xmlGetProp(node, BAD_CAST "ref")) != nullptr) {
1121 ref = atof( reinterpret_cast<const char*> (xmlBuff) );
1122 }
1123 if ((xmlBuff = xmlGetProp(node, BAD_CAST "quant")) != nullptr) {
1124 quant = atof( reinterpret_cast<const char*> (xmlBuff) );
1125 }
1126 mappings.insert(std::pair<double, double>(ref, quant) );
1127 }
1128 }
1129
1130 return mappings;
1131}
const boost::regex ref(r_ef)
static int quant(double min, double max, unsigned nSteps, double val)
double atof(std::string_view str)
Converts a string into a double / float.

◆ 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 //retrieve inverse CDF config file
50 {
51 ATH_MSG_WARNING("[PunchThroughG4Tool] unable to open or read the inverse CDF config");
52 return StatusCode::FAILURE;
53 }
54
55 //retrieve inverse PCA config file
57 {
58 ATH_MSG_WARNING("[PunchThroughG4Tool] unable to open or read the inverse PCA config");
59 return StatusCode::FAILURE;
60 }
61
62 //check first the size of infoMap for both PCA and CDF, they should be equal
63 if (!(m_xml_info_pca.size() == m_xml_info_cdf.size()))
64 {
65 ATH_MSG_WARNING("[PunchThroughG4Tool] size of infoMap for PCA and CDF differs! Something is wrong with input xml files.");
66 return StatusCode::FAILURE;
67 }
68
69 ATH_MSG_INFO( "[PunchThroughG4Tool] initialization is successful" );
70 return StatusCode::SUCCESS;
71}
#define ATH_MSG_INFO(x)
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
std::vector< std::map< std::string, std::string > > m_xml_info_cdf
StatusCode initializeInverseCDF(const std::string &quantileTransformerConfigFile)
StatusCode initializeInversePCA(const std::string &inversePCAConfigFile)
StringProperty m_filenameInversePCA
StringProperty m_filenameInverseCDF

◆ initializeInverseCDF()

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

Definition at line 1047 of file PunchThroughG4Tool.cxx.

1047 {
1048 std::map<double, double> variable0_inverse_cdf_row;
1049 std::map<double, double> variable1_inverse_cdf_row;
1050 std::map<double, double> variable2_inverse_cdf_row;
1051 std::map<double, double> variable3_inverse_cdf_row;
1052 std::map<double, double> variable4_inverse_cdf_row;
1053
1054 // Initialize pointers
1055 xmlDocPtr doc;
1056
1057 //parse xml that contains config for inverse CDF for each of punch through particle kinematics
1058
1059 doc = xmlParseFile( inverseCdfConfigFile.c_str() );
1060
1061 ATH_MSG_DEBUG( "[PunchThroughG4Tool] Loading inverse CDF: " << inverseCdfConfigFile);
1062
1063 //check info first
1064 m_xml_info_cdf = getInfoMap("CDFMappings",inverseCdfConfigFile);
1065
1066 //do the saving
1067 for (unsigned int i = 0; i < m_xml_info_cdf.size(); i++) {
1068 ATH_MSG_DEBUG( "[PunchThroughG4Tool] m_xml_info_cdf[" << i << "].at('name') = " << m_xml_info_cdf[i].at("name"));
1069
1070 for( xmlNodePtr nodeRoot = doc->children; nodeRoot != nullptr; nodeRoot = nodeRoot->next) {
1071 if (xmlStrEqual( nodeRoot->name, BAD_CAST "CDFMappings" )) {
1072 for( xmlNodePtr typeMappings = nodeRoot->children; typeMappings != nullptr; typeMappings = typeMappings->next ) {
1073 if (xmlStrEqual( typeMappings->name, BAD_CAST m_xml_info_cdf[i].at("name").c_str() )) {
1074 if (typeMappings->children != NULL) {
1075 for( xmlNodePtr nodeMappings = typeMappings->children; nodeMappings != nullptr; nodeMappings = nodeMappings->next) {
1076
1077 if (xmlStrEqual( nodeMappings->name, BAD_CAST "variable0" )) {
1078 variable0_inverse_cdf_row = getVariableCDFmappings(nodeMappings);
1079 }
1080 else if (xmlStrEqual( nodeMappings->name, BAD_CAST "variable1" )) {
1081 variable1_inverse_cdf_row = getVariableCDFmappings(nodeMappings);
1082 }
1083 else if (xmlStrEqual( nodeMappings->name, BAD_CAST "variable2" )) {
1084 variable2_inverse_cdf_row = getVariableCDFmappings(nodeMappings);
1085 }
1086 else if (xmlStrEqual( nodeMappings->name, BAD_CAST "variable3" )) {
1087 variable3_inverse_cdf_row = getVariableCDFmappings(nodeMappings);
1088 }
1089 else if (xmlStrEqual( nodeMappings->name, BAD_CAST "variable4" )) {
1090 variable4_inverse_cdf_row = getVariableCDFmappings(nodeMappings);
1091 }
1092 }
1093
1094 }
1095 }
1096 }
1097 }
1098 }
1099 m_variable0_inverse_cdf.push_back(variable0_inverse_cdf_row);
1100 m_variable1_inverse_cdf.push_back(variable1_inverse_cdf_row);
1101 m_variable2_inverse_cdf.push_back(variable2_inverse_cdf_row);
1102 m_variable3_inverse_cdf.push_back(variable3_inverse_cdf_row);
1103 m_variable4_inverse_cdf.push_back(variable4_inverse_cdf_row);
1104 }
1105
1106 // free memory when done
1107 xmlFreeDoc(doc);
1108
1109 return StatusCode::SUCCESS;
1110}
std::vector< std::map< std::string, std::string > > getInfoMap(const std::string &mainNode, const std::string &xmlFilePath)
static std::map< double, double > getVariableCDFmappings(xmlNodePtr &nodeParent)

◆ initializeInversePCA()

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

Definition at line 984 of file PunchThroughG4Tool.cxx.

984 {
985 // Initialize pointers
986 xmlDocPtr doc;
987 xmlChar* xmlBuff = nullptr;
988
989 doc = xmlParseFile( inversePCAConfigFile.c_str() );
990
991 ATH_MSG_DEBUG( "[PunchThroughG4Tool] Loading inversePCA: " << inversePCAConfigFile);
992
993 //check info first
994 m_xml_info_pca = getInfoMap("PCAinverse",inversePCAConfigFile);
995
996 //do the saving
997 for (unsigned int i = 0; i < m_xml_info_pca.size(); i++) {
998 std::vector<std::vector<double>> PCA_matrix;
999 ATH_MSG_DEBUG( "[PunchThroughG4Tool] m_xml_info_pca[" << i << "].at('name') = " << m_xml_info_pca[i].at("name"));
1000
1001 for( xmlNodePtr nodeRoot = doc->children; nodeRoot != nullptr; nodeRoot = nodeRoot->next) {
1002 if (xmlStrEqual( nodeRoot->name, BAD_CAST "PCAinverse" )) {
1003 for( xmlNodePtr nodePCAinverse = nodeRoot->children; nodePCAinverse != nullptr; nodePCAinverse = nodePCAinverse->next ) {
1004
1005 if (xmlStrEqual( nodePCAinverse->name, BAD_CAST m_xml_info_pca[i].at("name").c_str() )) {
1006 if (nodePCAinverse->children != NULL) {
1007 for( xmlNodePtr pcaNode = nodePCAinverse->children; pcaNode != nullptr; pcaNode = pcaNode->next) {
1008
1009 if (xmlStrEqual( pcaNode->name, BAD_CAST "PCAmatrix" )) {
1010 std::vector<double> PCA_matrix_row;
1011 for (int i = 0; i <= 4; ++i) {
1012 std::string propName = "comp_" + std::to_string(i); // Dynamically create property name
1013 if ((xmlBuff = xmlGetProp(pcaNode, BAD_CAST propName.c_str())) != nullptr) {
1014 PCA_matrix_row.push_back(atof(reinterpret_cast<const char*>(xmlBuff))); // Convert and push to the row
1015 }
1016 }
1017 PCA_matrix.push_back(PCA_matrix_row);
1018 }
1019 else if (xmlStrEqual( pcaNode->name, BAD_CAST "PCAmeans" )) {
1020 std::vector<double> PCA_means_row;
1021 for (int i = 0; i <= 4; ++i) {
1022 std::string propName = "mean_" + std::to_string(i); // Dynamically create property name
1023 if ((xmlBuff = xmlGetProp(pcaNode, BAD_CAST propName.c_str())) != nullptr) {
1024 PCA_means_row.push_back(atof(reinterpret_cast<const char*>(xmlBuff))); // Convert and push to the row
1025 }
1026 }
1027 m_PCA_means.push_back(PCA_means_row);
1028 }
1029
1030 }
1031
1032 }
1033 }
1034
1035 }
1036 }
1037 }
1038 m_inverse_PCA_matrix.push_back(PCA_matrix);
1039 }
1040
1041 // free memory when done
1042 xmlFreeDoc(doc);
1043
1044 return StatusCode::SUCCESS;
1045}
std::vector< std::vector< std::vector< double > > > m_inverse_PCA_matrix
pca vectors
std::vector< std::vector< double > > m_PCA_means

◆ initializePhysics()

StatusCode PunchThroughG4Tool::initializePhysics ( )
override

Definition at line 105 of file PunchThroughG4Tool.cxx.

105 {
106 // resolving lookuptable file
107
108 ATH_MSG_INFO("[PunchThroughG4Tool] PunchThroughG4Tool::initializePhysics() called");
109 std::string resolvedFileName = PathResolverFindCalibFile (m_filenameLookupTable);
110 if (resolvedFileName.empty()) {
111 ATH_MSG_ERROR( "[PunchThroughG4Tool] Parametrisation file '" << m_filenameLookupTable << "' not found" );
112 return StatusCode::FAILURE;
113 }
114 ATH_MSG_DEBUG( "[PunchThroughG4Tool] Parametrisation file found: " << resolvedFileName );
115 // open the LookupTable file
116 m_fileLookupTable = new TFile( resolvedFileName.c_str(), "READ");
117 if (!m_fileLookupTable) {
118 ATH_MSG_WARNING("[PunchThroughG4Tool] unable to open the lookup-table for the punch-through simulation (file does not exist)");
119 return StatusCode::FAILURE;
120 }
121
122 if (!m_fileLookupTable->IsOpen()) {
123 ATH_MSG_WARNING("[PunchThroughG4Tool] unable to open the lookup-table for the punch-through simulation (wrong or empty file?)");
124 return StatusCode::FAILURE;
125 }
126
127 //--------------------------------------------------------------------------------
128 // register all the punch-through particles which will be simulated
130
131 //--------------------------------------------------------------------------------
132 // register all the punch-through correlations between particles to be simulated
134
135 //--------------------------------------------------------------------------------
136 // close the file with the lookuptable
137 m_fileLookupTable->Close();
138
139 // Geometry identifier service
140 if ( !m_geoIDSvc.empty() && m_geoIDSvc.retrieve().isFailure())
141 {
142 ATH_MSG_FATAL ( "[PunchThroughG4Tool] Could not retrieve GeometryIdentifier Service. Abort");
143 return StatusCode::FAILURE;
144 }
145
146 //envelope definition service
147 if (m_envDefSvc.retrieve().isFailure() )
148 {
149 ATH_MSG_ERROR( "[PunchThroughG4Tool] Could not retrieve " << m_envDefSvc );
150 return StatusCode::FAILURE;
151 }
152
153 // direct-initialization of the Muon and Calo boundaries (giving R, Z coordinates)
154 // can also do like below (RZPairVector is vector<pair<double, double>>)
155 // const RZPairVector* rzMS = &(m_envDefSvc->getMuonRZBoundary());
156 const std::vector<std::pair<double, double>>* rzMS = &(m_envDefSvc->getMuonRZBoundary());
157 const std::vector<std::pair<double, double>>* rzCalo = &(m_envDefSvc->getCaloRZBoundary());
158 ATH_CHECK(checkCaloMSBoundaries(rzMS, rzCalo));
159 return StatusCode::SUCCESS;
160}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
ServiceHandle< IEnvelopeDefSvc > m_envDefSvc
TFile * m_fileLookupTable
ROOT objects.
StatusCode initializeRegisterCorrelations()
initialize register all correlations between particles
StatusCode checkCaloMSBoundaries(const std::vector< std::pair< double, double > > *rzMS, const std::vector< std::pair< double, double > > *rzCalo)
Check calo-MS boundaries.
StatusCode initializeRegisterPunchThroughParticles()
initialize register all the punch-through particles which will be simulated
StringProperty m_filenameLookupTable

◆ initializeRegisterCorrelations()

StatusCode PunchThroughG4Tool::initializeRegisterCorrelations ( )
private

initialize register all correlations between particles

Definition at line 162 of file PunchThroughG4Tool.cxx.

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

◆ initializeRegisterPunchThroughParticles()

StatusCode PunchThroughG4Tool::initializeRegisterPunchThroughParticles ( )
private

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

Definition at line 73 of file PunchThroughG4Tool.cxx.

73 {
74 G4ParticleTable *ptable = G4ParticleTable::GetParticleTable();
75 for ( unsigned int num = 0; num < m_punchThroughParticles.size(); num++ )
76 {
77 const int pdg = m_punchThroughParticles[num];
78 // if no information is given on the creation of anti-particles -> do not simulate anti-particles
79 const bool doAnti = ( num < m_doAntiParticles.size() ) ? m_doAntiParticles[num] : false;
80 // if no information is given on the minimum energy -> take 50. MeV as default
81 const double minEnergy = ( num < m_minEnergy.size() ) ? m_minEnergy[num] : 50.;
82 // if no information is given on the maximum number of punch-through particles -> take -1 as default
83 const int maxNum = ( num < m_minEnergy.size() ) ? m_maxNumParticles[num] : -1;
84 // if no information is given on the scale factor for the number of particles -> take 1. as defaulft
85 const double numFactor = ( num < m_numParticlesFactor.size() ) ? m_numParticlesFactor[num] : 1.;
86 // if no information is given on the position angle factor -> take 1.
87 const double posAngleFactor = ( num < m_posAngleFactor.size() ) ? m_posAngleFactor[num] : 1.;
88 // if no information is given on the momentum angle factor -> take 1.
89 const double momAngleFactor = ( num < m_momAngleFactor.size() ) ? m_momAngleFactor[num] : 1.;
90 // if no information is given on the scale factor for the energy -> take 1. as default
91 const double energyFactor = ( num < m_energyFactor.size() ) ? m_energyFactor[num] : 1.;
92
93 // register the particle
94 ATH_MSG_VERBOSE("VERBOSE: [PunchThroughG4Tool] registering punch-through particle type with pdg = " << pdg );
95 if (registerPunchThroughParticle( *ptable, pdg, doAnti, minEnergy, maxNum, numFactor, energyFactor, posAngleFactor, momAngleFactor ) != StatusCode::SUCCESS)
96 {
97 ATH_MSG_ERROR("[PunchThroughG4Tool] unable to register punch-through particle type with pdg = " << pdg);
98 return StatusCode::FAILURE;
99 }
100 }
101 // if all goes well
102 return StatusCode::SUCCESS;
103}
#define ATH_MSG_VERBOSE(x)
DoubleArrayProperty m_numParticlesFactor
DoubleArrayProperty m_posAngleFactor
DoubleArrayProperty m_minEnergy
IntegerArrayProperty m_maxNumParticles
BooleanArrayProperty m_doAntiParticles
DoubleArrayProperty m_energyFactor
DoubleArrayProperty m_momAngleFactor
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

◆ interpolateEnergy()

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

Definition at line 1148 of file PunchThroughG4Tool.cxx.

1148 {
1149
1150 ATH_MSG_DEBUG("[PunchThroughG4Tool] interpolating incoming energy: " << energy);
1151
1152 std::string energyPointsString;
1153 for (auto element:m_energyPoints){
1154 energyPointsString += std::to_string(element) + " ";
1155 }
1156
1157 ATH_MSG_DEBUG("[PunchThroughG4Tool] available energy points: " << energyPointsString);
1158
1159 auto const upperEnergy = std::upper_bound(m_energyPoints.begin(), m_energyPoints.end(), energy);
1160
1161 if(upperEnergy == m_etaPoints.end()){ //if no energy greater than input energy, choose greatest energy
1162 ATH_MSG_DEBUG("[PunchThroughG4Tool] incoming energy > largest energy point, returning greatest energy point: " << m_energyPoints.back());
1163 return m_energyPoints.back();
1164 }
1165 else if(upperEnergy == m_etaPoints.begin()){ //if smallest energy greater than input energy, choose smallest energy
1166 ATH_MSG_DEBUG("[PunchThroughG4Tool] incoming energy < smallest energy point, returning smallest energy point: " << *upperEnergy);
1167 return *upperEnergy;
1168 }
1169
1170 ATH_MSG_DEBUG("[PunchThroughG4Tool] energy points upper_bound: "<< *upperEnergy);
1171
1172 double randomShoot = CLHEP::RandFlat::shoot(rndmEngine);
1173
1174 ATH_MSG_DEBUG("[PunchThroughG4Tool] Shooting random number: "<< randomShoot);
1175
1176 double midPoint = *std::prev(upperEnergy)*M_SQRT2;
1177
1178 if(energy < midPoint){ //if energy smaller than mid point in log(energy)
1179
1180 double distance = std::abs(energy - *std::prev(upperEnergy))/((midPoint) - *std::prev(upperEnergy));
1181
1182 ATH_MSG_DEBUG( "[PunchThroughG4Tool] incoming energy is closest to prev(upper_bound) in log(energy), distance: " << distance );
1183
1184 if(randomShoot < distance){
1185 ATH_MSG_DEBUG( "[PunchThroughG4Tool] randomShoot < distance, returning upper_bound " << *upperEnergy );
1186 return *upperEnergy;
1187 }
1188 ATH_MSG_DEBUG( "[PunchThroughG4Tool] randomShoot > distance, returning prev(upper_bound) " << *std::prev(upperEnergy) );
1189
1190 return *std::prev(upperEnergy);
1191 }
1192 else if(energy > midPoint){ //if energy greater than mid point in log(energy)
1193
1194 double distance = std::abs(energy - *upperEnergy)/((*upperEnergy - midPoint));
1195
1196 ATH_MSG_DEBUG( "[PunchThroughG4Tool] incoming energy is closest to upper_bound in log(energy), distance: " << distance );
1197
1198 if(randomShoot < distance){
1199 ATH_MSG_DEBUG( "[PunchThroughG4Tool] randomShoot < distance, returning prev(upper_bound) " << *std::prev(upperEnergy) );
1200 return *std::prev(upperEnergy);
1201 }
1202 ATH_MSG_DEBUG( "[PunchThroughG4Tool] randomShoot > distance, returning upper_bound " << *upperEnergy );
1203 return *upperEnergy;
1204 }
1205
1206 return *upperEnergy;
1207}
std::vector< double > m_energyPoints
energy and eta points in param
std::vector< double > m_etaPoints
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space

◆ interpolateEta()

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

Definition at line 1209 of file PunchThroughG4Tool.cxx.

1209 {
1210
1211 double absEta = std::abs(eta);
1212
1213 ATH_MSG_DEBUG("[PunchThroughG4Tool] interpolating incoming abs(eta): " << absEta);
1214
1215 std::string etaPointsString;
1216 for (auto element:m_etaPoints){
1217 etaPointsString += std::to_string(element) + " ";
1218 }
1219
1220 ATH_MSG_DEBUG("[PunchThroughG4Tool] available eta points: " << etaPointsString);
1221
1222 auto const upperEta = std::upper_bound(m_etaPoints.begin(), m_etaPoints.end(), absEta);
1223
1224 if(upperEta == m_etaPoints.end()){
1225 ATH_MSG_DEBUG("[PunchThroughG4Tool] incoming abs(eta) > largest eta point, returning greatest eta point: " << m_etaPoints.back());
1226 return m_etaPoints.back();
1227 }
1228
1229
1230 ATH_MSG_DEBUG("[PunchThroughG4Tool] eta points upper_bound: "<< *upperEta);
1231
1232 double randomShoot = CLHEP::RandFlat::shoot(rndmEngine);
1233
1234 ATH_MSG_DEBUG("[PunchThroughG4Tool] Shooting random number: "<< randomShoot);
1235
1236 if(std::abs(absEta - *upperEta) < std::abs(absEta - *std::prev(upperEta))){
1237
1238 double distance = std::abs(absEta - *upperEta)/((*upperEta - *std::prev(upperEta))/2);
1239
1240 ATH_MSG_DEBUG( "[PunchThroughG4Tool] abs(eta) is closer to eta points upper_bound, distance: " << distance );
1241
1242 if(randomShoot > distance){
1243 ATH_MSG_DEBUG( "[PunchThroughG4Tool] randomShoot > distance, returning upper_bound " << *upperEta );
1244 return *upperEta;
1245 }
1246
1247 ATH_MSG_DEBUG( "[PunchThroughG4Tool] randomShoot < distance, returning prev(upper_bound) " << *std::prev(upperEta) );
1248
1249 return *std::prev(upperEta);
1250 }
1251 else if(std::abs(absEta - *std::prev(upperEta)) < std::abs(absEta - *upperEta)){
1252
1253 if(std::prev(upperEta) == m_etaPoints.begin()){
1254 ATH_MSG_DEBUG( "[PunchThroughG4Tool] prev of upper bound is begin, returning that: " << *std::prev(upperEta) );
1255 return *std::prev(upperEta);
1256 }
1257
1258 double distance = std::abs(absEta - *std::prev(upperEta))/((*std::prev(upperEta) - *std::prev(std::prev(upperEta)))/2);
1259
1260 ATH_MSG_DEBUG( "[PunchThroughG4Tool] abs(eta) is closer to eta points prev(upper_bound), distance: " << distance );
1261
1262 if(randomShoot > distance){
1263 ATH_MSG_DEBUG( "[PunchThroughG4Tool] randomShoot > distance, returning prev(prev(upper_bound)) " << *std::prev(std::prev(upperEta)) );
1264
1265 return *std::prev(std::prev(upperEta));
1266 }
1267 ATH_MSG_DEBUG( "[PunchThroughG4Tool] randomShoot < distance, returning prev(upper_bound) " << *std::prev(upperEta) );
1268
1269 return *std::prev(upperEta);
1270 }
1271
1272 return *std::prev(upperEta);
1273}
Scalar eta() const
pseudorapidity method
bool absEta(const xAOD::TauJet &tau, float &out)

◆ inverseCdfTransform()

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

Definition at line 1133 of file PunchThroughG4Tool.cxx.

1133 {
1134
1135 double norm_cdf = normal_cdf(variable);
1136
1137 auto upper = inverse_cdf_map.upper_bound(norm_cdf);
1138 auto lower = upper--;
1139
1140 double m = (upper->second - lower->second)/(upper->first - lower->first);
1141 double c = lower->second - m * lower->first;
1142 double transformed = m * norm_cdf + c;
1143
1144 return transformed;
1145
1146}
int upper(int c)
static double normal_cdf(double x)

◆ inversePCA()

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

Definition at line 975 of file PunchThroughG4Tool.cxx.

976{
977 std::vector<double> transformed_variables = dotProduct(m_inverse_PCA_matrix[pcaCdfIterator], variables);
978
979 std::transform (transformed_variables.begin(), transformed_variables.end(), m_PCA_means[pcaCdfIterator].begin(), transformed_variables.begin(), std::plus<double>()); // + means
980
981 return transformed_variables;
982}
static std::vector< double > dotProduct(const std::vector< std::vector< double > > &m, const std::vector< double > &v)

◆ normal_cdf()

double PunchThroughG4Tool::normal_cdf ( double x)
staticprivate

Definition at line 861 of file PunchThroughG4Tool.cxx.

861 {
862 return 0.5 * TMath::Erfc(-x * M_SQRT1_2);
863}
#define x

◆ passedParamIterator()

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

Definition at line 900 of file PunchThroughG4Tool.cxx.

901{
902 //convert the pid to absolute value and string for query
903 int pidStrSingle = std::abs(pid);
904 //STEP 1
905 //filter items matching pid first
906
907 for (unsigned int i = 0; i < mapvect.size(); i++){
908 const std::string &pidStr = mapvect[i].at("pidStr");
909 auto v = str_to_list<int>(pidStr);
910 if(std::find(v.begin(), v.end(),pidStrSingle)==v.end()) continue;
911 const std::string &etaMinsStr = mapvect[i].at("etaMins");
912 const std::string &etaMaxsStr = mapvect[i].at("etaMaxs");
913 std::vector<double> etaMinsVect = str_to_list<double>(etaMinsStr);
914 std::vector<double> etaMaxsVect = str_to_list<double>(etaMaxsStr);
915 assert(etaMaxsVect.size() == etaMinsVect.size());
916 for (unsigned int j = 0; j < etaMinsVect.size(); j++){ // assume size etaMinsVect == etaMaxsVect
917 double etaMinToCompare = etaMinsVect[j];
918 double etaMaxToCompare = etaMaxsVect[j];
919 if((eta >= etaMinToCompare) && (eta < etaMaxToCompare)){
920 //PASS CONDITION
921 //then choose the passing one and note it's iterator
922 return (i); //in case more than 1 match (ambiguous case)
923 }
924 }
925 }
926 return 0;
927}
std::vector< T > str_to_list(const std::string_view str)

◆ 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 1483 of file PunchThroughG4Tool.cxx.

1484{
1485 // phi, theta - direction of the punch-through particle coming into calo
1486 // particle propagates inside the calorimeter along the straight line
1487 // coordinates of this particles when exiting the calo (on calo-MS boundary)
1488
1489 double x, y, z, r;
1490
1491 // cylinders border angles
1492 const double theta1 = atan (R1 / z1);
1493 const double theta2 = atan (R1 / z2);
1494 const double theta3 = atan (R2 / z2);
1495 //where is the particle
1496
1497 if (theta >= 0 && theta < theta1)
1498 {
1499 z = z1;
1500 r = std::fabs (z1 * tan(theta));
1501 }
1502 else if (theta >= theta1 && theta < theta2)
1503 {
1504 z = R1 / tan(theta);
1505 r = R1;
1506 }
1507 else if (theta >= theta2 && theta < theta3)
1508 {
1509 z = z2;
1510 r = std::fabs(z2 * tan(theta));;
1511 }
1512 else if (theta >= theta3 && theta < (TMath::Pi() - theta3) )
1513 {
1514 z = R2 / tan(theta);
1515 r = R2;
1516 }
1517 else if (theta >= (TMath::Pi() - theta3) && theta < (TMath::Pi() - theta2) )
1518 {
1519 z = -z2;
1520 r = std::fabs(z2 * tan(theta));
1521 }
1522 else if (theta >= (TMath::Pi() - theta2) && theta < (TMath::Pi() - theta1) )
1523 {
1524 z = R1 / tan(theta);
1525 r = R1;
1526 }
1527 else if (theta >= (TMath::Pi() - theta1) && theta <= TMath::Pi() )
1528 {
1529 z = -z1;
1530 r = std::fabs(z1 * tan(theta));
1531 }
1532
1533 //parallel universe
1534 else
1535 {
1536 ATH_MSG_WARNING("[PunchThroughG4Tool::punchTroughPosPropagator] Given theta angle is incorrect, setting particle position to (0, 0, 0)");
1537 x = 0.0; y = 0.0; z = 0.0; r = 0.0;
1538 }
1539
1540 x = r * cos(phi);
1541 y = r * sin(phi);
1542 G4ThreeVector posVec(x, y, z);
1543
1544 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));
1545
1546 return posVec;
1547}
#define y
#define z

◆ 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 1397 of file PunchThroughG4Tool.cxx.

1398{
1399
1400 // will hold the PDFcreator class which will be returned at the end
1401 // this will store the distributions for the punch through particles
1402 // (as map of energy & eta of the incoming particle)
1403 //PunchThroughPDFCreator *pdf = new PunchThroughPDFCreator();
1404 std::unique_ptr<PunchThroughPDFCreator> pdf = std::make_unique<PunchThroughPDFCreator>();
1405
1406 //Get directory object
1407 std::stringstream dirName;
1408 dirName << folderName << pdg;
1409 pdf->setName(dirName.str());
1410
1411 TDirectory * dir = (TDirectory*)fileLookupTable->Get(dirName.str().c_str());
1412 if(! dir)
1413 {
1414 ATH_MSG_ERROR( "[PunchThroughG4Tool] unable to retrieve directory object ("<< folderName << pdg << ")" );
1415 return nullptr;
1416 }
1417
1418 //Get list of all objects in directory
1419 TIter keyList(dir->GetListOfKeys());
1420 TKey *key;
1421
1422 while ((key = (TKey*)keyList())) {
1423
1424 //Get histogram object from key and its name
1425 TH1* hist = nullptr;
1426
1427 std::string histName;
1428 if(strcmp(key->GetClassName(), "TH1F") == 0){
1429 hist = (TH1*)key->ReadObj();
1430 histName = hist->GetName();
1431 }
1432
1433 //extract energy and eta from hist name 6 and 1 to position delimeters correctly
1434 std::string strEnergy = histName.substr( histName.find_first_of('E') + 1, histName.find_first_of('_')-histName.find_first_of('E') - 1 );
1435 histName.erase(0, histName.find_first_of('_') + 1);
1436 std::string strEtaMin = histName.substr( histName.find("etaMin") + 6, histName.find_first_of('_') - histName.find("etaMin") - 6 );
1437 histName.erase(0, histName.find('_') + 1);
1438 std::string strEtaMax = histName.substr( histName.find("etaMax") + 6, histName.length());
1439
1440 //create integers to store in map
1441 const int energy = std::stoi(strEnergy);
1442 const int etaMin = std::stoi(strEtaMin);
1443
1444 //Add entry to pdf map
1445 pdf->addToEnergyEtaHist1DMap(energy, etaMin, hist);
1446
1447 //create doubles to store energy and eta points for interpolation
1448 const double energyDbl = static_cast<double>(energy);
1449 const double etaDbl = static_cast<double>(etaMin)/100.;
1450
1451 //create vectors to store the eta and energy points, this allows us to interpolate
1452 if (std::find(m_energyPoints.begin(), m_energyPoints.end(), energyDbl) == m_energyPoints.end()) {
1453 m_energyPoints.push_back(energyDbl);
1454 }
1455 if (std::find(m_etaPoints.begin(), m_etaPoints.end(), etaDbl) == m_etaPoints.end()) {
1456 m_etaPoints.push_back(etaDbl);
1457 }
1458
1459 }
1460
1461 return pdf;
1462}

◆ 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 1349 of file PunchThroughG4Tool.cxx.

1351{
1352 // find the given pdgs in the registered particle ids
1353 std::map<int, PunchThroughParticle*>::iterator location1 = m_particles.find(pdgID1);
1354 std::map<int, PunchThroughParticle*>::iterator location2 = m_particles.find(pdgID2);
1355
1356 // if at least one of the given pdgs was not registered yet -> return an error
1357 if ( (location1 == m_particles.end()) || (location2 == m_particles.end()) )
1358 return StatusCode::FAILURE;
1359
1360 // now look for the correlation histograms
1361 std::stringstream name;
1362 name << "NumExitCorrelations/x_PDG" << std::abs(pdgID1) << "__y_PDG" << std::abs(pdgID2) << "__lowE";
1363 TH2F *hist1_2_lowE = (TH2F*)m_fileLookupTable->Get(name.str().c_str());
1364 name.str("");
1365 name << "NumExitCorrelations/x_PDG" << std::abs(pdgID1) << "__y_PDG" << std::abs(pdgID2) << "__highE";
1366 TH2F *hist1_2_highE = (TH2F*)m_fileLookupTable->Get(name.str().c_str());
1367 name.str("");
1368 name << "NumExitCorrelations/x_PDG" << std::abs(pdgID2) << "__y_PDG" << std::abs(pdgID1) << "__lowE";
1369 TH2F *hist2_1_lowE = (TH2F*)m_fileLookupTable->Get(name.str().c_str());
1370 name.str("");
1371 name << "NumExitCorrelations/x_PDG" << std::abs(pdgID2) << "__y_PDG" << std::abs(pdgID1) << "__highE";
1372 TH2F *hist2_1_highE = (TH2F*)m_fileLookupTable->Get(name.str().c_str());
1373 // check if the histograms exist
1374 if ( (!hist1_2_lowE) || (!hist2_1_lowE) || (!hist1_2_highE) || (!hist2_1_highE) )
1375 {
1376 ATH_MSG_ERROR("[PunchThroughG4Tool] unable to retrieve the correlation data for PDG IDs " << pdgID1 << " and " << pdgID2);
1377 return StatusCode::FAILURE;
1378 }
1379
1380 // TODO: if only one of the two histograms exists, create the other one
1381 // by mirroring the data
1382 const double lowE = getFloatAfterPatternInStr( hist1_2_lowE->GetTitle(), "elow_");
1383 const double midE = getFloatAfterPatternInStr( hist1_2_lowE->GetTitle(), "ehigh_");
1384 //TODO: check if the same:
1385 // double midE = getFloatAfterPatternInStr( hist1_2_lowE->GetTitle(), "elow_");
1386 const double upperE = getFloatAfterPatternInStr( hist1_2_highE->GetTitle(), "ehigh_");
1387 // now store the correlation either way id1->id2 and id2->id1
1388 m_particles[pdgID1]->setCorrelation(pdgID2, hist2_1_lowE, hist2_1_highE,
1389 minCorrEnergy, fullCorrEnergy,
1390 lowE, midE, upperE);
1391 m_particles[pdgID2]->setCorrelation(pdgID1, hist1_2_lowE, hist1_2_highE,
1392 minCorrEnergy, fullCorrEnergy,
1393 lowE, midE, upperE);
1394 return StatusCode::SUCCESS;
1395}
double getFloatAfterPatternInStr(const char *str, const char *pattern)
get the floating point number in a string, after the given pattern

◆ 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 1276 of file PunchThroughG4Tool.cxx.

1279{
1280 G4ParticleDefinition* secG4Particle = ptable.FindParticle(std::abs(pdg));
1281 double restMass = secG4Particle->GetPDGMass();
1282
1283 // read in the data needed to construct the distributions for the number of punch-through particles
1284 // (1.) get the distribution function for the number of punch-through particles
1285 std::unique_ptr<PunchThroughPDFCreator> pdf_num(readLookuptablePDF(pdg, m_fileLookupTable, "FREQ_PDG"));
1286 if (!pdf_num ) return StatusCode::FAILURE; // return error if something went wrong
1287
1288 // (2.) get the PDF for the punch-through energy
1289 std::unique_ptr<PunchThroughPDFCreator> pdf_pca0 (readLookuptablePDF(pdg, m_fileLookupTable, "PCA0_PDG"));
1290 if (!pdf_pca0)
1291 {
1292 return StatusCode::FAILURE; // return error if something went wrong
1293 }
1294
1295 // (3.) get the PDF for the punch-through particles difference in
1296 // theta compared to the incoming particle
1297 std::unique_ptr<PunchThroughPDFCreator> pdf_pca1 (readLookuptablePDF(pdg, m_fileLookupTable, "PCA1_PDG"));
1298 if (!pdf_pca1)
1299 {
1300 return StatusCode::FAILURE;
1301 }
1302
1303 // (4.) get the PDF for the punch-through particles difference in
1304 // phi compared to the incoming particle
1305 std::unique_ptr<PunchThroughPDFCreator> pdf_pca2 (readLookuptablePDF(pdg, m_fileLookupTable, "PCA2_PDG"));
1306 if (!pdf_pca2)
1307 {
1308 return StatusCode::FAILURE;
1309 }
1310
1311 // (5.) get the PDF for the punch-through particle momentum delta theta angle
1312 std::unique_ptr<PunchThroughPDFCreator> pdf_pca3 (readLookuptablePDF(pdg, m_fileLookupTable, "PCA3_PDG"));
1313 if (!pdf_pca3)
1314 {
1315 return StatusCode::FAILURE;
1316 }
1317
1318 // (6.) get the PDF for the punch-through particle momentum delta phi angle
1319 std::unique_ptr<PunchThroughPDFCreator> pdf_pca4 (readLookuptablePDF(pdg, m_fileLookupTable, "PCA4_PDG"));
1320 if (!pdf_pca4)
1321 {
1322 return StatusCode::FAILURE;
1323 }
1324
1325 // (7.) now finally store all this in the right std::map
1326 PunchThroughParticle *particle = new PunchThroughParticle(pdg, doAntiparticle);
1327 particle->setNumParticlesPDF(std::move(pdf_num));
1328 particle->setPCA0PDF(std::move(pdf_pca0));
1329 particle->setPCA1PDF(std::move(pdf_pca1));
1330 particle->setPCA2PDF(std::move(pdf_pca2));
1331 particle->setPCA3PDF(std::move(pdf_pca3));
1332 particle->setPCA4PDF(std::move(pdf_pca4));
1333
1334 // (8.) set some additional particle and simulation properties
1335 minEnergy = ( minEnergy > restMass ) ? minEnergy : restMass;
1336 particle->setMinEnergy(minEnergy);
1337 particle->setMaxNumParticles(maxNumParticles);
1338 particle->setNumParticlesFactor(numParticlesFactor);
1339 particle->setEnergyFactor(energyFactor);
1340 particle->setPosAngleFactor(posAngleFactor);
1341 particle->setMomAngleFactor(momAngleFactor);
1342
1343 // (9.) insert this PunchThroughParticle instance into the std::map class member
1344 m_particles[pdg] = particle;
1345
1346 return StatusCode::SUCCESS;
1347}
std::unique_ptr< PunchThroughPDFCreator > readLookuptablePDF(int pdgID, TFile *fileLookupTable, const std::string &folderName)
reads out the lookuptable for the given type of particle
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses

Member Data Documentation

◆ m_beamPipe

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

beam pipe radius

Definition at line 220 of file PunchThroughG4Tool.h.

220{this, "BeamPipeRadius", 500.};

◆ m_correlatedParticle

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

Definition at line 203 of file PunchThroughG4Tool.h.

203{this, "CorrelatedParticle", {}, "holds the pdg of the correlated particle for each given pdg"};

◆ 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 202 of file PunchThroughG4Tool.h.

202{this, "DoAntiParticles", {}, "vector of bools to determine if anti-particles are created for each punch-through particle type"};

◆ m_energyFactor

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

Definition at line 211 of file PunchThroughG4Tool.h.

211{this, "EnergyFactor", {}, "scale the energy of the punch-through particles"};

◆ m_energyPoints

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

energy and eta points in param

Definition at line 176 of file PunchThroughG4Tool.h.

◆ m_envDefSvc

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

Definition at line 217 of file PunchThroughG4Tool.h.

217{this, "EnvelopeDefSvc", "AtlasGeometry_EnvelopeDefSvc"};

◆ m_etaPoints

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

Definition at line 177 of file PunchThroughG4Tool.h.

◆ m_fileLookupTable

TFile* PunchThroughG4Tool::m_fileLookupTable {nullptr}
private

ROOT objects.

the punch-through lookup table file

Definition at line 186 of file PunchThroughG4Tool.h.

186{nullptr};

◆ m_filenameInverseCDF

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

Definition at line 195 of file PunchThroughG4Tool.h.

195{this, "FilenameInverseCdf", "", "holds the filename of inverse quantile transformer config"};

◆ m_filenameInversePCA

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

Definition at line 196 of file PunchThroughG4Tool.h.

196{this, "FilenameInversePca", "", "holds the filename of inverse PCA config"};

◆ m_filenameLookupTable

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

Definition at line 194 of file PunchThroughG4Tool.h.

194{this, "FilenameLookupTable", "CaloPunchThroughParametrisation.root", "holds the filename of the lookup table"};

◆ m_fullCorrEnergy

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

Definition at line 205 of file PunchThroughG4Tool.h.

205{this, "FullCorrelationEnergy", {}, "holds the energy threshold above which a particle correlation is fully developed"};

◆ m_geoIDSvc

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

Definition at line 216 of file PunchThroughG4Tool.h.

216{this, "GeoIDSvc", "ISF::GeoIDSvc"};

◆ 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 200 of file PunchThroughG4Tool.h.

200{this, "InitiatorsEtaRange", {}, "vector of min and max abs eta range to allow punch through initiators"};

◆ m_initiatorsMinEnergy

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

Definition at line 199 of file PunchThroughG4Tool.h.

199{this, "InitiatorsMinEnergy", {}, "vector of punch-through initiator min energies to create punch through"};

◆ m_inverse_PCA_matrix

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

pca vectors

Definition at line 223 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 209 of file PunchThroughG4Tool.h.

209{this, "MaxNumParticles", {}, "maximum number of punch-through particles for each particle type"};

◆ m_minCorrEnergy

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

Definition at line 204 of file PunchThroughG4Tool.h.

204{this, "MinCorrelationEnergy", {}, "holds the energy threshold below which no particle correlation is computed"};

◆ m_minEnergy

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

Definition at line 208 of file PunchThroughG4Tool.h.

208{this, "MinEnergy", {}, "punch-through particles minimum energies"};

◆ m_momAngleFactor

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

Definition at line 207 of file PunchThroughG4Tool.h.

207{this, "ScaleMomDeflectionAngles", {}, "tuning parameter to scale the momentum deflection angles"};

◆ m_numParticlesFactor

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

Definition at line 210 of file PunchThroughG4Tool.h.

210{this, "NumParticlesFactor", {}, "scale the number of punch-through particles"};

◆ 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 189 of file PunchThroughG4Tool.h.

◆ m_PCA_means

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

Definition at line 224 of file PunchThroughG4Tool.h.

◆ m_pdgInitiators

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

Definition at line 198 of file PunchThroughG4Tool.h.

198{this, "PunchThroughInitiators", {}, "vector of punch-through initiator pgds"};

◆ m_posAngleFactor

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

Definition at line 206 of file PunchThroughG4Tool.h.

206{this, "ScalePosDeflectionAngles", {}, "tuning parameter to scale the position deflection angles"};

◆ m_punchThroughParticles

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

Definition at line 201 of file PunchThroughG4Tool.h.

201{this, "PunchThroughParticles", {}, "vector of pdgs of the particles produced in punch-throughs"};

◆ m_R1

double PunchThroughG4Tool::m_R1 {0.}
private

calo-MS borders

Definition at line 180 of file PunchThroughG4Tool.h.

180{0.};

◆ m_R2

double PunchThroughG4Tool::m_R2 {0.}
private

Definition at line 181 of file PunchThroughG4Tool.h.

181{0.};

◆ 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 231 of file PunchThroughG4Tool.h.

◆ m_variable1_inverse_cdf

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

Definition at line 232 of file PunchThroughG4Tool.h.

◆ m_variable2_inverse_cdf

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

Definition at line 233 of file PunchThroughG4Tool.h.

◆ m_variable3_inverse_cdf

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

Definition at line 234 of file PunchThroughG4Tool.h.

◆ m_variable4_inverse_cdf

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

Definition at line 235 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 228 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 227 of file PunchThroughG4Tool.h.

◆ m_z1

double PunchThroughG4Tool::m_z1 {0.}
private

Definition at line 182 of file PunchThroughG4Tool.h.

182{0.};

◆ m_z2

double PunchThroughG4Tool::m_z2 {0.}
private

Definition at line 183 of file PunchThroughG4Tool.h.

183{0.};

The documentation for this class was generated from the following files: