scikit-hep / uproot3-methods

Pythonic behaviors for non-I/O related ROOT classes.
BSD 3-Clause "New" or "Revised" License
21 stars 28 forks source link

Setters for TH1? #79

Open andrzejnovak opened 4 years ago

andrzejnovak commented 4 years ago

Could TH1 (or other methods) as well grow some setters, such that things like this might be possible?

aTH1 = TH1()
aTH1.values = np.array([2,3,2])
aTH1.edges = np.array([0,1,2,3])
aTH1.variances = np.array([4,5,1])
jpivarski commented 4 years ago

The classes in here are simple and flat, so you're free to suggest any improvements via pull request. It would be something like

    @values.setter
    def values(self, new_values):
        sanity_checks(new_values)
        self._f??? = new_values

(I don't remember the ROOT name for the values, or if she transformation is needed in the case of variances, but it would be the reverse of the getter.)

Some of these methods strip off the underflow (first) and overflow (last) bins. If that's what values does, what should setting it do? Leave the old value of the underflow/overflow? Set them to zero? If the latter, then someone trying to set all components one at a time would be surprised that setting underflow before values yields a different final state than values before underflow.

Since these are tiny objects maybe they shouldn't have mutable setters but functions that return a copy with the items set (i.e. with_values instead of set_values).

andrzejnovak commented 4 years ago

Setting values would be equivalent to SetBinContent I guess, so I'd say don't adjust under/over-flow by default. Which is not great, but I think that's kind of what root has.

One can always call .copy() on it prior to setting stuff no? Would setting values, edges and variance create 3 successive copies? That doesn't sound great.

jpivarski commented 4 years ago

It's up to you to decide how you want the interface to be. The only constraint is that the data model matches ROOT's: it has a single array of all bins, including overflow and underflow, and you can't change the values (no under/overflows) vs allvalues (with under/overflows) because other users are already using that.

Mutability often leads into these thorny issues, which is why some languages/libraries avoid it completely. Maybe you want allvalues to be a mutable property while values is read-only, because it represents a view.