Skip to content

Commit

Permalink
groot/rtree: handle parallel-merged TBaskets
Browse files Browse the repository at this point in the history
This CL adds proper handling of Geant4 files produced in multithreaded
mode (and merged).

Fixes #989.

Signed-off-by: Sebastien Binet <[email protected]>
  • Loading branch information
sbinet committed Sep 6, 2023
1 parent 404ed51 commit 548d277
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
18 changes: 18 additions & 0 deletions groot/rtree/bkreader.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,26 @@ func newBkReader(b Branch, n int, beg, end int64) *bkreader {
}

if len(base.basketEntry) == len(base.basketSeek) {
numBaskets := 0
for i, v := range base.basketSeek {
if v == 0 || i == base.writeBasket {
break
}
numBaskets++
}
if numBaskets > 0 {
base.basketSeek = base.basketSeek[:numBaskets]
bkr.spans = bkr.spans[:len(base.basketSeek)]
}

// prepare for recover basket mode.
base.basketEntry = append(base.basketEntry, 0)
bkr.spans[0] = rspan{
pos: base.basketSeek[0],
sz: base.basketBytes[0],
beg: base.basketEntry[0],
end: base.basketEntry[0+1],
}
} else {
for i, seek := range base.basketSeek {
bkr.spans[i] = rspan{
Expand Down
47 changes: 47 additions & 0 deletions groot/rtree/tree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1610,3 +1610,50 @@ func TestUprootTrees(t *testing.T) {
})
}
}

func TestReadG4Merge(t *testing.T) {
const fname = "../testdata/g4-merge.root"

f, err := riofs.Open(fname)
if err != nil {
t.Fatal(err)
}
defer f.Close()

tree, err := riofs.Get[Tree](f, "Photons")
if err != nil {
t.Fatal(err)
}

type Data struct {
X float64 `groot:"fX"`
}

var (
d Data
want = []Data{
{X: 0.12123017145693009},
{X: 0.11744358487972842},
{X: 0.1142964503404715},
{X: 0.11702763375596258},
{X: 0.1160675474106288},
}
)

r, err := NewReader(tree, ReadVarsFromStruct(&d), WithRange(0, 5))
if err != nil {
t.Fatalf("could not create reader: %+v", err)
}
defer r.Close()

err = r.Read(func(ctx RCtx) error {
i := int(ctx.Entry)
if got, want := d, want[i]; got != want {
return fmt.Errorf("invalid entry[%d]: got=%v, want=%v", i, got, want)
}
return nil
})
if err != nil {
t.Fatalf("error: %+v", err)
}
}
Binary file added groot/testdata/g4-merge.root
Binary file not shown.

0 comments on commit 548d277

Please sign in to comment.