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): Wolfgang Wittek 5/2002 <mailto:wittek@mppmu.mpg.de>
|
---|
19 | !
|
---|
20 | ! Copyright: MAGIC Software Development, 2000-2002
|
---|
21 | !
|
---|
22 | !
|
---|
23 | \* ======================================================================== */
|
---|
24 |
|
---|
25 | //////////////////////////////////////////////////////////////////////////////
|
---|
26 | // //
|
---|
27 | // MHFlux //
|
---|
28 | // //
|
---|
29 | // calculates absolute photon fluxes //
|
---|
30 | // from the distributions of the estimated energy //
|
---|
31 | // for the different bins in some variable 'Var' //
|
---|
32 | // (Var = Theta or time) //
|
---|
33 | // //
|
---|
34 | //////////////////////////////////////////////////////////////////////////////
|
---|
35 |
|
---|
36 | #include "MHFlux.h"
|
---|
37 |
|
---|
38 | #include <TStyle.h>
|
---|
39 |
|
---|
40 | #include <TF1.h>
|
---|
41 | #include <TH2.h>
|
---|
42 | #include <TProfile.h>
|
---|
43 |
|
---|
44 | #include <TCanvas.h>
|
---|
45 |
|
---|
46 | #include "MTime.h"
|
---|
47 |
|
---|
48 | #include "MBinning.h"
|
---|
49 | #include "MParList.h"
|
---|
50 |
|
---|
51 | #include "MLog.h"
|
---|
52 | #include "MLogManip.h"
|
---|
53 |
|
---|
54 | #include "MHThetabarTheta.h"
|
---|
55 | #include "MHEffOnTime.h"
|
---|
56 | #include "MHGamma.h"
|
---|
57 |
|
---|
58 | ClassImp(MHFlux);
|
---|
59 |
|
---|
60 | MHFlux::MHFlux(const MHGamma &hist, const TString varname, const TString unit)
|
---|
61 | : fHOrig(), fHUnfold(), fHFlux()
|
---|
62 | {
|
---|
63 | const TH2D &h2d = *hist.GetProject();
|
---|
64 |
|
---|
65 | if (varname.IsNull() || unit.IsNull())
|
---|
66 | *fLog << warn << dbginf << "varname or unit not defined" << endl;
|
---|
67 |
|
---|
68 | fVarname = varname;
|
---|
69 | fUnit = unit;
|
---|
70 |
|
---|
71 | // char txt[100];
|
---|
72 |
|
---|
73 | // original distribution of E-est for different bins
|
---|
74 | // of the variable (Theta or time)
|
---|
75 | // sprintf(txt, "gammas vs. E-est and %s",varname);
|
---|
76 |
|
---|
77 | ((TH2D&)h2d).Copy(fHOrig);
|
---|
78 |
|
---|
79 | fHOrig.SetName("E_est");
|
---|
80 | fHOrig.SetTitle(TString("No.of gammas vs. E-est and ")+fVarname);
|
---|
81 |
|
---|
82 | fHOrig.SetDirectory(NULL);
|
---|
83 | fHOrig.SetXTitle("E_{est} [GeV]");
|
---|
84 | fHOrig.SetYTitle(fVarname+fUnit);
|
---|
85 | //fHOrig.Sumw2();
|
---|
86 |
|
---|
87 | SetBinning((TH2*)&fHOrig, (TH2*)&h2d);
|
---|
88 |
|
---|
89 | fHOrig.Copy(fHUnfold);
|
---|
90 |
|
---|
91 | // unfolded distribution of E-unfold for different bins
|
---|
92 | // of the variable (Theta or time)
|
---|
93 | // sprintf(txt, "gammas vs. E-unfold and %s",varname);
|
---|
94 | fHUnfold.SetName("E-unfolded");
|
---|
95 | fHUnfold.SetTitle(TString("No.of gammas vs. E-unfold and ")+fVarname);
|
---|
96 |
|
---|
97 | fHUnfold.SetDirectory(NULL);
|
---|
98 | fHUnfold.SetXTitle("E_{unfold} [GeV]");
|
---|
99 | fHUnfold.SetYTitle(fVarname+fUnit);
|
---|
100 | //fHUnfold.Sumw2();
|
---|
101 |
|
---|
102 | SetBinning((TH2*)&fHUnfold, (TH2*)&fHOrig);
|
---|
103 |
|
---|
104 |
|
---|
105 | // absolute photon flux vs. E-unfold
|
---|
106 | // for different bins of the variable (Theta or time)
|
---|
107 | //
|
---|
108 | // sprintf(txt, "gamma flux [1/(s m2 GeV) vs. E-unfold and %s",varname);
|
---|
109 | fHFlux.SetName("photon flux");
|
---|
110 | fHFlux.SetTitle(TString("Gamma flux [1/(s m^2 GeV) vs. E-unfold and ")+fVarname);
|
---|
111 |
|
---|
112 | fHFlux.SetDirectory(NULL);
|
---|
113 | fHFlux.SetXTitle("E_{unfold} [GeV]");
|
---|
114 | fHFlux.SetYTitle(fVarname+fUnit);
|
---|
115 | fHFlux.Sumw2();
|
---|
116 |
|
---|
117 | SetBinning((TH2*)&fHFlux, (TH2*)&fHUnfold);
|
---|
118 | }
|
---|
119 |
|
---|
120 | // --------------------------------------------------------------------------
|
---|
121 | //
|
---|
122 | // Default Constructor. It sets the variable name (Theta or time)
|
---|
123 | // and the units for the variable
|
---|
124 | //
|
---|
125 | MHFlux::MHFlux(const TH2D &h2d, const TString varname, const TString unit)
|
---|
126 | : fHOrig(), fHUnfold(), fHFlux()
|
---|
127 | {
|
---|
128 | if (varname.IsNull() || unit.IsNull())
|
---|
129 | *fLog << warn << dbginf << "varname or unit not defined" << endl;
|
---|
130 |
|
---|
131 | fVarname = varname;
|
---|
132 | fUnit = unit;
|
---|
133 |
|
---|
134 | // char txt[100];
|
---|
135 |
|
---|
136 | // original distribution of E-est for different bins
|
---|
137 | // of the variable (Theta or time)
|
---|
138 | // sprintf(txt, "gammas vs. E-est and %s",varname);
|
---|
139 |
|
---|
140 | ((TH2D&)h2d).Copy(fHOrig);
|
---|
141 |
|
---|
142 | fHOrig.SetName("E_est");
|
---|
143 | fHOrig.SetTitle(TString("No.of gammas vs. E-est and ")+fVarname);
|
---|
144 |
|
---|
145 | fHOrig.SetDirectory(NULL);
|
---|
146 | fHOrig.SetXTitle("E_{est} [GeV]");
|
---|
147 | fHOrig.SetYTitle(fVarname+fUnit);
|
---|
148 | //fHOrig.Sumw2();
|
---|
149 |
|
---|
150 | // copy fHOrig into fHUnfold in case no unfolding is done
|
---|
151 | fHOrig.Copy(fHUnfold);
|
---|
152 |
|
---|
153 | SetBinning((TH2*)&fHOrig, (TH2*)&h2d);
|
---|
154 |
|
---|
155 |
|
---|
156 | // unfolded distribution of E-unfold for different bins
|
---|
157 | // of the variable (Theta or time)
|
---|
158 | // sprintf(txt, "gammas vs. E-unfold and %s",varname);
|
---|
159 | fHUnfold.SetName("E-unfolded");
|
---|
160 | fHUnfold.SetTitle(TString("No.of gammas vs. E-unfold and ")+fVarname);
|
---|
161 |
|
---|
162 | fHUnfold.SetDirectory(NULL);
|
---|
163 | fHUnfold.SetXTitle("E_{unfold} [GeV]");
|
---|
164 | fHUnfold.SetYTitle(fVarname+fUnit);
|
---|
165 | //fHUnfold.Sumw2();
|
---|
166 |
|
---|
167 | SetBinning((TH2*)&fHUnfold, (TH2*)&fHOrig);
|
---|
168 |
|
---|
169 |
|
---|
170 | // absolute photon flux vs. E-unfold
|
---|
171 | // for different bins of the variable (Theta or time)
|
---|
172 | //
|
---|
173 | // sprintf(txt, "gamma flux [1/(s m2 GeV) vs. E-unfold and %s",varname);
|
---|
174 | fHFlux.SetName("photon flux");
|
---|
175 | fHFlux.SetTitle(TString("Gamma flux [1/(s m^{2} GeV)] vs. E-unfold and ")+fVarname);
|
---|
176 |
|
---|
177 | fHFlux.SetDirectory(NULL);
|
---|
178 | fHFlux.SetXTitle("E_{unfold} [GeV]");
|
---|
179 | fHFlux.SetYTitle(fVarname+fUnit);
|
---|
180 | fHFlux.Sumw2();
|
---|
181 |
|
---|
182 | SetBinning((TH2*)&fHFlux, (TH2*)&fHUnfold);
|
---|
183 | }
|
---|
184 |
|
---|
185 | // -------------------------------------------------------------------------
|
---|
186 | //
|
---|
187 | // Dummy Fill (has to be included because in base class MH Fill is set to 0
|
---|
188 | // (abstract member function));
|
---|
189 | // without the dummy Fill one gets the error message :
|
---|
190 | //
|
---|
191 | // Error: Can't call MHFlux::MHFlux(evttime,"time","[s]") in current scope
|
---|
192 | // FILE:macros/flux.C LINE:465
|
---|
193 | // Possible candidates are...
|
---|
194 | // filename line:size busy function type and name (in MHFlux)
|
---|
195 | // filename line:size busy function type and name (in MH)
|
---|
196 | // filename line:size busy function type and name (in MParContainer)
|
---|
197 | // filename line:size busy function type and name (in TObject)
|
---|
198 | //
|
---|
199 | Bool_t MHFlux::Fill(const MParContainer *par)
|
---|
200 | {
|
---|
201 | return kTRUE;
|
---|
202 | }
|
---|
203 |
|
---|
204 |
|
---|
205 | // -------------------------------------------------------------------------
|
---|
206 | //
|
---|
207 | // Unfold the distribution in E-est
|
---|
208 | //
|
---|
209 | void MHFlux::Unfold()
|
---|
210 | {
|
---|
211 | }
|
---|
212 |
|
---|
213 | void MHFlux::CalcFlux(const MHEffOnTime &teff, const MHThetabarTheta &thetabar,
|
---|
214 | const TH2D *aeff)
|
---|
215 | {
|
---|
216 | CalcFlux(teff.GetHist(), thetabar.GetHist(), aeff);
|
---|
217 | }
|
---|
218 |
|
---|
219 | Double_t MHFlux::ParabInterpolLog(const TAxis &axe, Int_t j,
|
---|
220 | Double_t y[], Double_t Ebar) const
|
---|
221 | {
|
---|
222 | const double t1 = log10(axe.GetBinLowEdge(j-1)) + log10(axe.GetBinUpEdge(j-1));
|
---|
223 | const double t2 = log10(axe.GetBinLowEdge(j)) + log10(axe.GetBinUpEdge(j));
|
---|
224 | const double t3 = log10(axe.GetBinLowEdge(j+1)) + log10(axe.GetBinUpEdge(j+1));
|
---|
225 |
|
---|
226 | const Double_t lebar = log10(Ebar);
|
---|
227 |
|
---|
228 | return Parab(t1/2, t2/2, t3/2, y[j-2], y[j-1], y[j], lebar);
|
---|
229 | }
|
---|
230 |
|
---|
231 | // --------------------------------------------------------------------
|
---|
232 | //
|
---|
233 | // determine bins for interpolation (k3 is the middle one) in bar.
|
---|
234 | // k0 denotes the bin from which the error is copied
|
---|
235 | //
|
---|
236 | void MHFlux::FindBins(const TAxis &axe, const Double_t bar, Int_t &k3, Int_t &k0) const
|
---|
237 | {
|
---|
238 | const Int_t n = axe.GetNbins();
|
---|
239 |
|
---|
240 | k3 = axe.FindFixBin(bar);
|
---|
241 | k0 = k3;
|
---|
242 |
|
---|
243 | if (k3<2)
|
---|
244 | {
|
---|
245 | k3 = 2;
|
---|
246 | if (bar<axe.GetBinLowEdge(2))
|
---|
247 | k0 = 1;
|
---|
248 | }
|
---|
249 |
|
---|
250 | if (k3>n-1)
|
---|
251 | {
|
---|
252 | k3 = n-1;
|
---|
253 | if (bar>axe.GetBinLowEdge(n))
|
---|
254 | k0 = n;
|
---|
255 | }
|
---|
256 |
|
---|
257 | if (bar>=axe.GetBinLowEdge(1) && bar<=axe.GetBinUpEdge(n))
|
---|
258 | return;
|
---|
259 |
|
---|
260 | *fLog << dbginf << "extrapolation: bar = " << bar;
|
---|
261 | *fLog << ", min =" << axe.GetBinLowEdge(1);
|
---|
262 | *fLog << ", max =" << axe.GetBinUpEdge(n) << endl;
|
---|
263 | }
|
---|
264 |
|
---|
265 | Double_t MHFlux::ParabInterpolCos(const TAxis &axe, const TH2D *aeff, Int_t j, Int_t k3, Double_t val) const
|
---|
266 | {
|
---|
267 | const double t1 = cos( axe.GetBinCenter (k3-1) );
|
---|
268 | const double t2 = cos( axe.GetBinCenter (k3) );
|
---|
269 | const double t3 = cos( axe.GetBinCenter (k3+1) );
|
---|
270 |
|
---|
271 | const double a1 = aeff->GetBinContent(j, k3-1);
|
---|
272 | const double a2 = aeff->GetBinContent(j, k3);
|
---|
273 | const double a3 = aeff->GetBinContent(j, k3+1);
|
---|
274 |
|
---|
275 | return Parab(t1, t2, t3, a1, a2, a3, val);
|
---|
276 | }
|
---|
277 |
|
---|
278 | // -------------------------------------------------------------------------
|
---|
279 | //
|
---|
280 | // Calculate photon flux by dividing the distribution in Eunf (fHUnfold) by
|
---|
281 | // the width of the energy interval (deltaE)
|
---|
282 | // the effective ontime (*teff)
|
---|
283 | // and the effective collection area (*aeff)
|
---|
284 | //
|
---|
285 | void MHFlux::CalcFlux(const TH1D *teff, const TProfile *thetabar,
|
---|
286 | const TH2D *aeff)
|
---|
287 | {
|
---|
288 | //
|
---|
289 | // Note that fHUnfold has bins in Eunf and Var
|
---|
290 | // *teff has bins in Var (the same bins in Var as fHUnfold)
|
---|
291 | // *thetabar has bins in Var (the same bins in Var as fHUnfold)
|
---|
292 | // *aeff has bins in Etru and Theta
|
---|
293 | // (where in general the binning in Etru is different
|
---|
294 | // from the binning in Eunf)
|
---|
295 | // The variable Var may be 'time' or 'Theta'
|
---|
296 |
|
---|
297 | const TAxis &axex = *((TH2*)aeff)->GetXaxis();
|
---|
298 | const TAxis &axey = *((TH2*)aeff)->GetYaxis();
|
---|
299 |
|
---|
300 | if (axex.GetNbins()<3)
|
---|
301 | {
|
---|
302 | *fLog << err << "ERROR - Number of Energy bins <3 not implemented!" << endl;
|
---|
303 | return;
|
---|
304 | }
|
---|
305 |
|
---|
306 | if (axey.GetNbins()<3)
|
---|
307 | *fLog << warn << "WARNING - Less than 3 theta-bins not supported very well!" << endl;
|
---|
308 |
|
---|
309 | //
|
---|
310 | // calculate effective collection area
|
---|
311 | // for the Eunf and Var bins of the histogram fHUnfold
|
---|
312 | // from the histogram *aeff, which has bins in Etru and Theta
|
---|
313 | // the result is the histogram fHAeff
|
---|
314 | //
|
---|
315 | TH2D fHAeff;
|
---|
316 | SetBinning((TH2*)&fHAeff, (TH2*)&fHUnfold);
|
---|
317 | fHAeff.Sumw2();
|
---|
318 |
|
---|
319 | //
|
---|
320 | // ------ start loops ------
|
---|
321 | //
|
---|
322 | const Int_t nEtru = aeff->GetNbinsX();
|
---|
323 |
|
---|
324 | Double_t *aeffbar = new Double_t[nEtru];
|
---|
325 | Double_t *daeffbar = new Double_t[nEtru];
|
---|
326 |
|
---|
327 | const Int_t nVar = fHFlux.GetNbinsY();
|
---|
328 | for (int n=1; n<=nVar; n++)
|
---|
329 | {
|
---|
330 | const Double_t tbar = thetabar->GetBinContent(n);
|
---|
331 | const Double_t costbar = cos(tbar/kRad2Deg);
|
---|
332 |
|
---|
333 | // determine bins for interpolation (k3, k0)
|
---|
334 | Int_t kv, ke;
|
---|
335 | FindBins(axey, tbar, kv, ke);
|
---|
336 |
|
---|
337 | //
|
---|
338 | // calculate effective collection area at Theta = Thetabar
|
---|
339 | // by quadratic interpolation in cos(Theta);
|
---|
340 | // do this for each bin of Etru
|
---|
341 | //
|
---|
342 | for (int j=1; j<=nEtru; j++)
|
---|
343 | {
|
---|
344 | if (axey.GetNbins()<3)
|
---|
345 | {
|
---|
346 | // FIXME: Other interpolation?
|
---|
347 | aeffbar[j-1] = aeff->GetBinContent(j, n);
|
---|
348 | daeffbar[j-1] = aeff->GetBinError(j, n);
|
---|
349 | }
|
---|
350 | else
|
---|
351 | {
|
---|
352 | aeffbar[j-1] = ParabInterpolCos(axey, aeff, j, kv, costbar);
|
---|
353 | daeffbar[j-1] = aeff->GetBinError(j, ke);
|
---|
354 | }
|
---|
355 | }
|
---|
356 |
|
---|
357 | //
|
---|
358 | // calculate effective collection area at (E = Ebar, Theta = Thetabar)
|
---|
359 | // by quadratic interpolation in log10(Etru)
|
---|
360 | // do this for each bin of Eunf
|
---|
361 | //
|
---|
362 | CalcEffCol(axex, fHAeff, n, aeffbar, daeffbar);
|
---|
363 | }
|
---|
364 |
|
---|
365 | delete aeffbar;
|
---|
366 | delete daeffbar;
|
---|
367 |
|
---|
368 | //
|
---|
369 | // now calculate the absolute gamma flux
|
---|
370 | //
|
---|
371 | CalcAbsGammaFlux(*teff, fHAeff);
|
---|
372 | }
|
---|
373 |
|
---|
374 | // --------------------------------------------------------------------
|
---|
375 | //
|
---|
376 | // calculate effective collection area at (E = Ebar, Theta = Thetabar)
|
---|
377 | // by quadratic interpolation in log10(Etru)
|
---|
378 | // do this for each bin of Eunf
|
---|
379 | //
|
---|
380 | void MHFlux::CalcEffCol(const TAxis &axex, TH2D &fHAeff, Int_t n, Double_t aeffbar[], Double_t daeffbar[])
|
---|
381 | {
|
---|
382 | const Int_t nEunf = fHFlux.GetNbinsX();
|
---|
383 |
|
---|
384 | const TAxis &unfx = *fHUnfold.GetXaxis();
|
---|
385 |
|
---|
386 | for (int m=1; m<=nEunf; m++)
|
---|
387 | {
|
---|
388 | const Double_t Ebar = GetBinCenterLog(unfx, m);
|
---|
389 |
|
---|
390 | Int_t j0, j3;
|
---|
391 | FindBins(axex, Ebar, j3, j0);
|
---|
392 |
|
---|
393 | const Double_t v = ParabInterpolLog(axex, j3, aeffbar, Ebar);
|
---|
394 |
|
---|
395 | fHAeff.SetBinContent(m,n, v);
|
---|
396 | fHAeff.SetBinError(m,n, daeffbar[j0-1]);
|
---|
397 | }
|
---|
398 | }
|
---|
399 |
|
---|
400 | // --------------------------------------------------------------------
|
---|
401 | //
|
---|
402 | // calculate the absolute gamma flux
|
---|
403 | //
|
---|
404 | void MHFlux::CalcAbsGammaFlux(const TH1D &teff, const TH2D &fHAeff)
|
---|
405 | {
|
---|
406 | const Int_t nEunf = fHFlux.GetNbinsX();
|
---|
407 | const Int_t nVar = fHFlux.GetNbinsY();
|
---|
408 |
|
---|
409 | for (int m=1; m<=nEunf; m++)
|
---|
410 | {
|
---|
411 | const Double_t DeltaE = fHFlux.GetXaxis()->GetBinWidth(m);
|
---|
412 |
|
---|
413 | for (int n=1; n<=nVar; n++)
|
---|
414 | {
|
---|
415 | const Double_t Ngam = fHUnfold.GetBinContent(m,n);
|
---|
416 | const Double_t Aeff = fHAeff.GetBinContent(m,n);
|
---|
417 | const Double_t Effon = teff.GetBinContent(n);
|
---|
418 |
|
---|
419 | const Double_t c1 = fHUnfold.GetBinError(m,n)/Ngam;
|
---|
420 | const Double_t c2 = teff.GetBinError(n) /Effon;
|
---|
421 | const Double_t c3 = fHAeff.GetBinError(m,n) /Aeff;
|
---|
422 |
|
---|
423 | const Double_t cont = Ngam / (DeltaE * Effon * Aeff);
|
---|
424 | const Double_t dcont = sqrt(c1*c1 + c2*c2 + c3*c3);
|
---|
425 |
|
---|
426 | //
|
---|
427 | // Out of Range
|
---|
428 | //
|
---|
429 | const Bool_t oor = Ngam<=0 || DeltaE<=0 || Effon<=0 || Aeff<=0;
|
---|
430 |
|
---|
431 | if (oor)
|
---|
432 | *fLog << warn << "MHFlux::CalcAbsGammaFlux(" << m << "," << n << ") ";
|
---|
433 |
|
---|
434 | if (Ngam<=0)
|
---|
435 | *fLog << " Ngam=0";
|
---|
436 | if (DeltaE<=0)
|
---|
437 | *fLog << " DeltaE=0";
|
---|
438 | if (Effon<=0)
|
---|
439 | *fLog << " Effon=0";
|
---|
440 | if (Aeff<=0)
|
---|
441 | *fLog << " Aeff=0";
|
---|
442 |
|
---|
443 | if (oor)
|
---|
444 | *fLog << endl;
|
---|
445 |
|
---|
446 | fHFlux.SetBinContent(m,n, oor ? 1e-20 : cont);
|
---|
447 | fHFlux.SetBinError(m,n, oor ? 1e-20 : dcont*cont);
|
---|
448 | }
|
---|
449 | }
|
---|
450 | }
|
---|
451 |
|
---|
452 | // --------------------------------------------------------------------
|
---|
453 | //
|
---|
454 | // draw the differential photon flux vs. E-unf
|
---|
455 | // for the individual bins of the variable Var
|
---|
456 | //
|
---|
457 | void MHFlux::DrawFluxProjectionX(Option_t *opt) const
|
---|
458 | {
|
---|
459 | const Int_t nVar = fHFlux.GetNbinsY();
|
---|
460 |
|
---|
461 | for (int n=1; n<=nVar; n++)
|
---|
462 | {
|
---|
463 | TString strg0("Flux-");
|
---|
464 |
|
---|
465 | TH1D &h = *((TH2D)fHFlux).ProjectionX(strg0+fVarname, n, n, "E");
|
---|
466 |
|
---|
467 | TString strg1 = "Photon flux vs. E_{unfold} for ";
|
---|
468 | TString strg2 = fVarname+"-bin #";
|
---|
469 | strg2 += n;
|
---|
470 |
|
---|
471 | new TCanvas(strg2, strg1+strg2);
|
---|
472 | gPad->SetLogx();
|
---|
473 | gPad->SetLogy();
|
---|
474 |
|
---|
475 | TString name = fVarname+"bin_";
|
---|
476 | name += n;
|
---|
477 |
|
---|
478 | h.SetName(name);
|
---|
479 | h.SetTitle(strg1+strg2);
|
---|
480 | h.SetXTitle("E_{unfold} [GeV]");
|
---|
481 | h.SetYTitle("photons / (s m^{2} GeV)");
|
---|
482 | h.GetXaxis()->SetLabelOffset(-0.025);
|
---|
483 | h.GetXaxis()->SetTitleOffset(1.1);
|
---|
484 | h.GetXaxis()->SetNdivisions(1);
|
---|
485 | h.GetYaxis()->SetTitleOffset(1.25);
|
---|
486 | h.DrawCopy();
|
---|
487 | }
|
---|
488 | }
|
---|
489 |
|
---|
490 | void MHFlux::DrawOrigProjectionX(Option_t *opt) const
|
---|
491 | {
|
---|
492 | const Int_t nVar = fHOrig.GetNbinsY();
|
---|
493 |
|
---|
494 | for (int n=1; n<=nVar; n++)
|
---|
495 | {
|
---|
496 | TString strg0 = "Orig-";
|
---|
497 | strg0 += fVarname;
|
---|
498 | strg0 += "_";
|
---|
499 | strg0 += n;
|
---|
500 |
|
---|
501 | TH1D &h = *((TH2D)fHOrig).ProjectionX(strg0, n, n, "E");
|
---|
502 |
|
---|
503 | TString strg1("No.of photons vs. E-est for ");
|
---|
504 | strg1 += fVarname+"-bin ";
|
---|
505 | strg1 += n;
|
---|
506 |
|
---|
507 | new TCanvas(strg0, strg1);
|
---|
508 |
|
---|
509 | gPad->SetLogx();
|
---|
510 | gPad->SetLogy();
|
---|
511 |
|
---|
512 | h.SetName(strg0);
|
---|
513 | h.SetTitle(strg1);
|
---|
514 | h.SetXTitle("E_{est} [GeV]");
|
---|
515 | h.GetXaxis()->SetLabelOffset(-0.025);
|
---|
516 | h.GetXaxis()->SetTitleOffset(1.1);
|
---|
517 | h.GetXaxis()->SetNdivisions(1);
|
---|
518 | h.SetYTitle("No.of photons");
|
---|
519 | h.DrawCopy();
|
---|
520 | }
|
---|
521 | }
|
---|
522 |
|
---|
523 | // -------------------------------------------------------------------------
|
---|
524 | //
|
---|
525 | // Draw copies of the histograms
|
---|
526 | //
|
---|
527 | TObject *MHFlux::DrawClone(Option_t *opt) const
|
---|
528 | {
|
---|
529 | TCanvas &c = *MakeDefCanvas("flux", "Orig - Unfold - Flux plots");
|
---|
530 | c.Divide(2, 2);
|
---|
531 |
|
---|
532 | gROOT->SetSelectedPad(NULL);
|
---|
533 |
|
---|
534 | c.cd(1);
|
---|
535 | ((TH2*)&fHOrig)->DrawCopy("");
|
---|
536 | gPad->SetLogx();
|
---|
537 |
|
---|
538 | c.cd(2);
|
---|
539 | ((TH2*)&fHUnfold)->DrawCopy("");
|
---|
540 | gPad->SetLogx();
|
---|
541 |
|
---|
542 | c.cd(3);
|
---|
543 | ((TH2*)&fHFlux)->DrawCopy("");
|
---|
544 | gPad->SetLogx();
|
---|
545 |
|
---|
546 | c.Modified();
|
---|
547 | c.Update();
|
---|
548 |
|
---|
549 | return &c;
|
---|
550 | }
|
---|
551 |
|
---|
552 | // -------------------------------------------------------------------------
|
---|
553 | //
|
---|
554 | // Draw the histograms
|
---|
555 | //
|
---|
556 | void MHFlux::Draw(Option_t *opt)
|
---|
557 | {
|
---|
558 | if (!gPad)
|
---|
559 | MakeDefCanvas("flux", "orig-unfold-flux plots");
|
---|
560 |
|
---|
561 | gPad->Divide(2,2);
|
---|
562 |
|
---|
563 | gPad->cd(1);
|
---|
564 | fHOrig.Draw(opt);
|
---|
565 |
|
---|
566 | gPad->cd(2);
|
---|
567 | fHUnfold.Draw(opt);
|
---|
568 |
|
---|
569 | gPad->cd(3);
|
---|
570 | fHFlux.Draw(opt);
|
---|
571 |
|
---|
572 | gPad->Modified();
|
---|
573 | gPad->Update();
|
---|
574 | }
|
---|
575 |
|
---|
576 | Double_t MHFlux::Parab(Double_t x1, Double_t x2, Double_t x3,
|
---|
577 | Double_t y1, Double_t y2, Double_t y3,
|
---|
578 | Double_t val)
|
---|
579 | {
|
---|
580 | Double_t c0, c1, c2;
|
---|
581 | Parab(x1, x2, x3, y1, y2, y3, &c0, &c1, &c2);
|
---|
582 | return c0 + c1*val + c2*val*val;
|
---|
583 | }
|
---|
584 |
|
---|
585 | // -------------------------------------------------------------------------
|
---|
586 | //
|
---|
587 | // Quadratic interpolation
|
---|
588 | //
|
---|
589 | // *** calculate the parameters of a parabula
|
---|
590 | // y = a + b*x + c*x**2 = F(x)
|
---|
591 | // such that yi = F(xi) for (i=1,3)
|
---|
592 | //
|
---|
593 | Bool_t MHFlux::Parab(Double_t x1, Double_t x2, Double_t x3,
|
---|
594 | Double_t y1, Double_t y2, Double_t y3,
|
---|
595 | Double_t *a, Double_t *b, Double_t *c)
|
---|
596 | {
|
---|
597 | const double det =
|
---|
598 | + x2*x3*x3 + x1*x2*x2 + x3*x1*x1
|
---|
599 | - x2*x1*x1 - x3*x2*x2 - x1*x3*x3;
|
---|
600 |
|
---|
601 | if (det==0)
|
---|
602 | {
|
---|
603 | *a = 0;
|
---|
604 | *b = 0;
|
---|
605 | *c = 0;
|
---|
606 | return kFALSE;
|
---|
607 | }
|
---|
608 |
|
---|
609 | const double det1 = 1.0/det;
|
---|
610 |
|
---|
611 | const double ai11 = x2*x3*x3 - x3*x2*x2;
|
---|
612 | const double ai12 = x3*x1*x1 - x1*x3*x3;
|
---|
613 | const double ai13 = x1*x2*x2 - x2*x1*x1;
|
---|
614 |
|
---|
615 | const double ai21 = x2*x2 - x3*x3;
|
---|
616 | const double ai22 = x3*x3 - x1*x1;
|
---|
617 | const double ai23 = x1*x1 - x2*x2;
|
---|
618 |
|
---|
619 | const double ai31 = x3 - x2;
|
---|
620 | const double ai32 = x1 - x3;
|
---|
621 | const double ai33 = x2 - x1;
|
---|
622 |
|
---|
623 | *a = (ai11*y1 + ai12*y2 + ai13*y3) * det1;
|
---|
624 | *b = (ai21*y1 + ai22*y2 + ai23*y3) * det1;
|
---|
625 | *c = (ai31*y1 + ai32*y2 + ai33*y3) * det1;
|
---|
626 |
|
---|
627 | return kTRUE;
|
---|
628 | }
|
---|