Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions hist/histv7/inc/ROOT/RHist.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,35 @@ public:
/// \param[in] axes the axis objects, must have size > 0
explicit RHist(std::vector<RAxisVariant> axes) : fEngine(std::move(axes)), fStats(fEngine.GetNDimensions()) {}

/// Construct a one-dimensional histogram engine with a regular axis.
/// Construct a histogram.
///
/// Note that there is no perfect forwarding of the axis objects. If that is needed, use the
/// \ref RHist(std::vector<RAxisVariant> axes) "overload accepting a std::vector".
///
/// \param[in] axes the axis objects, must have size > 0
explicit RHist(std::initializer_list<RAxisVariant> axes) : RHist(std::vector(axes)) {}

/// Construct a histogram.
///
/// Note that there is no perfect forwarding of the axis objects. If that is needed, use the
/// \ref RHist(std::vector<RAxisVariant> axes) "overload accepting a std::vector".
///
/// \param[in] axis1 the first axis object
/// \param[in] axes the remaining axis objects
template <typename... Axes>
explicit RHist(const RAxisVariant &axis1, const Axes &...axes) : RHist(std::vector<RAxisVariant>{axis1, axes...})
{
}

/// Construct a one-dimensional histogram with a regular axis.
///
/// \param[in] nNormalBins the number of normal bins, must be > 0
/// \param[in] interval the axis interval (lower end inclusive, upper end exclusive)
/// \par See also
/// the \ref RRegularAxis::RRegularAxis(std::uint64_t nNormalBins, std::pair<double, double> interval, bool
/// enableFlowBins) "constructor of RRegularAxis"
RHist(std::uint64_t nNormalBins, std::pair<double, double> interval) : RHist({RRegularAxis(nNormalBins, interval)})
RHist(std::uint64_t nNormalBins, std::pair<double, double> interval)
: RHist(std::vector<RAxisVariant>{RRegularAxis(nNormalBins, interval)})
{
}

Expand Down
23 changes: 22 additions & 1 deletion hist/histv7/inc/ROOT/RHistEngine.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,27 @@ public:
fBinContents.resize(fAxes.ComputeTotalNBins());
}

/// Construct a histogram engine.
///
/// Note that there is no perfect forwarding of the axis objects. If that is needed, use the
/// \ref RHistEngine(std::vector<RAxisVariant> axes) "overload accepting a std::vector".
///
/// \param[in] axes the axis objects, must have size > 0
explicit RHistEngine(std::initializer_list<RAxisVariant> axes) : RHistEngine(std::vector(axes)) {}

/// Construct a histogram engine.
///
/// Note that there is no perfect forwarding of the axis objects. If that is needed, use the
/// \ref RHistEngine(std::vector<RAxisVariant> axes) "overload accepting a std::vector".
///
/// \param[in] axis1 the first axis object
/// \param[in] axes the remaining axis objects
template <typename... Axes>
explicit RHistEngine(const RAxisVariant &axis1, const Axes &...axes)
: RHistEngine(std::vector<RAxisVariant>{axis1, axes...})
{
}

/// Construct a one-dimensional histogram engine with a regular axis.
///
/// \param[in] nNormalBins the number of normal bins, must be > 0
Expand All @@ -92,7 +113,7 @@ public:
/// the \ref RRegularAxis::RRegularAxis(std::uint64_t nNormalBins, std::pair<double, double> interval, bool
/// enableFlowBins) "constructor of RRegularAxis"
RHistEngine(std::uint64_t nNormalBins, std::pair<double, double> interval)
: RHistEngine({RRegularAxis(nNormalBins, interval)})
: RHistEngine(std::vector<RAxisVariant>{RRegularAxis(nNormalBins, interval)})
{
}

Expand Down
45 changes: 34 additions & 11 deletions hist/histv7/test/hist_engine.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <array>
#include <stdexcept>
#include <type_traits>
#include <utility>
#include <variant>
#include <vector>

Expand All @@ -23,27 +24,49 @@ TEST(RHistEngine, Constructor)
const std::vector<std::string> categories = {"a", "b", "c"};
const RCategoricalAxis categoricalAxis(categories);

RHistEngine<int> engine({regularAxis, variableBinAxis, categoricalAxis});
// The most generic constructor takes a vector of axis objects.
const std::vector<RAxisVariant> axes = {regularAxis, variableBinAxis, categoricalAxis};
RHistEngine<int> engine(axes);
EXPECT_EQ(engine.GetNDimensions(), 3);
const auto &axes = engine.GetAxes();
ASSERT_EQ(axes.size(), 3);
EXPECT_EQ(axes[0].index(), 0);
EXPECT_EQ(axes[1].index(), 1);
EXPECT_EQ(axes[2].index(), 2);
EXPECT_TRUE(std::get_if<RRegularAxis>(&axes[0]) != nullptr);
EXPECT_TRUE(std::get_if<RVariableBinAxis>(&axes[1]) != nullptr);
EXPECT_TRUE(std::get_if<RCategoricalAxis>(&axes[2]) != nullptr);

