ROOT   Reference Guide
RAxis.cxx
Go to the documentation of this file.
1/// \file RAxis.cxx
2/// \ingroup Hist ROOT7
3/// \author Axel Naumann <axel@cern.ch>
4/// \date 2015-08-06
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/*************************************************************************
11 * *
12 * For the licensing terms see $ROOTSYS/LICENSE. * 13 * For the list of contributors see$ROOTSYS/README/CREDITS. *
14 *************************************************************************/
15
16#include "ROOT/RAxis.hxx"
17
18#include <cmath>
19
21
22/// If the coordinate x is a bin low edge (within 1E-6 of the coordinate),
23/// return the bin for which this is a low edge. If it's not a bin edge, return
24/// -1.
26{
27 // fracBinIdx is the fractional bin index of x in this axis. It's (close to)
28 // an integer if it's an axis border.
29 double fracBinIdx = (x - GetMinimum()) * fInvBinWidth;
30 // fracBinIdx might be 12.99999999. It's a bin border if the deviation from
31 // an actual bin border is "fairly small".
32 int binIdx = std::round(fracBinIdx + 0.5);
33 double binOffset = fracBinIdx - binIdx;
34 if (std::fabs(binOffset) > x * 1E-6)
35 return -1;
36
37 // If the bin index is below the first bin (i.e. x is the lower edge of the
38 // underflow bin) then it's out of range.
39 if (IsUnderflowBin(binIdx))
40 return -1;
41 // If x is the lower edge of the overflow bin then that's still okay - but if
42 // even the bin before binIdx is an overflow it's out of range.
43 if (IsOverflowBin(binIdx - 1))
44 return -1;
45
46 return binIdx;
47}
48
49/// Whether (and how) the source axis can be merged into the target axis.
51 RAxisEquidistant &source) noexcept
52{
53 if (source == target)
54 return EAxisCompatibility::kIdentical;
55
56 int idxTargetLow = target.GetBinIndexForLowEdge(source.GetMinimum());
57 int idxTargetHigh = target.GetBinIndexForLowEdge(source.GetMaximum());
58 if (idxTargetLow < 0 || idxTargetHigh < 0)
59 return EAxisCompatibility::kIncompatible;
60
61 // If both low and high exist in both axes and the bin width is identical then
62 // one axis contains the other.
63 if (source.GetInverseBinWidth() == target.GetInverseBinWidth())
64 return EAxisCompatibility::kContains;
65
66 // Now we are left with the case
67 // source: 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6
68 // target: ...0.0, 0.3, 0.6...
69 // The question is: is the ratio of the bin width identical to the ratio of
70 // the number of bin?
71 if (std::fabs(target.GetInverseBinWidth() * source.GetNBinsNoOver() -
72 source.GetInverseBinWidth() * (idxTargetHigh - idxTargetLow)) > 1E-6 * target.GetInverseBinWidth())
73 return EAxisCompatibility::kIncompatible;
74
75 // source is a fine-grained version of target.
76 return EAxisCompatibility::kSampling;
77}
78
79// RODO: the other CanMap() overloads
static constexpr const int kNOverflowBins[4]
Extra bins for each EAxisOverflow value.
Definition: RAxis.hxx:181
Axis with equidistant bin borders.
Definition: RAxis.hxx:403
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_t x[n]
Definition: legend1.C:17
EAxisCompatibility CanMap(RAxisEquidistant &target, RAxisEquidistant &source) noexcept
Whether (and how) the source axis can be merged into the target axis.
Definition: RAxis.cxx:50
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
constexpr Double_t E()
Base of natural log:
Definition: TMath.h:97