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