File indexing completed on 2026-09-16 08:30:29
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 "WLSSteppingAction.hh"
0030
0031 #include "WLSDetectorConstruction.hh"
0032 #include "WLSEventAction.hh"
0033 #include "WLSPhotonDetSD.hh"
0034 #include "WLSSteppingActionMessenger.hh"
0035 #include "WLSUserTrackInformation.hh"
0036
0037 #include "G4OpBoundaryProcess.hh"
0038 #include "G4OpticalPhoton.hh"
0039 #include "G4ProcessManager.hh"
0040 #include "G4Run.hh"
0041 #include "G4SDManager.hh"
0042 #include "G4Step.hh"
0043 #include "G4StepPoint.hh"
0044 #include "G4SystemOfUnits.hh"
0045 #include "G4ThreeVector.hh"
0046 #include "G4Track.hh"
0047 #include "G4TrackStatus.hh"
0048 #include "G4UImanager.hh"
0049 #include "G4VPhysicalVolume.hh"
0050 #include "G4ios.hh"
0051
0052
0053
0054
0055
0056 WLSSteppingAction::WLSSteppingAction(WLSDetectorConstruction* detector, WLSEventAction* event)
0057 : fDetector(detector), fEventAction(event)
0058 {
0059 fSteppingMessenger = new WLSSteppingActionMessenger(this);
0060 ResetCounters();
0061 }
0062
0063
0064
0065 WLSSteppingAction::~WLSSteppingAction()
0066 {
0067 delete fSteppingMessenger;
0068 }
0069
0070
0071
0072 void WLSSteppingAction::SetBounceLimit(G4int i)
0073 {
0074 fBounceLimit = i;
0075 }
0076
0077
0078
0079 G4int WLSSteppingAction::GetNumberOfBounces()
0080 {
0081 return fCounterBounce;
0082 }
0083
0084
0085
0086 G4int WLSSteppingAction::GetNumberOfClad1Bounces()
0087 {
0088 return fCounterClad1Bounce;
0089 }
0090
0091
0092
0093 G4int WLSSteppingAction::GetNumberOfClad2Bounces()
0094 {
0095 return fCounterClad2Bounce;
0096 }
0097
0098
0099
0100 G4int WLSSteppingAction::GetNumberOfWLSBounces()
0101 {
0102 return fCounterWLSBounce;
0103 }
0104
0105
0106
0107 G4int WLSSteppingAction::ResetSuccessCounter()
0108 {
0109 G4int temp = fCounterEnd;
0110 fCounterEnd = 0;
0111 return temp;
0112 }
0113
0114
0115
0116 void WLSSteppingAction::UserSteppingAction(const G4Step* theStep)
0117 {
0118 G4Track* theTrack = theStep->GetTrack();
0119 auto trackInformation = (WLSUserTrackInformation*)theTrack->GetUserInformation();
0120
0121 G4StepPoint* thePrePoint = theStep->GetPreStepPoint();
0122 G4StepPoint* thePostPoint = theStep->GetPostStepPoint();
0123
0124 G4VPhysicalVolume* thePrePV = thePrePoint->GetPhysicalVolume();
0125 G4VPhysicalVolume* thePostPV = thePostPoint->GetPhysicalVolume();
0126
0127 G4String thePrePVname = " ";
0128 G4String thePostPVname = " ";
0129
0130 if (thePostPV) {
0131 thePrePVname = thePrePV->GetName();
0132 thePostPVname = thePostPV->GetName();
0133 }
0134
0135
0136
0137 if (theTrack->GetParentID() == 0) {
0138
0139 if (theTrack->GetCurrentStepNumber() == 1) {
0140
0141
0142
0143
0144
0145
0146 }
0147 }
0148
0149
0150 G4OpBoundaryProcessStatus theStatus = Undefined;
0151
0152 static G4ThreadLocal G4ProcessManager* OpManager =
0153 G4OpticalPhoton::OpticalPhoton()->GetProcessManager();
0154
0155 if (OpManager) {
0156 G4int nproc = OpManager->GetPostStepProcessVector()->entries();
0157 G4ProcessVector* fPostStepDoItVector = OpManager->GetPostStepProcessVector(typeDoIt);
0158
0159 for (G4int i = 0; i < nproc; ++i) {
0160 G4VProcess* fCurrentProcess = (*fPostStepDoItVector)[i];
0161 fOpProcess = dynamic_cast<G4OpBoundaryProcess*>(fCurrentProcess);
0162 if (fOpProcess) {
0163 theStatus = fOpProcess->GetStatus();
0164 break;
0165 }
0166 }
0167 }
0168
0169
0170 if (fInitGamma == -1
0171 && (theStatus == TotalInternalReflection || theStatus == FresnelReflection
0172 || theStatus == FresnelRefraction)
0173 && trackInformation->IsStatus(InsideOfFiber))
0174 {
0175 G4double px = theTrack->GetVertexMomentumDirection().x();
0176 G4double py = theTrack->GetVertexMomentumDirection().y();
0177 G4double x = theTrack->GetPosition().x();
0178 G4double y = theTrack->GetPosition().y();
0179
0180 fInitGamma = x * px + y * py;
0181
0182 fInitGamma = fInitGamma / std::sqrt(px * px + py * py) / std::sqrt(x * x + y * y);
0183
0184 fInitGamma = std::acos(fInitGamma * rad);
0185
0186 if (fInitGamma / deg > 90.0) {
0187 fInitGamma = 180 * deg - fInitGamma;
0188 }
0189 }
0190
0191 if (!thePostPV && trackInformation->IsStatus(EscapedFromReadOut)) {
0192
0193 fEventAction->AddEscaped();
0194
0195 ResetCounters();
0196
0197 return;
0198 }
0199
0200
0201
0202 switch (theStatus) {
0203
0204 case FresnelRefraction:
0205 case SameMaterial:
0206 fEventAction->AddExiting();
0207
0208 if (thePostPVname == "WLSFiber" || thePostPVname == "Clad1" || thePostPVname == "Clad2") {
0209 if (trackInformation->IsStatus(OutsideOfFiber))
0210 trackInformation->AddStatusFlag(InsideOfFiber);
0211
0212
0213 }
0214 else if (trackInformation->IsStatus(InsideOfFiber)) {
0215
0216 if (theTrack->GetPosition().z() == fDetector->GetWLSFiberEnd()) {
0217 trackInformation->AddStatusFlag(EscapedFromReadOut);
0218 fCounterEnd++;
0219 fEventAction->AddEscapedEnd();
0220 }
0221 else
0222 {
0223 trackInformation->AddStatusFlag(EscapedFromSide);
0224 trackInformation->SetExitPosition(theTrack->GetPosition());
0225
0226
0227 fCounterMid++;
0228 fEventAction->AddEscapedMid();
0229 ResetCounters();
0230 }
0231
0232 trackInformation->AddStatusFlag(OutsideOfFiber);
0233 trackInformation->SetExitPosition(theTrack->GetPosition());
0234 }
0235
0236 return;
0237
0238
0239 case TotalInternalReflection:
0240
0241 fEventAction->AddTIR();
0242
0243
0244 if (fBounceLimit > 0 && fCounterBounce >= fBounceLimit) {
0245 theTrack->SetTrackStatus(fStopAndKill);
0246 trackInformation->AddStatusFlag(murderee);
0247 ResetCounters();
0248 G4cout << "\n Bounce Limit Exceeded" << G4endl;
0249 return;
0250 }
0251 break;
0252
0253 case FresnelReflection:
0254
0255 fCounterBounce++;
0256 fEventAction->AddBounce();
0257
0258 if (thePrePVname == "WLSFiber") {
0259 fCounterWLSBounce++;
0260 fEventAction->AddWLSBounce();
0261 }
0262 else if (thePrePVname == "Clad1") {
0263 fCounterClad1Bounce++;
0264 fEventAction->AddClad1Bounce();
0265 }
0266 else if (thePrePVname == "Clad2") {
0267 fCounterClad2Bounce++;
0268 fEventAction->AddClad1Bounce();
0269 }
0270
0271
0272 if (theTrack->GetPosition().z() == fDetector->GetWLSFiberEnd()) {
0273 if (!trackInformation->IsStatus(ReflectedAtReadOut)
0274 && trackInformation->IsStatus(InsideOfFiber))
0275 {
0276 trackInformation->AddStatusFlag(ReflectedAtReadOut);
0277
0278 if (fDetector->IsPerfectFiber() && theStatus == TotalInternalReflection) {
0279 theTrack->SetTrackStatus(fStopAndKill);
0280 trackInformation->AddStatusFlag(murderee);
0281
0282 ResetCounters();
0283 return;
0284 }
0285 }
0286 }
0287 return;
0288
0289
0290 case LambertianReflection:
0291 case LobeReflection:
0292 case SpikeReflection:
0293
0294 fEventAction->AddReflected();
0295
0296 if (thePostPVname == "Mirror") {
0297 trackInformation->AddStatusFlag(ReflectedAtMirror);
0298 fEventAction->AddMirror();
0299 }
0300 return;
0301
0302
0303 case Detection:
0304
0305
0306
0307 ResetCounters();
0308 theTrack->SetTrackStatus(fStopAndKill);
0309 return;
0310
0311 default:
0312 break;
0313 }
0314
0315
0316 if (theTrack->GetTrackStatus() != fAlive && trackInformation->IsStatus(InsideOfFiber)) {
0317
0318 ResetCounters();
0319 return;
0320 }
0321 }