File indexing completed on 2026-09-18 08:32:10
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 "Run.hh"
0032
0033 #include "G4IonTable.hh"
0034 #include "G4LossTableManager.hh"
0035 #include "G4ParticleDefinition.hh"
0036 #include "G4ParticleTypes.hh"
0037 #include "G4Step.hh"
0038 #include "G4StepPoint.hh"
0039 #include "G4SystemOfUnits.hh"
0040 #include "G4TouchableHistory.hh"
0041 #include "G4Track.hh"
0042 #include "G4VPhysicalVolume.hh"
0043 #include "G4VSolid.hh"
0044 #include "G4VTouchable.hh"
0045
0046 const std::array<G4String, SteppingAction::fkNumberKinematicRegions>
0047 SteppingAction::fkArrayKinematicRegionNames = {"", "below 20 MeV", "above 20 MeV"};
0048
0049 const std::array<G4String, SteppingAction::fkNumberScoringPositions>
0050 SteppingAction::fkArrayScoringPositionNames = {"forward", "backward"};
0051
0052 const std::array<G4String, SteppingAction::fkNumberParticleTypes>
0053 SteppingAction::fkArrayParticleTypeNames = {"all", "electron", "gamma", "muon",
0054 "neutrino", "pion", "neutron", "proton",
0055 "ion", "otherMeson", "otherBaryon"};
0056
0057
0058
0059 G4int SteppingAction::GetIndex(const G4int iKinematicRegion, const G4int iScoringPosition,
0060 const G4int iParticleType)
0061 {
0062 G4int index = -1;
0063 if (iKinematicRegion >= 0 && iKinematicRegion < fkNumberKinematicRegions && iScoringPosition >= 0
0064 && iScoringPosition < fkNumberScoringPositions && iParticleType >= 0
0065 && iParticleType < fkNumberParticleTypes)
0066 {
0067 index = iKinematicRegion * fkNumberScoringPositions * fkNumberParticleTypes
0068 + iScoringPosition * fkNumberParticleTypes + iParticleType;
0069 }
0070 if (index < 0 || index >= fkNumberCombinations) {
0071 G4cerr << "SteppingAction::GetIndex : WRONG index=" << index << " set it to 0 !" << G4endl;
0072 index = 0;
0073 }
0074 return index;
0075 }
0076
0077
0078
0079 SteppingAction::SteppingAction() : G4UserSteppingAction()
0080 {
0081 Initialize();
0082 }
0083
0084
0085
0086 void SteppingAction::Initialize()
0087 {
0088
0089 fPrimaryParticleId = 0;
0090 fPrimaryParticleEnergy = 0.0;
0091 fPrimaryParticleDirection = G4ThreeVector(0.0, 0.0, 1.0);
0092 fTargetMaterialName = "";
0093 fIsFirstStepOfTheEvent = true;
0094 fIsFirstStepInTarget = true;
0095 fIsFirstStepInScoringShell = true;
0096 fCubicVolumeScoringShell = 1.0;
0097 for (G4int i = 0; i < fkNumberCombinations; ++i) {
0098 fArraySumStepLengths[i] = 0.0;
0099 }
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118 }
0119
0120
0121
0122 void SteppingAction::UserSteppingAction(const G4Step* theStep)
0123 {
0124
0125 if (fIsFirstStepOfTheEvent) {
0126 if (theStep->GetTrack()->GetParentID() == 0) {
0127 fPrimaryParticleId = theStep->GetTrack()->GetDefinition()->GetPDGEncoding();
0128 fPrimaryParticleEnergy = theStep->GetPreStepPoint()->GetKineticEnergy();
0129 fPrimaryParticleDirection = theStep->GetPreStepPoint()->GetMomentumDirection();
0130 if (fRunPtr) {
0131 fRunPtr->SetPrimaryParticleId(fPrimaryParticleId);
0132 fRunPtr->SetPrimaryParticleEnergy(fPrimaryParticleEnergy);
0133 fRunPtr->SetPrimaryParticleDirection(fPrimaryParticleDirection);
0134 }
0135 fIsFirstStepOfTheEvent = false;
0136 }
0137 }
0138
0139 if (fIsFirstStepInTarget
0140 && theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiSphere")
0141 {
0142 fTargetMaterialName = theStep->GetPreStepPoint()->GetMaterial()->GetName();
0143 if (fRunPtr) fRunPtr->SetTargetMaterialName(fTargetMaterialName);
0144 fIsFirstStepInTarget = false;
0145 }
0146
0147 if (theStep->GetPreStepPoint()->GetPhysicalVolume()->GetName() == "physiScoringShell") {
0148 if (fIsFirstStepInScoringShell) {
0149 fCubicVolumeScoringShell =
0150 theStep->GetTrack()->GetVolume()->GetLogicalVolume()->GetSolid()->GetCubicVolume();
0151 if (fRunPtr) fRunPtr->SetCubicVolumeScoringShell(fCubicVolumeScoringShell);
0152 fIsFirstStepInScoringShell = false;
0153 }
0154 G4double stepLength = theStep->GetTrack()->GetStepLength() * theStep->GetTrack()->GetWeight();
0155 G4int absPdg = theStep->GetTrack()->GetDefinition() == nullptr
0156 ? 0
0157 : std::abs(theStep->GetTrack()->GetDefinition()->GetPDGEncoding());
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170 G4int iKinematicRegion = theStep->GetPreStepPoint()->GetKineticEnergy() < 20.0 ? 1 : 2;
0171
0172
0173 G4int iScoringPosition =
0174 fPrimaryParticleDirection.dot(theStep->GetTrack()->GetPosition().unit()) > 0.0 ? 0 : 1;
0175 G4int iParticleType = -1;
0176 if (absPdg == 11)
0177 iParticleType = 1;
0178 else if (absPdg == 22)
0179 iParticleType = 2;
0180 else if (absPdg == 13)
0181 iParticleType = 3;
0182 else if (absPdg == 12 || absPdg == 14 || absPdg == 16)
0183 iParticleType = 4;
0184
0185 else if (absPdg == 111 || absPdg == 211)
0186 iParticleType = 5;
0187 else if (absPdg == 2112)
0188 iParticleType = 6;
0189 else if (absPdg == 2212)
0190 iParticleType = 7;
0191 else if (G4IonTable::IsIon(theStep->GetTrack()->GetDefinition()) ||
0192 G4IonTable::IsAntiIon(theStep->GetTrack()->GetDefinition()))
0193 iParticleType = 8;
0194 else if (absPdg < 1000)
0195 iParticleType = 9;
0196
0197 else if (absPdg > 1000)
0198 iParticleType = 10;
0199
0200
0201 G4int index = GetIndex(iKinematicRegion, iScoringPosition, iParticleType);
0202 fArraySumStepLengths[index] += stepLength;
0203
0204 index = GetIndex(iKinematicRegion, iScoringPosition, 0);
0205 fArraySumStepLengths[index] += stepLength;
0206
0207 index = GetIndex(0, iScoringPosition, iParticleType);
0208 fArraySumStepLengths[index] += stepLength;
0209
0210 index = GetIndex(0, iScoringPosition, 0);
0211 fArraySumStepLengths[index] += stepLength;
0212 if (fRunPtr) fRunPtr->SetSteppingArray(fArraySumStepLengths);
0213 }
0214 }
0215
0216