ATLAS Offline Software
Fit2D.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 #include "GaudiKernel/MsgStream.h"
8 #include "gsl/gsl_statistics.h"
9 #include "gsl/gsl_fit.h"
10 #include <sstream>
11 
12 namespace Muon
13 {
14 
15 std::string Fit2D::SimpleStats::toString() const
16 {
17  std::ostringstream oss;
18  oss << "Mean=" << fMean
19  << ", Std=" << fStd
20  << ", N=" << n
21  << ", Chi2=" << fChi2;
22 
23  return oss.str();
24 }
25 
26 void Fit2D::LinStats::eval(double fX, double& fY, double& fYerr) const
27 {
28  gsl_fit_linear_est(fX, fIntercept, fSlope, fCov[0][0], fCov[0][1], fCov[1][1], &fY, &fYerr);
29 }
30 
31 std::string Fit2D::LinStats::toString() const
32 {
33  std::ostringstream oss;
34  oss << "Y=" << fIntercept << "+X*" << fSlope
35  << ", N=" << n
36  << ", Cov=[[" << fCov[0][0] << "," << fCov[0][1] << "],["
37  << fCov[1][0] << "," << fCov[1][1] << "]]"
38  << ", Chi2=" << fChi2;
39 
40  return oss.str();
41 }
42 
44 {
45  stats.clear();
46  double *y = new double[points.size()];
47  double *w = new double[points.size()];
48  for (unsigned iPt = 0; iPt < points.size(); iPt++)
49  {
50  // Exclude outliers.
51  if (!points[iPt]->bExclude)
52  {
53  y[stats.n] = points[iPt]->fY;
54  w[stats.n] = points[iPt]->fW;
55  stats.n++;
56  }
57  }
58  if (stats.n == 0) goto done;
59  // Calculate mean and standard deviation.
60  stats.fMean = gsl_stats_wmean(w, 1, y, 1, stats.n);
61  if (stats.n == 1) goto done;
62  stats.fStd = gsl_stats_wsd (w, 1, y, 1, stats.n);
63  for (int i = 0; i < stats.n; i++)
64  {
65  double fDiff = y[i] - stats.fMean;
66  stats.fChi2 += w[i] * fDiff * fDiff;
67  }
68 done:
69  delete [] y;
70  delete [] w;
71 }
72 
73 void Fit2D::fitPoint(PointArray& points, double fExclChi2, bool bDump, SimpleStats& stats)
74 {
75  MsgStream log(Athena::getMessageSvc(),"Fit2D::fitPoint(");
76  double *y = new double[points.size()];
77  double *w = new double[points.size()];
78  for (;;)
79  {
80  stats.clear();
81  for (unsigned iPt = 0; iPt < points.size(); iPt++)
82  {
83  // Exclude outliers.
84  if (!points[iPt]->bExclude)
85  {
86  y[stats.n] = points[iPt]->fY;
87  w[stats.n] = points[iPt]->fW;
88  stats.n++;
89  }
90  }
91  // Calculate mean and standard deviation.
92  if (stats.n == 0) goto done;
93  stats.fMean = gsl_stats_wmean(w, 1, y, 1, stats.n);
94  if (stats.n == 1) goto done;
95  stats.fStd = gsl_stats_wsd(w, 1, y, 1, stats.n);
96  double fMaxChi2 = 0;
97  int i = 0, iPtMax = 0;
98  for (unsigned iPt = 0; iPt < points.size(); iPt++)
99  {
100  if (!points[iPt]->bExclude)
101  {
102  double fDiff = y[i] - stats.fMean;
103  points[iPt]->fChi2 = w[i] * fDiff * fDiff;
104  stats.fChi2 += points[iPt]->fChi2;
105  if (fMaxChi2 < points[iPt]->fChi2)
106  {
107  fMaxChi2 = points[iPt]->fChi2;
108  iPtMax = iPt;
109  }
110  if (bDump && log.level()<=MSG::DEBUG)
111  {
112  log << MSG::DEBUG << "idx=" << points[iPt]->nIdx
113  << ", y=" << y[i]
114  << ", w=" << w[i]
115  << ", chi2=" << points[iPt]->fChi2
116  << endmsg;
117  }
118  i++;
119  }
120  }
121  if (bDump && log.level()<=MSG::DEBUG)
122  log << MSG::DEBUG << stats.toString() << endmsg;
123  if (fMaxChi2 < fExclChi2 || stats.n <= 2)
124  break;
125  points[iPtMax]->bExclude = true;
126  }
127 done:
128  delete [] y;
129  delete [] w;
130 }
131 
132 void Fit2D::fitLine(Fit2D::PointArray& points, double fExclChi2, bool bDump, LinStats& stats)
133 {
134  MsgStream log(Athena::getMessageSvc(),"Fit2D::fitLine(");
135  double *x = new double[points.size()];
136  double *y = new double[points.size()];
137  double *w = new double[points.size()];
138  for (;;)
139  {
140  stats.clear();
141  for (unsigned iPt = 0; iPt < points.size(); iPt++)
142  {
143  if (!points[iPt]->bExclude)
144  {
145  x[stats.n] = points[iPt]->fX;
146  y[stats.n] = points[iPt]->fY;
147  w[stats.n] = points[iPt]->fW;
148  stats.n++;
149  }
150  }
151  if (stats.n < 2) goto done;
152 
153  gsl_fit_wlinear(x, 1,
154  w, 1,
155  y, 1,
156  stats.n,
157  &stats.fIntercept, &stats.fSlope,
158  &stats.fCov[0][0], &stats.fCov[0][1], &stats.fCov[1][1],
159  &stats.fChi2);
160  stats.fCov[1][0] = stats.fCov[0][1];
161  if (bDump && log.level()<=MSG::DEBUG)
162  log << MSG::DEBUG << stats.toString() << endmsg;
163 
164  double fY, fYerr, fMaxChi2 = 0;
165  int i = 0, iPtMax = 0;
166  for (unsigned iPt = 0; iPt < points.size(); iPt++)
167  {
168  if (!points[iPt]->bExclude)
169  {
170  stats.eval(x[i], fY, fYerr);
171  double fDiff = y[i] - fY;
172  points[iPt]->fChi2 = w[i] * fDiff * fDiff;
173  if (fMaxChi2 < points[iPt]->fChi2)
174  {
175  fMaxChi2 = points[iPt]->fChi2;
176  iPtMax = iPt;
177  }
178  if (bDump && log.level()<=MSG::DEBUG)
179  {
180  log << MSG::DEBUG << "idx=" << points[iPt]->nIdx
181  << ", x=" << x[i]
182  << ", y=" << y[i]
183  << ", w=" << w[i]
184  << ", Y=" << fY
185  << ", chi2=" << points[iPt]->fChi2
186  << endmsg;
187  }
188  i++;
189  }
190  }
191  if (fMaxChi2 < fExclChi2 || stats.n <= 2)
192  break;
193  points[iPtMax]->bExclude = true;
194  }
195 done:
196  delete [] x;
197  delete [] y;
198  delete [] w;
199 }
200 
201 }
Muon::Fit2D::fitLine
static void fitLine(PointArray &points, double fExclChi2, bool bDump, LinStats &stats)
Fit a straight line through the given points.
getMessageSvc.h
singleton-like access to IMessageSvc via open function and helper
Fit2D.h
Muon
This class provides conversion from CSC RDO data to CSC Digits.
Definition: TrackSystemController.h:49
trigbs_dumpHLTContentInBS.stats
stats
Definition: trigbs_dumpHLTContentInBS.py:91
x
#define x
Athena::getMessageSvc
IMessageSvc * getMessageSvc(bool quiet=false)
Definition: getMessageSvc.cxx:20
lumiFormat.i
int i
Definition: lumiFormat.py:92
beamspotman.n
n
Definition: beamspotman.py:731
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
Muon::Fit2D::SimpleStats::n
int n
Definition: Fit2D.h:63
Muon::Fit2D::LinStats::eval
void eval(double fX, double &fY, double &fYerr) const
Evaluate a point along the fitted line.
Definition: Fit2D.cxx:26
Muon::Fit2D::fitPoint
static void fitPoint(PointArray &points, double fExclChi2, bool bDump, SimpleStats &stats)
Estimate a new point from the given points.
Muon::Fit2D::SimpleStats::fStd
double fStd
Definition: Fit2D.h:65
Muon::Fit2D::PointArray
std::vector< Point * > PointArray
A vector of points.
Definition: Fit2D.h:59
Muon::Fit2D::LinStats::toString
std::string toString() const
Get a string representation of the fit parameters.
Definition: Fit2D.cxx:31
Muon::Fit2D::SimpleStatistics
static void SimpleStatistics(const PointArray &points, SimpleStats &stats)
Calculate simple statistics for the Y values of a set of points.
Muon::Fit2D::SimpleStats::fChi2
double fChi2
Definition: Fit2D.h:66
y
#define y
Muon::Fit2D::SimpleStats::toString
std::string toString() const
Definition: Fit2D.cxx:15
DEBUG
#define DEBUG
Definition: page_access.h:11
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
Muon::Fit2D::SimpleStats::fMean
double fMean
Definition: Fit2D.h:64
python.IoTestsLib.w
def w
Definition: IoTestsLib.py:200
Muon::Fit2D::SimpleStats
Definition: Fit2D.h:62