source: trunk/WuerzburgSoft/Thomas/mphys/MElectron.cc@ 1369

Last change on this file since 1369 was 1369, checked in by tbretz, 22 years ago
*** empty log message ***
File size: 9.3 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Harald Kornmayer 1/2001 (harald@mppmu.mpg.de)
19! Author(s): Thomas Bretz 12/2000 (tbretz@uni-sw.gwdg.de)
20!
21! Copyright: MAGIC Software Development, 2000-2001
22!
23!
24\* ======================================================================== */
25
26//////////////////////////////////////////////////////////////////////////////
27// //
28// //
29//////////////////////////////////////////////////////////////////////////////
30#include "MElectron.h"
31
32#include <iostream.h>
33
34#include <TF1.h>
35#include <TH1.h>
36#include <TPad.h>
37#include <TCanvas.h>
38#include <TRandom.h>
39
40#include "MPhoton.h"
41
42ClassImp(MElectron);
43
44Double_t MElectron::Li(Double_t *x, Double_t *k)
45{
46 const Double_t t = x[0];
47 return log(1.-t)/t;
48}
49
50Double_t DiSum(Double_t *x, Double_t *k=NULL)
51{
52 Double_t t = x[0];
53
54 const Double_t eps = fabs(t*1e-2);
55
56 Double_t disum = t;
57 Double_t add = 0;
58
59 Int_t n = 2;
60 Double_t pow = t*t; // t^2
61
62 do
63 {
64 add = pow/n/n;
65
66 pow *= t; // pow = t^n
67 n++;
68
69 disum += add;
70
71 } while (fabs(add)>eps);
72
73 return disum;
74}
75
76Double_t MElectron::Li2(Double_t *x, Double_t *k=NULL)
77{
78 //
79 // Dilog, Li2
80 // ----------
81 //
82 // Integral(0, 1) = konst;
83 // Double_t konst = 1./6*TMath::Pi()*TMath::Pi();
84 //
85 // x[0]: z
86 //
87 const Double_t z = x[0];
88
89 if (fabs(z)<1)
90 return DiSum(x);
91
92 // TF1 IntLi("Li", Li, 0, z, 0);
93 static TF1 IntLi("Li", Li, 0, 0, 0);
94 const Double_t integ = IntLi.Integral(0, z, (Double_t*)NULL, 1e-2);
95 return -integ;
96}
97
98Double_t MElectron::Flim(Double_t *x, Double_t *k=NULL) // F(omegap)-F(omegam) mit b-->1 (Maple)
99{
100 const Double_t w = x[0];
101
102 const Double_t w4 = w*4;
103 const Double_t wsqr = w*w;
104
105 const Double_t u1 = (w*wsqr*16 + wsqr*40 + w*17 + 2)*log(w4 + 1);
106 const Double_t u2 = -w4*(wsqr*2 + w*9 + 2);
107 const Double_t d = w4*(w4 + 1);
108
109 Double_t s = -w*2*(1+1); // -2*omega*(1+beta)
110 const Double_t li2 = Li2(&s);
111
112 const Double_t res = (u1+u2)/d + li2;
113
114 return res; //<1e-10? 0 : res;
115}
116
117Double_t MElectron::Compton(Double_t *x, Double_t *k)
118{
119 const Double_t E0 = 511e-6; //[GeV]
120
121 Double_t epsilon = x[0];
122 Double_t z = k[1];
123
124 const Double_t E = k[0];
125
126 Double_t omega = epsilon*E/(E0*E0);
127
128 const Double_t n = MParticle::Planck(&epsilon, &z)/epsilon/epsilon; // [1]
129 return Flim(&omega)*n;
130}
131
132Double_t MElectron::InteractionLength(Double_t *E, Double_t *k=NULL)
133{
134 // E = electron energy, ~ TeV(?) 1e12
135 // e = photon energy, ~ meV(?) 1e-3
136 // mc^2 = electron rest mass energy ~.5keV(?) .5e3
137 //
138 // x^-1 = int( n(epsilon)/2beta * ((mc^2)^2/eE)^2 * int ( omega*sigma(omega), omega=o-..o+), epsilon=0..inf)
139 //
140 // o+/- = omage_0 (1 +- beta)
141 //
142 // omega_0 = eE/(mc^2)^2 ~1e12*1e-3/.25e6=4e3
143 //
144 // --> x^-1 = (alpha*hc)^2/4pibetaE^2 * int(n(epsilon)/epsilon^2 *( F(o+)-F(o-)), epsilon=0..inf)
145 //
146 // F(o) = -o/4 + (9/4 + 1/o + o/2) * ln(1+2o) + 1/8(1+2o) - 3/8 + Li2(-2o)
147 //
148 // Li2(x) = int(ln(1-t)/t, t=0..x)
149 //
150 // F(o+)~F(2o) = -o/2 + (9/4 + 1/2o + o) * ln(1+4o) + 1/8(1+4o) - 3/8 + Li2(-4o)
151 // F(o-)~F(0) = 14/8 = 1.75
152
153 const Double_t E0 = 511e-6; // [GeV]
154 const Double_t E02 = E0*E0; // [GeV^2]
155 const Double_t c = 299792458; // [m/s]
156 const Double_t e = 1.602176462e-19; // [C]
157 const Double_t h = 1e-9/e*6.62606876e-34; // [GeVs]
158 const Double_t hc = h*c; // [GeVm]
159 const Double_t alpha = 1./137.; // [1]
160
161 const Double_t z = k ? k[0] : 0;
162
163 /* -------------- old ----------------
164 Double_t from = 1e-15;
165 Double_t to = 1e-11;
166 eps = [default];
167 -----------------------------------
168 */
169 static TF1 func("Compton", Compton, 0, 0, 2); // [0, inf]
170
171 const Double_t from = 1e-17;
172 const Double_t to = 1e-11;
173
174 Double_t val[3] = { E[0], z }; // E[GeV]
175
176 Double_t integ = func.Integral(from, to, val, 1e-2); // [Gev] [0, inf]
177
178 const Double_t aE = alpha/E[0]; // [1/GeV]
179
180 const Double_t beta = 1;
181
182 const Double_t konst = 2.*E02/hc/beta; // [1 / GeV m]
183 const Double_t ret = konst * (aE*aE) * integ; // [1 / m]
184
185 const Double_t ly = 3600.*24.*365.*c; // [m/ly]
186 const Double_t pc = 1./3.258; // [pc/ly]
187
188 return (1./ret)/ly*pc/1000; // [kpc]
189}
190
191Double_t MElectron::GetInteractionLength(Double_t energy, Double_t z)
192{
193 return InteractionLength(&energy, &z);
194}
195
196Double_t MElectron::GetInteractionLength() const
197{
198 return InteractionLength((Double_t*)&fEnergy, (Double_t*)&fZ);
199}
200
201// --------------------------------------------------------------------------
202
203inline Double_t MElectron::p_e(Double_t *x, Double_t *k)
204{
205 Double_t e = pow(10, x[0]);
206 return Compton(&e, k);
207 /*
208 Double_t z = k[1];
209
210 const Double_t E = k[0];
211
212 const Double_t E0 = 511e-6; //[GeV]
213 const Double_t E02 = E0*E0;
214
215 Double_t omega = e*E/E02;
216
217 const Double_t n = Planck(&e, &z);
218
219 const Double_t F = Flim(&omega)/omega/omega;
220
221 return n*F*1e26;
222 */
223}
224
225Double_t MElectron::G_q(Double_t *x, Double_t *k)
226{
227 const Double_t q = x[0];
228 const Double_t Gamma = k[0];
229
230 const Double_t Gq = Gamma*q;
231
232 const Double_t s1 = 2.*q*log(q);
233 const Double_t s2 = (1.+2.*q);
234 const Double_t s3 = (Gq*Gq)/(1.+Gq)/2.;
235
236 return s1+(s2+s3)*(1.-q);
237}
238
239
240Double_t MElectron::EnergyLoss(Double_t *x, Double_t *k, Double_t *ep)
241{
242 const Double_t E = x[0];
243 const Double_t z = k ? k[0] : 0;
244
245 const Double_t E0 = 511e-6; //[GeV]
246
247 const Double_t lolim = -log10(E)/7*4-13;
248
249 TF1 fP("p_e", p_e, lolim, -10.8, 2);
250 TF1 fQ("G", G_q, 0, 1., 1);
251
252 fP.SetParameter(0, E);
253 fP.SetParameter(1, z);
254
255 const Double_t e = pow(10, fP.GetRandom());
256
257 if (ep)
258 *ep = e;
259
260 const Double_t omega = e*E/E0/E0;
261 const Double_t Gamma = 4.*omega;
262
263 fQ.SetParameter(0, Gamma);
264
265 const Double_t q = fQ.GetRandom();
266 const Double_t Gq = Gamma*q;
267
268 const Double_t e1 = Gq*E/(1.+Gq);
269
270 return e1;
271}
272
273Double_t MElectron::GetEnergyLoss(Double_t E, Double_t z, Double_t *ep)
274{
275 return EnergyLoss(&E, &z);
276}
277
278Double_t MElectron::GetEnergyLoss(Double_t *ep) const
279{
280 return EnergyLoss((Double_t*)&fEnergy, (Double_t*)&fZ, ep);
281}
282
283MPhoton *MElectron::DoInvCompton(Double_t theta)
284{
285 static TRandom rand(0);
286
287 const Double_t E0 = 511e-6; //[GeV]
288
289 Double_t epsilon;
290 const Double_t e = GetEnergyLoss(&epsilon);
291
292 // er: photon energy before interaction, rest frame
293 // e: photon energy after interaction, lab
294
295 const Double_t gamma = fEnergy/E0;
296 const Double_t beta = sqrt(1.-1./(gamma*gamma));
297
298 const Double_t f = fEnergy/e;
299
300 Double_t t=-1;
301 Double_t arg;
302 do
303 {
304 if (t>0)
305 cout << "~" << flush;
306 t = rand.Uniform(TMath::Pi()/2)+TMath::Pi()*3/4;
307 Double_t er = gamma*epsilon*(1.-beta*cos(t)); // photon energy rest frame
308 arg = (f - E0/er - 1)/(f*beta+1);
309
310 } while (arg<-1 || arg>1);
311
312 const Double_t theta1s = acos(arg);
313 const Double_t thetas = atan(sin(t)/(gamma*(cos(t)-beta)));
314
315 const Double_t thetastar = thetas-theta1s;
316
317 const Double_t theta1 = atan(sin(thetastar)/(gamma*(cos(thetastar)+beta)));
318
319 fEnergy -= e;
320
321 const Double_t phi = rand.Uniform(TMath::Pi()*2);
322
323 MPhoton &p = *new MPhoton(e, fZ);
324 p = *this;
325 p.SetNewDirection(theta1, phi);
326
327 const Double_t beta2 = sqrt(1.-E0/fEnergy*E0/fEnergy);
328 const Double_t theta2 = asin((epsilon*sin(t)-e*sin(theta1))/fEnergy/beta2);
329
330 SetNewDirection(theta2, phi);
331
332 return &p;
333}
334
335void MElectron::DrawInteractionLength(Double_t z)
336{
337 if (!gPad)
338 new TCanvas("IL_Electron", "Mean Interaction Length Electron");
339 else
340 gPad->GetVirtCanvas()->cd(3);
341
342 TF1 f2("length", MElectron::InteractionLength, 1e3, 1e10, 0);
343 f2.SetParameter(0, z);
344
345 gPad->SetLogx();
346 gPad->SetLogy();
347 gPad->SetGrid();
348 f2.SetLineWidth(1);
349
350 TH1 &h=*f2.DrawCopy()->GetHistogram();
351
352 h.SetTitle("Mean Interaction Length (Electron)");
353 h.SetXTitle("E [GeV]");
354 h.SetYTitle("x [kpc]");
355
356 gPad->Modified();
357 gPad->Update();
358}
359
360void MElectron::DrawInteractionLength() const
361{
362 DrawInteractionLength(fZ);
363}
Note: See TracBrowser for help on using the repository browser.