source: trunk/MagicSoft/Mars/manalysis/MHPedestalPixel.cc@ 3077

Last change on this file since 3077 was 3051, checked in by gaug, 21 years ago
*** empty log message ***
File size: 9.6 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): Markus Gaug 02/2004 <mailto:markus@ifae.es>
19!
20! Copyright: MAGIC Software Development, 2000-2004
21!
22!
23\* ======================================================================== */
24
25//////////////////////////////////////////////////////////////////////////////
26//
27// MHPedestalPixel
28//
29// Performs all the necessary fits to extract the mean number of photons
30// out of the derived light flux
31//
32//////////////////////////////////////////////////////////////////////////////
33#include "MHPedestalPixel.h"
34
35#include <TH1.h>
36#include <TF1.h>
37
38#include <TStyle.h>
39#include <TCanvas.h>
40
41#include "MLog.h"
42#include "MLogManip.h"
43
44ClassImp(MHPedestalPixel);
45
46using namespace std;
47// Square root of 2pi:
48const Float_t gkSq2Pi = 2.506628274631;
49const Float_t gkProbLimit = 0.01;
50const Int_t MHPedestalPixel::gkChargeNbins = 450 ;
51const Axis_t MHPedestalPixel::gkChargeFirst = -0.5;
52const Axis_t MHPedestalPixel::gkChargeLast = 449.5;
53const Int_t MHPedestalPixel::gkChargevsNbins = 1000;
54const Axis_t MHPedestalPixel::gkChargevsNFirst = -0.5;
55const Axis_t MHPedestalPixel::gkChargevsNLast = 999.5;
56
57// --------------------------------------------------------------------------
58//
59// Default Constructor.
60//
61MHPedestalPixel::MHPedestalPixel()
62 : fPixId(-1),
63 fGausFit(NULL)
64{
65
66 // Create a large number of bins, later we will rebin
67 fHPedestalCharge = new TH1F("HPedestalCharge","Distribution of Summed FADC Pedestal Slices Pixel ",
68 gkChargeNbins,gkChargeFirst,gkChargeLast);
69 fHPedestalCharge->SetXTitle("Sum FADC Slices");
70 fHPedestalCharge->SetYTitle("Nr. of events");
71 fHPedestalCharge->Sumw2();
72
73 // We define a reasonable number and later enlarge it if necessary
74 fHPedestalChargevsN = new TH1I("HChargevsN","Sum of Charges vs. Event Number Pixel ",
75 gkChargevsNbins,gkChargevsNFirst,gkChargevsNLast);
76 fHPedestalChargevsN->SetXTitle("Event Nr.");
77 fHPedestalChargevsN->SetYTitle("Sum of FADC slices");
78
79 fHPedestalCharge->SetDirectory(NULL);
80 fHPedestalChargevsN->SetDirectory(NULL);
81
82 Clear();
83}
84
85MHPedestalPixel::~MHPedestalPixel()
86{
87
88 delete fHPedestalCharge;
89 delete fHPedestalChargevsN;
90
91 if (fGausFit)
92 delete fGausFit;
93}
94
95
96void MHPedestalPixel::Clear(Option_t *o)
97{
98
99 fTotalEntries = 0;
100
101 fChargeMean = -1.;
102 fChargeMeanErr = -1.;
103 fChargeSigma = -1;
104 fChargeSigmaErr = -1;
105
106 fChargeChisquare = -1.;
107 fChargeProb = -1.;
108 fChargeNdf = -1;
109
110 fChargeFirst = gkChargeFirst;
111 fChargeLast = gkChargeLast;
112
113 if (fGausFit)
114 delete fGausFit;
115
116 CLRBIT(fFlags,kFitted);
117 CLRBIT(fFlags,kFitOK);
118 CLRBIT(fFlags,kOscillating);
119
120 return;
121}
122
123
124void MHPedestalPixel::Reset()
125{
126
127 Clear();
128
129 fHPedestalCharge->Reset();
130 fHPedestalChargevsN->Reset();
131
132}
133
134
135
136Bool_t MHPedestalPixel::IsEmpty() const
137{
138 return !fHPedestalCharge->GetEntries();
139}
140
141Bool_t MHPedestalPixel::IsFitOK() const
142{
143 return TESTBIT(fFlags,kFitOK);
144}
145
146Bool_t MHPedestalPixel::FillCharge(Float_t q)
147{
148 return (fHPedestalCharge->Fill(q) > -1);
149}
150
151Bool_t MHPedestalPixel::FillChargevsN(Float_t q)
152{
153
154 fTotalEntries++;
155 return (fHPedestalChargevsN->Fill(fTotalEntries,q) > -1);
156}
157
158void MHPedestalPixel::ChangeHistId(Int_t id)
159{
160
161 fPixId = id;
162
163 fHPedestalCharge->SetName(Form("%s%d", fHPedestalCharge->GetName(), id));
164 fHPedestalChargevsN->SetName(Form("%s%d", fHPedestalChargevsN->GetName(), id));
165 fHPedestalCharge->SetTitle(Form("%s%d", fHPedestalCharge->GetTitle(), id));
166 fHPedestalChargevsN->SetTitle(Form("%s%d", fHPedestalChargevsN->GetTitle(), id));
167
168}
169
170TObject *MHPedestalPixel::DrawClone(Option_t *option) const
171{
172
173 gROOT->SetSelectedPad(NULL);
174
175 MHPedestalPixel *newobj = (MHPedestalPixel*)Clone();
176
177 if (!newobj)
178 return 0;
179 newobj->SetBit(kCanDelete);
180
181
182 if (strlen(option))
183 newobj->Draw(option);
184 else
185 newobj->Draw(GetDrawOption());
186
187 return newobj;
188}
189
190
191// -------------------------------------------------------------------------
192//
193// Draw the histogram
194//
195void MHPedestalPixel::Draw(Option_t *opt)
196{
197
198 gStyle->SetOptStat(111111);
199 gStyle->SetOptFit();
200
201 gROOT->SetSelectedPad(NULL);
202
203 TCanvas *c = MH::MakeDefCanvas(this,600,900);
204
205 // c->Divide(1,2);
206
207 c->cd(1);
208 gPad->SetBorderMode(0);
209 gPad->SetTicks();
210
211 if (fHPedestalCharge->Integral() > 0)
212 gPad->SetLogy();
213
214 fHPedestalCharge->Draw(opt);
215
216 c->Modified();
217 c->Update();
218
219 if (fGausFit)
220 {
221 fGausFit->SetLineColor(IsFitOK() ? kGreen : kRed);
222 fGausFit->Draw("same");
223 }
224
225 c->Modified();
226 c->Update();
227
228 /*
229 c->cd(2);
230 gPad->SetTicks();
231
232 fHPedestalChargevsN->Draw(opt);
233 */
234
235 c->Modified();
236 c->Update();
237
238 return;
239}
240
241
242// --------------------------------------------------------------------------
243//
244// 1) Return if the charge distribution is already succesfully fitted
245// or if the histogram is empty
246// 2) Cut the histograms empty edges
247// 3) Fit the histograms with a Gaussian
248// 4) In case of failure print out the fit results
249// 5) Retrieve the results and store them in this class
250//
251Bool_t MHPedestalPixel::FitCharge(Option_t *option)
252{
253
254 if (fGausFit)
255 return kFALSE;
256
257 //
258 // Get the fitting ranges
259 //
260 Axis_t rmin = fChargeFirst;
261 Axis_t rmax = fChargeLast;
262
263 //
264 // First guesses for the fit (should be as close to reality as possible,
265 // otherwise the fit goes gaga because of high number of dimensions ...
266 //
267 const Stat_t entries = fHPedestalCharge->Integral();
268 const Double_t mu_guess = fHPedestalCharge->GetBinCenter(fHPedestalCharge->GetMaximumBin());
269 const Double_t sigma_guess = mu_guess/15.;
270 const Double_t area_guess = entries/gkSq2Pi/sigma_guess;
271
272 fGausFit = new TF1(Form("%s%d","GausFit ",fPixId),"gaus",rmin,rmax);
273
274 if (!fGausFit)
275 {
276 *fLog << warn << dbginf << "WARNING: Could not create fit function for Gauss fit" << endl;
277 return kFALSE;
278 }
279
280 fGausFit->SetParameters(area_guess,mu_guess,sigma_guess);
281 fGausFit->SetParNames("Area","#mu","#sigma");
282 fGausFit->SetParLimits(0,0.,entries);
283 fGausFit->SetParLimits(1,rmin,rmax);
284 fGausFit->SetParLimits(2,0.,rmax-rmin);
285 fGausFit->SetRange(rmin,rmax);
286
287 fHPedestalCharge->Fit(fGausFit,option);
288
289 //
290 // In order not to be affected by outliers,
291 // try once again with stricter borders
292 //
293 Axis_t rtry = fGausFit->GetParameter(1) - 2.5*fGausFit->GetParameter(2);
294 rmin = (rtry < rmin ? rmin : rtry);
295 rtry = fGausFit->GetParameter(1) + 2.5*fGausFit->GetParameter(2);
296 rmax = (rtry > rmax ? rmax : rtry);
297 fGausFit->SetRange(rmin,rmax);
298
299 fHPedestalCharge->Fit(fGausFit,option);
300
301 fChargeChisquare = fGausFit->GetChisquare();
302 fChargeNdf = fGausFit->GetNDF();
303 fChargeProb = fGausFit->GetProb();
304 fChargeMean = fGausFit->GetParameter(1);
305 fChargeMeanErr = fGausFit->GetParError(1);
306 fChargeSigma = fGausFit->GetParameter(2);
307 fChargeSigmaErr = fGausFit->GetParError(2);
308
309 SETBIT(fFlags,kFitted);
310 //
311 // The fit result is accepted under condition:
312 // The Results are not nan's
313 // The Probability is greater than gkProbLimit (default 0.001 == 99.9%)
314 //
315 if (TMath::IsNaN(fChargeMean) ||
316 TMath::IsNaN(fChargeMeanErr) ||
317 TMath::IsNaN(fChargeSigma) ||
318 TMath::IsNaN(fChargeSigmaErr))
319 {
320 Clear();
321 // CLRBIT(fFlags,kFitOK);
322 return kFALSE;
323 }
324
325 if ((fChargeProb < gkProbLimit) || (TMath::IsNaN(fChargeProb)))
326 {
327 CLRBIT(fFlags,kFitOK);
328 return kFALSE;
329 }
330
331 SETBIT(fFlags,kFitOK);
332 return kTRUE;
333}
334
335void MHPedestalPixel::Renorm(const Float_t nslices)
336{
337
338 if (!TESTBIT(fFlags,kFitOK))
339 return;
340
341 Float_t sqslices = TMath::Sqrt(nslices);
342
343 fChargeMean /= nslices;
344 //
345 // Mean error goes with PedestalRMS/Sqrt(entries) -> scale with slices
346 //
347 fChargeMeanErr /= nslices;
348 //
349 // Sigma goes like PedestalRMS -> scale with sqrt(slices)
350 //
351 fChargeSigma /= sqslices;
352 //
353 // Sigma error goes like PedestalRMS/2.(entries) -> scale with slices
354 //
355 fChargeSigmaErr /= nslices;
356
357}
358
359void MHPedestalPixel::CutAllEdges()
360{
361
362 Int_t nbins = 15;
363
364 MH::CutEdges(fHPedestalCharge,nbins);
365
366 fChargeFirst = fHPedestalCharge->GetBinLowEdge(fHPedestalCharge->GetXaxis()->GetFirst());
367 fChargeLast = fHPedestalCharge->GetBinLowEdge(fHPedestalCharge->GetXaxis()->GetLast())
368 +fHPedestalCharge->GetBinWidth(0);
369
370 MH::CutEdges(fHPedestalChargevsN,0);
371
372}
373
374void MHPedestalPixel::Print(const Option_t *o) const
375{
376
377 *fLog << all << "Pedestal Fits Pixel: " << fPixId << endl;
378
379 if (!TESTBIT(fFlags,kFitted))
380 {
381 gLog << "Pedestal Histogram has not yet been fitted" << endl;
382 return;
383 }
384
385 gLog << "Results of the Summed Charges Fit: " << endl;
386 gLog << "Chisquare: " << fChargeChisquare << endl;
387 gLog << "DoF: " << fChargeNdf << endl;
388 gLog << "Probability: " << fChargeProb << endl;
389 gLog << "Results of fit: " << (TESTBIT(fFlags,kFitOK) ? "Ok.": "Not OK!") << endl;
390
391}
392
Note: See TracBrowser for help on using the repository browser.