Class Reference for E1039 Core & Analysis Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
PHG4BlockSteppingAction.cc
Go to the documentation of this file.
2 #include "PHG4BlockDetector.h"
3 #include "PHG4StepStatusDecode.h"
4 
5 #include <phparameter/PHParameters.h>
6 
7 #include <g4main/PHG4Hit.h>
9 #include <g4main/PHG4Hitv1.h>
10 #include <g4main/PHG4Shower.h>
12 
13 #include <phool/getClass.h>
14 
15 #include <Geant4/G4Step.hh>
16 #include <Geant4/G4SystemOfUnits.hh>
17 
18 #include <iostream>
19 
20 using namespace std;
21 //____________________________________________________________________________..
23  : detector_(detector)
24  , params(parameters)
25  , hits_(nullptr)
26  , hit(nullptr)
27  , saveshower(nullptr)
28  , savevolpre(nullptr)
29  , savevolpost(nullptr)
30  , savetrackid(-1)
31  , saveprestepstatus(-1)
32  , savepoststepstatus(-1)
33  , active(params->get_int_param("active"))
34  , IsBlackHole(params->get_int_param("blackhole"))
35  , use_g4_steps(params->get_int_param("use_g4steps"))
36 {
37 }
38 
40 {
41  // if the last hit was a zero energie deposit hit, it is just reset
42  // and the memory is still allocated, so we need to delete it here
43  // if the last hit was saved, hit is a nullptr pointer which are
44  // legal to delete (it results in a no operation)
45  delete hit;
46 }
47 
48 //____________________________________________________________________________..
49 bool PHG4BlockSteppingAction::UserSteppingAction(const G4Step* aStep, bool)
50 {
51  G4TouchableHandle touch = aStep->GetPreStepPoint()->GetTouchableHandle();
52  G4TouchableHandle touchpost = aStep->GetPostStepPoint()->GetTouchableHandle();
53  // get volume of the current step
54  G4VPhysicalVolume* volume = touch->GetVolume();
55 
56  if (!detector_->IsInBlock(volume))
57  {
58  return false;
59  }
60 
61  // collect energy and track length step by step
62  G4double edep = aStep->GetTotalEnergyDeposit() / GeV;
63  G4double eion = (aStep->GetTotalEnergyDeposit() - aStep->GetNonIonizingEnergyDeposit()) / GeV;
64  const G4Track* aTrack = aStep->GetTrack();
65 
66  // if this block stops everything, just put all kinetic energy into edep
67  if (IsBlackHole)
68  {
69  edep = aTrack->GetKineticEnergy() / GeV;
70  G4Track* killtrack = const_cast<G4Track*>(aTrack);
71  killtrack->SetTrackStatus(fStopAndKill);
72  }
73 
74  // make sure we are in a volume
75  if (active)
76  {
77  int layer_id = detector_->get_Layer();
78  bool geantino = false;
79  // the check for the pdg code speeds things up, I do not want to make
80  // an expensive string compare for every track when we know
81  // geantino or chargedgeantino has pid=0
82  if (aTrack->GetParticleDefinition()->GetPDGEncoding() == 0 &&
83  aTrack->GetParticleDefinition()->GetParticleName().find("geantino") != string::npos)
84  {
85  geantino = true;
86  }
87  G4StepPoint* prePoint = aStep->GetPreStepPoint();
88  G4StepPoint* postPoint = aStep->GetPostStepPoint();
89  G4ThreeVector track_mom = aTrack->GetMomentum();
90  // cout << "track id " << aTrack->GetTrackID() << endl;
91  // cout << "time prepoint: " << prePoint->GetGlobalTime() << endl;
92  // cout << "time postpoint: " << postPoint->GetGlobalTime() << endl;
93  int prepointstatus = prePoint->GetStepStatus();
94  if (prepointstatus == fGeomBoundary ||
95  prepointstatus == fUndefined ||
96  (prepointstatus == fPostStepDoItProc && savepoststepstatus == fGeomBoundary) ||
97  use_g4_steps > 0)
98  {
99  if (prepointstatus == fPostStepDoItProc && savepoststepstatus == fGeomBoundary)
100  {
101  cout << GetName() << ": New Hit for " << endl;
102  cout << "prestep status: " << PHG4StepStatusDecode::GetStepStatus(prePoint->GetStepStatus())
103  << ", poststep status: " << PHG4StepStatusDecode::GetStepStatus(postPoint->GetStepStatus())
104  << ", last pre step status: " << PHG4StepStatusDecode::GetStepStatus(saveprestepstatus)
105  << ", last post step status: " << PHG4StepStatusDecode::GetStepStatus(savepoststepstatus) << endl;
106  cout << "last track: " << savetrackid
107  << ", current trackid: " << aTrack->GetTrackID() << endl;
108  cout << "phys pre vol: " << volume->GetName()
109  << " post vol : " << touchpost->GetVolume()->GetName() << endl;
110  cout << " previous phys pre vol: " << savevolpre->GetName()
111  << " previous phys post vol: " << savevolpost->GetName() << endl;
112  }
113  if (!hit)
114  {
115  hit = new PHG4Hitv1();
116  }
117  hit->set_layer(layer_id);
118  //here we set the entrance values in cm
119  hit->set_x(0, prePoint->GetPosition().x() / cm);
120  hit->set_y(0, prePoint->GetPosition().y() / cm);
121  hit->set_z(0, prePoint->GetPosition().z() / cm);
122  //
123  hit->set_px(0, track_mom.x()/GeV);
124  hit->set_py(0, track_mom.y()/GeV);
125  hit->set_pz(0, track_mom.z()/GeV);
126  // time in ns
127  hit->set_t(0, prePoint->GetGlobalTime() / nanosecond);
128  //set the track ID
129  hit->set_trkid(aTrack->GetTrackID());
130  savetrackid = aTrack->GetTrackID();
131 
132  //set the initial energy deposit
133  hit->set_edep(0);
134  if (!geantino && !IsBlackHole && active)
135  {
136  hit->set_eion(0);
137  }
138  if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
139  {
140  if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
141  {
142  hit->set_trkid(pp->GetUserTrackId());
143  hit->set_shower_id(pp->GetShower()->get_id());
144  saveshower = pp->GetShower();
145  }
146  }
147  }
148 
149  // some sanity checks for inconsistencies
150  // check if this hit was created, if not print out last post step status
151  if (!hit || !isfinite(hit->get_x(0)))
152  {
153  cout << GetName() << ": hit was not created" << endl;
154  cout << "prestep status: " << PHG4StepStatusDecode::GetStepStatus(prePoint->GetStepStatus())
155  << ", poststep status: " << PHG4StepStatusDecode::GetStepStatus(postPoint->GetStepStatus())
156  << ", last pre step status: " << PHG4StepStatusDecode::GetStepStatus(saveprestepstatus)
157  << ", last post step status: " << PHG4StepStatusDecode::GetStepStatus(savepoststepstatus) << endl;
158  cout << "last track: " << savetrackid
159  << ", current trackid: " << aTrack->GetTrackID() << endl;
160  cout << "phys pre vol: " << volume->GetName()
161  << " post vol : " << touchpost->GetVolume()->GetName() << endl;
162  cout << " previous phys pre vol: " << savevolpre->GetName()
163  << " previous phys post vol: " << savevolpost->GetName() << endl;
164  exit(1);
165  }
166  savepoststepstatus = postPoint->GetStepStatus();
167  // check if track id matches the initial one when the hit was created
168  if (aTrack->GetTrackID() != savetrackid)
169  {
170  cout << "hits do not belong to the same track" << endl;
171  cout << "saved track: " << savetrackid
172  << ", current trackid: " << aTrack->GetTrackID()
173  << endl;
174  exit(1);
175  }
176  saveprestepstatus = prePoint->GetStepStatus();
177  savepoststepstatus = postPoint->GetStepStatus();
178  savevolpre = volume;
179  savevolpost = touchpost->GetVolume();
180 
181  // here we just update the exit values, it will be overwritten
182  // for every step until we leave the volume or the particle
183  // ceases to exist
184  hit->set_x(1, postPoint->GetPosition().x() / cm);
185  hit->set_y(1, postPoint->GetPosition().y() / cm);
186  hit->set_z(1, postPoint->GetPosition().z() / cm);
187  hit->set_px(1, track_mom.x()/GeV);
188  hit->set_py(1, track_mom.y()/GeV);
189  hit->set_pz(1, track_mom.z()/GeV);
190 
191  hit->set_t(1, postPoint->GetGlobalTime() / nanosecond);
192  //sum up the energy to get total deposited
193  hit->set_edep(hit->get_edep() + edep);
194  // update ionization energy only for active volumes, not for black holes or geantinos
195  // if the hit is created without eion, get_eion() returns NAN
196  // if you see NANs check the creation of the hit
197  if (active && !IsBlackHole && !geantino)
198  {
199  hit->set_eion(hit->get_eion() + eion);
200  }
201  if (geantino)
202  {
203  hit->set_edep(-1); // only energy=0 g4hits get dropped, this way geantinos survive the g4hit compression
204  }
205  if (edep > 0)
206  {
207  if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
208  {
209  if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
210  {
211  pp->SetKeep(1); // we want to keep the track
212  }
213  }
214  }
215  // if any of these conditions is true this is the last step in
216  // this volume and we need to save the hit
217  // postPoint->GetStepStatus() == fGeomBoundary: track leaves this volume
218  // postPoint->GetStepStatus() == fWorldBoundary: track leaves this world
219  // (happens when your detector goes outside world volume)
220  // postPoint->GetStepStatus() == fAtRestDoItProc: track stops (typically
221  // aTrack->GetTrackStatus() == fStopAndKill is also set)
222  // aTrack->GetTrackStatus() == fStopAndKill: track ends
223  if (postPoint->GetStepStatus() == fGeomBoundary ||
224  postPoint->GetStepStatus() == fWorldBoundary ||
225  postPoint->GetStepStatus() == fAtRestDoItProc ||
226  aTrack->GetTrackStatus() == fStopAndKill ||
227  use_g4_steps > 0)
228  {
229  // save only hits with energy deposit (or -1 for geantino)
230  if (hit->get_edep())
231  {
232  hits_->AddHit(layer_id, hit);
233  if (saveshower)
234  {
235  saveshower->add_g4hit_id(hits_->GetID(), hit->get_hit_id());
236  }
237  // ownership has been transferred to container, set to null
238  // so we will create a new hit for the next track
239  hit = nullptr;
240  }
241  else
242  {
243  // if this hit has no energy deposit, just reset it for reuse
244  // this means we have to delete it in the dtor. If this was
245  // the last hit we processed the memory is still allocated
246  hit->Reset();
247  }
248  }
249  // return true to indicate the hit was used
250  return true;
251  }
252  else
253  {
254  return false;
255  }
256 }
257 
258 //____________________________________________________________________________..
260 {
261  string hitnodename;
262  if (detector_->SuperDetector() != "NONE")
263  {
264  hitnodename = "G4HIT_" + detector_->SuperDetector();
265  }
266  else
267  {
268  hitnodename = "G4HIT_" + detector_->GetName();
269  }
270 
271  //now look for the map and grab a pointer to it.
272  hits_ = findNode::getClass<PHG4HitContainer>(topNode, hitnodename.c_str());
273 
274  // if we do not find the node we need to make it.
275  if (!hits_)
276  {
277  std::cout << "PHG4BlockSteppingAction::SetTopNode - unable to find " << hitnodename << std::endl;
278  }
279 }
bool IsInBlock(G4VPhysicalVolume *) const
void SuperDetector(const std::string &name)
virtual void SetInterfacePointers(PHCompositeNode *)
reimplemented from base class
virtual ~PHG4BlockSteppingAction()
destructor
PHG4BlockSteppingAction(PHG4BlockDetector *, const PHParameters *parameters)
constructor
virtual bool UserSteppingAction(const G4Step *, bool)
stepping action
virtual std::string GetName() const
Definition: PHG4Detector.h:51
ConstIterator AddHit(PHG4Hit *newhit)
virtual void set_layer(const unsigned int i)
Definition: PHG4Hit.h:66
virtual float get_eion() const
Definition: PHG4Hit.h:32
virtual void set_y(const int i, const float f)
Definition: PHG4Hit.h:53
virtual void set_shower_id(const int i)
Definition: PHG4Hit.h:68
virtual float get_edep() const
Definition: PHG4Hit.h:31
virtual void set_px(const int i, const float f)
Definition: PHG4Hit.h:55
virtual void set_py(const int i, const float f)
Definition: PHG4Hit.h:56
virtual void set_t(const int i, const float f)
Definition: PHG4Hit.h:61
virtual void set_pz(const int i, const float f)
Definition: PHG4Hit.h:57
virtual void set_eion(const float f)
Definition: PHG4Hit.h:63
virtual void Reset()
Clear Event.
Definition: PHG4Hit.cc:63
virtual void set_z(const int i, const float f)
Definition: PHG4Hit.h:54
virtual void set_x(const int i, const float f)
Definition: PHG4Hit.h:52
virtual PHG4HitDefs::keytype get_hit_id() const
Definition: PHG4Hit.h:36
virtual float get_x(const int i) const
Definition: PHG4Hit.h:21
virtual void set_trkid(const int i)
Definition: PHG4Hit.h:71
virtual void set_edep(const float f)
Definition: PHG4Hit.h:62
virtual void add_g4hit_id(int volume, PHG4HitDefs::keytype id)
Definition: PHG4Shower.h:100
std::string GetName() const
std::string GetStepStatus(const int istatus)