ATLAS Offline Software
Loading...
Searching...
No Matches
APWeightHist.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
5#define APReweight_cxx
9#include <cmath>
10#include "TF1.h"
11#include "TGraphErrors.h"
12#include "TGraphAsymmErrors.h"
13
15
16using namespace std;
17
18APWeightHist::APWeightHist(const char *name, const char *title, const int n_bins, const float x_min, const float x_max)
19 : TH1D(name, title, n_bins, x_min, x_max)
20 //m_prec(0)
21{
22 m_graph_stat = new TGraphAsymmErrors();
23 m_graph_stat->GetXaxis()->SetTitle(GetXaxis()->GetTitle());
24 m_graph_stat->GetYaxis()->SetTitle(GetYaxis()->GetTitle());
25 m_graph_syst = new TGraphErrors();
26 m_graph_syst->GetXaxis()->SetTitle(GetXaxis()->GetTitle());
27 m_graph_syst->GetYaxis()->SetTitle(GetYaxis()->GetTitle());
29 Sumw2();
30 m_SumSys2 = vector< double >(n_bins, 0.);
32}
33
35 : m_graph_stat(0),
37 //m_prec(0)
38{
40}
41
45
46int APWeightHist::Fill(const double value, APWeightEntry* weight) {
47 // if (fBuffer) return BufferFill(value,w);
48 double w = weight->GetExpectancy();
49 int bin = fXaxis.FindBin(value);
50 fEntries++;
51 AddBinContent(bin, w);
52 if (fSumw2.fN) fSumw2.fArray[bin] += w * w;
53 if (bin == 0 || bin > fXaxis.GetNbins()) {
54 if (!GetStatOverflowsBehaviour()) return -1;
55 }
56 Double_t z = (w > 0 ? w : -w);
57 fTsumw += z;
58 fTsumw2 += z*z;
59 fTsumwx += z*value;
60 fTsumwx2 += z * value*value;
61 (m_binned_weights[bin - 1]).push_back(weight);
62 fSumw2.fArray[bin] += weight->GetVariance() + z*z;
63 m_SumSys2[bin - 1] += weight->GetSysUncert2();
64 return bin;
65}
66
67void APWeightHist::ComputeGraph(const int prec) {
68 for (int i = 0, I = m_graph_stat->GetN(); i < I; ++i) m_graph_stat->RemovePoint(i);
69 for (int i = 0, I = m_graph_syst->GetN(); i < I; ++i) m_graph_syst->RemovePoint(i);
70 vector< TH1D* > original_dists = vector< TH1D* >(fXaxis.GetNbins());
71 m_bin_dists = vector< TH1D* >(fXaxis.GetNbins());
72 int point_count = 0;
73 for (int j = 0; j < fXaxis.GetNbins(); ++j) {
74 //Create Poisson distributions for original histogram.
75 double unweighted_content = (double) (m_binned_weights[j]).size();
76 double sig_low_o = (max((double) 0.0, (unweighted_content - 5 * sqrt(unweighted_content))));
77 double sig_high_o = (unweighted_content + 5 * sqrt(unweighted_content));
78 double step = (sig_high_o - sig_low_o) * 1e-3;
79
80 original_dists[j] = new TH1D("", "", 1000, sig_low_o, sig_high_o);
81
82 int bin_no = 1;
83 double curr_fact = ln_factorialApp((m_binned_weights[j]).size());
84 for (double lambda = sig_low_o; lambda < sig_high_o; lambda += step) {
85 double value = exp(-lambda + unweighted_content * log(lambda) - curr_fact);
86 if (value != value) value = 0.;
87 (original_dists[j])->SetBinContent(bin_no, value);
88 ++bin_no;
89 }
90 (original_dists[j])->Scale(1. / (original_dists[j])->GetSum());
91 const double old_mode = (original_dists[j])->GetBinCenter((original_dists[j])->GetMaximumBin());
92 const double inv_old_mode = 1. / old_mode;
93
94 //Create different final sum of weights for this bin
95 vector< double > bin_sumw(prec, 0.);
96 double max_value = 1.e-100;
97 double min_value = 1.e100;
98
99 for (vector<double>::iterator it_hist = bin_sumw.begin(), it_histE = bin_sumw.end(); it_hist != it_histE; ++it_hist) {
100 for (vector<APWeightEntry*>::iterator it_func = (m_binned_weights[j]).begin(), it_funcE = (m_binned_weights[j]).end(); it_func != it_funcE; ++it_func) {
101 *it_hist += (*it_func)->GetRandom();
102 }
103 double cur_val = *it_hist;
104 if (cur_val < min_value) {
105 min_value = cur_val;
106 } else if (cur_val > max_value) {
107 max_value = cur_val;
108 }
109 }
110
111 //Create final distribution for this bin
112 TH1D* scaled_hist_l = (TH1D*) (original_dists[j])->Clone("");
113 TH1D* scaled_hist_h = (TH1D*) (original_dists[j])->Clone("");
114 double scale = min_value * inv_old_mode;
115 scaled_hist_l->GetXaxis()->SetLimits(scale * sig_low_o, scale * sig_high_o);
116 scale = max_value * inv_old_mode;
117 scaled_hist_h->GetXaxis()->SetLimits(scale * sig_low_o, scale * sig_high_o);
118
119 double quant[1];
120 double prob[1] = {0.001};
121
122 scaled_hist_l->GetQuantiles(1, quant, prob);
123 double sig_low = quant[0];
124 prob[0] = 0.999;
125 scaled_hist_h->GetQuantiles(1, quant, prob);
126 double sig_high = quant[0];
127
128 m_bin_dists[j] = new TH1D("", "", 1000, sig_low, sig_high);
129
130 //fill final distribution for this bin with scaled/weighted Poisson distributions
131 if (unweighted_content > 0.) {
132 for (int k = 0; k < prec; ++k) {
133 double new_val = bin_sumw[k];
134 TH1D* scaled_hist = (TH1D*) (original_dists[j])->Clone("");
135 double temp_scale = new_val * inv_old_mode;
136 scaled_hist->GetXaxis()->SetLimits(temp_scale * sig_low_o, temp_scale * sig_high_o);
137 for (int l = 1; l < 1001; ++l) {
138 (m_bin_dists[j])->AddBinContent(l, scaled_hist->GetBinContent(scaled_hist->FindBin((m_bin_dists[j])->GetBinCenter(l))));
139 }
140 delete scaled_hist;
141 }
142 double local_value = sig_low + (m_bin_dists[j])->GetMaximumBin() * ((sig_high - sig_low) * 1e-3);
143 m_graph_stat->SetPoint(point_count, (GetXaxis()->GetXmin() + j * GetBinWidth(j + 1) + GetBinWidth(j + 1) / 2), local_value);
144 m_graph_syst->SetPoint(point_count, (GetXaxis()->GetXmin() + j * GetBinWidth(j + 1) + GetBinWidth(j + 1) / 2), local_value);
145 double quantile[ 2 ];
146 double conf[ 2 ] = {0.1585, 0.8415};
147 (m_bin_dists[j])->GetQuantiles(2, quantile, conf);
148 m_graph_stat->SetPointError(point_count, GetBinWidth(j + 1) / 2, GetBinWidth(j + 1) / 2, local_value - quantile[0], quantile[1] - local_value);
149 m_graph_syst->SetPointError(point_count, GetBinWidth(j + 1) / 2, local_value * (sqrt(m_SumSys2[j]) / GetBinContent(j + 1)));
150 ++point_count;
151 }
152 }
153 m_computed_entries = fEntries;
154}
155
156TGraphAsymmErrors* APWeightHist::GetGraphStatUncert(bool autocompute) {
157 if (autocompute && fEntries > m_computed_entries) ComputeGraph();
158 return m_graph_stat;
159}
160
161TGraphErrors* APWeightHist::GetGraphSystUncert(bool simple, bool autocompute) {
162 if (simple) {
163 for (int i = 0, I = m_graph_syst->GetN(); i < I; ++i) m_graph_syst->RemovePoint(i);
164 int point_count = 0;
165 for (int j = 0; j < fXaxis.GetNbins(); ++j) {
166 if ((m_binned_weights[j]).size() > 0) {
167 m_graph_syst->SetPoint(point_count, (GetXaxis()->GetXmin() + j * GetBinWidth(j + 1) + GetBinWidth(j + 1) / 2), GetBinContent(j + 1));
168 m_graph_syst->SetPointError(point_count, GetBinWidth(j + 1) / 2, sqrt(m_SumSys2[j]));
169 ++point_count;
170 }
171 }
172 return m_graph_syst;
173 }
174 if (autocompute && fEntries > m_computed_entries) ComputeGraph();
175 return m_graph_syst;
176}
177
178TH1D* APWeightHist::GetBinPDF(unsigned int bin, bool autocompute) {
179 if (autocompute && fEntries > m_computed_entries) ComputeGraph();
180 return m_bin_dists[bin - 1];
181}
ClassImp(APWeightHist) using namespace std
static int quant(double min, double max, unsigned nSteps, double val)
#define I(x, y, z)
Definition MD5.cxx:116
double ln_factorialApp(unsigned int value)
Logarithmic factorial (approximative).
Definition MathTools.cxx:18
#define z
#define max(a, b)
Definition cfImp.cxx:41
Class to store a single weight entry (one bin).
Extended histogramming class.
void ComputeGraph(const int prec=250)
Computes the resulting graph from all added ntuples and calculates the uncertainties for all bins.
int Fill(const double value, APWeightEntry *weight)
< Overloads TH1D's Fill method.
APWeightHist()
Default constructor.
std::vector< std::vector< APWeightEntry * > > m_binned_weights
Holds all filled weights weights as pointers.
TGraphAsymmErrors * m_graph_stat
Holds the histogram with statistical uncertainties.
TH1D * GetBinPDF(unsigned int bin, bool autocompute=true)
std::vector< double > m_SumSys2
Holds the variances of systematic uncertainties for the individual bins.
~APWeightHist()
Default destructor.
std::vector< TH1D * > m_bin_dists
Holds the PDFs for the individual bins.
TGraphErrors * m_graph_syst
Holds the histogram with systematic uncertainties.
TGraphAsymmErrors * GetGraphStatUncert(bool autocompute=true)
Extracts the histogram with statistical uncertainties.
TGraphErrors * GetGraphSystUncert(bool simple=true, bool autocompute=true)
Extracts the histogram with systematic uncertainties.
double m_computed_entries
Flag to store information about the status of the computation.
void Scale(TH1 *h, double d=1)
STL namespace.