ATLAS Offline Software
Loading...
Searching...
No Matches
VariableBinwidthHistogram.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
7#include <TString.h> // for Form
8
9#include <cmath>
10
12#include "GaudiKernel/MsgStream.h"
13#include "TGraph.h"
14#include "TH1.h"
15
16namespace MuonCalib {
17
19 // Initialize(const &TH1 hist, double binc_rate, double max_bin_width) //
21
22 bool VariableBinwidthHistogram::Initialize(TH1F *hist, double binc_rate, double max_bin_width, double min_x, double max_x) {
23 if (binc_rate < 1.0)
24 throw std::runtime_error(
25 Form("File: %s, Line: %d\nVariableBinwidthHistogram::Initialize - binc_rate must be greater than 1!", __FILE__, __LINE__));
26
27 // get maximum, firest bin and last bin
28 double max;
29 int first_bin(hist->FindBin(min_x)), last_bin(hist->FindBin(max_x));
30 bool max_valid(true);
31 if (first_bin == 0)
32 first_bin = 1;
33 else
34 max_valid = false;
35 if (last_bin > hist->GetNbinsX())
36 last_bin = hist->GetNbinsX();
37 else
38 max_valid = false;
39 if (max_valid)
40 max = hist->GetMaximum();
41 else {
42 max = -9e9;
43 for (int i = first_bin; i <= last_bin; i++) {
44 if (max < hist->GetBinContent(i)) max = hist->GetBinContent(i);
45 }
46 }
47 // get number of entries per bin
48 m_binc = static_cast<unsigned int>(ceil(max * binc_rate));
49 m_max_bin_width = max_bin_width;
50 // create first bin
51 m_bins.clear();
52 m_bins.push_back(new VariableBinwidthHistogramBin(hist->GetBinLowEdge(first_bin) + 0.5 * max_bin_width, max_bin_width, 0));
53 VariableBinwidthHistogramBin *current_bin(m_bins[0]);
54 // loop on histogram bins
55 for (int i = first_bin; i <= last_bin; i++) {
56 // maximum binwidth reached
57 if (hist->GetBinCenter(i) > current_bin->Right()) {
58 m_bins.push_back(new VariableBinwidthHistogramBin(current_bin->Right() + 0.5 * m_max_bin_width, max_bin_width, 0));
59 current_bin = m_bins[m_bins.size() - 1];
60 }
61 // will the bin be full
62 if (current_bin->Entries() + static_cast<unsigned int>(hist->GetBinContent(i)) > m_binc) {
63 // this will be filled in the next bin
64 unsigned int overflow = current_bin->Entries() + static_cast<unsigned int>(hist->GetBinContent(i)) - m_binc;
65 // the current bin ends here.
66 current_bin->MoveRight(hist->GetBinLowEdge(i));
67 current_bin->SetContent(m_binc);
68 // create new bin
69 m_bins.push_back(new VariableBinwidthHistogramBin(current_bin->Right() + 0.5 * m_max_bin_width, m_max_bin_width, overflow));
70 current_bin = m_bins[m_bins.size() - 1];
71 continue;
72 }
73 // add to content of current bin
74 (*current_bin) += static_cast<unsigned int>(hist->GetBinContent(i));
75 }
76 // sort bins by content
77 for (auto & bin : m_bins) { m_sort_bins.push_back(VBHBinPtrSrt(bin)); }
78 m_sorted = false;
79 m_error = false;
80 return true;
81 }
82
84 // Smooth(double width) //
86
88 // needs at last 3 bins to smooth
89 if (m_bins.size() < 3) {
90 MsgStream log(Athena::getMessageSvc(), "VariableBinwidthHistogram");
91 log << MSG::WARNING << "Smooth() - VBH has less than 3 bins" << endmsg;
92 return false;
93 }
94 for (unsigned int i = 0; i < m_bins.size() - 3; i++) {
95 Double_t sl1 = m_bins[i + 1]->Width() - m_bins[i]->Width();
96 Double_t sl2 = m_bins[i + 2]->Width() - m_bins[i + 1]->Width();
97 // slopes must be oposit sign
98 if (sign(sl1) == sign(sl2)) continue;
99 // prevents numerical effects
100 if (std::abs(sl1) < width / 2 || std::abs(sl2) < width / 2) continue;
101 // move bin boarder
102 m_bins[i]->MoveRight(m_bins[i]->Right() - width / 2 * sign(sl2));
103 m_bins[i + 1]->MoveLeft(m_bins[i]->Right() - width / 2 * sign(sl2));
104 }
105 m_sorted = false;
106 return true;
107 }
108
110 // DenistyGraph() //
112
114 Double_t *x = new Double_t[m_bins.size()], *y = new Double_t[m_bins.size()];
115 for (unsigned int i = 0; i < m_bins.size(); i++) {
116 x[i] = m_bins[i]->Center();
117 y[i] = m_bins[i]->Density();
118 }
119 TGraph *gr = new TGraph(m_bins.size(), x, y);
120 return gr;
121 }
122
124 // BinWidthGraph() const //
126
128 Double_t *x = new Double_t[m_bins.size()], *y = new Double_t[m_bins.size()];
129 for (unsigned int i = 0; i < m_bins.size(); i++) {
130 x[i] = m_bins[i]->Center();
131 y[i] = m_bins[i]->Width();
132 }
133 TGraph *gr = new TGraph(m_bins.size(), x, y);
134 return gr;
135 }
136
138 // BinContentGraph() const //
140
142 Double_t *x = new Double_t[m_bins.size()], *y = new Double_t[m_bins.size()];
143 for (unsigned int i = 0; i < m_bins.size(); i++) {
144 x[i] = m_bins[i]->Center();
145 y[i] = m_bins[i]->Entries();
146 }
147 TGraph *gr = new TGraph(m_bins.size(), x, y);
148 return gr;
149 }
150
152 if (m_bins.size() < 2) {
153 MsgStream log(Athena::getMessageSvc(), "VariableBinwidthHistogram");
154 log << MSG::WARNING << "DiffDensityGraph() - Need at alst 2 bins for differential density!" << endmsg;
155 return new TGraph();
156 }
157 Double_t *x = new Double_t[m_bins.size() - 1], *y = new Double_t[m_bins.size() - 1];
158 for (unsigned int i = 0; i < m_bins.size() - 1; i++) {
159 x[i] = m_bins[i]->Center();
160 y[i] = m_bins[i + 1]->Density() - m_bins[i]->Density();
161 }
162 TGraph *gr = new TGraph(m_bins.size() - 1, x, y);
163 return gr;
164 }
165
167 if (m_bins.size() < 2) {
168 MsgStream log(Athena::getMessageSvc(), "VariableBinwidthHistogram");
169 log << MSG::WARNING << "DiffBinwidthGraph() - Need at alst 2 bins for differential density!" << endmsg;
170 return new TGraph();
171 }
172 Double_t *x = new Double_t[m_bins.size() - 1], *y = new Double_t[m_bins.size() - 1];
173 for (unsigned int i = 0; i < m_bins.size() - 1; i++) {
174 x[i] = m_bins[i]->Center();
175 y[i] = m_bins[i + 1]->Width() - m_bins[i]->Width();
176 }
177 TGraph *gr = new TGraph(m_bins.size() - 1, x, y);
178 return gr;
179 }
180
181} // namespace MuonCalib
#define endmsg
#define gr
const double width
#define y
#define x
#define max(a, b)
Definition cfImp.cxx:41
A pointer to a VariableBinwidthHistogramBin which supports sorting.
A bin of a VariableBinwidthHistogram.
unsigned int Entries() const
Get number of entries in the bin.
double Right() const
Get right (upper) bin border.
void MoveRight(double new_right)
move right bin boarder
std::vector< VariableBinwidthHistogramBin * > m_bins
vector containing histogram bins
std::vector< VBHBinPtrSrt > m_sort_bins
bins sorted by content
bool Smooth(double width)
Removes steps that origin in a binning effekt.
TGraph * DiffDensityGraph() const
Plot graph with differential density.
TGraph * DiffBinwidthGraph() const
Plot graph with differential binwidth.
TGraph * BinContentGraph() const
Plot bin content graph - bin content vs bin center.
bool Initialize(TH1F *hist, double binc_r, double max_bin_width, double min_x=-9e9, double max_x=9e9)
Initialize with new input histogram Returns on error false.
TGraph * DenistyGraph() const
create density graph - density vs bin center
TGraph * BinWidthGraph() const
Plot binwidth graph - binwidth versus bin center.
unsigned int m_binc
number of entries per bin
singleton-like access to IMessageSvc via open function and helper
IMessageSvc * getMessageSvc(bool quiet=false)
CscCalcPed - algorithm that finds the Cathode Strip Chamber pedestals from an RDO.