Skip to content

Instantly share code, notes, and snippets.

@matthewfeickert
Last active March 15, 2021 20:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matthewfeickert/ab6ac8677aad2e04738111d0af3e0549 to your computer and use it in GitHub Desktop.
Save matthewfeickert/ab6ac8677aad2e04738111d0af3e0549 to your computer and use it in GitHub Desktop.
demo of failing example of hist with np.sqrt
.ipynb_checkpoints/
example.root

Issue

Binder

At the moment there does not seem to be support for NumPy ufuncs for hist histograms created from uproot's .to_hist() API.

Environment Setup

$ git clone git@gist.github.com:ab6ac8677aad2e04738111d0af3e0549.git hist-issue
$ cd hist-issue
$ pyenv virtualenv 3.8.7 hist-issue
$ pyenv activate hist-issue
(hist-issue) $ pip install --upgrade --quiet pip setuptools wheel
(hist-issue) $ cat requirements.txt
hist[plot]==2.2.0
uproot~=4.0.6
uproot3~=3.14.4
jupyter~=1.0
jupyterlab~=2.2
(hist-issue) $ pip install -r requirements.txt

Minimal failing example

(hist-issue) $ python minimal-failing.py
hists in file: ['mass;1']
Traceback (most recent call last):
  File "minimal-failing.py", line 100, in <module>
    main()
  File "minimal-failing.py", line 96, in main
    minimal_failing(root_file)
  File "minimal-failing.py", line 74, in minimal_failing
    sqrt_values = np.sqrt(hist_mass)
TypeError: ufunc 'sqrt' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

Minimal passing example

