hist.view() /= 2
.
python-3.8
package, you still get pip 9 even on Python 3.8!!! (which is totally unsupported). I hate distro packaging sometimes…
Congratulations on boost-histogram
1.0! I'm adopting the new API for subclassing, and saw in https://boost-histogram.readthedocs.io/en/latest/usage/subclassing.html that family=object()
is recommended when only overriding Histogram
. What is the difference between object()
and object
? While trying to understand this, I noticed that object is object
is True
and object() is object()
(are those instances?) is False
. Is the latter part an issue given the following?
It just has to support is, and be the exact same object on all your subclasses.
object
is a class; classes are singletons, there’s just one. object()
is an instance, and you can make as many as you want, each will live in a different place in memory, check with id()
. Basically, family=
can be anything that supports is which is literally everything, with the exception of the Module boost_histogram
(as that’s already taken by boost-histogram). The Module hist
would be a bad choice too, as then your axes would come out randomly Hist's or your own. The old way works fine, FAMILY = object()
at the top of the file, then use family=FAMILY
when you subclass. But for most users, a handy existing object is the module you are in, that is, “hist” or “boost_histogram”. It’s unique to you, and is descriptive. You can use family=None
(or the object class, anything works), you just don’t want some other extension to also use the same one - then boost-histogram won’t be able to distinguish between them when picking Axis, Storage, etc. If all you use is Histogram, though, then it really doesn’t matter.
object()
is to make a truly unique object. For example, if I make NOTHING=object()
, then use def f(x =NOTHING): if x is NOTHING
, I can now always tell if someone passed a keyword argument in. They can’t make NOTHING, they have to pull NOTHING out of my source and using it from there, you can’t “remake” it accidentaly.
The ideal way would have been the following:
class Hist(bh.Histogram): …
class Regular(bh.axis.Regular, parent=Hist)
The problem with this would have been it is very hard to design without circular imports, as Histogram almost always has Axis usages in it. It can be done, but would have requried changes to boost-histogram and user code, which also has to follow this strict regimen. Using a token is much simpler; it doesn’t require as much caution in user code (or boost-histogram).
Histogram
would create a new object()
and then not match the object()
in the family definition, but from what I understand now this is not what happens - this object is created once when the class is defined, and any other class that may also inherit defined in my code with family=object()
would pick up a different object and be unique too.
If I added a default for family for Histogram, it would have been object(). I could special case None, that is, if family=None
, it just makes an object() for you.
I could also make that the default for Histogram, and only require family= on the other subclasses. But if you have an Axis or other subclass, you have to go back and add family= on the Histogram; that’s why I force it to always be delt with on Histogram, it prepares you for also subclassing other components. I didn’t really think too much about only subclassing Histogram.
By the way, can’t you do
import cabinetry
class Histogram(bh.Histogram, family=cabinetry): ...
? That would allow to easily add subclasses for axes eventually if you needed to customize them later.
Yes, I could use that too. I was looking at object()
following the documentation:
If you only override Histogram, just use family=object().
The additions in my histogram class are rather lightweight and I don't expect to go deeper and subclass axes. On the other hand I see no downside of family=cabinetry
either.
@henryiii @jpivarski Can you tell me if this is a hist
Issue or a uproot
Issue or neither? https://gist.github.com/matthewfeickert/ab6ac8677aad2e04738111d0af3e0549
(There's a Binder link in the Gist if you want to play with it in browser)
@henryiii @jpivarski Another followup question on moving from root files to hist.Hist
histograms via uproot
: Is there any way to be able to use uproot
's .to_hist()
API to get a hist.Hist
with storage=hist.storage.Weight()
? Or at the moment should I just write a little converter like I did here?
https://github.com/matthewfeickert/heputils/issues/24#issuecomment-800867686