File indexing completed on 2026-06-15 07:53:54
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #include "SteppingAction.hh"
0030
0031 #include "HistoManager.hh"
0032 #include "Run.hh"
0033 #include "SteppingMessenger.hh"
0034 #include "TrackInformation.hh"
0035
0036 #include "G4Cerenkov.hh"
0037 #include "G4Event.hh"
0038 #include "G4EventManager.hh"
0039 #include "G4OpBoundaryProcess.hh"
0040 #include "G4OpticalPhoton.hh"
0041 #include "G4ProcessManager.hh"
0042 #include "G4RunManager.hh"
0043 #include "G4Scintillation.hh"
0044 #include "G4Step.hh"
0045 #include "G4SteppingManager.hh"
0046 #include "G4SystemOfUnits.hh"
0047 #include "G4Track.hh"
0048
0049
0050 SteppingAction::SteppingAction() : G4UserSteppingAction()
0051 {
0052 fSteppingMessenger = new SteppingMessenger(this);
0053 }
0054
0055
0056 SteppingAction::~SteppingAction()
0057 {
0058 delete fSteppingMessenger;
0059 }
0060
0061
0062 void SteppingAction::UserSteppingAction(const G4Step* step)
0063 {
0064 static G4ParticleDefinition* opticalphoton = G4OpticalPhoton::OpticalPhotonDefinition();
0065
0066 G4AnalysisManager* analysisMan = G4AnalysisManager::Instance();
0067 Run* run = static_cast<Run*>(G4RunManager::GetRunManager()->GetNonConstCurrentRun());
0068
0069 G4Track* track = step->GetTrack();
0070 G4StepPoint* endPoint = step->GetPostStepPoint();
0071 G4StepPoint* startPoint = step->GetPreStepPoint();
0072
0073 const G4DynamicParticle* theParticle = track->GetDynamicParticle();
0074 const G4ParticleDefinition* particleDef = theParticle->GetParticleDefinition();
0075
0076 auto trackInfo = (TrackInformation*)(track->GetUserInformation());
0077
0078 if (particleDef == opticalphoton) {
0079 const G4VProcess* pds = endPoint->GetProcessDefinedStep();
0080 G4String procname = pds->GetProcessName();
0081 if (procname == "OpAbsorption") {
0082 run->AddOpAbsorption();
0083 if (trackInfo->GetIsFirstTankX()) {
0084 run->AddOpAbsorptionPrior();
0085 }
0086 }
0087 else if (procname == "OpRayleigh") {
0088 run->AddRayleigh();
0089 }
0090 else if (procname == "OpWLS") {
0091 G4double en = track->GetKineticEnergy();
0092 run->AddWLSAbsorption();
0093 run->AddWLSAbsorptionEnergy(en);
0094 analysisMan->FillH1(4, en / eV);
0095
0096
0097 auto secondaries = step->GetSecondaryInCurrentStep();
0098 for (auto sec : *secondaries) {
0099 en = sec->GetKineticEnergy();
0100 run->AddWLSEmission();
0101 run->AddWLSEmissionEnergy(en);
0102 analysisMan->FillH1(5, en / eV);
0103 G4double time = sec->GetGlobalTime();
0104 analysisMan->FillH1(6, time / ns);
0105 }
0106 }
0107 else if (procname == "OpWLS2") {
0108 G4double en = track->GetKineticEnergy();
0109 run->AddWLS2Absorption();
0110 run->AddWLS2AbsorptionEnergy(en);
0111 analysisMan->FillH1(7, en / eV);
0112
0113
0114 auto secondaries = step->GetSecondaryInCurrentStep();
0115 for (auto sec : *secondaries) {
0116 en = sec->GetKineticEnergy();
0117 run->AddWLS2Emission();
0118 run->AddWLS2EmissionEnergy(en);
0119 analysisMan->FillH1(8, en / eV);
0120 G4double time = sec->GetGlobalTime();
0121 analysisMan->FillH1(9, time / ns);
0122 }
0123 }
0124
0125
0126 if (endPoint->GetStepStatus() == fGeomBoundary) {
0127 G4ThreeVector p0 = startPoint->GetMomentumDirection();
0128 G4ThreeVector p1 = endPoint->GetMomentumDirection();
0129
0130 G4OpBoundaryProcessStatus theStatus = Undefined;
0131
0132 G4ProcessManager* OpManager = opticalphoton->GetProcessManager();
0133 G4ProcessVector* postStepDoItVector = OpManager->GetPostStepProcessVector(typeDoIt);
0134 G4int n_proc = postStepDoItVector->entries();
0135
0136 if (trackInfo->GetIsFirstTankX()) {
0137 G4double px1 = p1.x();
0138 G4double py1 = p1.y();
0139 G4double pz1 = p1.z();
0140
0141 if (track->GetTrackStatus() != fStopAndKill) {
0142 if (px1 < 0.) {
0143 analysisMan->FillH1(11, px1);
0144 analysisMan->FillH1(12, py1);
0145 analysisMan->FillH1(13, pz1);
0146 }
0147 else {
0148 analysisMan->FillH1(14, px1);
0149 analysisMan->FillH1(15, py1);
0150 analysisMan->FillH1(16, pz1);
0151 }
0152 }
0153
0154 trackInfo->SetIsFirstTankX(false);
0155 run->AddTotalSurface();
0156
0157 for (G4int i = 0; i < n_proc; ++i) {
0158 G4VProcess* currentProcess = (*postStepDoItVector)[i];
0159
0160 auto opProc = dynamic_cast<G4OpBoundaryProcess*>(currentProcess);
0161 if (opProc) {
0162 G4double angle = std::acos(p0.x());
0163 theStatus = opProc->GetStatus();
0164 analysisMan->FillH1(10, theStatus);
0165 switch (theStatus) {
0166 case Transmission:
0167 run->AddTransmission();
0168 analysisMan->FillH1(25, angle / deg);
0169 break;
0170 case FresnelRefraction:
0171 run->AddFresnelRefraction();
0172 analysisMan->FillH1(17, px1);
0173 analysisMan->FillH1(18, py1);
0174 analysisMan->FillH1(19, pz1);
0175 analysisMan->FillH1(20, angle / deg);
0176 break;
0177 case FresnelReflection:
0178 run->AddFresnelReflection();
0179 analysisMan->FillH1(21, angle / deg);
0180 analysisMan->FillH1(23, angle / deg);
0181 break;
0182 case TotalInternalReflection:
0183 run->AddTotalInternalReflection();
0184 analysisMan->FillH1(22, angle / deg);
0185 analysisMan->FillH1(23, angle / deg);
0186 break;
0187 case LambertianReflection:
0188 run->AddLambertianReflection();
0189 break;
0190 case LobeReflection:
0191 run->AddLobeReflection();
0192 break;
0193 case SpikeReflection:
0194 run->AddSpikeReflection();
0195 analysisMan->FillH1(26, angle / deg);
0196 break;
0197 case BackScattering:
0198 run->AddBackScattering();
0199 break;
0200 case Absorption:
0201 analysisMan->FillH1(24, angle / deg);
0202 run->AddAbsorption();
0203 break;
0204 case Detection:
0205 run->AddDetection();
0206 break;
0207 case NotAtBoundary:
0208 run->AddNotAtBoundary();
0209 break;
0210 case SameMaterial:
0211 run->AddSameMaterial();
0212 break;
0213 case StepTooSmall:
0214 run->AddStepTooSmall();
0215 break;
0216 case NoRINDEX:
0217 run->AddNoRINDEX();
0218 break;
0219 case PolishedLumirrorAirReflection:
0220 run->AddPolishedLumirrorAirReflection();
0221 break;
0222 case PolishedLumirrorGlueReflection:
0223 run->AddPolishedLumirrorGlueReflection();
0224 break;
0225 case PolishedAirReflection:
0226 run->AddPolishedAirReflection();
0227 break;
0228 case PolishedTeflonAirReflection:
0229 run->AddPolishedTeflonAirReflection();
0230 break;
0231 case PolishedTiOAirReflection:
0232 run->AddPolishedTiOAirReflection();
0233 break;
0234 case PolishedTyvekAirReflection:
0235 run->AddPolishedTyvekAirReflection();
0236 break;
0237 case PolishedVM2000AirReflection:
0238 run->AddPolishedVM2000AirReflection();
0239 break;
0240 case PolishedVM2000GlueReflection:
0241 run->AddPolishedVM2000AirReflection();
0242 break;
0243 case EtchedLumirrorAirReflection:
0244 run->AddEtchedLumirrorAirReflection();
0245 break;
0246 case EtchedLumirrorGlueReflection:
0247 run->AddEtchedLumirrorGlueReflection();
0248 break;
0249 case EtchedAirReflection:
0250 run->AddEtchedAirReflection();
0251 break;
0252 case EtchedTeflonAirReflection:
0253 run->AddEtchedTeflonAirReflection();
0254 break;
0255 case EtchedTiOAirReflection:
0256 run->AddEtchedTiOAirReflection();
0257 break;
0258 case EtchedTyvekAirReflection:
0259 run->AddEtchedTyvekAirReflection();
0260 break;
0261 case EtchedVM2000AirReflection:
0262 run->AddEtchedVM2000AirReflection();
0263 break;
0264 case EtchedVM2000GlueReflection:
0265 run->AddEtchedVM2000AirReflection();
0266 break;
0267 case GroundLumirrorAirReflection:
0268 run->AddGroundLumirrorAirReflection();
0269 break;
0270 case GroundLumirrorGlueReflection:
0271 run->AddGroundLumirrorGlueReflection();
0272 break;
0273 case GroundAirReflection:
0274 run->AddGroundAirReflection();
0275 break;
0276 case GroundTeflonAirReflection:
0277 run->AddGroundTeflonAirReflection();
0278 break;
0279 case GroundTiOAirReflection:
0280 run->AddGroundTiOAirReflection();
0281 break;
0282 case GroundTyvekAirReflection:
0283 run->AddGroundTyvekAirReflection();
0284 break;
0285 case GroundVM2000AirReflection:
0286 run->AddGroundVM2000AirReflection();
0287 break;
0288 case GroundVM2000GlueReflection:
0289 run->AddGroundVM2000AirReflection();
0290 break;
0291 case Dichroic:
0292 run->AddDichroic();
0293 break;
0294 case CoatedDielectricReflection:
0295 run->AddCoatedDielectricReflection();
0296 break;
0297 case CoatedDielectricRefraction:
0298 run->AddCoatedDielectricRefraction();
0299 break;
0300 case CoatedDielectricFrustratedTransmission:
0301 run->AddCoatedDielectricFrustratedTransmission();
0302 break;
0303 default:
0304 G4cout << "theStatus: " << theStatus << " was none of the above." << G4endl;
0305 break;
0306 }
0307 }
0308 }
0309 }
0310
0311
0312
0313
0314
0315 if (fKillOnSecondSurface) {
0316 if (trackInfo->GetReflectionNumber() >= 2) {
0317 track->SetTrackStatus(fStopAndKill);
0318 }
0319 }
0320 trackInfo->IncrementReflectionNumber();
0321 }
0322
0323
0324
0325
0326
0327
0328 if (endPoint->GetMaterial() == startPoint->GetMaterial()) {
0329 G4double trackVelocity = track->GetVelocity();
0330 G4double materialVelocity = CLHEP::c_light;
0331 G4MaterialPropertyVector* velVector =
0332 endPoint->GetMaterial()->GetMaterialPropertiesTable()->GetProperty(kGROUPVEL);
0333 if (velVector) {
0334 materialVelocity = velVector->Value(theParticle->GetTotalMomentum(), fIdxVelocity);
0335 }
0336
0337 if (std::abs(trackVelocity - materialVelocity) > 1e-9 * CLHEP::c_light) {
0338 G4ExceptionDescription ed;
0339 ed << "Optical photon group velocity: " << trackVelocity / (cm / ns)
0340 << " cm/ns is not what is expected from " << G4endl << "the material properties, "
0341 << materialVelocity / (cm / ns) << " cm/ns";
0342 G4Exception("OpNovice2 SteppingAction", "OpNovice2_1", FatalException, ed);
0343 }
0344 }
0345
0346 }
0347
0348 else {
0349
0350
0351 auto proc_man = track->GetDynamicParticle()->GetParticleDefinition()->GetProcessManager();
0352 G4ProcessVector* proc_vec = proc_man->GetPostStepProcessVector(typeDoIt);
0353 G4int n_proc = proc_vec->entries();
0354
0355 G4int n_scint = 0;
0356 G4int n_cer = 0;
0357 for (G4int i = 0; i < n_proc; ++i) {
0358 G4String proc_name = (*proc_vec)[i]->GetProcessName();
0359 if (proc_name == "Cerenkov") {
0360 auto cer = (G4Cerenkov*)(*proc_vec)[i];
0361 n_cer = cer->GetNumPhotons();
0362 }
0363 else if (proc_name == "Scintillation") {
0364 auto scint = (G4Scintillation*)(*proc_vec)[i];
0365 n_scint = scint->GetNumPhotons();
0366 }
0367 }
0368 if (fVerbose > 0) {
0369 if (n_cer > 0 || n_scint > 0) {
0370 G4cout << "In this step, " << n_cer << " Cerenkov and " << n_scint
0371 << " scintillation photons were produced." << G4endl;
0372 }
0373 }
0374
0375
0376 const std::vector<const G4Track*>* secondaries = step->GetSecondaryInCurrentStep();
0377
0378 for (auto sec : *secondaries) {
0379 if (sec->GetDynamicParticle()->GetParticleDefinition() == opticalphoton) {
0380 G4String creator_process = sec->GetCreatorProcess()->GetProcessName();
0381 if (creator_process == "Cerenkov") {
0382 G4double en = sec->GetKineticEnergy();
0383 run->AddCerenkovEnergy(en);
0384 run->AddCerenkov();
0385 analysisMan->FillH1(1, en / eV);
0386 }
0387 else if (creator_process == "Scintillation") {
0388 G4double en = sec->GetKineticEnergy();
0389 run->AddScintillationEnergy(en);
0390 run->AddScintillation();
0391 analysisMan->FillH1(2, en / eV);
0392
0393 G4double time = sec->GetGlobalTime();
0394 analysisMan->FillH1(3, time / ns);
0395 }
0396 }
0397 }
0398 }
0399
0400 return;
0401 }
0402
0403