ATLAS Offline Software
ZDC_G4CalibSD.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "ZDC_G4CalibSD.h"
10 #include "G4RunManager.hh"
11 #include "G4Step.hh"
13 
14 ZDC_G4CalibSD::ZDC_G4CalibSD(const G4String &a_name, const G4String& hitCollectionName, bool doPID)
15  : G4VSensitiveDetector(a_name), m_HitColl(hitCollectionName), m_numberInvalidHits(0), m_doPID(doPID)
16 {
18 }
19 
21 {
22  if (verboseLevel > 5 && m_numberInvalidHits > 0)
23  {
24  G4cout << "Destructor: Sensitive Detector <" << SensitiveDetectorName << "> had " << m_numberInvalidHits
25  << " G4Step energy deposits outside the region determined by its Calculator." << G4endl;
26  }
27  delete m_simulationEnergies;
28 }
29 
30 G4bool ZDC_G4CalibSD::ProcessHits(G4Step *a_step, G4TouchableHistory *)
31 {
32  // If there's no energy, there's no hit. (Aside: Isn't this energy
33  // the same as the energy from the calculator? Not necessarily.
34  // The calculator may include detector effects such as
35  // charge-collection which are not modeled by Geant4.)
36  if (a_step->GetTotalEnergyDeposit() == 0.)
37  return false;
38 
39  // Convert the G4Step into (eta,phi,sampling).
40  // Check that hit was valid. (It might be invalid if, for example,
41  // it occurred outside the sensitive region. If such a thing
42  // happens, it means that the geometry definitions in the
43  // detector-construction routine and the calculator do not agree.)
44 
45  m_energies.clear();
46  // classify different types of deposits (0: EM, 1: Non-EM, 2: Invisible, 3: Escaped)
47 
49 
50  // identifier needed to specify particular volme we're in. Used in HitCollection to make sure we don't have double hits
51  Identifier id;
52  id = a_step->GetPreStepPoint()->GetPhysicalVolume()->GetCopyNo();
53 
54  // build calibHit. check if we've had a hit in this cell already. if we havent add it to the set of cells. If we have add energies to existing energies. ie can't distinguish b/w different hits in single cell so must integrate all this information
55  return SimpleHit (id, m_energies );
56 }
57 
58 
59 G4bool ZDC_G4CalibSD::SimpleHit(const Identifier& id, const std::vector<double>& energies )
60 {
61 
62  // retreive particle ID
63  int particleID = HepMC::UNDEFINED_ID;
64  int particleUID = HepMC::UNDEFINED_ID;
65  if( m_doPID ) {
66  AtlasG4EventUserInfo * atlasG4EvtUserInfo = dynamic_cast<AtlasG4EventUserInfo*>(G4RunManager::GetRunManager()->GetCurrentEvent()->GetUserInformation());
67  if (atlasG4EvtUserInfo) {
68  particleID = HepMC::barcode(atlasG4EvtUserInfo->GetCurrentPrimaryGenParticle()); // FIXME Barcode-based
69  particleUID = HepMC::uniqueID(atlasG4EvtUserInfo->GetCurrentPrimaryGenParticle());
70  }
71  }
72 
73 
74  // Reject cases where invisible energy calculation produced values
75  // of order 10e-12 instead of 0 due to rounding errors in that
76  // calculation, or general cases where the energy deposits are
77  // trivially small.
78  if (energies[0] + energies[1] + energies[3] < 0.001 * CLHEP::eV && std::abs(energies[2]) < 0.001 * CLHEP::eV)
79  {
80  return true;
81  }
82 
83  // Build the hit.
85  energies[0],
86  energies[1],
87  energies[2],
88  energies[3],
89  particleID,
90  particleUID);
91 
92  //Get the hash for this volume to keep track of hits
93  uint32_t hash = id.get_identifier32().get_compact();
94 
96 
97  if(it == m_hitMap.end()){
98  //This is a new hit, insert it
99  m_hitMap.insert(std::pair<uint32_t,CaloCalibrationHit*>(hash,hit));
100  }else{
101  //Add this hit to the existing one for this volume
102  it->second->Add(hit);
103  delete hit;
104  }
105 
106  return true;
107 }
108 
109 // Something special has happened (probably the detection of escaped
110 // energy in CaloG4Sim/SimulationEnergies). We have to bypass the
111 // regular sensitive-detector processing. Determine the identifier
112 // (and only the identifier) using the calculator, then built a hit
113 // with that identifier and the energies in the vector.
114 
115 G4bool ZDC_G4CalibSD::SpecialHit(G4Step *a_step,
116  const std::vector<G4double> &a_energies)
117 {
118  // If we can't get the identifier, something is wrong.
119  Identifier id;
120  id = a_step->GetPreStepPoint()->GetPhysicalVolume()->GetCopyNo();
121 
122  return SimpleHit(id, a_energies);
123 }
124 
126 {
127 
128  //Move the hits from the hit set to the hit container
129  if (!m_HitColl.isValid())
130  m_HitColl = std::make_unique<CaloCalibrationHitContainer>(m_HitColl.name());
131 
132  // Loop through the hits...
133  for (auto hit : m_hitMap)
134  {
135  m_HitColl->push_back(hit.second);
136  } // End of loop over hits
137 
138  // Clean up
139  m_hitMap.clear();
140 }
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
CaloG4::SimulationEnergies::Energies
void Energies(const G4Step *, std::vector< G4double > &) const
The simple method to call from a calibration calculator: Examine the G4Step and return the energies r...
AtlasG4EventUserInfo
This class is attached to G4Event objects as UserInformation. It holds a pointer to the HepMC::GenEve...
Definition: AtlasG4EventUserInfo.h:21
ZDC_G4CalibSD::SimpleHit
G4bool SimpleHit(const Identifier &id, const std::vector< double > &energies)
Definition: ZDC_G4CalibSD.cxx:59
CaloCalibrationHit.h
ZDC_G4CalibSD::~ZDC_G4CalibSD
virtual ~ZDC_G4CalibSD()
Definition: ZDC_G4CalibSD.cxx:20
ZDC_G4CalibSD::m_HitColl
SG::WriteHandle< CaloCalibrationHitContainer > m_HitColl
Definition: ZDC_G4CalibSD.h:53
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
ZDC_G4CalibSD::ZDC_G4CalibSD
ZDC_G4CalibSD(const G4String &a_name, const G4String &hitCollectionName, bool doPID=false)
Definition: ZDC_G4CalibSD.cxx:14
SG::VarHandleBase::name
const std::string & name() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleBase.cxx:75
CaloG4::SimulationEnergies
Definition: SimulationEnergies.h:47
EscapedEnergyRegistry.h
skel.it
it
Definition: skel.GENtoEVGEN.py:396
ZDC_G4CalibSD::m_numberInvalidHits
G4int m_numberInvalidHits
Definition: ZDC_G4CalibSD.h:58
ZDC_G4CalibSD::m_hitMap
std::map< uint32_t, CaloCalibrationHit * > m_hitMap
Definition: ZDC_G4CalibSD.h:54
CaloCalibrationHitContainer.h
AthenaHitsVector::push_back
void push_back(T *t)
Definition: AthenaHitsVector.h:153
ZDC_G4CalibSD::EndOfAthenaEvent
void EndOfAthenaEvent()
Definition: ZDC_G4CalibSD.cxx:125
HepMC::barcode
int barcode(const T *p)
Definition: Barcode.h:16
HepMC::uniqueID
int uniqueID(const T &p)
Definition: MagicNumbers.h:116
HepMC::UNDEFINED_ID
constexpr int UNDEFINED_ID
Definition: MagicNumbers.h:56
ZDC_G4CalibSD::m_simulationEnergies
CaloG4::SimulationEnergies * m_simulationEnergies
Definition: ZDC_G4CalibSD.h:62
ZDC_G4CalibSD::SpecialHit
G4bool SpecialHit(G4Step *a_step, const std::vector< G4double > &a_energies)
Definition: ZDC_G4CalibSD.cxx:115
CaloCalibrationHit
Class to store calorimeter calibration hit.
Definition: CaloCalibrationHit.h:23
ZDC_G4CalibSD::m_doPID
G4bool m_doPID
Definition: ZDC_G4CalibSD.h:60
SG::WriteHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
id
SG::auxid_t id
Definition: Control/AthContainers/Root/debug.cxx:227
python.SystemOfUnits.eV
int eV
Definition: SystemOfUnits.py:155
AtlasG4EventUserInfo::GetCurrentPrimaryGenParticle
HepMC::ConstGenParticlePtr GetCurrentPrimaryGenParticle() const
return a pointer to the HepMC::GenParticle used to create the current G4PrimaryParticle.
Definition: AtlasG4EventUserInfo.h:44
ZDC_G4CalibSD.h
AtlasG4EventUserInfo.h
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:109
ZDC_G4CalibSD::m_energies
std::vector< G4double > m_energies
Definition: ZDC_G4CalibSD.h:55
ZDC_G4CalibSD::ProcessHits
G4bool ProcessHits(G4Step *a_step, G4TouchableHistory *) override
Definition: ZDC_G4CalibSD.cxx:30
SimulationEnergies.h
Identifier
Definition: IdentifierFieldParser.cxx:14