File indexing completed on 2025-08-05 08:18:18
0001 #include "PHG4TpcSteppingAction.h"
0002 #include "PHG4TpcDetector.h"
0003
0004 #include <g4detectors/PHG4StepStatusDecode.h>
0005
0006 #include <phparameter/PHParameters.h>
0007
0008 #include <g4main/PHG4Hit.h>
0009 #include <g4main/PHG4HitContainer.h>
0010 #include <g4main/PHG4Hitv1.h>
0011 #include <g4main/PHG4Shower.h>
0012 #include <g4main/PHG4SteppingAction.h> // for PHG4SteppingAction
0013
0014 #include <g4main/PHG4TrackUserInfoV1.h>
0015
0016 #include <phool/getClass.h>
0017
0018 #include <TSystem.h>
0019
0020 #include <Geant4/G4ParticleDefinition.hh>
0021 #include <Geant4/G4ReferenceCountedHandle.hh> // for G4ReferenceCountedHandle
0022 #include <Geant4/G4Step.hh>
0023 #include <Geant4/G4StepPoint.hh> // for G4StepPoint
0024 #include <Geant4/G4StepStatus.hh> // for fGeomBoundary, fPostSt...
0025 #include <Geant4/G4String.hh> // for G4String
0026 #include <Geant4/G4SystemOfUnits.hh>
0027 #include <Geant4/G4ThreeVector.hh> // for G4ThreeVector
0028 #include <Geant4/G4TouchableHandle.hh> // for G4TouchableHandle
0029 #include <Geant4/G4Track.hh> // for G4Track
0030 #include <Geant4/G4TrackStatus.hh> // for fStopAndKill
0031 #include <Geant4/G4Types.hh> // for G4double
0032 #include <Geant4/G4VPhysicalVolume.hh> // for G4VPhysicalVolume
0033 #include <Geant4/G4VTouchable.hh> // for G4VTouchable
0034 #include <Geant4/G4VUserTrackInformation.hh> // for G4VUserTrackInformation
0035
0036 #include <cmath> // for isfinite
0037 #include <cstdlib> // for exit
0038 #include <iostream>
0039 #include <string> // for operator<<, operator+
0040
0041 class PHCompositeNode;
0042
0043
0044 PHG4TpcSteppingAction::PHG4TpcSteppingAction(PHG4TpcDetector* detector, const PHParameters* parameters)
0045 : PHG4SteppingAction(detector->GetName())
0046 , m_Detector(detector)
0047 , m_Params(parameters)
0048 , m_IsBlackHoleFlag(m_Params->get_int_param("blackhole"))
0049 {
0050 if (std::isfinite(m_Params->get_double_param("steplimits")))
0051 {
0052 m_UseG4StepsFlag = 1;
0053 }
0054 SetName(m_Detector->GetName());
0055 }
0056
0057 PHG4TpcSteppingAction::~PHG4TpcSteppingAction()
0058 {
0059
0060
0061
0062
0063 delete m_Hit;
0064 }
0065
0066 bool PHG4TpcSteppingAction::UserSteppingAction(const G4Step* aStep, bool )
0067 {
0068 G4TouchableHandle touch = aStep->GetPreStepPoint()->GetTouchableHandle();
0069 G4TouchableHandle touchpost = aStep->GetPostStepPoint()->GetTouchableHandle();
0070
0071 G4VPhysicalVolume* volume = touch->GetVolume();
0072
0073
0074
0075
0076
0077
0078
0079 int whichactive = m_Detector->IsInTpc(volume);
0080 if (!whichactive)
0081 {
0082 return false;
0083 }
0084
0085 G4double edep = aStep->GetTotalEnergyDeposit() / GeV;
0086 G4double eion = (aStep->GetTotalEnergyDeposit() - aStep->GetNonIonizingEnergyDeposit()) / GeV;
0087 const G4Track* aTrack = aStep->GetTrack();
0088
0089
0090 if (m_IsBlackHoleFlag)
0091 {
0092 edep = aTrack->GetKineticEnergy() / GeV;
0093 G4Track* killtrack = const_cast<G4Track*>(aTrack);
0094 killtrack->SetTrackStatus(fStopAndKill);
0095 }
0096
0097 bool geantino = false;
0098
0099
0100
0101
0102 if (aTrack->GetParticleDefinition()->GetPDGEncoding() == 0 &&
0103 aTrack->GetParticleDefinition()->GetParticleName().find("geantino") != std::string::npos)
0104 {
0105 geantino = true;
0106 }
0107 G4StepPoint* prePoint = aStep->GetPreStepPoint();
0108 G4StepPoint* postPoint = aStep->GetPostStepPoint();
0109 int prepointstatus = prePoint->GetStepStatus();
0110
0111
0112
0113
0114
0115 if ((m_UseG4StepsFlag > 0 && whichactive > 0) ||
0116 prepointstatus == fGeomBoundary ||
0117 prepointstatus == fUndefined ||
0118 (prepointstatus == fPostStepDoItProc && m_SavePostStepStatus == fGeomBoundary))
0119 {
0120 unsigned int layer_id = 99;
0121
0122 if (prepointstatus == fPostStepDoItProc && m_SavePostStepStatus == fGeomBoundary)
0123 {
0124 std::cout << GetName() << ": New Hit for " << std::endl;
0125 std::cout << "prestep status: " << PHG4StepStatusDecode::GetStepStatus(prePoint->GetStepStatus())
0126 << ", poststep status: " << PHG4StepStatusDecode::GetStepStatus(postPoint->GetStepStatus())
0127 << ", last pre step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePreStepStatus)
0128 << ", last post step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePostStepStatus) << std::endl;
0129 std::cout << "last track: " << m_SaveTrackId
0130 << ", current trackid: " << aTrack->GetTrackID() << std::endl;
0131 std::cout << "phys pre vol: " << volume->GetName()
0132 << " post vol : " << touchpost->GetVolume()->GetName() << std::endl;
0133 std::cout << " previous phys pre vol: " << m_SaveVolPre->GetName()
0134 << " previous phys post vol: " << m_SaveVolPost->GetName() << std::endl;
0135 }
0136
0137
0138 if (!m_Hit)
0139 {
0140 m_Hit = new PHG4Hitv1();
0141 }
0142 m_Hit->set_layer(layer_id);
0143
0144 m_Hit->set_x(0, prePoint->GetPosition().x() / cm);
0145 m_Hit->set_y(0, prePoint->GetPosition().y() / cm);
0146 m_Hit->set_z(0, prePoint->GetPosition().z() / cm);
0147
0148
0149 m_Hit->set_px(0, prePoint->GetMomentum().x() / GeV);
0150 m_Hit->set_py(0, prePoint->GetMomentum().y() / GeV);
0151 m_Hit->set_pz(0, prePoint->GetMomentum().z() / GeV);
0152
0153
0154 m_Hit->set_t(0, prePoint->GetGlobalTime() / nanosecond);
0155
0156 m_Hit->set_trkid(aTrack->GetTrackID());
0157 m_SaveTrackId = aTrack->GetTrackID();
0158
0159 m_Hit->set_edep(0);
0160 if (whichactive > 0)
0161 {
0162 m_Hit->set_eion(0);
0163
0164 m_CurrentHitContainer = m_HitContainer;
0165 }
0166 else
0167 {
0168 m_CurrentHitContainer = m_AbsorberHitContainer;
0169 }
0170 if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
0171 {
0172 if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
0173 {
0174 m_Hit->set_trkid(pp->GetUserTrackId());
0175 m_Hit->set_shower_id(pp->GetShower()->get_id());
0176 m_Shower = pp->GetShower();
0177 }
0178 }
0179
0180
0181 if (!m_Hit || !std::isfinite(m_Hit->get_x(0)))
0182 {
0183 std::cout << GetName() << ": hit was not created" << std::endl;
0184 std::cout << "prestep status: " << PHG4StepStatusDecode::GetStepStatus(prePoint->GetStepStatus())
0185 << ", poststep status: " << PHG4StepStatusDecode::GetStepStatus(postPoint->GetStepStatus())
0186 << ", last pre step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePreStepStatus)
0187 << ", last post step status: " << PHG4StepStatusDecode::GetStepStatus(m_SavePostStepStatus) << std::endl;
0188 std::cout << "last track: " << m_SaveTrackId
0189 << ", current trackid: " << aTrack->GetTrackID() << std::endl;
0190 std::cout << "phys pre vol: " << volume->GetName()
0191 << " post vol : " << touchpost->GetVolume()->GetName() << std::endl;
0192 std::cout << " previous phys pre vol: " << m_SaveVolPre->GetName()
0193 << " previous phys post vol: " << m_SaveVolPost->GetName() << std::endl;
0194 exit(1);
0195 }
0196
0197 if (aTrack->GetTrackID() != m_SaveTrackId)
0198 {
0199 std::cout << GetName() << ": hits do not belong to the same track" << std::endl;
0200 std::cout << "saved track: " << m_SaveTrackId
0201 << ", current trackid: " << aTrack->GetTrackID()
0202 << ", prestep status: " << prePoint->GetStepStatus()
0203 << ", previous post step status: " << m_SavePostStepStatus
0204 << std::endl;
0205
0206 exit(1);
0207 }
0208 m_SavePreStepStatus = prePoint->GetStepStatus();
0209 m_SavePostStepStatus = postPoint->GetStepStatus();
0210 m_SaveVolPre = volume;
0211 m_SaveVolPost = touchpost->GetVolume();
0212
0213
0214
0215 m_Hit->set_x(1, postPoint->GetPosition().x() / cm);
0216 m_Hit->set_y(1, postPoint->GetPosition().y() / cm);
0217 m_Hit->set_z(1, postPoint->GetPosition().z() / cm);
0218
0219 m_Hit->set_px(1, postPoint->GetMomentum().x() / GeV);
0220 m_Hit->set_py(1, postPoint->GetMomentum().y() / GeV);
0221 m_Hit->set_pz(1, postPoint->GetMomentum().z() / GeV);
0222
0223 m_Hit->set_t(1, postPoint->GetGlobalTime() / nanosecond);
0224
0225
0226 m_Hit->set_edep(m_Hit->get_edep() + edep);
0227 if (whichactive > 0)
0228 {
0229 m_Hit->set_eion(m_Hit->get_eion() + eion);
0230 }
0231 if (geantino)
0232 {
0233 m_Hit->set_edep(-1);
0234 if (whichactive > 0)
0235 {
0236 m_Hit->set_eion(-1);
0237 }
0238 }
0239 if (edep > 0)
0240 {
0241 if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
0242 {
0243 if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
0244 {
0245 pp->SetKeep(1);
0246 }
0247 }
0248 }
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258 if ((m_UseG4StepsFlag > 0 && whichactive > 0) ||
0259 postPoint->GetStepStatus() == fGeomBoundary ||
0260 postPoint->GetStepStatus() == fWorldBoundary ||
0261 postPoint->GetStepStatus() == fAtRestDoItProc ||
0262 aTrack->GetTrackStatus() == fStopAndKill)
0263 {
0264
0265 if (m_Hit->get_edep())
0266 {
0267 m_CurrentHitContainer->AddHit(layer_id, m_Hit);
0268 if (m_Shower)
0269 {
0270 m_Shower->add_g4hit_id(m_CurrentHitContainer->GetID(), m_Hit->get_hit_id());
0271 }
0272
0273 double rin = sqrt((double) (m_Hit->get_x(0) * m_Hit->get_x(0) + m_Hit->get_y(0) * m_Hit->get_y(0)));
0274 double rout = sqrt((double) (m_Hit->get_x(1) * m_Hit->get_x(1) + m_Hit->get_y(1) * m_Hit->get_y(1)));
0275 if (Verbosity() > 10)
0276 {
0277 if ((rin > 69.0 && rin < 70.125) || (rout > 69.0 && rout < 70.125))
0278 {
0279 std::cout << "Added Tpc g4hit with rin, rout = " << rin << " " << rout
0280 << " g4hitid " << m_Hit->get_hit_id() << std::endl;
0281 std::cout << " xin " << m_Hit->get_x(0)
0282 << " yin " << m_Hit->get_y(0)
0283 << " zin " << m_Hit->get_z(0)
0284 << " rin " << rin
0285 << std::endl;
0286 std::cout << " xout " << m_Hit->get_x(1)
0287 << " yout " << m_Hit->get_y(1)
0288 << " zout " << m_Hit->get_z(1)
0289 << " rout " << rout
0290 << std::endl;
0291 std::cout << " xav " << (m_Hit->get_x(1) + m_Hit->get_x(0)) / 2.0
0292 << " yav " << (m_Hit->get_y(1) + m_Hit->get_y(0)) / 2.0
0293 << " zav " << (m_Hit->get_z(1) + m_Hit->get_z(0)) / 2.0
0294 << " rav " << (rout + rin) / 2.0
0295 << std::endl;
0296 }
0297 }
0298
0299
0300
0301 m_Hit = nullptr;
0302 }
0303 else
0304 {
0305
0306
0307
0308 m_Hit->Reset();
0309 }
0310 }
0311
0312 return true;
0313 }
0314 else
0315 {
0316 return false;
0317 }
0318 }
0319
0320
0321 void PHG4TpcSteppingAction::SetInterfacePointers(PHCompositeNode* topNode)
0322 {
0323 m_HitContainer = findNode::getClass<PHG4HitContainer>(topNode, m_HitNodeName);
0324 m_AbsorberHitContainer = findNode::getClass<PHG4HitContainer>(topNode, m_AbsorberNodeName);
0325
0326
0327 if (!m_HitContainer)
0328 {
0329 std::cout << "PHG4TpcSteppingAction::SetTopNode - unable to find " << m_HitNodeName << std::endl;
0330 }
0331 if (!m_AbsorberHitContainer)
0332 {
0333 if (Verbosity() > 1)
0334 {
0335 std::cout << "PHG4HcalSteppingAction::SetTopNode - unable to find " << m_AbsorberNodeName << std::endl;
0336 }
0337 }
0338 }
0339
0340 void PHG4TpcSteppingAction::SetHitNodeName(const std::string& type, const std::string& name)
0341 {
0342 if (type == "G4HIT")
0343 {
0344 m_HitNodeName = name;
0345 return;
0346 }
0347 else if (type == "G4HIT_ABSORBER")
0348 {
0349 m_AbsorberNodeName = name;
0350 return;
0351 }
0352 std::cout << "Invalid output hit node type " << type << std::endl;
0353 gSystem->Exit(1);
0354 return;
0355 }