File indexing completed on 2026-09-18 08:31:26
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 "DetectorConstruction.hh"
0032 #include "HistoManager.hh"
0033 #include "RunAction.hh"
0034
0035 #include "G4ParticleTypes.hh"
0036 #include "G4RunManager.hh"
0037
0038 #include <G4RotationMatrix.hh>
0039 #include <G4ThreeVector.hh>
0040
0041
0042
0043 SteppingAction::SteppingAction(DetectorConstruction* det, RunAction* RuAct)
0044 : G4UserSteppingAction(), fDetector(det), fRunAction(RuAct)
0045 {}
0046
0047
0048
0049 SteppingAction::~SteppingAction() {}
0050
0051
0052
0053 void SteppingAction::UserSteppingAction(const G4Step* aStep)
0054 {
0055 G4StepPoint* prePoint = aStep->GetPreStepPoint();
0056
0057
0058 if (prePoint->GetTouchableHandle()->GetVolume() == fDetector->GetWorld()) return;
0059
0060
0061
0062
0063 G4RunManager::GetRunManager()->AbortEvent();
0064
0065
0066
0067 G4StepPoint* endPoint = aStep->GetPostStepPoint();
0068 G4String procName = endPoint->GetProcessDefinedStep()->GetProcessName();
0069 fRunAction->CountProcesses(procName);
0070
0071 if (procName == "msc" || procName == "muMsc" || procName == "stepMax") {
0072
0073
0074 G4ThreeVector position = endPoint->GetPosition();
0075 G4ThreeVector direction = endPoint->GetMomentumDirection();
0076
0077 G4double truePathLength = aStep->GetStepLength();
0078 G4double geomPathLength = position.x() + 0.5 * fDetector->GetBoxSize();
0079 G4double ratio = geomPathLength / truePathLength;
0080 fRunAction->SumPathLength(truePathLength, geomPathLength);
0081 G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
0082 analysisManager->FillH1(1, truePathLength);
0083 analysisManager->FillH1(2, geomPathLength);
0084 analysisManager->FillH1(3, ratio);
0085
0086 G4double yend = position.y(), zend = position.z();
0087 G4double lateralDisplacement = std::sqrt(yend * yend + zend * zend);
0088 fRunAction->SumLateralDisplacement(lateralDisplacement);
0089 analysisManager->FillH1(4, lateralDisplacement);
0090
0091 G4double psi = std::atan(lateralDisplacement / geomPathLength);
0092 fRunAction->SumPsi(psi);
0093 analysisManager->FillH1(5, psi);
0094
0095 G4double xdir = direction.x(), ydir = direction.y(), zdir = direction.z();
0096 G4double tetaPlane = std::atan2(ydir, xdir);
0097 fRunAction->SumTetaPlane(tetaPlane);
0098 analysisManager->FillH1(6, tetaPlane);
0099 tetaPlane = std::atan2(zdir, xdir);
0100 fRunAction->SumTetaPlane(tetaPlane);
0101 analysisManager->FillH1(6, tetaPlane);
0102
0103 G4double phiPos = std::atan2(zend, yend);
0104 analysisManager->FillH1(7, phiPos);
0105 G4double phiDir = std::atan2(zdir, ydir);
0106 analysisManager->FillH1(8, phiDir);
0107
0108 G4double phiCorrel = 0.;
0109 if (lateralDisplacement > 0.) phiCorrel = (yend * ydir + zend * zdir) / lateralDisplacement;
0110 fRunAction->SumPhiCorrel(phiCorrel);
0111 analysisManager->FillH1(9, phiCorrel);
0112 }
0113 else if (procName == "conv" || procName == "GammaToMuPair") {
0114
0115
0116 G4StepPoint* PrePoint = aStep->GetPreStepPoint();
0117 G4double EGamma = PrePoint->GetTotalEnergy();
0118 G4ThreeVector PGamma = PrePoint->GetMomentum();
0119 G4ThreeVector PolaGamma = PrePoint->GetPolarization();
0120
0121 G4double Eplus = -1;
0122 G4ThreeVector Pplus, Pminus, Precoil;
0123
0124 const G4TrackVector* secondary = fpSteppingManager->GetSecondary();
0125
0126 const size_t Nsecondaries = (*secondary).size();
0127
0128
0129 if (Nsecondaries == 0) return;
0130
0131 for (size_t lp = 0; lp < std::min(Nsecondaries, size_t(2)); lp++) {
0132 if (((*secondary)[lp]->GetDefinition() == G4Electron::Definition())
0133 || ((*secondary)[lp]->GetDefinition() == G4MuonMinus::Definition()))
0134 {
0135 Pminus = (*secondary)[lp]->GetMomentum();
0136 }
0137 if (((*secondary)[lp]->GetDefinition() == G4Positron::Definition())
0138 || ((*secondary)[lp]->GetDefinition() == G4MuonPlus::Definition()))
0139 {
0140 Eplus = (*secondary)[lp]->GetTotalEnergy();
0141 Pplus = (*secondary)[lp]->GetMomentum();
0142 }
0143 }
0144
0145 if (Nsecondaries >= 3) {
0146 Precoil = (*secondary)[2]->GetMomentum();
0147 }
0148
0149 G4AnalysisManager* analysisManager = G4AnalysisManager::Instance();
0150
0151
0152
0153 G4ThreeVector z = PGamma.unit();
0154 G4ThreeVector x(1., 0., 0.);
0155
0156
0157
0158 if (PolaGamma.mag() != 0.0) {
0159 x = PolaGamma.unit();
0160 }
0161 else {
0162 x = z.orthogonal().unit();
0163 }
0164
0165 G4ThreeVector y = z;
0166 y = y.cross(x);
0167
0168 G4RotationMatrix GtoW(x, y, z);
0169 G4RotationMatrix WtoG = inverseOf(GtoW);
0170
0171 G4double angleE = Pplus.angle(Pminus) * EGamma;
0172 analysisManager->FillH1(10, angleE);
0173
0174 if (Nsecondaries >= 3) {
0175
0176 analysisManager->FillH1(11, std::log10(Precoil.mag()));
0177 analysisManager->FillH1(12, Precoil.transform(WtoG).phi());
0178 }
0179 G4double phiPlus = Pplus.transform(WtoG).phi();
0180 G4double phiMinus = Pminus.transform(WtoG).phi();
0181 analysisManager->FillH1(13, phiPlus);
0182 analysisManager->FillH1(14, std::cos(phiPlus + phiMinus) * -2.0);
0183 analysisManager->FillH1(15, Eplus / EGamma);
0184
0185 G4double phiPola = PolaGamma.transform(WtoG).phi();
0186 analysisManager->FillH1(16, phiPola);
0187 }
0188 }
0189
0190