source: trunk/MagicSoft/Mars/mhcalib/MHGausEvents.cc@ 5004

Last change on this file since 5004 was 4994, checked in by gaug, 21 years ago
*** empty log message ***
File size: 25.3 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// MHGausEvents
28//
29// A base class for events which are believed to follow a Gaussian distribution
30// with time, e.g. calibration events, observables containing white noise, ...
31//
32// MHGausEvents derives from MH, thus all features of MH can be used by a class
33// deriving from MHGausEvents, especially the filling functions.
34//
35// The central objects are:
36//
37// 1) The TH1F fHGausHist:
38// ====================
39//
40// It is created with a default name and title and resides in directory NULL.
41// - Any class deriving from MHGausEvents needs to apply a binning to fHGausHist
42// (e.g. by setting the variables fNbins, fFirst, fLast and calling the function
43// InitBins() or by directly calling fHGausHist.SetBins(..) )
44// - The histogram is filled with the functions FillHist() or FillHistAndArray().
45// - The histogram can be fitted with the function FitGaus(). This involves stripping
46// of all zeros at the lower and upper end of the histogram and re-binning to
47// a new number of bins, specified in the variable fBinsAfterStripping.
48// - The fit result's probability is compared to a reference probability fProbLimit
49// The NDF is compared to fNDFLimit and a check is made whether results are NaNs.
50// Accordingly, a flag IsGausFitOK() is set.
51// - One can repeat the fit within a given amount of sigmas from the previous mean
52// (specified by the variables fPickupLimit and fBlackoutLimit) with the function RepeatFit()
53// - One can completely skip the fitting to set mean, sigma and its errors directly
54// from the histograms with the function BypassFit()
55//
56// 2) The TArrayF fEvents:
57// ==========================
58//
59// It is created with 0 entries and not expanded unless FillArray() or FillHistAndArray()
60// are called.
61// - A first call to FillArray() or FillHistAndArray() initializes fEvents by default
62// to 512 entries.
63// - Any later call to FillArray() or FillHistAndArray() fills up the array.
64// Reaching the limit, the array is expanded by a factor 2.
65// - The array can be fourier-transformed into the array fPowerSpectrum.
66// Note that any FFT accepts only number of events which are a power of 2.
67// Thus, fEvents is cut to the next power of 2 smaller than its actual number of entries.
68// Be aware that you might lose information at the end of your analysis.
69// - Calling the function CreateFourierSpectrum() creates the array fPowerSpectrum
70// and its projection fHPowerProbability which in turn is fit to an exponential.
71// - The fit result's probability is compared to a referenc probability fProbLimit
72// and accordingly the flag IsExpFitOK() is set.
73// - The flag IsFourierSpectrumOK() is set accordingly to IsExpFitOK().
74// Later, a closer check will be installed.
75// - You can display all arrays by calls to: CreateGraphEvents() and
76// CreateGraphPowerSpectrum() and successive calls to the corresponding Getters.
77//
78// To see an example, have a look at: Draw()
79//
80//////////////////////////////////////////////////////////////////////////////
81#include "MHGausEvents.h"
82
83#include <TH1.h>
84#include <TF1.h>
85#include <TGraph.h>
86#include <TPad.h>
87#include <TVirtualPad.h>
88#include <TCanvas.h>
89#include <TStyle.h>
90
91#include "MFFT.h"
92#include "MArrayF.h"
93
94#include "MH.h"
95
96#include "MLog.h"
97#include "MLogManip.h"
98
99ClassImp(MHGausEvents);
100
101using namespace std;
102
103const Int_t MHGausEvents::fgNDFLimit = 2;
104const Float_t MHGausEvents::fgProbLimit = 0.001;
105const Int_t MHGausEvents::fgPowerProbabilityBins = 30;
106// --------------------------------------------------------------------------
107//
108// Default Constructor.
109// Sets:
110// - the default Probability Bins for fPowerProbabilityBins (fgPowerProbabilityBins)
111// - the default Probability Limit for fProbLimit (fgProbLimit)
112// - the default NDF Limit for fNDFLimit (fgNDFLimit)
113// - the default number of bins after stripping for fBinsAfterStipping (fgBinsAfterStipping)
114// - the default name of the fHGausHist ("HGausHist")
115// - the default title of the fHGausHist ("Histogram of Events with Gaussian Distribution")
116// - the default directory of the fHGausHist (NULL)
117// - the default for fNbins (100)
118// - the default for fFirst (0.)
119// - the default for fLast (100.)
120//
121// Initializes:
122// - fEvents to 0 entries
123// - fHGausHist()
124// - all other pointers to NULL
125// - all variables to 0.
126// - all flags to kFALSE
127//
128MHGausEvents::MHGausEvents(const char *name, const char *title)
129 : fEventFrequency(0),
130 fHPowerProbability(NULL),
131 fPowerSpectrum(NULL),
132 fFGausFit(NULL), fFExpFit(NULL),
133 fFirst(0.),
134 fGraphEvents(NULL), fGraphPowerSpectrum(NULL),
135 fLast(100.), fNbins(100)
136{
137
138 fName = name ? name : "MHGausEvents";
139 fTitle = title ? title : "Events with expected Gaussian distributions";
140
141 Clear();
142
143 SetBinsAfterStripping();
144 SetNDFLimit();
145 SetPowerProbabilityBins();
146 SetProbLimit();
147
148 fHGausHist.SetName("HGausHist");
149 fHGausHist.SetTitle("Histogram of Events with Gaussian Distribution");
150 // important, other ROOT will not draw the axes:
151 fHGausHist.UseCurrentStyle();
152 fHGausHist.SetDirectory(NULL);
153 fHGausHist.GetYaxis()->CenterTitle();
154}
155
156
157
158// --------------------------------------------------------------------------
159//
160// Default Destructor.
161//
162// Deletes (if Pointer is not NULL):
163//
164// - fHPowerProbability
165// - fFGausFit
166// - fFExpFit
167// - fPowerSpectrum
168// - fGraphEvents
169// - fGraphPowerSpectrum
170//
171MHGausEvents::~MHGausEvents()
172{
173
174 // delete histograms
175 if (fHPowerProbability)
176 delete fHPowerProbability;
177
178 // delete fits
179 if (fFGausFit)
180 delete fFGausFit;
181
182 if (fFExpFit)
183 delete fFExpFit;
184
185 // delete arrays
186 if (fPowerSpectrum)
187 delete fPowerSpectrum;
188
189 // delete graphs
190 if (fGraphEvents)
191 delete fGraphEvents;
192
193 if (fGraphPowerSpectrum)
194 delete fGraphPowerSpectrum;
195
196}
197
198// --------------------------------------------------------------------------
199//
200// Default Clear(), can be overloaded.
201//
202// Sets:
203// - all other pointers to NULL
204// - all variables to 0. and keep fEventFrequency
205// - all flags to kFALSE
206//
207// Deletes (if not NULL):
208// - all pointers
209//
210void MHGausEvents::Clear(Option_t *o)
211{
212
213 SetGausFitOK ( kFALSE );
214 SetExpFitOK ( kFALSE );
215 SetFourierSpectrumOK( kFALSE );
216 SetExcluded ( kFALSE );
217
218 fMean = 0.;
219 fSigma = 0.;
220 fMeanErr = 0.;
221 fSigmaErr = 0.;
222 fProb = 0.;
223
224 fCurrentSize = 0;
225
226 if (fHPowerProbability)
227 {
228 delete fHPowerProbability;
229 fHPowerProbability = NULL;
230 }
231
232 // delete fits
233 if (fFGausFit)
234 {
235 delete fFGausFit;
236 fFGausFit = NULL;
237 }
238
239 if (fFExpFit)
240 {
241 delete fFExpFit;
242 fFExpFit = NULL;
243 }
244
245 // delete arrays
246 if (fPowerSpectrum)
247 {
248 delete fPowerSpectrum;
249 fPowerSpectrum = NULL;
250 }
251
252 // delete graphs
253 if (fGraphEvents)
254 {
255 delete fGraphEvents;
256 fGraphEvents = NULL;
257 }
258
259 if (fGraphPowerSpectrum)
260 {
261 delete fGraphPowerSpectrum;
262 fGraphPowerSpectrum = NULL;
263 }
264}
265
266// --------------------------------------------------------------------------
267//
268// Use the MH::Clone function and clone additionally the rest of the
269// data members.
270//
271TObject *MHGausEvents::Clone(const char *name) const
272{
273
274 MHGausEvents &pix = (MHGausEvents&)*MH::Clone(name);
275
276 /*
277 //
278 // Copy data members
279 //
280 pix.fBinsAfterStripping = fBinsAfterStripping;
281 pix.fCurrentSize = fCurrentSize;
282 pix.fFlags = fFlags;
283 pix.fPowerProbabilityBins = fPowerProbabilityBins;
284
285 if (fHPowerProbability)
286 pix.fHPowerProbability=(TH1I*)fHPowerProbability->Clone();
287
288 if (fPowerSpectrum)
289 pix.fPowerSpectrum = new TArrayF(*fPowerSpectrum);
290
291 if (fFGausFit)
292 pix.fFGausFit=(TF1*)fFGausFit->Clone();
293 if (fFExpFit)
294 pix.fFExpFit=(TF1*)fFExpFit->Clone();
295
296 pix.fFirst = fFirst;
297
298 if (fGraphEvents)
299 pix.fGraphEvents=(TGraph*)fGraphEvents->Clone();
300 if (fGraphPowerSpectrum)
301 pix.fGraphPowerSpectrum=(TGraph*)fGraphPowerSpectrum->Clone();
302
303 pix.fHGausHist = fHGausHist;
304
305 pix.fEventFrequency = fEventFrequency;
306 pix.fLast = fLast;
307 pix.fMean = fMean;
308 pix.fMeanErr = fMeanErr;
309 pix.fNbins = fNbins;
310 pix.fNDFLimit = fNDFLimit;
311 pix.fSigma = fSigma;
312 pix.fSigmaErr = fSigmaErr;
313 pix.fProb = fProb;
314 pix.fProbLimit = fProbLimit;
315 */
316 return &pix;
317}
318
319
320// -----------------------------------------------------------------------------
321//
322// Create the x-axis for the event graph
323//
324Float_t *MHGausEvents::CreateEventXaxis(Int_t n)
325{
326
327 Float_t *xaxis = new Float_t[n];
328
329 if (fEventFrequency)
330 for (Int_t i=0;i<n;i++)
331 xaxis[i] = (Float_t)i/fEventFrequency;
332 else
333 for (Int_t i=0;i<n;i++)
334 xaxis[i] = (Float_t)i;
335
336 return xaxis;
337
338}
339
340
341// -------------------------------------------------------------------
342//
343// Create the fourier spectrum using the class MFFT.
344// The result is projected into a histogram and fitted by an exponential
345//
346void MHGausEvents::CreateFourierSpectrum()
347{
348
349 if (fFExpFit)
350 return;
351
352 if (fEvents.GetSize() < 8)
353 {
354 *fLog << warn << "Cannot create Fourier spectrum in: " << fName
355 << ". Number of events smaller than 8 " << endl;
356 return;
357 }
358
359 //
360 // The number of entries HAS to be a potence of 2,
361 // so we can only cut out from the last potence of 2 to the rest.
362 // Another possibility would be to fill everything with
363 // zeros, but that gives a low frequency peak, which we would
364 // have to cut out later again.
365 //
366 // So, we have to live with the possibility that at the end
367 // of the calibration run, something has happened without noticing
368 // it...
369 //
370
371 // This cuts only the non-used zero's, but MFFT will later cut the rest
372 fEvents.StripZeros();
373
374 if (fEvents.GetSize() < 8)
375 {
376 /*
377 *fLog << warn << "Cannot create Fourier spectrum. " << endl;
378 *fLog << warn << "Number of events (after stripping of zeros) is smaller than 8 "
379 << "in pixel: " << fPixId << endl;
380 */
381 return;
382 }
383
384 MFFT fourier;
385
386 fPowerSpectrum = fourier.PowerSpectrumDensity(&fEvents);
387 fHPowerProbability = ProjectArray(*fPowerSpectrum, fPowerProbabilityBins,
388 Form("%s%s","PowerProbability",GetName()),
389 "Probability of Power occurrance");
390 fHPowerProbability->SetXTitle("P(f)");
391 fHPowerProbability->SetYTitle("Counts");
392 fHPowerProbability->GetYaxis()->CenterTitle();
393 fHPowerProbability->SetDirectory(NULL);
394 fHPowerProbability->SetBit(kCanDelete);
395 //
396 // First guesses for the fit (should be as close to reality as possible,
397 //
398 const Double_t xmax = fHPowerProbability->GetXaxis()->GetXmax();
399
400 fFExpFit = new TF1("FExpFit","exp([0]-[1]*x)",0.,xmax);
401
402 const Double_t slope_guess = (TMath::Log(fHPowerProbability->GetEntries())+1.)/xmax;
403 const Double_t offset_guess = slope_guess*xmax;
404
405 fFExpFit->SetParameters(offset_guess, slope_guess);
406 fFExpFit->SetParNames("Offset","Slope");
407 fFExpFit->SetParLimits(0,offset_guess/2.,2.*offset_guess);
408 fFExpFit->SetParLimits(1,slope_guess/1.5,1.5*slope_guess);
409 fFExpFit->SetRange(0.,xmax);
410
411 fHPowerProbability->Fit(fFExpFit,"RQL0");
412
413 if (GetExpProb() > fProbLimit)
414 SetExpFitOK(kTRUE);
415
416 //
417 // For the moment, this is the only check, later we can add more...
418 //
419 SetFourierSpectrumOK(IsExpFitOK());
420
421 return;
422}
423
424// ----------------------------------------------------------------------------------
425//
426// Create a graph to display the array fEvents
427// If the variable fEventFrequency is set, the x-axis is transformed into real time.
428//
429void MHGausEvents::CreateGraphEvents()
430{
431
432 fEvents.StripZeros();
433
434 const Int_t n = fEvents.GetSize();
435
436 if (n==0)
437 return;
438
439 fGraphEvents = new TGraph(n,CreateEventXaxis(n),fEvents.GetArray());
440 fGraphEvents->SetTitle("Evolution of Events with time");
441 fGraphEvents->GetXaxis()->SetTitle((fEventFrequency) ? "Time [s]" : "Event Nr.");
442 fGraphEvents->GetYaxis()->SetTitle(fHGausHist.GetXaxis()->GetTitle());
443 fGraphEvents->GetYaxis()->CenterTitle();
444}
445
446// ----------------------------------------------------------------------------------
447//
448// Create a graph to display the array fPowerSpectrum
449// If the variable fEventFrequency is set, the x-axis is transformed into real frequency.
450//
451void MHGausEvents::CreateGraphPowerSpectrum()
452{
453
454 fPowerSpectrum->StripZeros();
455
456 const Int_t n = fPowerSpectrum->GetSize();
457
458 fGraphPowerSpectrum = new TGraph(n,CreatePSDXaxis(n),fPowerSpectrum->GetArray());
459 fGraphPowerSpectrum->SetTitle("Power Spectrum Density");
460 fGraphPowerSpectrum->GetXaxis()->SetTitle((fEventFrequency) ? "Frequency [Hz]" : "Frequency");
461 fGraphPowerSpectrum->GetYaxis()->SetTitle("P(f)");
462 fGraphPowerSpectrum->GetYaxis()->CenterTitle();
463
464}
465
466
467// -----------------------------------------------------------------------------
468//
469// Create the x-axis for the event graph
470//
471Float_t *MHGausEvents::CreatePSDXaxis(Int_t n)
472{
473
474 Float_t *xaxis = new Float_t[n];
475
476 if (fEventFrequency)
477 for (Int_t i=0;i<n;i++)
478 xaxis[i] = 0.5*(Float_t)i*fEventFrequency/n;
479 else
480 for (Int_t i=0;i<n;i++)
481 xaxis[i] = 0.5*(Float_t)i/n;
482
483 return xaxis;
484
485}
486
487// -----------------------------------------------------------------------------
488//
489// Default draw:
490//
491// The following options can be chosen:
492//
493// "EVENTS": displays a TGraph of the array fEvents
494// "FOURIER": display a TGraph of the fourier transform of fEvents
495// displays the projection of the fourier transform with the fit
496//
497// The following picture shows a typical outcome of call to Draw("fourierevents"):
498// - The first plot shows the distribution of the values with the Gauss fit
499// (which did not succeed, in this case, for obvious reasons)
500// - The second plot shows the TGraph with the events vs. time
501// - The third plot shows the fourier transform and a small peak at about 85 Hz.
502// - The fourth plot shows the projection of the fourier components and an exponential
503// fit, with the result that the observed deviation is still statistical with a
504// probability of 0.5%.
505//
506//Begin_Html
507/*
508<img src="images/MHGausEventsDraw.gif">
509*/
510//End_Html
511//
512void MHGausEvents::Draw(const Option_t *opt)
513{
514
515 TVirtualPad *pad = gPad ? gPad : MH::MakeDefCanvas(this,600, 900);
516
517 TString option(opt);
518 option.ToLower();
519
520 Int_t win = 1;
521
522 if (option.Contains("events"))
523 {
524 option.ReplaceAll("events","");
525 win += 1;
526 }
527 if (option.Contains("fourier"))
528 {
529 option.ReplaceAll("fourier","");
530 win += 2;
531 }
532
533 pad->SetBorderMode(0);
534 pad->Divide(1,win);
535 pad->cd(1);
536
537 if (!IsEmpty() && !IsOnlyOverflow() && !IsOnlyUnderflow())
538 gPad->SetLogy();
539
540 gPad->SetTicks();
541
542 fHGausHist.Draw(option);
543
544 if (fFGausFit)
545 {
546 fFGausFit->SetLineColor(IsGausFitOK() ? kGreen : kRed);
547 fFGausFit->Draw("same");
548 }
549 switch (win)
550 {
551 case 2:
552 pad->cd(2);
553 DrawEvents();
554 break;
555 case 3:
556 pad->cd(2);
557 DrawPowerSpectrum(*pad,3);
558 break;
559 case 4:
560 pad->cd(2);
561 DrawEvents();
562 pad->cd(3);
563 DrawPowerSpectrum(*pad,4);
564 break;
565 }
566}
567
568void MHGausEvents::DrawEvents(Option_t *opt)
569{
570
571 if (!fGraphEvents)
572 CreateGraphEvents();
573
574 if (!fGraphEvents)
575 return;
576
577 fGraphEvents->SetBit(kCanDelete);
578 fGraphEvents->SetTitle("Events with time");
579
580 TString option(opt);
581 option.ToLower();
582
583 if (option.Contains("same"))
584 {
585 option.ReplaceAll("same","");
586 fGraphEvents->Draw(option+"L");
587 }
588 else
589 fGraphEvents->Draw(option+"AL");
590}
591
592
593void MHGausEvents::DrawPowerSpectrum(TVirtualPad &pad, Int_t i)
594{
595
596 if (fPowerSpectrum)
597 {
598 if (!fGraphPowerSpectrum)
599 CreateGraphPowerSpectrum();
600
601 fGraphPowerSpectrum->Draw("AL");
602 fGraphPowerSpectrum->SetBit(kCanDelete);
603 }
604
605 pad.cd(i);
606
607 if (fHPowerProbability && fHPowerProbability->GetEntries() > 0)
608 {
609 gPad->SetLogy();
610 fHPowerProbability->Draw();
611 if (fFExpFit)
612 {
613 fFExpFit->SetLineColor(IsExpFitOK() ? kGreen : kRed);
614 fFExpFit->Draw("same");
615 }
616 }
617}
618
619
620// --------------------------------------------------------------------------
621//
622// Fill fEvents with f
623// If size of fEvents is 0, initializes it to 512
624// If size of fEvents is smaller than fCurrentSize, double the size
625// Increase fCurrentSize by 1
626//
627void MHGausEvents::FillArray(const Float_t f)
628{
629
630 if (fEvents.GetSize() == 0)
631 fEvents.Set(512);
632
633 if (fCurrentSize >= fEvents.GetSize())
634 fEvents.Set(fEvents.GetSize()*2);
635
636 fEvents.AddAt(f,fCurrentSize++);
637}
638
639
640// --------------------------------------------------------------------------
641//
642// Fills fHGausHist with f
643// Returns kFALSE, if overflow or underflow occurred, else kTRUE
644//
645Bool_t MHGausEvents::FillHist(const Float_t f)
646{
647 return fHGausHist.Fill(f) > -1;
648}
649
650// --------------------------------------------------------------------------
651//
652// Executes:
653// - FillArray()
654// - FillHist()
655//
656Bool_t MHGausEvents::FillHistAndArray(const Float_t f)
657{
658
659 FillArray(f);
660 return FillHist(f);
661}
662
663// -------------------------------------------------------------------
664//
665// Fit fGausHist with a Gaussian after stripping zeros from both ends
666// and rebinned to the number of bins specified in fBinsAfterStripping
667//
668// The fit results are retrieved and stored in class-own variables.
669//
670// A flag IsGausFitOK() is set according to whether the fit probability
671// is smaller or bigger than fProbLimit, whether the NDF is bigger than
672// fNDFLimit and whether results are NaNs.
673//
674Bool_t MHGausEvents::FitGaus(Option_t *option, const Double_t xmin, const Double_t xmax)
675{
676
677 if (IsGausFitOK())
678 return kTRUE;
679
680 //
681 // First, strip the zeros from the edges which contain only zeros and rebin
682 // to fBinsAfterStripping bins. If fBinsAfterStripping is 0, reduce bins only by
683 // a factor 10.
684 //
685 // (ATTENTION: The Chisquare method is more sensitive,
686 // the _less_ bins, you have!)
687 //
688 StripZeros(&fHGausHist,
689 fBinsAfterStripping ? fBinsAfterStripping
690 : (fNbins > 1000 ? fNbins/10 : 0));
691
692 TAxis *axe = fHGausHist.GetXaxis();
693 //
694 // Get the fitting ranges
695 //
696 Axis_t rmin = ((xmin==0.) && (xmax==0.)) ? fHGausHist.GetBinCenter(axe->GetFirst()) : xmin;
697 Axis_t rmax = ((xmin==0.) && (xmax==0.)) ? fHGausHist.GetBinCenter(axe->GetLast()) : xmax;
698
699 //
700 // First guesses for the fit (should be as close to reality as possible,
701 //
702 const Stat_t entries = fHGausHist.Integral(axe->FindBin(rmin),axe->FindBin(rmax),"width");
703 const Double_t mu_guess = fHGausHist.GetBinCenter(fHGausHist.GetMaximumBin());
704 const Double_t sigma_guess = fHGausHist.GetRMS();
705 const Double_t area_guess = entries/TMath::Sqrt(TMath::TwoPi())/sigma_guess;
706
707 fFGausFit = new TF1("GausFit","gaus",rmin,rmax);
708
709 if (!fFGausFit)
710 {
711 *fLog << warn << dbginf << "WARNING: Could not create fit function for Gauss fit "
712 << "in: " << fName << endl;
713 return kFALSE;
714 }
715
716 fFGausFit->SetParameters(area_guess,mu_guess,sigma_guess);
717 fFGausFit->SetParNames("Area","#mu","#sigma");
718 fFGausFit->SetParLimits(0,0.,area_guess*25.);
719 fFGausFit->SetParLimits(1,rmin,rmax);
720 fFGausFit->SetParLimits(2,0.,rmax-rmin);
721 fFGausFit->SetRange(rmin,rmax);
722
723 fHGausHist.Fit(fFGausFit,option);
724
725
726 fMean = fFGausFit->GetParameter(1);
727 fSigma = fFGausFit->GetParameter(2);
728 fMeanErr = fFGausFit->GetParError(1);
729 fSigmaErr = fFGausFit->GetParError(2);
730 fProb = fFGausFit->GetProb();
731 //
732 // The fit result is accepted under condition:
733 // 1) The results are not nan's
734 // 2) The NDF is not smaller than fNDFLimit (default: fgNDFLimit)
735 // 3) The Probability is greater than fProbLimit (default: fgProbLimit)
736 //
737 if ( TMath::IsNaN(fMean)
738 || TMath::IsNaN(fMeanErr)
739 || TMath::IsNaN(fProb)
740 || TMath::IsNaN(fSigma)
741 || TMath::IsNaN(fSigmaErr)
742 || fFGausFit->GetNDF() < fNDFLimit
743 || fProb < fProbLimit )
744 return kFALSE;
745
746 SetGausFitOK(kTRUE);
747 return kTRUE;
748}
749
750
751const Double_t MHGausEvents::GetChiSquare() const
752{
753 return ( fFGausFit ? fFGausFit->GetChisquare() : 0.);
754}
755
756
757const Double_t MHGausEvents::GetExpChiSquare() const
758{
759 return ( fFExpFit ? fFExpFit->GetChisquare() : 0.);
760}
761
762
763const Int_t MHGausEvents::GetExpNdf() const
764{
765 return ( fFExpFit ? fFExpFit->GetNDF() : 0);
766}
767
768
769const Double_t MHGausEvents::GetExpProb() const
770{
771 return ( fFExpFit ? fFExpFit->GetProb() : 0.);
772}
773
774
775const Int_t MHGausEvents::GetNdf() const
776{
777 return ( fFGausFit ? fFGausFit->GetNDF() : 0);
778}
779
780const Double_t MHGausEvents::GetOffset() const
781{
782 return ( fFExpFit ? fFExpFit->GetParameter(0) : 0.);
783}
784
785
786
787// --------------------------------------------------------------------------
788//
789// If fFExpFit exists, returns fit parameter 1 (Slope of Exponential fit),
790// otherwise 0.
791//
792const Double_t MHGausEvents::GetSlope() const
793{
794 return ( fFExpFit ? fFExpFit->GetParameter(1) : 0.);
795}
796
797// --------------------------------------------------------------------------
798//
799// Default InitBins, can be overloaded.
800//
801// Executes:
802// - fHGausHist.SetBins(fNbins,fFirst,fLast)
803//
804void MHGausEvents::InitBins()
805{
806 fHGausHist.SetBins(fNbins,fFirst,fLast);
807}
808
809// --------------------------------------------------------------------------
810//
811// Return kFALSE if number of entries is 0
812//
813const Bool_t MHGausEvents::IsEmpty() const
814{
815 return !(fHGausHist.GetEntries());
816}
817
818// --------------------------------------------------------------------------
819//
820// Return kTRUE if number of entries is bin content of fNbins+1
821//
822const Bool_t MHGausEvents::IsOnlyOverflow() const
823{
824 return fHGausHist.GetEntries() == fHGausHist.GetBinContent(fNbins+1);
825}
826
827// --------------------------------------------------------------------------
828//
829// Return kTRUE if number of entries is bin content of 0
830//
831const Bool_t MHGausEvents::IsOnlyUnderflow() const
832{
833 return fHGausHist.GetEntries() == fHGausHist.GetBinContent(0);
834}
835
836
837const Bool_t MHGausEvents::IsExcluded() const
838{
839 return TESTBIT(fFlags,kExcluded);
840}
841
842
843const Bool_t MHGausEvents::IsExpFitOK() const
844{
845 return TESTBIT(fFlags,kExpFitOK);
846}
847
848const Bool_t MHGausEvents::IsFourierSpectrumOK() const
849{
850 return TESTBIT(fFlags,kFourierSpectrumOK);
851}
852
853
854const Bool_t MHGausEvents::IsGausFitOK() const
855{
856 return TESTBIT(fFlags,kGausFitOK);
857}
858
859
860// -----------------------------------------------------------------------------------
861//
862// A default print
863//
864void MHGausEvents::Print(const Option_t *o) const
865{
866
867 *fLog << all << endl;
868 *fLog << all << "Results of the Gauss Fit in: " << fName << endl;
869 *fLog << all << "Mean: " << GetMean() << endl;
870 *fLog << all << "Sigma: " << GetSigma() << endl;
871 *fLog << all << "Chisquare: " << GetChiSquare() << endl;
872 *fLog << all << "DoF: " << GetNdf() << endl;
873 *fLog << all << "Probability: " << GetProb() << endl;
874 *fLog << all << endl;
875
876}
877
878
879// --------------------------------------------------------------------------
880//
881// Default Reset(), can be overloaded.
882//
883// Executes:
884// - Clear()
885// - fHGausHist.Reset()
886// - fEvents.Set(0)
887//
888void MHGausEvents::Reset()
889{
890
891 Clear();
892 fHGausHist.Reset();
893 fEvents.Set(0);
894
895}
896
897// --------------------------------------------------------------------------
898//
899// Set Excluded bit from outside
900//
901void MHGausEvents::SetExcluded(const Bool_t b)
902{
903 b ? SETBIT(fFlags,kExcluded) : CLRBIT(fFlags,kExcluded);
904}
905
906
907// -------------------------------------------------------------------
908//
909// The flag setters are to be used ONLY for Monte-Carlo!!
910//
911void MHGausEvents::SetExpFitOK(const Bool_t b)
912{
913
914 b ? SETBIT(fFlags,kExpFitOK) : CLRBIT(fFlags,kExpFitOK);
915}
916
917// -------------------------------------------------------------------
918//
919// The flag setters are to be used ONLY for Monte-Carlo!!
920//
921void MHGausEvents::SetFourierSpectrumOK(const Bool_t b)
922{
923
924 b ? SETBIT(fFlags,kFourierSpectrumOK) : CLRBIT(fFlags,kFourierSpectrumOK);
925}
926
927
928// -------------------------------------------------------------------
929//
930// The flag setters are to be used ONLY for Monte-Carlo!!
931//
932void MHGausEvents::SetGausFitOK(const Bool_t b)
933{
934 b ? SETBIT(fFlags,kGausFitOK) : CLRBIT(fFlags,kGausFitOK);
935
936}
937
Note: See TracBrowser for help on using the repository browser.