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

Last change on this file since 3033 was 3015, checked in by gaug, 21 years ago
*** empty log message ***
File size: 9.0 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 = 500 ;
51const Int_t MHPedestalPixel::gkChargevsNbins = 1000;
52const Axis_t MHPedestalPixel::gkChargevsNFirst = -0.5;
53const Axis_t MHPedestalPixel::gkChargevsNLast = 999.5;
54const Axis_t MHPedestalPixel::gkChargeFirst = -0.5;
55const Axis_t MHPedestalPixel::gkChargeLast = 499.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->SetOptFit(1);
199 gStyle->SetOptStat(111111);
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(1);
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 c->cd(2);
229 gPad->SetTicks();
230
231 fHPedestalChargevsN->Draw(opt);
232 c->Modified();
233 c->Update();
234
235 return;
236}
237
238
239// --------------------------------------------------------------------------
240//
241// 1) Return if the charge distribution is already succesfully fitted
242// or if the histogram is empty
243// 2) Cut the histograms empty edges
244// 3) Fit the histograms with a Gaussian
245// 4) In case of failure print out the fit results
246// 5) Retrieve the results and store them in this class
247//
248Bool_t MHPedestalPixel::FitCharge(Option_t *option)
249{
250
251 if (fGausFit)
252 return kFALSE;
253
254 //
255 // Get the fitting ranges
256 //
257 Axis_t rmin = fChargeFirst;
258 Axis_t rmax = fChargeLast;
259
260 //
261 // First guesses for the fit (should be as close to reality as possible,
262 // otherwise the fit goes gaga because of high number of dimensions ...
263 //
264 const Stat_t entries = fHPedestalCharge->Integral();
265 const Double_t mu_guess = fHPedestalCharge->GetBinCenter(fHPedestalCharge->GetMaximumBin());
266 const Double_t sigma_guess = mu_guess/15.;
267 const Double_t area_guess = entries/gkSq2Pi/sigma_guess;
268
269 fGausFit = new TF1(Form("%s%d","GausFit ",fPixId),"gaus",rmin,rmax);
270
271 if (!fGausFit)
272 {
273 *fLog << warn << dbginf << "WARNING: Could not create fit function for Gauss fit" << endl;
274 return kFALSE;
275 }
276
277 fGausFit->SetParameters(area_guess,mu_guess,sigma_guess);
278 fGausFit->SetParNames("Area","#mu","#sigma");
279 fGausFit->SetParLimits(0,0.,entries);
280 fGausFit->SetParLimits(1,rmin,rmax);
281 fGausFit->SetParLimits(2,0.,rmax-rmin);
282 fGausFit->SetRange(rmin,rmax);
283
284 fHPedestalCharge->Fit(fGausFit,option);
285
286 //
287 // If we are not able to fit, try once again
288 //
289 if (fGausFit->GetProb() < gkProbLimit)
290 {
291
292 Axis_t rtry = fGausFit->GetParameter(1) - 2.0*fGausFit->GetParameter(2);
293 rmin = (rtry < rmin ? rmin : rtry);
294 rmax = fGausFit->GetParameter(1) + 2.0*fGausFit->GetParameter(2);
295 fGausFit->SetRange(rmin,rmax);
296
297 fHPedestalCharge->Fit(fGausFit,option);
298 }
299
300 fChargeChisquare = fGausFit->GetChisquare();
301 fChargeNdf = fGausFit->GetNDF();
302 fChargeProb = fGausFit->GetProb();
303 fChargeMean = fGausFit->GetParameter(1);
304 fChargeMeanErr = fGausFit->GetParError(1);
305 fChargeSigma = fGausFit->GetParameter(2);
306 fChargeSigmaErr = fGausFit->GetParError(2);
307
308 SETBIT(fFlags,kFitted);
309 //
310 // The fit result is accepted under condition:
311 // The Results are not nan's
312 // The Probability is greater than gkProbLimit (default 0.001 == 99.9%)
313 //
314 if (TMath::IsNaN(fChargeMean) || TMath::IsNaN(fChargeMeanErr))
315 {
316 CLRBIT(fFlags,kFitOK);
317 return kFALSE;
318 }
319
320 if ((fChargeProb < gkProbLimit) || (TMath::IsNaN(fChargeProb)))
321 {
322 CLRBIT(fFlags,kFitOK);
323 return kFALSE;
324 }
325
326 SETBIT(fFlags,kFitOK);
327 return kTRUE;
328}
329
330void MHPedestalPixel::CutAllEdges()
331{
332
333 Int_t nbins = 30;
334
335 MH::CutEdges(fHPedestalCharge,nbins);
336
337 fChargeFirst = fHPedestalCharge->GetBinLowEdge(fHPedestalCharge->GetXaxis()->GetFirst());
338 fChargeLast = fHPedestalCharge->GetBinLowEdge(fHPedestalCharge->GetXaxis()->GetLast())
339 +fHPedestalCharge->GetBinWidth(0);
340
341 MH::CutEdges(fHPedestalChargevsN,0);
342
343}
344
345void MHPedestalPixel::Print(const Option_t *o) const
346{
347
348 *fLog << all << "Pedestal Fits Pixel: " << fPixId << endl;
349
350 if (!TESTBIT(fFlags,kFitted))
351 {
352 gLog << "Pedestal Histogram has not yet been fitted" << endl;
353 return;
354 }
355
356 gLog << "Results of the Summed Charges Fit: " << endl;
357 gLog << "Chisquare: " << fChargeChisquare << endl;
358 gLog << "DoF: " << fChargeNdf << endl;
359 gLog << "Probability: " << fChargeProb << endl;
360 gLog << "Results of fit: " << (TESTBIT(fFlags,kFitOK) ? "Ok.": "Not OK!") << endl;
361
362}
363
Note: See TracBrowser for help on using the repository browser.