Skip to content

Commit 913a34b

Browse files
authored
Updating boost.histogram (#333)
* updating boost.histogram * adding crop
1 parent 6071588 commit 913a34b

File tree

4 files changed

+266
-80
lines changed

4 files changed

+266
-80
lines changed

src/boost_histogram/cpp/algorithm.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,37 @@
44

55
__all__ = (
66
"shrink_and_rebin",
7-
"shrink",
7+
"crop_and_rebin",
88
"slice_and_rebin",
99
"rebin",
1010
"shrink",
11+
"crop",
1112
"slice",
13+
"slice_mode",
1214
"sum",
1315
"reduce",
1416
"empty",
1517
"reduce",
1618
"project",
1719
)
1820

19-
from .._core.algorithm import shrink_and_rebin, slice_and_rebin, rebin, shrink, slice
21+
from .._core.algorithm import (
22+
shrink_and_rebin,
23+
crop_and_rebin,
24+
slice_and_rebin,
25+
rebin,
26+
shrink,
27+
crop,
28+
slice,
29+
slice_mode,
30+
)
2031

2132
shrink_and_rebin.__module__ = "boost_histogram.cpp"
33+
crop_and_rebin.__module__ = "boost_histogram.cpp"
2234
slice_and_rebin.__module__ = "boost_histogram.cpp"
2335
rebin.__module__ = "boost_histogram.cpp"
2436
shrink.__module__ = "boost_histogram.cpp"
37+
crop.__module__ = "boost_histogram.cpp"
2538
slice.__module__ = "boost_histogram.cpp"
2639

2740

@@ -44,7 +57,6 @@ def reduce(histogram, *args):
4457
"""
4558
Reduce based on one or more reduce_option's.
4659
"""
47-
4860
return histogram._reduce(*args)
4961

5062

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

src/register_algorithm.cpp

Lines changed: 152 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -9,46 +9,48 @@
99

1010
void register_algorithms(py::module& algorithm) {
1111
py::class_<bh::algorithm::reduce_command>(algorithm, "reduce_command")
12+
.def(py::init<bh::algorithm::reduce_command>())
1213
.def("__repr__", [](const bh::algorithm::reduce_command& self) {
13-
using state_t = bh::algorithm::reduce_command::state_t;
14-
15-
const char* postfix
16-
= (self.state == state_t::rebin || self.merge <= 1) ? "" : "_and_rebin";
17-
const char* start = self.iaxis == bh::algorithm::reduce_command::unset
18-
? ""
19-
: "iaxis={0}, ";
20-
const char* merge = (self.state == state_t::rebin || self.merge <= 1)
21-
? ""
22-
: ", merge={3}";
23-
24-
std::string name;
25-
py::str result;
26-
27-
switch(self.state) {
28-
case state_t::slice:
29-
name = std::string("slice") + postfix + "(" + start
30-
+ "begin={1}, end={2}" + merge + ")";
31-
result = py::str(name).format(
32-
self.iaxis, self.begin.index, self.end.index, self.merge);
33-
break;
34-
case state_t::shrink:
35-
name = std::string("shink") + postfix + "(" + start
36-
+ "lower={1}, upper={2}" + merge + ")";
37-
result = py::str(name).format(
38-
self.iaxis, self.begin.value, self.end.value, self.merge);
39-
break;
40-
case state_t::rebin:
41-
name = std::string("rebin") + postfix + "(" + start + "merge={1})";
42-
result = py::str(name).format(self.iaxis, self.merge);
43-
break;
14+
using range_t = bh::algorithm::reduce_command::range_t;
15+
16+
if(self.range != range_t::none) {
17+
const char* suffix = self.merge > 0 ? "_and_rebin" : "";
18+
const char* start = self.iaxis == bh::algorithm::reduce_command::unset
19+
? ""
20+
: "iaxis={0}, ";
21+
const char* merge = self.merge > 0 ? ", merge={3}" : "";
22+
23+
if(self.range == range_t::indices) {
24+
return py::str("reduce_command(slice{0}({1}, begin={2}, "
25+
"end={3}{4}, mode={5}))")
26+
.format(suffix,
27+
start,
28+
self.begin.index,
29+
self.end.index,
30+
merge,
31+
self.crop);
32+
} else {
33+
return py::
34+
str("reduce_command(shrink{0}({1}, lower={2}, upper={3}{4}))")
35+
.format(
36+
suffix, start, self.begin.value, self.end.value, merge);
37+
}
4438
}
4539

46-
return result;
40+
// self.range == range_t::none
41+
return py::str("reduce_command(merge({0}))").format(self.merge);
4742
});
4843

49-
py::class_<bh::algorithm::shrink_and_rebin, bh::algorithm::reduce_command>(
50-
algorithm, "shrink_and_rebin")
51-
.def(py::init<unsigned, double, double, unsigned>(),
44+
using slice_mode = bh::algorithm::slice_mode;
45+
46+
py::enum_<slice_mode>(algorithm, "slice_mode")
47+
.value("shrink", slice_mode::shrink)
48+
.value("crop", slice_mode::crop);
49+
50+
algorithm
51+
.def("shrink_and_rebin",
52+
py::overload_cast<unsigned, double, double, unsigned>(
53+
&bh::algorithm::shrink_and_rebin),
5254
"iaxis"_a,
5355
"lower"_a,
5456
"upper"_a,
@@ -65,21 +67,74 @@ void register_algorithms(py::module& algorithm) {
6567
"bin interval, the whole "
6668
"interval is removed.\n"
6769
":param merge: how many adjacent bins to merge into one.")
68-
.def(py::init<double, double, unsigned>(),
70+
.def("shrink_and_rebin",
71+
py::overload_cast<double, double, unsigned>(
72+
&bh::algorithm::shrink_and_rebin),
6973
"lower"_a,
7074
"upper"_a,
7175
"merge"_a,
72-
"Shortcut form of shrink_and_reduce")
73-
74-
;
76+
"Positional shrink and rebin option to be used in reduce().\n"
77+
"\n"
78+
"To shrink and rebin in one command. Equivalent to passing both the "
79+
"shrink() and the\n"
80+
"rebin() option for the same axis to reduce.\n"
81+
"\n"
82+
":param iaxis: which axis to operate on.\n"
83+
":param lower: lowest bound that should be kept.\n"
84+
":param upper: highest bound that should be kept. If upper is inside "
85+
"bin interval, the whole "
86+
"interval is removed.\n"
87+
":param merge: how many adjacent bins to merge into one.")
7588

76-
py::class_<bh::algorithm::slice_and_rebin, bh::algorithm::reduce_command>(
77-
algorithm, "slice_and_rebin")
78-
.def(py::init<unsigned, bh::axis::index_type, bh::axis::index_type, unsigned>(),
89+
.def("crop_and_rebin",
90+
py::overload_cast<unsigned, double, double, unsigned>(
91+
&bh::algorithm::crop_and_rebin),
92+
"iaxis"_a,
93+
"lower"_a,
94+
"upper"_a,
95+
"merge"_a,
96+
"Crop and rebin option to be used in reduce().\n"
97+
"\n"
98+
"To crop and rebin in one command. Equivalent to passing both the "
99+
"crop and the\n"
100+
"rebin option for the same axis to reduce.\n"
101+
"\n"
102+
":param iaxis: which axis to operate on.\n"
103+
":param lower: lowest bound that should be kept.\n"
104+
":param upper: highest bound that should be kept. If upper is inside "
105+
"bin interval, the whole "
106+
"interval is removed.\n"
107+
":param merge: how many adjacent bins to merge into one.")
108+
.def(
109+
"crop_and_rebin",
110+
py::overload_cast<double, double, unsigned>(&bh::algorithm::crop_and_rebin),
111+
"lower"_a,
112+
"upper"_a,
113+
"merge"_a,
114+
"Positional crop and rebin option to be used in reduce().\n"
115+
"\n"
116+
"To crop and rebin in one command. Equivalent to passing both the "
117+
"crop and the\n"
118+
"rebin option for the same axis to reduce.\n"
119+
"\n"
120+
":param iaxis: which axis to operate on.\n"
121+
":param lower: lowest bound that should be kept.\n"
122+
":param upper: highest bound that should be kept. If upper is inside "
123+
"bin interval, the whole "
124+
"interval is removed.\n"
125+
":param merge: how many adjacent bins to merge into one.")
126+
127+
.def("slice_and_rebin",
128+
py::overload_cast<unsigned,
129+
bh::axis::index_type,
130+
bh::axis::index_type,
131+
unsigned,
132+
slice_mode>(&bh::algorithm::slice_and_rebin),
79133
"iaxis"_a,
80134
"begin"_a,
81135
"end"_a,
82136
"merge"_a,
137+
"mode"_a = slice_mode::shrink,
83138
"Slice and rebin option to be used in reduce().\n"
84139
"\n"
85140
"To slice and rebin in one command. Equivalent to passing both the "
@@ -89,32 +144,70 @@ void register_algorithms(py::module& algorithm) {
89144
":param iaxis: which axis to operate on.\n"
90145
":param begin: first index that should be kept.\n"
91146
":param end: one past the last index that should be kept.\n"
92-
":param merge: how many adjacent bins to merge into one.")
93-
.def(py::init<bh::axis::index_type, bh::axis::index_type, unsigned>(),
147+
":param merge: how many adjacent bins to merge into one.\n"
148+
":param mode: see slice_mode")
149+
.def("slice_and_rebin",
150+
py::overload_cast<bh::axis::index_type,
151+
bh::axis::index_type,
152+
unsigned,
153+
slice_mode>(&bh::algorithm::slice_and_rebin),
94154
"begin"_a,
95155
"end"_a,
96156
"merge"_a,
97-
"Shortcut form of slice_and_rebin.");
98-
99-
py::class_<bh::algorithm::rebin, bh::algorithm::reduce_command>(algorithm, "rebin")
100-
.def(py::init<unsigned, unsigned>(), "iaxis"_a, "merge"_a)
101-
.def(py::init<unsigned>(), "merge"_a)
157+
"mode"_a = slice_mode::shrink,
158+
"Positional slice and rebin option to be used in reduce().\n"
159+
"\n"
160+
"To slice and rebin in one command. Equivalent to passing both the "
161+
"slice() and the\n"
162+
"rebin() option for the same axis to reduce.\n"
163+
"\n"
164+
":param iaxis: which axis to operate on.\n"
165+
":param begin: first index that should be kept.\n"
166+
":param end: one past the last index that should be kept.\n"
167+
":param merge: how many adjacent bins to merge into one.\n"
168+
":param mode: see slice_mode")
102169

103-
;
170+
.def("rebin",
171+
py::overload_cast<unsigned, unsigned>(&bh::algorithm::rebin),
172+
"iaxis"_a,
173+
"merge"_a)
174+
.def("rebin", py::overload_cast<unsigned>(&bh::algorithm::rebin), "merge"_a)
104175

105-
py::class_<bh::algorithm::shrink, bh::algorithm::reduce_command>(algorithm,
106-
"shrink")
107-
.def(py::init<unsigned, double, double>(), "iaxis"_a, "lower"_a, "upper"_a)
108-
.def(py::init<double, double>(), "lower"_a, "upper"_a)
176+
.def("shrink",
177+
py::overload_cast<unsigned, double, double>(&bh::algorithm::shrink),
178+
"iaxis"_a,
179+
"lower"_a,
180+
"upper"_a)
181+
.def("shrink",
182+
py::overload_cast<double, double>(&bh::algorithm::shrink),
183+
"lower"_a,
184+
"upper"_a)
109185

110-
;
186+
.def("crop",
187+
py::overload_cast<unsigned, double, double>(&bh::algorithm::crop),
188+
"iaxis"_a,
189+
"lower"_a,
190+
"upper"_a)
191+
.def("crop",
192+
py::overload_cast<double, double>(&bh::algorithm::crop),
193+
"lower"_a,
194+
"upper"_a)
111195

112-
py::class_<bh::algorithm::slice, bh::algorithm::reduce_command>(algorithm, "slice")
113-
.def(py::init<unsigned, bh::axis::index_type, bh::axis::index_type>(),
196+
.def("slice",
197+
py::overload_cast<unsigned,
198+
bh::axis::index_type,
199+
bh::axis::index_type,
200+
slice_mode>(&bh::algorithm::slice),
114201
"iaxis"_a,
115202
"begin"_a,
116-
"end"_a)
117-
.def(py::init<bh::axis::index_type, bh::axis::index_type>(), "begin"_a, "end"_a)
203+
"end"_a,
204+
"mode"_a = slice_mode::shrink)
205+
.def("slice",
206+
py::overload_cast<bh::axis::index_type, bh::axis::index_type, slice_mode>(
207+
&bh::algorithm::slice),
208+
"begin"_a,
209+
"end"_a,
210+
"mode"_a = slice_mode::shrink)
118211

119212
;
120213
}

0 commit comments

Comments
 (0)