Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RRegularAxis.hxx
Go to the documentation of this file.
1/// \file
2/// \warning This is part of the %ROOT 7 prototype! It will change without notice. It might trigger earthquakes.
3/// Feedback is welcome!
4
5#ifndef ROOT_RRegularAxis
6#define ROOT_RRegularAxis
7
8#include "RBinIndex.hxx"
9#include "RBinIndexRange.hxx"
10#include "RLinearizedIndex.hxx"
11
12#include <cassert>
13#include <cmath>
14#include <cstdint>
15#include <stdexcept>
16#include <string>
17#include <utility>
18
19class TBuffer;
20
21namespace ROOT {
22namespace Experimental {
23
24/**
25A regular axis with equidistant bins in the interval \f$[fLow, fHigh)\f$.
26
27For example, the following creates a regular axis with 10 normal bins between 5 and 15:
28\code
29ROOT::Experimental::RRegularAxis axis(10, {5, 15});
30\endcode
31
32It is possible to disable underflow and overflow bins by passing `enableFlowBins = false`. In that case, arguments
33outside the axis will be silently discarded.
34
35\warning This is part of the %ROOT 7 prototype! It will change without notice. It might trigger earthquakes.
36Feedback is welcome!
37*/
39public:
41
42private:
43 /// The number of normal bins
44 std::uint64_t fNNormalBins;
45 /// The lower end of the axis interval
46 double fLow;
47 /// The upper end of the axis interval
48 double fHigh;
49 /// The cached inverse of the bin width to speed up ComputeLinearizedIndex
50 double fInvBinWidth; //!
51 /// Whether underflow and overflow bins are enabled
53
54public:
55 /// Construct a regular axis object.
56 ///
57 /// \param[in] nNormalBins the number of normal bins, must be > 0
58 /// \param[in] interval the axis interval (lower end inclusive, upper end exclusive), must be finite
59 /// \param[in] enableFlowBins whether to enable underflow and overflow bins
60 RRegularAxis(std::uint64_t nNormalBins, std::pair<double, double> interval, bool enableFlowBins = true)
62 {
63 if (nNormalBins == 0) {
64 throw std::invalid_argument("nNormalBins must be > 0");
65 }
66 if (!std::isfinite(fLow)) {
67 throw std::invalid_argument("low must be a finite value, but is " + std::to_string(fLow));
68 }
69 if (!std::isfinite(fHigh)) {
70 throw std::invalid_argument("high must be a finite value, but is " + std::to_string(fHigh));
71 }
72 if (fLow >= fHigh) {
73 std::string msg = "high must be > low, but " + std::to_string(fLow) + " >= " + std::to_string(fHigh);
74 throw std::invalid_argument(msg);
75 }
77 assert(std::isfinite(fInvBinWidth));
78 }
79
80 std::uint64_t GetNNormalBins() const { return fNNormalBins; }
81 std::uint64_t GetTotalNBins() const { return fEnableFlowBins ? fNNormalBins + 2 : fNNormalBins; }
82 double GetLow() const { return fLow; }
83 double GetHigh() const { return fHigh; }
84 bool HasFlowBins() const { return fEnableFlowBins; }
85
86 friend bool operator==(const RRegularAxis &lhs, const RRegularAxis &rhs)
87 {
88 return lhs.fNNormalBins == rhs.fNNormalBins && lhs.fLow == rhs.fLow && lhs.fHigh == rhs.fHigh &&
89 lhs.fEnableFlowBins == rhs.fEnableFlowBins;
90 }
91
92 /// Compute the linarized index for a single argument.
93 ///
94 /// If flow bins are disabled, the normal bins have indices \f$0\f$ to \f$fNNormalBins - 1\f$. Otherwise the
95 /// underflow bin has index \f$0\$, the indices of all normal bins shift by one, and the overflow bin has index
96 /// \f$fNNormalBins + 1\f$. If the argument is outside the interval \f$[fLow, fHigh)\f$ and the flow bins are
97 /// disabled, the return value is invalid.
98 ///
99 /// \param[in] x the argument
100 /// \return the linearized index that may be invalid
101 RLinearizedIndex ComputeLinearizedIndex(double x) const
102 {
103 bool underflow = x < fLow;
104 // Put NaNs into overflow bin.
105 bool overflow = !(x < fHigh);
106 if (underflow) {
107 return {0, fEnableFlowBins};
108 } else if (overflow) {
109 return {fNNormalBins + 1, fEnableFlowBins};
110 }
111
112 std::uint64_t bin = (x - fLow) * fInvBinWidth;
113 if (bin >= fNNormalBins) {
114 bin = fNNormalBins - 1;
115 }
116 // If the underflow bin is enabled, shift the normal bins by one.
117 if (fEnableFlowBins) {
118 bin += 1;
119 }
120 return {bin, true};
121 }
122
123 /// Get the linearized index for an RBinIndex.
124 ///
125 /// If flow bins are disabled, the normal bins have indices \f$0\f$ to \f$fNNormalBins - 1\f$. Otherwise the
126 /// underflow bin has index \f$0\$, the indices of all normal bins shift by one, and the overflow bin has index
127 /// \f$fNNormalBins + 1\f$.
128 ///
129 /// \param[in] index the RBinIndex
130 /// \return the linearized index that may be invalid
132 {
133 if (index.IsUnderflow()) {
134 return {0, fEnableFlowBins};
135 } else if (index.IsOverflow()) {
136 return {fNNormalBins + 1, fEnableFlowBins};
137 } else if (index.IsInvalid()) {
138 return {0, false};
139 }
140 assert(index.IsNormal());
141 std::uint64_t bin = index.GetIndex();
142 if (bin >= fNNormalBins) {
143 // Index is out of range and invalid.
144 return {bin, false};
145 }
146 // If the underflow bin is enabled, shift the normal bins by one.
147 if (fEnableFlowBins) {
148 bin += 1;
149 }
150 return {bin, true};
151 }
152
153 /// Get the range of all normal bins.
154 ///
155 /// \return the bin index range from the first to the last normal bin, inclusive
160
161 /// Get a range of normal bins.
162 ///
163 /// \param[in] begin the begin of the bin index range (inclusive), must be normal
164 /// \param[in] end the end of the bin index range (exclusive), must be normal and >= begin
165 /// \return a bin index range \f$[begin, end)\f$
167 {
168 if (!begin.IsNormal()) {
169 throw std::invalid_argument("begin must be a normal bin");
170 }
171 if (begin.GetIndex() >= fNNormalBins) {
172 throw std::invalid_argument("begin must be inside the axis");
173 }
174 if (!end.IsNormal()) {
175 throw std::invalid_argument("end must be a normal bin");
176 }
177 if (end.GetIndex() > fNNormalBins) {
178 throw std::invalid_argument("end must be inside or past the axis");
179 }
180 if (!(end >= begin)) {
181 throw std::invalid_argument("end must be >= begin");
182 }
183 return Internal::CreateBinIndexRange(begin, end, 0);
184 }
185
186 /// Get the full range of all bins.
187 ///
188 /// This includes underflow and overflow bins, if enabled.
189 ///
190 /// \return the bin index range of all bins
196
197 /// %ROOT Streamer function to throw when trying to store an object of this class.
198 void Streamer(TBuffer &) { throw std::runtime_error("unable to store RRegularAxis"); }
199};
200
201} // namespace Experimental
202} // namespace ROOT
203
204#endif
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
A bin index with special values for underflow and overflow bins.
Definition RBinIndex.hxx:23
bool IsNormal() const
A bin index is normal iff it is not one of the special values.
Definition RBinIndex.hxx:80
std::uint64_t GetIndex() const
Return the index for a normal bin.
Definition RBinIndex.hxx:71
static RBinIndex Underflow()
A regular axis with equidistant bins in the interval .
std::uint64_t GetTotalNBins() const
RBinIndexRange GetNormalRange(RBinIndex begin, RBinIndex end) const
Get a range of normal bins.
bool fEnableFlowBins
Whether underflow and overflow bins are enabled.
friend bool operator==(const RRegularAxis &lhs, const RRegularAxis &rhs)
RBinIndexRange GetFullRange() const
Get the full range of all bins.
double fInvBinWidth
The cached inverse of the bin width to speed up ComputeLinearizedIndex.
RRegularAxis(std::uint64_t nNormalBins, std::pair< double, double > interval, bool enableFlowBins=true)
Construct a regular axis object.
std::uint64_t fNNormalBins
The number of normal bins.
double fLow
The lower end of the axis interval.
RBinIndexRange GetNormalRange() const
Get the range of all normal bins.
void Streamer(TBuffer &)
ROOT Streamer function to throw when trying to store an object of this class.
double fHigh
The upper end of the axis interval.
RLinearizedIndex GetLinearizedIndex(RBinIndex index) const
Compute the linarized index for a single argument.
std::uint64_t GetNNormalBins() const
Buffer base class used for serializing objects.
Definition TBuffer.h:43
Double_t x[n]
Definition legend1.C:17
static RBinIndexRange CreateBinIndexRange(RBinIndex begin, RBinIndex end, std::uint64_t nNormalBins)
Internal function to create RBinIndexRange.
A linearized index that can be invalid.