Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
GFlashSamplingShowerParameterisation.cc
Go to the documentation of this file.
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//
28// ------------------------------------------------------------
29// GEANT 4 class implementation
30//
31// ------- GFlashSamplingShowerParameterisation -------
32//
33// Authors: E.Barberio & Joanna Weng - 11.2005
34// ------------------------------------------------------------
35
36#include <cmath>
37
40#include "G4SystemOfUnits.hh"
41#include "Randomize.hh"
42#include "G4ios.hh"
43#include "G4Material.hh"
44#include "G4MaterialTable.hh"
45
48 G4double dd1, G4double dd2,
51 ParAveT2(0.), ParSigLogT1(0.), ParSigLogT2(0.),
52 ParSigLogA1(0.), ParSigLogA2(0.), ParRho1(0.), ParRho2(0.), ParsAveA2(0.),
53 AveLogAlphah(0.), AveLogTmaxh(0.), SigmaLogAlphah(0.), SigmaLogTmaxh(0.),
54 Rhoh(0.), Alphah(0.), Tmaxh(0.), Betah(0.), AveLogAlpha(0.), AveLogTmax(0.),
55 SigmaLogAlpha(0.), SigmaLogTmax(0.), Rho(0.), Alpha(0.), Tmax(0.), Beta(0.)
56{
57 if(!aPar) {
58 thePar = new GFlashSamplingShowerTuning;
59 } else {
60 thePar = aPar;
61 }
62
63 SetMaterial(aMat1,aMat2 );
64 d1=dd1;
65 d2=dd2;
66
67 // Longitudinal Coefficients for a homogenious calo
68
69 // shower max
70 ParAveT1 = thePar->ParAveT1(); // ln (ln y -0.812)
71 ParAveA1 = thePar->ParAveA1(); // ln a (0.81 + (0.458 + 2.26/Z)ln y)
72 ParAveA2 = thePar->ParAveA2();
73 ParAveA3 = thePar->ParAveA3();
74 // Variance of shower max sampling
75 ParSigLogT1 = thePar->ParsSigLogT1(); // Sigma T1 (-1.4 + 1.26 ln y)**-1 --> bug : these two lines were missing,
76 ParSigLogT2 = thePar->ParsSigLogT2(); // leaving ParSigLogT1, ParSigLogT2 as 0.0
77 // variance of 'alpha'
78 ParSigLogA1 = thePar->ParSigLogA1(); // Sigma a (-0.58 + 0.86 ln y)**-1 --> bug : these two lines were missing
79 ParSigLogA2 = thePar->ParSigLogA2(); // leaving ParSigLogA1 ParSigLogAé as 0.0
80 // correlation alpha%T
81 ParRho1 = thePar->ParRho1(); // Rho = 0.705 -0.023 ln y --> bug : these two lines were missing,
82 ParRho2 = thePar->ParRho2(); // leaving ParRho1 and ParRho2 being 0.0
83 // Sampling
84 ParsAveT1 = thePar->ParsAveT1(); // T_sam = log(exp( log T_hom) + t1*Fs-1 + t2*(1-ehat));
85 ParsAveT2 = thePar->ParsAveT2();
86 ParsAveA1 = thePar->ParsAveA1();
87 // Variance of shower max sampling
88 ParsSigLogT1 = thePar->ParsSigLogT1(); // Sigma T1 (-2.5 + 1.25 ln y)**-1 --> bug ParSigLogT1() was called instead of ParsSigLogT1(); Same for T2.
89 ParsSigLogT2 = thePar->ParsSigLogT2();
90 // variance of 'alpha'
91 ParsSigLogA1 = thePar->ParsSigLogA1(); // Sigma a (-0.82 + 0.79 ln y)**-1 --> bug ParSigLogA1() was called instead of ParsSigLogA1(); Same for A2
92 ParsSigLogA2 = thePar->ParsSigLogA2();
93 // correlation alpha%T
94 ParsRho1 = thePar->ParsRho1(); // Rho = 0.784 -0.023 ln y --> bug was using ParRho1() and ParRho2()
95 ParsRho2 = thePar->ParsRho2();
96
97 // Radial Coefficients
98 // r_C (tau)= z_1 +z_2 tau
99 // r_t (tau)= k1 (std::exp (k3(tau -k2 ))+std::exp (k_4 (tau- k_2))))
100 ParRC1 = thePar->ParRC1(); // z_1 = 0.0251 + 0.00319 ln E
101 ParRC2 = thePar->ParRC2();
102 ParRC3 = thePar->ParRC3(); // z_2 = 0.1162 + - 0.000381 Z
103 ParRC4 = thePar->ParRC4();
104
105 ParWC1 = thePar->ParWC1();
106 ParWC2 = thePar->ParWC2();
107 ParWC3 = thePar->ParWC3();
108 ParWC4 = thePar->ParWC4();
109 ParWC5 = thePar->ParWC5();
110 ParWC6 = thePar->ParWC6();
111 ParRT1 = thePar->ParRT1();
112 ParRT2 = thePar->ParRT2();
113 ParRT3 = thePar->ParRT3();
114 ParRT4 = thePar->ParRT4();
115 ParRT5 = thePar->ParRT5();
116 ParRT6 = thePar->ParRT6();
117
118 //additional sampling parameter
119 ParsRC1= thePar->ParsRC1();
120 ParsRC2= thePar->ParsRC2();
121 ParsWC1= thePar->ParsWC1();
122 ParsWC2= thePar->ParsWC2();
123 ParsRT1= thePar->ParsRT1();
124 ParsRT2= thePar->ParsRT2();
125
126 // Coeff for fluctuedted radial profiles for a sampling media
127 ParsSpotT1 = thePar->ParSpotT1(); // T_spot = T_hom =(0.698 + 0.00212)
128 ParsSpotT2 = thePar->ParSpotT2();
129 ParsSpotA1 = thePar->ParSpotA1(); // a_spot= a_hom (0.639 + 0.00334)
130 ParsSpotA2 = thePar->ParSpotA2();
131 ParsSpotN1 = thePar->ParSpotN1(); // N_Spot 93 * ln(Z) E ** 0.876
132 ParsSpotN2 = thePar->ParSpotN2();
133 SamplingResolution = thePar->SamplingResolution();
134 ConstantResolution = thePar->ConstantResolution();
135 NoiseResolution = thePar->NoiseResolution();
136
137 // Inits
138 NSpot = 0.00;
139 AlphaNSpot = 0.00;
140 TNSpot = 0.00;
141 BetaNSpot = 0.00;
142 RadiusCore = 0.00;
143 WeightCore = 0.00;
144 RadiusTail = 0.00;
146
147 G4cout << "/********************************************/ " << G4endl;
148 G4cout << " - GFlashSamplingShowerParameterisation::Constructor - " << G4endl;
149 G4cout << "/********************************************/ " << G4endl;
150}
151
152// ------------------------------------------------------------
153
158
159// ------------------------------------------------------------
160
163{
164 G4double Es = 21*MeV;
165 material1= mat1;
166 Z1 = GetEffZ(material1);
167 A1 = GetEffA(material1);
168 density1 = material1->GetDensity();
169 X01 = material1->GetRadlen();
170 Ec1 = 2.66 * std::pow((X01 * Z1 / A1),1.1);
171 Rm1 = X01*Es/Ec1;
172
173 material2= mat2;
174 Z2 = GetEffZ(material2);
175 A2 = GetEffA(material2);
176 density2 = material2->GetDensity();
177 X02 = material2->GetRadlen();
178 Ec2 = 2.66 * std::pow((X02 * Z2 / A2),1.1);
179 Rm2 = X02*Es/Ec2;
180 // PrintMaterial();
181}
182
183// ------------------------------------------------------------
184
186{
187 G4cout << "/************ ComputeZAX0EFFetc ************/" << G4endl;
188 G4cout << " - GFlashSamplingShowerParameterisation::Material - " << G4endl;
189
190 G4double Es = 21*MeV; //constant
191
192 // material and geometry parameters for a sampling calorimeter
193 G4double denominator = (d1*density1 + d2*density2);
194 G4double W1 = (d1*density1) / denominator;
195 G4double W2 = (d2*density2) / denominator;
196 Zeff = ( W1*Z1 ) + ( W2*Z2 ); //X0*Es/Ec;
197 Aeff = ( W1*A1 ) + ( W2*A2 );
198 Rhoeff = ( ( d1*density1 ) + ( d2*density2 ) ) / ( d1 + d2 ); // --> was G4double ( d2 + d1 );
199 X0eff = (W1 * Rhoeff) / (X01 * density1) + (W2 * Rhoeff) / (X02 * density2 );
200 X0eff = 1./ X0eff;
201 Rmeff = 1./ ( ( ((W1*Ec1)/X01) + ((W2*Ec2)/X02) ) / Es ) ;
202 Eceff = X0eff * ( (W1*Ec1)/X01 + (W2*Ec2)/X02 );
203 Fs = X0eff/(d1+d2);// --> was G4double ((d1/mm )+(d2/mm) ); Can't understand if dividing by mm makes sense... looks weird.
204 ehat = ( 1. / ( 1 + 0.007*(Z1- Z2) ) );
205
206 G4cout << "W1= " << W1 << G4endl;
207 G4cout << "W2= " << W2 << G4endl;
208 G4cout << "effective quantities Zeff = "<<Zeff<< G4endl;
209 G4cout << "effective quantities Aeff = "<<Aeff<< G4endl;
210 G4cout << "effective quantities Rhoeff = "<<Rhoeff/g *cm3<<" g/cm3" << G4endl;
211 G4cout << "effective quantities X0eff = "<<X0eff/cm <<" cm" << G4endl;
212
213 X0eff = X0eff * Rhoeff;
214
215 G4cout << "effective quantities X0eff = "<<X0eff/g*cm2 <<" g/cm2" << G4endl;
216 X0eff = X0eff /Rhoeff;
217 G4cout << "effective quantities RMeff = "<<Rmeff/cm<<" cm" << G4endl;
218 Rmeff = Rmeff* Rhoeff;
219 G4cout << "effective quantities RMeff = "<<Rmeff/g *cm2<<" g/cm2" << G4endl;
220 Rmeff = Rmeff/ Rhoeff;
221 G4cout << "effective quantities Eceff = "<<Eceff/MeV<< " MeV"<< G4endl;
222 G4cout << "effective quantities Fs = "<<Fs<<G4endl;
223 G4cout << "effective quantities ehat = "<<ehat<<G4endl;
224 G4cout << "/********************************************/ " <<G4endl;
225}
226
227// ------------------------------------------------------------
228
231{
232 if ((material1==0) || (material2 ==0))
233 {
234 G4Exception("GFlashSamplingShowerParameterisation::GenerateLongitudinalProfile()",
235 "InvalidSetup", FatalException, "No material initialized!");
236 }
237 G4double y = Energy/Eceff;
238 ComputeLongitudinalParameters(y);
239 GenerateEnergyProfile(y);
240 GenerateNSpotProfile(y);
241}
242
243// ------------------------------------------------------------
244
245void
246GFlashSamplingShowerParameterisation::ComputeLongitudinalParameters(G4double y)
247{
248 AveLogTmaxh = std::log( std::max( ParAveT1 + std::log(y), 0.1 ) ); // ok
249 AveLogAlphah = std::log( std::max( ParAveA1 + (ParAveA2+ParAveA3/Zeff)*std::log(y), 0.1 ) ); // ok
250 // hom
251 SigmaLogTmaxh = std::min( 0.5, 1.00/( ParSigLogT1 + ParSigLogT2*std::log(y) ) ); // ok
252 SigmaLogAlphah = std::min( 0.5, 1.00/( ParSigLogA1 + ParSigLogA2*std::log(y) ) ); // ok
253 Rhoh = ParRho1 + ParRho2*std::log(y); //ok
254 // if sampling
255 AveLogTmax = std::max( 0.1, std::log(std::exp(AveLogTmaxh) + ParsAveT1/Fs + ParsAveT2*(1-ehat)) ); // ok
256 AveLogAlpha = std::max( 0.1, std::log(std::exp(AveLogAlphah) + ParsAveA1/Fs) ); // ok
257 //
258 SigmaLogTmax = std::min( 0.5, 1.00 / (ParsSigLogT1 + ParsSigLogT2*std::log(y)) ); // ok
259 SigmaLogAlpha = std::min( 0.5, 1.00 / (ParsSigLogA1 + ParsSigLogA2*std::log(y)) ); // ok
260 Rho = ParsRho1 + ParsRho2*std::log(y); // ok
261
262
263 if (0) {
264 G4cout << " y = " << y << G4endl;
265 G4cout << " std::log(std::exp(AveLogTmaxh) + ParsAveT1/Fs + ParsAveT2*(1-ehat)) = "
266 << " std::log(" << std::exp(AveLogTmaxh) << " + " << ParsAveT1/Fs << " + " << ParsAveT2*(1-ehat) << ") = "
267 << " std::log(" << std::exp(AveLogTmaxh) << " + " << ParsAveT1 << "/" << Fs << " + " << ParsAveT2 << "*" << (1-ehat) << ") = "
268 << " std::log(" << std::exp(AveLogTmaxh) + ParsAveT1/Fs + ParsAveT2*(1-ehat) << ")" << G4endl;
269 G4cout << " AveLogTmaxh " << AveLogTmaxh << G4endl;
270 G4cout << " AveLogAlphah " << AveLogAlphah << G4endl;
271 G4cout << " SigmaLogTmaxh " << SigmaLogTmaxh << G4endl;
272 G4cout << " 1.00/( ParSigLogT1 + ParSigLogT2*std::log(y) ) = " << 1.00 << "/" << ( ParSigLogT1 + ParSigLogT2*std::log(y) ) << " = "
273 << 1.00 << "/" << "(" << ParSigLogT1 << " + " << ParSigLogT2*std::log(y) << " ) = "
274 << 1.00 << "/" << "(" << ParSigLogT1 << " + " << ParSigLogT2 << "*" << std::log(y) << " ) "
275 << G4endl;
276 G4cout << " SigmaLogAlphah " << SigmaLogAlphah << G4endl;
277 G4cout << " Rhoh " << Rhoh << G4endl;
278 G4cout << " AveLogTmax " << AveLogTmax << G4endl;
279 G4cout << " AveLogAlpha " << AveLogAlpha << G4endl;
280 G4cout << " SigmaLogTmax " << SigmaLogTmax << G4endl;
281 G4cout << " SigmaLogAlpha " << SigmaLogAlpha << G4endl;
282 G4cout << " Rho " << Rho << G4endl;
283 }
284}
285
286// ------------------------------------------------------------
287
288void GFlashSamplingShowerParameterisation::GenerateEnergyProfile(G4double /* y */)
289{
290 G4double Correlation1 = std::sqrt( (1+Rho )/2 );
291 G4double Correlation2 = std::sqrt( (1-Rho )/2 );
292 G4double Correlation1h = std::sqrt( (1+Rhoh)/2 );
293 G4double Correlation2h = std::sqrt( (1-Rhoh)/2 );
294 G4double Random1 = G4RandGauss::shoot();
295 G4double Random2 = G4RandGauss::shoot();
296
297 Tmax = std::max( 1., std::exp( AveLogTmax + SigmaLogTmax * (Correlation1*Random1 + Correlation2*Random2) ) );
298 Alpha = std::max( 1.1, std::exp( AveLogAlpha + SigmaLogAlpha * (Correlation1*Random1 - Correlation2*Random2) ) );
299 Beta = (Alpha-1.00)/Tmax;
300 //Parameters for Enenrgy Profile including correaltion and sigmas
301 Tmaxh = std::exp( AveLogTmaxh + SigmaLogTmaxh *
302 (Correlation1h*Random1 + Correlation2h*Random2) );
303 Alphah = std::exp( AveLogAlphah + SigmaLogAlphah *
304 (Correlation1h*Random1 - Correlation2h*Random2) );
305 Betah = (Alphah-1.00)/Tmaxh;
306}
307
308// ------------------------------------------------------------
309
310void GFlashSamplingShowerParameterisation::GenerateNSpotProfile(const G4double y)
311{
312 TNSpot = Tmaxh * (ParsSpotT1+ParsSpotT2*Zeff); //ok.
313 TNSpot = std::max(0.5,Tmaxh * (ParsSpotT1+ParsSpotT2*Zeff));
314 AlphaNSpot = Alphah * (ParsSpotA1+ParsSpotA2*Zeff);
315 BetaNSpot = (AlphaNSpot-1.00)/TNSpot; // ok
316 NSpot = ParsSpotN1 /SamplingResolution * std::pow(y*Eceff/GeV,ParsSpotN2 );
317}
318
319// ------------------------------------------------------------
320
323ApplySampling(const G4double DEne, const G4double )
324{
325 G4double DEneFluctuated = DEne;
326 G4double Resolution = std::pow(SamplingResolution,2);
327
328 // +pow(NoiseResolution,2)/ //@@@@@@@@ FIXME
329 // Energy*(1.*MeV)+
330 // pow(ConstantResolution,2)*
331 // Energy/(1.*MeV);
332
333 if(Resolution >0.0 && DEne > 0.00)
334 {
335 G4float x1=DEne/Resolution;
336 G4float x2 = G4RandGamma::shoot(x1, 1.0)*Resolution;
337 DEneFluctuated=x2;
338 }
339 return DEneFluctuated;
340}
341
342// ------------------------------------------------------------
343
345IntegrateEneLongitudinal(G4double LongitudinalStep)
346{
347 G4double LongitudinalStepInX0 = LongitudinalStep / X0eff;
348 G4float x1= Betah*LongitudinalStepInX0;
349 G4float x2= Alphah;
350 float x3 = gam(x1,x2);
351 G4double DEne=x3;
352 return DEne;
353}
354
355// ------------------------------------------------------------
356
358IntegrateNspLongitudinal(G4double LongitudinalStep)
359{
360 G4double LongitudinalStepInX0 = LongitudinalStep / X0eff;
361 G4float x1 = BetaNSpot*LongitudinalStepInX0;
362 G4float x2 = AlphaNSpot;
363 G4float x3 = gam(x1,x2);
364 G4double DNsp = x3;
365 return DNsp;
366}
367
368// ------------------------------------------------------------
369
371GenerateRadius(G4int ispot, G4double Energy, G4double LongitudinalPosition)
372{
373 if(ispot < 1)
374 {
375 // Determine lateral parameters in the middle of the step.
376 // They depend on energy & position along step
377 //
378 G4double Tau = ComputeTau(LongitudinalPosition);
379 ComputeRadialParameters(Energy,Tau);
380 }
381
382 G4double Radius;
383 G4double Random1 = G4UniformRand();
384 G4double Random2 = G4UniformRand();
385 if(Random1 <WeightCore) //WeightCore = p < w_i
386 {
387 Radius = Rmeff * RadiusCore * std::sqrt( Random2/(1. - Random2) );
388 }
389 else
390 {
391 Radius = Rmeff * RadiusTail * std::sqrt( Random2/(1. - Random2) );
392 }
393 Radius = std::min(Radius,DBL_MAX);
394 return Radius;
395}
396
397// ------------------------------------------------------------
398
401ComputeTau(G4double LongitudinalPosition)
402{
403 G4double tau = LongitudinalPosition / Tmax/ X0eff //<t> = T* a /(a - 1)
404 * (Alpha-1.00) /Alpha
405 * std::exp(AveLogAlpha)/(std::exp(AveLogAlpha)-1.); //ok
406 return tau;
407}
408
409// ------------------------------------------------------------
410
413{
414 G4double z1 = ParRC1 + ParRC2* std::log(Energy/GeV); //ok
415 G4double z2 = ParRC3+ParRC4*Zeff; //ok
416 RadiusCore = z1 + z2 * Tau; //ok
417 G4double p1 = ParWC1+ParWC2*Zeff; //ok
418 G4double p2 = ParWC3+ParWC4*Zeff; //ok
419 G4double p3 = ParWC5+ParWC6*std::log(Energy/GeV); //ok
420 WeightCore = p1 * std::exp( (p2-Tau)/p3- std::exp( (p2-Tau) /p3) ); //ok
421
422 G4double k1 = ParRT1+ParRT2*Zeff; // ok
423 G4double k2 = ParRT3; // ok
424 G4double k3 = ParRT4; // ok
425 G4double k4 = ParRT5+ParRT6* std::log(Energy/GeV); // ok
426
427 RadiusTail = k1*(std::exp(k3*(Tau-k2))
428 + std::exp(k4*(Tau-k2)) ); //ok
429
430 // sampling calorimeter
431
432 RadiusCore = RadiusCore + ParsRC1*(1-ehat) + ParsRC2/Fs*std::exp(-Tau); //ok
433 WeightCore = WeightCore + (1-ehat)
434 * (ParsWC1+ParsWC2/Fs * std::exp(-std::pow((Tau-1.),2))); //ok
435 RadiusTail = RadiusTail + (1-ehat)* ParsRT1+ ParsRT2/Fs *std::exp(-Tau); //ok
436}
437
438// ------------------------------------------------------------
439
441GenerateExponential(const G4double /* Energy */ )
442{
443 G4double ParExp1 = 9./7.*X0eff;
444 G4double random = -ParExp1*G4RandExponential::shoot() ;
445 return random;
446}
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
float G4float
Definition G4Types.hh:84
double G4double
Definition G4Types.hh:83
int G4int
Definition G4Types.hh:85
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition Randomize.hh:52
G4double GetDensity() const
G4double GetRadlen() const
G4double GenerateRadius(G4int ispot, G4double Energy, G4double LongitudinalPosition)
GFlashSamplingShowerParameterisation(G4Material *aMat1, G4Material *aMat2, G4double d1, G4double d2, GFlashSamplingShowerTuning *aPar=0)
G4double ApplySampling(const G4double DEne, const G4double Energy)
G4double IntegrateNspLongitudinal(G4double LongitudinalStep)
G4double IntegrateEneLongitudinal(G4double LongitudinalStep)
G4double ComputeTau(G4double LongitudinalPosition)
void SetMaterial(G4Material *mat1, G4Material *mat2)
G4double GetEffZ(const G4Material *material)
G4double GetEffA(const G4Material *material)
G4double gam(G4double x, G4double a) const
#define DBL_MAX
Definition templates.hh:62