EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PHG4SectorSteppingAction.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PHG4SectorSteppingAction.cc
2 #include "PHG4SectorDetector.h"
3 
4 #include <g4main/PHG4Hit.h>
6 #include <g4main/PHG4Hitv1.h>
7 #include <g4main/PHG4Shower.h>
8 #include <g4main/PHG4SteppingAction.h> // for PHG4SteppingAction
10 
11 #include <phool/getClass.h>
12 
13 #include <Geant4/G4ParticleDefinition.hh> // for G4ParticleDefinition
14 #include <Geant4/G4Step.hh>
15 #include <Geant4/G4StepPoint.hh> // for G4StepPoint
16 #include <Geant4/G4StepStatus.hh> // for fGeomBoundary, fAtRestD...
17 #include <Geant4/G4String.hh> // for G4String
18 #include <Geant4/G4SystemOfUnits.hh> // for cm, GeV, nanosecond
19 #include <Geant4/G4ThreeVector.hh> // for G4ThreeVector
20 #include <Geant4/G4TouchableHandle.hh> // for G4TouchableHandle
21 #include <Geant4/G4Track.hh> // for G4Track
22 #include <Geant4/G4TrackStatus.hh> // for fStopAndKill
23 #include <Geant4/G4Types.hh> // for G4double
24 #include <Geant4/G4VTouchable.hh> // for G4VTouchable
25 #include <Geant4/G4VUserTrackInformation.hh> // for G4VUserTrackInformation
26 
27 #include <iostream>
28 #include <string> // for string, operator+, oper...
29 
30 class G4VPhysicalVolume;
31 class PHCompositeNode;
32 
33 using namespace std;
34 //____________________________________________________________________________..
36  : PHG4SteppingAction(detector->GetName())
37  , detector_(detector)
38  , hits_(nullptr)
39  , hit(nullptr)
40  , saveshower(nullptr)
41  , layer_id(-1)
42 {
43 }
44 
46 {
47  // if the last hit was a zero energie deposit hit, it is just reset
48  // and the memory is still allocated, so we need to delete it here
49  // if the last hit was saved, hit is a nullptr pointer which are
50  // legal to delete (it results in a no operation)
51  delete hit;
52 }
53 
54 //____________________________________________________________________________..
55 bool PHG4SectorSteppingAction::UserSteppingAction(const G4Step* aStep, bool)
56 {
57  // get volume of the current step
58  G4VPhysicalVolume* volume =
59  aStep->GetPreStepPoint()->GetTouchableHandle()->GetVolume();
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 
65  const G4Track* aTrack = aStep->GetTrack();
66 
67  // make sure we are in a volume
68  if (detector_->IsInSectorActive(volume))
69  {
70  bool geantino = false;
71  // the check for the pdg code speeds things up, I do not want to make
72  // an expensive string compare for every track when we know
73  // geantino or chargedgeantino has pid=0
74  if (aTrack->GetParticleDefinition()->GetPDGEncoding() == 0 && aTrack->GetParticleDefinition()->GetParticleName().find("geantino") != string::npos)
75  {
76  geantino = true;
77  }
78  G4StepPoint* prePoint = aStep->GetPreStepPoint();
79  G4StepPoint* postPoint = aStep->GetPostStepPoint();
80  // cout << "track id " << aTrack->GetTrackID() << endl;
81  // cout << "time prepoint: " << prePoint->GetGlobalTime() << endl;
82  // cout << "time postpoint: " << postPoint->GetGlobalTime() << endl;
83  //layer_id is sector number
84  switch (prePoint->GetStepStatus())
85  {
86  case fGeomBoundary:
87  case fUndefined:
88  if (!hit)
89  {
90  hit = new PHG4Hitv1();
91  }
92  //here we set the entrance values in cm
93  hit->set_x(0, prePoint->GetPosition().x() / cm);
94  hit->set_y(0, prePoint->GetPosition().y() / cm);
95  hit->set_z(0, prePoint->GetPosition().z() / cm);
96  // time in ns
97  hit->set_t(0, prePoint->GetGlobalTime() / nanosecond);
98  //set the track ID
99  hit->set_trkid(aTrack->GetTrackID());
100  if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
101  {
102  if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
103  {
104  hit->set_trkid(pp->GetUserTrackId());
105  hit->set_shower_id(pp->GetShower()->get_id());
106  saveshower = pp->GetShower();
107  }
108  }
109 
110  //set the initial energy deposit
111  hit->set_edep(0);
112  hit->set_eion(0); // only implemented for v5 otherwise empty
113  layer_id = aStep->GetPreStepPoint()->GetTouchable()->GetReplicaNumber(1);
114  // hit->set_light_yield(0);
115 
116  break;
117  default:
118  break;
119  }
120  // here we just update the exit values, it will be overwritten
121  // for every step until we leave the volume or the particle
122  // ceases to exist
123  hit->set_x(1, postPoint->GetPosition().x() / cm);
124  hit->set_y(1, postPoint->GetPosition().y() / cm);
125  hit->set_z(1, postPoint->GetPosition().z() / cm);
126 
127  hit->set_t(1, postPoint->GetGlobalTime() / nanosecond);
128  //sum up the energy to get total deposited
129  hit->set_edep(hit->get_edep() + edep);
130  hit->set_eion(hit->get_eion() + eion);
131  hit->set_path_length(aTrack->GetTrackLength() / cm);
132  if (geantino)
133  {
134  hit->set_edep(-1); // only energy=0 g4hits get dropped, this way geantinos survive the g4hit compression
135  }
136  if (edep > 0)
137  {
138  if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
139  {
140  if (PHG4TrackUserInfoV1* pp =
141  dynamic_cast<PHG4TrackUserInfoV1*>(p))
142  {
143  pp->SetKeep(1); // we want to keep the track
144  }
145  }
146  }
147  // if any of these conditions is true this is the last step in
148  // this volume and we need to save the hit
149  // postPoint->GetStepStatus() == fGeomBoundary: track leaves this volume
150  // postPoint->GetStepStatus() == fWorldBoundary: track leaves this world
151  // (not sure if this will ever be the case)
152  // aTrack->GetTrackStatus() == fStopAndKill: track ends
153  if (postPoint->GetStepStatus() == fGeomBoundary ||
154  postPoint->GetStepStatus() == fWorldBoundary ||
155  postPoint->GetStepStatus() == fAtRestDoItProc ||
156  aTrack->GetTrackStatus() == fStopAndKill)
157  {
158  // save only hits with energy deposit (or -1 for geantino)
159  if (hit->get_edep())
160  {
162  if (saveshower)
163  {
165  }
166  // ownership has been transferred to container, set to null
167  // so we will create a new hit for the next track
168  hit = nullptr;
169  }
170  else
171  {
172  // if this hit has no energy deposit, just reset it for reuse
173  // this means we have to delete it in the dtor. If this was
174  // the last hit we processed the memory is still allocated
175  hit->Reset();
176  }
177  }
178 
179  // hit->identify();
180  // return true to indicate the hit was used
181  return true;
182  }
183  else
184  {
185  return false;
186  }
187 }
188 
189 //____________________________________________________________________________..
191 {
192  string hitnodename;
193  if (detector_->SuperDetector() != "NONE")
194  {
195  hitnodename = "G4HIT_" + detector_->SuperDetector();
196  }
197  else
198  {
199  hitnodename = "G4HIT_" + detector_->GetName();
200  }
201 
202  //now look for the map and grab a pointer to it.
203  hits_ = findNode::getClass<PHG4HitContainer>(topNode, hitnodename.c_str());
204 
205  // if we do not find the node we need to make it.
206  if (!hits_)
207  {
208  std::cout << "PHG4SectorSteppingAction::SetTopNode - unable to find "
209  << hitnodename << std::endl;
210  }
211 }