Binning.cxx
Go to the documentation of this file.
1 #include "CAFAna/Core/Binning.h"
2 
3 #include "CAFAna/Core/DepMan.h"
4 
5 #include "TDirectory.h"
6 #include "TH1.h"
7 #include "TObjString.h"
8 #include "TVectorD.h"
9 
10 namespace ana
11 {
12  //----------------------------------------------------------------------
14  : fNBins(-1) // need a non-zero value so we count as constructed
15  {
16  // Don't want children copying from us at this point. Only when we're
17  // "fully constructed". So I inserted explicit calls in Simple() and
18  // Custom() instead.
19 
20  // DepMan<Binning>::Instance().RegisterConstruction(this);
21  }
22 
23  //----------------------------------------------------------------------
25  {
27  }
28 
29  //----------------------------------------------------------------------
31  {
32  if(&b == this) return;
33 
34  if(b.fNBins){
35  fEdges = b.fEdges;
36  fLabels = b.fLabels;
37  fNBins = b.fNBins;
38  fMin = b.fMin;
39  fMax = b.fMax;
40  fIsSimple = b.fIsSimple;
41 
43  }
44  else{
45  fNBins = 0;
46  fMin = 0;
47  fMax = 0;
48  fIsSimple = false;
49 
50  // If we are copying from a Binning with zero bins, that is probably
51  // because it is all zero because it hasn't been statically constructed
52  // yet. Register our interest of getting constructed in turn once it is.
54  }
55  }
56 
57  //----------------------------------------------------------------------
59  {
60  if(&b == this) return *this;
61 
62  if(b.fNBins){
63  fEdges = b.fEdges;
64  fLabels = b.fLabels;
65  fNBins = b.fNBins;
66  fMin = b.fMin;
67  fMax = b.fMax;
68  fIsSimple = b.fIsSimple;
69 
71  }
72  else{
73  fNBins = 0;
74  fMin = 0;
75  fMax = 0;
76  fIsSimple = false;
77 
78  // If we are copying from a Binning with zero bins, that is probably
79  // because it is all zero because it hasn't been statically constructed
80  // yet. Register our interest of getting constructed in turn once it is.
82  }
83 
84  return *this;
85  }
86 
87  //----------------------------------------------------------------------
88  Binning Binning::SimpleHelper(int n, double lo, double hi,
89  const std::vector<std::string>& labels)
90  {
91  assert(labels.empty() || int(labels.size()) == n);
92 
93  Binning bins;
94  bins.fNBins = n;
95  bins.fMin = lo;
96  bins.fMax = hi;
97  bins.fEdges.resize(n+1);
98  for (int i = 0; i <= n; i++)
99  bins.fEdges[i] = lo + i*(hi-lo)/n;
100  bins.fLabels = labels;
101  bins.fIsSimple = true;
102 
103  return bins;
104  }
105 
106  //----------------------------------------------------------------------
107  Binning Binning::Simple(int n, double lo, double hi,
108  const std::vector<std::string>& labels)
109  {
110  Binning bins = SimpleHelper(n, lo, hi, labels);
111 
113 
114  return bins;
115  }
116 
117  //----------------------------------------------------------------------
118  Binning Binning::LogUniform(int n, double lo, double hi)
119  {
120  std::vector<double> edges(n+1);
121  const double logSpacing = exp( (log(hi) - log(lo)) / n );
122  for (int i = 0; i <= n; ++i) {
123  if (i == 0) edges[i] = lo;
124  else edges[i] = logSpacing*edges[i-1];
125  }
126  return Custom(edges);
127  }
128 
129  //----------------------------------------------------------------------
130  Binning Binning::CustomHelper(const std::vector<double>& edges)
131  {
132  assert(edges.size() > 1);
133 
134  Binning bins;
135  bins.fEdges = edges;
136  bins.fNBins = edges.size()-1;
137  bins.fMin = edges.front();
138  bins.fMax = edges.back();
139  bins.fIsSimple = false;
140 
141  return bins;
142  }
143 
144  //----------------------------------------------------------------------
145  Binning Binning::Custom(const std::vector<double>& edges)
146  {
147  Binning bins = CustomHelper(edges);
148 
150 
151  return bins;
152  }
153 
154  //----------------------------------------------------------------------
155  int Binning::FindBin(double x) const
156  {
157  // Treat anything outside [fMin, fMax) as Underflow / Overflow
158  if (x < fMin) return 0; // Underflow
159  if (x >= fMax) return fEdges.size(); // Overflow
160 
161  // Follow ROOT convention, first bin of histogram is bin 1
162 
163  if(IsSimple()) return fNBins * (x - fMin) / (fMax - fMin) +1;
164 
165  int bin =
166  std::lower_bound(fEdges.begin(), fEdges.end(), x) - fEdges.begin();
167  if (x == fEdges[bin]) bin++;
168  assert(bin >= 0 && bin < (int)fEdges.size());
169  return bin;
170  }
171 
172  //----------------------------------------------------------------------
174  {
175  Binning bins;
176 
177  // Evenly spaced binning
178  if(!ax->GetXbins()->GetArray()){
179  bins = SimpleHelper(ax->GetNbins(), ax->GetXmin(), ax->GetXmax());
180  }
181  else{
182  std::vector<double> edges(ax->GetNbins()+1);
183  ax->GetLowEdge(&edges.front());
184  edges[ax->GetNbins()] = ax->GetBinUpEdge(ax->GetNbins());
185 
186  bins = Binning::Custom(edges);
187  }
188 
189  return bins;
190  }
191 
192  //----------------------------------------------------------------------
193  void Binning::SaveTo(TDirectory* dir, const std::string& name) const
194  {
195  TDirectory* tmp = gDirectory;
196 
197  dir = dir->mkdir(name.c_str()); // switch to subdir
198  dir->cd();
199 
200  TObjString("Binning").Write("type");
201 
202  TVectorD nminmax(3);
203 
204  nminmax[0] = fNBins;
205  nminmax[1] = fMin;
206  nminmax[2] = fMax;
207 
208  nminmax.Write("nminmax");
209 
210  TVectorD issimple(1);
211  issimple[0] = fIsSimple;
212  issimple.Write("issimple");
213 
214  TVectorD edges(fEdges.size());
215  for(unsigned int i = 0; i < fEdges.size(); ++i)
216  edges[i] = fEdges[i];
217 
218  edges.Write("edges");
219 
220  for(unsigned int i = 0; i < fLabels.size(); ++i)
221  TObjString(fLabels[i].c_str()).Write(TString::Format("label%d", i).Data());
222 
223  dir->Write();
224  delete dir;
225 
226  tmp->cd();
227  }
228 
229  //----------------------------------------------------------------------
230  std::unique_ptr<Binning> Binning::LoadFrom(TDirectory* dir, const std::string& name)
231  {
232  dir = dir->GetDirectory(name.c_str()); // switch to subdir
233  assert(dir);
234 
235  TObjString* tag = (TObjString*)dir->Get("type");
236  assert(tag);
237  assert(tag->GetString() == "Binning");
238 
239  TVectorD* vMinMax = (TVectorD*)dir->Get("nminmax");
240  assert(vMinMax);
241 
242  Binning ret;
243 
244  const TVectorD* issimple = (TVectorD*)dir->Get("issimple");
245  if((*issimple)[0]){
246  ret = Binning::Simple((*vMinMax)[0],
247  (*vMinMax)[1],
248  (*vMinMax)[2]);
249  }
250  else{
251  const TVectorD* vEdges = (TVectorD*)dir->Get("edges");
252  std::vector<double> edges(vEdges->GetNrows());
253  for(int i = 0; i < vEdges->GetNrows(); ++i) edges[i] = (*vEdges)[i];
254 
255  ret = Binning::Custom(edges);
256  }
257 
258  for(unsigned int i = 0; ; ++i){
259  TObjString* s = (TObjString*)dir->Get(TString::Format("label%d", i).Data());
260  if(!s) break;
261  ret.fLabels.push_back(s->GetString().Data());
262  }
263 
264  delete dir;
265 
266  return std::make_unique<Binning>(ret);
267  }
268 
269  //----------------------------------------------------------------------
270  bool Binning::operator==(const Binning& rhs) const
271  {
272  if(fIsSimple != rhs.fIsSimple) return false;
273  if(fIsSimple){
274  return fNBins == rhs.fNBins && fMin == rhs.fMin && fMax == rhs.fMax;
275  }
276  else{
277  return fEdges == rhs.fEdges;
278  }
279  }
280 
281  //----------------------------------------------------------------------
282  bool Binning::operator<(const Binning& rhs) const
283  {
284  if(fIsSimple != rhs.fIsSimple) return fIsSimple < rhs.fIsSimple;
285  if(fIsSimple){
286  return std::make_tuple(fNBins, fMin, fMax) < std::make_tuple(rhs.fNBins, rhs.fMin, rhs.fMax);
287  }
288  else{
289  return fEdges < rhs.fEdges;
290  }
291  }
292 
293 }
static std::unique_ptr< Binning > LoadFrom(TDirectory *dir, const std::string &name)
Definition: Binning.cxx:230
Binning & operator=(const Binning &b)
Definition: Binning.cxx:58
const XML_Char * name
Definition: expat.h:151
TSpline3 lo("lo", xlo, ylo, 12,"0")
Represent the binning of a Spectrum&#39;s x-axis.
Definition: Binning.h:16
Cuts and Vars for the 2020 FD DiF Study.
Definition: vars.h:6
bool operator<(const Binning &rhs) const
Definition: Binning.cxx:282
static Binning FromTAxis(const TAxis *ax)
Definition: Binning.cxx:173
int FindBin(double x) const
Definition: Binning.cxx:155
std::vector< std::string > fLabels
Definition: Binning.h:56
static Binning CustomHelper(const std::vector< double > &edges)
Definition: Binning.cxx:130
Float_t tmp
Definition: plot.C:36
std::vector< double > fEdges
Definition: Binning.h:55
bool fIsSimple
Definition: Binning.h:59
bool IsSimple() const
Definition: Binning.h:33
const XML_Char * s
Definition: expat.h:262
TSpline3 hi("hi", xhi, yhi, 18,"0")
bool operator==(const Binning &rhs) const
Definition: Binning.cxx:270
std::void_t< T > n
void RegisterDependency(const T *parent, T *child)
Call from copy constructor and assignment operator.
Definition: DepMan.cxx:122
static Binning Custom(const std::vector< double > &edges)
Definition: Binning.cxx:145
float bin[41]
Definition: plottest35.C:14
const Binning bins
Definition: NumuCC_CPiBin.h:8
double fMax
Definition: Binning.h:58
static Binning LogUniform(int n, double lo, double hi)
Definition: Binning.cxx:118
TDirectory * dir
Definition: macro.C:5
void RegisterDestruction(T *x)
Call from destructor.
Definition: DepMan.cxx:97
void SaveTo(TDirectory *dir, const std::string &name) const
Definition: Binning.cxx:193
static DepMan & Instance()
Definition: DepMan.cxx:51
const hit & b
Definition: hits.cxx:21
assert(nhit_max >=nhit_nbins)
void Format(TGraph *gr, int lcol, int lsty, int lwid, int mcol, int msty, double msiz)
Definition: Style.cxx:154
void RegisterConstruction(T *x)
Call from constructor (in the success case)
Definition: DepMan.cxx:73
double fMin
Definition: Binning.h:58
static Binning Simple(int n, double lo, double hi, const std::vector< std::string > &labels={})
Definition: Binning.cxx:107
int fNBins
Definition: Binning.h:57
gm Write()
static Binning SimpleHelper(int n, double lo, double hi, const std::vector< std::string > &labels={})
Definition: Binning.cxx:88
enum BeamMode string