File indexing completed on 2025-08-05 08:18:14
0001 #include "PHG4MvtxSteppingAction.h"
0002
0003 #include "PHG4MvtxDetector.h"
0004
0005 #include <g4main/PHG4Hit.h>
0006 #include <g4main/PHG4HitContainer.h>
0007 #include <g4main/PHG4Hitv1.h>
0008 #include <g4main/PHG4Shower.h>
0009 #include <g4main/PHG4SteppingAction.h> // for PHG4SteppingAction
0010 #include <g4main/PHG4TrackUserInfoV1.h>
0011
0012 #include <phparameter/PHParameters.h>
0013 #include <phparameter/PHParametersContainer.h>
0014
0015 #include <phool/getClass.h>
0016 #include <phool/phool.h> // for PHWHERE
0017
0018 #include <TSystem.h>
0019
0020 #include <Geant4/G4NavigationHistory.hh>
0021 #include <Geant4/G4ParticleDefinition.hh> // for G4ParticleDefinition
0022 #include <Geant4/G4ReferenceCountedHandle.hh> // for G4ReferenceCountedHandle
0023 #include <Geant4/G4Step.hh>
0024 #include <Geant4/G4StepPoint.hh> // for G4StepPoint
0025 #include <Geant4/G4StepStatus.hh> // for fGeomBoundary, fAtRest...
0026 #include <Geant4/G4String.hh> // for G4String
0027 #include <Geant4/G4SystemOfUnits.hh>
0028 #include <Geant4/G4ThreeVector.hh> // for G4ThreeVector
0029 #include <Geant4/G4TouchableHandle.hh> // for G4TouchableHandle
0030 #include <Geant4/G4Track.hh> // for G4Track
0031 #include <Geant4/G4TrackStatus.hh> // for fStopAndKill
0032 #include <Geant4/G4Types.hh> // for G4double
0033 #include <Geant4/G4VPhysicalVolume.hh> // for G4VPhysicalVolume
0034 #include <Geant4/G4VTouchable.hh> // for G4VTouchable
0035 #include <Geant4/G4VUserTrackInformation.hh> // for G4VUserTrackInformation
0036
0037 #include <boost/tokenizer.hpp>
0038
0039
0040
0041 #include <boost/version.hpp> // to get BOOST_VERSION
0042 #if (__GNUC__ == 4 && __GNUC_MINOR__ == 4 && BOOST_VERSION == 105700)
0043 #pragma GCC diagnostic ignored "-Wuninitialized"
0044 #pragma message "ignoring bogus gcc warning in boost header lexical_cast.hpp"
0045 #include <boost/lexical_cast.hpp>
0046 #pragma GCC diagnostic warning "-Wuninitialized"
0047 #else
0048 #include <boost/lexical_cast.hpp>
0049 #endif
0050
0051 #include <cstdlib> // for exit
0052 #include <iostream>
0053 #include <string> // for operator<<, basic_string
0054
0055 class PHCompositeNode;
0056
0057
0058 PHG4MvtxSteppingAction::PHG4MvtxSteppingAction(PHG4MvtxDetector* detector, PHParametersContainer* paramscont)
0059 : PHG4SteppingAction(detector->GetName())
0060 , m_Detector(detector)
0061 {
0062 PHParametersContainer::ConstRange begin_end = paramscont->GetAllParameters();
0063
0064 for (auto iter = begin_end.first; iter != begin_end.second; ++iter)
0065 {
0066 if (iter->first >= 0)
0067 {
0068 const PHParameters* params = paramscont->GetParameters(iter->first);
0069 if (params->get_int_param("supportactive"))
0070 {
0071 m_SupportActiveFlag = 1;
0072 }
0073 if (params->get_int_param("blackhole"))
0074 {
0075 m_BlackHoleFlag = 1;
0076 }
0077 }
0078 }
0079 }
0080
0081
0082 PHG4MvtxSteppingAction::~PHG4MvtxSteppingAction()
0083 {
0084
0085
0086
0087
0088 delete m_Hit;
0089 }
0090
0091
0092 bool PHG4MvtxSteppingAction::UserSteppingAction(const G4Step* aStep, bool )
0093 {
0094 G4TouchableHandle touch = aStep->GetPreStepPoint()->GetTouchableHandle();
0095
0096 G4VPhysicalVolume* sensor_volume = touch->GetVolume();
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109 int whichactive = m_Detector->IsSensor(sensor_volume);
0110
0111 if (!whichactive)
0112 {
0113 return false;
0114 }
0115
0116
0117
0118
0119
0120
0121
0122 int layer_id = -9999;
0123 int stave_id = -9999;
0124
0125 int half_stave_number = -1;
0126 int module_number = -1;
0127 int chip_number = -1;
0128 if (whichactive < 0)
0129 {
0130 layer_id = 0;
0131 }
0132 if (whichactive > 0)
0133 {
0134
0135 G4VPhysicalVolume* vstave = touch->GetVolume(3);
0136 int whichlayer = m_Detector->IsInMvtx(vstave, layer_id, stave_id);
0137 if (layer_id < 0 || stave_id < 0)
0138 {
0139 std::cout << PHWHERE << "invalid Mvtx's layer (" << layer_id << ") or stave (" << stave_id << ") index " << std::endl;
0140 exit(1);
0141 }
0142
0143 if (!whichlayer)
0144 {
0145 return false;
0146 }
0147
0148 if (Verbosity() > 5)
0149 {
0150
0151 G4VPhysicalVolume* vtest = touch->GetVolume();
0152 std::cout << "Entering PHG4MvtxSteppingAction::UserSteppingAction for volume " << vtest->GetName() << std::endl;
0153 G4VPhysicalVolume* vtest1 = touch->GetVolume(1);
0154 std::cout << "Entering PHG4MvtxSteppingAction::UserSteppingAction for volume 1 up " << vtest1->GetName() << std::endl;
0155 G4VPhysicalVolume* vtest2 = touch->GetVolume(2);
0156 std::cout << "Entering PHG4MvtxSteppingAction::UserSteppingAction for volume 2 up " << vtest2->GetName() << std::endl;
0157 G4VPhysicalVolume* vtest3 = touch->GetVolume(3);
0158 std::cout << "Entering PHG4MvtxSteppingAction::UserSteppingAction for volume 3 up " << vtest3->GetName() << std::endl;
0159 G4VPhysicalVolume* vtest4 = touch->GetVolume(4);
0160 std::cout << "Entering PHG4MvtxSteppingAction::UserSteppingAction for volume 4 up " << vtest4->GetName() << std::endl;
0161 }
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173 if (Verbosity() > 0)
0174 {
0175 std::cout << std::endl
0176 << " UserSteppingAction: layer " << layer_id;
0177 }
0178 boost::char_separator<char> sep("_");
0179 boost::tokenizer<boost::char_separator<char> >::const_iterator tokeniter;
0180
0181
0182
0183 G4VPhysicalVolume* v1 = touch->GetVolume(1);
0184 boost::tokenizer<boost::char_separator<char> > tok1(v1->GetName(), sep);
0185 tokeniter = tok1.begin();
0186 ++tokeniter;
0187 chip_number = boost::lexical_cast<int>(*tokeniter);
0188 if (Verbosity() > 0)
0189 {
0190 std::cout << " chip " << chip_number;
0191 }
0192 G4VPhysicalVolume* v2 = touch->GetVolume(2);
0193 boost::tokenizer<boost::char_separator<char> > tok2(v2->GetName(), sep);
0194 tokeniter = tok2.begin();
0195 ++tokeniter;
0196 module_number = boost::lexical_cast<int>(*tokeniter);
0197 if (Verbosity() > 0)
0198 {
0199 std::cout << " module " << module_number;
0200 }
0201
0202
0203
0204
0205
0206
0207
0208 G4VPhysicalVolume* v3 = touch->GetVolume(3);
0209 boost::tokenizer<boost::char_separator<char> > tok3(v3->GetName(), sep);
0210 tokeniter = tok3.begin();
0211 ++tokeniter;
0212 ++tokeniter;
0213 ++tokeniter;
0214
0215 if (Verbosity() > 0)
0216 {
0217 std::cout << " stave " << stave_id;
0218 }
0219 ++tokeniter;
0220 ++tokeniter;
0221 ++tokeniter;
0222 half_stave_number = boost::lexical_cast<int>(*tokeniter);
0223 if (Verbosity() > 0)
0224 {
0225 std::cout << " half_stave " << half_stave_number;
0226 }
0227 }
0228
0229
0230
0231
0232
0233
0234 G4double edep = aStep->GetTotalEnergyDeposit() / GeV;
0235 const G4Track* aTrack = aStep->GetTrack();
0236 if (Verbosity() > 0)
0237 {
0238 std::cout << " edep = " << edep << std::endl;
0239 }
0240
0241
0242 if (m_Detector->IsBlackHole(layer_id))
0243 {
0244 edep = aTrack->GetKineticEnergy() / GeV;
0245 G4Track* killtrack = const_cast<G4Track*>(aTrack);
0246 killtrack->SetTrackStatus(fStopAndKill);
0247 }
0248
0249 if (whichactive < 0 && !m_SupportActiveFlag)
0250 {
0251 return false;
0252 }
0253
0254 if (m_Detector->IsActive(layer_id))
0255 {
0256 bool geantino = false;
0257
0258
0259
0260 if (aTrack->GetParticleDefinition()->GetPDGEncoding() == 0 &&
0261 aTrack->GetParticleDefinition()->GetParticleName().find("geantino") != std::string::npos)
0262 {
0263 geantino = true;
0264 }
0265
0266 G4ThreeVector worldPosition;
0267 G4TouchableHandle theTouchable;
0268
0269 G4StepPoint* prePoint = aStep->GetPreStepPoint();
0270 G4StepPoint* postPoint = aStep->GetPostStepPoint();
0271
0272 if (Verbosity() > 0)
0273 {
0274 G4ParticleDefinition* def = aTrack->GetDefinition();
0275 std::cout << " Particle: " << def->GetParticleName() << std::endl;
0276 }
0277
0278 switch (prePoint->GetStepStatus())
0279 {
0280 case fGeomBoundary:
0281 case fUndefined:
0282 if (!m_Hit)
0283 {
0284 m_Hit = new PHG4Hitv1();
0285 }
0286 m_Hit->set_layer((unsigned int) layer_id);
0287 if (whichactive > 0)
0288 {
0289
0290 m_Hit->set_property(PHG4Hit::prop_stave_index, stave_id);
0291 m_Hit->set_property(PHG4Hit::prop_half_stave_index, half_stave_number);
0292 m_Hit->set_property(PHG4Hit::prop_module_index, module_number);
0293 m_Hit->set_property(PHG4Hit::prop_chip_index, chip_number);
0294
0295 worldPosition = prePoint->GetPosition();
0296
0297 if (Verbosity() > 0)
0298 {
0299 theTouchable = prePoint->GetTouchableHandle();
0300 std::cout << "entering: depth = " << theTouchable->GetHistory()->GetDepth() << std::endl;
0301 G4VPhysicalVolume* vol1 = theTouchable->GetVolume();
0302 std::cout << "entering volume name = " << vol1->GetName() << std::endl;
0303 }
0304
0305
0306
0307
0308
0309
0310 StoreLocalCoordinate(m_Hit, aStep, true, false);
0311 m_SaveHitContainer = m_HitContainer;
0312 }
0313 else
0314 {
0315 std::cout << "adding support hit" << std::endl;
0316 m_SaveHitContainer = m_SupportHitContainer;
0317 }
0318
0319 m_Hit->set_x(0, prePoint->GetPosition().x() / cm);
0320 m_Hit->set_y(0, prePoint->GetPosition().y() / cm);
0321 m_Hit->set_z(0, prePoint->GetPosition().z() / cm);
0322
0323 m_Hit->set_px(0, prePoint->GetMomentum().x() / GeV);
0324 m_Hit->set_py(0, prePoint->GetMomentum().y() / GeV);
0325 m_Hit->set_pz(0, prePoint->GetMomentum().z() / GeV);
0326
0327
0328 m_Hit->set_t(0, prePoint->GetGlobalTime() / nanosecond);
0329
0330 m_Hit->set_trkid(aTrack->GetTrackID());
0331 if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
0332 {
0333 if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
0334 {
0335 m_Hit->set_trkid(pp->GetUserTrackId());
0336 m_Hit->set_shower_id(pp->GetShower()->get_id());
0337 m_SaveShower = pp->GetShower();
0338 }
0339 }
0340
0341 m_Hit->set_edep(0);
0342
0343
0344
0345
0346 break;
0347 default:
0348 break;
0349 }
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388 if (whichactive > 0)
0389 {
0390
0391 StoreLocalCoordinate(m_Hit, aStep, false, true);
0392 }
0393
0394
0395 m_Hit->set_x(1, postPoint->GetPosition().x() / cm);
0396 m_Hit->set_y(1, postPoint->GetPosition().y() / cm);
0397 m_Hit->set_z(1, postPoint->GetPosition().z() / cm);
0398
0399 m_Hit->set_px(1, postPoint->GetMomentum().x() / GeV);
0400 m_Hit->set_py(1, postPoint->GetMomentum().y() / GeV);
0401 m_Hit->set_pz(1, postPoint->GetMomentum().z() / GeV);
0402
0403 m_Hit->set_t(1, postPoint->GetGlobalTime() / nanosecond);
0404
0405 m_Hit->set_edep(m_Hit->get_edep() + edep);
0406 if (geantino)
0407 {
0408 m_Hit->set_edep(-1);
0409 }
0410 if (edep > 0)
0411 {
0412 if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
0413 {
0414 if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
0415 {
0416 pp->SetKeep(1);
0417 }
0418 }
0419 }
0420
0421 if (Verbosity() > 0)
0422 {
0423 G4StepPoint* prePointA = aStep->GetPreStepPoint();
0424 G4StepPoint* postPointA = aStep->GetPostStepPoint();
0425 std::cout << "----- PHg4MvtxSteppingAction::UserSteppingAction - active volume = " << sensor_volume->GetName() << std::endl;
0426 std::cout << " layer = " << layer_id << std::endl;
0427 std::cout << " stave number = " << stave_id << " half_stave_number = " << half_stave_number << std::endl;
0428 std::cout << " module number = " << module_number << std::endl;
0429 std::cout << " chip number = " << chip_number << std::endl;
0430 std::cout << " prepoint x position " << prePointA->GetPosition().x() / cm << std::endl;
0431 std::cout << " prepoint y position " << prePointA->GetPosition().y() / cm << std::endl;
0432 std::cout << " prepoint z position " << prePointA->GetPosition().z() / cm << std::endl;
0433 std::cout << " postpoint x position " << postPointA->GetPosition().x() / cm << std::endl;
0434 std::cout << " postpoint y position " << postPointA->GetPosition().y() / cm << std::endl;
0435 std::cout << " postpoint z position " << postPointA->GetPosition().z() / cm << std::endl;
0436 std::cout << " edep " << edep << std::endl;
0437 }
0438
0439 if (Verbosity() > 0)
0440 {
0441 std::cout << " stepping action found hit:" << std::endl;
0442 m_Hit->print();
0443 std::cout << std::endl
0444 << std::endl;
0445 }
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455 if (postPoint->GetStepStatus() == fGeomBoundary ||
0456 postPoint->GetStepStatus() == fWorldBoundary ||
0457 postPoint->GetStepStatus() == fAtRestDoItProc ||
0458 aTrack->GetTrackStatus() == fStopAndKill)
0459 {
0460
0461 if (m_Hit->get_edep())
0462 {
0463 m_SaveHitContainer->AddHit(layer_id, m_Hit);
0464 if (m_SaveShower)
0465 {
0466 m_SaveShower->add_g4hit_id(m_HitContainer->GetID(), m_Hit->get_hit_id());
0467 }
0468
0469
0470 m_Hit = nullptr;
0471 }
0472 else
0473 {
0474
0475
0476
0477 m_Hit->Reset();
0478 }
0479 }
0480
0481
0482 return true;
0483 }
0484 else
0485 {
0486 return false;
0487 }
0488
0489 return false;
0490 }
0491
0492
0493 void PHG4MvtxSteppingAction::SetInterfacePointers(PHCompositeNode* topNode)
0494 {
0495 m_HitContainer = findNode::getClass<PHG4HitContainer>(topNode, m_HitNodeName);
0496 m_SupportHitContainer = findNode::getClass<PHG4HitContainer>(topNode, m_SupportNodeName);
0497
0498
0499 if (!m_HitContainer)
0500 {
0501 if (!m_BlackHoleFlag)
0502 {
0503 std::cout << "PHG4MvtxSteppingAction::SetTopNode - unable to find " << m_HitNodeName << std::endl;
0504 gSystem->Exit(1);
0505 }
0506 }
0507 if (!m_SupportHitContainer)
0508 {
0509 if (Verbosity() > 0)
0510 {
0511 std::cout << "PHG4MvtxSteppingAction::SetTopNode - unable to find " << m_SupportNodeName << std::endl;
0512 }
0513 }
0514 }
0515
0516 void PHG4MvtxSteppingAction::SetHitNodeName(const std::string& type, const std::string& name)
0517 {
0518 if (type == "G4HIT")
0519 {
0520 m_HitNodeName = name;
0521 return;
0522 }
0523 else if (type == "G4HIT_SUPPORT")
0524 {
0525 m_SupportNodeName = name;
0526 return;
0527 }
0528 std::cout << "Invalid output hit node type " << type << std::endl;
0529 gSystem->Exit(1);
0530 return;
0531 }