source: trunk/MagicSoft/Mars/mcalib/MHCalibrationPixel.cc@ 3086

Last change on this file since 3086 was 3086, checked in by gaug, 21 years ago
*** empty log message ***
File size: 22.4 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 11/2003 <mailto:markus@ifae.es>
19!
20! Copyright: MAGIC Software Development, 2000-2002
21!
22!
23\* ======================================================================== */
24
25//////////////////////////////////////////////////////////////////////////////
26//
27// MHCalibrationPixel
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 "MHCalibrationPixel.h"
34#include "MHCalibrationConfig.h"
35
36#include <TH1.h>
37#include <TF1.h>
38#include <TProfile.h>
39
40#include <TStyle.h>
41#include <TCanvas.h>
42#include <TPaveText.h>
43#include <TText.h>
44#include <TGraph.h>
45
46#include "MFFT.h"
47
48#include "MLog.h"
49#include "MLogManip.h"
50
51ClassImp(MHCalibrationPixel);
52
53using namespace std;
54
55const Int_t MHCalibrationPixel::fChargeNbinsHiGain = 2100;
56const Int_t MHCalibrationPixel::fChargeNbinsLoGain = 1010;
57const Int_t MHCalibrationPixel::fAbsTimeNbins = 16;
58const Axis_t MHCalibrationPixel::fAbsTimeFirst = - 0.25;
59const Axis_t MHCalibrationPixel::fAbsTimeLast = 15.75;
60const Float_t MHCalibrationPixel::fProbLimit = 0.001;
61const Int_t MHCalibrationPixel::fNDFLimit = 5;
62
63const Int_t MHCalibrationPixel::fPSDNbins = 30;
64
65// --------------------------------------------------------------------------
66//
67// Default Constructor.
68//
69MHCalibrationPixel::MHCalibrationPixel(const char *name, const char *title)
70 : fPixId(-1),
71 fHivsLoGain(NULL),
72 fPSDHiGain(NULL),
73 fPSDLoGain(NULL),
74 fChargeGausFit(NULL),
75 fHPSD(NULL),
76 fPSDExpFit(NULL),
77 fChargeXaxis(NULL),
78 fPSDXaxis(NULL),
79 fFitLegend(NULL),
80 fCurrentSize(1024)
81{
82
83 fName = name ? name : "MHCalibrationPixel";
84 fTitle = title ? title : "Fill the accumulated charges of all events and perform fits";
85
86 fChargeFirstHiGain = -100.5;
87 fChargeLastHiGain = 1999.5;
88 fChargeFirstLoGain = -100.5;
89 fChargeLastLoGain = 9999.5;
90
91 // Create a large number of bins, later we will rebin
92 fHChargeHiGain = new TH1F("HChargeHiGain","Distribution of Summed FADC Hi Gain Slices Pixel ",
93 fChargeNbinsHiGain,fChargeFirstHiGain,fChargeLastHiGain);
94 fHChargeLoGain = new TH1F("HChargeLoGain","Distribution of Summed FADC Lo Gain Slices Pixel ",
95 fChargeNbinsLoGain,fChargeFirstLoGain,fChargeLastLoGain);
96
97 fHChargeLoGain->SetXTitle("Sum FADC Slices (Lo Gain)");
98 fHChargeHiGain->SetXTitle("Sum FADC Slices (Hi Gain)");
99
100 fHChargeLoGain->SetYTitle("Nr. of events");
101 fHChargeHiGain->SetYTitle("Nr. of events");
102
103 fHChargeHiGain->Sumw2();
104 fHChargeLoGain->Sumw2();
105
106 // Absolute Times
107 fHAbsTimeHiGain = new TH1F("HAbsTimeHiGain","Distribution of Absolute Arrival Hi Gain Times Pixel ",
108 fAbsTimeNbins,fAbsTimeFirst,fAbsTimeLast);
109 fHAbsTimeLoGain = new TH1F("HAbsTimeLoGain","Distribution of Absolute Arrival Lo Gain Times Pixel ",
110 fAbsTimeNbins,fAbsTimeFirst,fAbsTimeLast);
111
112 fHAbsTimeHiGain->SetXTitle("Absolute Arrival Time [Hi Gain FADC slice nr]");
113 fHAbsTimeLoGain->SetXTitle("Absolute Arrival Time [Lo Gain FADC slice nr]");
114
115 fHAbsTimeHiGain->SetYTitle("Nr. of events");
116 fHAbsTimeLoGain->SetYTitle("Nr. of events");
117
118
119 fHChargeHiGain->SetDirectory(NULL);
120 fHChargeLoGain->SetDirectory(NULL);
121 fHAbsTimeHiGain->SetDirectory(NULL);
122 fHAbsTimeLoGain->SetDirectory(NULL);
123
124 fHiGains = new TArrayF(fCurrentSize);
125 fLoGains = new TArrayF(fCurrentSize);
126
127 Clear();
128
129}
130
131MHCalibrationPixel::~MHCalibrationPixel()
132{
133
134 delete fHChargeHiGain;
135 delete fHAbsTimeHiGain;
136
137 delete fHChargeLoGain;
138 delete fHAbsTimeLoGain;
139
140 delete fHiGains;
141 delete fLoGains;
142
143 if (fChargeGausFit)
144 delete fChargeGausFit;
145 if (fPSDExpFit)
146 delete fPSDExpFit;
147 if (fHPSD)
148 delete fHPSD;
149 if (fFitLegend)
150 delete fFitLegend;
151 if (fHivsLoGain)
152 delete fHivsLoGain;
153 if (fChargeXaxis)
154 delete fChargeXaxis;
155 if (fPSDXaxis)
156 delete fPSDXaxis;
157}
158
159
160void MHCalibrationPixel::Clear(Option_t *o)
161{
162
163 fTotalEntries = 0;
164 fCurrentSize = 1024;
165
166 fChargeFirstHiGain = -100.5;
167 fChargeLastHiGain = 1999.5;
168 fChargeFirstLoGain = -100.5;
169 fChargeLastLoGain = 9999.5;
170
171 fChargeChisquare = -1.;
172 fChargeProb = -1.;
173 fChargeNdf = -1;
174
175 fAbsTimeFirstHiGain = -1.;
176 fAbsTimeFirstLoGain = -1.;
177 fAbsTimeLastHiGain = -1.;
178 fAbsTimeLastLoGain = -1.;
179
180 fAbsTimeMean = -1.;
181 fAbsTimeMeanErr = -1.;
182 fAbsTimeRms = -1.;
183
184 fOffset = 0.;
185 fSlope = 0.;
186
187 if (fChargeGausFit)
188 delete fChargeGausFit;
189 if (fPSDExpFit)
190 delete fPSDExpFit;
191 if (fHPSD)
192 delete fHPSD;
193 if (fFitLegend)
194 delete fFitLegend;
195 if (fHivsLoGain)
196 delete fHivsLoGain;
197 if (fChargeXaxis)
198 delete fChargeXaxis;
199 if (fPSDXaxis)
200 delete fPSDXaxis;
201 if (fPSDHiGain)
202 delete fPSDHiGain;
203 if (fPSDLoGain)
204 delete fPSDLoGain;
205
206 CLRBIT(fFlags,kUseLoGain);
207 CLRBIT(fFlags,kChargeFitOK);
208 CLRBIT(fFlags,kOscillating);
209
210 return;
211}
212
213
214void MHCalibrationPixel::Reset()
215{
216
217 Clear();
218
219 fHChargeHiGain->Reset();
220 fHChargeLoGain->Reset();
221
222 fHAbsTimeHiGain->Reset();
223 fHAbsTimeLoGain->Reset();
224
225 fHiGains->Set(1024);
226 fLoGains->Set(1024);
227
228 fHiGains->Reset(0.);
229 fLoGains->Reset(0.);
230
231}
232
233void MHCalibrationPixel::SetUseLoGain(Bool_t b)
234{
235 if (b)
236 SETBIT(fFlags, kUseLoGain) ;
237 else
238 CLRBIT(fFlags, kUseLoGain);
239}
240
241
242Bool_t MHCalibrationPixel::CheckOscillations()
243{
244
245 if (fPSDExpFit)
246 return IsOscillating();
247
248 //
249 // The number of entries HAS to be a potence of 2,
250 // so we can only cut out from the last potence of 2 to the rest.
251 // Another possibility would be to fill everything with
252 // zeros, but that gives a low frequency peak, which we would
253 // have to cut out later again.
254 //
255 // So, we have to live with the possibility that at the end
256 // of the calibration run, something has happened without noticing
257 // it...
258 //
259
260 // This cuts only the non-used zero's, but MFFT will later cut the rest
261 CutArrayBorder(fHiGains);
262 CutArrayBorder(fLoGains);
263
264 MFFT fourier;
265
266 fPSDLoGain = fourier.PowerSpectrumDensity(fLoGains);
267 fPSDHiGain = fourier.PowerSpectrumDensity(fHiGains);
268
269 if (IsUseLoGain())
270 fHPSD = MH::ProjectArray(fPSDLoGain, fPSDNbins,
271 Form("%s%d","PSDProjection",fPixId),
272 Form("%s%d","Power Spectrum Density Projection LoGain ",fPixId));
273 else
274 fHPSD = MH::ProjectArray(fPSDHiGain, fPSDNbins,
275 Form("%s%d","PSDProjection",fPixId),
276 Form("%s%d","Power Spectrum Density Projection HiGain ",fPixId));
277
278 //
279 // First guesses for the fit (should be as close to reality as possible,
280 //
281 const Double_t xmax = fHPSD->GetXaxis()->GetXmax();
282
283 fPSDExpFit = new TF1(Form("%s%d","PSDExpFit",fPixId),"exp([0]-[1]*x)",0.,xmax);
284
285 const Double_t slope_guess = (TMath::Log(fHPSD->GetEntries())+1.)/xmax;
286 const Double_t offset_guess = slope_guess*xmax;
287
288 fPSDExpFit->SetParameters(offset_guess, slope_guess);
289 fPSDExpFit->SetParNames("Offset","Slope");
290 fPSDExpFit->SetParLimits(0,offset_guess/2.,2.*offset_guess);
291 fPSDExpFit->SetParLimits(1,slope_guess/1.5,1.5*slope_guess);
292 fPSDExpFit->SetRange(0.,xmax);
293
294 fHPSD->Fit(fPSDExpFit,"RQL0");
295
296 fPSDProb = fPSDExpFit->GetProb();
297
298 if (fPSDProb < gkProbLimit)
299 {
300 SETBIT(fFlags,kOscillating);
301 return kTRUE;
302 }
303
304 CLRBIT(fFlags,kOscillating);
305
306 return kFALSE;
307}
308
309void MHCalibrationPixel::CreatePSDXaxis(Int_t n)
310{
311
312 if (fPSDXaxis)
313 return;
314
315 fPSDXaxis = new TArrayF(n);
316
317 for (Int_t i=0;i<n;i++)
318 fPSDXaxis->AddAt((Float_t)i,i);
319}
320
321void MHCalibrationPixel::CreateChargeXaxis(Int_t n)
322{
323
324 if (!fChargeXaxis)
325 {
326 fChargeXaxis = new TArrayF(n);
327 for (Int_t i=0;i<n;i++)
328 fChargeXaxis->AddAt((Float_t)i,i);
329 return;
330 }
331
332 if (fChargeXaxis->GetSize() == n)
333 return;
334
335 const Int_t diff = fChargeXaxis->GetSize()-n;
336
337 fChargeXaxis->Set(n);
338 if (diff < 0)
339 for (Int_t i=n-1;i>n-diff-1;i--)
340 fChargeXaxis->AddAt((Float_t)i,i);
341}
342
343void MHCalibrationPixel::CutArrayBorder(TArrayF *array)
344{
345
346 Int_t i;
347
348 for (i=array->GetSize()-1;i>=0;i--)
349 if (array->At(i) != 0)
350 {
351 array->Set(i+1);
352 break;
353 }
354}
355
356
357
358Bool_t MHCalibrationPixel::IsEmpty() const
359{
360 return !(fHChargeHiGain->GetEntries() || fHChargeLoGain->GetEntries());
361}
362
363Bool_t MHCalibrationPixel::IsUseLoGain() const
364{
365 return TESTBIT(fFlags,kUseLoGain);
366}
367
368Bool_t MHCalibrationPixel::IsChargeFitOK() const
369{
370 return TESTBIT(fFlags,kChargeFitOK);
371}
372
373Bool_t MHCalibrationPixel::IsOscillating()
374{
375
376 if (fPSDExpFit)
377 return TESTBIT(fFlags,kOscillating);
378
379 return CheckOscillations();
380
381}
382
383Bool_t MHCalibrationPixel::FillChargeLoGain(Float_t q)
384{
385 return (fHChargeLoGain->Fill(q) > -1);
386}
387
388Bool_t MHCalibrationPixel::FillAbsTimeLoGain(Float_t t)
389{
390 return (fHAbsTimeLoGain->Fill(t)> -1);
391}
392
393Bool_t MHCalibrationPixel::FillChargeHiGain(Float_t q)
394{
395 return (fHChargeHiGain->Fill(q) > -1);
396}
397
398Bool_t MHCalibrationPixel::FillAbsTimeHiGain(Float_t t)
399{
400 return (fHAbsTimeHiGain->Fill(t) > -1);
401}
402
403void MHCalibrationPixel::ChangeHistId(Int_t id)
404{
405
406 // Change only if the names have not yet been changed
407 if (fPixId == -1)
408 {
409
410 //
411 // Names Hi gain Histograms
412 //
413 fHChargeHiGain->SetName( Form("%s%d",fHChargeHiGain->GetName(), id));
414 fHAbsTimeHiGain->SetName( Form("%s%d",fHAbsTimeHiGain->GetName(), id));
415
416 //
417 // Title Hi gain Histograms
418 //
419 fHChargeHiGain->SetTitle( Form("%s%d",fHChargeHiGain->GetTitle(), id));
420 fHAbsTimeHiGain->SetTitle( Form("%s%d",fHAbsTimeHiGain->GetTitle(), id));
421
422 //
423 // Names Low Gain Histograms
424 //
425 fHChargeLoGain->SetName( Form("%s%d",fHChargeLoGain->GetName(),id));
426 fHAbsTimeLoGain->SetName( Form("%s%d",fHAbsTimeLoGain->GetName(),id));
427
428 //
429 // Titles Low Gain Histograms
430 //
431 fHChargeLoGain->SetTitle( Form("%s%d",fHChargeLoGain->GetTitle(),id));
432 fHAbsTimeLoGain->SetTitle( Form("%s%d",fHAbsTimeLoGain->GetTitle(),id));
433
434 fPixId = id;
435 }
436
437}
438
439
440Bool_t MHCalibrationPixel::UseLoGain()
441{
442
443 if (fHChargeHiGain->Integral() > fHChargeLoGain->Integral())
444 {
445 CLRBIT(fFlags,kUseLoGain);
446 return kFALSE;
447 }
448 else
449 {
450 SETBIT(fFlags,kUseLoGain);
451 return kTRUE;
452 }
453}
454
455Bool_t MHCalibrationPixel::FillGraphs(Float_t qhi,Float_t qlo)
456{
457
458 if (fTotalEntries >= fCurrentSize)
459 {
460 fCurrentSize *= 2;
461
462 fHiGains->Set(fCurrentSize);
463 fLoGains->Set(fCurrentSize);
464 }
465
466 fHiGains->AddAt(qhi,fTotalEntries);
467 fLoGains->AddAt(qlo,fTotalEntries);
468
469 fTotalEntries++;
470
471 return kTRUE;
472
473}
474
475
476// -------------------------------------------------------------------------
477//
478// Draw a legend with the fit results
479//
480void MHCalibrationPixel::DrawLegend()
481{
482
483 fFitLegend = new TPaveText(0.05,0.05,0.95,0.95);
484
485 if (IsChargeFitOK())
486 fFitLegend->SetFillColor(80);
487 else
488 fFitLegend->SetFillColor(2);
489
490 fFitLegend->SetLabel("Results of the Gauss Fit:");
491 fFitLegend->SetTextSize(0.05);
492
493 const TString line1 =
494 Form("Mean: Q_{#mu} = %2.2f #pm %2.2f",fChargeMean,fChargeMeanErr);
495 TText *t1 = fFitLegend->AddText(line1);
496 t1->SetBit(kCanDelete);
497
498 const TString line4 =
499 Form("Sigma: #sigma_{Q} = %2.2f #pm %2.2f",fChargeSigma,fChargeSigmaErr);
500 TText *t2 = fFitLegend->AddText(line4);
501 t2->SetBit(kCanDelete);
502
503 const TString line7 =
504 Form("#chi^{2} / N_{dof}: %4.2f / %3i",fChargeChisquare,fChargeNdf);
505 TText *t3 = fFitLegend->AddText(line7);
506 t3->SetBit(kCanDelete);
507
508 const TString line8 =
509 Form("Probability: %4.3f ",fChargeProb);
510 TText *t4 = fFitLegend->AddText(line8);
511 t4->SetBit(kCanDelete);
512
513 if (IsChargeFitOK())
514 {
515 TText *t5 = fFitLegend->AddText("Result of the Fit: OK");
516 t5->SetBit(kCanDelete);
517 }
518 else
519 {
520 TText *t6 = fFitLegend->AddText("Result of the Fit: NOT OK");
521 t6->SetBit(kCanDelete);
522 }
523
524 fFitLegend->SetBit(kCanDelete);
525 fFitLegend->Draw();
526
527}
528
529
530TObject *MHCalibrationPixel::DrawClone(Option_t *option) const
531{
532
533 gROOT->SetSelectedPad(NULL);
534
535 MHCalibrationPixel *newobj = (MHCalibrationPixel*)Clone();
536
537 if (!newobj)
538 return 0;
539 newobj->SetBit(kCanDelete);
540
541 if (strlen(option))
542 newobj->Draw(option);
543 else
544 newobj->Draw(GetDrawOption());
545
546 return newobj;
547}
548
549
550
551// -------------------------------------------------------------------------
552//
553// Draw the histogram
554//
555void MHCalibrationPixel::Draw(Option_t *opt)
556{
557
558 if (!fHivsLoGain)
559 FitHiGainvsLoGain();
560
561 gStyle->SetOptFit(0);
562 gStyle->SetOptStat(111111);
563
564 gROOT->SetSelectedPad(NULL);
565
566 TCanvas *c = MH::MakeDefCanvas(this,600,900);
567 c->SetBit(kCanDelete);
568
569 c->Divide(2,5);
570
571 c->cd(1);
572 gPad->SetBorderMode(0);
573 gPad->SetTicks();
574
575 if (fHChargeHiGain->Integral() > 0)
576 gPad->SetLogy();
577
578 fHChargeHiGain->Draw(opt);
579
580 if (IsUseLoGain())
581 {
582
583 c->cd(2);
584 gPad->SetTicks();
585
586 if (fHChargeLoGain->Integral() > 0)
587 gPad->SetLogy();
588
589 fHChargeLoGain->Draw(opt);
590
591 if (fChargeGausFit)
592 {
593 fChargeGausFit->SetLineColor(IsChargeFitOK() ? kGreen : kRed);
594 fChargeGausFit->Draw("same");
595 }
596
597 c->cd(3);
598 gROOT->SetSelectedPad(NULL);
599 gStyle->SetOptFit();
600 if (fHivsLoGain)
601 fHivsLoGain->Draw("prof");
602
603 c->cd(4);
604 DrawLegend();
605 }
606 else
607 {
608 if (fChargeGausFit)
609 {
610 fChargeGausFit->SetLineColor(IsChargeFitOK() ? kGreen : kRed);
611 fChargeGausFit->Draw("same");
612 }
613
614 c->cd(2);
615 gPad->SetTicks();
616
617 if (fHChargeLoGain->Integral() > 0)
618 gPad->SetLogy(1);
619
620 fHChargeLoGain->Draw(opt);
621
622 c->cd(3);
623 DrawLegend();
624
625 c->cd(4);
626
627 gROOT->SetSelectedPad(NULL);
628 gStyle->SetOptFit();
629 if (fHivsLoGain)
630 fHivsLoGain->Draw("prof");
631 }
632
633 c->cd(5);
634 gPad->SetTicks();
635 fHAbsTimeHiGain->Draw(opt);
636
637 c->cd(6);
638 gPad->SetTicks();
639 fHAbsTimeLoGain->Draw(opt);
640
641 CreateChargeXaxis(fHiGains->GetSize());
642
643 c->cd(7);
644 gPad->SetTicks();
645 TGraph *gr1 = new TGraph(fChargeXaxis->GetSize(),
646 fChargeXaxis->GetArray(),
647 fHiGains->GetArray());
648 gr1->SetTitle("Evolution of HiGain charges with event number");
649 gr1->SetBit(kCanDelete);
650 gr1->Draw("AL");
651
652 CreateChargeXaxis(fLoGains->GetSize());
653
654 c->cd(8);
655 gPad->SetTicks();
656 TGraph *gr2 = new TGraph(fChargeXaxis->GetSize(),
657 fChargeXaxis->GetArray(),
658 fLoGains->GetArray());
659 gr2->SetTitle("Evolution of LoGain charges with event number");
660 gr2->SetBit(kCanDelete);
661 gr2->Draw("AL");
662
663 c->Modified();
664 c->Update();
665
666 c->cd(9);
667
668 TArrayF *array;
669 TString title = "Power Spectrum Density ";
670
671 if(IsUseLoGain())
672 {
673 if (!fPSDLoGain)
674 return;
675 array = fPSDLoGain;
676 title += "LoGain";
677 }
678 else
679 {
680 if (!fPSDHiGain)
681 return;
682 array = fPSDHiGain;
683 title += "HiGain";
684 }
685
686 if (!fPSDXaxis)
687 CreatePSDXaxis(array->GetSize());
688
689 TGraph *gr3 = new TGraph(fPSDXaxis->GetSize(),fPSDXaxis->GetArray(),array->GetArray());
690 gr3->SetTitle(title.Data());
691 gr3->SetBit(kCanDelete);
692 gr3->Draw("AL");
693
694 c->Modified();
695 c->Update();
696
697 c->cd(10);
698
699 gStyle->SetOptStat(111111);
700 gStyle->SetOptFit();
701 gPad->SetTicks();
702
703 if (fHPSD->Integral() > 0)
704 gPad->SetLogy();
705
706 fHPSD->Draw(opt);
707
708 if (fPSDExpFit)
709 {
710 fPSDExpFit->SetLineColor(IsOscillating() ? kRed : kGreen);
711 fPSDExpFit->Draw("same");
712 }
713
714 c->Modified();
715 c->Update();
716
717 c->Iconify();
718
719 return;
720}
721
722void MHCalibrationPixel::FitHiGainvsLoGain()
723{
724
725 *fLog << inf << "Fit Hi Gain vs Lo Gain " << endl;
726
727 if (fHivsLoGain)
728 return;
729
730 if ((!fHiGains) || (!fLoGains) || (fHiGains->GetSize() == 0) || (fLoGains->GetSize() == 0))
731 return;
732
733 gStyle->SetOptFit();
734
735 fHivsLoGain = new TProfile("HiGainvsLoGain","Plot the High Gain vs. Low Gain",100,0.,1000.,0.,1000.);
736 fHivsLoGain->GetXaxis()->SetTitle("Sum of Charges High Gain");
737 fHivsLoGain->GetYaxis()->SetTitle("Sum of Charges Low Gain");
738 fHivsLoGain->SetName(Form("%s%d",fHivsLoGain->GetName(),fPixId));
739
740 for (Int_t i=0;i<fTotalEntries;i++)
741 fHivsLoGain->Fill(fHiGains->At(i),fLoGains->At(i),1);
742
743 fHivsLoGain->Fit("pol1","rq","",fHivsLoGain->GetMean()-2.5*fHivsLoGain->GetRMS(),
744 fHivsLoGain->GetMean()+2.5*fHivsLoGain->GetRMS());
745
746 fOffset = fHivsLoGain->GetFunction("pol1")->GetParameter(0);
747 fSlope = fHivsLoGain->GetFunction("pol1")->GetParameter(1);
748
749}
750
751
752
753Bool_t MHCalibrationPixel::FitCharge(Option_t *option)
754{
755
756 if (fChargeGausFit)
757 return kFALSE;
758
759 //
760 // Get the fitting ranges
761 //
762 Axis_t rmin = fChargeFirstHiGain;
763 Axis_t rmax = fChargeLastHiGain;
764 TH1F *hist = fHChargeHiGain;
765
766 if (TESTBIT(fFlags,kUseLoGain))
767 {
768 rmin = fChargeFirstLoGain;
769 rmax = fChargeLastLoGain;
770 hist = fHChargeLoGain;
771 }
772
773 //
774 // First guesses for the fit (should be as close to reality as possible,
775 //
776 const Stat_t entries = hist->Integral("width");
777 const Double_t mu_guess = hist->GetBinCenter(hist->GetMaximumBin());
778 const Double_t sigma_guess = (rmax-rmin)/2.;
779 const Double_t area_guess = entries/gkSq2Pi/sigma_guess;
780
781 fChargeGausFit = new TF1(Form("%s%d","ChargeGausFit",fPixId),"gaus",rmin,rmax);
782
783 if (!fChargeGausFit)
784 {
785 *fLog << warn << dbginf << "WARNING: Could not create fit function for Gauss fit" << endl;
786 return kFALSE;
787 }
788
789 fChargeGausFit->SetParameters(area_guess,mu_guess,sigma_guess);
790 fChargeGausFit->SetParNames("Area","#mu","#sigma");
791 fChargeGausFit->SetParLimits(0,0.,entries);
792 fChargeGausFit->SetParLimits(1,rmin,rmax);
793 fChargeGausFit->SetParLimits(2,0.,rmax-rmin);
794 fChargeGausFit->SetRange(rmin,rmax);
795
796 hist->Fit(fChargeGausFit,option);
797
798 //
799 // If we are not able to fit, try once again
800 //
801 if (fChargeGausFit->GetProb() < fProbLimit)
802 {
803
804 Axis_t rtry = fChargeGausFit->GetParameter(1) - 2.5*fChargeGausFit->GetParameter(2);
805 rmin = (rtry < rmin ? rmin : rtry);
806 rmax = fChargeGausFit->GetParameter(1) + 2.5*fChargeGausFit->GetParameter(2);
807
808 fChargeGausFit->SetRange(rmin,rmax);
809 hist->Fit(fChargeGausFit,option);
810 }
811
812 fChargeChisquare = fChargeGausFit->GetChisquare();
813 fChargeNdf = fChargeGausFit->GetNDF();
814 fChargeProb = fChargeGausFit->GetProb();
815 fChargeMean = fChargeGausFit->GetParameter(1);
816 fChargeMeanErr = fChargeGausFit->GetParError(1);
817 fChargeSigma = fChargeGausFit->GetParameter(2);
818 fChargeSigmaErr = fChargeGausFit->GetParError(2);
819
820 //
821 // From the absolute time, we only take the mean and RMS
822 //
823 fAbsTimeMean = (Float_t)fHAbsTimeHiGain->GetMean();
824 fAbsTimeRms = (Float_t)fHAbsTimeHiGain->GetRMS();
825 fAbsTimeMeanErr = (Float_t)fAbsTimeRms / TMath::Sqrt(fHAbsTimeHiGain->GetEntries());
826
827 if (TESTBIT(fFlags,kUseLoGain))
828 {
829 fAbsTimeMean = fHAbsTimeLoGain->GetMean();
830 fAbsTimeRms = fHAbsTimeLoGain->GetRMS();
831 fAbsTimeMeanErr = fAbsTimeRms / TMath::Sqrt(fHAbsTimeLoGain->GetEntries());
832 }
833
834 //
835 // The fit result is accepted under condition:
836 // 1) The results are not nan's
837 // 2) The NDF is not smaller than fNDFLimit (5)
838 // 3) The Probability is greater than fProbLimit (default 0.001 == 99.9%)
839 //
840 // Otherwise take means and RMS of the histograms
841 //
842 if ( TMath::IsNaN(fChargeMean)
843 || TMath::IsNaN(fChargeMeanErr)
844 || TMath::IsNaN(fChargeProb)
845 || TMath::IsNaN(fChargeSigma)
846 || TMath::IsNaN(fChargeSigmaErr)
847 || (fChargeNdf < fNDFLimit)
848 || (fChargeProb < fProbLimit) )
849 {
850
851 fChargeMean = hist->GetMean();
852 fChargeMeanErr = hist->GetRMS()/hist->GetEntries();
853 fChargeSigma = hist->GetRMS();
854 fChargeSigmaErr = fChargeMeanErr/2.;
855
856 CLRBIT(fFlags,kChargeFitOK);
857 return kFALSE;
858 }
859
860 SETBIT(fFlags,kChargeFitOK);
861 return kTRUE;
862}
863
864
865void MHCalibrationPixel::CutAllEdges()
866{
867
868 Int_t nbins = 30;
869
870 CutEdges(fHChargeHiGain,nbins);
871
872 fChargeFirstHiGain = fHChargeHiGain->GetBinLowEdge(fHChargeHiGain->GetXaxis()->GetFirst());
873 fChargeLastHiGain = fHChargeHiGain->GetBinLowEdge(fHChargeHiGain->GetXaxis()->GetLast())
874 +fHChargeHiGain->GetBinWidth(0);
875
876 CutEdges(fHChargeLoGain,nbins);
877
878 fChargeFirstLoGain = fHChargeLoGain->GetBinLowEdge(fHChargeLoGain->GetXaxis()->GetFirst());
879 fChargeLastLoGain = fHChargeLoGain->GetBinLowEdge(fHChargeLoGain->GetXaxis()->GetLast())
880 +fHChargeLoGain->GetBinWidth(0);
881
882
883 CutEdges(fHAbsTimeHiGain,0);
884
885 fAbsTimeFirstHiGain = fHAbsTimeHiGain->GetBinLowEdge(fHAbsTimeHiGain->GetXaxis()->GetFirst());
886 fAbsTimeLastHiGain = fHAbsTimeHiGain->GetBinLowEdge(fHAbsTimeHiGain->GetXaxis()->GetLast())
887 +fHAbsTimeHiGain->GetBinWidth(0);
888
889 CutEdges(fHAbsTimeLoGain,0);
890
891 fAbsTimeFirstLoGain = fHAbsTimeLoGain->GetBinLowEdge(fHAbsTimeLoGain->GetXaxis()->GetFirst());
892 fAbsTimeLastLoGain = fHAbsTimeLoGain->GetBinLowEdge(fHAbsTimeLoGain->GetXaxis()->GetLast())
893 +fHAbsTimeLoGain->GetBinWidth(0);
894
895
896}
897
898void MHCalibrationPixel::PrintChargeFitResult()
899{
900
901 *fLog << all << "Results of the Summed Charges Fit: " << endl;
902 *fLog << all << "Chisquare: " << fChargeChisquare << endl;
903 *fLog << all << "DoF: " << fChargeNdf << endl;
904 *fLog << all << "Probability: " << fChargeProb << endl;
905 *fLog << all << endl;
906
907}
908
Note: See TracBrowser for help on using the repository browser.