Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 /// \file Par01/src/Par01PionShowerModel.cc 27 /// \brief Implementation of the Par01PionShowerModel class 28 // 29 // 30 // 31 #include "Par01PionShowerModel.hh" 32 33 #include "Par01EnergySpot.hh" 34 35 #include "G4Colour.hh" 36 #include "G4PhysicalConstants.hh" 37 #include "G4PionMinus.hh" 38 #include "G4PionPlus.hh" 39 #include "G4SystemOfUnits.hh" 40 #include "G4TouchableHistory.hh" 41 #include "G4TransportationManager.hh" 42 #include "G4VSensitiveDetector.hh" 43 #include "Randomize.hh" 44 45 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 46 47 Par01PionShowerModel::Par01PionShowerModel(G4String modelName, G4Region* envelope) 48 : G4VFastSimulationModel(modelName, envelope) 49 { 50 fFakeStep = new G4Step(); 51 fFakePreStepPoint = fFakeStep->GetPreStepPoint(); 52 fFakePostStepPoint = fFakeStep->GetPostStepPoint(); 53 fTouchableHandle = new G4TouchableHistory(); 54 fpNavigator = new G4Navigator(); 55 fNaviSetup = false; 56 } 57 58 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 59 60 Par01PionShowerModel::Par01PionShowerModel(G4String modelName) : G4VFastSimulationModel(modelName) 61 { 62 fFakeStep = new G4Step(); 63 fFakePreStepPoint = fFakeStep->GetPreStepPoint(); 64 fFakePostStepPoint = fFakeStep->GetPostStepPoint(); 65 fTouchableHandle = new G4TouchableHistory(); 66 fpNavigator = new G4Navigator(); 67 fNaviSetup = false; 68 } 69 70 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 71 72 Par01PionShowerModel::~Par01PionShowerModel() 73 { 74 delete fFakeStep; 75 delete fpNavigator; 76 } 77 78 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 79 80 G4bool Par01PionShowerModel::IsApplicable(const G4ParticleDefinition& particleType) 81 { 82 return &particleType == G4PionMinus::PionMinusDefinition() 83 || &particleType == G4PionPlus::PionPlusDefinition(); 84 } 85 86 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 87 88 G4bool Par01PionShowerModel::ModelTrigger(const G4FastTrack&) 89 { 90 // Applies the parameterisation always: 91 // ie as soon as the pion enters the envelope 92 return true; 93 } 94 95 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 96 97 void Par01PionShowerModel::DoIt(const G4FastTrack& fastTrack, G4FastStep& fastStep) 98 { 99 // G4cout << "Par01PionShowerModel::DoIt" << G4endl; 100 101 // Kill the parameterised particle: 102 fastStep.KillPrimaryTrack(); 103 fastStep.ProposePrimaryTrackPathLength(0.0); 104 fastStep.ProposeTotalEnergyDeposited(fastTrack.GetPrimaryTrack()->GetKineticEnergy()); 105 106 // split into "energy spots" energy according to the shower shape: 107 Explode(fastTrack); 108 109 // and put those energy spots into the crystals: 110 BuildDetectorResponse(); 111 } 112 113 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 114 115 void Par01PionShowerModel::Explode(const G4FastTrack& fastTrack) 116 { 117 //----------------------------------------------------- 118 // Non-physical shower generated: exp along z and 119 // transverse. 120 //----------------------------------------------------- 121 122 // center of the shower, we put at the middle of the ghost: 123 G4ThreeVector showerCenter; 124 G4double distOut; 125 distOut = fastTrack.GetEnvelopeSolid()->DistanceToOut(fastTrack.GetPrimaryTrackLocalPosition(), 126 fastTrack.GetPrimaryTrackLocalDirection()); 127 showerCenter = fastTrack.GetPrimaryTrackLocalPosition() 128 + (distOut / 2.) * fastTrack.GetPrimaryTrackLocalDirection(); 129 130 showerCenter = fastTrack.GetInverseAffineTransformation()->TransformPoint(showerCenter); 131 132 // axis of the shower, in global reference frame: 133 G4ThreeVector xShower, yShower, zShower; 134 zShower = fastTrack.GetPrimaryTrack()->GetMomentumDirection(); 135 xShower = zShower.orthogonal(); 136 yShower = zShower.cross(xShower); 137 138 // shoot the energy spots: 139 G4double Energy = fastTrack.GetPrimaryTrack()->GetKineticEnergy(); 140 G4int nSpot = 50; 141 G4double deposit = Energy / double(nSpot); 142 Par01EnergySpot eSpot; 143 eSpot.SetEnergy(deposit); 144 G4ThreeVector ePoint; 145 146 // clear the spot list before use 147 feSpotList.clear(); 148 149 G4double z, r, phi; 150 for (int i = 0; i < nSpot; i++) { 151 z = G4RandGauss::shoot(0, 20 * cm); 152 r = G4RandGauss::shoot(0, 10 * cm); 153 phi = G4UniformRand() * twopi; 154 ePoint = showerCenter + z * zShower + r * std::cos(phi) * xShower + r * std::sin(phi) * yShower; 155 eSpot.SetPosition(ePoint); 156 feSpotList.push_back(eSpot); 157 } 158 } 159 160 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 161 162 void Par01PionShowerModel::BuildDetectorResponse() 163 { 164 // Does the assignation of the energy spots to the sensitive volumes: 165 for (size_t i = 0; i < feSpotList.size(); i++) { 166 // Draw the energy spot: 167 // G4Colour red(1.,0.,0.); 168 // feSpotList[i].Draw(&red); 169 // feSpotList[i].Print(); 170 171 // "converts" the energy spot into the fake 172 // G4Step to pass to sensitive detector: 173 AssignSpotAndCallHit(feSpotList[i]); 174 } 175 } 176 177 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 178 179 void Par01PionShowerModel::AssignSpotAndCallHit(const Par01EnergySpot& eSpot) 180 { 181 // 182 // "converts" the energy spot into the fake 183 // G4Step to pass to sensitive detector: 184 // 185 FillFakeStep(eSpot); 186 187 // 188 // call sensitive part: taken/adapted from the stepping: 189 // Send G4Step information to Hit/Dig if the volume is sensitive 190 // 191 G4VPhysicalVolume* pCurrentVolume = fFakeStep->GetPreStepPoint()->GetPhysicalVolume(); 192 G4VSensitiveDetector* pSensitive; 193 194 if (pCurrentVolume != nullptr) { 195 pSensitive = pCurrentVolume->GetLogicalVolume()->GetSensitiveDetector(); 196 if (pSensitive != nullptr) { 197 pSensitive->Hit(fFakeStep); 198 } 199 } 200 } 201 202 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 203 204 void Par01PionShowerModel::FillFakeStep(const Par01EnergySpot& eSpot) 205 { 206 //----------------------------------------------------------- 207 // find in which volume the spot is. 208 //----------------------------------------------------------- 209 if (!fNaviSetup) { 210 fpNavigator->SetWorldVolume(G4TransportationManager::GetTransportationManager() 211 ->GetNavigatorForTracking() 212 ->GetWorldVolume()); 213 fpNavigator->LocateGlobalPointAndUpdateTouchableHandle( 214 eSpot.GetPosition(), G4ThreeVector(0., 0., 0.), fTouchableHandle, false); 215 fNaviSetup = true; 216 } 217 else { 218 fpNavigator->LocateGlobalPointAndUpdateTouchableHandle( 219 eSpot.GetPosition(), G4ThreeVector(0., 0., 0.), fTouchableHandle); 220 } 221 //-------------------------------------- 222 // Fills attribute of the G4Step needed 223 // by our sensitive detector: 224 //------------------------------------- 225 // set touchable volume at PreStepPoint: 226 fFakePreStepPoint->SetTouchableHandle(fTouchableHandle); 227 // set total energy deposit: 228 fFakeStep->SetTotalEnergyDeposit(eSpot.GetEnergy()); 229 } 230