go-hep / hep

hep is the mono repository holding all of go-hep.org/x/hep packages and tools
https://go-hep.org
BSD 3-Clause "New" or "Revised" License
230 stars 35 forks source link

hbook/rootcnv: H1D looses TH1x::BinLabel informations #502

Open reikdas opened 5 years ago

reikdas commented 5 years ago

Creating test.root (which has a labelled bin) -

[reik@reik-msi ~]$ python
Python 3.7.3 (default, Jun 24 2019, 04:54:02) 
[GCC 9.1.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ROOT
>>> f = ROOT.TFile.Open("test.root", "RECREATE")
>>> h = ROOT.TH1F("hvar", "title", 5, 1, 10)
>>> h.Fill(1.0, 3)
1
>>> h.GetXaxis().SetBinLabel(1, "Hi")
>>> h.Write()
332
>>> f.Close()

Reading it and writing it back in Go - (I am absolutely new to Go so maybe the error is in my code?)

package main

import (
    "fmt"
    "hep/groot"
    "hep/groot/rhist"
    "hep/hbook/rootcnv"
    "log"
)

func main() {
    const fname = "test.root"

    r, err := groot.Open(fname)
    if err != nil {
        log.Fatal(err)
    }
    defer r.Close()

    for _, k := range r.Keys() {
        fmt.Printf("key: name=%q, type=%q\n", k.Name(), k.ClassName())
    }

    robj, err := r.Get("hvar")
    if err != nil {
        log.Fatal(err)
    }

    hr, err := rootcnv.H1D(robj.(rhist.H1))
    if err != nil {
        log.Fatal(err)
    }

    f, err := groot.Create("test-go.root")
    if err != nil {
        log.Fatal(err)
    }
    defer f.Close()

    hroot := rhist.NewH1FFrom(hr)

    err = f.Put("hvar", hroot)
    if err != nil {
        log.Fatal(err)
    }

    err = f.Close()
    if err != nil {
        log.Fatalf("error closing ROOT file: %v", err)
    }

}

Reading it back in ROOT -

>>> import ROOT
>>> f = ROOT.TFile.Open("test-go.root")
>>> h = f.Get("hvar")
>>> h.GetXaxis()
<ROOT.TAxis object ("xaxis") at 0x56396ba8ec58>
>>> h.GetXaxis().GetBinLabel(1)
''

No label was found.

I am particularly curious because there seems to be code to write it - https://github.com/go-hep/hep/blob/master/groot/rhist/axis.go#L132 But the test - https://github.com/go-hep/hep/blob/master/groot/rhist/rhist_test.go has the labels always set to nil so maybe groot cannot write labels yet? If that is the case, is it because of some error in WriteObjectAny (https://github.com/go-hep/hep/blob/master/groot/rbytes/wbuffer.go#L136)? (I have been looking at WriteObjectAny as reference for a similar implementation in uproot)

cc: @jpivarski

sbinet commented 5 years ago

hi,

your Go code looks fine :) (even if go-hep might not be installed in the expected location)

it's just that it is being hit by an hysteresis effect originating from hbook/rootcnv. hbook/rootcnv is meant to convert ROOT TH1x (and TH2x and TGraphs) into their hbook equivalent, and vice versa. but hbook objects are very barebones.

when converting your TH1F into a hbook.H1D, you loose the bin-label information.

here is a program that does not loose bin-label informations:

package main

import (
    "flag"
    "log"

    "go-hep.org/x/hep/groot"
)

func main() {
    fname := "test.root"

    flag.Parse()
    if flag.NArg() > 0 {
        fname = flag.Arg(0)
    }

    r, err := groot.Open(fname)
    if err != nil {
        log.Fatal(err)
    }
    defer r.Close()

    o, err := r.Get("hvar")
    if err != nil {
        log.Fatal(err)
    }

    w, err := groot.Create("out.root")
    if err != nil {
        log.Fatal(err)
    }
    defer w.Close()

    err = w.Put("hvar", o)
    if err != nil {
        log.Fatal(err)
    }

    err = w.Close()
    if err != nil {
        log.Fatal(err)
    }
}

that program is actually a slimmed down version of go-hep.org/x/hep/groot/cmd/root-cp:

$> root-cp test.root foo.root
$> python
>>> import ROOT
>>> f = ROOT.TFile.Open("foo.root")
>>> f.Get("hvar").GetXaxis().GetBinLabel(1)
'Hi'
reikdas commented 5 years ago

Thanks!

hbook/rootcnv is meant to convert ROOT TH1x (and TH2x and TGraphs) into their hbook equivalent, and vice versa. but hbook objects are very barebones.

I noticed that you renamed the issue and didn't close it. Is hbook retaining ROOT bin labels something that is required though? (The way I created a histogram by first converting it to a hbook is obviously not the recommended way to do it)

sbinet commented 5 years ago

I am still considering whether this is something that hbook/rootcnv should do or not, and thus whether hbook.H{1,2}D should have a way to "decorate" labels. (perhaps as an hbook.Annotation?)

hbook isn't concerned with displaying histograms, but it already provides the ability to give histos a name and a title, so...