Logo ROOT  
Reference Guide
RAxis.hxx
Go to the documentation of this file.
1 /// \file ROOT/RAxis.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_RAxis
17 #define ROOT7_RAxis
18 
19 #include <algorithm>
20 #include <cmath>
21 #include <limits>
22 #include <string>
23 #include <unordered_map>
24 #include <vector>
25 
26 #include "ROOT/RAxisConfig.hxx"
27 #include "ROOT/RStringView.hxx"
28 #include "ROOT/RLogger.hxx"
29 
30 namespace ROOT {
31 namespace Experimental {
32 
33 /**
34  \class RAxisBase
35  Histogram axis base class. Keeps track of the number of bins and overflow
36  handling. Offers bin iteration.
37 
38  Regular bin indices are starting from 1, up to N + 1 for an axis with N bins.
39  Index -1 is for the underflow bin, representing values that are lower than
40  the axis range. Index -2 is the overflow bin for values larger than the axis
41  range.
42  Growable axes do not have underflow or overflow bins, as they don't need them.
43  */
44 class RAxisBase {
45 protected:
46  ///\name Inaccessible copy, assignment
47  /// The copy and move constructors and assignment operators are protected to
48  /// prevent slicing.
49  ///\{
50  RAxisBase(const RAxisBase &) = default;
51  RAxisBase(RAxisBase &&) = default;
52  RAxisBase &operator=(const RAxisBase &) = default;
53  RAxisBase &operator=(RAxisBase &&) = default;
54  ///\}
55 
56  /// Default construct a RAxisBase (for use by derived classes for I/O)
57  RAxisBase() noexcept = default;
58 
59  /// Virtual destructor needed in this inheritance-based design
60  virtual ~RAxisBase();
61 
62  /// Construct a RAxisBase.
63  ///
64  ///\param[in] title - axis title used for graphics and text representation.
65  RAxisBase(std::string_view title) noexcept: fTitle(title) {}
66 
67  /// Given rawbin (`<0` for underflow, `>=GetNBinsNoOver()` for overflow),
68  /// determine the bin number taking into account how over/underflow
69  /// should be handled.
70  ///
71  /// \param[out] result status of the bin determination.
72  /// \return Returns the bin number adjusted for potential over- and underflow
73  /// bins. Returns `kInvalidBin` if the axis cannot handle the over- / underflow.
74  ///
75  int AdjustOverflowBinNumber(double rawbin) const
76  {
77  ++rawbin;
78 
79  // Underflow: Put in underflow bin if any, otherwise ignore
80  if (rawbin < GetFirstBin())
81  return CanGrow() ? kInvalidBin : GetUnderflowBin();
82 
83  // Overflow: Put in overflow bin if any, otherwise ignore
84  // `rawbin` is not an integer, cannot compare `rawbin > GetLastBin()`.
85  if (rawbin >= GetLastBin() + 1)
86  return CanGrow() ? kInvalidBin : GetOverflowBin();
87 
88  // Bin index is in range and has been corrected for over/underflow
89  return (int)rawbin;
90  }
91 
92  /// Check if two axis have the same bin borders
93  ///
94  /// Default implementation should work for any RAxis type, but is quite
95  /// inefficient as it does virtual GetBinFrom calls in a loop. RAxis
96  /// implementations are encouraged to provide optimized overrides for common
97  /// axis binning comparison scenarios.
98  virtual bool HasSameBinBordersAs(const RAxisBase& other) const {
99  // Axis growability (and thus under/overflow bin existence) must match
100  if (CanGrow() != other.CanGrow())
101  return false;
102 
103  // Number of normal bins must match
104  if (GetNBinsNoOver() != other.GetNBinsNoOver())
105  return false;
106 
107  // Left borders of normal bins must match
108  for (int bin: *this)
109  if (GetBinFrom(bin) != other.GetBinFrom(bin))
110  return false;
111 
112  // Right border of the last normal bin (aka maximum) must also match
113  if (GetMaximum() != other.GetMaximum())
114  return false;
115 
116  // If all of these checks passed, the two axes have the same bin borders
117  return true;
118  }
119 
120 public:
121  /**
122  \class const_iterator
123  Random const_iterator through bins. Represents the bin index, not a bin
124  content: the axis has no notion of any content.
125  */
126  class const_iterator: public std::iterator<std::random_access_iterator_tag, int /*value*/, int /*distance*/,
127  const int * /*pointer*/, const int & /*ref*/> {
128  int fCursor = 0; ///< Current iteration position
129 
130  public:
131  const_iterator() = default;
132 
133  /// Initialize a const_iterator with its position
134  explicit const_iterator(int cursor) noexcept: fCursor(cursor) {}
135 
136  /// ++i
137  const_iterator &operator++() noexcept
138  {
139  // Could check whether fCursor < fEnd - but what for?
141  return *this;
142  }
143 
144  /// --i
145  const_iterator &operator--() noexcept
146  {
147  // Could check whether fCursor > fBegin - but what for?
148  --fCursor;
149  return *this;
150  }
151 
152  /// i++
153  const_iterator operator++(int)noexcept
154  {
155  const_iterator old(*this);
156  ++(*this);
157  return old;
158  }
159 
160  // i--
161  const_iterator operator--(int)noexcept
162  {
163  const_iterator old(*this);
164  --(*this);
165  return old;
166  }
167 
168  // i += 2
169  const_iterator &operator+=(int d) noexcept
170  {
171  fCursor += d;
172  return *this;
173  }
174 
175  // i -= 2
176  const_iterator &operator-=(int d) noexcept
177  {
178  fCursor -= d;
179  return *this;
180  }
181 
182  // i + 2
183  const_iterator operator+(int d) noexcept
184  {
185  const_iterator ret(*this);
186  ret += d;
187  return ret;
188  }
189  friend const_iterator operator+(int d, const_iterator rhs) noexcept;
190 
191  // i - 2
192  const_iterator operator-(int d) noexcept
193  {
194  const_iterator ret(*this);
195  ret -= d;
196  return ret;
197  }
198 
199  // i - j
200  int operator-(const const_iterator& j) noexcept
201  {
202  return fCursor - j.fCursor;
203  }
204 
205  // i[2]
206  int operator[](int d) noexcept
207  {
208  return fCursor + d;
209  }
210 
211  // *i
212  int operator*() const noexcept { return fCursor; }
213 
214  // i->
215  const int *operator->() const noexcept { return &fCursor; }
216 
217  friend bool operator<(const_iterator lhs, const_iterator rhs) noexcept;
218  friend bool operator>(const_iterator lhs, const_iterator rhs) noexcept;
219  friend bool operator<=(const_iterator lhs, const_iterator rhs) noexcept;
220  friend bool operator>=(const_iterator lhs, const_iterator rhs) noexcept;
221  friend bool operator==(const_iterator lhs, const_iterator rhs) noexcept;
222  friend bool operator!=(const_iterator lhs, const_iterator rhs) noexcept;
223  };
224 
225  /// Special bin index returned to signify that no bin matches a request.
226  constexpr static const int kInvalidBin = 0;
227 
228  /// Index of the underflow bin, if any.
229  constexpr static const int kUnderflowBin = -1;
230 
231  /// Index of the overflow bin, if any.
232  constexpr static const int kOverflowBin = -2;
233 
234  /// Get the axis's title
235  const std::string &GetTitle() const { return fTitle; }
236 
237  /// Whether this axis can grow (and thus has no overflow bins).
238  virtual bool CanGrow() const noexcept = 0;
239 
240  /// Get the number of bins, excluding under- and overflow.
241  virtual int GetNBinsNoOver() const noexcept = 0;
242 
243  /// Get the number of bins, including under- and overflow.
244  int GetNBins() const noexcept { return GetNBinsNoOver() + GetNOverflowBins(); }
245 
246  /// Get the number of over- and underflow bins: 0 for growable axes, 2 otherwise.
247  int GetNOverflowBins() const noexcept
248  {
249  if (CanGrow())
250  return 0;
251  else
252  return 2;
253  };
254 
255  /// Get the bin index for the underflow bin (or `kInvalidBin`
256  /// if CanGrow()).
257  int GetUnderflowBin() const noexcept {
258  if (CanGrow())
259  return kInvalidBin;
260  else
261  return kUnderflowBin;
262  }
263 
264  /// Get the bin index for the overflow bin (or `kInvalidBin`
265  /// if CanGrow()).
266  int GetOverflowBin() const noexcept {
267  if (CanGrow())
268  return kInvalidBin;
269  else
270  return kOverflowBin;
271  }
272 
273  /// Get the bin index for the first bin of the axis
274  int GetFirstBin() const noexcept { return 1; }
275 
276  /// Get the bin index for the last bin of the axis
277  int GetLastBin() const noexcept { return GetNBinsNoOver(); }
278 
279  ///\name Iterator interfaces
280  ///\{
281 
282  /// Get a const_iterator pointing to the first regular bin.
283  const_iterator begin() const noexcept { return const_iterator{GetFirstBin()}; }
284 
285  /// Get a const_iterator pointing beyond the last regular bin
286  const_iterator end() const noexcept { return const_iterator{GetLastBin() + 1}; }
287  ///\}
288 
289  /// Find the adjusted bin index (returning `kUnderflowBin` for underflow and `kOverflowBin`
290  /// for overflow) for the given coordinate.
291  /// \note Passing a bin border coordinate can either return the bin above or
292  /// below the bin border. I.e. don't do that for reliable results!
293  virtual int FindBin(double x) const noexcept = 0;
294 
295  /// Get the bin center for the given bin index.
296  /// The result of this method on an overflow or underflow bin is unspecified.
297  virtual double GetBinCenter(int bin) const = 0;
298 
299  /// Get the low bin border ("left edge") for the given bin index.
300  /// The result of this method on an underflow bin is unspecified.
301  virtual double GetBinFrom(int bin) const = 0;
302 
303  /// Get the high bin border ("right edge") for the given bin index.
304  /// The result of this method on an overflow bin is unspecified.
305  double GetBinTo(int bin) const {
306  const double result = (bin == kUnderflowBin) ? GetMinimum() : GetBinFrom(bin + 1);
307  return result;
308  }
309 
310  /// Get the low end of the axis range.
311  double GetMinimum() const { return GetBinFrom(GetFirstBin()); }
312 
313  /// Get the high end of the axis range.
314  double GetMaximum() const { return GetBinTo(GetLastBin()); }
315 
316  /// Check if two axes use the same binning convention, i.e.
317  ///
318  /// - Either they are both growable or neither of them is growable.
319  /// - Minimum, maximum, and all bin borders in the middle are the same.
320  /// - Bin labels must match (exactly including order, for now).
321  bool HasSameBinningAs(const RAxisBase& other) const;
322 
323  /// If the coordinate `x` is within 10 ULPs of a bin low edge coordinate,
324  /// return the bin for which this is a low edge. If it's not a bin edge,
325  /// return `kInvalidBin`.
326  virtual int GetBinIndexForLowEdge(double x) const noexcept = 0;
327 
328 private:
329  std::string fTitle; ///< Title of this axis, used for graphics / text.
330 };
331 
332 ///\name RAxisBase::const_iterator external operators
333 ///\{
334 
335 /// 2 + i
337 {
338  return rhs + d;
339 }
340 
341 /// i < j
343 {
344  return lhs.fCursor < rhs.fCursor;
345 }
346 
347 /// i > j
349 {
350  return lhs.fCursor > rhs.fCursor;
351 }
352 
353 /// i <= j
355 {
356  return lhs.fCursor <= rhs.fCursor;
357 }
358 
359 /// i >= j
361 {
362  return lhs.fCursor >= rhs.fCursor;
363 }
364 
365 /// i == j
367 {
368  return lhs.fCursor == rhs.fCursor;
369 }
370 
371 /// i != j
373 {
374  return lhs.fCursor != rhs.fCursor;
375 }
376 ///\}
377 
378 /**
379  Axis with equidistant bin borders. Defined by lower l and upper u limit and
380  the number of bins n. All bins have the same width (u-l)/n.
381 
382  This axis cannot grow; use `RAxisGrow` for that.
383  */
385 protected:
386  double fLow = 0.; ///< The lower limit of the axis
387  double fInvBinWidth = 0.; ///< The inverse of the bin width
388  unsigned int fNBinsNoOver; ///< Number of bins excluding under- and overflow.
389 
390  /// Determine the inverse bin width.
391  /// \param nbinsNoOver - number of bins without unter-/overflow
392  /// \param lowOrHigh - first axis boundary
393  /// \param lighOrLow - second axis boundary
394  static double GetInvBinWidth(int nbinsNoOver, double lowOrHigh, double highOrLow)
395  {
396  return nbinsNoOver / std::fabs(highOrLow - lowOrHigh);
397  }
398 
399  /// See RAxisBase::HasSameBinBordersAs
400  bool HasSameBinBordersAs(const RAxisBase& other) const override;
401 
402  /// Find the raw bin index (not adjusted) for the given coordinate.
403  /// The resulting raw bin is 0-based.
404  /// \note Passing a bin border coordinate can either return the bin above or
405  /// below the bin border. I.e. don't do that for reliable results!
406  double FindBinRaw(double x) const noexcept
407  {
408  return (x - fLow) * fInvBinWidth;
409  }
410 
411 public:
412  RAxisEquidistant() = default;
413 
414  /// Initialize a RAxisEquidistant.
415  /// \param[in] title - axis title used for graphics and text representation.
416  /// \param nbins - number of bins in the axis, excluding under- and overflow
417  /// bins.
418  /// \param low - the low axis range. Any coordinate below that is considered
419  /// as underflow. The first bin's lower edge is at this value.
420  /// \param high - the high axis range. Any coordinate above that is considered
421  /// as overflow. The last bin's higher edge is at this value.
422  explicit RAxisEquidistant(std::string_view title, int nbinsNoOver, double low, double high) noexcept
423  : RAxisBase(title)
424  , fLow(low)
425  , fInvBinWidth(GetInvBinWidth(nbinsNoOver, low, high))
426  , fNBinsNoOver(nbinsNoOver)
427  {}
428 
429  /// Initialize a RAxisEquidistant.
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  /// \param canGrow - whether this axis can extend its range.
437  explicit RAxisEquidistant(int nbinsNoOver, double low, double high) noexcept
438  : RAxisEquidistant("", nbinsNoOver, low, high)
439  {}
440 
441  /// Convert to RAxisConfig.
442  operator RAxisConfig() const { return RAxisConfig(GetTitle(), GetNBinsNoOver(), GetMinimum(), GetMaximum()); }
443 
444  /// Get the number of bins, excluding under- and overflow.
445  int GetNBinsNoOver() const noexcept final override { return fNBinsNoOver; }
446 
447  /// Find the adjusted bin index (returning `kUnderflowBin` for underflow and
448  /// `kOverflowBin` for overflow) for the given coordinate.
449  /// \note Passing a bin border coordinate can either return the bin above or
450  /// below the bin border. I.e. don't do that for reliable results!
451  int FindBin(double x) const noexcept final override
452  {
453  double rawbin = FindBinRaw(x);
454  return AdjustOverflowBinNumber(rawbin);
455  }
456 
457  /// This axis cannot grow.
458  bool CanGrow() const noexcept override { return false; }
459 
460  /// Get the width of the bins.
461  double GetBinWidth() const noexcept { return 1. / fInvBinWidth; }
462 
463  /// Get the inverse of the width of the bins.
464  double GetInverseBinWidth() const noexcept { return fInvBinWidth; }
465 
466  /// Get the bin center for the given bin index.
467  /// For the bin == 1 (the first bin) of 2 bins for an axis (0., 1.), this
468  /// returns 0.25.
469  /// The result of this method on an overflow or underflow bin is unspecified.
470  double GetBinCenter(int bin) const final override { return fLow + (bin - GetFirstBin() + 0.5) / fInvBinWidth; }
471 
472  /// Get the low bin border for the given bin index.
473  /// For the bin == 1 (the first bin) of 2 bins for an axis (0., 1.), this
474  /// returns 0.
475  /// The result of this method on an underflow bin is unspecified.
476  double GetBinFrom(int bin) const final override {
477  const double result = (bin == kOverflowBin) ? GetMaximum() : fLow + (bin - GetFirstBin()) / fInvBinWidth;
478  return result;
479  }
480 
481  /// If the coordinate `x` is within 10 ULPs of a bin low edge coordinate,
482  /// return the bin for which this is a low edge. If it's not a bin edge,
483  /// return `kInvalidBin`.
484  int GetBinIndexForLowEdge(double x) const noexcept final override;
485 };
486 
487 namespace Internal {
488 
489 template <>
490 struct AxisConfigToType<RAxisConfig::kEquidistant> {
491  using Axis_t = RAxisEquidistant;
492 
493  Axis_t operator()(const RAxisConfig &cfg) noexcept
494  {
495  return RAxisEquidistant(cfg.GetTitle(), cfg.GetNBinsNoOver(), cfg.GetBinBorders()[0], cfg.GetBinBorders()[1]);
496  }
497 };
498 
499 } // namespace Internal
500 
501 /** An axis that can extend its range, keeping the number of its bins unchanged.
502  The axis is constructed with an initial range. Apart from its ability to
503  grow, this axis behaves like a RAxisEquidistant.
504  */
506 public:
507  /// Initialize a RAxisGrow.
508  /// \param nbins - number of bins in the axis, excluding under- and overflow
509  /// bins. This value is fixed over the lifetime of the object.
510  /// \param low - the initial value for the low axis range. Any coordinate
511  /// below that is considered as underflow. To trigger the growing of the
512  /// axis call `Grow()`.
513  /// \param high - the initial value for the high axis range. Any coordinate
514  /// above that is considered as overflow. To trigger the growing of the
515  /// axis call `Grow()`.
516  explicit RAxisGrow(std::string_view title, int nbins, double low, double high) noexcept
517  : RAxisEquidistant(title, nbins, low, high)
518  {}
519 
520  /// Initialize a RAxisGrow.
521  /// \param[in] title - axis title used for graphics and text representation.
522  /// \param nbins - number of bins in the axis, excluding under- and overflow
523  /// bins. This value is fixed over the lifetime of the object.
524  /// \param low - the initial value for the low axis range. Any coordinate
525  /// below that is considered as underflow. To trigger the growing of the
526  /// axis call `Grow()`.
527  /// \param high - the initial value for the high axis range. Any coordinate
528  /// above that is considered as overflow. To trigger the growing of the
529  /// axis call `Grow()`.
530  explicit RAxisGrow(int nbins, double low, double high) noexcept: RAxisGrow("", nbins, low, high) {}
531 
532  /// Convert to RAxisConfig.
533  operator RAxisConfig() const { return RAxisConfig(GetTitle(), RAxisConfig::Grow, GetNBinsNoOver(), GetMinimum(), GetMaximum()); }
534 
535  /// Grow this axis to make the "virtual bin" toBin in-range. This keeps the
536  /// non-affected axis limit unchanged, and extends the other axis limit such
537  /// that a number of consecutive bins are merged.
538  ///
539  /// Example, assuming an initial RAxisGrow with 10 bins from 0. to 1.:
540  /// - `Grow(0)`: that (virtual) bin spans from -0.1 to 0. To include it
541  /// in the axis range, the lower limit must be shifted. The minimal number
542  /// of bins that can be merged is 2, thus the new axis will span from
543  /// -1. to 1.
544  /// - `Grow(-1)`: that (virtual) bin spans from -0.2 to 0.1. To include it
545  /// in the axis range, the lower limit must be shifted. The minimal number
546  /// of bins that can be merged is 2, thus the new axis will span from
547  /// -1. to 1.
548  /// - `Grow(50)`: that (virtual) bin spans from 4.9 to 5.0. To include it
549  /// in the axis range, the higher limit must be shifted. Five bins need to
550  /// be merged, making the new axis range 0. to 5.0.
551  ///
552  /// \param toBin - the "virtual" bin number, as if the axis had an infinite
553  /// number of bins with the current bin width. For instance, for an axis
554  /// with ten bins in the range 0. to 1., the coordinate 2.05 has the virtual
555  /// bin index 20.
556  /// \return Returns the number of bins that were merged to reach the value.
557  /// A value of 1 means that no bins were merged (toBin was in the original
558  /// axis range).
559  int Grow(int toBin);
560 
561  /// This axis kind can increase its range.
562  bool CanGrow() const noexcept final override { return true; }
563 };
564 
565 namespace Internal {
566 
567 template <>
568 struct AxisConfigToType<RAxisConfig::kGrow> {
569  using Axis_t = RAxisGrow;
570 
571  Axis_t operator()(const RAxisConfig &cfg) noexcept
572  {
573  return RAxisGrow(cfg.GetTitle(), cfg.GetNBinsNoOver(), cfg.GetBinBorders()[0], cfg.GetBinBorders()[1]);
574  }
575 };
576 
577 } // namespace Internal
578 
579 /**
580  An axis with non-equidistant bins (also known as "variable binning"). It is
581  defined by an array of bin borders - one more than the number of
582  (non-overflow-) bins it has! As an example, an axis with two bin needs three
583  bin borders:
584  - lower edge of the first bin;
585  - higher edge of the first bin, identical to the lower edge of the second
586  bin;
587  - higher edge of the second bin
588 
589  This axis cannot grow; the size of new bins would not be well defined.
590  */
591 class RAxisIrregular: public RAxisBase {
592 private:
593  /// Bin borders, one more than the number of regular bins.
594  std::vector<double> fBinBorders;
595 
596 protected:
597  /// See RAxisBase::HasSameBinBordersAs
598  bool HasSameBinBordersAs(const RAxisBase& other) const override;
599 
600  /// Find the raw bin index (not adjusted) for the given coordinate `x`.
601  /// The resulting raw bin is 1-based.
602  /// \note Passing a bin border coordinate can either return the bin above or
603  /// below the bin border. I.e. don't do that for reliable results!
604  double FindBinRaw(double x) const noexcept
605  {
606  const auto bBegin = fBinBorders.begin();
607  const auto bEnd = fBinBorders.end();
608  // lower_bound finds the first bin border that is >= x.
609  auto iNotLess = std::lower_bound(bBegin, bEnd, x);
610  return iNotLess - bBegin;
611  }
612 
613 public:
614  RAxisIrregular() = default;
615 
616  /// Construct a RAxisIrregular from a vector of bin borders.
617  /// \note The bin borders must be sorted in increasing order!
618  explicit RAxisIrregular(const std::vector<double> &binborders)
619  : RAxisBase(), fBinBorders(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 RAxisIrregular from a vector of bin borders.
628  /// \note The bin borders must be sorted in increasing order!
629  /// Faster, noexcept version taking an rvalue of binborders. The compiler will
630  /// know when it can take this one.
631  explicit RAxisIrregular(std::vector<double> &&binborders) noexcept
632  : RAxisBase(), fBinBorders(std::move(binborders))
633  {
634 #ifdef R__DO_RANGE_CHECKS
635  if (!std::is_sorted(fBinBorders.begin(), fBinBorders.end()))
636  R__ERROR_HERE("HIST") << "Bin borders must be sorted!";
637 #endif // R__DO_RANGE_CHECKS
638  }
639 
640  /// Construct a RAxisIrregular from a vector of bin borders.
641  /// \note The bin borders must be sorted in increasing order!
642  explicit RAxisIrregular(std::string_view title, const std::vector<double> &binborders)
643  : RAxisBase(title), fBinBorders(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  /// Construct a RAxisIrregular from a vector of bin borders.
652  /// \note The bin borders must be sorted in increasing order!
653  /// Faster, noexcept version taking an rvalue of binborders. The compiler will
654  /// know when it can take this one.
655  explicit RAxisIrregular(std::string_view title, std::vector<double> &&binborders) noexcept
656  : RAxisBase(title), fBinBorders(std::move(binborders))
657  {
658 #ifdef R__DO_RANGE_CHECKS
659  if (!std::is_sorted(fBinBorders.begin(), fBinBorders.end()))
660  R__ERROR_HERE("HIST") << "Bin borders must be sorted!";
661 #endif // R__DO_RANGE_CHECKS
662  }
663 
664  /// Convert to RAxisConfig.
665  operator RAxisConfig() const { return RAxisConfig(GetTitle(), GetBinBorders()); }
666 
667  /// Get the number of bins, excluding under- and overflow.
668  int GetNBinsNoOver() const noexcept final override { return fBinBorders.size() - 1; }
669 
670  /// Find the bin index (adjusted with under- and overflow) for the given coordinate `x`.
671  /// \note Passing a bin border coordinate can either return the bin above or
672  /// below the bin border. I.e. don't do that for reliable results!
673  int FindBin(double x) const noexcept final override
674  {
675  int rawbin = FindBinRaw(x);
676  // No need for AdjustOverflowBinNumber(rawbin) here; lower_bound() is the
677  // answer: e.g. for x < *bBegin, rawbin is -1.
678  if (rawbin < GetFirstBin())
679  return kUnderflowBin;
680  if (rawbin >= GetLastBin() + 1)
681  return kOverflowBin;
682  return rawbin;
683  }
684 
685  /// Get the bin center of the bin with the given index.
686  /// The result of this method on an overflow or underflow bin is unspecified.
687  double GetBinCenter(int bin) const final override { return 0.5 * (fBinBorders[bin - 1] + fBinBorders[bin]); }
688 
689  /// Get the lower bin border for a given bin index.
690  /// The result of this method on an underflow bin is unspecified.
691  double GetBinFrom(int bin) const final override
692  {
693  if (bin == kOverflowBin)
694  return fBinBorders[GetLastBin()];
695  return fBinBorders[bin - 1];
696  }
697 
698  /// If the coordinate `x` is within 10 ULPs of a bin low edge coordinate,
699  /// return the bin for which this is a low edge. If it's not a bin edge,
700  /// return `kInvalidBin`.
701  int GetBinIndexForLowEdge(double x) const noexcept final override;
702 
703  /// This axis cannot be extended.
704  bool CanGrow() const noexcept final override { return false; }
705 
706  /// Access to the bin borders used by this axis.
707  const std::vector<double> &GetBinBorders() const noexcept { return fBinBorders; }
708 };
709 
710 namespace Internal {
711 
712 template <>
713 struct AxisConfigToType<RAxisConfig::kIrregular> {
714  using Axis_t = RAxisIrregular;
715 
716  Axis_t operator()(const RAxisConfig &cfg) { return RAxisIrregular(cfg.GetTitle(), cfg.GetBinBorders()); }
717 };
718 
719 } // namespace Internal
720 
721 /**
722  \class RAxisLabels
723  A RAxisGrow that has a label assigned to each bin and a bin width of 1.
724 
725  While filling still works through coordinates (i.e. arrays of doubles),
726  RAxisLabels allows to convert a string to a bin number or the bin's coordinate
727  center. The number of labels and the number of bins reported by RAxisGrow might
728  differ: the RAxisGrow will only grow when seeing a Fill(), while the RAxisLabels
729  will add a new label whenever `GetBinCenter()` is called.
730 
731  Implementation details:
732  Filling happens often; `GetBinCenter()` needs to be fast. Thus the unordered_map.
733  The painter needs the reverse: it wants the label for bin 0, bin 1 etc. The axis
734  should only store the bin labels once; referencing them is (due to re-allocation,
735  hashing etc) non-trivial. So instead, build a `vector<string_view>` for the few
736  times the axis needs to be painted.
737  */
738 class RAxisLabels: public RAxisGrow {
739 private:
740  /// Map of label (view on `fLabels`'s elements) to bin index
741  std::unordered_map<std::string, int /*bin number*/> fLabelsIndex;
742 
743 public:
744  /// Construct a RAxisLables from a `vector` of `string_view`s, with title.
745  explicit RAxisLabels(std::string_view title, const std::vector<std::string_view> &labels)
746  : RAxisGrow(title, labels.size(), 0., static_cast<double>(labels.size()))
747  {
748  for (size_t i = 0, n = labels.size(); i < n; ++i)
749  fLabelsIndex[std::string(labels[i])] = i;
750  }
751 
752  /// Construct a RAxisLables from a `vector` of `string`s, with title.
753  explicit RAxisLabels(std::string_view title, const std::vector<std::string> &labels)
754  : RAxisGrow(title, labels.size(), 0., static_cast<double>(labels.size()))
755  {
756  for (size_t i = 0, n = labels.size(); i < n; ++i)
757  fLabelsIndex[labels[i]] = i;
758  }
759 
760  /// Construct a RAxisLables from a `vector` of `string_view`s
761  explicit RAxisLabels(const std::vector<std::string_view> &labels): RAxisLabels("", labels) {}
762 
763  /// Construct a RAxisLables from a `vector` of `string`s
764  explicit RAxisLabels(const std::vector<std::string> &labels): RAxisLabels("", labels) {}
765 
766  /// Convert to RAxisConfig.
767  operator RAxisConfig() const { return RAxisConfig(GetTitle(), GetBinLabels()); }
768 
769  /// Get the bin index with label.
770  int FindBinByName(const std::string &label)
771  {
772  auto insertResult = fLabelsIndex.insert({label, -1});
773  if (insertResult.second) {
774  // we have created a new label
775  int idx = fLabelsIndex.size() - 1;
776  insertResult.first->second = idx;
777  return idx;
778  }
779  return insertResult.first->second;
780  }
781 
782  /// Get the center of the bin with label.
783  double GetBinCenterByName(const std::string &label)
784  {
785  return FindBinByName(label) + 0.5; // bin *center*
786  }
787 
788  /// Build a vector of labels. The position in the vector defines the label's bin.
789  std::vector<std::string_view> GetBinLabels() const
790  {
791  std::vector<std::string_view> vec(fLabelsIndex.size());
792  for (const auto &kv: fLabelsIndex)
793  vec.at(kv.second) = kv.first;
794  return vec;
795  }
796 
797  /// Result of an RAxisLabels label set comparison
798  enum LabelsCmpFlags {
799  /// Both axes have the same labels, mapping to the same bins
800  kLabelsCmpSame = 0,
801 
802  /// The other axis doesn't have some labels from this axis
803  kLabelsCmpSubset = 0b1,
804 
805  /// The other axis has some labels which this axis doesn't have
806  kLabelsCmpSuperset = 0b10,
807 
808  /// The labels shared by both axes do not map into the same bins
809  kLabelsCmpDisordered = 0b100,
810  };
811 
812  /// Compare the labels of this axis with those of another axis
813  LabelsCmpFlags CompareBinLabels(const RAxisLabels& other) const noexcept {
814  // This will eventually contain the results of the labels comparison
816  size_t missing_in_other = 0;
817 
818  // First, check how this axis' labels map into the other axis
819  for (const auto &kv: fLabelsIndex) {
820  auto iter = other.fLabelsIndex.find(kv.first);
821  if (iter == other.fLabelsIndex.cend()) {
822  ++missing_in_other;
823  } else if (iter->second != kv.second) {
824  result = LabelsCmpFlags(result | kLabelsCmpDisordered);
825  }
826  }
827  if (missing_in_other > 0)
828  result = LabelsCmpFlags(result | kLabelsCmpSubset);
829 
830  // If this covered all labels in the other axis, we're done
831  if (fLabelsIndex.size() == other.fLabelsIndex.size() + missing_in_other)
832  return result;
833 
834  // Otherwise, we must check the labels of the other axis too
835  for (const auto &kv: other.fLabelsIndex)
836  if (fLabelsIndex.find(kv.first) == fLabelsIndex.cend())
837  return LabelsCmpFlags(result | kLabelsCmpSuperset);
838  return result;
839  }
840 };
841 
842 namespace Internal {
843 
844 template <>
845 struct AxisConfigToType<RAxisConfig::kLabels> {
846  using Axis_t = RAxisLabels;
847 
848  Axis_t operator()(const RAxisConfig &cfg) { return RAxisLabels(cfg.GetTitle(), cfg.GetBinLabels()); }
849 };
850 
851 } // namespace Internal
852 
853 ///\name Axis Compatibility
854 ///\{
855 enum class EAxisCompatibility {
856  kIdentical, ///< Source and target axes are identical
857 
858  kContains, ///< The source is a subset of bins of the target axis
859 
860  /// The bins of the source axis have finer granularity, but the bin borders
861  /// are compatible. Example:
862  /// source: 0., 1., 2., 3., 4., 5., 6.; target: 0., 2., 5., 6.
863  /// Note that this is *not* a symmetrical property: only one of
864  /// CanMerge(source, target), CanMap(target, source) can return kContains.
865  kSampling,
866 
867  /// The source axis and target axis have different binning. Example:
868  /// source: 0., 1., 2., 3., 4., target: 0., 0.1, 0.2, 0.3, 0.4
870 };
871 
872 /// Whether (and how) the source axis can be merged into the target axis.
873 EAxisCompatibility CanMap(const RAxisEquidistant &target, const RAxisEquidistant &source) noexcept;
874 ///\}
875 
876 } // namespace Experimental
877 } // namespace ROOT
878 
879 #endif // ROOT7_RAxis header guard
ROOT::Experimental::RAxisBase::GetNOverflowBins
int GetNOverflowBins() const noexcept
Get the number of over- and underflow bins: 0 for growable axes, 2 otherwise.
Definition: RAxis.hxx:259
ROOT::Experimental::RAxisConfig::Grow
constexpr static const Grow_t Grow
Tag signalling that an axis should be able to grow; used for calling the appropriate constructor like...
Definition: RAxisConfig.hxx:84
ROOT::Experimental::RAxisLabels::kLabelsCmpSuperset
@ kLabelsCmpSuperset
The other axis has some labels which this axis doesn't have.
Definition: RAxis.hxx:818
ROOT::Experimental::RAxisBase::GetBinFrom
virtual double GetBinFrom(int bin) const =0
Get the low bin border ("left edge") for the given bin index.
ROOT::Experimental::RAxisBase::const_iterator::operator==
friend bool operator==(const_iterator lhs, const_iterator rhs) noexcept
i == j
Definition: RAxis.hxx:378
n
const Int_t n
Definition: legend1.C:16
ROOT::Experimental::RAxisBase::GetOverflowBin
int GetOverflowBin() const noexcept
Get the bin index for the overflow bin (or kInvalidBin if CanGrow()).
Definition: RAxis.hxx:278
ROOT::Experimental::RAxisIrregular::GetBinFrom
double GetBinFrom(int bin) const final override
Get the lower bin border for a given bin index.
Definition: RAxis.hxx:703
ROOT::Experimental::RAxisBase::HasSameBinBordersAs
virtual bool HasSameBinBordersAs(const RAxisBase &other) const
Check if two axis have the same bin borders.
Definition: RAxis.hxx:110
ROOT::Experimental::RAxisBase::FindBin
virtual int FindBin(double x) const noexcept=0
Find the adjusted bin index (returning kUnderflowBin for underflow and kOverflowBin for overflow) for...
ROOT::Experimental::operator!=
bool operator!=(RAxisBase::const_iterator lhs, RAxisBase::const_iterator rhs) noexcept
i != j
Definition: RAxis.hxx:384
ROOT::Experimental::RAxisBase::const_iterator::operator!=
friend bool operator!=(const_iterator lhs, const_iterator rhs) noexcept
i != j
Definition: RAxis.hxx:384
ROOT::Experimental::RAxisConfig::GetTitle
const std::string & GetTitle() const
Get the axis's title.
Definition: RAxisConfig.hxx:137
ROOT::Experimental::operator>=
bool operator>=(RAxisBase::const_iterator lhs, RAxisBase::const_iterator rhs) noexcept
i >= j
Definition: RAxis.hxx:372
ROOT::Experimental::RAxisLabels::fLabelsIndex
std::unordered_map< std::string, int > fLabelsIndex
Map of label (view on fLabels's elements) to bin index.
Definition: RAxis.hxx:753
ROOT::Experimental::RAxisConfig
Definition: RAxisConfig.hxx:47
ROOT::Experimental::RAxisBase::const_iterator::operator-
const_iterator operator-(int d) noexcept
Definition: RAxis.hxx:204
ROOT::Experimental::CanMap
EAxisCompatibility CanMap(const RAxisEquidistant &target, const RAxisEquidistant &source) noexcept
Whether (and how) the source axis can be merged into the target axis.
Definition: RAxis.cxx:116
ROOT::Experimental::RAxisIrregular::fBinBorders
std::vector< double > fBinBorders
Bin borders, one more than the number of regular bins.
Definition: RAxis.hxx:606
ROOT::Experimental::RAxisBase::end
const_iterator end() const noexcept
Get a const_iterator pointing beyond the last regular bin.
Definition: RAxis.hxx:298
ROOT::Experimental::RAxisConfig::GetBinBorders
const std::vector< double > & GetBinBorders() const noexcept
Get the bin borders; non-empty if the GetKind() == kIrregular.
Definition: RAxisConfig.hxx:146
ROOT::Experimental::RAxisIrregular::GetBinCenter
double GetBinCenter(int bin) const final override
Get the bin center of the bin with the given index.
Definition: RAxis.hxx:699
Axis_t
double Axis_t
Definition: RtypesCore.h:76
basic_string_view
Definition: libcpp_string_view.h:199
ROOT::Experimental::RAxisIrregular::FindBinRaw
double FindBinRaw(double x) const noexcept
Find the raw bin index (not adjusted) for the given coordinate x.
Definition: RAxis.hxx:616
ROOT::Experimental::RAxisIrregular::GetBinBorders
const std::vector< double > & GetBinBorders() const noexcept
Access to the bin borders used by this axis.
Definition: RAxis.hxx:719
ROOT::Experimental::RAxisBase::fTitle
std::string fTitle
Title of this axis, used for graphics / text.
Definition: RAxis.hxx:341
ROOT::Experimental::EAxisCompatibility::kIncompatible
@ kIncompatible
The source axis and target axis have different binning.
ROOT::Experimental::RAxisIrregular
An axis with non-equidistant bins (also known as "variable binning").
Definition: RAxis.hxx:603
string_view
basic_string_view< char > string_view
Definition: libcpp_string_view.h:785
ROOT::Experimental::RAxisEquidistant::FindBin
int FindBin(double x) const noexcept final override
Find the adjusted bin index (returning kUnderflowBin for underflow and kOverflowBin for overflow) for...
Definition: RAxis.hxx:463
ROOT::Experimental::EAxisCompatibility
EAxisCompatibility
Definition: RAxis.hxx:867
ROOT::Experimental::RAxisBase::const_iterator::operator[]
int operator[](int d) noexcept
Definition: RAxis.hxx:218
ROOT::Experimental::RAxisBase::const_iterator::fCursor
int fCursor
Current iteration position.
Definition: RAxis.hxx:140
ROOT::Experimental::RAxisGrow
An axis that can extend its range, keeping the number of its bins unchanged.
Definition: RAxis.hxx:517
ROOT::Experimental::RAxisBase::const_iterator::operator>=
friend bool operator>=(const_iterator lhs, const_iterator rhs) noexcept
i >= j
Definition: RAxis.hxx:372
ROOT::Experimental::RAxisBase::GetFirstBin
int GetFirstBin() const noexcept
Get the bin index for the first bin of the axis.
Definition: RAxis.hxx:286
x
Double_t x[n]
Definition: legend1.C:17
operator()
TRObject operator()(const T1 &t1) const
Definition: TRFunctionImport__oprtr.h:14
ROOT::Experimental::RAxisBase::const_iterator::operator*
int operator*() const noexcept
Definition: RAxis.hxx:224
ROOT::Experimental::RAxisLabels::FindBinByName
int FindBinByName(const std::string &label)
Get the bin index with label.
Definition: RAxis.hxx:782
ROOT::Experimental::RAxisLabels::GetBinLabels
std::vector< std::string_view > GetBinLabels() const
Build a vector of labels. The position in the vector defines the label's bin.
Definition: RAxis.hxx:801
ROOT::Experimental::operator<=
bool operator<=(RAxisBase::const_iterator lhs, RAxisBase::const_iterator rhs) noexcept
i <= j
Definition: RAxis.hxx:366
ROOT::Experimental::RAxisBase::const_iterator::operator++
const_iterator & operator++() noexcept
++i
Definition: RAxis.hxx:149
ROOT::Experimental::RAxisBase::GetTitle
const std::string & GetTitle() const
Get the axis's title.
Definition: RAxis.hxx:247
ROOT::Experimental::RAxisBase::kOverflowBin
constexpr static const int kOverflowBin
Index of the overflow bin, if any.
Definition: RAxis.hxx:244
ROOT::Experimental::RAxisLabels::kLabelsCmpDisordered
@ kLabelsCmpDisordered
The labels shared by both axes do not map into the same bins.
Definition: RAxis.hxx:821
ROOT::Experimental::RAxisBase::GetBinIndexForLowEdge
virtual int GetBinIndexForLowEdge(double x) const noexcept=0
If the coordinate x is within 10 ULPs of a bin low edge coordinate, return the bin for which this is ...
ROOT::Experimental::RAxisEquidistant::GetBinCenter
double GetBinCenter(int bin) const final override
Get the bin center for the given bin index.
Definition: RAxis.hxx:482
ROOT::Experimental::RAxisBase::GetMinimum
double GetMinimum() const
Get the low end of the axis range.
Definition: RAxis.hxx:323
ROOT::Experimental::RAxisLabels::LabelsCmpFlags
LabelsCmpFlags
Result of an RAxisLabels label set comparison.
Definition: RAxis.hxx:810
ROOT::Experimental::RAxisBase::RAxisBase
RAxisBase() noexcept=default
Default construct a RAxisBase (for use by derived classes for I/O)
ROOT::Experimental::RAxisBase::GetBinTo
double GetBinTo(int bin) const
Get the high bin border ("right edge") for the given bin index.
Definition: RAxis.hxx:317
ROOT::Experimental::RAxisEquidistant::fLow
double fLow
The lower limit of the axis.
Definition: RAxis.hxx:398
ROOT::Experimental::RAxisBase::const_iterator::operator+
const_iterator operator+(int d) noexcept
Definition: RAxis.hxx:195
ROOT::Experimental::EAxisCompatibility::kSampling
@ kSampling
The bins of the source axis have finer granularity, but the bin borders are compatible.
ROOT::Experimental::RAxisEquidistant::GetBinIndexForLowEdge
int GetBinIndexForLowEdge(double x) const noexcept final override
If the coordinate x is within 10 ULPs of a bin low edge coordinate, return the bin for which this is ...
Definition: RAxis.cxx:41
RLogger.hxx
ROOT::Experimental::RAxisIrregular::GetBinIndexForLowEdge
int GetBinIndexForLowEdge(double x) const noexcept final override
If the coordinate x is within 10 ULPs of a bin low edge coordinate, return the bin for which this is ...
Definition: RAxis.cxx:81
ROOT::Experimental::RAxisEquidistant::FindBinRaw
double FindBinRaw(double x) const noexcept
Find the raw bin index (not adjusted) for the given coordinate.
Definition: RAxis.hxx:418
ROOT::Math::fabs
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
Definition: UnaryOperators.h:131
ROOT::Experimental::RAxisLabels::kLabelsCmpSame
@ kLabelsCmpSame
Both axes have the same labels, mapping to the same bins.
Definition: RAxis.hxx:812
ROOT::Experimental::RAxisBase::const_iterator::operator--
const_iterator & operator--() noexcept
–i
Definition: RAxis.hxx:157
ROOT::Experimental::RAxisLabels::RAxisLabels
RAxisLabels(std::string_view title, const std::vector< std::string_view > &labels)
Construct a RAxisLables from a vector of string_views, with title.
Definition: RAxis.hxx:757
ROOT::Experimental::RAxisIrregular::RAxisIrregular
RAxisIrregular()=default
ROOT::Experimental::RAxisEquidistant
Axis with equidistant bin borders.
Definition: RAxis.hxx:396
ROOT::Experimental::operator<
bool operator<(RAxisBase::const_iterator lhs, RAxisBase::const_iterator rhs) noexcept
i < j
Definition: RAxis.hxx:354
ROOT::Experimental::RAxisBase::const_iterator
Definition: RAxis.hxx:138
R__ERROR_HERE
#define R__ERROR_HERE(GROUP)
Definition: RLogger.hxx:183
ROOT::Experimental::RAxisBase::kInvalidBin
constexpr static const int kInvalidBin
Special bin index returned to signify that no bin matches a request.
Definition: RAxis.hxx:238
ROOT::Experimental::RAxisLabels
Definition: RAxis.hxx:750
ROOT::Experimental::EAxisCompatibility::kIdentical
@ kIdentical
Source and target axes are identical.
ROOT::Experimental::RAxisGrow::RAxisGrow
RAxisGrow(std::string_view title, int nbins, double low, double high) noexcept
Initialize a RAxisGrow.
Definition: RAxis.hxx:528
RStringView.hxx
ROOT::Experimental::RAxisBase::GetLastBin
int GetLastBin() const noexcept
Get the bin index for the last bin of the axis.
Definition: RAxis.hxx:289
ROOT::Experimental::RAxisBase::kUnderflowBin
constexpr static const int kUnderflowBin
Index of the underflow bin, if any.
Definition: RAxis.hxx:241
ROOT::Experimental::RAxisEquidistant::GetBinWidth
double GetBinWidth() const noexcept
Get the width of the bins.
Definition: RAxis.hxx:473
ROOT::Experimental::RAxisEquidistant::HasSameBinBordersAs
bool HasSameBinBordersAs(const RAxisBase &other) const override
See RAxisBase::HasSameBinBordersAs.
Definition: RAxis.cxx:66
ROOT::Experimental::RAxisBase::const_iterator::operator+=
const_iterator & operator+=(int d) noexcept
Definition: RAxis.hxx:181
double
double
Definition: Converters.cxx:921
ROOT::Experimental::RAxisIrregular::HasSameBinBordersAs
bool HasSameBinBordersAs(const RAxisBase &other) const override
See RAxisBase::HasSameBinBordersAs.
Definition: RAxis.cxx:104
ROOT::Experimental::RAxisIrregular::CanGrow
bool CanGrow() const noexcept final override
This axis cannot be extended.
Definition: RAxis.hxx:716
ROOT::Experimental::RAxisEquidistant::GetInverseBinWidth
double GetInverseBinWidth() const noexcept
Get the inverse of the width of the bins.
Definition: RAxis.hxx:476
ROOT::Experimental::RAxisBase::AdjustOverflowBinNumber
int AdjustOverflowBinNumber(double rawbin) const
Given rawbin (<0 for underflow, >=GetNBinsNoOver() for overflow), determine the bin number taking int...
Definition: RAxis.hxx:87
ROOT::Experimental::RAxisBase::CanGrow
virtual bool CanGrow() const noexcept=0
Whether this axis can grow (and thus has no overflow bins).
ROOT::Experimental::RAxisEquidistant::CanGrow
bool CanGrow() const noexcept override
This axis cannot grow.
Definition: RAxis.hxx:470
ROOT::Experimental::RAxisEquidistant::GetInvBinWidth
static double GetInvBinWidth(int nbinsNoOver, double lowOrHigh, double highOrLow)
Determine the inverse bin width.
Definition: RAxis.hxx:406
ROOT::Experimental::RAxisBase
Definition: RAxis.hxx:56
ROOT::Experimental::RAxisBase::const_iterator::operator<
friend bool operator<(const_iterator lhs, const_iterator rhs) noexcept
i < j
Definition: RAxis.hxx:354
ROOT::Experimental::RAxisBase::GetNBins
int GetNBins() const noexcept
Get the number of bins, including under- and overflow.
Definition: RAxis.hxx:256
ROOT::Experimental::RAxisBase::begin
const_iterator begin() const noexcept
Get a const_iterator pointing to the first regular bin.
Definition: RAxis.hxx:295
ROOT::Experimental::RAxisLabels::kLabelsCmpSubset
@ kLabelsCmpSubset
The other axis doesn't have some labels from this axis.
Definition: RAxis.hxx:815
ROOT::Experimental::RAxisBase::HasSameBinningAs
bool HasSameBinningAs(const RAxisBase &other) const
Check if two axes use the same binning convention, i.e.
Definition: RAxis.cxx:23
ROOT::Experimental::RAxisEquidistant::GetNBinsNoOver
int GetNBinsNoOver() const noexcept final override
Get the number of bins, excluding under- and overflow.
Definition: RAxis.hxx:457
ROOT::Experimental::RAxisConfig::GetNBinsNoOver
int GetNBinsNoOver() const noexcept
Get the number of bins, excluding under- and overflow.
Definition: RAxisConfig.hxx:143
ROOT::Experimental::RAxisLabels::CompareBinLabels
LabelsCmpFlags CompareBinLabels(const RAxisLabels &other) const noexcept
Compare the labels of this axis with those of another axis.
Definition: RAxis.hxx:825
ROOT::Experimental::RAxisIrregular::GetNBinsNoOver
int GetNBinsNoOver() const noexcept final override
Get the number of bins, excluding under- and overflow.
Definition: RAxis.hxx:680
ROOT::Experimental::RAxisBase::const_iterator::operator-=
const_iterator & operator-=(int d) noexcept
Definition: RAxis.hxx:188
RAxisConfig.hxx
ROOT::Experimental::RAxisBase::GetNBinsNoOver
virtual int GetNBinsNoOver() const noexcept=0
Get the number of bins, excluding under- and overflow.
ROOT::Experimental::RAxisBase::const_iterator::operator<=
friend bool operator<=(const_iterator lhs, const_iterator rhs) noexcept
i <= j
Definition: RAxis.hxx:366
ROOT::Experimental::RAxisEquidistant::fNBinsNoOver
unsigned int fNBinsNoOver
Number of bins excluding under- and overflow.
Definition: RAxis.hxx:400
d
#define d(i)
Definition: RSha256.hxx:120
ROOT::Experimental::RAxisEquidistant::fInvBinWidth
double fInvBinWidth
The inverse of the bin width.
Definition: RAxis.hxx:399
ROOT::Experimental::RAxisBase::const_iterator::operator->
const int * operator->() const noexcept
Definition: RAxis.hxx:227
ROOT::Experimental::RAxisBase::const_iterator::const_iterator
const_iterator()=default
ROOT::Experimental::RAxisBase::operator=
RAxisBase & operator=(const RAxisBase &)=default
ROOT::Experimental::RAxisBase::const_iterator::operator>
friend bool operator>(const_iterator lhs, const_iterator rhs) noexcept
i > j
Definition: RAxis.hxx:360
ROOT::Experimental::EAxisCompatibility::kContains
@ kContains
The source is a subset of bins of the target axis.
ROOT::Experimental::operator==
bool operator==(const TString &t, const std::string &s)
Definition: REveTypes.cxx:13
ROOT::Experimental::RAxisBase::GetUnderflowBin
int GetUnderflowBin() const noexcept
Get the bin index for the underflow bin (or kInvalidBin if CanGrow()).
Definition: RAxis.hxx:269
ROOT::Experimental::RAxisBase::GetMaximum
double GetMaximum() const
Get the high end of the axis range.
Definition: RAxis.hxx:326
ROOT::Experimental::RAxisIrregular::FindBin
int FindBin(double x) const noexcept final override
Find the bin index (adjusted with under- and overflow) for the given coordinate x.
Definition: RAxis.hxx:685
ROOT::Experimental::RAxisBase::GetBinCenter
virtual double GetBinCenter(int bin) const =0
Get the bin center for the given bin index.
ROOT::Experimental::RAxisGrow::Grow
int Grow(int toBin)
Grow this axis to make the "virtual bin" toBin in-range.
ROOT
VSD Structures.
Definition: StringConv.hxx:21
ROOT::Experimental::RAxisEquidistant::RAxisEquidistant
RAxisEquidistant()=default
ROOT::Experimental::RAxisLabels::GetBinCenterByName
double GetBinCenterByName(const std::string &label)
Get the center of the bin with label.
Definition: RAxis.hxx:795
ROOT::Experimental::operator+
REveException operator+(const REveException &s1, const std::string &s2)
Definition: REveTypes.cxx:21
ROOT::Experimental::operator>
bool operator>(RAxisBase::const_iterator lhs, RAxisBase::const_iterator rhs) noexcept
i > j
Definition: RAxis.hxx:360
ROOT::Experimental::RAxisGrow::CanGrow
bool CanGrow() const noexcept final override
This axis kind can increase its range.
Definition: RAxis.hxx:574
ROOT::Experimental::RAxisEquidistant::GetBinFrom
double GetBinFrom(int bin) const final override
Get the low bin border for the given bin index.
Definition: RAxis.hxx:488