Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] histogram heart surgery #432

Merged
merged 26 commits into from Oct 10, 2013
Merged

[WIP] histogram heart surgery #432

merged 26 commits into from Oct 10, 2013

Conversation

ndawe
Copy link
Member

@ndawe ndawe commented Sep 12, 2013

Addresses #227

Bins are 0-indexed at the underflow bin like ROOT

This PR changes the histogram indexing so that index 0 refers to the underflow bin and index nbins(axis) + 1 is the overflow bin. In the end this seemed like the best option. Allowing the user to decide the indexing scheme at init would just be a mess. Note though, that the methods that return a generator if index is None allow the option of excluding or including the overflow bins.

So with this change, rootpy's indexing scheme will be identical to ROOT's. rootpy just defines the centers, edges and widths of the overflow bins as (+/-)infinity, where ROOT gives you bogus values.

We will advertise this in BIG BOLD TEXT in the WHATSNEW.md and mail list. I'll start updating the WHATSNEW.md in this PR.

Full slicing support

Histogram __getitem__ and __setitem__ methods now accept slicing by global bin index or along each axis separately.

Access contents and errors:

>>> from rootpy.plotting import Hist
>>> a = Hist(10, 0, 1)
>>> a[1].value = 2
>>> a[1].value
2.0
>>> a[1].error = 2
>>> a[1].error
2.0

__setitem__ with a slice and a single value just repeats that value over the sliced view:

>>> from rootpy.plotting import Hist3D
>>> a = Hist3D(10, 0, 1, 10, 0, 1, 10, 0, 1)
>>> a[:,:,5] = a[40] # set with a BinProxy
>>> a[:,:,:] = (2, 4) # set content and error with a 2-tuple
>>> a[:,:,:] = 2 # only set the content

If a single index is requested then a BinProxy is returned:

>>> from rootpy.plotting import Hist3D
>>> a = Hist3D(10, 0, 1, 10, 0, 1, 10, 0, 1)
>>> a[3,4,8]
BinProxy(Hist3D('5a8e7fbe8ff54be6be18709220b3da31'), 1203)
>>> a[3,4,8].value
1.0
>>> a[3,6,8].value
5.0
>>> a[3,6,8].error
2.23606797749979
>>> a[0,5,6].overflow
True
>>> a[1,5,6].overflow
False

If a slice is requested, then a HistIndexView or Hist[2D|3D]View is returned. You may iterate over the BinProxies in these views.

>>> a[:]
HistIndexView(Hist3D('5a8e7fbe8ff54be6be18709220b3da31'), idx=[start=None, stop=None, step=None])
>>> a[:,:,:]
Hist3DView(Hist3D('5a8e7fbe8ff54be6be18709220b3da31'), x=[start=None, stop=None, step=None], y=[start=None, stop=None, step=None], z=[start=None, stop=None, step=None])
>>> a[:,:,2:5]
Hist3DView(Hist3D('5a8e7fbe8ff54be6be18709220b3da31'), x=[start=None, stop=None, step=None], y=[start=None, stop=None, step=None], z=[start=2, stop=5, step=None])
>>> a[:,:,::-1]
Hist3DView(Hist3D('5a8e7fbe8ff54be6be18709220b3da31'), x=[start=None, stop=None, step=None], y=[start=None, stop=None, step=None], z=[start=None, stop=None, step=-1])

You can then construct a new histogram using a view of another. The step member of a slice translates to a rebinning along the associated axis.

>>> b = Hist3D(a[3:5,::2,:])
>>> list(b.xedges())
[0.2, 0.30000000000000004, 0.4]
>>> list(b.yedges())
[0.0, 0.2, 0.4, 0.6000000000000001, 0.8, 1.0]
>>> list(b.zedges())
[0.0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9, 1.0]

Example: reverse the bin contents and errors:

>>> from rootpy.plotting import Hist
>>> a = Hist(10, 0, 1)
>>> a.FillRandom('gaus')
>>> a.Draw()
>>> a[:] = a.Clone(shallow=True)[::-1]
>>> a.Draw()

Summary of changes

  • len(hist) is now the same as h.GetSize() (so includes overflow bins):
>>> from rootpy.plotting import Hist
>>> from rootpy.plotting import Hist2D
>>> a = Hist(10, 0, 1)
>>> len(a)
12
>>> b = Hist2D(10, 0, 1, 10, 0, 1)
>>> len(b)
144
  • Index 0 along an axis corresponds to the underflow bin on that axis and index h.nbins(axis) + 1 is the overflow bin.
  • The [] operator returns a BinProxy if a single bin is selected or a view if a slice is selected:
>>> a[a.nbins(0)+1]
BinProxy(Hist('a28e8312a641403b8b5049ed78d8c77e'), 11)
>>> a[0].overflow
True
>>> a[2:4]
HistView(Hist('a28e8312a641403b8b5049ed78d8c77e'), x=[start=2, stop=4, step=None])
  • Histogram constructors accept views of other histograms.

@pwaller
Copy link
Member

pwaller commented Sep 12, 2013

Heh, don't do it for me because I'm not using it any more. Beware messing with lots of code in production. Maybe try and gauge how many people this will affect by making a really simple email which solicits complaints.

@ndawe
Copy link
Member Author

ndawe commented Sep 12, 2013

Yeah, it was more of a joke. Maybe I could lure you back to HEP :)

That's a good plan. I will send an email out to the users and dev lists when this PR is ready.

@ndawe
Copy link
Member Author

ndawe commented Sep 24, 2013

@schmitts you mind taking a peek at this?

@schmitts
Copy link
Member

I'll have a look.

@pwaller
Copy link
Member

pwaller commented Oct 7, 2013

👍

@ndawe
Copy link
Member Author

ndawe commented Oct 7, 2013

@pwaller thanks for having a look!

@ndawe
Copy link
Member Author

ndawe commented Oct 9, 2013

I'll be merging this PR in soon. Last chance for comments :)

ndawe added a commit that referenced this pull request Oct 10, 2013
[WIP] histogram heart surgery
@ndawe ndawe merged commit 40caf4a into rootpy:master Oct 10, 2013
@ndawe ndawe deleted the index branch October 10, 2013 04:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants