File indexing completed on 2025-08-05 08:20:44
0001 #include "PHG4Prototype2InnerHcalSteppingAction.h"
0002
0003 #include "PHG4Prototype2InnerHcalDetector.h"
0004
0005 #include <phparameter/PHParameters.h>
0006
0007 #include <g4main/PHG4Hit.h>
0008 #include <g4main/PHG4HitContainer.h>
0009 #include <g4main/PHG4Hitv1.h>
0010 #include <g4main/PHG4Shower.h>
0011 #include <g4main/PHG4SteppingAction.h> // for PHG4SteppingAction
0012 #include <g4main/PHG4TrackUserInfoV1.h>
0013
0014 #include <phool/getClass.h>
0015
0016 #include <Geant4/G4ParticleDefinition.hh> // for G4ParticleDefinition
0017 #include <Geant4/G4ReferenceCountedHandle.hh> // for G4ReferenceCountedHandle
0018 #include <Geant4/G4Step.hh>
0019 #include <Geant4/G4StepPoint.hh> // for G4StepPoint
0020 #include <Geant4/G4StepStatus.hh> // for fGeomBoundary, fAtRest...
0021 #include <Geant4/G4String.hh> // for G4String
0022 #include <Geant4/G4SystemOfUnits.hh>
0023 #include <Geant4/G4ThreeVector.hh> // for G4ThreeVector
0024 #include <Geant4/G4TouchableHandle.hh> // for G4TouchableHandle
0025 #include <Geant4/G4Track.hh> // for G4Track
0026 #include <Geant4/G4TrackStatus.hh> // for fStopAndKill
0027 #include <Geant4/G4Types.hh> // for G4double
0028 #include <Geant4/G4VPhysicalVolume.hh> // for G4VPhysicalVolume
0029 #include <Geant4/G4VTouchable.hh> // for G4VTouchable
0030 #include <Geant4/G4VUserTrackInformation.hh> // for G4VUserTrackInformation
0031
0032 #include <cmath> // for isfinite, sqrt
0033 #include <iostream>
0034 #include <string> // for string, operator+, ope...
0035
0036 class PHCompositeNode;
0037
0038
0039 #ifdef TESTSINGLESLAT
0040 static const int nrow = 4;
0041 static const int nslat = 9;
0042 #endif
0043
0044 using namespace std;
0045
0046 PHG4Prototype2InnerHcalSteppingAction::PHG4Prototype2InnerHcalSteppingAction(PHG4Prototype2InnerHcalDetector* detector, const PHParameters* parameters)
0047 : PHG4SteppingAction(detector->GetName())
0048 , m_Detector(detector)
0049 , m_HitContainer(nullptr)
0050 , m_AbsorberHitContainer(nullptr)
0051 , m_Hit(nullptr)
0052 , m_Params(parameters)
0053 , m_SaveHitContainer(nullptr)
0054 , m_SaveShower(nullptr)
0055 , m_AbsorberTruthFlag(m_Params->get_int_param("absorbertruth"))
0056 , m_IsActiveFlag(m_Params->get_int_param("active"))
0057 , m_IsBlackHoleFlag(m_Params->get_int_param("blackhole"))
0058 , m_LightScintModelFlag(m_Params->get_int_param("light_scint_model"))
0059 , m_LightBalanceInnerCorr(m_Params->get_double_param("light_balance_inner_corr"))
0060 , m_LightBalanceInnerRadius(m_Params->get_double_param("light_balance_inner_radius") * cm)
0061 , m_LightBalanceOuterCorr(m_Params->get_double_param("light_balance_outer_corr"))
0062 , m_LightBalanceOuterRadius(m_Params->get_double_param("light_balance_outer_radius") * cm)
0063 {
0064 }
0065
0066 PHG4Prototype2InnerHcalSteppingAction::~PHG4Prototype2InnerHcalSteppingAction()
0067 {
0068
0069
0070
0071
0072 delete m_Hit;
0073 }
0074
0075
0076 bool PHG4Prototype2InnerHcalSteppingAction::UserSteppingAction(const G4Step* aStep, bool)
0077 {
0078 G4TouchableHandle touch = aStep->GetPreStepPoint()->GetTouchableHandle();
0079
0080 G4VPhysicalVolume* volume = touch->GetVolume();
0081
0082
0083
0084
0085
0086
0087
0088 int whichactive = m_Detector->IsInPrototype2InnerHcal(volume);
0089
0090 if (!whichactive)
0091 {
0092 return false;
0093 }
0094 int row_id = -1;
0095 int slat_id = -1;
0096 if (whichactive > 0)
0097 {
0098 slat_id = volume->GetCopyNo();
0099
0100 G4VPhysicalVolume* mothervolume = touch->GetVolume(1);
0101 row_id = m_Detector->get_scinti_row_id(mothervolume->GetName());
0102
0103
0104
0105 #ifdef TESTSINGLESLAT
0106 if (row_id != nrow)
0107 {
0108 return false;
0109 }
0110 if (slat_id != nslat)
0111 {
0112 return false;
0113 }
0114 #endif
0115 }
0116 else
0117 {
0118
0119 row_id = m_Detector->get_steel_plate_id(volume->GetName());
0120 #ifdef TESTSINGLESLAT
0121 return false;
0122 #endif
0123 }
0124
0125 G4double edep = aStep->GetTotalEnergyDeposit() / GeV;
0126 G4double eion = (aStep->GetTotalEnergyDeposit() - aStep->GetNonIonizingEnergyDeposit()) / GeV;
0127 G4double light_yield = 0;
0128 const G4Track* aTrack = aStep->GetTrack();
0129
0130
0131 if (m_IsBlackHoleFlag)
0132 {
0133 edep = aTrack->GetKineticEnergy() / GeV;
0134 G4Track* killtrack = const_cast<G4Track*>(aTrack);
0135 killtrack->SetTrackStatus(fStopAndKill);
0136 }
0137 int layer_id = m_Detector->get_Layer();
0138
0139 if (m_IsActiveFlag)
0140 {
0141 bool geantino = false;
0142
0143
0144
0145
0146 if (aTrack->GetParticleDefinition()->GetPDGEncoding() == 0 &&
0147 aTrack->GetParticleDefinition()->GetParticleName().find("geantino") != string::npos)
0148 {
0149 geantino = true;
0150 }
0151 G4StepPoint* prePoint = aStep->GetPreStepPoint();
0152 G4StepPoint* postPoint = aStep->GetPostStepPoint();
0153
0154
0155
0156 switch (prePoint->GetStepStatus())
0157 {
0158 case fGeomBoundary:
0159 case fUndefined:
0160 if (!m_Hit)
0161 {
0162 m_Hit = new PHG4Hitv1();
0163 }
0164 m_Hit->set_row(row_id);
0165 if (whichactive > 0)
0166 {
0167 m_Hit->set_scint_id(slat_id);
0168 }
0169
0170 m_Hit->set_x(0, prePoint->GetPosition().x() / cm);
0171 m_Hit->set_y(0, prePoint->GetPosition().y() / cm);
0172 m_Hit->set_z(0, prePoint->GetPosition().z() / cm);
0173
0174 m_Hit->set_t(0, prePoint->GetGlobalTime() / nanosecond);
0175
0176 m_Hit->set_trkid(aTrack->GetTrackID());
0177 if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
0178 {
0179 if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
0180 {
0181 m_Hit->set_trkid(pp->GetUserTrackId());
0182 m_Hit->set_shower_id(pp->GetShower()->get_id());
0183 }
0184 }
0185
0186
0187 m_Hit->set_edep(0);
0188
0189 m_Hit->set_hit_type(0);
0190 if ((aTrack->GetParticleDefinition()->GetParticleName().find("e+") != string::npos) ||
0191 (aTrack->GetParticleDefinition()->GetParticleName().find("e-") != string::npos))
0192 m_Hit->set_hit_type(1);
0193
0194 if (whichactive > 0)
0195 {
0196 m_SaveHitContainer = m_HitContainer;
0197 m_Hit->set_light_yield(0);
0198 m_Hit->set_eion(0);
0199 }
0200 else
0201 {
0202 m_SaveHitContainer = m_AbsorberHitContainer;
0203 }
0204
0205 if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
0206 {
0207 if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
0208 {
0209 m_Hit->set_trkid(pp->GetUserTrackId());
0210 m_Hit->set_shower_id(pp->GetShower()->get_id());
0211 m_SaveShower = pp->GetShower();
0212 }
0213 }
0214 break;
0215 default:
0216 break;
0217 }
0218
0219
0220
0221 m_Hit->set_x(1, postPoint->GetPosition().x() / cm);
0222 m_Hit->set_y(1, postPoint->GetPosition().y() / cm);
0223 m_Hit->set_z(1, postPoint->GetPosition().z() / cm);
0224
0225 m_Hit->set_t(1, postPoint->GetGlobalTime() / nanosecond);
0226
0227 if (whichactive > 0)
0228 {
0229 m_Hit->set_eion(m_Hit->get_eion() + eion);
0230 light_yield = eion;
0231 if (m_LightScintModelFlag)
0232 {
0233 light_yield = GetVisibleEnergyDeposition(aStep);
0234 }
0235 if (isfinite(m_LightBalanceOuterRadius) &&
0236 isfinite(m_LightBalanceInnerRadius) &&
0237 isfinite(m_LightBalanceOuterCorr) &&
0238 isfinite(m_LightBalanceInnerCorr))
0239 {
0240 double r = sqrt(postPoint->GetPosition().x() * postPoint->GetPosition().x() + postPoint->GetPosition().y() * postPoint->GetPosition().y());
0241 double cor = GetLightCorrection(r);
0242 light_yield = light_yield * cor;
0243 }
0244 m_Hit->set_light_yield(m_Hit->get_light_yield() + light_yield);
0245 }
0246
0247
0248 m_Hit->set_edep(m_Hit->get_edep() + edep);
0249 if (geantino)
0250 {
0251 m_Hit->set_edep(-1);
0252 if (whichactive > 0)
0253 {
0254 m_Hit->set_light_yield(-1);
0255 m_Hit->set_eion(-1);
0256 }
0257 }
0258 if (edep > 0 && (whichactive > 0 || m_AbsorberTruthFlag > 0))
0259 {
0260 if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
0261 {
0262 if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
0263 {
0264 pp->SetKeep(1);
0265 }
0266 }
0267 }
0268
0269
0270
0271
0272
0273
0274
0275
0276 if (postPoint->GetStepStatus() == fGeomBoundary ||
0277 postPoint->GetStepStatus() == fWorldBoundary ||
0278 postPoint->GetStepStatus() == fAtRestDoItProc ||
0279 aTrack->GetTrackStatus() == fStopAndKill)
0280 {
0281
0282 if (m_Hit->get_edep())
0283 {
0284 m_SaveHitContainer->AddHit(layer_id, m_Hit);
0285 if (m_SaveShower)
0286 {
0287 m_SaveShower->add_g4hit_id(m_SaveHitContainer->GetID(), m_Hit->get_hit_id());
0288 }
0289
0290
0291 m_Hit = nullptr;
0292 }
0293 else
0294 {
0295
0296
0297
0298 m_Hit->Reset();
0299 }
0300 }
0301
0302
0303
0304 return true;
0305 }
0306 else
0307 {
0308 return false;
0309 }
0310 }
0311
0312
0313 void PHG4Prototype2InnerHcalSteppingAction::SetInterfacePointers(PHCompositeNode* topNode)
0314 {
0315 string hitnodename;
0316 string absorbernodename;
0317 if (m_Detector->SuperDetector() != "NONE")
0318 {
0319 hitnodename = "G4HIT_" + m_Detector->SuperDetector();
0320 absorbernodename = "G4HIT_ABSORBER_" + m_Detector->SuperDetector();
0321 }
0322 else
0323 {
0324 hitnodename = "G4HIT_" + m_Detector->GetName();
0325 absorbernodename = "G4HIT_ABSORBER_" + m_Detector->GetName();
0326 }
0327
0328
0329 m_HitContainer = findNode::getClass<PHG4HitContainer>(topNode, hitnodename.c_str());
0330 m_AbsorberHitContainer = findNode::getClass<PHG4HitContainer>(topNode, absorbernodename.c_str());
0331
0332
0333 if (!m_HitContainer)
0334 {
0335 std::cout << "PHG4Prototype2InnerHcalSteppingAction::SetTopNode - unable to find " << hitnodename << std::endl;
0336 }
0337 if (!m_AbsorberHitContainer)
0338 {
0339 if (Verbosity() > 1)
0340 {
0341 cout << "PHG4HcalSteppingAction::SetTopNode - unable to find " << absorbernodename << endl;
0342 }
0343 }
0344 }
0345
0346 double
0347 PHG4Prototype2InnerHcalSteppingAction::GetLightCorrection(const double r) const
0348 {
0349 double m = (m_LightBalanceOuterCorr - m_LightBalanceInnerCorr) / (m_LightBalanceOuterRadius - m_LightBalanceInnerRadius);
0350 double b = m_LightBalanceInnerCorr - m * m_LightBalanceInnerRadius;
0351 double value = m * r + b;
0352 if (value > 1.0) return 1.0;
0353 if (value < 0.0) return 0.0;
0354
0355 return value;
0356 }