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