source: trunk/examples/novice/N05/src/ExN05EMShowerModel.cc@ 1198

Last change on this file since 1198 was 807, checked in by garnier, 17 years ago

update

File size: 8.1 KB
Line 
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//
27// $Id: ExN05EMShowerModel.cc,v 1.15 2006/11/14 09:21:44 gcosmo Exp $
28// GEANT4 tag $Name: $
29//
30#include "ExN05EMShowerModel.hh"
31#include "ExN05EnergySpot.hh"
32
33#include "Randomize.hh"
34
35#include "G4Electron.hh"
36#include "G4Positron.hh"
37#include "G4Gamma.hh"
38#include "G4TransportationManager.hh"
39#include "G4VSensitiveDetector.hh"
40#include "G4TouchableHandle.hh"
41
42ExN05EMShowerModel::ExN05EMShowerModel(G4String modelName, G4Region* envelope)
43: G4VFastSimulationModel(modelName, envelope)
44{
45 fFakeStep = new G4Step();
46 fFakePreStepPoint = fFakeStep->GetPreStepPoint();
47 fFakePostStepPoint = fFakeStep->GetPostStepPoint();
48 fTouchableHandle = new G4TouchableHistory();
49 fpNavigator = new G4Navigator();
50 fNaviSetup = false;
51}
52
53ExN05EMShowerModel::ExN05EMShowerModel(G4String modelName)
54: G4VFastSimulationModel(modelName)
55{
56 fFakeStep = new G4Step();
57 fFakePreStepPoint = fFakeStep->GetPreStepPoint();
58 fFakePostStepPoint = fFakeStep->GetPostStepPoint();
59 fTouchableHandle = new G4TouchableHistory();
60 fpNavigator = new G4Navigator();
61 fNaviSetup = false;
62}
63
64ExN05EMShowerModel::~ExN05EMShowerModel()
65{
66 delete fFakeStep;
67 delete fpNavigator;
68}
69
70G4bool ExN05EMShowerModel::IsApplicable(const G4ParticleDefinition& particleType)
71{
72 return
73 &particleType == G4Electron::ElectronDefinition() ||
74 &particleType == G4Positron::PositronDefinition() ||
75 &particleType == G4Gamma::GammaDefinition();
76}
77
78G4bool ExN05EMShowerModel::ModelTrigger(const G4FastTrack& fastTrack)
79{
80 // Applies the parameterisation above 100 MeV:
81 return fastTrack.GetPrimaryTrack()->GetKineticEnergy() > 100*MeV;
82}
83
84void ExN05EMShowerModel::DoIt(const G4FastTrack& fastTrack,
85 G4FastStep& fastStep)
86{
87 // Kill the parameterised particle:
88 fastStep.KillPrimaryTrack();
89 fastStep.ProposePrimaryTrackPathLength(0.0);
90 fastStep.ProposeTotalEnergyDeposited(fastTrack.GetPrimaryTrack()->GetKineticEnergy());
91
92 // split into "energy spots" energy according to the shower shape:
93 Explode(fastTrack);
94
95 // and put those energy spots into the crystals:
96 BuildDetectorResponse();
97
98}
99
100void ExN05EMShowerModel::Explode(const G4FastTrack& fastTrack)
101{
102 //-----------------------------------------------------
103 //
104 //-----------------------------------------------------
105
106 // Reduced quantities:
107 // -- critical energy in CsI:
108 G4double Ec = 800*MeV/(54. + 1.2); // 54 = mean Z of CsI
109 G4double Energy = fastTrack.GetPrimaryTrack()->GetKineticEnergy();
110 G4double y = Energy/Ec;
111
112 // compute value of parameter "a" of longitudinal profile, b assumed = 0.5
113 G4double a, tmax, b(0.5), C;
114 if (fastTrack.GetPrimaryTrack()->GetDefinition() == G4Gamma::GammaDefinition()) C = 0.5;
115 else C = -0.5;
116 tmax = 1.0 * (std::log(y) + C);
117 a = 1.0 + b*tmax;
118
119 // t : reduced quantity = z/X0:
120 G4double t, bt;
121 G4Material* CsI = G4Material::GetMaterial("CsI");
122 G4double X0 = CsI->GetRadlen();
123 // Moliere radius:
124 G4double Es = 21*MeV;
125 G4double Rm = X0*Es/Ec;
126
127 // axis of the shower, in global reference frame:
128 G4ThreeVector xShower, yShower, zShower;
129 zShower = fastTrack.GetPrimaryTrack()->GetMomentumDirection();
130 xShower = zShower.orthogonal();
131 yShower = zShower.cross(xShower);
132 // starting point of the shower:
133 G4ThreeVector sShower = fastTrack.GetPrimaryTrack()->GetPosition();
134
135 // We shoot 100 spots of energy:
136 G4int nSpots = 100;
137 G4double deposit = Energy/double(nSpots);
138 ExN05EnergySpot eSpot;
139 eSpot.SetEnergy(deposit);
140 G4ThreeVector ePoint;
141 G4double z, r, phi;
142
143 feSpotList.clear();
144 for (int i = 0; i < nSpots; i++)
145 {
146 // Longitudinal profile:
147 // -- shoot z according to Gamma distribution:
148 bt = CLHEP::RandGamma::shoot(a,1.0);
149 t = bt/b;
150 z = t*X0;
151
152 // transverse profile:
153 // we set 90% of energy in one Rm,
154 // the rest between 1 and 3.5 Rm:
155 G4double xr = G4UniformRand();
156 if (xr < 0.9) r = xr/0.9*Rm;
157 else r = ((xr - 0.9)/0.1*2.5 + 1.0)*Rm;
158 phi = G4UniformRand()*twopi;
159
160 // build the position:
161 ePoint = sShower +
162 z*zShower +
163 r*std::cos(phi)*xShower + r*std::sin(phi)*yShower;
164
165 // and the energy spot:
166 eSpot.SetPosition(ePoint);
167
168 // Records the eSpot:
169 feSpotList.push_back(eSpot);
170 }
171}
172
173
174void ExN05EMShowerModel::BuildDetectorResponse()
175{
176 // Does the assignation of the energy spots to the sensitive volumes:
177 for (size_t i = 0; i < feSpotList.size(); i++)
178 {
179 // Draw the energy spot:
180 feSpotList[i].Draw();
181 // feSpotList[i].Print();
182
183 // "converts" the energy spot into the fake
184 // G4Step to pass to sensitive detector:
185 AssignSpotAndCallHit(feSpotList[i]);
186 }
187}
188
189
190void ExN05EMShowerModel::AssignSpotAndCallHit(const ExN05EnergySpot &eSpot)
191{
192 //
193 // "converts" the energy spot into the fake
194 // G4Step to pass to sensitive detector:
195 //
196 FillFakeStep(eSpot);
197
198 //
199 // call sensitive part: taken/adapted from the stepping:
200 // Send G4Step information to Hit/Dig if the volume is sensitive
201 //
202 G4VPhysicalVolume* pCurrentVolume =
203 fFakeStep->GetPreStepPoint()->GetPhysicalVolume();
204 G4VSensitiveDetector* pSensitive;
205
206 if( pCurrentVolume != 0 )
207 {
208 pSensitive = pCurrentVolume->GetLogicalVolume()->
209 GetSensitiveDetector();
210 if( pSensitive != 0 )
211 {
212 pSensitive->Hit(fFakeStep);
213 }
214 }
215}
216
217
218void ExN05EMShowerModel::FillFakeStep(const ExN05EnergySpot &eSpot)
219{
220 //-----------------------------------------------------------
221 // find in which volume the spot is.
222 //-----------------------------------------------------------
223 if (!fNaviSetup)
224 {
225 fpNavigator->
226 SetWorldVolume(G4TransportationManager::GetTransportationManager()->
227 GetNavigatorForTracking()->GetWorldVolume());
228 fpNavigator->
229 LocateGlobalPointAndUpdateTouchableHandle(eSpot.GetPosition(),
230 G4ThreeVector(0.,0.,0.),
231 fTouchableHandle,
232 false);
233 fNaviSetup = true;
234 }
235 else
236 {
237 fpNavigator->
238 LocateGlobalPointAndUpdateTouchableHandle(eSpot.GetPosition(),
239 G4ThreeVector(0.,0.,0.),
240 fTouchableHandle);
241 }
242 //--------------------------------------
243 // Fills attribute of the G4Step needed
244 // by our sensitive detector:
245 //-------------------------------------
246 // set touchable volume at PreStepPoint:
247 fFakePreStepPoint->SetTouchableHandle(fTouchableHandle);
248 // set total energy deposit:
249 fFakeStep->SetTotalEnergyDeposit(eSpot.GetEnergy());
250}
Note: See TracBrowser for help on using the repository browser.