File indexing completed on 2026-09-13 08:30:15
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 "Par01PionShowerModel.hh"
0030
0031 #include "Par01EnergySpot.hh"
0032
0033 #include "G4Colour.hh"
0034 #include "G4PhysicalConstants.hh"
0035 #include "G4PionMinus.hh"
0036 #include "G4PionPlus.hh"
0037 #include "G4SystemOfUnits.hh"
0038 #include "G4TouchableHistory.hh"
0039 #include "G4TransportationManager.hh"
0040 #include "G4VSensitiveDetector.hh"
0041 #include "Randomize.hh"
0042
0043
0044
0045 Par01PionShowerModel::Par01PionShowerModel(G4String modelName, G4Region* envelope)
0046 : G4VFastSimulationModel(modelName, envelope)
0047 {
0048 fFakeStep = new G4Step();
0049 fFakePreStepPoint = fFakeStep->GetPreStepPoint();
0050 fFakePostStepPoint = fFakeStep->GetPostStepPoint();
0051 fTouchableHandle = new G4TouchableHistory();
0052 fpNavigator = new G4Navigator();
0053 fNaviSetup = false;
0054 }
0055
0056
0057
0058 Par01PionShowerModel::Par01PionShowerModel(G4String modelName) : G4VFastSimulationModel(modelName)
0059 {
0060 fFakeStep = new G4Step();
0061 fFakePreStepPoint = fFakeStep->GetPreStepPoint();
0062 fFakePostStepPoint = fFakeStep->GetPostStepPoint();
0063 fTouchableHandle = new G4TouchableHistory();
0064 fpNavigator = new G4Navigator();
0065 fNaviSetup = false;
0066 }
0067
0068
0069
0070 Par01PionShowerModel::~Par01PionShowerModel()
0071 {
0072 delete fFakeStep;
0073 delete fpNavigator;
0074 }
0075
0076
0077
0078 G4bool Par01PionShowerModel::IsApplicable(const G4ParticleDefinition& particleType)
0079 {
0080 return &particleType == G4PionMinus::PionMinusDefinition()
0081 || &particleType == G4PionPlus::PionPlusDefinition();
0082 }
0083
0084
0085
0086 G4bool Par01PionShowerModel::ModelTrigger(const G4FastTrack&)
0087 {
0088
0089
0090 return true;
0091 }
0092
0093
0094
0095 void Par01PionShowerModel::DoIt(const G4FastTrack& fastTrack, G4FastStep& fastStep)
0096 {
0097
0098
0099
0100 fastStep.KillPrimaryTrack();
0101 fastStep.ProposePrimaryTrackPathLength(0.0);
0102 fastStep.ProposeTotalEnergyDeposited(fastTrack.GetPrimaryTrack()->GetKineticEnergy());
0103
0104
0105 Explode(fastTrack);
0106
0107
0108 BuildDetectorResponse();
0109 }
0110
0111
0112
0113 void Par01PionShowerModel::Explode(const G4FastTrack& fastTrack)
0114 {
0115
0116
0117
0118
0119
0120
0121 G4ThreeVector showerCenter;
0122 G4double distOut;
0123 distOut = fastTrack.GetEnvelopeSolid()->DistanceToOut(fastTrack.GetPrimaryTrackLocalPosition(),
0124 fastTrack.GetPrimaryTrackLocalDirection());
0125 showerCenter = fastTrack.GetPrimaryTrackLocalPosition()
0126 + (distOut / 2.) * fastTrack.GetPrimaryTrackLocalDirection();
0127
0128 showerCenter = fastTrack.GetInverseAffineTransformation()->TransformPoint(showerCenter);
0129
0130
0131 G4ThreeVector xShower, yShower, zShower;
0132 zShower = fastTrack.GetPrimaryTrack()->GetMomentumDirection();
0133 xShower = zShower.orthogonal();
0134 yShower = zShower.cross(xShower);
0135
0136
0137 G4double Energy = fastTrack.GetPrimaryTrack()->GetKineticEnergy();
0138 G4int nSpot = 50;
0139 G4double deposit = Energy / double(nSpot);
0140 Par01EnergySpot eSpot;
0141 eSpot.SetEnergy(deposit);
0142 G4ThreeVector ePoint;
0143
0144
0145 feSpotList.clear();
0146
0147 G4double z, r, phi;
0148 for (int i = 0; i < nSpot; i++) {
0149 z = G4RandGauss::shoot(0, 20 * cm);
0150 r = G4RandGauss::shoot(0, 10 * cm);
0151 phi = G4UniformRand() * twopi;
0152 ePoint = showerCenter + z * zShower + r * std::cos(phi) * xShower + r * std::sin(phi) * yShower;
0153 eSpot.SetPosition(ePoint);
0154 feSpotList.push_back(eSpot);
0155 }
0156 }
0157
0158
0159
0160 void Par01PionShowerModel::BuildDetectorResponse()
0161 {
0162
0163 for (size_t i = 0; i < feSpotList.size(); i++) {
0164
0165
0166
0167
0168
0169
0170
0171 AssignSpotAndCallHit(feSpotList[i]);
0172 }
0173 }
0174
0175
0176
0177 void Par01PionShowerModel::AssignSpotAndCallHit(const Par01EnergySpot& eSpot)
0178 {
0179
0180
0181
0182
0183 FillFakeStep(eSpot);
0184
0185
0186
0187
0188
0189 G4VPhysicalVolume* pCurrentVolume = fFakeStep->GetPreStepPoint()->GetPhysicalVolume();
0190 G4VSensitiveDetector* pSensitive;
0191
0192 if (pCurrentVolume != nullptr) {
0193 pSensitive = pCurrentVolume->GetLogicalVolume()->GetSensitiveDetector();
0194 if (pSensitive != nullptr) {
0195 pSensitive->Hit(fFakeStep);
0196 }
0197 }
0198 }
0199
0200
0201
0202 void Par01PionShowerModel::FillFakeStep(const Par01EnergySpot& eSpot)
0203 {
0204
0205
0206
0207 if (!fNaviSetup) {
0208 fpNavigator->SetWorldVolume(G4TransportationManager::GetTransportationManager()
0209 ->GetNavigatorForTracking()
0210 ->GetWorldVolume());
0211 fpNavigator->LocateGlobalPointAndUpdateTouchableHandle(
0212 eSpot.GetPosition(), G4ThreeVector(0., 0., 0.), fTouchableHandle, false);
0213 fNaviSetup = true;
0214 }
0215 else {
0216 fpNavigator->LocateGlobalPointAndUpdateTouchableHandle(
0217 eSpot.GetPosition(), G4ThreeVector(0., 0., 0.), fTouchableHandle);
0218 }
0219
0220
0221
0222
0223
0224 fFakePreStepPoint->SetTouchableHandle(fTouchableHandle);
0225
0226 fFakeStep->SetTotalEnergyDeposit(eSpot.GetEnergy());
0227 }