File indexing completed on 2025-08-06 08:22:08
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "PHG4SpacalPrototypeSteppingAction.h"
0010 #include "PHG4SpacalPrototypeDetector.h"
0011 #include <g4detectors/PHG4CylinderGeom_Spacalv3.h>
0012
0013 #include <g4main/PHG4HitContainer.h>
0014 #include <g4main/PHG4Hit.h> // for PHG4Hit
0015 #include <g4main/PHG4Hitv1.h>
0016 #include <g4main/PHG4Shower.h>
0017 #include <g4main/PHG4SteppingAction.h> // for PHG4SteppingAction
0018 #include <g4main/PHG4TrackUserInfoV1.h>
0019
0020 #include <phool/getClass.h>
0021
0022 #include <Geant4/G4IonisParamMat.hh> // for G4IonisParamMat
0023 #include <Geant4/G4Material.hh> // for G4Material
0024 #include <Geant4/G4MaterialCutsCouple.hh>
0025 #include <Geant4/G4ParticleDefinition.hh> // for G4ParticleDefinition
0026 #include <Geant4/G4Step.hh>
0027 #include <Geant4/G4StepPoint.hh> // for G4StepPoint
0028 #include <Geant4/G4StepStatus.hh> // for fGeomBoundary, fUndefined
0029 #include <Geant4/G4String.hh> // for G4String
0030 #include <Geant4/G4SystemOfUnits.hh>
0031 #include <Geant4/G4ThreeVector.hh> // for G4ThreeVector
0032 #include <Geant4/G4TouchableHandle.hh> // for G4TouchableHandle
0033 #include <Geant4/G4Track.hh> // for G4Track
0034 #include <Geant4/G4TrackStatus.hh> // for fStopAndKill
0035 #include <Geant4/G4Types.hh> // for G4double
0036 #include <Geant4/G4VTouchable.hh> // for G4VTouchable
0037 #include <Geant4/G4VUserTrackInformation.hh> // for G4VUserTrackInformation
0038
0039 #include <iostream>
0040 #include <string> // for operator+, operator<<
0041
0042 class G4VPhysicalVolume;
0043 class PHCompositeNode;
0044
0045 using namespace std;
0046
0047 PHG4SpacalPrototypeSteppingAction::PHG4SpacalPrototypeSteppingAction(PHG4SpacalPrototypeDetector* detector) :
0048 PHG4SteppingAction(detector->GetName()),
0049 detector_(detector),
0050 hits_(nullptr),
0051 absorberhits_(nullptr),
0052 hit(nullptr),
0053 savehitcontainer(nullptr),
0054 saveshower(nullptr)
0055 {}
0056
0057
0058 bool
0059 PHG4SpacalPrototypeSteppingAction::UserSteppingAction(const G4Step* aStep, bool)
0060 {
0061
0062
0063 G4VPhysicalVolume* volume =
0064 aStep->GetPreStepPoint()->GetTouchableHandle()->GetVolume();
0065
0066
0067 G4double edep = aStep->GetTotalEnergyDeposit() / GeV;
0068 G4double eion = (aStep->GetTotalEnergyDeposit()
0069 - aStep->GetNonIonizingEnergyDeposit()) / GeV;
0070
0071 const G4Track* aTrack = aStep->GetTrack();
0072
0073 const int layer_id = 0;
0074
0075
0076
0077 int isactive = detector_->IsInCylinderActive(volume);
0078 if (isactive > PHG4SpacalPrototypeDetector::INACTIVE)
0079 {
0080 bool geantino = false;
0081
0082
0083
0084 if (aTrack->GetParticleDefinition()->GetPDGEncoding() == 0
0085 && aTrack->GetParticleDefinition()->GetParticleName().find("geantino")
0086 != string::npos)
0087 {
0088 geantino = true;
0089 }
0090 G4StepPoint * prePoint = aStep->GetPreStepPoint();
0091 G4StepPoint * postPoint = aStep->GetPostStepPoint();
0092 int scint_id = -1;
0093
0094 if (
0095 detector_->get_geom()->get_config() == PHG4SpacalPrototypeDetector::SpacalGeom_t::kFullProjective_2DTaper
0096 or
0097 detector_->get_geom()->get_config() == PHG4SpacalPrototypeDetector::SpacalGeom_t::kFullProjective_2DTaper_SameLengthFiberPerTower
0098 )
0099 {
0100
0101 int sector_ID =0;
0102 int tower_ID = 0;
0103 int fiber_ID = 0;
0104
0105 if (isactive == PHG4SpacalPrototypeDetector::FIBER_CORE)
0106 {
0107
0108 fiber_ID = prePoint->GetTouchable()->GetReplicaNumber(1);
0109 tower_ID = prePoint->GetTouchable()->GetReplicaNumber(2);
0110 sector_ID = prePoint->GetTouchable()->GetReplicaNumber(3);
0111
0112 }
0113
0114 else if (isactive == PHG4SpacalPrototypeDetector::FIBER_CLADING)
0115 {
0116 fiber_ID = prePoint->GetTouchable()->GetReplicaNumber(0);
0117 tower_ID = prePoint->GetTouchable()->GetReplicaNumber(1);
0118 sector_ID = prePoint->GetTouchable()->GetReplicaNumber(2);
0119 }
0120
0121 else if (isactive == PHG4SpacalPrototypeDetector::ABSORBER)
0122 {
0123 tower_ID = prePoint->GetTouchable()->GetReplicaNumber(0);
0124 sector_ID = prePoint->GetTouchable()->GetReplicaNumber(1);
0125 }
0126
0127
0128 scint_id = PHG4CylinderGeom_Spacalv3::scint_id_coder(sector_ID, tower_ID, fiber_ID).scint_ID;
0129
0130 }
0131 else
0132 {
0133
0134 if (isactive == PHG4SpacalPrototypeDetector::FIBER_CORE)
0135 {
0136 scint_id = prePoint->GetTouchable()->GetReplicaNumber(2);
0137 }
0138 else if (isactive == PHG4SpacalPrototypeDetector::FIBER_CLADING)
0139 {
0140 scint_id = prePoint->GetTouchable()->GetReplicaNumber(1);
0141 }
0142 else
0143 {
0144 scint_id = prePoint->GetTouchable()->GetReplicaNumber(0);
0145 }
0146 }
0147
0148
0149
0150
0151 switch (prePoint->GetStepStatus())
0152 {
0153 case fGeomBoundary:
0154 case fUndefined:
0155
0156
0157 if (! hit)
0158 {
0159 hit = new PHG4Hitv1();
0160 }
0161 hit->set_layer((unsigned int) layer_id);
0162 hit->set_scint_id(scint_id);
0163
0164 hit->set_x(0, prePoint->GetPosition().x() / cm);
0165 hit->set_y(0, prePoint->GetPosition().y() / cm);
0166 hit->set_z(0, prePoint->GetPosition().z() / cm);
0167
0168
0169 hit->set_t(0, prePoint->GetGlobalTime() / nanosecond);
0170
0171 if (isactive == PHG4SpacalPrototypeDetector::FIBER_CORE)
0172 {
0173
0174 StoreLocalCoordinate(hit, aStep, true, false);
0175 }
0176
0177
0178 hit->set_trkid(aTrack->GetTrackID());
0179 if ( G4VUserTrackInformation* p = aTrack->GetUserInformation() )
0180 {
0181 if ( PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p) )
0182 {
0183 hit->set_trkid(pp->GetUserTrackId());
0184 hit->set_shower_id(pp->GetShower()->get_id());
0185 }
0186 }
0187
0188 hit->set_edep(0);
0189 if (isactive == PHG4SpacalPrototypeDetector::FIBER_CORE)
0190 {
0191 hit->set_eion(0);
0192 hit->set_light_yield(0);
0193 savehitcontainer = hits_;
0194 }
0195 else
0196 {
0197 savehitcontainer = absorberhits_;
0198 }
0199
0200 if ( G4VUserTrackInformation* p = aTrack->GetUserInformation() )
0201 {
0202 if ( PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p) )
0203 {
0204 hit->set_trkid(pp->GetUserTrackId());
0205 hit->set_shower_id(pp->GetShower()->get_id());
0206 saveshower = pp->GetShower();
0207 }
0208 }
0209
0210
0211
0212
0213
0214
0215
0216 break;
0217 default:
0218 break;
0219 }
0220
0221
0222
0223 hit->set_x(1, postPoint->GetPosition().x() / cm);
0224 hit->set_y(1, postPoint->GetPosition().y() / cm);
0225 hit->set_z(1, postPoint->GetPosition().z() / cm);
0226
0227 hit->set_t(1, postPoint->GetGlobalTime() / nanosecond);
0228
0229
0230
0231 hit->set_edep(hit->get_edep() + edep);
0232
0233 if (isactive == PHG4SpacalPrototypeDetector::FIBER_CORE)
0234 {
0235
0236 StoreLocalCoordinate(hit, aStep, false, true);
0237 hit->set_eion(hit->get_eion() + eion);
0238
0239 double light_yield = GetVisibleEnergyDeposition(aStep);
0240
0241 static bool once = true;
0242 if (once and edep > 0)
0243 {
0244 once = false;
0245
0246 if (Verbosity() > 0) {
0247 cout << "PHG4SpacalPrototypeSteppingAction::UserSteppingAction::"
0248
0249 << detector_->GetName() << " - "
0250 << " use scintillating light model at each Geant4 steps. "
0251 << "First step: " << "Material = "
0252 << aTrack->GetMaterialCutsCouple()->GetMaterial()->GetName()
0253 << ", " << "Birk Constant = "
0254 << aTrack->GetMaterialCutsCouple()->GetMaterial()->GetIonisation()->GetBirksConstant()
0255 << "," << "edep = " << edep << ", " << "eion = " << eion
0256 << ", " << "light_yield = " << light_yield << endl;
0257 }
0258 }
0259
0260 hit->set_light_yield(hit->get_light_yield() + light_yield);
0261 }
0262
0263
0264
0265
0266
0267
0268
0269
0270 if (geantino)
0271 {
0272 hit->set_edep(-1);
0273
0274 }
0275 if (edep > 0)
0276 {
0277 if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
0278 {
0279 if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
0280 {
0281 pp->SetKeep(1);
0282 }
0283 }
0284 }
0285
0286
0287
0288
0289
0290
0291
0292 if (postPoint->GetStepStatus() == fGeomBoundary ||
0293 postPoint->GetStepStatus() == fWorldBoundary||
0294 aTrack->GetTrackStatus() == fStopAndKill)
0295 {
0296
0297 if (hit->get_edep())
0298 {
0299 savehitcontainer->AddHit(layer_id, hit);
0300 if (saveshower)
0301 {
0302
0303 saveshower->add_g4hit_id(savehitcontainer->GetID(),hit->get_hit_id());
0304 }
0305
0306
0307 hit = nullptr;
0308 }
0309 else
0310 {
0311
0312
0313
0314 hit->Reset();
0315 }
0316 }
0317
0318 return true;
0319
0320 }
0321 else
0322 {
0323 return false;
0324 }
0325 }
0326
0327
0328 void
0329 PHG4SpacalPrototypeSteppingAction::SetInterfacePointers(PHCompositeNode* topNode)
0330 {
0331
0332 string hitnodename;
0333 string absorbernodename;
0334 if (detector_->SuperDetector() != "NONE")
0335 {
0336 hitnodename = "G4HIT_" + detector_->SuperDetector();
0337 absorbernodename = "G4HIT_ABSORBER_" + detector_->SuperDetector();
0338 }
0339 else
0340 {
0341 hitnodename = "G4HIT_" + detector_->GetName();
0342 absorbernodename = "G4HIT_ABSORBER_" + detector_->GetName();
0343 }
0344
0345
0346 hits_ = findNode::getClass<PHG4HitContainer>(topNode, hitnodename.c_str());
0347 absorberhits_ = findNode::getClass<PHG4HitContainer>(topNode,
0348 absorbernodename.c_str());
0349
0350 if (!hits_)
0351 {
0352 std::cout << "PHG4SpacalPrototypeSteppingAction::SetTopNode - unable to find "
0353 << hitnodename << std::endl;
0354 }
0355 if (!absorberhits_)
0356 {
0357 if (Verbosity() > 1)
0358 {
0359 std::cout << "PHG4SpacalPrototypeSteppingAction::SetTopNode - unable to find "
0360 << absorbernodename << std::endl;
0361 }
0362 }
0363 }
0364
0365 double
0366 PHG4SpacalPrototypeSteppingAction::get_zmin()
0367 {
0368 if (!detector_)
0369 return 0;
0370 else
0371 return detector_->get_geom()->get_zmin() - .0001;
0372 }
0373
0374 double
0375 PHG4SpacalPrototypeSteppingAction::get_zmax()
0376 {
0377 if (!detector_)
0378 return 0;
0379 else
0380 return detector_->get_geom()->get_zmax() + .0001;
0381 }