ATLAS Offline Software
TestActionShowerLib.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 #include <string>
8 
9 #include "G4Step.hh"
10 #include "G4Event.hh"
11 #include "G4AffineTransform.hh"
12 #include "G4TouchableHistory.hh"
13 #include "G4ThreeVector.hh"
14 #include "G4VSolid.hh"
15 
18 
19 // For MC Truth information:
21 
22 #undef _myDEBUG_
23 
24 namespace G4UA
25 {
26 
28  m_evtStore("StoreGateSvc/StoreGateSvc","TestActionShowerLib"),
29  m_current_calculator("","TestActionShowerLib"),
30  m_current_solid(nullptr),
31  m_current_transform(nullptr),
32  m_calculator_EMECIW("EMECPosInnerWheelCalculator","TestActionShowerLib"),
33  m_calculator_EMECOW("EMECPosOuterWheelCalculator","TestActionShowerLib"),
34  m_calculator_FCAL1("FCAL1Calculator","TestActionShowerLib"),
35  m_calculator_FCAL2("FCAL2Calculator","TestActionShowerLib"),
36  m_calculator_FCAL3("FCAL3Calculator","TestActionShowerLib"),
37  m_calculator_EMB("EMBCalculator","TestActionShowerLib"),
38  m_eventSteps(nullptr)
39  {
40 #ifdef _myDEBUG_
41  G4cout << "#########################################" << G4endl
42  << "## TestActionShowerLib - Constructor ##" << G4endl
43  << "#########################################" << G4endl;
44 #endif
45  }
46 
48  {
49  if (m_current_transform == nullptr) {
50  m_current_transform = new G4AffineTransform();
51  }
52 
54 
55 #ifdef _myDEBUG_
56  G4cout << "#########################################" << G4endl
57  << "## TestActionShowerLib - BeginOfEvent ##" << G4endl
58  << "#########################################" << G4endl;
59 #endif
60  }
61 
63  {
64 #ifdef _myDEBUG_
65  G4cout << "#########################################" << G4endl
66  << "## TestActionShowerLib - EndOfEvent ##" << G4endl
67  //<< "## MMM="<<m_count<<" ###" << G4endl
68  << "#########################################" << G4endl;
69 #endif
70 
71  //
72  // Zero order cleanup
73  // combine hits from the same spot (distance < 1 mm^2)
74  // only necessary for large number of spots (> 500)
75  //
76  const double dsame = 1.; // 1mm^2
77 
78 #ifdef _myDEBUG_
79  G4cout << "TestActionShowerLib::EndOfEventAction: Before initial cleanup, N="
80  << m_eventSteps->size() << G4endl;
81 #endif
82 
83  if (m_eventSteps->size()>500) {
85  while (i1 != m_eventSteps->end()) {
87  while (i2 != m_eventSteps->end()) {
88  // if distance below cut off, combined and erase
89  if ( (i1 != i2) && ((*i1)->diff2(**i2) < dsame)) {
90  **i1 += **i2;
91  i2 = m_eventSteps->erase(i2);
92  } else {
93  ++i2;
94  }
95  }
96  ++i1;
97  }
98  }
99 
100 #ifdef _myDEBUG_
101  G4cout << "TestActionShowerLib::EndOfEventAction: After initial cleanup, N="
102  << m_eventSteps->size() << G4endl;
103 #endif
104 
105  //
106  // Put eventSteps into event store
107  //
108  std::string location("EventSteps");
109  StatusCode sc = m_evtStore->record( m_eventSteps, location, true );
110  if( sc.isFailure() ) {
111  G4cout << "TestActionShowerLib::EndOfEventAction Error: Couldn't store "
112  << "EventSteps object in event store at location: " << location << G4endl;
113  } else {
114 #ifdef _myDEBUG_
115  G4cout << "TestActionShowerLib::EndOfEventAction: Stored EventSteps "
116  << "object (size: " << m_eventSteps->size() << ")"
117  << " in event store at location: " << location << G4endl;
118 #endif
119  }
120  }
121 
123  {
124 #ifdef _myDEBUG_
125  G4cout << "#########################################" << G4endl
126  << "## TestActionShowerLib - BeginOfRun ##" << G4endl
127  << "#########################################" << G4endl;
128 #endif
129  // init calculator
130  if(!m_calculator_EMECIW.retrieve().isSuccess()) {
131  G4cout<<"Could not get ILArCalculatorSvc/InnerAbsorberWheel"<<G4endl;
132  return;
133  }
134  if(!m_calculator_EMECOW.retrieve().isSuccess()) {
135  G4cout<<"Could not get ILArCalculatorSvc/OuterAbsorberWheel"<<G4endl;
136  return;
137  }
138  if(!m_calculator_FCAL1.retrieve().isSuccess()) {
139  G4cout<<"Could not get ILArCalculatorSvc/FCAL1Calculator"<<G4endl;
140  return;
141  }
142  if(!m_calculator_FCAL2.retrieve().isSuccess()) {
143  G4cout<<"Could not get ILArCalculatorSvc/FCAL2Calculator"<<G4endl;
144  return;
145  }
146  if(!m_calculator_FCAL3.retrieve().isSuccess()) {
147  G4cout<<"Could not get ILArCalculatorSvc/FCAL3Calculator"<<G4endl;
148  return;
149  }
150  if(!m_calculator_EMB.retrieve().isSuccess()) {
151  G4cout<<"Could not get ILArCalculatorSvc/BarrelCalculator"<<G4endl;
152  return;
153  }
154 
155  if (m_current_transform == nullptr) {
156  m_current_transform = new G4AffineTransform ();
157  }
158  }
159 
161  {
162 #ifdef _myDEBUG_
163  G4cout << "#########################################" << G4endl
164  << "## TestActionShowerLib - EndOfRun ##" << G4endl
165  << "#########################################" << G4endl;
166 #endif
167  }
168 
169 
170  void TestActionShowerLib::UserSteppingAction(const G4Step* aStep)
171  {
172  bool hasCalc=true;
173  bool emptydet = (m_eventSteps->detector[0] == '\0'); //empty string. man, i hate pure C!
174  if (emptydet) { //give name to the detector, set calculator, transformation and G4Solid for the whole shower
175  G4ThreeVector pos = aStep->GetPostStepPoint()->GetPosition();
176  const G4TouchableHistory* theTouchable = static_cast<const G4TouchableHistory*>(aStep->GetPostStepPoint()->GetTouchable());
177  int depth = theTouchable->GetHistoryDepth();
178  bool correct_volume = false;
179  if (depth < 2) { //this is obviously the wrong volume
180  correct_volume = true; // this may appear misleading, but actually it means: "no need to look deeper"
181  }
182  G4VPhysicalVolume* rootVol = theTouchable->GetVolume(depth - 1);
183  int curdepth = 0;
184  m_current_transform->SetNetRotation(*(theTouchable->GetRotation(curdepth)));
185  m_current_transform->SetNetTranslation(theTouchable->GetTranslation(curdepth));
186  m_current_transform->Invert();
187  G4VPhysicalVolume* cur_volume = theTouchable->GetVolume(curdepth);
188  G4LogicalVolume* cur_log_volume = cur_volume->GetLogicalVolume();
189 
190  do {
191  if ((cur_log_volume->GetName() == "LArMgr::LAr::FCAL::Module1::Absorber") ||
192  (cur_log_volume->GetName() == "LArMgr::LAr::FCAL::Module2::Absorber") ||
193  (cur_log_volume->GetName() == "LArMgr::LAr::EMEC::Pos::OuterWheel") ||
194  (cur_log_volume->GetName() == "LArMgr::LAr::EMEC::Neg::OuterWheel") ||
195  (cur_log_volume->GetName() == "LArMgr::LAr::EMEC::Pos::InnerWheel") ||
196  (cur_log_volume->GetName() == "LArMgr::LAr::EMEC::Neg::InnerWheel") ||
197  (cur_log_volume->GetName() == "LArMgr::LAr::EMB::STAC")) {
198  correct_volume = true;
199  }
200  if (!correct_volume) { //go one level up
201  curdepth++;
202  m_current_transform->SetNetRotation(*(theTouchable->GetRotation(curdepth)));
203  m_current_transform->SetNetTranslation(theTouchable->GetTranslation(curdepth));
204  cur_volume = theTouchable->GetVolume(curdepth);
205  cur_log_volume = cur_volume->GetLogicalVolume();
206  }
207  } while ((!correct_volume) && (cur_volume != rootVol) && (curdepth < (depth-1)));
208 
209  m_current_solid = cur_log_volume->GetSolid();
210 
211  if (cur_log_volume->GetName() == "LArMgr::LAr::FCAL::Module1::Absorber") {
212  // shower is inside FCAL1
214  strcpy(m_eventSteps->detector,"FCAL1");
215  } else if (cur_log_volume->GetName() == "LArMgr::LAr::FCAL::Module2::Absorber") {
216  // shower is inside FCAL2
218  strcpy(m_eventSteps->detector,"FCAL2");
219  } else if ((cur_log_volume->GetName() == "LArMgr::LAr::EMEC::Pos::InnerWheel") ||
220  (cur_log_volume->GetName() == "LArMgr::LAr::EMEC::Neg::InnerWheel")) {
221  // shower is inside inner EMEC
223  strcpy(m_eventSteps->detector,"EMEC");
224  } else if ((cur_log_volume->GetName() == "LArMgr::LAr::EMEC::Pos::OuterWheel") ||
225  (cur_log_volume->GetName() == "LArMgr::LAr::EMEC::Neg::OuterWheel")) {
226  // shower is inside outer EMEC positive
228  strcpy(m_eventSteps->detector,"EMEC");
229  } else if (cur_log_volume->GetName() == "LArMgr::LAr::EMB::STAC") {
230  // shower is inside EMB positive
232  strcpy(m_eventSteps->detector,"EMB");
233  } else {
234  // outside.
235  //m_current_calculator = NULL;
236  hasCalc=false;
237  }
238  }
239 
240  if (aStep->GetTotalEnergyDeposit()>0) {
241  //first, let's see if the shower is valid
242  if (!hasCalc) {
243  m_eventSteps->invalid_energy += aStep->GetTotalEnergyDeposit();
244  return;
245  }
246  //then, let's see if we travel outside the detector volume
247 
248  // Initial position:
249  G4ThreeVector pos1=aStep->GetPreStepPoint()->GetPosition();
250  G4ThreeVector pos2=aStep->GetPostStepPoint()->GetPosition();
251 
252  // Average position:
253  G4ThreeVector pos = 0.5*(pos1+pos2);
254 
255  G4ThreeVector prepos = pos1;
256  m_current_transform->ApplyPointTransform(prepos);
257  if (m_current_solid->Inside(prepos) == kOutside) {
258  m_eventSteps->invalid_energy += aStep->GetTotalEnergyDeposit();
259  return;
260  }
261 
262  G4VPhysicalVolume* pCurrentVolume = aStep->GetPreStepPoint()->GetPhysicalVolume();
263  if (!pCurrentVolume->GetLogicalVolume()->GetSensitiveDetector()){
264  return;
265  }
266 
267  double et = 0; // Total collected charge
268  std::vector<LArHitData> results;
269  if (m_current_calculator->Process(aStep, results))
270  {
271  for (const auto& larhit: results)
272  {
273  et += larhit.energy;
274  }
275  }
276  else
277  {
278  G4cout << "Error: Hit not processed by calculator!" << G4endl;
279  return;
280  }
281 
282  // drop hits with zero deposited energy (could still happen with negative corrections from calculator)
283  if (et <= 0.) {
284  return;
285  }
286 
287  ShowerLib::StepInfo* theInfo = new ShowerLib::StepInfo();
288 
289  theInfo->setE(et);
290 
291 #ifdef _myDEBUG_
292  G4cout<<" TAGINFO: "<< et <<" "<<aStep->GetTotalEnergyDeposit()<< G4endl;
293 #endif
294 
295  theInfo->setTime(aStep->GetPreStepPoint()->GetGlobalTime());
296 
297  theInfo->setP(pos);
298 
299  m_eventSteps->push_back(theInfo);
300 
301  } else {
302 #ifdef _myDEBUG_
303  G4cout << "DEBUG: step " << aStep->GetTotalEnergyDeposit() << G4endl;
304 #endif
305  }
306  }
307 
308 } // namespace G4UA
G4UA::TestActionShowerLib::m_current_solid
G4VSolid * m_current_solid
Definition: TestActionShowerLib.h:68
StepInfo.h
et
Extra patterns decribing particle interation process.
verify_menu_config.results
results
Definition: verify_menu_config.py:67
egammaParameters::depth
@ depth
pointing depth of the shower as calculated in egammaqgcld
Definition: egammaParamDefs.h:276
ShowerLib::StepInfoCollection::detector
char detector[10]
Definition: StepInfoCollection.h:38
ShowerLib::StepInfo::setTime
void setTime(const double t)
set time
Definition: StepInfo.h:57
G4UA
for nSW
Definition: CalibrationDefaultProcessing.h:19
G4UA::TestActionShowerLib::m_eventSteps
ShowerLib::StepInfoCollection * m_eventSteps
Collection of StepInfo.
Definition: TestActionShowerLib.h:86
G4UA::TestActionShowerLib::TestActionShowerLib
TestActionShowerLib()
Definition: TestActionShowerLib.cxx:27
G4UA::TestActionShowerLib::m_calculator_EMB
ServiceHandle< ILArCalculatorSvc > m_calculator_EMB
Definition: TestActionShowerLib.h:81
ShowerLib::StepInfoCollection
Class for collection of StepInfo class (G4 hits)
Definition: StepInfoCollection.h:32
G4UA::TestActionShowerLib::m_calculator_FCAL3
ServiceHandle< ILArCalculatorSvc > m_calculator_FCAL3
Definition: TestActionShowerLib.h:80
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
ShowerLib::StepInfo::setP
void setP(const CLHEP::Hep3Vector &p)
set position
Definition: StepInfo.h:47
G4UA::TestActionShowerLib::m_calculator_FCAL1
ServiceHandle< ILArCalculatorSvc > m_calculator_FCAL1
Definition: TestActionShowerLib.h:78
McEventCollection.h
DataModel_detail::iterator
(Non-const) Iterator class for DataVector/DataList.
Definition: DVLIterator.h:184
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
G4UA::TestActionShowerLib::BeginOfEventAction
virtual void BeginOfEventAction(const G4Event *) override
Definition: TestActionShowerLib.cxx:47
G4UA::TestActionShowerLib::m_calculator_EMECOW
ServiceHandle< ILArCalculatorSvc > m_calculator_EMECOW
Pointer to EMEC outer wheel calculator.
Definition: TestActionShowerLib.h:77
ShowerLib::StepInfoCollection::invalid_energy
float invalid_energy
Definition: StepInfoCollection.h:39
G4UA::TestActionShowerLib::EndOfRunAction
virtual void EndOfRunAction(const G4Run *) override
Definition: TestActionShowerLib.cxx:160
G4UA::TestActionShowerLib::m_calculator_FCAL2
ServiceHandle< ILArCalculatorSvc > m_calculator_FCAL2
Definition: TestActionShowerLib.h:79
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
G4UA::TestActionShowerLib::m_current_calculator
ServiceHandle< ILArCalculatorSvc > m_current_calculator
Definition: TestActionShowerLib.h:67
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
G4UA::TestActionShowerLib::BeginOfRunAction
virtual void BeginOfRunAction(const G4Run *) override
Definition: TestActionShowerLib.cxx:122
G4UA::TestActionShowerLib::m_evtStore
ServiceHandle< StoreGateSvc > m_evtStore
Pointer to StoreGate (event store by default)
Definition: TestActionShowerLib.h:63
G4UA::TestActionShowerLib::m_current_transform
G4AffineTransform * m_current_transform
Definition: TestActionShowerLib.h:69
G4UA::TestActionShowerLib::m_calculator_EMECIW
ServiceHandle< ILArCalculatorSvc > m_calculator_EMECIW
Pointer to EMEC inner wheel calculator.
Definition: TestActionShowerLib.h:75
ShowerLib::StepInfo::setE
void setE(const double t)
set depoisted energy
Definition: StepInfo.h:55
G4UA::TestActionShowerLib::UserSteppingAction
virtual void UserSteppingAction(const G4Step *) override
Definition: TestActionShowerLib.cxx:170
DataVector::erase
iterator erase(iterator position)
Remove element at a given position.
G4UA::TestActionShowerLib::EndOfEventAction
virtual void EndOfEventAction(const G4Event *) override
Definition: TestActionShowerLib.cxx:62
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
TestActionShowerLib.h
StepInfoCollection.h
ShowerLib::StepInfo
Class to collect information about G4 steps.
Definition: StepInfo.h:35
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.