Skip to content

Commit

Permalink
Updating boost.histogram (#333)
Browse files Browse the repository at this point in the history
* updating boost.histogram

* adding crop
  • Loading branch information
HDembinski authored Mar 11, 2020
1 parent 6071588 commit 913a34b
Show file tree
Hide file tree
Showing 4 changed files with 266 additions and 80 deletions.
19 changes: 15 additions & 4 deletions src/boost_histogram/cpp/algorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,37 @@

__all__ = (
"shrink_and_rebin",
"shrink",
"crop_and_rebin",
"slice_and_rebin",
"rebin",
"shrink",
"crop",
"slice",
"slice_mode",
"sum",
"reduce",
"empty",
"reduce",
"project",
)

from .._core.algorithm import shrink_and_rebin, slice_and_rebin, rebin, shrink, slice
from .._core.algorithm import (
shrink_and_rebin,
crop_and_rebin,
slice_and_rebin,
rebin,
shrink,
crop,
slice,
slice_mode,
)

shrink_and_rebin.__module__ = "boost_histogram.cpp"
crop_and_rebin.__module__ = "boost_histogram.cpp"
slice_and_rebin.__module__ = "boost_histogram.cpp"
rebin.__module__ = "boost_histogram.cpp"
shrink.__module__ = "boost_histogram.cpp"
crop.__module__ = "boost_histogram.cpp"
slice.__module__ = "boost_histogram.cpp"


Expand All @@ -44,7 +57,6 @@ def reduce(histogram, *args):
"""
Reduce based on one or more reduce_option's.
"""

return histogram._reduce(*args)


Expand All @@ -54,5 +66,4 @@ def project(histogram, *args):
Provided a list of axis numbers, this will produce the histogram over those
axes only. Flow bins are used if available.
"""

return histogram._project(*args)
211 changes: 152 additions & 59 deletions src/register_algorithm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,46 +9,48 @@

void register_algorithms(py::module& algorithm) {
py::class_<bh::algorithm::reduce_command>(algorithm, "reduce_command")
.def(py::init<bh::algorithm::reduce_command>())
.def("__repr__", [](const bh::algorithm::reduce_command& self) {
using state_t = bh::algorithm::reduce_command::state_t;

const char* postfix
= (self.state == state_t::rebin || self.merge <= 1) ? "" : "_and_rebin";
const char* start = self.iaxis == bh::algorithm::reduce_command::unset
? ""
: "iaxis={0}, ";
const char* merge = (self.state == state_t::rebin || self.merge <= 1)
? ""
: ", merge={3}";

std::string name;
py::str result;

switch(self.state) {
case state_t::slice:
name = std::string("slice") + postfix + "(" + start
+ "begin={1}, end={2}" + merge + ")";
result = py::str(name).format(
self.iaxis, self.begin.index, self.end.index, self.merge);
break;
case state_t::shrink:
name = std::string("shink") + postfix + "(" + start
+ "lower={1}, upper={2}" + merge + ")";
result = py::str(name).format(
self.iaxis, self.begin.value, self.end.value, self.merge);
break;
case state_t::rebin:
name = std::string("rebin") + postfix + "(" + start + "merge={1})";
result = py::str(name).format(self.iaxis, self.merge);
break;
using range_t = bh::algorithm::reduce_command::range_t;

if(self.range != range_t::none) {
const char* suffix = self.merge > 0 ? "_and_rebin" : "";
const char* start = self.iaxis == bh::algorithm::reduce_command::unset
? ""
: "iaxis={0}, ";
const char* merge = self.merge > 0 ? ", merge={3}" : "";

if(self.range == range_t::indices) {
return py::str("reduce_command(slice{0}({1}, begin={2}, "
"end={3}{4}, mode={5}))")
.format(suffix,
start,
self.begin.index,
self.end.index,
merge,
self.crop);
} else {
return py::
str("reduce_command(shrink{0}({1}, lower={2}, upper={3}{4}))")
.format(
suffix, start, self.begin.value, self.end.value, merge);
}
}

return result;
// self.range == range_t::none
return py::str("reduce_command(merge({0}))").format(self.merge);
});

py::class_<bh::algorithm::shrink_and_rebin, bh::algorithm::reduce_command>(
algorithm, "shrink_and_rebin")
.def(py::init<unsigned, double, double, unsigned>(),
using slice_mode = bh::algorithm::slice_mode;

py::enum_<slice_mode>(algorithm, "slice_mode")
.value("shrink", slice_mode::shrink)
.value("crop", slice_mode::crop);

algorithm
.def("shrink_and_rebin",
py::overload_cast<unsigned, double, double, unsigned>(
&bh::algorithm::shrink_and_rebin),
"iaxis"_a,
"lower"_a,
"upper"_a,
Expand All @@ -65,21 +67,74 @@ void register_algorithms(py::module& algorithm) {
"bin interval, the whole "
"interval is removed.\n"
":param merge: how many adjacent bins to merge into one.")
.def(py::init<double, double, unsigned>(),
.def("shrink_and_rebin",
py::overload_cast<double, double, unsigned>(
&bh::algorithm::shrink_and_rebin),
"lower"_a,
"upper"_a,
"merge"_a,
"Shortcut form of shrink_and_reduce")

;
"Positional shrink and rebin option to be used in reduce().\n"
"\n"
"To shrink and rebin in one command. Equivalent to passing both the "
"shrink() and the\n"
"rebin() option for the same axis to reduce.\n"
"\n"
":param iaxis: which axis to operate on.\n"
":param lower: lowest bound that should be kept.\n"
":param upper: highest bound that should be kept. If upper is inside "
"bin interval, the whole "
"interval is removed.\n"
":param merge: how many adjacent bins to merge into one.")

py::class_<bh::algorithm::slice_and_rebin, bh::algorithm::reduce_command>(
algorithm, "slice_and_rebin")
.def(py::init<unsigned, bh::axis::index_type, bh::axis::index_type, unsigned>(),
.def("crop_and_rebin",
py::overload_cast<unsigned, double, double, unsigned>(
&bh::algorithm::crop_and_rebin),
"iaxis"_a,
"lower"_a,
"upper"_a,
"merge"_a,
"Crop and rebin option to be used in reduce().\n"
"\n"
"To crop and rebin in one command. Equivalent to passing both the "
"crop and the\n"
"rebin option for the same axis to reduce.\n"
"\n"
":param iaxis: which axis to operate on.\n"
":param lower: lowest bound that should be kept.\n"
":param upper: highest bound that should be kept. If upper is inside "
"bin interval, the whole "
"interval is removed.\n"
":param merge: how many adjacent bins to merge into one.")
.def(
"crop_and_rebin",
py::overload_cast<double, double, unsigned>(&bh::algorithm::crop_and_rebin),
"lower"_a,
"upper"_a,
"merge"_a,
"Positional crop and rebin option to be used in reduce().\n"
"\n"
"To crop and rebin in one command. Equivalent to passing both the "
"crop and the\n"
"rebin option for the same axis to reduce.\n"
"\n"
":param iaxis: which axis to operate on.\n"
":param lower: lowest bound that should be kept.\n"
":param upper: highest bound that should be kept. If upper is inside "
"bin interval, the whole "
"interval is removed.\n"
":param merge: how many adjacent bins to merge into one.")

.def("slice_and_rebin",
py::overload_cast<unsigned,
bh::axis::index_type,
bh::axis::index_type,
unsigned,
slice_mode>(&bh::algorithm::slice_and_rebin),
"iaxis"_a,
"begin"_a,
"end"_a,
"merge"_a,
"mode"_a = slice_mode::shrink,
"Slice and rebin option to be used in reduce().\n"
"\n"
"To slice and rebin in one command. Equivalent to passing both the "
Expand All @@ -89,32 +144,70 @@ void register_algorithms(py::module& algorithm) {
":param iaxis: which axis to operate on.\n"
":param begin: first index that should be kept.\n"
":param end: one past the last index that should be kept.\n"
":param merge: how many adjacent bins to merge into one.")
.def(py::init<bh::axis::index_type, bh::axis::index_type, unsigned>(),
":param merge: how many adjacent bins to merge into one.\n"
":param mode: see slice_mode")
.def("slice_and_rebin",
py::overload_cast<bh::axis::index_type,
bh::axis::index_type,
unsigned,
slice_mode>(&bh::algorithm::slice_and_rebin),
"begin"_a,
"end"_a,
"merge"_a,
"Shortcut form of slice_and_rebin.");

py::class_<bh::algorithm::rebin, bh::algorithm::reduce_command>(algorithm, "rebin")
.def(py::init<unsigned, unsigned>(), "iaxis"_a, "merge"_a)
.def(py::init<unsigned>(), "merge"_a)
"mode"_a = slice_mode::shrink,
"Positional slice and rebin option to be used in reduce().\n"
"\n"
"To slice and rebin in one command. Equivalent to passing both the "
"slice() and the\n"
"rebin() option for the same axis to reduce.\n"
"\n"
":param iaxis: which axis to operate on.\n"
":param begin: first index that should be kept.\n"
":param end: one past the last index that should be kept.\n"
":param merge: how many adjacent bins to merge into one.\n"
":param mode: see slice_mode")

;
.def("rebin",
py::overload_cast<unsigned, unsigned>(&bh::algorithm::rebin),
"iaxis"_a,
"merge"_a)
.def("rebin", py::overload_cast<unsigned>(&bh::algorithm::rebin), "merge"_a)

py::class_<bh::algorithm::shrink, bh::algorithm::reduce_command>(algorithm,
"shrink")
.def(py::init<unsigned, double, double>(), "iaxis"_a, "lower"_a, "upper"_a)
.def(py::init<double, double>(), "lower"_a, "upper"_a)
.def("shrink",
py::overload_cast<unsigned, double, double>(&bh::algorithm::shrink),
"iaxis"_a,
"lower"_a,
"upper"_a)
.def("shrink",
py::overload_cast<double, double>(&bh::algorithm::shrink),
"lower"_a,
"upper"_a)

;
.def("crop",
py::overload_cast<unsigned, double, double>(&bh::algorithm::crop),
"iaxis"_a,
"lower"_a,
"upper"_a)
.def("crop",
py::overload_cast<double, double>(&bh::algorithm::crop),
"lower"_a,
"upper"_a)

py::class_<bh::algorithm::slice, bh::algorithm::reduce_command>(algorithm, "slice")
.def(py::init<unsigned, bh::axis::index_type, bh::axis::index_type>(),
.def("slice",
py::overload_cast<unsigned,
bh::axis::index_type,
bh::axis::index_type,
slice_mode>(&bh::algorithm::slice),
"iaxis"_a,
"begin"_a,
"end"_a)
.def(py::init<bh::axis::index_type, bh::axis::index_type>(), "begin"_a, "end"_a)
"end"_a,
"mode"_a = slice_mode::shrink)
.def("slice",
py::overload_cast<bh::axis::index_type, bh::axis::index_type, slice_mode>(
&bh::algorithm::slice),
"begin"_a,
"end"_a,
"mode"_a = slice_mode::shrink)

;
}
Loading

0 comments on commit 913a34b

Please sign in to comment.