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

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