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