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