source: trunk/MagicSoft/Mars/mhistmc/MHMcUnfoldCoeff.cc@ 8550

Last change on this file since 8550 was 6549, checked in by rico, 20 years ago
*** empty log message ***
File size: 10.8 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! Author(s): Javier Rico 02/2005 <mailto:jrico@ifae.es>
18!
19! Copyright: MAGIC Software Development, 2000-2005
20!
21!
22\* ======================================================================== */
23
24//////////////////////////////////////////////////////////////////////////////
25//
26// MHMcUnfoldCoeff
27// Container that stores the coefficients to convert from estimated to real
28// (unfolded) energy.
29// It is filled by MMcUnfoldCoeffCalc
30// Events are weighted from any initial spectrum to a tentative spectrum
31// that must be set through MMcUnfoldCoeffCalc::SetSpectrum method.
32//
33//////////////////////////////////////////////////////////////////////////////
34
35#include <fstream>
36#include <math.h>
37
38#include "TH1D.h"
39#include "TH2D.h"
40#include "TF1.h"
41#include "TCanvas.h"
42#include "TArrayD.h"
43
44#include "MHMcUnfoldCoeff.h"
45
46#include "MBinning.h"
47
48#include "MLog.h"
49#include "MLogManip.h"
50
51ClassImp(MHMcUnfoldCoeff);
52
53using namespace std;
54
55
56// -------------------------------------------------------------------------
57//
58// Constructor: Define and configure the different histograms to be filled
59//
60MHMcUnfoldCoeff::MHMcUnfoldCoeff(const char *name, const char *title) :
61 fNsubbins(20), fEmin(1.), fEmax(100000.), fNumMin(10), fFineBinning(NULL)
62{
63 fName = name ? name : "MHMcUnfoldCoeff";
64 fTitle = title ? title : "Unfolding Coefficients vs. Theta vs. Energy";
65
66 // define histos
67 fHistAll = new TH1D();
68 fHistWeight = new TH1D();
69 fHistMcE = new TH2D();
70 fHistEstE = new TH2D();
71 fHistCoeff = new TH2D();
72
73 // set histo names
74 fHistAll->SetName("AllEvents");
75 fHistWeight->SetName("Weights");
76 fHistMcE->SetName("MCEnergy");
77 fHistEstE->SetName("EstimatedEnergy");
78 fHistCoeff->SetName("UnfoldCoeff");
79
80 // set histo titles
81 fHistAll->SetTitle("MC energy for all generated events");
82 fHistWeight->SetTitle("Weights");
83 fHistMcE->SetTitle("MC energy for survivors");
84 fHistEstE->SetTitle("Estimate energy for survivors");
85 fHistCoeff->SetTitle(fTitle);
86
87 // histos directory
88 fHistAll->SetDirectory(NULL);
89 fHistWeight->SetDirectory(NULL);
90 fHistMcE->SetDirectory(NULL);
91 fHistEstE->SetDirectory(NULL);
92 fHistCoeff->SetDirectory(NULL);
93
94 // histos style
95 fHistAll->UseCurrentStyle();
96 fHistWeight->UseCurrentStyle();
97 fHistMcE->UseCurrentStyle();
98 fHistEstE->UseCurrentStyle();
99 fHistCoeff->UseCurrentStyle();
100
101 // labels
102 fHistAll->SetXTitle("E [GeV]");
103 fHistWeight->SetXTitle("E [GeV]");
104 fHistMcE->SetXTitle("E_{MC} [GeV]");
105 fHistEstE->SetXTitle("E_{est} [GeV]");
106 fHistCoeff->SetXTitle("E_{est} [GeV]");
107
108 fHistWeight->SetYTitle("weight");
109 fHistMcE->SetYTitle("\\theta [\\circ]");
110 fHistEstE->SetYTitle("\\theta [\\circ]");
111 fHistCoeff->SetYTitle("\\theta [\\circ]");
112
113 fHistMcE->SetZTitle("weighted entries");
114 fHistEstE->SetZTitle("weighted entries");
115 fHistCoeff->SetZTitle("Coefficient");
116}
117
118// -------------------------------------------------------------------------
119//
120// Destructor: Delete all the histograms
121//
122MHMcUnfoldCoeff::~MHMcUnfoldCoeff()
123{
124 delete fHistAll;
125 delete fHistWeight;
126 delete fHistMcE;
127 delete fHistEstE;
128 delete fHistCoeff;
129
130 if(fFineBinning)
131 delete fFineBinning;
132}
133
134// --------------------------------------------------------------------------
135//
136// Set the histograms binning. The coarse binning has to be provided
137// from outside (in the parameter list) whereas the fine binning for
138// energy is computed from the former.
139// The subbinning is set logarithmicaly (linearly) for a logarithmic
140// (linear) coarse binning.
141// It is extended down to fEmin and up to fEmax
142// The number of subbins per coarse bins may be changed using
143// SetNsubbins() method
144// The maximum and minimum energies of the fine binning histograms
145// may be changed with the SetEmin() and SetEmax() methods
146//
147void MHMcUnfoldCoeff::SetCoarseBinnings(const MBinning &binsEnergy,
148 const MBinning &binsTheta)
149{
150 // set histo binning (for coarse bin histos)
151 MH::SetBinning(fHistMcE,&binsEnergy,&binsTheta);
152 MH::SetBinning(fHistEstE,&binsEnergy,&binsTheta);
153 MH::SetBinning(fHistCoeff,&binsEnergy,&binsTheta);
154
155 // good errors
156 fHistMcE->Sumw2();
157 fHistEstE->Sumw2();
158
159 // define fine binning from coarse one
160 const Int_t nbins = binsEnergy.GetNumBins();
161 const TArrayD edges = binsEnergy.GetEdgesD();
162 const Bool_t isLinear = binsEnergy.IsLinear();
163
164 // compute bins needed to extend down to fEmin and up to fEmax
165 Double_t dedown, deup;
166 Int_t binsdown,binsup;
167 MBinning dbin;
168 MBinning ubin;
169 if(isLinear)
170 {
171 dedown = (edges[1]-edges[0])/fNsubbins;
172 deup = (edges[nbins]-edges[nbins-1])/fNsubbins;
173 binsdown = (fEmin<edges[0]) ? Int_t((edges[0]-fEmin)/dedown) : 0;
174 binsup = (fEmax>edges[nbins]) ? Int_t((fEmax-edges[nbins])/deup) : 0;
175 if(binsdown) dbin.SetEdges(binsdown,fEmin,edges[0]);
176 if(binsup) ubin.SetEdges(binsup,edges[nbins],fEmax);
177 }
178 else
179 {
180 dedown = (TMath::Log10(edges[1])-TMath::Log10(edges[0]))/fNsubbins;
181 deup = (TMath::Log10(edges[nbins])-TMath::Log10(edges[nbins-1]))/fNsubbins;
182 binsdown = (fEmin<edges[0]) ? Int_t((TMath::Log10(edges[0])-TMath::Log10(fEmin))/dedown) : 0;
183 binsup = (fEmax>edges[nbins])? Int_t((TMath::Log10(fEmax)-TMath::Log10(edges[nbins]))/deup) : 0;
184 if(binsdown) dbin.SetEdgesLog(binsdown,fEmin,edges[0]);
185 if(binsup) ubin.SetEdgesLog(binsup,edges[nbins],fEmax);
186 }
187
188 // fill the subins' edges
189 TArrayD fineedges(binsdown+nbins*fNsubbins+binsup+1);
190
191 for(Int_t i=0;i<binsdown;i++)
192 fineedges[i] = dbin.GetEdgesD().At(i);
193
194 for(Int_t i=0;i<nbins;i++)
195 {
196 MBinning coarb;
197 if(isLinear)
198 coarb.SetEdges(fNsubbins,edges[i],edges[i+1]);
199 else
200 coarb.SetEdgesLog(fNsubbins,edges[i],edges[i+1]);
201
202 for(Int_t j=0;j<fNsubbins;j++)
203 fineedges[binsdown+i*fNsubbins+j] = coarb.GetEdgesD().At(j);
204 }
205
206 for(Int_t i=0;i<binsup;i++)
207 fineedges[binsdown+nbins*fNsubbins+i] = ubin.GetEdgesD().At(i);
208
209 fineedges[binsdown+nbins*fNsubbins+binsup] = binsup ? ubin.GetEdgesD().At(binsup): edges[nbins];
210
211 // define fine binning object
212 fFineBinning = new MBinning;
213 fFineBinning->SetEdges(fineedges);
214
215 // apply fine binning to histograms that need it
216 fFineBinning->Apply(*fHistAll);
217 fFineBinning->Apply(*fHistWeight);
218}
219
220// -------------------------------------------------------------------------
221//
222// Compute the weights for a particular tentative spectrum.
223// For each energy (fine) bin we compute it as the value of the input function
224// divided by the number of entries in the actual energy histogram.
225// First and last bin are not filled since they could be biased
226//
227void MHMcUnfoldCoeff::ComputeWeights(TF1* spectrum)
228{
229 Bool_t first=kTRUE;
230 Int_t lastb=0;
231 for(Int_t i=0;i<fHistAll->GetNbinsX();i++)
232 {
233 const Float_t denom = fHistAll->GetBinContent(i+1); // number of events in initial spectrum
234 const Float_t ew = fHistAll->GetBinCenter(i+1); // energy associated to the bin
235 const Float_t numer = spectrum->Eval(ew); // number of events for the required spectrum
236
237 if(denom>fNumMin)
238 {
239 // do not fill it if it is the first one
240 if(first)
241 {
242 fHistWeight->SetBinContent(i+1,-1);
243 first=kFALSE;
244 }
245 else
246 {
247 fHistWeight->SetBinContent(i+1,numer/denom);
248 lastb=i+1;
249 }
250 }
251 else
252 fHistWeight->SetBinContent(i+1,-1);
253 }
254
255 //remove last filled bin
256 if(lastb)
257 fHistWeight->SetBinContent(lastb,-1);
258}
259
260// --------------------------------------------------------------
261//
262// Compute the coefficients used for the (iterative) unfolding
263// The coefficients are the ratio between the contents of the
264// mc energy and estimate energy histograms (filled with weighted
265// events
266// Errors are computed as if estimated and MC energy histos where
267// uncorrelated
268//
269void MHMcUnfoldCoeff::ComputeCoefficients()
270{
271 for(Int_t j=0;j<fHistEstE->GetNbinsY();j++)
272 for(Int_t i=0;i<fHistEstE->GetNbinsX();i++)
273 {
274 const Float_t num = fHistMcE->GetBinContent(i+1,j+1);
275 const Float_t den = fHistEstE->GetBinContent(i+1,j+1);
276
277 if(den>0)
278 {
279 const Float_t cf = num/den;
280 fHistCoeff->SetBinContent(i+1,j+1,cf);
281
282 if(num>0)
283 {
284 const Float_t ernum = fHistMcE->GetBinError(i+1,j+1);
285 const Float_t erden = fHistEstE->GetBinError(i+1,j+1);
286 const Float_t ercf = cf*(TMath::Sqrt(ernum/num*ernum/num+erden/den*erden/den));
287 fHistCoeff->SetBinError(i+1,j+1,ercf);
288 }
289 else
290 fHistCoeff->SetBinError(i+1,j+1,0);
291 }
292 else
293 {
294 *fLog << warn << "MHMcUnfoldCoeff::ComputeCoefficients Warning: energy bin " << i << ", thetabin " << j << " has no survivors, setting coefficient to 0" << endl;
295 fHistCoeff->SetBinContent(i+1,j+1,0.);
296 fHistCoeff->SetBinError(i+1,j+1,0.);
297 }
298 }
299}
300
301// --------------------------------------------------------------------------
302//
303// Fill data into the histogram which contains all showers
304//
305void MHMcUnfoldCoeff::FillAll(Double_t energy)
306{
307 fHistAll->Fill(energy);
308}
309
310// --------------------------------------------------------------------------
311//
312// Fill data into the histograms which contain survivors
313// each event is introduced with a weight depending on its (MC) energy
314//
315void MHMcUnfoldCoeff::FillSel(Double_t mcenergy,Double_t estenergy,Double_t theta)
316{
317 // bin of the corresponding weight
318 const Int_t wbin = fFineBinning->FindHiEdge(mcenergy);
319
320 if(wbin>0)
321 {
322 // weight
323 const Double_t weight = fHistWeight->GetBinContent(wbin);
324
325 if(weight>0)
326 {
327 fHistMcE->Fill(mcenergy,theta,weight);
328 fHistEstE->Fill(estenergy,theta,weight);
329 }
330 // else
331 // *fLog << warn << "MHMcUnfoldCoeff::FillSel Warning: event with energy " << mcenergy << " has no computed weight (lack of MC statistics), skipping" << endl;
332 }
333 // the event has an energy out of the considered range
334 else
335 *fLog << warn << "MHMcUnfoldCoeff::FillSel Warning: event with energy " << mcenergy << " has energy out of bounds, skipping" << endl;
336}
337
338// --------------------------------------------------------------------------
339//
340// Draw
341//
342void MHMcUnfoldCoeff::Draw(Option_t* option)
343{
344 TCanvas *c1 = new TCanvas();
345 c1->SetLogx();
346 c1->SetLogy();
347 c1->SetGridx();
348 c1->SetGridy();
349
350 fHistCoeff->Draw("");
351}
352
Note: See TracBrowser for help on using the repository browser.