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