ATLAS Offline Software
ZDC_EscapedEnergyProcessing.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 #include "ZDC_G4CalibSD.h"
7 
8 
9 #include "G4MultiSensitiveDetector.hh"
10 #include "G4TouchableHandle.hh"
11 #include "G4Step.hh"
12 #include "G4StepPoint.hh"
13 #include "G4VPhysicalVolume.hh"
14 #include "G4LogicalVolume.hh"
15 #include "G4VSensitiveDetector.hh"
16 
17 #undef DEBUG_PROCESS
18 
19 
21  : m_defaultSD(SD)
22 {}
23 
25 {;}
26 
27 G4bool ZDC_EscapedEnergyProcessing::Process( G4Step* fakeStep ) {
28  // Escaped energy requires special processing. The energy was not
29  // deposited in the current G4Step, but at the beginning of the
30  // particle's track. For example, if a neutrino escapes the
31  // detector, the energy should be recorded at the point where the
32  // neutrino was created, not at the point where it escaped the
33  // detector.
34 
35  // The calibration sensitive detector has a special routine to
36  // handle this: CalibrationSensitiveDetector::SpecialHit(). We
37  // have to locate the correct sensitive detector in order to
38  // deposit the escaped energy.
39 
40  // Escaped energies from non-sensitive volumes requires a special
41  // sensitive detector.
42 
43  G4StepPoint* fakePreStepPoint = fakeStep->GetPreStepPoint();
44  G4StepPoint* fakePostStepPoint = fakeStep->GetPostStepPoint();
45  G4TouchableHandle a_touchableHandle = fakePreStepPoint->GetTouchableHandle();
46 
47  // Here is the actual location of the escaped energy, as the
48  // fourth component of a vector. (Why not just pass the energy in
49  // the G4Step? Because CalibrationSensitiveDetector::SpecialHit()
50  // is not designed just for escaped energy, but any unusual cases
51  // in which we have to deposit any of the calibration energies in
52  // a place other than the current step.)
53 
54  std::vector<G4double> energies;
55  energies.resize(4,0.);
56  energies[3] = fakeStep->GetTotalEnergyDeposit();//a_energy;
57 
58  // If we find a calibration sensitive detector in the original
59  // volume, use that sensitive detector. If we don't, use a
60  // "default" sensitive detector that's designed to accumulate
61  // these "dead material" energies.
62 
63  // Find out in which physical volume our hit is located.
64  G4VPhysicalVolume* physicalVolume = a_touchableHandle->GetVolume();
65 
66  // If the volume is valid...
67  if (ATH_LIKELY(physicalVolume))
68  {
69 #ifdef DEBUG_PROCESS
70  G4cout << "ZdcG4::ZDC_EscapedEnergyProcessing::Process - "
71  << " particle created in volume '"
72  << physicalVolume->GetName()
73  << "'" << G4endl;
74 #endif
75 
76  G4LogicalVolume* logicalVolume = physicalVolume->GetLogicalVolume();
77 
78  // To prevent some potential problems with uninitialized values,
79  // set the material of the step points.
80  fakePreStepPoint->SetMaterial( logicalVolume->GetMaterial() );
81  fakePostStepPoint->SetMaterial( logicalVolume->GetMaterial() );
82 
83  // Is this volume associated with a sensitive detector?
84  G4VSensitiveDetector* sensitiveDetector =
85  logicalVolume->GetSensitiveDetector();
86 
87  if (ATH_LIKELY(sensitiveDetector)){
88 #ifdef DEBUG_PROCESS
89  G4cout << " ... which has sensitive detector '" << sensitiveDetector->GetName() << "'" << G4endl;
90 #endif
91  ZDC_G4CalibSD* zdcG4CalibSD(nullptr);
92  G4MultiSensitiveDetector* zdcG4MultSD = dynamic_cast<G4MultiSensitiveDetector*>(sensitiveDetector);
93  // The multiSensitiveDetector is needed for the quartz rods and RPD fibers that have FiberSD and G4CalibSD associated with it
94  if(zdcG4MultSD !=0){
95  G4bool found = false;
96  for(unsigned int i=0; i<zdcG4MultSD->GetSize(); i++){
97  zdcG4CalibSD = dynamic_cast<ZDC_G4CalibSD*>(zdcG4MultSD->GetSD(i));
98  if (zdcG4CalibSD){
99  // We found one. Process the energy.
100  found = true;
101 #ifdef DEBUG_PROCESS
102  G4cout << " ... which contains calibration sensitive detector '" << zdcG4CalibSD->GetName() << "'" << G4endl;
103 #endif
104  zdcG4CalibSD->SpecialHit(fakeStep,energies);
105  }
106  }// -- for (1)
107  if(ATH_UNLIKELY(!found)){
108 #ifdef DEBUG_PROCESS
109  G4cout << "ZdcG4::ZDC_EscapedEnergyProcessing::Process - "
110  << " particle (x,y,z)=("
111  << a_point.x() << ","
112  << a_point.y() << ","
113  << a_point.z() << ") with energy="
114  << a_energy
115  << " was created in volume '"
116  << physicalVolume->GetName()
117  << "'; could not find a CalibrationSensitiveDetector"
118  << " within ZdcG4MultSD'"
119  << zdcG4MultSD->GetName() << "'"
120  << G4endl;
121  G4cout << " Using default sensitive detector." << G4endl;
122 #endif
123  m_defaultSD->SpecialHit( fakeStep, energies );
124  return false; // error
125  }// - !found (1)
126 
127  } else { // zdcG4MultSD == 0
128  // Next possibility: ZDC_G4CalibSD
129  zdcG4CalibSD = dynamic_cast<ZDC_G4CalibSD*>(sensitiveDetector);
130  if(ATH_UNLIKELY(zdcG4CalibSD)){
131 #ifdef DEBUG_PROCESS
132  G4cout << " ... which is a ZDC_G4CalibSD " << G4endl;
133 #endif
134  zdcG4CalibSD->SpecialHit( fakeStep, energies );
135  }
136  else // zdcG4CalibSD==0
137  {
138  // --- backwards compatibility ---
139 
140  // We've found a sensitive detector. Is it a CalibrationSensitiveDetector?
141  ZDC_G4CalibSD* calibSD = dynamic_cast<ZDC_G4CalibSD*>(sensitiveDetector);
142  if ( calibSD != 0 ){
143  // It is! Process the energy.
144 #ifdef DEBUG_PROCESS
145  G4cout << " ... which is a calibration sensitive detector " << G4endl;
146 #endif
147  calibSD->SpecialHit( fakeStep, energies );
148  } else {
149 #ifdef DEBUG_PROCESS
150  G4cout << "ZdcG4::ZDC_EscapedEnergyProcessing::Process - "
151  << " particle (x,y,z)=("
152  << a_point.x() << ","
153  << a_point.y() << ","
154  << a_point.z() << ") with energy="
155  << a_energy
156  << " was created in volume '"
157  << physicalVolume->GetName()
158  << "' with sensitive detector '"
159  << sensitiveDetector->GetName()
160  << "' which is not a CalibrationSensitiveDetector."
161  << G4endl;
162  G4cout << " Using default sensitive detector." << G4endl;
163 #endif
164  // of type ZDC_G4CalibSD
165  m_defaultSD->SpecialHit( fakeStep, energies );
166  return false; // error
167  }
168  }
169  }
170  } else {
171  // If we reach this point, then the particle whose energy
172  // has escaped was created outside of a sensitive region.
173 #ifdef DEBUG_PROCESS
174  G4cout << "ZdcG4::ZDC_EscapedEnergyProcessing::Process - "
175  << " particle (x,y,z)=("
176  << a_point.x() << ","
177  << a_point.y() << ","
178  << a_point.z() << ") with energy="
179  << a_energy
180  << " was created in volume '"
181  << physicalVolume->GetName()
182  << "' which is not sensitive."
183  << G4endl;
184  G4cout << " Using default sensitive detector." << G4endl;
185 #endif
186  m_defaultSD->SpecialHit( fakeStep, energies );
187  return false; // error
188  }
189  }
190 
191  // Processing was OK.
192  return true;
193 }
ZDC_EscapedEnergyProcessing::m_defaultSD
ZDC_G4CalibSD * m_defaultSD
Definition: ZDC_EscapedEnergyProcessing.h:47
ZDC_EscapedEnergyProcessing::Process
G4bool Process(G4Step *fakeStep)
Definition: ZDC_EscapedEnergyProcessing.cxx:27
ATH_UNLIKELY
#define ATH_UNLIKELY(x)
Definition: AthUnlikelyMacros.h:17
ZDC_G4CalibSD
Definition: ZDC_G4CalibSD.h:23
ZDC_EscapedEnergyProcessing::~ZDC_EscapedEnergyProcessing
~ZDC_EscapedEnergyProcessing()
Definition: ZDC_EscapedEnergyProcessing.cxx:24
ZDC_EscapedEnergyProcessing.h
lumiFormat.i
int i
Definition: lumiFormat.py:85
ZDC_G4CalibSD::SpecialHit
G4bool SpecialHit(G4Step *a_step, const std::vector< G4double > &a_energies)
Definition: ZDC_G4CalibSD.cxx:115
checkTriggerxAOD.found
found
Definition: checkTriggerxAOD.py:328
ZDC_G4CalibSD.h
ATH_LIKELY
#define ATH_LIKELY(x)
Definition: AthUnlikelyMacros.h:16
ZDC_EscapedEnergyProcessing::ZDC_EscapedEnergyProcessing
ZDC_EscapedEnergyProcessing(ZDC_G4CalibSD *SD)
Definition: ZDC_EscapedEnergyProcessing.cxx:20