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