GausRmsFitter.cxx
Go to the documentation of this file.
1 // GausRmsFitter.cxx
2 
3 #include "GausRmsFitter.h"
6 #include "TF1.h"
7 #include "TH1.h"
8 #include "TList.h"
9 #include <iostream>
10 #include <iomanip>
11 
12 using std::cout;
13 using std::endl;
14 using std::setw;
15 
16 //**********************************************************************
17 
19 : m_sigma0(0.0), m_nsigma(0.0), m_fnam(fnam), m_LogLevel(0) { }
20 
21 //**********************************************************************
22 
23 GausRmsFitter::GausRmsFitter(double sigma0, double nsigma, Name fnam)
24 : m_sigma0(sigma0), m_nsigma(nsigma), m_fnam(fnam), m_LogLevel(0) { }
25 
26 //**********************************************************************
27 
28 int GausRmsFitter::fit(TH1* ph, double mean0) const {
29  Name myname = "GausRmsFitter::fit: ";
30  if ( ph->GetEntries() == 0 ) {
31  if ( m_LogLevel >= 2 ) cout << "Histogram has no entries." << endl;
32  return 101; // E.g. empty histo.
33  }
34  if ( m_LogLevel >= 2 ) cout << myname << "Fitting with sigma " << m_sigma0
35  << " and nsigma " << m_nsigma << endl;
36  double mean = mean0;
37  double sigma = ph->GetRMS();
38  double height = ph->GetMaximum();
39  int nbin = ph->GetXaxis()->GetNbins();
40  int ibin1Start = ph->GetXaxis()->GetFirst();
41  int ibin2Start = ph->GetXaxis()->GetLast();
42  double x1 = ph->GetXaxis()->GetBinLowEdge(ibin1Start);
43  double x2 = ph->GetXaxis()->GetBinUpEdge(ibin2Start);
44  // Evaluate mean and sigma.
45  if ( m_sigma0 > 0.0 && m_nsigma > 0.0 ) {
46  sigma = 0.0;
47  double sigmaOld = m_sigma0;
48  if ( m_LogLevel >= 2 ) {
49  cout << myname << "Start loop with mean, sigma: " << mean << ", " << sigmaOld << endl;
50  }
51  const Index maxtry = 100;
52  Index itry = 0;
53  int ibin1 = ibin1Start;
54  int ibin2 = ibin2Start;
55  for ( ; itry<maxtry; ++itry ) {
56  double dx = m_nsigma*sigmaOld;
57  x1 = mean - dx;
58  ibin1 = ph->GetXaxis()->FindFixBin(x1);
59  if ( ibin1 == 0 ) ibin1 = 1;
60  x1 = ph->GetXaxis()->GetBinLowEdge(ibin1);
61  x2 = mean + dx;
62  ibin2 = ph->GetXaxis()->FindFixBin(x2);
63  if ( ibin2 == nbin+1 ) ibin2 = nbin;
64  x2 = ph->GetXaxis()->GetBinUpEdge(ibin2);
65  ph->GetXaxis()->SetRange(ibin1, ibin2);
66  sigma = ph->GetRMS();
67  mean = ph->GetMean();
68  if ( m_LogLevel >= 2 ) {
69  cout << myname << setw(5) << itry << ": (" << x1 << ", " << x2 << "): "
70  << mean << ", " << sigma << endl;
71  }
72  if ( sigma < 1.001*sigmaOld ) {
73  break;
74  }
75  sigmaOld = sigma;
76  }
77  ph->GetXaxis()->SetRange(ibin1Start, ibin2Start);
78  if ( itry >= 100 ) cout << myname << "WARNING: too many iterations." << endl;
79  // Use input mean and configured sigma.
80  } else if ( m_sigma0 > 0.0 ) {
81  sigma = m_sigma0;
82  // Use histogram mean and RMS.
83  } else {
84  mean = ph->GetMean();
85  }
86  // Protect against sigma == 0.
87  if ( sigma <= 0.0 ) {
88  sigma = ph->GetXaxis()->GetBinWidth(1)/sqrt(12.0);
89  if ( m_LogLevel >= 1 ) cout << myname << "Reset sigma = 0 --> " << sigma << endl;
90  }
91  TF1* pffix = gausTF1(height, mean, sigma, m_fnam);
92  pffix->FixParameter(1, mean);
93  pffix->FixParameter(2, sigma);
94  pffix->SetRange(x1, x2);
95  string fopt = "SR";
96  if ( m_LogLevel <= 1 ) fopt += "Q";
97  int fstat = quietHistFit(ph, pffix, fopt);
98  if ( m_LogLevel >= 1 ) cout << myname << " status " << fstat << endl;
99  if ( fstat == 0 ) {
100  if ( m_LogLevel >= 1 ) cout << myname << "Fit suceeded." << endl;
101  return 0;
102  }
103  // Otherwise we may get a crash when we try to view saved copy of histo:
104  ph->GetListOfFunctions()->Clear();
105  delete pffix;
106  if ( m_LogLevel >= 1 ) cout << myname << "Fit failed." << endl;
107  return 1;
108 }
109 
110 //**********************************************************************
std::string Name
Definition: GausRmsFitter.h:39
GausRmsFitter(Name fnam)
int quietHistFit(TH1 *ph, std::string fname, std::string fopt)
TF1 * gausTF1(double heightIn, double meanIn, double sigmaIn, std::string fname)
Definition: gausTF1.cxx:28
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
int fit(TH1 *ph, double mean0) const
unsigned int Index
Definition: GausRmsFitter.h:40
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:16
QTextStream & endl(QTextStream &s)