Logo ROOT   6.10/09
Reference Guide
TAxis.hxx
Go to the documentation of this file.
1 /// \file ROOT/TAxis.h
2 /// \ingroup Hist
3 /// \author Axel Naumann <axel@cern.ch>
4 /// \date 2015-03-23
5 /// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback is welcome!
6 
7 /*************************************************************************
8  * Copyright (C) 1995-2015, Rene Brun and Fons Rademakers. *
9  * All rights reserved. *
10  * *
11  * For the licensing terms see $ROOTSYS/LICENSE. *
12  * For the list of contributors see $ROOTSYS/README/CREDITS. *
13  *************************************************************************/
14 
15 #ifndef ROOT7_TAxis
16 #define ROOT7_TAxis
17 
18 #include <algorithm>
19 #include <cmath>
20 #include <initializer_list>
21 #include <string>
22 #include <unordered_map>
23 #include <vector>
24 
25 #include "RStringView.h"
26 #include "ROOT/TLogger.hxx"
27 
28 namespace ROOT {
29 namespace Experimental {
30 
31 /**
32  \class TAxisBase ROOT7
33  Histogram axis base class. Keeps track of the number of bins and overflow
34  handling. Offers bin iteration.
35 
36  Bin indices are starting from 0 for the underflow bin (representing values that
37  are lower than the axis range). Starting at index 1 are the actual bins of the
38  axis, up to N + 1 for an axis with N bins. Index N + 2 is the overflow bin for
39  values larger than the axis range.
40  */
41 class TAxisBase {
42 public:
43  /// Status of FindBin(x)
44  enum class EFindStatus {
45  kCanGrow, ///< Coordinate could fit after growing the axis
46  kValid ///< The returned bin index is valid
47  };
48 
49 protected:
50  ///\name Inaccessible copy, assignment
51  /// The copy and move constructors and assignment operators are protected to
52  /// prevent slicing.
53  ///\{
54  TAxisBase(const TAxisBase &) = default;
55  TAxisBase(TAxisBase &&) = default;
56  TAxisBase &operator=(const TAxisBase &) = default;
57  TAxisBase &operator=(TAxisBase &&) = default;
58  ///\}
59 
60  /// Default construct a TAxisBase (for use by derived classes for I/O)
61  TAxisBase() : fCanGrow(false)
62  {
63  }
64 
65  /// Given rawbin (<0 for underflow, >= GetNBinsNoOver() for overflow), determine the
66  /// actual bin number taking into account how over/underflow should be
67  /// handled.
68  ///
69  /// \param[out] status result status of the bin determination.
70  /// \return Returns the bin number adjusted for potential over- and underflow
71  /// bins. Returns kIgnoreBin if the axis cannot handle the over- / underflow,
72  /// in which case `status` will tell how to deal with this overflow.
73  int AdjustOverflowBinNumber(int rawbin) const {
74  if (rawbin < 0) return 0;
75  // Take underflow into account.
76  ++rawbin;
77 
78  if (rawbin >= GetNBins())
79  return GetNBins() - 1;
80 
81  return rawbin;
82  }
83 
84 public:
85  /**
86  \class const_iterator
87  Random const_iterator through bins. Represents the bin index, not a bin
88  content: the axis has no notion of any content.
89  */
91  public std::iterator<std::random_access_iterator_tag,
92  int /*value*/, int /*distance*/,
93  const int * /*pointer*/, const int & /*ref*/> {
94  int fCursor = 0; ///< Current iteration position
95 
96  public:
97  const_iterator() = default;
98 
99  /// Initialize a const_iterator with its position
100  explicit const_iterator(int cursor) noexcept: fCursor(cursor) { }
101 
102  /// ++i
104  // Could check whether fCursor < fEnd - but what for?
105  ++fCursor;
106  return *this;
107  }
108 
109  /// --i
111  // Could check whether fCursor > fBegin - but what for?
112  --fCursor;
113  return *this;
114  }
115 
116  /// i++
117  const_iterator operator++(int) noexcept {
118  const_iterator old(*this);
119  ++(*this);
120  return old;
121  }
122 
123  // i--
124  const_iterator operator--(int) noexcept {
125  const_iterator old(*this);
126  --(*this);
127  return old;
128  }
129 
130  // i += 2
131  const_iterator &operator+=(int d) noexcept {
132  fCursor += d;
133  return *this;
134  }
135 
136  // i -= 2
137  const_iterator &operator-=(int d) noexcept {
138  fCursor -= d;
139  return *this;
140  }
141 
142  // i + 2
143  const_iterator operator+(int d) noexcept {
144  const_iterator ret(*this);
145  ret += d;
146  return ret;
147  }
148 
149  // i - 2
150  const_iterator operator-(int d) noexcept {
151  const_iterator ret(*this);
152  ret -= d;
153  return ret;
154  }
155 
156  // *i
157  const int *operator*() const noexcept { return &fCursor; }
158 
159  // i->
160  int operator->() const noexcept { return fCursor; }
161 
162  friend bool operator<(const_iterator lhs, const_iterator rhs) noexcept;
163  friend bool operator>(const_iterator lhs, const_iterator rhs) noexcept;
164  friend bool operator<=(const_iterator lhs, const_iterator rhs) noexcept;
165  friend bool operator>=(const_iterator lhs, const_iterator rhs) noexcept;
166  friend bool operator==(const_iterator lhs, const_iterator rhs) noexcept;
167  friend bool operator!=(const_iterator lhs, const_iterator rhs) noexcept;
168  };
169 
170 
171  /// FindBin() returns this bin to signal that the bin number is invalid.
172  constexpr static const int kIgnoreBin = -1;
173 
174  /// Extra bins for each EAxisOverflow value.
175  constexpr static const int kNOverflowBins[4] = {0, 1, 1, 2};
176 
177  /// Construct a TAxisBase.
178  ///
179  ///\param[in] title - axis title used for graphics and text representation.
180  ///\param[in] nbins - number of bins in this axis, excluding under- and
181  /// overflow bins.
182  ///\param[in] canGrow - whether this axis can extend its range.
183  TAxisBase(std::string_view title, int nbinsNoOver, bool canGrow) noexcept:
184  fNBins(nbinsNoOver + (canGrow ? 0 : 2)), fTitle(title), fCanGrow(canGrow) { }
185 
186  /// Construct a TAxisBase.
187  ///
188  ///\param[in] nbins - number of bins in this axis, excluding under- and
189  /// overflow bins.
190  ///\param[in] canGrow - whether this axis can extend its range.
191  TAxisBase(int nbinsNoOver, bool canGrow) noexcept:
192  TAxisBase("", nbinsNoOver, canGrow) { }
193 
194  const std::string& GetTitle() const { return fTitle; }
195 
196  /// Get the number of bins, excluding under- and overflow.
197  int GetNBinsNoOver() const noexcept {
198  return fNBins - GetNOverflowBins();
199  }
200 
201  /// Get the number of bins, including under- and overflow.
202  int GetNBins() const noexcept {
203  return fNBins;
204  }
205 
206  /// Get the number of over- and underflow bins: 0 for growable axes, 2 otherwise.
207  int GetNOverflowBins() const noexcept {
208  if (fCanGrow)
209  return 0;
210  else
211  return 2;
212  };
213 
214  /// Get the bin index for the underflow bin.
215  int GetUnderflowBin() const noexcept { return 0; }
216 
217  /// Get the bin index for the underflow bin (or the next bin outside range
218  /// if CanGrow()).
219  int GetOverflowBin() const noexcept {
220  return GetNBinsNoOver() + 1;
221  }
222 
223  /// Whether the bin index is referencing a bin lower than the axis range.
224  bool IsUnderflowBin(int bin) const noexcept {
225  return bin <= GetUnderflowBin();
226  }
227 
228  /// Whether the bin index is referencing a bin higher than the axis range.
229  bool IsOverflowBin(int bin) const noexcept {
230  return bin >= GetOverflowBin();
231  }
232 
233  ///\name Iterator interfaces
234  ///\{
235 
236  /// Get a const_iterator pointing to the first non-underflow bin.
237  const_iterator begin() const noexcept { return const_iterator{1}; }
238 
239  /// Get a const_iterator pointing the underflow bin.
241  return const_iterator{0};
242  }
243 
244  /// Get a const_iterator pointing right beyond the last non-overflow bin
245  /// (i.e. pointing to the overflow bin).
246  const_iterator end() const noexcept {
247  return const_iterator{GetOverflowBin()};
248  }
249 
250  /// Get a const_iterator pointing right beyond the overflow bin.
252  return const_iterator{GetOverflowBin() + 1};
253  }
254  ///\}
255 
256 private:
257  unsigned int fNBins; ///< Number of bins including under- and overflow.
258  std::string fTitle; ///< Title of this axis, used for graphics / text.
259  const bool fCanGrow; ///< Whether this axis can grow (and thus has no overflow bins).
260 };
261 
262 ///\name TAxisBase::const_iterator comparison operators
263 ///\{
264 
265 /// i < j
267  TAxisBase::const_iterator rhs) noexcept {
268  return lhs.fCursor < rhs.fCursor;
269 }
270 
271 /// i > j
273  TAxisBase::const_iterator rhs) noexcept {
274  return lhs.fCursor > rhs.fCursor;
275 }
276 
277 /// i <= j
279  TAxisBase::const_iterator rhs) noexcept {
280  return lhs.fCursor <= rhs.fCursor;
281 }
282 
283 /// i >= j
285  TAxisBase::const_iterator rhs) noexcept {
286  return lhs.fCursor >= rhs.fCursor;
287 }
288 
289 /// i == j
291  TAxisBase::const_iterator rhs) noexcept {
292  return lhs.fCursor == rhs.fCursor;
293 }
294 
295 /// i != j
297  TAxisBase::const_iterator rhs) noexcept {
298  return lhs.fCursor != rhs.fCursor;
299 }
300 ///\}
301 
302 
303 
304  /**
305  \class TAxisConfig
306  Objects used to configure the different axis types. It can store the
307  properties of all possible axis types, together with the type of the axis.
308 
309  TODO: that's what a variant will be invented for!
310  */
311 class TAxisConfig: public TAxisBase {
312 public:
313  enum EKind {
314  kEquidistant, ///< represents a TAxisEquidistant
315  kGrow, ///< represents a TAxisGrow
316  kIrregular, ///< represents a TAxisIrregular
317  kLabels, ///< represents a TAxisLabels
318  kNumKinds
319  };
320 
321 private:
322  EKind fKind; ///< The kind of axis represented by this configuration
323  std::vector<double> fBinBorders; ///< Bin borders of the TAxisIrregular
324  std::vector <std::string> fLabels; ///< Bin labels for a TAxisLabels
325 
326  /// Represents a `TAxisEquidistant` with `nbins` from `from` to `to`, and
327  /// axis title.
328  explicit TAxisConfig(std::string_view title, int nbins, double from, double to,
329  EKind kind):
330  TAxisBase(title, nbins, kind == kGrow), fKind(kind), fBinBorders(2)
331  {
332  if (from > to)
333  std::swap(to, from);
334 
335  fBinBorders[0] = from;
336  fBinBorders[1] = to;
337  }
338 
339 public:
340  /// Tag type signalling that an axis should be able to grow; used for calling
341  /// the appropriate constructor.
342  struct Grow_t {};
343  /// Tag signalling that an axis should be able to grow; used for calling the
344  /// appropriate constructor like so:
345  /// TAxisConfig ac(TAxisConfig::Grow, 10, 0., 1.);
346  constexpr static const Grow_t Grow{};
347 
348  /// Represents a `TAxisEquidistant` with `nbins` from `from` to `to`, and
349  /// axis title.
350  TAxisConfig(std::string_view title, int nbins, double from, double to):
351  TAxisConfig(title, nbins, from, to, kEquidistant) {}
352 
353  /// Represents a `TAxisEquidistant` with `nbins` from `from` to `to`.
354  TAxisConfig(int nbins, double from, double to):
355  TAxisConfig("", nbins, from, to, kEquidistant) {}
356 
357  /// Represents a `TAxisGrow` with `nbins` from `from` to `to`, and axis title.
358  TAxisConfig(std::string_view title, Grow_t, int nbins, double from, double to):
359  TAxisConfig(title, nbins, from, to, kGrow) {}
360 
361  /// Represents a `TAxisGrow` with `nbins` from `from` to `to`.
362  TAxisConfig(Grow_t, int nbins, double from, double to):
363  TAxisConfig("", nbins, from, to, kGrow) {}
364 
365 
366  /// Represents a `TAxisIrregular` with `binborders` and title.
367  TAxisConfig(std::string_view title, const std::vector<double> &binborders):
368  TAxisBase(title, binborders.size() - 1, false /*canGrow*/), fKind(kIrregular),
369  fBinBorders(binborders) { }
370 
371  /// Represents a `TAxisIrregular` with `binborders`.
372  TAxisConfig(const std::vector<double> &binborders):
373  TAxisConfig("", binborders) { }
374 
375  /// Represents a `TAxisIrregular` with `binborders` and title.
376  TAxisConfig(std::string_view title, std::vector<double> &&binborders) noexcept:
377  TAxisBase(title, binborders.size() - 1, false /*canGrow*/), fKind(kIrregular),
378  fBinBorders(std::move(binborders)) { }
379 
380  /// Represents a `TAxisIrregular` with `binborders`.
381  TAxisConfig(std::vector<double> &&binborders) noexcept:
382  TAxisConfig("", std::move(binborders)) { }
383 
384  /// Represents a `TAxisLabels` with `labels` and title.
385  TAxisConfig(std::string_view title, const std::vector<std::string_view> &labels):
386  TAxisBase(title, labels.size(), true /*canGrow*/),
387  fKind(kLabels),
388  fLabels(labels.begin(), labels.end()) { }
389 
390  /// Represents a `TAxisLabels` with `labels`.
391  TAxisConfig(const std::vector<std::string_view> &labels):
392  TAxisConfig("", labels) { }
393 
394  /// Represents a `TAxisLabels` with `labels` and title.
395  TAxisConfig(std::string_view title, std::vector<std::string> &&labels):
396  TAxisBase(title, labels.size(), true /*canGrow*/),
397  fKind(kLabels),
398  fLabels(std::move(labels)) { }
399 
400  /// Represents a `TAxisLabels` with `labels`.
401  TAxisConfig(std::vector<std::string> &&labels):
402  TAxisConfig("", std::move(labels)) { }
403 
404  /// Get the axis kind represented by this `TAxisConfig`.
405  EKind GetKind() const noexcept { return fKind; }
406 
407  /// Get the bin borders; non-empty if the GetKind() == kIrregular.
408  const std::vector<double> &GetBinBorders() const noexcept { return fBinBorders; }
409 
410  /// Get the bin labels; non-empty if the GetKind() == kLabels.
411  const std::vector <std::string> &GetBinLabels() const noexcept { return fLabels; }
412 };
413 
414 
415 /**
416  Axis with equidistant bin borders. Defined by lower l and upper u limit and
417  the number of bins n. All bins have the same width (u-l)/n.
418 
419  This axis cannot grow; use `TAxisGrow` for that.
420  */
422 protected:
423  double fLow = 0.; ///< The lower limit of the axis
424  double fInvBinWidth = 0.; ///< The inverse of the bin width
425 
426  /// Determine the inverse bin width.
427  /// \param nbinsNoOver - number of bins without unter-/overflow
428  /// \param lowOrHigh - first axis boundary
429  /// \param lighOrLow - second axis boundary
430  static double GetInvBinWidth(int nbinsNoOver, double lowOrHigh, double highOrLow) {
431  return nbinsNoOver / std::abs(highOrLow - lowOrHigh);
432  }
433 
434  /// Initialize a TAxisEquidistant.
435  /// \param[in] title - axis title used for graphics and text representation.
436  /// \param nbins - number of bins in the axis, excluding under- and overflow
437  /// bins.
438  /// \param low - the low axis range. Any coordinate below that is considered
439  /// as underflow. The first bin's lower edge is at this value.
440  /// \param high - the high axis range. Any coordinate above that is considered
441  /// as overflow. The last bin's higher edge is at this value.
442  explicit TAxisEquidistant(std::string_view title, int nbinsNoOver, double low,
443  double high, bool canGrow) noexcept:
444  TAxisBase(title, nbinsNoOver, canGrow), fLow(low),
445  fInvBinWidth(GetInvBinWidth(nbinsNoOver, low, high)) { }
446 
447  /// Initialize a TAxisEquidistant.
448  /// \param nbins - number of bins in the axis, excluding under- and overflow
449  /// bins.
450  /// \param low - the low axis range. Any coordinate below that is considered
451  /// as underflow. The first bin's lower edge is at this value.
452  /// \param high - the high axis range. Any coordinate above that is considered
453  /// as overflow. The last bin's higher edge is at this value.
454  explicit TAxisEquidistant(int nbinsNoOver, double low, double high, bool canGrow) noexcept:
455  TAxisEquidistant("", nbinsNoOver, low, high, canGrow) {}
456 
457 public:
458  TAxisEquidistant() = default;
459 
460  /// Initialize a TAxisEquidistant.
461  /// \param nbins - number of bins in the axis, excluding under- and overflow
462  /// bins.
463  /// \param low - the low axis range. Any coordinate below that is considered
464  /// as underflow. The first bin's lower edge is at this value.
465  /// \param high - the high axis range. Any coordinate above that is considered
466  /// as overflow. The last bin's higher edge is at this value.
467  /// \param canGrow - whether this axis can extend its range.
468  explicit TAxisEquidistant(int nbinsNoOver, double low, double high) noexcept:
469  TAxisEquidistant(nbinsNoOver, low, high, false /*canGrow*/) { }
470 
471  /// Initialize a TAxisEquidistant.
472  /// \param[in] title - axis title used for graphics and text representation.
473  /// \param nbins - number of bins in the axis, excluding under- and overflow
474  /// bins.
475  /// \param low - the low axis range. Any coordinate below that is considered
476  /// as underflow. The first bin's lower edge is at this value.
477  /// \param high - the high axis range. Any coordinate above that is considered
478  /// as overflow. The last bin's higher edge is at this value.
479  explicit TAxisEquidistant(std::string_view title, int nbinsNoOver, double low,
480  double high) noexcept:
481  TAxisEquidistant(title, nbinsNoOver, low, high, false /*canGrow*/) { }
482 
483  /// Convert to TAxisConfig.
484  operator TAxisConfig() const { return TAxisConfig(GetNBinsNoOver(), GetMinimum(), GetMaximum()); }
485 
486  /// Find the bin index for the given coordinate.
487  /// \note Passing a bin border coordinate can either return the bin above or
488  /// below the bin border. I.e. don't do that for reliable results!
489  int FindBin(double x) const noexcept {
490  int rawbin = (x - fLow) * fInvBinWidth;
491  return AdjustOverflowBinNumber(rawbin);
492  }
493 
494  /// This axis cannot grow.
495  static bool CanGrow() noexcept { return false; }
496 
497  /// Get the low end of the axis range.
498  double GetMinimum() const noexcept { return fLow; }
499 
500  /// Get the high end of the axis range.
501  double GetMaximum() const noexcept {
502  return fLow + GetNBinsNoOver()/ fInvBinWidth;
503  }
504 
505  /// Get the width of the bins
506  double GetBinWidth() const noexcept { return 1. / fInvBinWidth; }
507 
508  /// Get the inverse of the width of the bins
509  double GetInverseBinWidth() const noexcept { return fInvBinWidth; }
510 
511  /// Get the bin center for the given bin index.
512  /// For the bin == 1 (the first bin) of 2 bins for an axis (0., 1.), this
513  /// returns 0.25.
514  double GetBinCenter(int bin) const noexcept {
515  return fLow + (bin - 0.5) / fInvBinWidth;
516  }
517 
518  /// Get the low bin border for the given bin index.
519  /// For the bin == 1 (the first bin) of 2 bins for an axis (0., 1.), this
520  /// returns 0.
521  double GetBinFrom(int bin) const noexcept {
522  return fLow + (bin - 1) / fInvBinWidth;
523  }
524 
525  /// Get the high bin border for the given bin index.
526  /// For the bin == 1 (the first bin) of 2 bins for an axis (0., 1.), this
527  /// returns 0.5.
528  double GetBinTo(int bin) const noexcept {
529  return GetBinFrom(bin + 1);
530  }
531 
532  int GetBinIndexForLowEdge(double x) const noexcept;
533 };
534 
535 /// Equality-compare two TAxisEquidistant.
536 inline
537 bool operator==(const TAxisEquidistant &lhs,
538  const TAxisEquidistant &rhs) noexcept {
539  return lhs.GetNBins() == rhs.GetNBins()
540  && lhs.GetMinimum() == rhs.GetMinimum()
541  && lhs.GetInverseBinWidth() == rhs.GetInverseBinWidth();
542 }
543 
544 
545 /** An axis that can extend its range, keeping the number of its bins unchanged.
546  The axis is constructed with an initial range. Apart from its ability to
547  grow, this axis behaves like a TAxisEquidistant.
548  */
550 public:
551  /// Initialize a TAxisGrow.
552  /// \param nbins - number of bins in the axis, excluding under- and overflow
553  /// bins. This value is fixed over the lifetime of the object.
554  /// \param low - the initial value for the low axis range. Any coordinate
555  /// below that is considered as underflow. To trigger the growing of the
556  /// axis call Grow().
557  /// \param high - the initial value for the high axis range. Any coordinate
558  /// above that is considered as overflow. To trigger the growing of the
559  /// axis call Grow()
560  explicit TAxisGrow(std::string_view title, int nbins, double low,
561  double high) noexcept:
562  TAxisEquidistant(title, nbins, low, high, CanGrow()) { }
563 
564  /// Initialize a TAxisGrow.
565  /// \param[in] title - axis title used for graphics and text representation.
566  /// \param nbins - number of bins in the axis, excluding under- and overflow
567  /// bins. This value is fixed over the lifetime of the object.
568  /// \param low - the initial value for the low axis range. Any coordinate
569  /// below that is considered as underflow. To trigger the growing of the
570  /// axis call Grow().
571  /// \param high - the initial value for the high axis range. Any coordinate
572  /// above that is considered as overflow. To trigger the growing of the
573  /// axis call Grow()
574  explicit TAxisGrow(int nbins, double low, double high) noexcept:
575  TAxisEquidistant(nbins, low, high, CanGrow()) { }
576 
577  /// Convert to TAxisConfig.
578  operator TAxisConfig() const {
579  return TAxisConfig(TAxisConfig::Grow, GetNBinsNoOver(), GetMinimum(), GetMaximum());
580  }
581 
582  /// Grow this axis to make the "virtual bin" toBin in-range. This keeps the
583  /// non-affected axis limit unchanged, and extends the other axis limit such
584  /// that a number of consecutive bins are merged.
585  ///
586  /// Example, assuming an initial TAxisGrow with 10 bins from 0. to 1.:
587  /// - `Grow(0)`: that (virtual) bin spans from -0.1 to 0. To include it
588  /// in the axis range, the lower limit must be shifted. The minimal number
589  /// of bins that can be merged is 2, thus the new axis will span from
590  /// -1. to 1.
591  /// - `Grow(-1)`: that (virtual) bin spans from -0.2 to 0.1. To include it
592  /// in the axis range, the lower limit must be shifted. The minimal number
593  /// of bins that can be merged is 2, thus the new axis will span from
594  /// -1. to 1.
595  /// - `Grow(50)`: that (virtual) bin spans from 4.9 to 5.0. To include it
596  /// in the axis range, the higher limit must be shifted. Five bins need to
597  /// be merged, making the new axis range 0. to 5.0.
598  ///
599  /// \param toBin - the "virtual" bin number, as if the axis had an infinite
600  /// number of bins with the current bin width. For instance, for an axis
601  /// with ten bins in the range 0. to 1., the coordinate 2.05 has the virtual
602  /// bin index 20.
603  /// \return Returns the number of bins that were merged to reach the value.
604  /// A value of 1 means that no bins were merged (toBin was in the original
605  /// axis range).
606  int Grow(int toBin);
607 
608  /// This axis kind can increase its range.
609  bool CanGrow() const { return true; }
610 };
611 
612 
613 /**
614  An axis with non-equidistant bins (also known as "variable binning"). It is
615  defined by an array of bin borders - one more than the number of
616  (non-overflow-) bins it has! As an example, an axis with two bin needs three
617  bin borders:
618  - lower edge of the first bin;
619  - higher edge of the first bin, identical to the lower edge of the second
620  bin;
621  - higher edge of the second bin
622 
623  This axis cannot grow; the size of new bins would not be well defined.
624  */
625 class TAxisIrregular: public TAxisBase {
626 private:
627  /// Bin borders, one more than the number of non-overflow bins.
628  std::vector<double> fBinBorders;
629 
630 public:
631  TAxisIrregular() = default;
632 
633  /// Construct a TAxisIrregular from a vector of bin borders.
634  /// \note The bin borders must be sorted in increasing order!
635  explicit TAxisIrregular(const std::vector<double> &binborders):
636  TAxisBase(binborders.size() - 1, CanGrow()), fBinBorders(binborders) {
637 #ifdef R__DO_RANGE_CHECKS
638  if (!std::is_sorted(fBinBorders.begin(), fBinBorders.end()))
639  R__ERROR_HERE("HIST") << "Bin borders must be sorted!";
640 #endif // R__DO_RANGE_CHECKS
641  }
642 
643  /// Construct a TAxisIrregular from a vector of bin borders.
644  /// \note The bin borders must be sorted in increasing order!
645  /// Faster, noexcept version taking an rvalue of binborders. The compiler will
646  /// know when it can take this one.
647  explicit TAxisIrregular(std::vector<double> &&binborders) noexcept:
648  TAxisBase(binborders.size() - 1, CanGrow()), fBinBorders(std::move(binborders)) {
649 #ifdef R__DO_RANGE_CHECKS
650  if (!std::is_sorted(fBinBorders.begin(), fBinBorders.end()))
651  R__ERROR_HERE("HIST") << "Bin borders must be sorted!";
652 #endif // R__DO_RANGE_CHECKS
653  }
654 
655  /// Construct a TAxisIrregular from a vector of bin borders.
656  /// \note The bin borders must be sorted in increasing order!
657  explicit TAxisIrregular(std::string_view title, const std::vector<double> &binborders):
658  TAxisBase(title, binborders.size() - 1, CanGrow()), fBinBorders(binborders) {
659 #ifdef R__DO_RANGE_CHECKS
660  if (!std::is_sorted(fBinBorders.begin(), fBinBorders.end()))
661  R__ERROR_HERE("HIST") << "Bin borders must be sorted!";
662 #endif // R__DO_RANGE_CHECKS
663  }
664 
665  /// Construct a TAxisIrregular from a vector of bin borders.
666  /// \note The bin borders must be sorted in increasing order!
667  /// Faster, noexcept version taking an rvalue of binborders. The compiler will
668  /// know when it can take this one.
669  explicit TAxisIrregular(std::string_view title, std::vector<double> &&binborders) noexcept:
670  TAxisBase(title, binborders.size() - 1, CanGrow()), fBinBorders(std::move(binborders)) {
671 #ifdef R__DO_RANGE_CHECKS
672  if (!std::is_sorted(fBinBorders.begin(), fBinBorders.end()))
673  R__ERROR_HERE("HIST") << "Bin borders must be sorted!";
674 #endif // R__DO_RANGE_CHECKS
675  }
676 
677  /// Convert to TAxisConfig.
678  operator TAxisConfig() const { return TAxisConfig(GetBinBorders()); }
679 
680  /// Find the bin index corresponding to coordinate x. If the coordinate is
681  /// below the axis range, return 0. If it is above, return N + 1 for an axis
682  /// with N non-overflow bins.
683  int FindBin(double x) const noexcept {
684  const auto bBegin = fBinBorders.begin();
685  const auto bEnd = fBinBorders.end();
686  auto iNotLess = std::lower_bound(bBegin, bEnd, x);
687  int rawbin = iNotLess - bBegin;
688  // if x is < bBegin then iNotLess == bBegin thus rawbin == 0:
689  // we don't want not-less but just-below, thus:
690  rawbin -= 1;
691  // No need for AdjustOverflowBinNumber(rawbin) here; lower_bound() - 1 is
692  // the answer.
693  return rawbin;
694  }
695 
696  /// Get the bin center of the bin with the given index.
697  ///
698  /// For the bin at index 0 (i.e. the underflow bin), a bin center of
699  /// `std::numeric_limits<double>::min()` is returned, i.e. the minimum value
700  /// that can be held in a double.
701  /// Similarly, for the bin at index N + 1 (i.e. the overflow bin), a bin
702  /// center of `std::numeric_limits<double>::max()` is returned, i.e. the
703  /// maximum value that can be held in a double.
704  double GetBinCenter(int bin) const noexcept {
705  if (IsUnderflowBin(bin))
706  return std::numeric_limits<double>::min();
707  if (IsOverflowBin(bin))
708  return std::numeric_limits<double>::max();
709  return 0.5 * (fBinBorders[bin - 1] + fBinBorders[bin]);
710  }
711 
712  /// Get the lower bin border for a given bin index.
713  ///
714  /// For the bin at index 0 (i.e. the underflow bin), a lower bin border of
715  /// `std::numeric_limits<double>::min()` is returned, i.e. the minimum value
716  /// that can be held in a double.
717  double GetBinFrom(int bin) const noexcept {
718  if (IsUnderflowBin(bin))
719  return std::numeric_limits<double>::min();
720  // bin 0 is underflow;
721  // bin 1 starts at fBinBorders[0]
722  return fBinBorders[bin - 1];
723  }
724 
725  /// Get the higher bin border for a given bin index.
726  ///
727  /// For the bin at index N + 1 (i.e. the overflow bin), a bin border of
728  /// `std::numeric_limits<double>::max()` is returned, i.e. the maximum value
729  /// that can be held in a double.
730  double GetBinTo(int bin) const noexcept {
731  if (IsOverflowBin(bin))
732  return std::numeric_limits<double>::max();
733  return GetBinFrom(bin + 1);
734  }
735 
736  /// This axis cannot be extended.
737  static bool CanGrow() noexcept { return false; }
738 
739  /// Access to the bin borders used by this axis.
740  const std::vector<double> &GetBinBorders() const noexcept { return fBinBorders; }
741 };
742 
743 
744 /**
745  \class TAxisLabels
746  A TAxisGrow that has a label assigned to each bin and a bin width of 1.
747 
748  While filling still works through coordinates (i.e. arrays of doubles),
749  TAxisLabels allows to convert a string to a bin number or the bin's coordinate
750  center. The number of labels and the number of bins reported by TAxisGrow might
751  differ: the TAxisGrow will only grow when seeing a Fill(), while the TAxisLabels
752  will add a new label whenever `GetBinCenter()` is called.
753 
754  Implementation details:
755  Filling happens often; GetBinCenter() needs to be fast. Thus the unordered_map.
756  The painter needs the reverse: it wants the label for bin 0, bin 1 etc. The axis
757  should only store the bin labels once; referencing them is (due to re-allocation,
758  hashing etc) non-trivial. So instead, build a vector<string_view> for the few
759  times the axis needs to be painted.
760  */
761 class TAxisLabels: public TAxisGrow {
762 private:
763  /// Map of label (view on `fLabels`'s elements) to bin index
764  std::unordered_map<std::string, int /*bin number*/> fLabelsIndex;
765 
766 public:
767  /// Construct a TAxisLables from a `vector` of `string_view`s, with title.
768  explicit TAxisLabels(std::string_view title, const std::vector<std::string_view> &labels):
769  TAxisGrow(title, labels.size(), 0., static_cast<double>(labels.size())) {
770  for (size_t i = 0, n = labels.size(); i < n; ++i)
771  fLabelsIndex[std::string(labels[i])] = i;
772  }
773 
774  /// Construct a TAxisLables from a `vector` of `string`s, with title.
775  explicit TAxisLabels(std::string_view title, const std::vector<std::string> &labels):
776  TAxisGrow(title, labels.size(), 0., static_cast<double>(labels.size())) {
777  for (size_t i = 0, n = labels.size(); i < n; ++i)
778  fLabelsIndex[labels[i]] = i;
779  }
780 
781  /// Construct a TAxisLables from a `vector` of `string_view`s
782  explicit TAxisLabels(const std::vector<std::string_view> &labels):
783  TAxisLabels("", labels) {}
784 
785  /// Construct a TAxisLables from a `vector` of `string`s
786  explicit TAxisLabels(const std::vector<std::string> &labels):
787  TAxisLabels("", labels) {}
788 
789  /// Get the bin index with label.
790  int GetBinIndex(const std::string &label) {
791  auto insertResult = fLabelsIndex.insert({label, -1});
792  if (insertResult.second) {
793  // we have created a new label
794  int idx = fLabelsIndex.size() - 1;
795  insertResult.first->second = idx;
796  return idx;
797  }
798  return insertResult.first->second;
799  }
800 
801  /// Get the center of the bin with label.
802  double GetBinCenter(const std::string &label) {
803  return GetBinIndex(label) - 0.5; // bin *center*
804  }
805 
806  /// Build a vector of labels. The position in the vector defines the label's bin.
807  std::vector <std::string_view> GetBinLabels() const {
808  std::vector <std::string_view> vec(fLabelsIndex.size());
809  for (const auto &kv: fLabelsIndex)
810  vec.at(kv.second) = kv.first;
811  return vec;
812  }
813 };
814 
815 
816 namespace Internal {
817 
818 /// Converts a TAxisConfig of whatever kind to the corresponding TAxisBase-derived
819 /// object.
820 template<TAxisConfig::EKind>
821 struct AxisConfigToType; // Only specializations are defined.
822 
823 template<>
824 struct AxisConfigToType<TAxisConfig::kEquidistant> {
826 
827  Axis_t operator()(const TAxisConfig& cfg) noexcept {
828  return TAxisEquidistant(cfg.GetTitle(), cfg.GetNBinsNoOver(),
829  cfg.GetBinBorders()[0], cfg.GetBinBorders()[1]);
830  }
831 };
832 
833 template<>
835  using Axis_t = TAxisGrow;
836 
837  Axis_t operator()(const TAxisConfig& cfg) noexcept {
838  return TAxisGrow(cfg.GetTitle(), cfg.GetNBinsNoOver(),
839  cfg.GetBinBorders()[0], cfg.GetBinBorders()[1]);
840  }
841 };
842 template<>
843 struct AxisConfigToType<TAxisConfig::kIrregular> {
845 
847  return TAxisIrregular(cfg.GetTitle(), cfg.GetBinBorders());
848  }
849 };
850 
851 template<>
852 struct AxisConfigToType<TAxisConfig::kLabels> {
854 
856  return TAxisLabels(cfg.GetTitle(), cfg.GetBinLabels());
857  }
858 };
859 
860 } // namespace Internal
861 
862 
863 /// Common view on a TAxis, no matter what its kind.
864 class TAxisView {
865  /// View on a `TAxisEquidistant`, `TAxisGrow` or `TAxisLabel`.
866  const TAxisEquidistant *fEqui = nullptr;
867  /// View on a `TAxisIrregular`.
868  const TAxisIrregular *fIrr = nullptr;
869 
870 public:
871  TAxisView() = default;
872 
873  /// Construct a view on a `TAxisEquidistant`, `TAxisGrow` or `TAxisLabel`.
874  TAxisView(const TAxisEquidistant &equi): fEqui(&equi) { }
875 
876  /// Construct a view on a `TAxisIrregular`.
877  TAxisView(const TAxisIrregular &irr): fIrr(&irr) { }
878 
879  const std::string& GetTitle() const {
880  return fEqui ? fEqui->GetTitle() : fIrr->GetTitle();
881  }
882 
883  /// Find the bin containing coordinate `x`. Forwards to the underlying axis.
884  int FindBin(double x) const noexcept {
885  if (fEqui)
886  return fEqui->FindBin(x);
887  return fIrr->FindBin(x);
888  }
889 
890  /// Get the number of bins. Forwards to the underlying axis.
891  int GetNBins() const noexcept {
892  if (fEqui)
893  return fEqui->GetNBins();
894  return fIrr->GetNBins();
895  }
896 
897  /// Get the lower axis limit.
898  double GetFrom() const { return GetBinFrom(1); }
899  /// Get the upper axis limit.
900  double GetTo() const { return GetBinTo(GetNBins() - 2); }
901 
902  /// Get the bin center of bin index `i`. Forwards to the underlying axis.
903  double GetBinCenter(int i) const noexcept {
904  if (fEqui)
905  return fEqui->GetBinCenter(i);
906  return fIrr->GetBinCenter(i);
907  }
908 
909  /// Get the minimal coordinate of bin index `i`. Forwards to the underlying axis.
910  double GetBinFrom(int i) const noexcept {
911  if (fEqui)
912  return fEqui->GetBinFrom(i);
913  return fIrr->GetBinFrom(i);
914  }
915 
916  /// Get the maximal coordinate of bin index `i`. Forwards to the underlying axis.
917  double GetBinTo(int i) const noexcept {
918  if (fEqui)
919  return fEqui->GetBinTo(i);
920  return fIrr->GetBinTo(i);
921  }
922 
923  /// Get the axis as a TAxisEquidistant; returns nullptr if it's a TAxisIrregular.
924  const TAxisEquidistant* GetAsEquidistant() const { return fEqui; }
925  /// Get the axis as a TAxisIrregular; returns nullptr if it's a TAxisEquidistant.
926  const TAxisIrregular* GetAsIrregular() const { return fIrr; }
927 };
928 
929 ///\name Axis Compatibility
930 ///\{
931 enum class EAxisCompatibility {
932  kIdentical, ///< Source and target axes are identical
933 
934  kContains, ///< The source is a subset of bins of the target axis
935 
936  /// The bins of the source axis have finer granularity, but the bin borders
937  /// are compatible. Example:
938  /// source: 0., 1., 2., 3., 4., 5., 6.; target: 0., 2., 5., 6.
939  /// Note that this is *not* a symmetrical property: only one of
940  /// CanMerge(source, target), CanMap(target, source) can return kContains.
941  kSampling,
942 
943  /// The source axis and target axis have different binning. Example:
944  /// source: 0., 1., 2., 3., 4., target: 0., 0.1, 0.2, 0.3, 0.4
946 };
947 
949  TAxisEquidistant &source) noexcept;
950 ///\}
951 
952 
953 
954 } // namespace Experimental
955 } // namespace ROOT
956 
957 #endif
double GetFrom() const
Get the lower axis limit.
Definition: TAxis.hxx:898
TAxisView(const TAxisEquidistant &equi)
Construct a view on a TAxisEquidistant, TAxisGrow or TAxisLabel.
Definition: TAxis.hxx:874
TAxisBase(std::string_view title, int nbinsNoOver, bool canGrow) noexcept
Construct a TAxisBase.
Definition: TAxis.hxx:183
TAxisConfig(std::vector< double > &&binborders) noexcept
Represents a TAxisIrregular with binborders.
Definition: TAxis.hxx:381
const_iterator operator+(int d) noexcept
Definition: TAxis.hxx:143
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
TAxisLabels(std::string_view title, const std::vector< std::string > &labels)
Construct a TAxisLables from a vector of strings, with title.
Definition: TAxis.hxx:775
TAxisBase & operator=(const TAxisBase &)=default
const_iterator begin() const noexcept
Get a const_iterator pointing to the first non-underflow bin.
Definition: TAxis.hxx:237
double GetMinimum() const noexcept
Get the low end of the axis range.
Definition: TAxis.hxx:498
double GetBinCenter(int i) const noexcept
Get the bin center of bin index i. Forwards to the underlying axis.
Definition: TAxis.hxx:903
TAxisConfig(const std::vector< double > &binborders)
Represents a TAxisIrregular with binborders.
Definition: TAxis.hxx:372
const_iterator operator++(int) noexcept
i++
Definition: TAxis.hxx:117
void swap(TDirectoryEntry &e1, TDirectoryEntry &e2) noexcept
double GetBinTo(int bin) const noexcept
Get the higher bin border for a given bin index.
Definition: TAxis.hxx:730
TAxisLabels(const std::vector< std::string > &labels)
Construct a TAxisLables from a vector of strings.
Definition: TAxis.hxx:786
const std::vector< double > & GetBinBorders() const noexcept
Get the bin borders; non-empty if the GetKind() == kIrregular.
Definition: TAxis.hxx:408
const_iterator & operator--() noexcept
–i
Definition: TAxis.hxx:110
double GetInverseBinWidth() const noexcept
Get the inverse of the width of the bins.
Definition: TAxis.hxx:509
TAxisEquidistant(std::string_view title, int nbinsNoOver, double low, double high, bool canGrow) noexcept
Initialize a TAxisEquidistant.
Definition: TAxis.hxx:442
double GetBinTo(int bin) const noexcept
Get the high bin border for the given bin index.
Definition: TAxis.hxx:528
int FindBin(double x) const noexcept
Find the bin containing coordinate x. Forwards to the underlying axis.
Definition: TAxis.hxx:884
Common view on a TAxis, no matter what its kind.
Definition: TAxis.hxx:864
int GetNBinsNoOver() const noexcept
Get the number of bins, excluding under- and overflow.
Definition: TAxis.hxx:197
Axis with equidistant bin borders.
Definition: TAxis.hxx:421
int nbins[3]
STL namespace.
double GetBinFrom(int bin) const noexcept
Get the lower bin border for a given bin index.
Definition: TAxis.hxx:717
double GetTo() const
Get the upper axis limit.
Definition: TAxis.hxx:900
TAxisConfig(Grow_t, int nbins, double from, double to)
Represents a TAxisGrow with nbins from from to to.
Definition: TAxis.hxx:362
EFindStatus
Status of FindBin(x)
Definition: TAxis.hxx:44
std::vector< double > fBinBorders
Bin borders of the TAxisIrregular.
Definition: TAxis.hxx:323
const int * operator*() const noexcept
Definition: TAxis.hxx:157
int AdjustOverflowBinNumber(int rawbin) const
Given rawbin (<0 for underflow, >= GetNBinsNoOver() for overflow), determine the actual bin number ta...
Definition: TAxis.hxx:73
int FindBin(double x) const noexcept
Find the bin index corresponding to coordinate x.
Definition: TAxis.hxx:683
const_iterator end_with_overflow() const noexcept
Get a const_iterator pointing right beyond the overflow bin.
Definition: TAxis.hxx:251
The bins of the source axis have finer granularity, but the bin borders are compatible.
Double_t x[n]
Definition: legend1.C:17
std::vector< double > fBinBorders
Bin borders, one more than the number of non-overflow bins.
Definition: TAxis.hxx:628
static constexpr const int kNOverflowBins[4]
Extra bins for each EAxisOverflow value.
Definition: TAxis.hxx:175
double GetBinFrom(int i) const noexcept
Get the minimal coordinate of bin index i. Forwards to the underlying axis.
Definition: TAxis.hxx:910
represents a TAxisEquidistant
Definition: TAxis.hxx:314
const_iterator begin_with_underflow() const noexcept
Get a const_iterator pointing the underflow bin.
Definition: TAxis.hxx:240
represents a TAxisGrow
Definition: TAxis.hxx:315
int GetUnderflowBin() const noexcept
Get the bin index for the underflow bin.
Definition: TAxis.hxx:215
const std::vector< double > & GetBinBorders() const noexcept
Access to the bin borders used by this axis.
Definition: TAxis.hxx:740
const TAxisIrregular * GetAsIrregular() const
Get the axis as a TAxisIrregular; returns nullptr if it&#39;s a TAxisEquidistant.
Definition: TAxis.hxx:926
TAxisEquidistant(int nbinsNoOver, double low, double high) noexcept
Initialize a TAxisEquidistant.
Definition: TAxis.hxx:468
An axis that can extend its range, keeping the number of its bins unchanged.
Definition: TAxis.hxx:549
EAxisCompatibility CanMap(TAxisEquidistant &target, TAxisEquidistant &source) noexcept
Whether (and how) the source axis can be merged into the target axis.
Definition: TAxis.cxx:49
double GetBinFrom(int bin) const noexcept
Get the low bin border for the given bin index.
Definition: TAxis.hxx:521
TAxisConfig(const std::vector< std::string_view > &labels)
Represents a TAxisLabels with labels.
Definition: TAxis.hxx:391
bool operator>=(TAxisBase::const_iterator lhs, TAxisBase::const_iterator rhs) noexcept
i >= j
Definition: TAxis.hxx:284
TAxisIrregular(std::string_view title, std::vector< double > &&binborders) noexcept
Construct a TAxisIrregular from a vector of bin borders.
Definition: TAxis.hxx:669
double GetBinCenter(const std::string &label)
Get the center of the bin with label.
Definition: TAxis.hxx:802
TAxisBase(int nbinsNoOver, bool canGrow) noexcept
Construct a TAxisBase.
Definition: TAxis.hxx:191
bool operator<(TAxisBase::const_iterator lhs, TAxisBase::const_iterator rhs) noexcept
i < j
Definition: TAxis.hxx:266
const std::vector< std::string > & GetBinLabels() const noexcept
Get the bin labels; non-empty if the GetKind() == kLabels.
Definition: TAxis.hxx:411
EKind fKind
The kind of axis represented by this configuration.
Definition: TAxis.hxx:322
TAxisConfig(std::string_view title, int nbins, double from, double to)
Represents a TAxisEquidistant with nbins from from to to, and axis title.
Definition: TAxis.hxx:350
Objects used to configure the different axis types.
Definition: TAxis.hxx:311
unsigned int fNBins
Number of bins including under- and overflow.
Definition: TAxis.hxx:257
TAxisConfig(std::string_view title, const std::vector< double > &binborders)
Represents a TAxisIrregular with binborders and title.
Definition: TAxis.hxx:367
TAxisGrow(std::string_view title, int nbins, double low, double high) noexcept
Initialize a TAxisGrow.
Definition: TAxis.hxx:560
Random const_iterator through bins.
Definition: TAxis.hxx:90
TAxisIrregular(std::string_view title, const std::vector< double > &binborders)
Construct a TAxisIrregular from a vector of bin borders.
Definition: TAxis.hxx:657
double GetBinCenter(int bin) const noexcept
Get the bin center for the given bin index.
Definition: TAxis.hxx:514
TAxisConfig(int nbins, double from, double to)
Represents a TAxisEquidistant with nbins from from to to.
Definition: TAxis.hxx:354
int GetNOverflowBins() const noexcept
Get the number of over- and underflow bins: 0 for growable axes, 2 otherwise.
Definition: TAxis.hxx:207
const_iterator & operator++() noexcept
++i
Definition: TAxis.hxx:103
const_iterator operator--(int) noexcept
Definition: TAxis.hxx:124
represents a TAxisIrregular
Definition: TAxis.hxx:316
TAxisConfig(std::string_view title, int nbins, double from, double to, EKind kind)
Represents a TAxisEquidistant with nbins from from to to, and axis title.
Definition: TAxis.hxx:328
int GetBinIndex(const std::string &label)
Get the bin index with label.
Definition: TAxis.hxx:790
Tag type signalling that an axis should be able to grow; used for calling the appropriate constructor...
Definition: TAxis.hxx:342
static constexpr const int kIgnoreBin
FindBin() returns this bin to signal that the bin number is invalid.
Definition: TAxis.hxx:172
TAxisConfig(std::vector< std::string > &&labels)
Represents a TAxisLabels with labels.
Definition: TAxis.hxx:401
bool operator==(TAxisBase::const_iterator lhs, TAxisBase::const_iterator rhs) noexcept
i == j
Definition: TAxis.hxx:290
int GetNBins() const noexcept
Get the number of bins, including under- and overflow.
Definition: TAxis.hxx:202
int GetOverflowBin() const noexcept
Get the bin index for the underflow bin (or the next bin outside range if CanGrow()).
Definition: TAxis.hxx:219
std::vector< std::string_view > GetBinLabels() const
Build a vector of labels. The position in the vector defines the label&#39;s bin.
Definition: TAxis.hxx:807
bool operator>(TAxisBase::const_iterator lhs, TAxisBase::const_iterator rhs) noexcept
i > j
Definition: TAxis.hxx:272
TAxisEquidistant(int nbinsNoOver, double low, double high, bool canGrow) noexcept
Initialize a TAxisEquidistant.
Definition: TAxis.hxx:454
TAxisConfig(std::string_view title, std::vector< double > &&binborders) noexcept
Represents a TAxisIrregular with binborders and title.
Definition: TAxis.hxx:376
std::string fTitle
Title of this axis, used for graphics / text.
Definition: TAxis.hxx:258
TAxisGrow(int nbins, double low, double high) noexcept
Initialize a TAxisGrow.
Definition: TAxis.hxx:574
bool CanGrow() const
This axis kind can increase its range.
Definition: TAxis.hxx:609
const_iterator operator-(int d) noexcept
Definition: TAxis.hxx:150
An axis with non-equidistant bins (also known as "variable binning").
Definition: TAxis.hxx:625
TAxisView(const TAxisIrregular &irr)
Construct a view on a TAxisIrregular.
Definition: TAxis.hxx:877
bool IsUnderflowBin(int bin) const noexcept
Whether the bin index is referencing a bin lower than the axis range.
Definition: TAxis.hxx:224
bool operator!=(TAxisBase::const_iterator lhs, TAxisBase::const_iterator rhs) noexcept
i != j
Definition: TAxis.hxx:296
TAxisEquidistant(std::string_view title, int nbinsNoOver, double low, double high) noexcept
Initialize a TAxisEquidistant.
Definition: TAxis.hxx:479
const TAxisEquidistant * GetAsEquidistant() const
Get the axis as a TAxisEquidistant; returns nullptr if it&#39;s a TAxisIrregular.
Definition: TAxis.hxx:924
TAxisBase()
Default construct a TAxisBase (for use by derived classes for I/O)
Definition: TAxis.hxx:61
double GetBinTo(int i) const noexcept
Get the maximal coordinate of bin index i. Forwards to the underlying axis.
Definition: TAxis.hxx:917
represents a TAxisLabels
Definition: TAxis.hxx:317
static bool CanGrow() noexcept
This axis cannot be extended.
Definition: TAxis.hxx:737
EKind GetKind() const noexcept
Get the axis kind represented by this TAxisConfig.
Definition: TAxis.hxx:405
static double GetInvBinWidth(int nbinsNoOver, double lowOrHigh, double highOrLow)
Determine the inverse bin width.
Definition: TAxis.hxx:430
The source is a subset of bins of the target axis.
TAxisLabels(const std::vector< std::string_view > &labels)
Construct a TAxisLables from a vector of string_views.
Definition: TAxis.hxx:782
const_iterator(int cursor) noexcept
Initialize a const_iterator with its position.
Definition: TAxis.hxx:100
const std::string & GetTitle() const
Definition: TAxis.hxx:194
const_iterator end() const noexcept
Get a const_iterator pointing right beyond the last non-overflow bin (i.e.
Definition: TAxis.hxx:246
Converts a TAxisConfig of whatever kind to the corresponding TAxisBase-derived object.
Definition: TAxis.hxx:821
double GetBinWidth() const noexcept
Get the width of the bins.
Definition: TAxis.hxx:506
std::unordered_map< std::string, int > fLabelsIndex
Map of label (view on fLabels&#39;s elements) to bin index.
Definition: TAxis.hxx:764
double GetBinCenter(int bin) const noexcept
Get the bin center of the bin with the given index.
Definition: TAxis.hxx:704
TAxisIrregular(std::vector< double > &&binborders) noexcept
Construct a TAxisIrregular from a vector of bin borders.
Definition: TAxis.hxx:647
Histogram axis base class.
Definition: TAxis.hxx:41
TAxisConfig(std::string_view title, std::vector< std::string > &&labels)
Represents a TAxisLabels with labels and title.
Definition: TAxis.hxx:395
const_iterator & operator-=(int d) noexcept
Definition: TAxis.hxx:137
TAxisConfig(std::string_view title, Grow_t, int nbins, double from, double to)
Represents a TAxisGrow with nbins from from to to, and axis title.
Definition: TAxis.hxx:358
A TAxisGrow that has a label assigned to each bin and a bin width of 1.
Definition: TAxis.hxx:761
Source and target axes are identical.
int GetNBins() const noexcept
Get the number of bins. Forwards to the underlying axis.
Definition: TAxis.hxx:891
static constexpr const Grow_t Grow
Tag signalling that an axis should be able to grow; used for calling the appropriate constructor like...
Definition: TAxis.hxx:346
Axis_t operator()(const TAxisConfig &cfg) noexcept
Definition: TAxis.hxx:837
The source axis and target axis have different binning.
Coordinate could fit after growing the axis.
bool IsOverflowBin(int bin) const noexcept
Whether the bin index is referencing a bin higher than the axis range.
Definition: TAxis.hxx:229
const bool fCanGrow
Whether this axis can grow (and thus has no overflow bins).
Definition: TAxis.hxx:259
static bool CanGrow() noexcept
This axis cannot grow.
Definition: TAxis.hxx:495
double GetMaximum() const noexcept
Get the high end of the axis range.
Definition: TAxis.hxx:501
int FindBin(double x) const noexcept
Find the bin index for the given coordinate.
Definition: TAxis.hxx:489
TAxisIrregular(const std::vector< double > &binborders)
Construct a TAxisIrregular from a vector of bin borders.
Definition: TAxis.hxx:635
TAxisLabels(std::string_view title, const std::vector< std::string_view > &labels)
Construct a TAxisLables from a vector of string_views, with title.
Definition: TAxis.hxx:768
const Int_t n
Definition: legend1.C:16
const_iterator & operator+=(int d) noexcept
Definition: TAxis.hxx:131
#define R__ERROR_HERE(GROUP)
Definition: TLogger.hxx:122
std::vector< std::string > fLabels
Bin labels for a TAxisLabels.
Definition: TAxis.hxx:324
const std::string & GetTitle() const
Definition: TAxis.hxx:879
bool operator<=(TAxisBase::const_iterator lhs, TAxisBase::const_iterator rhs) noexcept
i <= j
Definition: TAxis.hxx:278
TAxisConfig(std::string_view title, const std::vector< std::string_view > &labels)
Represents a TAxisLabels with labels and title.
Definition: TAxis.hxx:385