source: trunk/Mars/mhcalib/MHGausEvents.cc@ 9899

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