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