File indexing completed on 2025-08-06 08:19:18
0001 #include "PHG4InttSteppingAction.h"
0002 #include "PHG4InttDefs.h"
0003 #include "PHG4InttDetector.h"
0004
0005 #include <phparameter/PHParameters.h>
0006 #include <phparameter/PHParametersContainer.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, fAtRes...
0024 #include <Geant4/G4String.hh> // for G4String
0025 #include <Geant4/G4SystemOfUnits.hh>
0026 #include <Geant4/G4ThreeVector.hh>
0027 #include <Geant4/G4TouchableHandle.hh>
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 <cassert> // for assert
0036 #include <iostream>
0037 #include <set> // for set
0038 #include <string> // for operator<<, string
0039 #include <tuple> // for tie, tuple
0040
0041 class PHCompositeNode;
0042
0043
0044 PHG4InttSteppingAction::PHG4InttSteppingAction(PHG4InttDetector* detector, const PHParametersContainer* parameters, const std::pair<std::vector<std::pair<int, int>>::const_iterator, std::vector<std::pair<int, int>>::const_iterator>& layer_begin_end)
0045 : PHG4SteppingAction(detector->GetName())
0046 , m_Detector(detector)
0047 , m_ParamsContainer(parameters)
0048 {
0049
0050 for (auto layeriter = layer_begin_end.first; layeriter != layer_begin_end.second; ++layeriter)
0051 {
0052 int layer = layeriter->second;
0053 const PHParameters* par = m_ParamsContainer->GetParameters(layer);
0054 m_IsActiveMap[layer] = par->get_int_param("active");
0055 m_IsBlackHoleMap[layer] = par->get_int_param("blackhole");
0056 m_LadderTypeMap.insert(std::make_pair(layer, par->get_int_param("laddertype")));
0057 m_InttToTrackerLayerMap.insert(std::make_pair(layeriter->second, layeriter->first));
0058 }
0059
0060
0061 for (int iter : PHG4InttDefs::m_SensorSegmentationSet)
0062 {
0063 const PHParameters* par = m_ParamsContainer->GetParameters(iter);
0064 m_StripYMap.insert(std::make_pair(iter, par->get_double_param("strip_y") * cm));
0065 m_StripZMap.insert(std::make_pair(iter, std::make_pair(par->get_double_param("strip_z_0") * cm, par->get_double_param("strip_z_1") * cm)));
0066 m_nStripsPhiCell.insert(std::make_pair(iter, par->get_int_param("nstrips_phi_cell")));
0067 m_nStripsZSensor.insert(std::make_pair(iter, std::make_pair(par->get_int_param("nstrips_z_sensor_0"), par->get_int_param("nstrips_z_sensor_1"))));
0068 }
0069 }
0070
0071 PHG4InttSteppingAction::~PHG4InttSteppingAction()
0072 {
0073
0074
0075
0076
0077 delete m_Hit;
0078 }
0079
0080
0081 bool PHG4InttSteppingAction::UserSteppingAction(const G4Step* aStep, bool )
0082 {
0083 G4TouchableHandle touch = aStep->GetPreStepPoint()->GetTouchableHandle();
0084
0085 G4VPhysicalVolume* volume = touch->GetVolume();
0086 const G4Track* aTrack = aStep->GetTrack();
0087 G4StepPoint* prePoint = aStep->GetPreStepPoint();
0088 G4StepPoint* postPoint = aStep->GetPostStepPoint();
0089
0090 const int whichactive = m_Detector->IsInIntt(volume);
0091
0092 if (!whichactive)
0093 {
0094 return false;
0095 }
0096
0097 if (Verbosity() > 0)
0098 {
0099 std::cout << std::endl
0100 << "PHG4SilicoTrackerSteppingAction::UserSteppingAction for volume name (pre) " << touch->GetVolume()->GetName()
0101 << " volume name (1) " << touch->GetVolume(1)->GetName()
0102 << " volume->GetTranslation " << touch->GetVolume()->GetTranslation()
0103 << std::endl;
0104 }
0105
0106
0107 int sphxlayer = 0;
0108 int inttlayer = 0;
0109 int ladderz = 0;
0110 int ladderphi = 0;
0111 int zposneg = 0;
0112
0113 if (whichactive > 0)
0114 {
0115
0116
0117
0118 auto iter = m_Detector->get_ActiveVolumeTuple(touch->GetVolume(1));
0119 std::tie(inttlayer, ladderz, ladderphi, zposneg) = iter->second;
0120 if (Verbosity() > 0)
0121 {
0122 std::cout << " inttlayer " << inttlayer << " ladderz_base " << ladderz << " ladderphi " << ladderphi << " zposneg " << zposneg << std::endl;
0123 }
0124 if (inttlayer < 0 || inttlayer > 7)
0125 {
0126 assert(!"PHG4InttSteppingAction: check Intt ladder layer.");
0127 }
0128 sphxlayer = m_InttToTrackerLayerMap.find(inttlayer)->second;
0129 std::map<int, int>::const_iterator activeiter = m_IsActiveMap.find(inttlayer);
0130 if (activeiter == m_IsActiveMap.end())
0131 {
0132 std::cout << "PHG4InttSteppingAction: could not find active flag for layer " << inttlayer << std::endl;
0133 gSystem->Exit(1);
0134 }
0135 if (activeiter->second == 0)
0136 {
0137 return false;
0138 }
0139 }
0140 else
0141 {
0142 auto iter = m_Detector->get_PassiveVolumeTuple(touch->GetVolume(0)->GetLogicalVolume());
0143 std::tie(inttlayer, ladderz) = iter->second;
0144 sphxlayer = inttlayer;
0145 }
0146
0147
0148 G4double edep = aStep->GetTotalEnergyDeposit() / GeV;
0149 G4double eion = (aStep->GetTotalEnergyDeposit() - aStep->GetNonIonizingEnergyDeposit()) / GeV;
0150
0151
0152 if ((m_IsBlackHoleMap.find(inttlayer))->second == 1)
0153 {
0154 edep = aTrack->GetKineticEnergy() / GeV;
0155 G4Track* killtrack = const_cast<G4Track*>(aTrack);
0156 killtrack->SetTrackStatus(fStopAndKill);
0157 }
0158
0159 bool geantino = false;
0160
0161
0162
0163
0164 if (aTrack->GetParticleDefinition()->GetPDGEncoding() == 0 && aTrack->GetParticleDefinition()->GetParticleName().find("geantino") != std::string::npos)
0165 {
0166 geantino = true;
0167 }
0168
0169 if (Verbosity() > 1)
0170 {
0171 std::cout << " aTrack->GetTrackID " << aTrack->GetTrackID() << " aTrack->GetParentID " << aTrack->GetParentID()
0172 << " Intt layer " << inttlayer
0173 << " prePoint step status = " << prePoint->GetStepStatus() << " postPoint step status = " << postPoint->GetStepStatus()
0174 << std::endl;
0175 }
0176 switch (prePoint->GetStepStatus())
0177 {
0178 case fGeomBoundary:
0179 case fUndefined:
0180
0181 if (Verbosity() > 1)
0182 {
0183 std::cout << " start new g4hit for: aTrack->GetParentID " << aTrack->GetParentID() << " aTrack->GetTrackID " << aTrack->GetTrackID() << " Intt layer " << inttlayer
0184 << " prePoint step status = " << prePoint->GetStepStatus() << " postPoint->GetStepStatus = " << postPoint->GetStepStatus() << std::endl;
0185 }
0186
0187
0188 if (!m_Hit)
0189 {
0190 m_Hit = new PHG4Hitv1();
0191 }
0192
0193
0194 if (zposneg == 1)
0195 {
0196 ladderz += 2;
0197 }
0198 if (Verbosity() > 0)
0199 {
0200 std::cout << " ladderz = " << ladderz << std::endl;
0201 }
0202
0203 m_Hit->set_ladder_z_index(ladderz);
0204
0205 if (whichactive > 0)
0206 {
0207 m_Hit->set_layer(sphxlayer);
0208 m_Hit->set_ladder_phi_index(ladderphi);
0209 m_Hit->set_px(0, prePoint->GetMomentum().x() / GeV);
0210 m_Hit->set_py(0, prePoint->GetMomentum().y() / GeV);
0211 m_Hit->set_pz(0, prePoint->GetMomentum().z() / GeV);
0212 m_Hit->set_eion(0);
0213 }
0214
0215
0216 m_Hit->set_x(0, prePoint->GetPosition().x() / cm);
0217 m_Hit->set_y(0, prePoint->GetPosition().y() / cm);
0218 m_Hit->set_z(0, prePoint->GetPosition().z() / cm);
0219
0220 StoreLocalCoordinate(m_Hit, aStep, true, false);
0221
0222 if (Verbosity() > 0)
0223 {
0224 std::cout << " prePoint hit position x,y,z = " << prePoint->GetPosition().x() / cm
0225 << " " << prePoint->GetPosition().y() / cm
0226 << " " << prePoint->GetPosition().z() / cm
0227 << std::endl;
0228 }
0229
0230
0231 m_Hit->set_t(0, prePoint->GetGlobalTime() / nanosecond);
0232
0233
0234 m_Hit->set_trkid(aTrack->GetTrackID());
0235
0236
0237 m_Hit->set_edep(0);
0238
0239 if (whichactive > 0)
0240 {
0241
0242 m_SaveHitContainer = m_HitContainer;
0243 }
0244 else
0245 {
0246 m_SaveHitContainer = m_AbsorberHitContainer;
0247 }
0248
0249 if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
0250 {
0251 if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
0252 {
0253 m_Hit->set_trkid(pp->GetUserTrackId());
0254 m_Hit->set_shower_id(pp->GetShower()->get_id());
0255 m_SaveShower = pp->GetShower();
0256 }
0257 }
0258 break;
0259
0260 default:
0261 break;
0262 }
0263
0264
0265
0266
0267
0268
0269 m_Hit->set_x(1, postPoint->GetPosition().x() / cm);
0270 m_Hit->set_y(1, postPoint->GetPosition().y() / cm);
0271 m_Hit->set_z(1, postPoint->GetPosition().z() / cm);
0272
0273 StoreLocalCoordinate(m_Hit, aStep, false, true);
0274
0275 if (whichactive > 0)
0276 {
0277 m_Hit->set_px(1, postPoint->GetMomentum().x() / GeV);
0278 m_Hit->set_py(1, postPoint->GetMomentum().y() / GeV);
0279 m_Hit->set_pz(1, postPoint->GetMomentum().z() / GeV);
0280 m_Hit->set_eion(m_Hit->get_eion() + eion);
0281 }
0282
0283 m_Hit->set_t(1, postPoint->GetGlobalTime() / nanosecond);
0284
0285
0286 m_Hit->set_edep(m_Hit->get_edep() + edep);
0287
0288 if (geantino)
0289 {
0290 m_Hit->set_edep(-1);
0291 if (whichactive > 0)
0292 {
0293 m_Hit->set_eion(-1);
0294 }
0295 }
0296
0297 if (edep > 0)
0298 {
0299 if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
0300 {
0301 if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
0302 {
0303 pp->SetKeep(1);
0304 }
0305 }
0306 }
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316 if (postPoint->GetStepStatus() == fGeomBoundary ||
0317 postPoint->GetStepStatus() == fWorldBoundary ||
0318 postPoint->GetStepStatus() == fAtRestDoItProc ||
0319 aTrack->GetTrackStatus() == fStopAndKill)
0320 {
0321 if (Verbosity() > 0)
0322 {
0323 std::cout << " postPoint step status changed to " << postPoint->GetStepStatus() << " or aTrack status changed to "
0324 << aTrack->GetTrackStatus() << std::endl;
0325 std::cout << " end g4hit for: aTrack->GetParentID " << aTrack->GetParentID() << " aTrack->GetTrackID " << aTrack->GetTrackID() << " eion = " << eion << std::endl;
0326 std::cout << " end hit position x,y,z = " << postPoint->GetPosition().x() / cm
0327 << " " << postPoint->GetPosition().y() / cm
0328 << " " << postPoint->GetPosition().z() / cm
0329 << std::endl;
0330 }
0331
0332
0333 if (m_Hit->get_edep())
0334 {
0335 m_SaveHitContainer->AddHit(sphxlayer, m_Hit);
0336 if (m_SaveShower)
0337 {
0338 m_SaveShower->add_g4hit_id(m_SaveHitContainer->GetID(), m_Hit->get_hit_id());
0339 }
0340 if (Verbosity() > 0)
0341 {
0342 m_Hit->print();
0343 }
0344
0345
0346 m_Hit = nullptr;
0347 }
0348 else
0349 {
0350
0351
0352
0353 m_Hit->Reset();
0354 }
0355 }
0356 return true;
0357 }
0358
0359
0360 void PHG4InttSteppingAction::SetInterfacePointers(PHCompositeNode* topNode)
0361 {
0362 m_HitContainer = findNode::getClass<PHG4HitContainer>(topNode, m_HitNodeName);
0363 m_AbsorberHitContainer = findNode::getClass<PHG4HitContainer>(topNode, m_AbsorberNodeName);
0364
0365
0366 if (!m_HitContainer)
0367 {
0368 std::cout << "PHG4InttSteppingAction::SetTopNode - unable to find " << m_HitNodeName << std::endl;
0369 gSystem->Exit(1);
0370 }
0371
0372 if (!m_AbsorberHitContainer && Verbosity() > 1)
0373 {
0374 std::cout << "PHG4InttSteppingAction::SetTopNode - unable to find " << m_AbsorberNodeName << std::endl;
0375 }
0376 }
0377
0378 void PHG4InttSteppingAction::SetHitNodeName(const std::string& type, const std::string& name)
0379 {
0380 if (type == "G4HIT")
0381 {
0382 m_HitNodeName = name;
0383 return;
0384 }
0385 else if (type == "G4HIT_ABSORBER")
0386 {
0387 m_AbsorberNodeName = name;
0388 return;
0389 }
0390 std::cout << "Invalid output hit node type " << type << std::endl;
0391 gSystem->Exit(1);
0392 return;
0393 }