ATLAS Offline Software
Loading...
Searching...
No Matches
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
14ZDC_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 }
28}
29
30G4bool 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
48 m_simulationEnergies->Energies(a_step, m_energies);
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
59G4bool 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
95 std::map<uint32_t,CaloCalibrationHit*>::iterator it = m_hitMap.find(hash);
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
115G4bool 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}
This class is attached to G4Event objects as UserInformation.
HepMC::ConstGenParticlePtr GetCurrentPrimaryGenParticle() const
return a pointer to the HepMC::GenParticle used to create the current G4PrimaryParticle.
Class to store calorimeter calibration hit.
This class implements the calculations requires to categorize the energies deposited during the simul...
CaloG4::SimulationEnergies * m_simulationEnergies
std::vector< G4double > m_energies
std::map< uint32_t, CaloCalibrationHit * > m_hitMap
G4bool SimpleHit(const Identifier &id, const std::vector< double > &energies)
G4int m_numberInvalidHits
G4bool SpecialHit(G4Step *a_step, const std::vector< G4double > &a_energies)
virtual ~ZDC_G4CalibSD()
ZDC_G4CalibSD(const G4String &a_name, const G4String &hitCollectionName, bool doPID=false)
G4bool ProcessHits(G4Step *a_step, G4TouchableHistory *) override
SG::WriteHandle< CaloCalibrationHitContainer > m_HitColl
int barcode(const T *p)
Definition Barcode.h:16
int uniqueID(const T &p)
constexpr int UNDEFINED_ID