(hist-issue) $  python minimal-failing.py pass
np.sqrt gives: [0.         0.         0.         0.         0.         0.36136437
 1.36677301 2.24499357 3.3028363  4.01532338 4.46574546 4.50899645
 4.54050631 4.45316398 4.04590633 3.8036544  3.50747509 3.26808198
 2.91475639 2.61148735 2.36931914 2.15342051 1.73440724 1.6316221
 1.40370282 1.23654795 1.06892428 1.0623001  0.95068096 0.73183709
 0.50208207 0.58183567 0.53861281 0.39997453 0.35529868 0.28219637
 0.20478919 0.18039576 0.19334187 0.07509284 0.         0.
 0.07867583 0.         0.         0.         0.10174972 0.
 0.         0.        ]
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import hist\n",
"import numpy as np\n",
"import uproot3\n",
"import uproot\n",
"from hist import Hist"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First contstruct the histogram by hand and write it to the ROOT file so we have a public example"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"values = np.array(\n",
" [\n",
" 0.0,\n",
" 0.0,\n",
" 0.0,\n",
" 0.0,\n",
" 0.0,\n",
" 0.1305842101573944,\n",
" 1.8680684566497803,\n",
" 5.039996147155762,\n",
" 10.908727645874023,\n",
" 16.122821807861328,\n",
" 19.942882537841797,\n",
" 20.3310489654541,\n",
" 20.61619758605957,\n",
" 19.830669403076172,\n",
" 16.36935806274414,\n",
" 14.46778678894043,\n",
" 12.30238151550293,\n",
" 10.680359840393066,\n",
" 8.495804786682129,\n",
" 6.819866180419922,\n",
" 5.613673210144043,\n",
" 4.6372199058532715,\n",
" 3.0081684589385986,\n",
" 2.6621906757354736,\n",
" 1.9703816175460815,\n",
" 1.5290508270263672,\n",
" 1.142599105834961,\n",
" 1.1284815073013306,\n",
" 0.9037942886352539,\n",
" 0.5355855226516724,\n",
" 0.2520864009857178,\n",
" 0.3385327458381653,\n",
" 0.2901037633419037,\n",
" 0.15997962653636932,\n",
" 0.126237154006958,\n",
" 0.07963479310274124,\n",
" 0.04193861410021782,\n",
" 0.0325426310300827,\n",
" 0.03738107904791832,\n",
" 0.005638935137540102,\n",
" 0.0,\n",
" 0.0,\n",
" 0.006189885549247265,\n",
" 0.0,\n",
" 0.0,\n",
" 0.0,\n",
" 0.010353004559874535,\n",
" 0.0,\n",
" 0.0,\n",
" 0.0,\n",
" ]\n",
")\n",
"edges = np.arange(0, 10000 + 200, 200)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"with uproot3.recreate(\"example.root\", compression=uproot3.ZLIB(4)) as outfile:\n",
" outfile[\"mass\"] = (values, edges)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['mass;1']"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"root_file = uproot.open(\"example.root\")\n",
"root_file.keys()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The following will throw a `TypeError` but continue execution"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<html>\n",
"<div style=\"display:flex; align-items:center;\">\n",
"<div style=\"width:290px;\">\n",
"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"-10 -105 270 120\">\n",
"<line x1=\"-5\" y1=\"0\" x2=\"255\" y2=\"0\" style=\"fill:none;stroke-width:2;stroke:currentColor\"/>\n",
"<text text-anchor=\"middle\" x=\"0\" y=\"15\" style=\"fill:currentColor;\">\n",
"0\n",
"</text>\n",
"<text text-anchor=\"middle\" x=\"250\" y=\"15\" style=\"fill:currentColor;\">\n",
"1e+04\n",
"</text>\n",
"<text text-anchor=\"middle\" x=\"125.0\" y=\"15\" style=\"fill:currentColor;\">\n",
"xaxis\n",
"</text>\n",
"<polyline points=\" 0,0 0,-0 5,-0 5,-0 10,-0 10,-0 15,-0 15,-0 20,-0 20,-0 25,-0 25,-0.633 30,-0.633 30,-9.06 35,-9.06 35,-24.4 40,-24.4 40,-52.9 45,-52.9 45,-78.2 50,-78.2 50,-96.7 55,-96.7 55,-98.6 60,-98.6 60,-100 65,-100 65,-96.2 70,-96.2 70,-79.4 75,-79.4 75,-70.2 80,-70.2 80,-59.7 85,-59.7 85,-51.8 90,-51.8 90,-41.2 95,-41.2 95,-33.1 100,-33.1 100,-27.2 105,-27.2 105,-22.5 110,-22.5 110,-14.6 115,-14.6 115,-12.9 120,-12.9 120,-9.56 125,-9.56 125,-7.42 130,-7.42 130,-5.54 135,-5.54 135,-5.47 140,-5.47 140,-4.38 145,-4.38 145,-2.6 150,-2.6 150,-1.22 155,-1.22 155,-1.64 160,-1.64 160,-1.41 165,-1.41 165,-0.776 170,-0.776 170,-0.612 175,-0.612 175,-0.386 180,-0.386 180,-0.203 185,-0.203 185,-0.158 190,-0.158 190,-0.181 195,-0.181 195,-0.0274 200,-0.0274 200,-0 205,-0 205,-0 210,-0 210,-0.03 215,-0.03 215,-0 220,-0 220,-0 225,-0 225,-0 230,-0 230,-0.0502 235,-0.0502 235,-0 240,-0 240,-0 245,-0 245,-0 250,-0 250,0\" style=\"fill:none; stroke:currentColor;\"/>\n",
"</svg>\n",
"</div>\n",
"<div style=\"flex=grow:1;\">\n",
"Regular(50, 0, 10000, name='xaxis', label='xaxis')<br/>\n",
"<hr style=\"margin-top:.2em; margin-bottom:.2em;\"/>\n",
"Weight() Σ=WeightedSum(value=208.438, variance=2977.96)\n",
"\n",
"</div>\n",
"</div>\n",
"</html>"
],
"text/plain": [
"Hist(Regular(50, 0, 10000, name='xaxis', label='xaxis'), storage=Weight()) # Sum: WeightedSum(value=208.438, variance=2977.96)"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"hist_mass = root_file[\"mass\"].to_hist()\n",
"hist_mass"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"hist.hist.Hist"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"type(hist_mass)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"ename": "TypeError",
"evalue": "ufunc 'sqrt' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-7-31178d06e764>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msqrt\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhist_mass\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m: ufunc 'sqrt' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''"
]
}
],
"source": [
"np.sqrt(hist_mass)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Below is a cumbersome way of doing things that works"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<html>\n",
"<div style=\"display:flex; align-items:center;\">\n",
"<div style=\"width:290px;\">\n",
"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"-10 -105 270 120\">\n",
"<line x1=\"-5\" y1=\"0\" x2=\"255\" y2=\"0\" style=\"fill:none;stroke-width:2;stroke:currentColor\"/>\n",
"<text text-anchor=\"middle\" x=\"0\" y=\"15\" style=\"fill:currentColor;\">\n",
"0\n",
"</text>\n",
"<text text-anchor=\"middle\" x=\"250\" y=\"15\" style=\"fill:currentColor;\">\n",
"1e+04\n",
"</text>\n",
"<text text-anchor=\"middle\" x=\"125.0\" y=\"15\" style=\"fill:currentColor;\">\n",
"mass\n",
"</text>\n",
"<polyline points=\" 0,0 0,-0 5,-0 5,-0 10,-0 10,-0 15,-0 15,-0 20,-0 20,-0 25,-0 25,-0.633 30,-0.633 30,-9.06 35,-9.06 35,-24.4 40,-24.4 40,-52.9 45,-52.9 45,-78.2 50,-78.2 50,-96.7 55,-96.7 55,-98.6 60,-98.6 60,-100 65,-100 65,-96.2 70,-96.2 70,-79.4 75,-79.4 75,-70.2 80,-70.2 80,-59.7 85,-59.7 85,-51.8 90,-51.8 90,-41.2 95,-41.2 95,-33.1 100,-33.1 100,-27.2 105,-27.2 105,-22.5 110,-22.5 110,-14.6 115,-14.6 115,-12.9 120,-12.9 120,-9.56 125,-9.56 125,-7.42 130,-7.42 130,-5.54 135,-5.54 135,-5.47 140,-5.47 140,-4.38 145,-4.38 145,-2.6 150,-2.6 150,-1.22 155,-1.22 155,-1.64 160,-1.64 160,-1.41 165,-1.41 165,-0.776 170,-0.776 170,-0.612 175,-0.612 175,-0.386 180,-0.386 180,-0.203 185,-0.203 185,-0.158 190,-0.158 190,-0.181 195,-0.181 195,-0.0274 200,-0.0274 200,-0 205,-0 205,-0 210,-0 210,-0.03 215,-0.03 215,-0 220,-0 220,-0 225,-0 225,-0 230,-0 230,-0.0502 235,-0.0502 235,-0 240,-0 240,-0 245,-0 245,-0 250,-0 250,0\" style=\"fill:none; stroke:currentColor;\"/>\n",
"</svg>\n",
"</div>\n",
"<div style=\"flex=grow:1;\">\n",
"Regular(50, 0, 10000, name='mass', label='mass')<br/>\n",
"<hr style=\"margin-top:.2em; margin-bottom:.2em;\"/>\n",
"Double() Σ=208.43831768771634\n",
"\n",
"</div>\n",
"</div>\n",
"</html>"
],
"text/plain": [
"Hist(Regular(50, 0, 10000, name='mass', label='mass'), storage=Double()) # Sum: 208.43831768771634"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"h_values, h_edges = root_file[\"mass\"].to_numpy()\n",
"hist_mass = Hist(\n",
" hist.axis.Regular(len(h_edges) - 1, h_edges[0], h_edges[-1], name=\"mass\"),\n",
" storage=hist.storage.Double(),\n",
")\n",
"hist_mass[:] = h_values\n",
"hist_mass"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([0. , 0. , 0. , 0. , 0. ,\n",
" 0.36136437, 1.36677301, 2.24499357, 3.3028363 , 4.01532338,\n",
" 4.46574546, 4.50899645, 4.54050631, 4.45316398, 4.04590633,\n",
" 3.8036544 , 3.50747509, 3.26808198, 2.91475639, 2.61148735,\n",
" 2.36931914, 2.15342051, 1.73440724, 1.6316221 , 1.40370282,\n",
" 1.23654795, 1.06892428, 1.0623001 , 0.95068096, 0.73183709,\n",
" 0.50208207, 0.58183567, 0.53861281, 0.39997453, 0.35529868,\n",
" 0.28219637, 0.20478919, 0.18039576, 0.19334187, 0.07509284,\n",
" 0. , 0. , 0.07867583, 0. , 0. ,\n",
" 0. , 0.10174972, 0. , 0. , 0. ])"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.sqrt(hist_mass)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.7"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
import sys
import hist
import numpy as np
import uproot3
import uproot
from hist import Hist
def write_root_file(name="example.root"):
values = np.array(
[
0.0,
0.0,
0.0,
0.0,
0.0,
0.1305842101573944,
1.8680684566497803,
5.039996147155762,
10.908727645874023,
16.122821807861328,
19.942882537841797,
20.3310489654541,
20.61619758605957,
19.830669403076172,
16.36935806274414,
14.46778678894043,
12.30238151550293,
10.680359840393066,
8.495804786682129,
6.819866180419922,
5.613673210144043,
4.6372199058532715,
3.0081684589385986,
2.6621906757354736,
1.9703816175460815,
1.5290508270263672,
1.142599105834961,
1.1284815073013306,
0.9037942886352539,
0.5355855226516724,
0.2520864009857178,
0.3385327458381653,
0.2901037633419037,
0.15997962653636932,
0.126237154006958,
0.07963479310274124,
0.04193861410021782,
0.0325426310300827,
0.03738107904791832,
0.005638935137540102,
0.0,
0.0,
0.006189885549247265,
0.0,
0.0,
0.0,
0.010353004559874535,
0.0,
0.0,
0.0,
]
)
edges = np.arange(0, 10000 + 200, 200)
with uproot3.recreate(name, compression=uproot3.ZLIB(4)) as outfile:
outfile["mass"] = (values, edges)
def minimal_failing(root_file):
print(f"hists in file: {root_file.keys()}")
hist_mass = root_file["mass"].to_hist()
sqrt_values = np.sqrt(hist_mass)
print(f"np.sqrt gives: {sqrt_values}")
def minimal_passing(root_file):
values, edges = root_file["mass"].to_numpy()
hist_mass = Hist(
hist.axis.Regular(len(edges) - 1, edges[0], edges[-1], name="mass"),
storage=hist.storage.Double(),
)
hist_mass[:] = values
sqrt_values = np.sqrt(hist_mass)
print(f"np.sqrt gives: {sqrt_values}")
def main(input=sys.argv):
write_root_file("example.root")
root_file = uproot.open("example.root")
if input[-1] == "pass":
minimal_passing(root_file)
else:
minimal_failing(root_file)
if __name__ == "__main__":
main()
hist[plot]==2.2.0
uproot~=4.0.6
uproot3~=3.14.4
jupyter~=1.0
jupyterlab~=2.2
@matthewfeickert
Copy link
Author

@henryiii has pointed out this isn't really using the proper API and I should be using

sqrt_values = np.sqrt(hist_mass.values())

Which is already what I'm doing in the minimal_passing example, so that's seem fair. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment