Logo ROOT  
Reference Guide
RAxis.hxx
Go to the documentation of this file.
1 /// \file ROOT/RAxis.hxx
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(noexcept(std::string())) = 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[in] rawbin for which to determine the bin number.
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
138  {
139  // Could check whether fCursor < fEnd - but what for?
140  ++fCursor;
141  return *this;
142  }
143 
144  /// --i
146  {
147  // Could check whether fCursor > fBegin - but what for?
148  --fCursor;
149  return *this;
150  }
151 
152  /// i++
154  {
155  const_iterator old(*this);
156  ++(*this);
157  return old;
158  }
159 
160  // i--
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 highOrLow - 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 nbinsNoOver - 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 nbinsNoOver - 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 RAxisEquidistant(int nbinsNoOver, double low, double high) noexcept
437  : RAxisEquidistant("", nbinsNoOver, low, high)
438  {}
439 
440  /// Convert to RAxisConfig.
441  operator RAxisConfig() const { return RAxisConfig(GetTitle(), GetNBinsNoOver(), GetMinimum(), GetMaximum()); }
442 
443  /// Get the number of bins, excluding under- and overflow.
444  int GetNBinsNoOver() const noexcept final override { return fNBinsNoOver; }
445 
446  /// Find the adjusted bin index (returning `kUnderflowBin` for underflow and
447  /// `kOverflowBin` for overflow) for the given coordinate.
448  /// \note Passing a bin border coordinate can either return the bin above or
449  /// below the bin border. I.e. don't do that for reliable results!
450  int FindBin(double x) const noexcept final override
451  {
452  double rawbin = FindBinRaw(x);
453  return AdjustOverflowBinNumber(rawbin);
454  }
455 
456  /// This axis cannot grow.
457  bool CanGrow() const noexcept override { return false; }
458 
459  /// Get the width of the bins.
460  double GetBinWidth() const noexcept { return 1. / fInvBinWidth; }
461 
462  /// Get the inverse of the width of the bins.
463  double GetInverseBinWidth() const noexcept { return fInvBinWidth; }
464 
465  /// Get the bin center for the given bin index.
466  /// For the bin == 1 (the first bin) of 2 bins for an axis (0., 1.), this
467  /// returns 0.25.
468  /// The result of this method on an overflow or underflow bin is unspecified.
469  double GetBinCenter(int bin) const final override { return fLow + (bin - GetFirstBin() + 0.5) / fInvBinWidth; }
470 
471  /// Get the low bin border for the given bin index.
472  /// For the bin == 1 (the first bin) of 2 bins for an axis (0., 1.), this
473  /// returns 0.
474  /// The result of this method on an underflow bin is unspecified.
475  double GetBinFrom(int bin) const final override {
476  const double result = (bin == kOverflowBin) ? GetMaximum() : fLow + (bin - GetFirstBin()) / fInvBinWidth;
477  return result;
478  }
479 
480  /// If the coordinate `x` is within 10 ULPs of a bin low edge coordinate,
481  /// return the bin for which this is a low edge. If it's not a bin edge,
482  /// return `kInvalidBin`.
483  int GetBinIndexForLowEdge(double x) const noexcept final override;
484 };
485 
486 namespace Internal {
487 
488 template <>
489 struct AxisConfigToType<RAxisConfig::kEquidistant> {
491 
492  Axis_t operator()(const RAxisConfig &cfg) noexcept
493  {
494  return RAxisEquidistant(cfg.GetTitle(), cfg.GetNBinsNoOver(), cfg.GetBinBorders()[0], cfg.GetBinBorders()[1]);
495  }
496 };
497 
498 } // namespace Internal
499 
500 /** An axis that can extend its range, keeping the number of its bins unchanged.
501  The axis is constructed with an initial range. Apart from its ability to
502  grow, this axis behaves like a RAxisEquidistant.
503  */
505 public:
506  /// Initialize a RAxisGrow.
507  /// \param[in] title - axis title used for graphics and text representation.
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 nbins - number of bins in the axis, excluding under- and overflow
522  /// bins. This value is fixed over the lifetime of the object.
523  /// \param low - the initial value for the low axis range. Any coordinate
524  /// below that is considered as underflow. To trigger the growing of the
525  /// axis call `Grow()`.
526  /// \param high - the initial value for the high axis range. Any coordinate
527  /// above that is considered as overflow. To trigger the growing of the
528  /// axis call `Grow()`.
529  explicit RAxisGrow(int nbins, double low, double high) noexcept: RAxisGrow("", nbins, low, high) {}
530 
531  /// Convert to RAxisConfig.
533 
534  /// Grow this axis to make the "virtual bin" toBin in-range. This keeps the
535  /// non-affected axis limit unchanged, and extends the other axis limit such
536  /// that a number of consecutive bins are merged.
537  ///
538  /// Example, assuming an initial RAxisGrow with 10 bins from 0. to 1.:
539  /// - `Grow(0)`: that (virtual) bin spans from -0.1 to 0. To include it
540  /// in the axis range, the lower limit must be shifted. The minimal number
541  /// of bins that can be merged is 2, thus the new axis will span from
542  /// -1. to 1.
543  /// - `Grow(-1)`: that (virtual) bin spans from -0.2 to 0.1. To include it
544  /// in the axis range, the lower limit must be shifted. The minimal number
545  /// of bins that can be merged is 2, thus the new axis will span from
546  /// -1. to 1.
547  /// - `Grow(50)`: that (virtual) bin spans from 4.9 to 5.0. To include it
548  /// in the axis range, the higher limit must be shifted. Five bins need to
549  /// be merged, making the new axis range 0. to 5.0.
550  ///
551  /// \param toBin - the "virtual" bin number, as if the axis had an infinite
552  /// number of bins with the current bin width. For instance, for an axis
553  /// with ten bins in the range 0. to 1., the coordinate 2.05 has the virtual
554  /// bin index 20.
555  /// \return Returns the number of bins that were merged to reach the value.
556  /// A value of 1 means that no bins were merged (toBin was in the original
557  /// axis range).
558  int Grow(int toBin);
559 
560  /// This axis kind can increase its range.
561  bool CanGrow() const noexcept final override { return true; }
562 };
563 
564 namespace Internal {
565 
566 template <>
568  using Axis_t = RAxisGrow;
569 
570  Axis_t operator()(const RAxisConfig &cfg) noexcept
571  {
572  return RAxisGrow(cfg.GetTitle(), cfg.GetNBinsNoOver(), cfg.GetBinBorders()[0], cfg.GetBinBorders()[1]);
573  }
574 };
575 
576 } // namespace Internal
577 
578 /**
579  An axis with non-equidistant bins (also known as "variable binning"). It is
580  defined by an array of bin borders - one more than the number of
581  (non-overflow-) bins it has! As an example, an axis with two bin needs three
582  bin borders:
583  - lower edge of the first bin;
584  - higher edge of the first bin, identical to the lower edge of the second
585  bin;
586  - higher edge of the second bin
587 
588  This axis cannot grow; the size of new bins would not be well defined.
589  */
590 class RAxisIrregular: public RAxisBase {
591 private:
592  /// Bin borders, one more than the number of regular bins.
593  std::vector<double> fBinBorders;
594 
595 protected:
596  /// See RAxisBase::HasSameBinBordersAs
597  bool HasSameBinBordersAs(const RAxisBase& other) const override;
598 
599  /// Find the raw bin index (not adjusted) for the given coordinate `x`.
600  /// The resulting raw bin is 1-based.
601  /// \note Passing a bin border coordinate can either return the bin above or
602  /// below the bin border. I.e. don't do that for reliable results!
603  double FindBinRaw(double x) const noexcept
604  {
605  const auto bBegin = fBinBorders.begin();
606  const auto bEnd = fBinBorders.end();
607  // lower_bound finds the first bin border that is >= x.
608  auto iNotLess = std::lower_bound(bBegin, bEnd, x);
609  return iNotLess - bBegin;
610  }
611 
612 public:
613  RAxisIrregular() = default;
614 
615  /// Construct a RAxisIrregular from a vector of bin borders.
616  /// \note The bin borders must be sorted in increasing order!
617  explicit RAxisIrregular(const std::vector<double> &binborders)
618  : RAxisBase(), fBinBorders(binborders)
619  {
620 #ifdef R__DO_RANGE_CHECKS
621  if (!std::is_sorted(fBinBorders.begin(), fBinBorders.end()))
622  R__LOG_ERROR("HIST") << "Bin borders must be sorted!";
623 #endif // R__DO_RANGE_CHECKS
624  }
625 
626  /// Construct a RAxisIrregular from a vector of bin borders.
627  /// \note The bin borders must be sorted in increasing order!
628  /// Faster, noexcept version taking an rvalue of binborders. The compiler will
629  /// know when it can take this one.
630  explicit RAxisIrregular(std::vector<double> &&binborders) noexcept
631  : RAxisBase(), fBinBorders(std::move(binborders))
632  {
633 #ifdef R__DO_RANGE_CHECKS
634  if (!std::is_sorted(fBinBorders.begin(), fBinBorders.end()))
635  R__LOG_ERROR("HIST") << "Bin borders must be sorted!";
636 #endif // R__DO_RANGE_CHECKS
637  }
638 
639  /// Construct a RAxisIrregular from a vector of bin borders.
640  /// \note The bin borders must be sorted in increasing order!
641  explicit RAxisIrregular(std::string_view title, const std::vector<double> &binborders)
642  : RAxisBase(title), fBinBorders(binborders)
643  {
644 #ifdef R__DO_RANGE_CHECKS
645  if (!std::is_sorted(fBinBorders.begin(), fBinBorders.end()))
646  R__LOG_ERROR("HIST") << "Bin borders must be sorted!";
647 #endif // R__DO_RANGE_CHECKS
648  }
649 
650  /// Construct a RAxisIrregular from a vector of bin borders.
651  /// \note The bin borders must be sorted in increasing order!
652  /// Faster, noexcept version taking an rvalue of binborders. The compiler will
653  /// know when it can take this one.
654  explicit RAxisIrregular(std::string_view title, std::vector<double> &&binborders) noexcept
655  : RAxisBase(title), fBinBorders(std::move(binborders))
656  {
657 #ifdef R__DO_RANGE_CHECKS
658  if (!std::is_sorted(fBinBorders.begin(), fBinBorders.end()))
659  R__LOG_ERROR("HIST") << "Bin borders must be sorted!";
660 #endif // R__DO_RANGE_CHECKS
661  }
662 
663  /// Convert to RAxisConfig.
664  operator RAxisConfig() const { return RAxisConfig(GetTitle(), GetBinBorders()); }
665 
666  /// Get the number of bins, excluding under- and overflow.
667  int GetNBinsNoOver() const noexcept final override { return fBinBorders.size() - 1; }
668 
669  /// Find the bin index (adjusted with under- and overflow) for the given coordinate `x`.
670  /// \note Passing a bin border coordinate can either return the bin above or
671  /// below the bin border. I.e. don't do that for reliable results!
672  int FindBin(double x) const noexcept final override
673  {
674  int rawbin = FindBinRaw(x);
675  // No need for AdjustOverflowBinNumber(rawbin) here; lower_bound() is the
676  // answer: e.g. for x < *bBegin, rawbin is -1.
677  if (rawbin < GetFirstBin())
678  return kUnderflowBin;
679  if (rawbin >= GetLastBin() + 1)
680  return kOverflowBin;
681  return rawbin;
682  }
683 
684  /// Get the bin center of the bin with the given index.
685  /// The result of this method on an overflow or underflow bin is unspecified.
686  double GetBinCenter(int bin) const final override { return 0.5 * (fBinBorders[bin - 1] + fBinBorders[bin]); }
687 
688  /// Get the lower bin border for a given bin index.
689  /// The result of this method on an underflow bin is unspecified.
690  double GetBinFrom(int bin) const final override
691  {
692  if (bin == kOverflowBin)
693  return fBinBorders[GetLastBin()];
694  return fBinBorders[bin - 1];
695  }
696 
697  /// If the coordinate `x` is within 10 ULPs of a bin low edge coordinate,
698  /// return the bin for which this is a low edge. If it's not a bin edge,
699  /// return `kInvalidBin`.
700  int GetBinIndexForLowEdge(double x) const noexcept final override;
701 
702  /// This axis cannot be extended.
703  bool CanGrow() const noexcept final override { return false; }
704 
705  /// Access to the bin borders used by this axis.
706  const std::vector<double> &GetBinBorders() const noexcept { return fBinBorders; }
707 };
708 
709 namespace Internal {
710 
711 template <>
712 struct AxisConfigToType<RAxisConfig::kIrregular> {
714 
715  Axis_t operator()(const RAxisConfig &cfg) { return RAxisIrregular(cfg.GetTitle(), cfg.GetBinBorders()); }
716 };
717 
718 } // namespace Internal
719 
720 /**
721  \class RAxisLabels
722  A RAxisGrow that has a label assigned to each bin and a bin width of 1.
723 
724  While filling still works through coordinates (i.e. arrays of doubles),
725  RAxisLabels allows to convert a string to a bin number or the bin's coordinate
726  center. The number of labels and the number of bins reported by RAxisGrow might
727  differ: the RAxisGrow will only grow when seeing a Fill(), while the RAxisLabels
728  will add a new label whenever `GetBinCenter()` is called.
729 
730  Implementation details:
731  Filling happens often; `GetBinCenter()` needs to be fast. Thus the unordered_map.
732  The painter needs the reverse: it wants the label for bin 0, bin 1 etc. The axis
733  should only store the bin labels once; referencing them is (due to re-allocation,
734  hashing etc) non-trivial. So instead, build a `vector<string_view>` for the few
735  times the axis needs to be painted.
736  */
737 class RAxisLabels: public RAxisGrow {
738 private:
739  /// Map of label (view on `fLabels`'s elements) to bin index
740  std::unordered_map<std::string, int /*bin number*/> fLabelsIndex;
741 
742 public:
743  /// Construct a RAxisLables from a `vector` of `string_view`s, with title.
744  explicit RAxisLabels(std::string_view title, const std::vector<std::string_view> &labels)
745  : RAxisGrow(title, labels.size(), 0., static_cast<double>(labels.size()))
746  {
747  for (size_t i = 0, n = labels.size(); i < n; ++i)
748  fLabelsIndex[std::string(labels[i])] = i;
749  }
750 
751  /// Construct a RAxisLables from a `vector` of `string`s, with title.
752  explicit RAxisLabels(std::string_view title, const std::vector<std::string> &labels)
753  : RAxisGrow(title, labels.size(), 0., static_cast<double>(labels.size()))
754  {
755  for (size_t i = 0, n = labels.size(); i < n; ++i)
756  fLabelsIndex[labels[i]] = i;
757  }
758 
759  /// Construct a RAxisLables from a `vector` of `string_view`s
760  explicit RAxisLabels(const std::vector<std::string_view> &labels): RAxisLabels("", labels) {}
761 
762  /// Construct a RAxisLables from a `vector` of `string`s
763  explicit RAxisLabels(const std::vector<std::string> &labels): RAxisLabels("", labels) {}
764 
765  /// Convert to RAxisConfig.
766  operator RAxisConfig() const { return RAxisConfig(GetTitle(), GetBinLabels()); }
767 
768  /// Get the bin index with label.
769  int FindBinByName(const std::string &label)
770  {
771  auto insertResult = fLabelsIndex.insert({label, -1});
772  if (insertResult.second) {
773  // we have created a new label
774  int idx = fLabelsIndex.size() - 1;
775  insertResult.first->second = idx;
776  return idx;
777  }
778  return insertResult.first->second;
779  }
780 
781  /// Get the center of the bin with label.
782  double GetBinCenterByName(const std::string &label)
783  {
784  return FindBinByName(label) + 0.5; // bin *center*
785  }
786 
787  /// Build a vector of labels. The position in the vector defines the label's bin.
788  std::vector<std::string_view> GetBinLabels() const
789  {
790  std::vector<std::string_view> vec(fLabelsIndex.size());
791  for (const auto &kv: fLabelsIndex)
792  vec.at(kv.second) = kv.first;
793  return vec;
794  }
795 
796  /// Result of an RAxisLabels label set comparison
798  /// Both axes have the same labels, mapping to the same bins
800 
801  /// The other axis doesn't have some labels from this axis
803 
804  /// The other axis has some labels which this axis doesn't have
806 
807  /// The labels shared by both axes do not map into the same bins
809  };
810 
811  /// Compare the labels of this axis with those of another axis
812  LabelsCmpFlags CompareBinLabels(const RAxisLabels& other) const noexcept {
813  // This will eventually contain the results of the labels comparison
815  size_t missing_in_other = 0;
816 
817  // First, check how this axis' labels map into the other axis
818  for (const auto &kv: fLabelsIndex) {
819  auto iter = other.fLabelsIndex.find(kv.first);
820  if (iter == other.fLabelsIndex.cend()) {
821  ++missing_in_other;
822  } else if (iter->second != kv.second) {
823  result = LabelsCmpFlags(result | kLabelsCmpDisordered);
824  }
825  }
826  if (missing_in_other > 0)
827  result = LabelsCmpFlags(result | kLabelsCmpSubset);
828 
829  // If this covered all labels in the other axis, we're done
830  if (fLabelsIndex.size() == other.fLabelsIndex.size() + missing_in_other)
831  return result;
832 
833  // Otherwise, we must check the labels of the other axis too
834  for (const auto &kv: other.fLabelsIndex)
835  if (fLabelsIndex.find(kv.first) == fLabelsIndex.cend())
836  return LabelsCmpFlags(result | kLabelsCmpSuperset);
837  return result;
838  }
839 };
840 
841 namespace Internal {
842 
843 template <>
844 struct AxisConfigToType<RAxisConfig::kLabels> {
846 
847  Axis_t operator()(const RAxisConfig &cfg) { return RAxisLabels(cfg.GetTitle(), cfg.GetBinLabels()); }
848 };
849 
850 } // namespace Internal
851 
852 ///\name Axis Compatibility
853 ///\{
854 enum class EAxisCompatibility {
855  kIdentical, ///< Source and target axes are identical
856 
857  kContains, ///< The source is a subset of bins of the target axis
858 
859  /// The bins of the source axis have finer granularity, but the bin borders
860  /// are compatible. Example:
861  /// source: 0., 1., 2., 3., 4., 5., 6.; target: 0., 2., 5., 6.
862  /// Note that this is *not* a symmetrical property: only one of
863  /// CanMerge(source, target), CanMap(target, source) can return kContains.
864  kSampling,
865 
866  /// The source axis and target axis have different binning. Example:
867  /// source: 0., 1., 2., 3., 4., target: 0., 0.1, 0.2, 0.3, 0.4
869 };
870 
871 /// Whether (and how) the source axis can be merged into the target axis.
872 EAxisCompatibility CanMap(const RAxisEquidistant &target, const RAxisEquidistant &source) noexcept;
873 ///\}
874 
875 } // namespace Experimental
876 } // namespace ROOT
877 
878 #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:247
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:72
ROOT::Experimental::RAxisLabels::kLabelsCmpSuperset
@ kLabelsCmpSuperset
The other axis has some labels which this axis doesn't have.
Definition: RAxis.hxx:805
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:366
ROOT::Experimental::RAxisIrregular::RAxisIrregular
RAxisIrregular(std::string_view title, std::vector< double > &&binborders) noexcept
Construct a RAxisIrregular from a vector of bin borders.
Definition: RAxis.hxx:654
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:266
ROOT::Experimental::RAxisIrregular::GetBinFrom
double GetBinFrom(int bin) const final override
Get the lower bin border for a given bin index.
Definition: RAxis.hxx:690
ROOT::Experimental::RAxisBase::HasSameBinBordersAs
virtual bool HasSameBinBordersAs(const RAxisBase &other) const
Check if two axis have the same bin borders.
Definition: RAxis.hxx:98
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:372
ROOT::Experimental::RAxisBase::const_iterator::operator!=
friend bool operator!=(const_iterator lhs, const_iterator rhs) noexcept
i != j
Definition: RAxis.hxx:372
ROOT::Experimental::RAxisConfig::GetTitle
const std::string & GetTitle() const
Get the axis's title.
Definition: RAxisConfig.hxx:125
ROOT::Experimental::operator>=
bool operator>=(RAxisBase::const_iterator lhs, RAxisBase::const_iterator rhs) noexcept
i >= j
Definition: RAxis.hxx:360
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:740
ROOT::Experimental::RAxisConfig::GetBinLabels
const std::vector< std::string > & GetBinLabels() const noexcept
Get the bin labels; non-empty if the GetKind() == kLabels.
Definition: RAxisConfig.hxx:137
ROOT::Experimental::RAxisConfig
Objects used to configure the different axis types.
Definition: RAxisConfig.hxx:35
R__LOG_ERROR
#define R__LOG_ERROR(...)
Definition: RLogger.hxx:362
ROOT::Experimental::operator+
ELogLevel operator+(ELogLevel severity, int offset)
Definition: RLogger.hxx:45
ROOT::Experimental::RAxisBase::const_iterator::operator-
const_iterator operator-(int d) noexcept
Definition: RAxis.hxx:192
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:126
ROOT::Experimental::RAxisIrregular::fBinBorders
std::vector< double > fBinBorders
Bin borders, one more than the number of regular bins.
Definition: RAxis.hxx:593
ROOT::Experimental::RAxisBase::end
const_iterator end() const noexcept
Get a const_iterator pointing beyond the last regular bin.
Definition: RAxis.hxx:286
ROOT::Experimental::RAxisConfig::GetBinBorders
const std::vector< double > & GetBinBorders() const noexcept
Get the bin borders; non-empty if the GetKind() == kIrregular.
Definition: RAxisConfig.hxx:134
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:686
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:603
ROOT::Experimental::RAxisIrregular::GetBinBorders
const std::vector< double > & GetBinBorders() const noexcept
Access to the bin borders used by this axis.
Definition: RAxis.hxx:706
ROOT::Experimental::RAxisBase::fTitle
std::string fTitle
Title of this axis, used for graphics / text.
Definition: RAxis.hxx:329
ROOT::Experimental::RAxisLabels::RAxisLabels
RAxisLabels(std::string_view title, const std::vector< std::string > &labels)
Construct a RAxisLables from a vector of strings, with title.
Definition: RAxis.hxx:752
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:590
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:450
ROOT::Experimental::EAxisCompatibility
EAxisCompatibility
Definition: RAxis.hxx:854
ROOT::Experimental::RAxisBase::const_iterator::operator[]
int operator[](int d) noexcept
Definition: RAxis.hxx:206
ROOT::Experimental::RAxisLabels::RAxisLabels
RAxisLabels(const std::vector< std::string_view > &labels)
Construct a RAxisLables from a vector of string_views.
Definition: RAxis.hxx:760
ROOT::Experimental::RAxisBase::RAxisBase
RAxisBase(const RAxisBase &)=default
ROOT::Experimental::RAxisBase::const_iterator::fCursor
int fCursor
Current iteration position.
Definition: RAxis.hxx:128
ROOT::Experimental::RAxisGrow
An axis that can extend its range, keeping the number of its bins unchanged.
Definition: RAxis.hxx:504
ROOT::Experimental::RAxisBase::const_iterator::operator>=
friend bool operator>=(const_iterator lhs, const_iterator rhs) noexcept
i >= j
Definition: RAxis.hxx:360
ROOT::Experimental::RAxisBase::GetFirstBin
int GetFirstBin() const noexcept
Get the bin index for the first bin of the axis.
Definition: RAxis.hxx:274
x
Double_t x[n]
Definition: legend1.C:17
ROOT::Experimental::RAxisBase::const_iterator::operator*
int operator*() const noexcept
Definition: RAxis.hxx:212
ROOT::Experimental::RAxisLabels::FindBinByName
int FindBinByName(const std::string &label)
Get the bin index with label.
Definition: RAxis.hxx:769
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:788
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::operator++
const_iterator & operator++() noexcept
++i
Definition: RAxis.hxx:137
ROOT::Experimental::RAxisBase::GetTitle
const std::string & GetTitle() const
Get the axis's title.
Definition: RAxis.hxx:235
ROOT::Experimental::RAxisEquidistant::RAxisEquidistant
RAxisEquidistant(std::string_view title, int nbinsNoOver, double low, double high) noexcept
Initialize a RAxisEquidistant.
Definition: RAxis.hxx:422
ROOT::Experimental::RAxisBase::kOverflowBin
constexpr static const int kOverflowBin
Index of the overflow bin, if any.
Definition: RAxis.hxx:232
ROOT::Experimental::RAxisLabels::kLabelsCmpDisordered
@ kLabelsCmpDisordered
The labels shared by both axes do not map into the same bins.
Definition: RAxis.hxx:808
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:469
ROOT::Experimental::RAxisBase::GetMinimum
double GetMinimum() const
Get the low end of the axis range.
Definition: RAxis.hxx:311
ROOT::Experimental::RAxisLabels::LabelsCmpFlags
LabelsCmpFlags
Result of an RAxisLabels label set comparison.
Definition: RAxis.hxx:797
ROOT::Experimental::RAxisBase::const_iterator::operator-
int operator-(const const_iterator &j) noexcept
Definition: RAxis.hxx:200
ROOT::Experimental::RAxisBase::GetBinTo
double GetBinTo(int bin) const
Get the high bin border ("right edge") for the given bin index.
Definition: RAxis.hxx:305
ROOT::Experimental::RAxisEquidistant::fLow
double fLow
The lower limit of the axis.
Definition: RAxis.hxx:386
ROOT::Experimental::RAxisBase::const_iterator::operator+
const_iterator operator+(int d) noexcept
Definition: RAxis.hxx:183
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:51
ROOT::Experimental::RAxisBase::const_iterator::const_iterator
const_iterator(int cursor) noexcept
Initialize a const_iterator with its position.
Definition: RAxis.hxx:134
ROOT::Experimental::RAxisIrregular::RAxisIrregular
RAxisIrregular(std::string_view title, const std::vector< double > &binborders)
Construct a RAxisIrregular from a vector of bin borders.
Definition: RAxis.hxx:641
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:91
ROOT::Experimental::RAxisEquidistant::FindBinRaw
double FindBinRaw(double x) const noexcept
Find the raw bin index (not adjusted) for the given coordinate.
Definition: RAxis.hxx:406
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:799
ROOT::Experimental::RAxisBase::const_iterator::operator--
const_iterator & operator--() noexcept
–i
Definition: RAxis.hxx:145
ROOT::Experimental::RAxisBase::operator=
RAxisBase & operator=(RAxisBase &&)=default
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:744
ROOT::Experimental::RAxisIrregular::RAxisIrregular
RAxisIrregular()=default
ROOT::Experimental::RAxisEquidistant
Axis with equidistant bin borders.
Definition: RAxis.hxx:384
ROOT::Experimental::operator<
bool operator<(RAxisBase::const_iterator lhs, RAxisBase::const_iterator rhs) noexcept
i < j
Definition: RAxis.hxx:342
ROOT::Experimental::RAxisBase::const_iterator
Random const_iterator through bins.
Definition: RAxis.hxx:127
ROOT::Experimental::RAxisBase::kInvalidBin
constexpr static const int kInvalidBin
Special bin index returned to signify that no bin matches a request.
Definition: RAxis.hxx:226
ROOT::Experimental::RAxisLabels
A RAxisGrow that has a label assigned to each bin and a bin width of 1.
Definition: RAxis.hxx:737
ROOT::Experimental::RAxisGrow::RAxisGrow
RAxisGrow(int nbins, double low, double high) noexcept
Initialize a RAxisGrow.
Definition: RAxis.hxx:529
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:516
RStringView.hxx
ROOT::Experimental::RAxisBase::GetLastBin
int GetLastBin() const noexcept
Get the bin index for the last bin of the axis.
Definition: RAxis.hxx:277
ROOT::Experimental::Internal::AxisConfigToType< RAxisConfig::kGrow >::operator()
Axis_t operator()(const RAxisConfig &cfg) noexcept
Definition: RAxis.hxx:570
ROOT::Experimental::RAxisIrregular::RAxisIrregular
RAxisIrregular(const std::vector< double > &binborders)
Construct a RAxisIrregular from a vector of bin borders.
Definition: RAxis.hxx:617
ROOT::Experimental::Internal::AxisConfigToType< RAxisConfig::kIrregular >::operator()
Axis_t operator()(const RAxisConfig &cfg)
Definition: RAxis.hxx:715
ROOT::Experimental::RAxisBase::kUnderflowBin
constexpr static const int kUnderflowBin
Index of the underflow bin, if any.
Definition: RAxis.hxx:229
ROOT::Experimental::RAxisBase::RAxisBase
RAxisBase() noexcept(noexcept(std::string()))=default
Default construct a RAxisBase (for use by derived classes for I/O)
ROOT::Experimental::RAxisEquidistant::GetBinWidth
double GetBinWidth() const noexcept
Get the width of the bins.
Definition: RAxis.hxx:460
ROOT::Experimental::RAxisEquidistant::HasSameBinBordersAs
bool HasSameBinBordersAs(const RAxisBase &other) const override
See RAxisBase::HasSameBinBordersAs.
Definition: RAxis.cxx:76
ROOT::Experimental::RAxisBase::const_iterator::operator+=
const_iterator & operator+=(int d) noexcept
Definition: RAxis.hxx:169
double
double
Definition: Converters.cxx:921
ROOT::Experimental::RAxisIrregular::HasSameBinBordersAs
bool HasSameBinBordersAs(const RAxisBase &other) const override
See RAxisBase::HasSameBinBordersAs.
Definition: RAxis.cxx:114
ROOT::Experimental::RAxisIrregular::CanGrow
bool CanGrow() const noexcept final override
This axis cannot be extended.
Definition: RAxis.hxx:703
ROOT::Experimental::RAxisEquidistant::GetInverseBinWidth
double GetInverseBinWidth() const noexcept
Get the inverse of the width of the bins.
Definition: RAxis.hxx:463
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:75
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:457
ROOT::Experimental::RAxisEquidistant::GetInvBinWidth
static double GetInvBinWidth(int nbinsNoOver, double lowOrHigh, double highOrLow)
Determine the inverse bin width.
Definition: RAxis.hxx:394
ROOT::Experimental::RAxisBase
Histogram axis base class.
Definition: RAxis.hxx:44
ROOT::Experimental::RAxisBase::const_iterator::operator<
friend bool operator<(const_iterator lhs, const_iterator rhs) noexcept
i < j
Definition: RAxis.hxx:342
ROOT::Experimental::RAxisBase::GetNBins
int GetNBins() const noexcept
Get the number of bins, including under- and overflow.
Definition: RAxis.hxx:244
ROOT::Experimental::RAxisBase::begin
const_iterator begin() const noexcept
Get a const_iterator pointing to the first regular bin.
Definition: RAxis.hxx:283
ROOT::Experimental::RAxisLabels::kLabelsCmpSubset
@ kLabelsCmpSubset
The other axis doesn't have some labels from this axis.
Definition: RAxis.hxx:802
ROOT::Experimental::RAxisBase::HasSameBinningAs
bool HasSameBinningAs(const RAxisBase &other) const
Check if two axes use the same binning convention, i.e.
Definition: RAxis.cxx:33
ROOT::Experimental::RAxisEquidistant::GetNBinsNoOver
int GetNBinsNoOver() const noexcept final override
Get the number of bins, excluding under- and overflow.
Definition: RAxis.hxx:444
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:812
ROOT::Experimental::RAxisIrregular::GetNBinsNoOver
int GetNBinsNoOver() const noexcept final override
Get the number of bins, excluding under- and overflow.
Definition: RAxis.hxx:667
ROOT::Experimental::RAxisBase::const_iterator::operator-=
const_iterator & operator-=(int d) noexcept
Definition: RAxis.hxx:176
RAxisConfig.hxx
ROOT::Experimental::RAxisBase::GetNBinsNoOver
virtual int GetNBinsNoOver() const noexcept=0
Get the number of bins, excluding under- and overflow.
ROOT::Experimental::Internal::AxisConfigToType< RAxisConfig::kLabels >::operator()
Axis_t operator()(const RAxisConfig &cfg)
Definition: RAxis.hxx:847
ROOT::Experimental::RAxisBase::const_iterator::operator<=
friend bool operator<=(const_iterator lhs, const_iterator rhs) noexcept
i <= j
Definition: RAxis.hxx:354
ROOT::Experimental::RAxisLabels::RAxisLabels
RAxisLabels(const std::vector< std::string > &labels)
Construct a RAxisLables from a vector of strings.
Definition: RAxis.hxx:763
ROOT::Experimental::RAxisEquidistant::fNBinsNoOver
unsigned int fNBinsNoOver
Number of bins excluding under- and overflow.
Definition: RAxis.hxx:388
d
#define d(i)
Definition: RSha256.hxx:102
ROOT::Experimental::RAxisEquidistant::fInvBinWidth
double fInvBinWidth
The inverse of the bin width.
Definition: RAxis.hxx:387
ROOT::Experimental::RAxisBase::const_iterator::operator->
const int * operator->() const noexcept
Definition: RAxis.hxx:215
ROOT::Experimental::RAxisBase::const_iterator::const_iterator
const_iterator()=default
ROOT::Experimental::RAxisBase::operator=
RAxisBase & operator=(const RAxisBase &)=default
ROOT::Experimental::Internal::AxisConfigToType
Converts a RAxisConfig of whatever kind to the corresponding RAxisBase-derived object.
Definition: RAxisConfig.hxx:145
ROOT::Experimental::RAxisBase::const_iterator::operator>
friend bool operator>(const_iterator lhs, const_iterator rhs) noexcept
i > j
Definition: RAxis.hxx:348
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:24
ROOT::Experimental::RAxisBase::RAxisBase
RAxisBase(RAxisBase &&)=default
ROOT::Experimental::RAxisBase::GetUnderflowBin
int GetUnderflowBin() const noexcept
Get the bin index for the underflow bin (or kInvalidBin if CanGrow()).
Definition: RAxis.hxx:257
ROOT::Experimental::RAxisEquidistant::RAxisEquidistant
RAxisEquidistant(int nbinsNoOver, double low, double high) noexcept
Initialize a RAxisEquidistant.
Definition: RAxis.hxx:436
ROOT::Experimental::RAxisIrregular::RAxisIrregular
RAxisIrregular(std::vector< double > &&binborders) noexcept
Construct a RAxisIrregular from a vector of bin borders.
Definition: RAxis.hxx:630
ROOT::Experimental::RAxisBase::GetMaximum
double GetMaximum() const
Get the high end of the axis range.
Definition: RAxis.hxx:314
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:672
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
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Definition: EExecutionPolicy.hxx:4
ROOT::Experimental::RAxisEquidistant::RAxisEquidistant
RAxisEquidistant()=default
ROOT::Experimental::RAxisBase::const_iterator::operator++
const_iterator operator++(int) noexcept
i++
Definition: RAxis.hxx:153
ROOT::Experimental::RAxisLabels::GetBinCenterByName
double GetBinCenterByName(const std::string &label)
Get the center of the bin with label.
Definition: RAxis.hxx:782
ROOT::Experimental::Internal::AxisConfigToType< RAxisConfig::kEquidistant >::operator()
Axis_t operator()(const RAxisConfig &cfg) noexcept
Definition: RAxis.hxx:492
ROOT::Experimental::RAxisBase::const_iterator::operator--
const_iterator operator--(int) noexcept
Definition: RAxis.hxx:161
ROOT::Experimental::operator>
bool operator>(RAxisBase::const_iterator lhs, RAxisBase::const_iterator rhs) noexcept
i > j
Definition: RAxis.hxx:348
ROOT::Experimental::RAxisGrow::CanGrow
bool CanGrow() const noexcept final override
This axis kind can increase its range.
Definition: RAxis.hxx:561
ROOT::Experimental::RAxisEquidistant::GetBinFrom
double GetBinFrom(int bin) const final override
Get the low bin border for the given bin index.
Definition: RAxis.hxx:475