ATLAS Offline Software
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 
16 namespace 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
MuonCalib::VariableBinwidthHistogramBin::SetContent
void SetContent(unsigned int n)
set content
Definition: VariableBinwidthHistogramBin.h:56
MuonCalib::VariableBinwidthHistogramBin::MoveRight
void MoveRight(double new_right)
move right bin boarder
Definition: VariableBinwidthHistogramBin.h:80
max
#define max(a, b)
Definition: cfImp.cxx:41
getMessageSvc.h
singleton-like access to IMessageSvc via open function and helper
MuonCalib::VBHBinPtrSrt
Definition: VariableBinwidthHistogramBin.h:135
MuonCalib::VariableBinwidthHistogram::m_sort_bins
std::vector< VBHBinPtrSrt > m_sort_bins
bins sorted by content
Definition: VariableBinwidthHistogram.h:108
plotmaker.hist
hist
Definition: plotmaker.py:148
MuonCalib::VariableBinwidthHistogram::DiffDensityGraph
TGraph * DiffDensityGraph() const
Plot graph with differential density.
Definition: VariableBinwidthHistogram.cxx:151
bin
Definition: BinsDiffFromStripMedian.h:43
gr
#define gr
MuonCalib::VariableBinwidthHistogram::DenistyGraph
TGraph * DenistyGraph() const
create density graph - density vs bin center
Definition: VariableBinwidthHistogram.cxx:113
x
#define x
MuonCalib::VariableBinwidthHistogram::m_bins
std::vector< VariableBinwidthHistogramBin * > m_bins
vector containing histogram bins
Definition: VariableBinwidthHistogram.h:105
VariableBinwidthHistogram.h
Athena::getMessageSvc
IMessageSvc * getMessageSvc(bool quiet=false)
Definition: getMessageSvc.cxx:20
MuonCalib::VariableBinwidthHistogram::m_error
bool m_error
error flag
Definition: VariableBinwidthHistogram.h:117
MuonCalib::VariableBinwidthHistogram::DiffBinwidthGraph
TGraph * DiffBinwidthGraph() const
Plot graph with differential binwidth.
Definition: VariableBinwidthHistogram.cxx:166
MuonCalib::VariableBinwidthHistogram::m_max_bin_width
double m_max_bin_width
maximum bin width
Definition: VariableBinwidthHistogram.h:114
lumiFormat.i
int i
Definition: lumiFormat.py:92
MuonCalib::VariableBinwidthHistogram::BinContentGraph
TGraph * BinContentGraph() const
Plot bin content graph - bin content vs bin center.
Definition: VariableBinwidthHistogram.cxx:141
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
MuonCalib::VariableBinwidthHistogram::Smooth
bool Smooth(double width)
Removes steps that origin in a binning effekt.
Definition: VariableBinwidthHistogram.cxx:87
MuonCalib::VariableBinwidthHistogram::sign
double sign(double val) const
Definition: VariableBinwidthHistogram.h:122
MuonCalib
CscCalcPed - algorithm that finds the Cathode Strip Chamber pedestals from an RDO.
Definition: CscCalcPed.cxx:22
MuonCalib::VariableBinwidthHistogramBin::Entries
unsigned int Entries() const
Get number of entries in the bin.
Definition: VariableBinwidthHistogramBin.h:117
MuonCalib::VariableBinwidthHistogram::m_binc
unsigned int m_binc
number of entries per bin
Definition: VariableBinwidthHistogram.h:111
MuonCalib::VariableBinwidthHistogram::m_sorted
bool m_sorted
Definition: VariableBinwidthHistogram.h:119
MuonCalib::VariableBinwidthHistogram::Initialize
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.
Definition: VariableBinwidthHistogram.cxx:22
MuonCalib::VariableBinwidthHistogramBin
Definition: VariableBinwidthHistogramBin.h:22
y
#define y
TH1F
Definition: rootspy.cxx:320
Base_Fragment.width
width
Definition: Sherpa_i/share/common/Base_Fragment.py:59
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
MuonCalib::VariableBinwidthHistogram::BinWidthGraph
TGraph * BinWidthGraph() const
Plot binwidth graph - binwidth versus bin center.
Definition: VariableBinwidthHistogram.cxx:127
MuonCalib::VariableBinwidthHistogramBin::Right
double Right() const
Get right (upper) bin border.
Definition: VariableBinwidthHistogramBin.h:114