// Both axes include underflow and overflow bins.
{
const auto &engineAxes = engine.GetAxes();
ASSERT_EQ(engineAxes.size(), 3);
EXPECT_EQ(engineAxes[0].index(), 0);
EXPECT_EQ(engineAxes[1].index(), 1);
EXPECT_EQ(engineAxes[2].index(), 2);
EXPECT_TRUE(std::get_if<RRegularAxis>(&engineAxes[0]) != nullptr);
EXPECT_TRUE(std::get_if<RVariableBinAxis>(&engineAxes[1]) != nullptr);
EXPECT_TRUE(std::get_if<RCategoricalAxis>(&engineAxes[2]) != nullptr);
}

// All axes include underflow and overflow bins.
EXPECT_EQ(engine.GetTotalNBins(), (BinsX + 2) * (BinsY + 2) * (categories.size() + 1));

// Test other constructors, including move-assignment.
engine = RHistEngine<int>(BinsX, {0, BinsX});
ASSERT_EQ(engine.GetNDimensions(), 1);
auto *regular = std::get_if<RRegularAxis>(&engine.GetAxes()[0]);
ASSERT_TRUE(regular != nullptr);
EXPECT_EQ(regular->GetNNormalBins(), BinsX);
EXPECT_EQ(regular->GetLow(), 0);
EXPECT_EQ(regular->GetHigh(), BinsX);
// std::make_pair will take the types of the arguments, std::size_t in this case.
engine = RHistEngine<int>(BinsX, std::make_pair(0, BinsX));
EXPECT_EQ(engine.GetNDimensions(), 1);

// Brace-enclosed initializer list
engine = RHistEngine<int>({variableBinAxis});
EXPECT_EQ(engine.GetNDimensions(), 1);
engine = RHistEngine<int>({variableBinAxis, categoricalAxis});
EXPECT_EQ(engine.GetNDimensions(), 2);

// Templated constructors
engine = RHistEngine<int>(variableBinAxis);
EXPECT_EQ(engine.GetNDimensions(), 1);
engine = RHistEngine<int>(variableBinAxis, categoricalAxis);
EXPECT_EQ(engine.GetNDimensions(), 2);
engine = RHistEngine<int>(variableBinAxis, categoricalAxis, regularAxis);
EXPECT_EQ(engine.GetNDimensions(), 3);
}

TEST(RHistEngine, GetBinContentInvalidNumberOfArguments)
Expand Down
22 changes: 21 additions & 1 deletion hist/histv7/test/hist_hist.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ TEST(RHist, Constructor)
static constexpr std::size_t Bins = 20;
const RRegularAxis regularAxis(Bins, {0, Bins});

RHist<int> hist({regularAxis, regularAxis});
// The most generic constructor takes a vector of axis objects.
const std::vector<RAxisVariant> axes = {regularAxis, regularAxis};
RHist<int> hist(axes);
EXPECT_EQ(hist.GetNDimensions(), 2);
const auto &engine = hist.GetEngine();
EXPECT_EQ(engine.GetNDimensions(), 2);
Expand All @@ -26,13 +28,31 @@ TEST(RHist, Constructor)
// Both axes include underflow and overflow bins.
EXPECT_EQ(hist.GetTotalNBins(), (Bins + 2) * (Bins + 2));

// Test other constructors, including move-assignment.
hist = RHist<int>(Bins, {0, Bins});
ASSERT_EQ(hist.GetNDimensions(), 1);
auto *regular = std::get_if<RRegularAxis>(&hist.GetAxes()[0]);
ASSERT_TRUE(regular != nullptr);
EXPECT_EQ(regular->GetNNormalBins(), Bins);
EXPECT_EQ(regular->GetLow(), 0);
EXPECT_EQ(regular->GetHigh(), Bins);
// std::make_pair will take the types of the arguments, std::size_t in this case.
hist = RHist<int>(Bins, std::make_pair(0, Bins));
EXPECT_EQ(hist.GetNDimensions(), 1);

// Brace-enclosed initializer list
hist = RHist<int>({regularAxis});
EXPECT_EQ(hist.GetNDimensions(), 1);
hist = RHist<int>({regularAxis, regularAxis});
EXPECT_EQ(hist.GetNDimensions(), 2);

// Templated constructors
hist = RHist<int>(regularAxis);
EXPECT_EQ(hist.GetNDimensions(), 1);
hist = RHist<int>(regularAxis, regularAxis);
EXPECT_EQ(hist.GetNDimensions(), 2);
hist = RHist<int>(regularAxis, regularAxis, regularAxis);
EXPECT_EQ(hist.GetNDimensions(), 3);
}

TEST(RHist, Add)
Expand Down
Loading