AachenTable.cc
Go to the documentation of this file.
1 #include "AachenTable.h"
2 
3 #include <utl/AugerUnits.h>
4 #include <utl/NormalDistribution.h>
5 #include <utl/AugerException.h>
6 
7 #include <TFile.h>
8 #include <TH1D.h>
9 #include <TF1.h>
10 #include <TGraph.h>
11 #include <TCanvas.h>
12 
13 #include <iostream>
14 #include <sstream>
15 #include <algorithm>
16 
17 using namespace tls;
18 using namespace std;
19 using namespace utl;
20 
22 {}
23 
24 AachenTable::AachenTable(const string& fileName)
25 {
26  OpenFile(fileName);
27 }
28 
30 {
31 }
32 
33 void AachenTable::OpenFile(const string& fileName)
34 {
35  TFile* f = TFile::Open(fileName.c_str(),"READ");
36  if (!f) {
37  ostringstream msg;
38  msg << "ERROR: could not open file " << fileName;
39  throw NoDataForModelException(msg.str());
40  }
41 
42  cout << "AachenTankResponse convolving";
43  for (int theta = GetThetaMinDeg(); theta <= GetThetaMaxDeg(); theta+=2) {
44  cout << "." << flush;
45 
46  fTable.push_back(TableItem());
47  TableItem& item = fTable.back();
48 
49  item.theta = theta*degree;
50 
51  //read the histogram
52  ostringstream histoID;
53  histoID << "p" << theta << "_1";
54 
55  TH1D *histResponse = 0;
56  histResponse = static_cast<TH1D*>(f->Get(histoID.str().c_str()));
57  if (!histResponse) {
58  ostringstream msg;
59  msg << "ERROR: Histogram " << histoID.str() << " not found in " << fileName << "\n";
60  throw NoDataForModelException(msg.str());
61  }
62 
63  // Rough fix to reduce the failure rate of MINOS,
64  // which gets confused by zero probabilities in rare cases
65  double firstMean = histResponse->GetMean();
66  double firstSigma = histResponse->GetRMS();
67  for (int ix=1;ix<histResponse->GetNbinsX()+1;++ix)
68  {
69  double y = histResponse->GetBinContent(ix);
70  if (y==0) {
71  const double x = histResponse->GetXaxis()->GetBinCenter(ix);
72  histResponse->SetBinContent(ix,NormalPDF(x,firstMean,firstSigma));
73  }
74  }
75 
76  // fill the first TPF
77  item.GetTPF(1).SetScale(
78  histResponse->GetXaxis()->GetXmin()+histResponse->GetXaxis()->GetBinWidth(1)/2,
79  histResponse->GetXaxis()->GetBinWidth(1));
80  for (int ix=1;ix<histResponse->GetNbinsX()+1;++ix)
81  {
82  const double& y = histResponse->GetBinContent(ix);
83  item.GetTPF(1).PushBack(y);
84  }
85  item.GetTPF(1).Normalise();
86  item.GetMean(1) = item.GetTPF(1).Moment(1);
87 
88  // auto-convolution
89  TH1D* h0 = histResponse;
90  const int n = h0->GetNbinsX();
91  double* conv = new double[n];
92  double* last = new double[n];
93  for (int i=0;i<n;++i) last[i] = h0->GetBinContent(i+1);
94 
95  for (int nmu=2;nmu<GetTableLimit();++nmu) {
96  for (int i=0;i<n;++i) {
97  double psum = 0;
98  for (int ii=0;ii<=i;++ii) {
99  const double p1 = last[ii];
100  const double p2 = h0->GetBinContent(i-ii+1);
101  psum += p1*p2;
102  }
103  conv[i] = psum;
104  }
105 
106  // fill the next TPF
107  item.GetTPF(nmu).SetScale(
108  histResponse->GetXaxis()->GetXmin()+histResponse->GetXaxis()->GetBinWidth(1)/2,
109  histResponse->GetXaxis()->GetBinWidth(1));
110  for (int i = 0;i<n;++i)
111  {
112  const double& y = conv[i];
113  item.GetTPF(nmu).PushBack(y);
114  }
115  item.GetTPF(nmu).Normalise();
116  item.GetMean(nmu) = item.GetTPF(nmu).Median();
117 
118  for (int i=0;i<n;++i) last[i] = conv[i];
119  }
120 
121  delete histResponse;
122 
123  // calculate extrapolation parameters
124  TGraph gMean;
125  TGraph gSigma;
126  for (int nmu=1;nmu<GetTableLimit();++nmu) {
127  const double mean = item.GetTPF(nmu).Moment(1);
128  /* use truncated variance to get better control over the long tails */
129  const double truncVar = item.GetTPF(nmu).Variance(item.GetTPF(nmu).Quantile(0.05),item.GetTPF(nmu).Quantile(0.95));
130  gMean.SetPoint(gMean.GetN(),nmu,mean);
131  gSigma.SetPoint(gSigma.GetN(),nmu,sqrt(truncVar));
132  }
133 
134  TF1 fitMean("fitMean","[0]*x");
135  gMean.Fit(&fitMean,"0Q");
136  item.parMean = fitMean.GetParameter(0);
137 
138  TF1 fitSigma("fitSigma","sqrt([0]+[1]*x)");
139  gSigma.Fit(&fitSigma,"0Q");
140  item.parSigma[0] = fitSigma.GetParameter(0);
141  item.parSigma[1] = fitSigma.GetParameter(1);
142  }
143  cout << endl;
144 
145  delete f;
146 }
147 
148 double AachenTable::PDF(double signal, double theta, int nmu) const
149 {
150  if (theta <= fTable[0].theta) {
151  return fTable[0].GetTPF(nmu).Density(signal);
152  }
153 
154  if (theta >= fTable.back().theta) {
155  return fTable.back().GetTPF(nmu).Density(signal);
156  }
157 
158  const InternalTable::const_iterator itu = UpperLimit(theta);
159  const TableItem& upper = *itu;
160  const TableItem& lower = *(itu-1);
161 
162  const double m = (theta - lower.theta)/(upper.theta-lower.theta);
163 
164  const double delta_mean = signal - (lower.GetMean(nmu) + m*(upper.GetMean(nmu)-lower.GetMean(nmu)));
165 
166  const double p0 = lower.GetTPF(nmu).Density(delta_mean + lower.GetMean(nmu));
167  const double p1 = upper.GetTPF(nmu).Density(delta_mean + upper.GetMean(nmu));
168 
169  return p0 + m*(p1-p0);
170 }
171 
172 double AachenTable::CDF(double signalmin, double theta, int nmu) const
173 {
174  if (theta <= fTable[0].theta)
175  return 1.0 - fTable[0].GetTPF(nmu).Integral(signalmin);
176 
177  if (theta >= fTable.back().theta)
178  return 1.0 - fTable.back().GetTPF(nmu).Integral(signalmin);
179 
180  const InternalTable::const_iterator itu = UpperLimit(theta);
181  const TableItem& upper = *itu;
182  const TableItem& lower = *(itu-1);
183 
184  const double m = (theta - lower.theta)/(upper.theta-lower.theta);
185 
186  const double p0 = 1.0 - lower.GetTPF(nmu).Integral(signalmin);
187  const double p1 = 1.0 - upper.GetTPF(nmu).Integral(signalmin);
188 
189  return p0 + m*(p1-p0);
190 }
191 
192 double AachenTable::Moment(double theta, int nmu, int order) const {
193  if (theta <= fTable[0].theta)
194  return fTable[0].GetTPF(nmu).Moment((unsigned short)order);
195 
196  if (theta >= fTable.back().theta)
197  return fTable.back().GetTPF(nmu).Moment((unsigned short)order);
198 
199  const InternalTable::const_iterator itu = UpperLimit(theta);
200  const TableItem& upper = *itu;
201  const TableItem& lower = *(itu-1);
202 
203  const double m = (theta - lower.theta)/(upper.theta-lower.theta);
204 
205  const double m0 = lower.GetTPF(nmu).Moment((unsigned short)order);
206  const double m1 = upper.GetTPF(nmu).Moment((unsigned short)order);
207 
208  return m0 + m*(m1-m0);
209 }
210 
211 double AachenTable::GetFittedMean(double theta, int nmu) const {
212  if (theta <= fTable[0].theta)
213  return fTable[0].GetFittedMean(nmu);
214 
215  if (theta >= fTable.back().theta)
216  return fTable.back().GetFittedMean(nmu);
217 
218  const InternalTable::const_iterator itu = UpperLimit(theta);
219  const TableItem& upper = *itu;
220  const TableItem& lower = *(itu-1);
221 
222  const double m = (theta - lower.theta)/(upper.theta-lower.theta);
223 
224  const double m0 = lower.GetFittedMean(nmu);
225  const double m1 = upper.GetFittedMean(nmu);
226 
227  return m0 + m*(m1-m0);
228 }
229 
230 double AachenTable::GetFittedSigma(double theta, int nmu) const {
231  if (theta <= fTable[0].theta)
232  return fTable[0].GetFittedSigma(nmu);
233 
234  if (theta >= fTable.back().theta)
235  return fTable.back().GetFittedSigma(nmu);
236 
237  const InternalTable::const_iterator itu = UpperLimit(theta);
238  const TableItem& upper = *itu;
239  const TableItem& lower = *(itu-1);
240 
241  const double m = (theta - lower.theta)/(upper.theta-lower.theta);
242 
243  const double m0 = lower.GetFittedSigma(nmu);
244  const double m1 = upper.GetFittedSigma(nmu);
245 
246  return m0 + m*(m1-m0);
247 }
double Median() const
Definition: TabulatedPDF.h:33
const double degree
tls::TabulatedPDF & GetTPF(int nmu)
Definition: AachenTable.h:56
double Moment(unsigned short order, double xmin=-DBL_MAX, double xmax=DBL_MAX) const
double GetFittedSigma(double theta, int nmu) const
Definition: AachenTable.cc:230
double NormalPDF(const double x)
Exception to use in a atmosphere model cannot find data it needs.
double Integral(double xmin=-DBL_MAX, double xmax=DBL_MAX) const
double & GetMean(int nmu)
Definition: AachenTable.h:61
double GetFittedMean(int nmu) const
Definition: AachenTable.h:66
void PushBack(double y)
Definition: TabulatedPDF.cc:55
double GetFittedMean(double theta, int nmu) const
Definition: AachenTable.cc:211
double PDF(double signal, double theta, int nmu) const
Definition: AachenTable.cc:148
double Variance(double xmin=-DBL_MAX, double xmax=DBL_MAX) const
void OpenFile(const std::string &fileName)
Definition: AachenTable.cc:33
void SetScale(double xmin, double xstep)
Definition: TabulatedPDF.h:20
constexpr double m
Definition: AugerUnits.h:121
double GetFittedSigma(int nmu) const
Definition: AachenTable.h:68
double CDF(double signalmin, double theta, int nmu) const
Definition: AachenTable.cc:172
double Moment(double theta, int nmu, int order) const
Definition: AachenTable.cc:192
double Quantile(double psum) const
double Density(double x) const

, generated on Tue Sep 26 2023.