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