rtree

package
Version: v0.29.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 29, 2021 License: BSD-3-Clause Imports: 19 Imported by: 3

Documentation

Overview

Package rtree contains the interfaces and types to decode, read, concatenate and iterate over ROOT Trees.

Example (CreateEventNtupleFullSplit)
package main

import (
	"bytes"
	"fmt"
	"log"
	"reflect"

	"go-hep.org/x/hep/groot"
	"go-hep.org/x/hep/groot/rcmd"
	"go-hep.org/x/hep/groot/rdict"
	"go-hep.org/x/hep/groot/rtree"
)

func main() {
	type P4 struct {
		Px float64 `groot:"px"`
		Py float64 `groot:"py"`
		Pz float64 `groot:"pz"`
		E  float64 `groot:"ene"`
	}

	type Particle struct {
		ID int32 `groot:"id"`
		P4 P4    `groot:"p4"`
	}

	type Event struct {
		I32 int32      `groot:"i32"`
		F64 float64    `groot:"f64"`
		Str string     `groot:"str"`
		Arr [5]float64 `groot:"arr"`
		Sli []float64  `groot:"sli"`
		P4  P4         `groot:"p4"`
		Ps  []Particle `groot:"mc"`
	}

	// register streamers
	for _, typ := range []reflect.Type{
		reflect.TypeOf(P4{}),
		reflect.TypeOf(Particle{}),
		reflect.TypeOf(Event{}),
	} {

		rdict.StreamerInfos.Add(rdict.StreamerOf(
			rdict.StreamerInfos,
			typ,
		))
	}

	const (
		fname = "../testdata/groot-event-ntuple-fullsplit.root"
		nevts = 5
	)

	func() {
		f, err := groot.Create(fname)
		if err != nil {
			log.Fatalf("could not create ROOT file: %+v", err)
		}
		defer f.Close()

		var (
			evt   Event
			wvars = rtree.WriteVarsFromStruct(&evt)
		)

		tree, err := rtree.NewWriter(f, "mytree", wvars)
		if err != nil {
			log.Fatalf("could not create tree writer: %+v", err)
		}
		defer tree.Close()

		fmt.Printf("-- created tree %q:\n", tree.Name())
		for i, b := range tree.Branches() {
			fmt.Printf("branch[%d]: name=%q, title=%q\n", i, b.Name(), b.Title())
		}

		for i := 0; i < nevts; i++ {
			evt.I32 = int32(i)
			evt.F64 = float64(i)
			evt.Str = fmt.Sprintf("evt-%0d", i)
			evt.Arr = [5]float64{float64(i), float64(i + 1), float64(i + 2), float64(i + 3), float64(i + 4)}
			evt.Sli = []float64{float64(i), float64(i + 1), float64(i + 2), float64(i + 3), float64(i + 4)}[:i]
			evt.P4 = P4{Px: float64(i), Py: float64(i + 1), Pz: float64(i + 2), E: float64(i + 3)}
			evt.Ps = []Particle{
				{ID: int32(i), P4: evt.P4},
				{ID: int32(i + 1), P4: evt.P4},
				{ID: int32(i + 2), P4: evt.P4},
				{ID: int32(i + 3), P4: evt.P4},
				{ID: int32(i + 4), P4: evt.P4},
			}[:i]

			_, err = tree.Write()
			if err != nil {
				log.Fatalf("could not write event %d: %+v", i, err)
			}
		}
		fmt.Printf("-- filled tree with %d entries\n", tree.Entries())

		err = tree.Close()
		if err != nil {
			log.Fatalf("could not write tree: %+v", err)
		}

		err = f.Close()
		if err != nil {
			log.Fatalf("could not close tree: %+v", err)
		}
	}()

	{
		fmt.Printf("-- read back ROOT file\n")
		out := new(bytes.Buffer)
		err := rcmd.List(out, fname, rcmd.ListTrees(true))
		if err != nil {
			log.Fatalf("could not list ROOT file content: %+v", err)
		}
		fmt.Printf("%s\n", out.String())
	}

	{
		var (
			deep   = true
			filter = func(name string) bool { return true }
		)
		out := new(bytes.Buffer)
		err := rcmd.Dump(out, fname, deep, filter)
		if err != nil {
			log.Fatalf("could not dump ROOT file: %+v", err)
		}
		fmt.Printf("%s\n", out.String())
	}

}
Output:

-- created tree "mytree":
branch[0]: name="i32", title="i32/I"
branch[1]: name="f64", title="f64/D"
branch[2]: name="str", title="str/C"
branch[3]: name="arr", title="arr[5]/D"
branch[4]: name="sli", title="sli"
branch[5]: name="p4", title="p4"
branch[6]: name="mc", title="mc"
-- filled tree with 5 entries
-- read back ROOT file
=== [../testdata/groot-event-ntuple-fullsplit.root] ===
version: 62400
  TTree mytree             (entries=5)
    i32 "i32/I"    TBranch
    f64 "f64/D"    TBranch
    str "str/C"    TBranch
    arr "arr[5]/D" TBranch
    sli "sli"      TBranchElement
    p4  "p4"       TBranchElement
    mc  "mc"       TBranchElement

key[000]: mytree;1 "" (TTree)
[000][i32]: 0
[000][f64]: 0
[000][str]: evt-0
[000][arr]: [0 1 2 3 4]
[000][sli]: []
[000][p4]: {0 1 2 3}
[000][mc]: []
[001][i32]: 1
[001][f64]: 1
[001][str]: evt-1
[001][arr]: [1 2 3 4 5]
[001][sli]: [1]
[001][p4]: {1 2 3 4}
[001][mc]: [{1 {1 2 3 4}}]
[002][i32]: 2
[002][f64]: 2
[002][str]: evt-2
[002][arr]: [2 3 4 5 6]
[002][sli]: [2 3]
[002][p4]: {2 3 4 5}
[002][mc]: [{2 {2 3 4 5}} {3 {2 3 4 5}}]
[003][i32]: 3
[003][f64]: 3
[003][str]: evt-3
[003][arr]: [3 4 5 6 7]
[003][sli]: [3 4 5]
[003][p4]: {3 4 5 6}
[003][mc]: [{3 {3 4 5 6}} {4 {3 4 5 6}} {5 {3 4 5 6}}]
[004][i32]: 4
[004][f64]: 4
[004][str]: evt-4
[004][arr]: [4 5 6 7 8]
[004][sli]: [4 5 6 7]
[004][p4]: {4 5 6 7}
[004][mc]: [{4 {4 5 6 7}} {5 {4 5 6 7}} {6 {4 5 6 7}} {7 {4 5 6 7}}]
Example (CreateEventNtupleNoSplit)
package main

import (
	"bytes"
	"fmt"
	"log"
	"reflect"

	"go-hep.org/x/hep/groot"
	"go-hep.org/x/hep/groot/rcmd"
	"go-hep.org/x/hep/groot/rdict"
	"go-hep.org/x/hep/groot/rtree"
)

func main() {
	type P4 struct {
		Px float64 `groot:"px"`
		Py float64 `groot:"py"`
		Pz float64 `groot:"pz"`
		E  float64 `groot:"ene"`
	}

	type Particle struct {
		ID int32 `groot:"id"`
		P4 P4    `groot:"p4"`
	}

	type Event struct {
		I32 int32      `groot:"i32"`
		F64 float64    `groot:"f64"`
		Str string     `groot:"str"`
		Arr [5]float64 `groot:"arr"`
		Sli []float64  `groot:"sli"`
		P4  P4         `groot:"p4"`
		Ps  []Particle `groot:"mc"`
	}

	// register streamers
	for _, typ := range []reflect.Type{
		reflect.TypeOf(P4{}),
		reflect.TypeOf(Particle{}),
		reflect.TypeOf(Event{}),
	} {

		rdict.StreamerInfos.Add(rdict.StreamerOf(
			rdict.StreamerInfos,
			typ,
		))
	}

	const (
		fname = "../testdata/groot-event-ntuple-nosplit.root"
		nevts = 5
	)

	func() {
		f, err := groot.Create(fname)
		if err != nil {
			log.Fatalf("could not create ROOT file: %+v", err)
		}
		defer f.Close()

		var (
			evt   Event
			wvars = []rtree.WriteVar{
				{Name: "evt", Value: &evt},
			}
		)

		tree, err := rtree.NewWriter(f, "mytree", wvars)
		if err != nil {
			log.Fatalf("could not create tree writer: %+v", err)
		}
		defer tree.Close()

		fmt.Printf("-- created tree %q:\n", tree.Name())
		for i, b := range tree.Branches() {
			fmt.Printf("branch[%d]: name=%q, title=%q\n", i, b.Name(), b.Title())
		}

		for i := 0; i < nevts; i++ {
			evt.I32 = int32(i)
			evt.F64 = float64(i)
			evt.Str = fmt.Sprintf("evt-%0d", i)
			evt.Arr = [5]float64{float64(i), float64(i + 1), float64(i + 2), float64(i + 3), float64(i + 4)}
			evt.Sli = []float64{float64(i), float64(i + 1), float64(i + 2), float64(i + 3), float64(i + 4)}[:i]
			evt.P4 = P4{Px: float64(i), Py: float64(i + 1), Pz: float64(i + 2), E: float64(i + 3)}
			evt.Ps = []Particle{
				{ID: int32(i), P4: evt.P4},
				{ID: int32(i + 1), P4: evt.P4},
				{ID: int32(i + 2), P4: evt.P4},
				{ID: int32(i + 3), P4: evt.P4},
				{ID: int32(i + 4), P4: evt.P4},
			}[:i]

			_, err = tree.Write()
			if err != nil {
				log.Fatalf("could not write event %d: %+v", i, err)
			}
		}
		fmt.Printf("-- filled tree with %d entries\n", tree.Entries())

		err = tree.Close()
		if err != nil {
			log.Fatalf("could not write tree: %+v", err)
		}

		err = f.Close()
		if err != nil {
			log.Fatalf("could not close tree: %+v", err)
		}
	}()

	{
		fmt.Printf("-- read back ROOT file\n")
		out := new(bytes.Buffer)
		err := rcmd.List(out, fname, rcmd.ListTrees(true))
		if err != nil {
			log.Fatalf("could not list ROOT file content: %+v", err)
		}
		fmt.Printf("%s\n", out.String())
	}

	{
		var (
			deep   = true
			filter = func(name string) bool { return true }
		)
		out := new(bytes.Buffer)
		err := rcmd.Dump(out, fname, deep, filter)
		if err != nil {
			log.Fatalf("could not dump ROOT file: %+v", err)
		}
		fmt.Printf("%s\n", out.String())
	}

}
Output:

-- created tree "mytree":
branch[0]: name="evt", title="evt"
-- filled tree with 5 entries
-- read back ROOT file
=== [../testdata/groot-event-ntuple-nosplit.root] ===
version: 62400
  TTree mytree          (entries=5)
    evt "evt"   TBranchElement

key[000]: mytree;1 "" (TTree)
[000][evt]: {0 0 evt-0 [0 1 2 3 4] [] {0 1 2 3} []}
[001][evt]: {1 1 evt-1 [1 2 3 4 5] [1] {1 2 3 4} [{1 {1 2 3 4}}]}
[002][evt]: {2 2 evt-2 [2 3 4 5 6] [2 3] {2 3 4 5} [{2 {2 3 4 5}} {3 {2 3 4 5}}]}
[003][evt]: {3 3 evt-3 [3 4 5 6 7] [3 4 5] {3 4 5 6} [{3 {3 4 5 6}} {4 {3 4 5 6}} {5 {3 4 5 6}}]}
[004][evt]: {4 4 evt-4 [4 5 6 7 8] [4 5 6 7] {4 5 6 7} [{4 {4 5 6 7}} {5 {4 5 6 7}} {6 {4 5 6 7}} {7 {4 5 6 7}}]}
Example (CreateFlatNtuple)
package main

import (
	"fmt"
	"log"

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

func main() {
	type Data struct {
		I32    int32
		F64    float64
		Str    string
		ArrF64 [5]float64
		N      int32
		SliF64 []float64
	}
	const (
		fname = "../testdata/groot-flat-ntuple.root"
		nevts = 5
	)
	func() {
		f, err := groot.Create(fname)
		if err != nil {
			log.Fatalf("%+v", err)
		}
		defer f.Close()

		var evt Data

		wvars := []rtree.WriteVar{
			{Name: "I32", Value: &evt.I32},
			{Name: "F64", Value: &evt.F64},
			{Name: "Str", Value: &evt.Str},
			{Name: "ArrF64", Value: &evt.ArrF64},
			{Name: "N", Value: &evt.N},
			{Name: "SliF64", Value: &evt.SliF64, Count: "N"},
		}
		tree, err := rtree.NewWriter(f, "mytree", wvars)
		if err != nil {
			log.Fatalf("could not create tree writer: %+v", err)
		}
		defer tree.Close()

		fmt.Printf("-- created tree %q:\n", tree.Name())
		for i, b := range tree.Branches() {
			fmt.Printf("branch[%d]: name=%q, title=%q\n", i, b.Name(), b.Title())
		}

		for i := 0; i < nevts; i++ {
			evt.I32 = int32(i)
			evt.F64 = float64(i)
			evt.Str = fmt.Sprintf("evt-%0d", i)
			evt.ArrF64 = [5]float64{float64(i), float64(i + 1), float64(i + 2), float64(i + 3), float64(i + 4)}
			evt.N = int32(i)
			evt.SliF64 = []float64{float64(i), float64(i + 1), float64(i + 2), float64(i + 3), float64(i + 4)}[:i]
			_, err = tree.Write()
			if err != nil {
				log.Fatalf("could not write event %d: %+v", i, err)
			}
		}
		fmt.Printf("-- filled tree with %d entries\n", tree.Entries())

		err = tree.Close()
		if err != nil {
			log.Fatalf("could not write tree: %+v", err)
		}

		err = f.Close()
		if err != nil {
			log.Fatalf("could not close tree: %+v", err)
		}
	}()

	func() {
		fmt.Printf("-- read back ROOT file\n")
		f, err := groot.Open(fname)
		if err != nil {
			log.Fatalf("could not open ROOT file: %+v", err)
		}
		defer f.Close()

		obj, err := f.Get("mytree")
		if err != nil {
			log.Fatalf("%+v", err)
		}

		tree := obj.(rtree.Tree)

		var data Data
		r, err := rtree.NewReader(tree, rtree.ReadVarsFromStruct(&data))
		if err != nil {
			log.Fatal(err)
		}
		defer r.Close()

		err = r.Read(func(ctx rtree.RCtx) error {
			fmt.Printf("entry[%d]: %+v\n", ctx.Entry, data)
			return nil
		})

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

}
Output:

-- created tree "mytree":
branch[0]: name="I32", title="I32/I"
branch[1]: name="F64", title="F64/D"
branch[2]: name="Str", title="Str/C"
branch[3]: name="ArrF64", title="ArrF64[5]/D"
branch[4]: name="N", title="N/I"
branch[5]: name="SliF64", title="SliF64[N]/D"
-- filled tree with 5 entries
-- read back ROOT file
entry[0]: {I32:0 F64:0 Str:evt-0 ArrF64:[0 1 2 3 4] N:0 SliF64:[]}
entry[1]: {I32:1 F64:1 Str:evt-1 ArrF64:[1 2 3 4 5] N:1 SliF64:[1]}
entry[2]: {I32:2 F64:2 Str:evt-2 ArrF64:[2 3 4 5 6] N:2 SliF64:[2 3]}
entry[3]: {I32:3 F64:3 Str:evt-3 ArrF64:[3 4 5 6 7] N:3 SliF64:[3 4 5]}
entry[4]: {I32:4 F64:4 Str:evt-4 ArrF64:[4 5 6 7 8] N:4 SliF64:[4 5 6 7]}
Example (CreateFlatNtupleFromStruct)
package main

import (
	"fmt"
	"log"

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

func main() {
	type Data struct {
		I32    int32
		F64    float64
		Str    string
		ArrF64 [5]float64
		N      int32
		SliF64 []float64 `groot:"SliF64[N]"`
	}
	const (
		fname = "../testdata/groot-flat-ntuple-with-struct.root"
		nevts = 5
	)
	func() {
		f, err := groot.Create(fname)
		if err != nil {
			log.Fatalf("%+v", err)
		}
		defer f.Close()

		var evt Data

		tree, err := rtree.NewWriter(f, "mytree", rtree.WriteVarsFromStruct(&evt))
		if err != nil {
			log.Fatalf("could not create tree writer: %+v", err)
		}
		defer tree.Close()

		fmt.Printf("-- created tree %q:\n", tree.Name())
		for i, b := range tree.Branches() {
			fmt.Printf("branch[%d]: name=%q, title=%q\n", i, b.Name(), b.Title())
		}

		for i := 0; i < nevts; i++ {
			evt.I32 = int32(i)
			evt.F64 = float64(i)
			evt.Str = fmt.Sprintf("evt-%0d", i)
			evt.ArrF64 = [5]float64{float64(i), float64(i + 1), float64(i + 2), float64(i + 3), float64(i + 4)}
			evt.N = int32(i)
			evt.SliF64 = []float64{float64(i), float64(i + 1), float64(i + 2), float64(i + 3), float64(i + 4)}[:i]
			_, err = tree.Write()
			if err != nil {
				log.Fatalf("could not write event %d: %+v", i, err)
			}
		}
		fmt.Printf("-- filled tree with %d entries\n", tree.Entries())

		err = tree.Close()
		if err != nil {
			log.Fatalf("could not write tree: %+v", err)
		}

		err = f.Close()
		if err != nil {
			log.Fatalf("could not close tree: %+v", err)
		}
	}()

	func() {
		fmt.Printf("-- read back ROOT file\n")
		f, err := groot.Open(fname)
		if err != nil {
			log.Fatalf("could not open ROOT file: %+v", err)
		}
		defer f.Close()

		obj, err := f.Get("mytree")
		if err != nil {
			log.Fatalf("%+v", err)
		}

		tree := obj.(rtree.Tree)

		var data Data
		r, err := rtree.NewReader(tree, rtree.ReadVarsFromStruct(&data))
		if err != nil {
			log.Fatal(err)
		}
		defer r.Close()

		err = r.Read(func(ctx rtree.RCtx) error {
			fmt.Printf("entry[%d]: %+v\n", ctx.Entry, data)
			return nil
		})

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

}
Output:

-- created tree "mytree":
branch[0]: name="I32", title="I32/I"
branch[1]: name="F64", title="F64/D"
branch[2]: name="Str", title="Str/C"
branch[3]: name="ArrF64", title="ArrF64[5]/D"
branch[4]: name="N", title="N/I"
branch[5]: name="SliF64", title="SliF64[N]/D"
-- filled tree with 5 entries
-- read back ROOT file
entry[0]: {I32:0 F64:0 Str:evt-0 ArrF64:[0 1 2 3 4] N:0 SliF64:[]}
entry[1]: {I32:1 F64:1 Str:evt-1 ArrF64:[1 2 3 4 5] N:1 SliF64:[1]}
entry[2]: {I32:2 F64:2 Str:evt-2 ArrF64:[2 3 4 5 6] N:2 SliF64:[2 3]}
entry[3]: {I32:3 F64:3 Str:evt-3 ArrF64:[3 4 5 6 7] N:3 SliF64:[3 4 5]}
entry[4]: {I32:4 F64:4 Str:evt-4 ArrF64:[4 5 6 7 8] N:4 SliF64:[4 5 6 7]}
Example (CreateFlatNtupleWithLZMA)
package main

import (
	"compress/flate"
	"fmt"
	"log"

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

func main() {
	type Data struct {
		I32    int32
		F64    float64
		Str    string
		ArrF64 [5]float64
		N      int32
		SliF64 []float64
	}
	const (
		fname = "../testdata/groot-flat-ntuple-with-lzma.root"
		nevts = 5
	)
	func() {
		f, err := groot.Create(fname)
		if err != nil {
			log.Fatalf("%+v", err)
		}
		defer f.Close()

		var evt Data

		wvars := []rtree.WriteVar{
			{Name: "I32", Value: &evt.I32},
			{Name: "F64", Value: &evt.F64},
			{Name: "Str", Value: &evt.Str},
			{Name: "ArrF64", Value: &evt.ArrF64},
			{Name: "N", Value: &evt.N},
			{Name: "SliF64", Value: &evt.SliF64, Count: "N"},
		}
		tree, err := rtree.NewWriter(f, "mytree", wvars, rtree.WithLZMA(flate.BestCompression), rtree.WithBasketSize(32*1024))
		if err != nil {
			log.Fatalf("could not create tree writer: %+v", err)
		}
		defer tree.Close()

		fmt.Printf("-- created tree %q:\n", tree.Name())
		for i, b := range tree.Branches() {
			fmt.Printf("branch[%d]: name=%q, title=%q\n", i, b.Name(), b.Title())
		}

		for i := 0; i < nevts; i++ {
			evt.I32 = int32(i)
			evt.F64 = float64(i)
			evt.Str = fmt.Sprintf("evt-%0d", i)
			evt.ArrF64 = [5]float64{float64(i), float64(i + 1), float64(i + 2), float64(i + 3), float64(i + 4)}
			evt.N = int32(i)
			evt.SliF64 = []float64{float64(i), float64(i + 1), float64(i + 2), float64(i + 3), float64(i + 4)}[:i]
			_, err = tree.Write()
			if err != nil {
				log.Fatalf("could not write event %d: %+v", i, err)
			}
		}
		fmt.Printf("-- filled tree with %d entries\n", tree.Entries())

		err = tree.Close()
		if err != nil {
			log.Fatalf("could not write tree: %+v", err)
		}

		err = f.Close()
		if err != nil {
			log.Fatalf("could not close tree: %+v", err)
		}
	}()

	func() {
		fmt.Printf("-- read back ROOT file\n")
		f, err := groot.Open(fname)
		if err != nil {
			log.Fatalf("could not open ROOT file: %+v", err)
		}
		defer f.Close()

		obj, err := f.Get("mytree")
		if err != nil {
			log.Fatalf("%+v", err)
		}

		tree := obj.(rtree.Tree)

		var data Data
		r, err := rtree.NewReader(tree, rtree.ReadVarsFromStruct(&data))
		if err != nil {
			log.Fatal(err)
		}
		defer r.Close()

		err = r.Read(func(ctx rtree.RCtx) error {
			fmt.Printf("entry[%d]: %+v\n", ctx.Entry, data)
			return nil
		})

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

}
Output:

-- created tree "mytree":
branch[0]: name="I32", title="I32/I"
branch[1]: name="F64", title="F64/D"
branch[2]: name="Str", title="Str/C"
branch[3]: name="ArrF64", title="ArrF64[5]/D"
branch[4]: name="N", title="N/I"
branch[5]: name="SliF64", title="SliF64[N]/D"
-- filled tree with 5 entries
-- read back ROOT file
entry[0]: {I32:0 F64:0 Str:evt-0 ArrF64:[0 1 2 3 4] N:0 SliF64:[]}
entry[1]: {I32:1 F64:1 Str:evt-1 ArrF64:[1 2 3 4 5] N:1 SliF64:[1]}
entry[2]: {I32:2 F64:2 Str:evt-2 ArrF64:[2 3 4 5 6] N:2 SliF64:[2 3]}
entry[3]: {I32:3 F64:3 Str:evt-3 ArrF64:[3 4 5 6 7] N:3 SliF64:[3 4 5]}
entry[4]: {I32:4 F64:4 Str:evt-4 ArrF64:[4 5 6 7 8] N:4 SliF64:[4 5 6 7]}

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Copy added in v0.22.0

func Copy(dst Writer, src *Reader) (int64, error)

Copy copies from src to dst until either the reader is depleted or an error occurs. It returns the number of bytes copied and the first error encountered while copying, if any.

func FileOf added in v0.19.0

func FileOf(tree Tree) *riofs.File

FileOf returns the file hosting the given Tree. If the tree is not connected to any ROOT file, nil is returned.

Types

type Basket

type Basket struct {
	// contains filtered or unexported fields
}

func (*Basket) Class

func (b *Basket) Class() string

func (*Basket) MarshalROOT added in v0.20.0

func (b *Basket) MarshalROOT(w *rbytes.WBuffer) (int, error)

func (*Basket) Name

func (b *Basket) Name() string

func (*Basket) RVersion added in v0.20.0

func (*Basket) RVersion() int16

func (*Basket) Title

func (b *Basket) Title() string

func (*Basket) UnmarshalROOT

func (b *Basket) UnmarshalROOT(r *rbytes.RBuffer) error

type Branch

type Branch interface {
	root.Named

	Branches() []Branch
	Leaves() []Leaf
	Branch(name string) Branch
	Leaf(name string) Leaf

	GoType() reflect.Type
	// contains filtered or unexported methods
}

Branch describes a branch of a ROOT Tree.

type Leaf

type Leaf interface {
	root.Named

	Branch() Branch
	HasRange() bool
	IsUnsigned() bool
	LeafCount() Leaf // returns the leaf count if is variable length
	Len() int        // Len returns the number of fixed length elements
	LenType() int    // LenType returns the number of bytes for this data type
	Shape() []int
	Offset() int
	Kind() reflect.Kind
	Type() reflect.Type
	TypeName() string
	// contains filtered or unexported methods
}

Leaf describes branches data types

type LeafB

type LeafB struct {
	// contains filtered or unexported fields
}

LeafB implements ROOT TLeafB

func (*LeafB) Branch

func (leaf *LeafB) Branch() Branch

func (*LeafB) Class

func (leaf *LeafB) Class() string

Class returns the ROOT class name.

func (*LeafB) HasRange

func (leaf *LeafB) HasRange() bool

func (*LeafB) IsUnsigned

func (leaf *LeafB) IsUnsigned() bool

func (*LeafB) Kind

func (leaf *LeafB) Kind() reflect.Kind

Kind returns the leaf's kind.

func (*LeafB) LeafCount

func (leaf *LeafB) LeafCount() Leaf

func (*LeafB) Len

func (leaf *LeafB) Len() int

func (*LeafB) LenType

func (leaf *LeafB) LenType() int

func (*LeafB) MarshalROOT

func (leaf *LeafB) MarshalROOT(w *rbytes.WBuffer) (int, error)

func (*LeafB) Maximum

func (leaf *LeafB) Maximum() int8

Maximum returns the maximum value of the leaf.

func (*LeafB) Minimum

func (leaf *LeafB) Minimum() int8

Minimum returns the minimum value of the leaf.

func (*LeafB) Name

func (leaf *LeafB) Name() string

Name returns the name of the instance

func (*LeafB) Offset

func (leaf *LeafB) Offset() int

func (*LeafB) RVersion added in v0.20.0

func (*LeafB) RVersion() int16

func (*LeafB) Shape added in v0.28.0

func (leaf *LeafB) Shape() []int

func (*LeafB) Title

func (leaf *LeafB) Title() string

Title returns the title of the instance

func (*LeafB) Type

func (leaf *LeafB) Type() reflect.Type

Type returns the leaf's type.

func (*LeafB) TypeName

func (leaf *LeafB) TypeName() string

func (*LeafB) UnmarshalROOT

func (leaf *LeafB) UnmarshalROOT(r *rbytes.RBuffer) error

type LeafC

type LeafC struct {
	// contains filtered or unexported fields
}

LeafC implements ROOT TLeafC

func (*LeafC) Branch

func (leaf *LeafC) Branch() Branch

func (*LeafC) Class

func (leaf *LeafC) Class() string

Class returns the ROOT class name.

func (*LeafC) HasRange

func (leaf *LeafC) HasRange() bool

func (*LeafC) IsUnsigned

func (leaf *LeafC) IsUnsigned() bool

func (*LeafC) Kind

func (leaf *LeafC) Kind() reflect.Kind

Kind returns the leaf's kind.

func (*LeafC) LeafCount

func (leaf *LeafC) LeafCount() Leaf

func (*LeafC) Len

func (leaf *LeafC) Len() int

func (*LeafC) LenType

func (leaf *LeafC) LenType() int

func (*LeafC) MarshalROOT

func (leaf *LeafC) MarshalROOT(w *rbytes.WBuffer) (int, error)

func (*LeafC) Maximum

func (leaf *LeafC) Maximum() int32

Maximum returns the maximum value of the leaf.

func (*LeafC) Minimum

func (leaf *LeafC) Minimum() int32

Minimum returns the minimum value of the leaf.

func (*LeafC) Name

func (leaf *LeafC) Name() string

Name returns the name of the instance

func (*LeafC) Offset

func (leaf *LeafC) Offset() int

func (*LeafC) RVersion added in v0.20.0

func (*LeafC) RVersion() int16

func (*LeafC) Shape added in v0.28.0

func (leaf *LeafC) Shape() []int

func (*LeafC) Title

func (leaf *LeafC) Title() string

Title returns the title of the instance

func (*LeafC) Type

func (leaf *LeafC) Type() reflect.Type

Type returns the leaf's type.

func (*LeafC) TypeName

func (leaf *LeafC) TypeName() string

func (*LeafC) UnmarshalROOT

func (leaf *LeafC) UnmarshalROOT(r *rbytes.RBuffer) error

type LeafD

type LeafD struct {
	// contains filtered or unexported fields
}

LeafD implements ROOT TLeafD

func (*LeafD) Branch

func (leaf *LeafD) Branch() Branch

func (*LeafD) Class

func (leaf *LeafD) Class() string

Class returns the ROOT class name.

func (*LeafD) HasRange

func (leaf *LeafD) HasRange() bool

func (*LeafD) IsUnsigned

func (leaf *LeafD) IsUnsigned() bool

func (*LeafD) Kind

func (leaf *LeafD) Kind() reflect.Kind

Kind returns the leaf's kind.

func (*LeafD) LeafCount

func (leaf *LeafD) LeafCount() Leaf

func (*LeafD) Len

func (leaf *LeafD) Len() int

func (*LeafD) LenType

func (leaf *LeafD) LenType() int

func (*LeafD) MarshalROOT

func (leaf *LeafD) MarshalROOT(w *rbytes.WBuffer) (int, error)

func (*LeafD) Maximum

func (leaf *LeafD) Maximum() float64

Maximum returns the maximum value of the leaf.

func (*LeafD) Minimum

func (leaf *LeafD) Minimum() float64

Minimum returns the minimum value of the leaf.

func (*LeafD) Name

func (leaf *LeafD) Name() string

Name returns the name of the instance

func (*LeafD) Offset

func (leaf *LeafD) Offset() int

func (*LeafD) RVersion added in v0.20.0

func (*LeafD) RVersion() int16

func (*LeafD) Shape added in v0.28.0

func (leaf *LeafD) Shape() []int

func (*LeafD) Title

func (leaf *LeafD) Title() string

Title returns the title of the instance

func (*LeafD) Type

func (leaf *LeafD) Type() reflect.Type

Type returns the leaf's type.

func (*LeafD) TypeName

func (leaf *LeafD) TypeName() string

func (*LeafD) UnmarshalROOT

func (leaf *LeafD) UnmarshalROOT(r *rbytes.RBuffer) error

type LeafD32 added in v0.23.0

type LeafD32 struct {
	// contains filtered or unexported fields
}

LeafD32 implements ROOT TLeafD32

func (*LeafD32) Branch added in v0.23.0

func (leaf *LeafD32) Branch() Branch

func (*LeafD32) Class added in v0.23.0

func (leaf *LeafD32) Class() string

Class returns the ROOT class name.

func (*LeafD32) HasRange added in v0.23.0

func (leaf *LeafD32) HasRange() bool

func (*LeafD32) IsUnsigned added in v0.23.0

func (leaf *LeafD32) IsUnsigned() bool

func (*LeafD32) Kind added in v0.23.0

func (leaf *LeafD32) Kind() reflect.Kind

Kind returns the leaf's kind.

func (*LeafD32) LeafCount added in v0.23.0

func (leaf *LeafD32) LeafCount() Leaf

func (*LeafD32) Len added in v0.23.0

func (leaf *LeafD32) Len() int

func (*LeafD32) LenType added in v0.23.0

func (leaf *LeafD32) LenType() int

func (*LeafD32) MarshalROOT added in v0.23.0

func (leaf *LeafD32) MarshalROOT(w *rbytes.WBuffer) (int, error)

func (*LeafD32) Maximum added in v0.23.0

func (leaf *LeafD32) Maximum() root.Double32

Maximum returns the maximum value of the leaf.

func (*LeafD32) Minimum added in v0.23.0

func (leaf *LeafD32) Minimum() root.Double32

Minimum returns the minimum value of the leaf.

func (*LeafD32) Name added in v0.23.0

func (leaf *LeafD32) Name() string

Name returns the name of the instance

func (*LeafD32) Offset added in v0.23.0

func (leaf *LeafD32) Offset() int

func (*LeafD32) RVersion added in v0.23.0

func (*LeafD32) RVersion() int16

func (*LeafD32) Shape added in v0.28.0

func (leaf *LeafD32) Shape() []int

func (*LeafD32) Title added in v0.23.0

func (leaf *LeafD32) Title() string

Title returns the title of the instance

func (*LeafD32) Type added in v0.23.0

func (leaf *LeafD32) Type() reflect.Type

Type returns the leaf's type.

func (*LeafD32) TypeName added in v0.23.0

func (leaf *LeafD32) TypeName() string

func (*LeafD32) UnmarshalROOT added in v0.23.0

func (leaf *LeafD32) UnmarshalROOT(r *rbytes.RBuffer) error

type LeafF

type LeafF struct {
	// contains filtered or unexported fields
}

LeafF implements ROOT TLeafF

func (*LeafF) Branch

func (leaf *LeafF) Branch() Branch

func (*LeafF) Class

func (leaf *LeafF) Class() string

Class returns the ROOT class name.

func (*LeafF) HasRange

func (leaf *LeafF) HasRange() bool

func (*LeafF) IsUnsigned

func (leaf *LeafF) IsUnsigned() bool

func (*LeafF) Kind

func (leaf *LeafF) Kind() reflect.Kind

Kind returns the leaf's kind.

func (*LeafF) LeafCount

func (leaf *LeafF) LeafCount() Leaf

func (*LeafF) Len

func (leaf *LeafF) Len() int

func (*LeafF) LenType

func (leaf *LeafF) LenType() int

func (*LeafF) MarshalROOT

func (leaf *LeafF) MarshalROOT(w *rbytes.WBuffer) (int, error)

func (*LeafF) Maximum

func (leaf *LeafF) Maximum() float32

Maximum returns the maximum value of the leaf.

func (*LeafF) Minimum

func (leaf *LeafF) Minimum() float32

Minimum returns the minimum value of the leaf.

func (*LeafF) Name

func (leaf *LeafF) Name() string

Name returns the name of the instance

func (*LeafF) Offset

func (leaf *LeafF) Offset() int

func (*LeafF) RVersion added in v0.20.0

func (*LeafF) RVersion() int16

func (*LeafF) Shape added in v0.28.0

func (leaf *LeafF) Shape() []int

func (*LeafF) Title

func (leaf *LeafF) Title() string

Title returns the title of the instance

func (*LeafF) Type

func (leaf *LeafF) Type() reflect.Type

Type returns the leaf's type.

func (*LeafF) TypeName

func (leaf *LeafF) TypeName() string

func (*LeafF) UnmarshalROOT

func (leaf *LeafF) UnmarshalROOT(r *rbytes.RBuffer) error

type LeafF16 added in v0.23.0

type LeafF16 struct {
	// contains filtered or unexported fields
}

LeafF16 implements ROOT TLeafF16

func (*LeafF16) Branch added in v0.23.0

func (leaf *LeafF16) Branch() Branch

func (*LeafF16) Class added in v0.23.0

func (leaf *LeafF16) Class() string

Class returns the ROOT class name.

func (*LeafF16) HasRange added in v0.23.0

func (leaf *LeafF16) HasRange() bool

func (*LeafF16) IsUnsigned added in v0.23.0

func (leaf *LeafF16) IsUnsigned() bool

func (*LeafF16) Kind added in v0.23.0

func (leaf *LeafF16) Kind() reflect.Kind

Kind returns the leaf's kind.

func (*LeafF16) LeafCount added in v0.23.0

func (leaf *LeafF16) LeafCount() Leaf

func (*LeafF16) Len added in v0.23.0

func (leaf *LeafF16) Len() int

func (*LeafF16) LenType added in v0.23.0

func (leaf *LeafF16) LenType() int

func (*LeafF16) MarshalROOT added in v0.23.0

func (leaf *LeafF16) MarshalROOT(w *rbytes.WBuffer) (int, error)

func (*LeafF16) Maximum added in v0.23.0

func (leaf *LeafF16) Maximum() root.Float16

Maximum returns the maximum value of the leaf.

func (*LeafF16) Minimum added in v0.23.0

func (leaf *LeafF16) Minimum() root.Float16

Minimum returns the minimum value of the leaf.

func (*LeafF16) Name added in v0.23.0

func (leaf *LeafF16) Name() string

Name returns the name of the instance

func (*LeafF16) Offset added in v0.23.0

func (leaf *LeafF16) Offset() int

func (*LeafF16) RVersion added in v0.23.0

func (*LeafF16) RVersion() int16

func (*LeafF16) Shape added in v0.28.0

func (leaf *LeafF16) Shape() []int

func (*LeafF16) Title added in v0.23.0

func (leaf *LeafF16) Title() string

Title returns the title of the instance

func (*LeafF16) Type added in v0.23.0

func (leaf *LeafF16) Type() reflect.Type

Type returns the leaf's type.

func (*LeafF16) TypeName added in v0.23.0

func (leaf *LeafF16) TypeName() string

func (*LeafF16) UnmarshalROOT added in v0.23.0

func (leaf *LeafF16) UnmarshalROOT(r *rbytes.RBuffer) error

type LeafI

type LeafI struct {
	// contains filtered or unexported fields
}

LeafI implements ROOT TLeafI

func (*LeafI) Branch

func (leaf *LeafI) Branch() Branch

func (*LeafI) Class

func (leaf *LeafI) Class() string

Class returns the ROOT class name.

func (*LeafI) HasRange

func (leaf *LeafI) HasRange() bool

func (*LeafI) IsUnsigned

func (leaf *LeafI) IsUnsigned() bool

func (*LeafI) Kind

func (leaf *LeafI) Kind() reflect.Kind

Kind returns the leaf's kind.

func (*LeafI) LeafCount

func (leaf *LeafI) LeafCount() Leaf

func (*LeafI) Len

func (leaf *LeafI) Len() int

func (*LeafI) LenType

func (leaf *LeafI) LenType() int

func (*LeafI) MarshalROOT

func (leaf *LeafI) MarshalROOT(w *rbytes.WBuffer) (int, error)

func (*LeafI) Maximum

func (leaf *LeafI) Maximum() int32

Maximum returns the maximum value of the leaf.

func (*LeafI) Minimum

func (leaf *LeafI) Minimum() int32

Minimum returns the minimum value of the leaf.

func (*LeafI) Name

func (leaf *LeafI) Name() string

Name returns the name of the instance

func (*LeafI) Offset

func (leaf *LeafI) Offset() int

func (*LeafI) RVersion added in v0.20.0

func (*LeafI) RVersion() int16

func (*LeafI) Shape added in v0.28.0

func (leaf *LeafI) Shape() []int

func (*LeafI) Title

func (leaf *LeafI) Title() string

Title returns the title of the instance

func (*LeafI) Type

func (leaf *LeafI) Type() reflect.Type

Type returns the leaf's type.

func (*LeafI) TypeName

func (leaf *LeafI) TypeName() string

func (*LeafI) UnmarshalROOT

func (leaf *LeafI) UnmarshalROOT(r *rbytes.RBuffer) error

type LeafL

type LeafL struct {
	// contains filtered or unexported fields
}

LeafL implements ROOT TLeafL

func (*LeafL) Branch

func (leaf *LeafL) Branch() Branch

func (*LeafL) Class

func (leaf *LeafL) Class() string

Class returns the ROOT class name.

func (*LeafL) HasRange

func (leaf *LeafL) HasRange() bool

func (*LeafL) IsUnsigned

func (leaf *LeafL) IsUnsigned() bool

func (*LeafL) Kind

func (leaf *LeafL) Kind() reflect.Kind

Kind returns the leaf's kind.

func (*LeafL) LeafCount

func (leaf *LeafL) LeafCount() Leaf

func (*LeafL) Len

func (leaf *LeafL) Len() int

func (*LeafL) LenType

func (leaf *LeafL) LenType() int

func (*LeafL) MarshalROOT

func (leaf *LeafL) MarshalROOT(w *rbytes.WBuffer) (int, error)

func (*LeafL) Maximum

func (leaf *LeafL) Maximum() int64

Maximum returns the maximum value of the leaf.

func (*LeafL) Minimum

func (leaf *LeafL) Minimum() int64

Minimum returns the minimum value of the leaf.

func (*LeafL) Name

func (leaf *LeafL) Name() string

Name returns the name of the instance

func (*LeafL) Offset

func (leaf *LeafL) Offset() int

func (*LeafL) RVersion added in v0.20.0

func (*LeafL) RVersion() int16

func (*LeafL) Shape added in v0.28.0

func (leaf *LeafL) Shape() []int

func (*LeafL) Title

func (leaf *LeafL) Title() string

Title returns the title of the instance

func (*LeafL) Type

func (leaf *LeafL) Type() reflect.Type

Type returns the leaf's type.

func (*LeafL) TypeName

func (leaf *LeafL) TypeName() string

func (*LeafL) UnmarshalROOT

func (leaf *LeafL) UnmarshalROOT(r *rbytes.RBuffer) error

type LeafO

type LeafO struct {
	// contains filtered or unexported fields
}

LeafO implements ROOT TLeafO

func (*LeafO) Branch

func (leaf *LeafO) Branch() Branch

func (*LeafO) Class

func (leaf *LeafO) Class() string

Class returns the ROOT class name.

func (*LeafO) HasRange

func (leaf *LeafO) HasRange() bool

func (*LeafO) IsUnsigned

func (leaf *LeafO) IsUnsigned() bool

func (*LeafO) Kind

func (leaf *LeafO) Kind() reflect.Kind

Kind returns the leaf's kind.

func (*LeafO) LeafCount

func (leaf *LeafO) LeafCount() Leaf

func (*LeafO) Len

func (leaf *LeafO) Len() int

func (*LeafO) LenType

func (leaf *LeafO) LenType() int

func (*LeafO) MarshalROOT

func (leaf *LeafO) MarshalROOT(w *rbytes.WBuffer) (int, error)

func (*LeafO) Maximum

func (leaf *LeafO) Maximum() bool

Maximum returns the maximum value of the leaf.

func (*LeafO) Minimum

func (leaf *LeafO) Minimum() bool

Minimum returns the minimum value of the leaf.

func (*LeafO) Name

func (leaf *LeafO) Name() string

Name returns the name of the instance

func (*LeafO) Offset

func (leaf *LeafO) Offset() int

func (*LeafO) RVersion added in v0.20.0

func (*LeafO) RVersion() int16

func (*LeafO) Shape added in v0.28.0

func (leaf *LeafO) Shape() []int

func (*LeafO) Title

func (leaf *LeafO) Title() string

Title returns the title of the instance

func (*LeafO) Type

func (leaf *LeafO) Type() reflect.Type

Type returns the leaf's type.

func (*LeafO) TypeName

func (leaf *LeafO) TypeName() string

func (*LeafO) UnmarshalROOT

func (leaf *LeafO) UnmarshalROOT(r *rbytes.RBuffer) error

type LeafS

type LeafS struct {
	// contains filtered or unexported fields
}

LeafS implements ROOT TLeafS

func (*LeafS) Branch

func (leaf *LeafS) Branch() Branch

func (*LeafS) Class

func (leaf *LeafS) Class() string

Class returns the ROOT class name.

func (*LeafS) HasRange

func (leaf *LeafS) HasRange() bool

func (*LeafS) IsUnsigned

func (leaf *LeafS) IsUnsigned() bool

func (*LeafS) Kind

func (leaf *LeafS) Kind() reflect.Kind

Kind returns the leaf's kind.

func (*LeafS) LeafCount

func (leaf *LeafS) LeafCount() Leaf

func (*LeafS) Len

func (leaf *LeafS) Len() int

func (*LeafS) LenType

func (leaf *LeafS) LenType() int

func (*LeafS) MarshalROOT

func (leaf *LeafS) MarshalROOT(w *rbytes.WBuffer) (int, error)

func (*LeafS) Maximum

func (leaf *LeafS) Maximum() int16

Maximum returns the maximum value of the leaf.

func (*LeafS) Minimum

func (leaf *LeafS) Minimum() int16

Minimum returns the minimum value of the leaf.

func (*LeafS) Name

func (leaf *LeafS) Name() string

Name returns the name of the instance

func (*LeafS) Offset

func (leaf *LeafS) Offset() int

func (*LeafS) RVersion added in v0.20.0

func (*LeafS) RVersion() int16

func (*LeafS) Shape added in v0.28.0

func (leaf *LeafS) Shape() []int

func (*LeafS) Title

func (leaf *LeafS) Title() string

Title returns the title of the instance

func (*LeafS) Type

func (leaf *LeafS) Type() reflect.Type

Type returns the leaf's type.

func (*LeafS) TypeName

func (leaf *LeafS) TypeName() string

func (*LeafS) UnmarshalROOT

func (leaf *LeafS) UnmarshalROOT(r *rbytes.RBuffer) error

type RCtx added in v0.25.0

type RCtx struct {
	Entry int64 // Current tree entry.
}

RCtx provides an entry-wise local context to the tree Reader.

type ReadOption added in v0.25.0

type ReadOption func(r *Reader) error

ReadOption configures how a ROOT tree should be traversed.

func WithPrefetchBaskets added in v0.27.0

func WithPrefetchBaskets(n int) ReadOption

WithPrefetchBaskets specifies the number of baskets to read-ahead, per branch. The default is 2. The number of prefetch baskets is cap'ed by the number of baskets, per branch.

func WithRange added in v0.25.0

func WithRange(beg, end int64) ReadOption

WithRange specifies the half-open interval [beg, end) of entries a Tree reader will read through.

type ReadVar added in v0.25.0

type ReadVar struct {
	Name  string      // name of the branch to read
	Leaf  string      // name of the leaf to read
	Value interface{} // pointer to the value to fill
	// contains filtered or unexported fields
}

ReadVar describes a variable to be read out of a tree.

func NewReadVars added in v0.25.0

func NewReadVars(t Tree) []ReadVar

NewReadVars returns the complete set of ReadVars to read all the data contained in the provided Tree.

func ReadVarsFromStruct added in v0.26.0

func ReadVarsFromStruct(ptr interface{}) []ReadVar

ReadVarsFromStruct returns a list of ReadVars bound to the exported fields of the provided pointer to a struct value.

ReadVarsFromStruct panicks if the provided value is not a pointer to a struct value.

func (ReadVar) Deref added in v0.28.0

func (rv ReadVar) Deref() interface{}

Deref returns the value pointed at by this read-var.

type Reader added in v0.25.0

type Reader struct {
	// contains filtered or unexported fields
}

Reader reads data from a Tree.

Example
package main

import (
	"fmt"
	"log"

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

func main() {
	f, err := groot.Open("../testdata/simple.root")
	if err != nil {
		log.Fatalf("could not open ROOT file: %+v", err)
	}
	defer f.Close()

	o, err := f.Get("tree")
	if err != nil {
		log.Fatalf("could not retrieve ROOT tree: %+v", err)
	}
	t := o.(rtree.Tree)

	var (
		v1 int32
		v2 float32
		v3 string

		rvars = []rtree.ReadVar{
			{Name: "one", Value: &v1},
			{Name: "two", Value: &v2},
			{Name: "three", Value: &v3},
		}
	)

	r, err := rtree.NewReader(t, rvars)
	if err != nil {
		log.Fatalf("could not create tree reader: %+v", err)
	}
	defer r.Close()

	err = r.Read(func(ctx rtree.RCtx) error {
		fmt.Printf("evt[%d]: %v, %v, %v\n", ctx.Entry, v1, v2, v3)
		return nil
	})
	if err != nil {
		log.Fatalf("could not process tree: %+v", err)
	}

}
Output:

evt[0]: 1, 1.1, uno
evt[1]: 2, 2.2, dos
evt[2]: 3, 3.3, tres
evt[3]: 4, 4.4, quatro
Example (WithChain)
package main

import (
	"fmt"
	"log"

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

func main() {
	f, err := groot.Open("../testdata/simple.root")
	if err != nil {
		log.Fatalf("could not open ROOT file: %+v", err)
	}
	defer f.Close()

	o, err := f.Get("tree")
	if err != nil {
		log.Fatalf("could not retrieve ROOT tree: %+v", err)
	}
	t := o.(rtree.Tree)

	t = rtree.Chain(t, t, t, t)

	var (
		v1 int32
		v2 float32
		v3 string

		rvars = []rtree.ReadVar{
			{Name: "one", Value: &v1},
			{Name: "two", Value: &v2},
			{Name: "three", Value: &v3},
		}
	)

	r, err := rtree.NewReader(t, rvars,
		rtree.WithRange(0, -1),
		rtree.WithPrefetchBaskets(2),
	)
	if err != nil {
		log.Fatalf("could not create tree reader: %+v", err)
	}
	defer r.Close()

	err = r.Read(func(ctx rtree.RCtx) error {
		fmt.Printf("evt[%d]: %v, %v, %v\n", ctx.Entry, v1, v2, v3)
		return nil
	})
	if err != nil {
		log.Fatalf("could not process tree: %+v", err)
	}

}
Output:

evt[0]: 1, 1.1, uno
evt[1]: 2, 2.2, dos
evt[2]: 3, 3.3, tres
evt[3]: 4, 4.4, quatro
evt[4]: 1, 1.1, uno
evt[5]: 2, 2.2, dos
evt[6]: 3, 3.3, tres
evt[7]: 4, 4.4, quatro
evt[8]: 1, 1.1, uno
evt[9]: 2, 2.2, dos
evt[10]: 3, 3.3, tres
evt[11]: 4, 4.4, quatro
evt[12]: 1, 1.1, uno
evt[13]: 2, 2.2, dos
evt[14]: 3, 3.3, tres
evt[15]: 4, 4.4, quatro
Example (WithFormulaFromUser)
package main

import (
	"fmt"
	"log"

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

type UsrF64 struct {
	rvars []string
	v1    *int32
	v2    *float32
	v3    *string
	fct   func(int32, float32, string) float64
}

func (usr *UsrF64) RVars() []string { return usr.rvars }
func (usr *UsrF64) Bind(args []interface{}) error {
	if got, want := len(args), 3; got != want {
		return fmt.Errorf(
			"rfunc: invalid number of bind arguments (got=%d, want=%d)",
			got, want,
		)
	}
	usr.v1 = args[0].(*int32)
	usr.v2 = args[1].(*float32)
	usr.v3 = args[2].(*string)
	return nil
}

func (usr *UsrF64) Func() interface{} {
	return func() float64 {
		return usr.fct(*usr.v1, *usr.v2, *usr.v3)
	}
}

type UsrStr struct {
	rvars []string
	v1    *int32
	v2    *float32
	v3    *string
	fct   func(int32, float32, string) string
}

func (usr *UsrStr) RVars() []string { return usr.rvars }
func (usr *UsrStr) Bind(args []interface{}) error {
	if got, want := len(args), 3; got != want {
		return fmt.Errorf(
			"rfunc: invalid number of bind arguments (got=%d, want=%d)",
			got, want,
		)
	}
	usr.v1 = args[0].(*int32)
	usr.v2 = args[1].(*float32)
	usr.v3 = args[2].(*string)
	return nil
}

func (usr *UsrStr) Func() interface{} {
	return func() string {
		return usr.fct(*usr.v1, *usr.v2, *usr.v3)
	}
}

func main() {
	f, err := groot.Open("../testdata/simple.root")
	if err != nil {
		log.Fatalf("could not open ROOT file: %+v", err)
	}
	defer f.Close()

	o, err := f.Get("tree")
	if err != nil {
		log.Fatalf("could not retrieve ROOT tree: %+v", err)
	}
	t := o.(rtree.Tree)

	var (
		data struct {
			V1 int32   `groot:"one"`
			V2 float32 `groot:"two"`
			V3 string  `groot:"three"`
		}
		rvars = rtree.ReadVarsFromStruct(&data)
	)

	r, err := rtree.NewReader(t, rvars)
	if err != nil {
		log.Fatalf("could not create tree reader: %+v", err)
	}
	defer r.Close()

	f64, err := r.Formula(&UsrF64{
		rvars: []string{"one", "two", "three"},
		fct: func(v1 int32, v2 float32, v3 string) float64 {
			return float64(v2*10) + float64(1000*v1) + float64(100*len(v3))
		},
	})
	if err != nil {
		log.Fatalf("could not create formula: %+v", err)
	}

	fstr, err := r.Formula(&UsrStr{
		rvars: []string{"one", "two", "three"},
		fct: func(v1 int32, v2 float32, v3 string) string {
			return fmt.Sprintf(
				"%q: %v, %q: %v, %q: %v",
				"one", v1, "two", v2, "three", v3,
			)
		},
	})
	if err != nil {
		log.Fatalf("could not create formula: %+v", err)
	}

	f1 := f64.Func().(func() float64)
	f2 := fstr.Func().(func() string)

	err = r.Read(func(ctx rtree.RCtx) error {
		v64 := f1()
		str := f2()
		fmt.Printf("evt[%d]: %v, %v, %v -> %g | %s\n", ctx.Entry, data.V1, data.V2, data.V3, v64, str)
		return nil
	})
	if err != nil {
		log.Fatalf("could not process tree: %+v", err)
	}

}
Output:

evt[0]: 1, 1.1, uno -> 1311 | "one": 1, "two": 1.1, "three": uno
evt[1]: 2, 2.2, dos -> 2322 | "one": 2, "two": 2.2, "three": dos
evt[2]: 3, 3.3, tres -> 3433 | "one": 3, "two": 3.3, "three": tres
evt[3]: 4, 4.4, quatro -> 4644 | "one": 4, "two": 4.4, "three": quatro
Example (WithFormulaFunc)
package main

import (
	"fmt"
	"log"

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

func main() {
	f, err := groot.Open("../testdata/simple.root")
	if err != nil {
		log.Fatalf("could not open ROOT file: %+v", err)
	}
	defer f.Close()

	o, err := f.Get("tree")
	if err != nil {
		log.Fatalf("could not retrieve ROOT tree: %+v", err)
	}
	t := o.(rtree.Tree)

	var (
		data struct {
			V1 int32   `groot:"one"`
			V2 float32 `groot:"two"`
			V3 string  `groot:"three"`
		}
		rvars = rtree.ReadVarsFromStruct(&data)
	)

	r, err := rtree.NewReader(t, rvars)
	if err != nil {
		log.Fatalf("could not create tree reader: %+v", err)
	}
	defer r.Close()

	f64, err := r.FormulaFunc(
		[]string{"one", "two", "three"},
		func(v1 int32, v2 float32, v3 string) float64 {
			return float64(v2*10) + float64(1000*v1) + float64(100*len(v3))
		},
	)
	if err != nil {
		log.Fatalf("could not create formula: %+v", err)
	}

	fstr, err := r.FormulaFunc(
		[]string{"one", "two", "three"},
		func(v1 int32, v2 float32, v3 string) string {
			return fmt.Sprintf(
				"%q: %v, %q: %v, %q: %v",
				"one", v1, "two", v2, "three", v3,
			)
		},
	)
	if err != nil {
		log.Fatalf("could not create formula: %+v", err)
	}

	f1 := f64.Func().(func() float64)
	f2 := fstr.Func().(func() string)

	err = r.Read(func(ctx rtree.RCtx) error {
		v64 := f1()
		str := f2()
		fmt.Printf("evt[%d]: %v, %v, %v -> %g | %s\n", ctx.Entry, data.V1, data.V2, data.V3, v64, str)
		return nil
	})
	if err != nil {
		log.Fatalf("could not process tree: %+v", err)
	}

}
Output:

evt[0]: 1, 1.1, uno -> 1311 | "one": 1, "two": 1.1, "three": uno
evt[1]: 2, 2.2, dos -> 2322 | "one": 2, "two": 2.2, "three": dos
evt[2]: 3, 3.3, tres -> 3433 | "one": 3, "two": 3.3, "three": tres
evt[3]: 4, 4.4, quatro -> 4644 | "one": 4, "two": 4.4, "three": quatro
Example (WithRange)
package main

import (
	"fmt"
	"log"

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

func main() {
	f, err := groot.Open("../testdata/simple.root")
	if err != nil {
		log.Fatalf("could not open ROOT file: %+v", err)
	}
	defer f.Close()

	o, err := f.Get("tree")
	if err != nil {
		log.Fatalf("could not retrieve ROOT tree: %+v", err)
	}
	t := o.(rtree.Tree)

	var (
		v1 int32
		v2 float32
		v3 string

		rvars = []rtree.ReadVar{
			{Name: "one", Value: &v1},
			{Name: "two", Value: &v2},
			{Name: "three", Value: &v3},
		}
	)

	r, err := rtree.NewReader(t, rvars, rtree.WithRange(1, 3))
	if err != nil {
		log.Fatalf("could not create tree reader: %+v", err)
	}
	defer r.Close()

	err = r.Read(func(ctx rtree.RCtx) error {
		fmt.Printf("evt[%d]: %v, %v, %v\n", ctx.Entry, v1, v2, v3)
		return nil
	})
	if err != nil {
		log.Fatalf("could not process tree: %+v", err)
	}

}
Output:

evt[1]: 2, 2.2, dos
evt[2]: 3, 3.3, tres
Example (WithReadVarsFromStruct)
package main

import (
	"fmt"
	"log"

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

func main() {
	f, err := groot.Open("../testdata/simple.root")
	if err != nil {
		log.Fatalf("could not open ROOT file: %+v", err)
	}
	defer f.Close()

	o, err := f.Get("tree")
	if err != nil {
		log.Fatalf("could not retrieve ROOT tree: %+v", err)
	}
	t := o.(rtree.Tree)

	var (
		data struct {
			V1 int32   `groot:"one"`
			V2 float32 `groot:"two"`
			V3 string  `groot:"three"`
		}
		rvars = rtree.ReadVarsFromStruct(&data)
	)

	r, err := rtree.NewReader(t, rvars)
	if err != nil {
		log.Fatalf("could not create tree reader: %+v", err)
	}
	defer r.Close()

	err = r.Read(func(ctx rtree.RCtx) error {
		fmt.Printf("evt[%d]: %v, %v, %v\n", ctx.Entry, data.V1, data.V2, data.V3)
		return nil
	})
	if err != nil {
		log.Fatalf("could not process tree: %+v", err)
	}

}
Output:

evt[0]: 1, 1.1, uno
evt[1]: 2, 2.2, dos
evt[2]: 3, 3.3, tres
evt[3]: 4, 4.4, quatro
Example (WithReset)
package main

import (
	"fmt"
	"log"

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

func main() {
	f, err := groot.Open("../testdata/simple.root")
	if err != nil {
		log.Fatalf("could not open ROOT file: %+v", err)
	}
	defer f.Close()

	o, err := f.Get("tree")
	if err != nil {
		log.Fatalf("could not retrieve ROOT tree: %+v", err)
	}
	t := o.(rtree.Tree)

	var (
		v1 int32
		v2 float32
		v3 string

		rvars = []rtree.ReadVar{
			{Name: "one", Value: &v1},
			{Name: "two", Value: &v2},
			{Name: "three", Value: &v3},
		}
	)

	r, err := rtree.NewReader(t, rvars)
	if err != nil {
		log.Fatalf("could not create tree reader: %+v", err)
	}
	defer r.Close()

	err = r.Reset()
	if err != nil {
		log.Fatalf("could not reset tree reader: %+v", err)
	}

	err = r.Reset(rtree.WithRange(1, 3))
	if err != nil {
		log.Fatalf("could not reset tree reader: %+v", err)
	}

	err = r.Read(func(ctx rtree.RCtx) error {
		fmt.Printf("evt[%d]: %v, %v, %v\n", ctx.Entry, v1, v2, v3)
		return nil
	})
	if err != nil {
		log.Fatalf("could not process tree: %+v", err)
	}

}
Output:

evt[1]: 2, 2.2, dos
evt[2]: 3, 3.3, tres

func NewReader added in v0.25.0

func NewReader(t Tree, rvars []ReadVar, opts ...ReadOption) (*Reader, error)

NewReader creates a new Tree Reader from the provided ROOT Tree and the set of read-variables into which data will be read.

func (*Reader) Close added in v0.25.0

func (r *Reader) Close() error

Close closes the Reader.

func (*Reader) Formula added in v0.26.0

func (r *Reader) Formula(f rfunc.Formula) (rfunc.Formula, error)

Formula creates a new formula based on the provided user provided formula. Formula binds the provided function with the requested list of leaves.

func (*Reader) FormulaFunc added in v0.27.0

func (r *Reader) FormulaFunc(branches []string, fct interface{}) (rfunc.Formula, error)

FormulaFunc creates a new formula based on the provided function and the list of branches as inputs.

func (*Reader) Read added in v0.25.0

func (r *Reader) Read(f func(ctx RCtx) error) error

Read will read data from the underlying tree over the whole specified range. Read calls the provided user function f for each entry successfully read.

func (*Reader) Reset added in v0.28.0

func (r *Reader) Reset(opts ...ReadOption) error

Reset resets the current Reader with the provided options.

type Tree

type Tree interface {
	root.Named

	Entries() int64
	Branch(name string) Branch
	Branches() []Branch
	Leaf(name string) Leaf
	Leaves() []Leaf
}

func Chain

func Chain(trees ...Tree) Tree

Chain returns a Tree that is the concatenation of all the input Trees.

Example

ExampleChain shows how to create a chain made of 2 trees.

package main

import (
	"fmt"
	"log"

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

func main() {
	const name = "tree"

	f1, err := groot.Open("../testdata/chain.1.root")
	if err != nil {
		log.Fatal(err)
	}
	defer f1.Close()

	o1, err := f1.Get(name)
	if err != nil {
		log.Fatal(err)
	}
	t1 := o1.(rtree.Tree)

	f2, err := groot.Open("../testdata/chain.2.root")
	if err != nil {
		log.Fatal(err)
	}
	defer f2.Close()

	o2, err := f2.Get(name)
	if err != nil {
		log.Fatal(err)
	}
	t2 := o2.(rtree.Tree)

	chain := rtree.Chain(t1, t2)

	type Data struct {
		Event struct {
			Beg       string      `groot:"Beg"`
			F64       float64     `groot:"F64"`
			ArrF64    [10]float64 `groot:"ArrayF64"`
			N         int32       `groot:"N"`
			SliF64    []float64   `groot:"SliceF64"`
			StdStr    string      `groot:"StdStr"`
			StlVecF64 []float64   `groot:"StlVecF64"`
			StlVecStr []string    `groot:"StlVecStr"`
			End       string      `groot:"End"`
		} `groot:"evt"`
	}

	var data Data
	r, err := rtree.NewReader(chain, rtree.ReadVarsFromStruct(&data))
	if err != nil {
		log.Fatal(err)
	}
	defer r.Close()

	err = r.Read(func(ctx rtree.RCtx) error {
		fmt.Printf(
			"entry[%02d]: beg=%q f64=%v\n",
			ctx.Entry, data.Event.Beg, data.Event.F64,
		)
		return nil
	})

	if err != nil {
		log.Fatalf("error during scan: %v", err)
	}

}
Output:

entry[00]: beg="beg-000" f64=0
entry[01]: beg="beg-001" f64=1
entry[02]: beg="beg-002" f64=2
entry[03]: beg="beg-003" f64=3
entry[04]: beg="beg-004" f64=4
entry[05]: beg="beg-005" f64=5
entry[06]: beg="beg-006" f64=6
entry[07]: beg="beg-007" f64=7
entry[08]: beg="beg-008" f64=8
entry[09]: beg="beg-009" f64=9
entry[10]: beg="beg-010" f64=10
entry[11]: beg="beg-011" f64=11
entry[12]: beg="beg-012" f64=12
entry[13]: beg="beg-013" f64=13
entry[14]: beg="beg-014" f64=14
entry[15]: beg="beg-015" f64=15
entry[16]: beg="beg-016" f64=16
entry[17]: beg="beg-017" f64=17
entry[18]: beg="beg-018" f64=18
entry[19]: beg="beg-019" f64=19

func ChainOf

func ChainOf(name string, files ...string) (Tree, func() error, error)

ChainOf returns a Tree, a close function and an error if any. The tree is the logical concatenation of all the name trees located in the input named files. The close function allows to close all the open named files.

Example

ExampleChainOf shows how to create a chain made of trees from 2 files.

package main

import (
	"fmt"
	"log"

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

func main() {
	const name = "tree"

	chain, closer, err := rtree.ChainOf(name, "../testdata/chain.1.root", "../testdata/chain.2.root")
	if err != nil {
		log.Fatal(err)
	}
	defer func() {
		err = closer()
		if err != nil {
			log.Fatalf("could not close ROOT chain: %+v", err)
		}
	}()

	type Data struct {
		Event struct {
			Beg       string      `groot:"Beg"`
			F64       float64     `groot:"F64"`
			ArrF64    [10]float64 `groot:"ArrayF64"`
			N         int32       `groot:"N"`
			SliF64    []float64   `groot:"SliceF64"`
			StdStr    string      `groot:"StdStr"`
			StlVecF64 []float64   `groot:"StlVecF64"`
			StlVecStr []string    `groot:"StlVecStr"`
			End       string      `groot:"End"`
		} `groot:"evt"`
	}

	var data Data
	r, err := rtree.NewReader(chain, rtree.ReadVarsFromStruct(&data))
	if err != nil {
		log.Fatal(err)
	}
	defer r.Close()

	err = r.Read(func(ctx rtree.RCtx) error {
		fmt.Printf(
			"entry[%02d]: beg=%q f64=%v\n",
			ctx.Entry, data.Event.Beg, data.Event.F64,
		)
		return nil
	})

	if err != nil {
		log.Fatalf("error during scan: %v", err)
	}

}
Output:

entry[00]: beg="beg-000" f64=0
entry[01]: beg="beg-001" f64=1
entry[02]: beg="beg-002" f64=2
entry[03]: beg="beg-003" f64=3
entry[04]: beg="beg-004" f64=4
entry[05]: beg="beg-005" f64=5
entry[06]: beg="beg-006" f64=6
entry[07]: beg="beg-007" f64=7
entry[08]: beg="beg-008" f64=8
entry[09]: beg="beg-009" f64=9
entry[10]: beg="beg-010" f64=10
entry[11]: beg="beg-011" f64=11
entry[12]: beg="beg-012" f64=12
entry[13]: beg="beg-013" f64=13
entry[14]: beg="beg-014" f64=14
entry[15]: beg="beg-015" f64=15
entry[16]: beg="beg-016" f64=16
entry[17]: beg="beg-017" f64=17
entry[18]: beg="beg-018" f64=18
entry[19]: beg="beg-019" f64=19

func Join added in v0.28.0

func Join(trees ...Tree) (Tree, error)

Join returns a new Tree that represents the logical join of the input trees. The returned tree will contain all the columns of all the input trees. Join errors out if the input slice of trees is empty. Join errors out if the input trees do not have the same amount of entries. Join errors out if two trees have each a column with the same name.

Example
package main

import (
	"fmt"
	"log"

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

func main() {

	get := func(fname, tname string) (rtree.Tree, func() error) {
		f, err := groot.Open(fname)
		if err != nil {
			log.Fatal(err)
		}
		t, err := f.Get(tname)
		if err != nil {
			_ = f.Close()
			log.Fatal(err)
		}
		return t.(rtree.Tree), f.Close
	}
	chk := func(f func() error) {
		err := f()
		if err != nil {
			log.Fatal(err)
		}
	}

	t1, f1 := get("../testdata/join1.root", "j1")
	defer chk(f1)

	t2, f2 := get("../testdata/join2.root", "j2")
	defer chk(f2)

	t3, f3 := get("../testdata/join3.root", "j3")
	defer chk(f3)

	join, err := rtree.Join(t1, t2, t3)
	if err != nil {
		log.Fatalf("could not join trees: %+v", err)
	}

	fmt.Printf("t1:   %s (nevts=%d)\n", t1.Name(), t1.Entries())
	fmt.Printf("t2:   %s (nevts=%d)\n", t2.Name(), t2.Entries())
	fmt.Printf("t3:   %s (nevts=%d)\n", t3.Name(), t3.Entries())
	fmt.Printf("join: %s\n", join.Name())
	fmt.Printf("entries: %d\n", join.Entries())

	rvars := rtree.NewReadVars(join)
	r, err := rtree.NewReader(join, rvars)
	if err != nil {
		log.Fatalf("could not create reader for joined trees: %+v", err)
	}
	defer r.Close()

	rf1, err := r.FormulaFunc(
		[]string{"b10", "b30", "b20"},
		func(b1, b3, b2 float64) float64 {
			return b1 + b2 + b3
		},
	)
	if err != nil {
		log.Fatalf("could not bind formula: %+v", err)
	}
	fct1 := rf1.Func().(func() float64)

	err = r.Read(func(rctx rtree.RCtx) error {
		for _, rv := range rvars {
			fmt.Printf("join[%03d][%s]: %v\n", rctx.Entry, rv.Name, rv.Deref())
		}
		fmt.Printf("join[%03d][fun]: %v\n", rctx.Entry, fct1())
		return nil
	})

	if err != nil {
		log.Fatalf("could not process events: %+v", err)
	}

}
Output:

t1:   j1 (nevts=10)
t2:   j2 (nevts=10)
t3:   j3 (nevts=10)
join: join_j1_j2_j3
entries: 10
join[000][b10]: 101
join[000][b11]: 101
join[000][b12]: j1-101
join[000][b20]: 201
join[000][b21]: 201
join[000][b22]: j2-201
join[000][b30]: 301
join[000][b31]: 301
join[000][b32]: j3-301
join[000][fun]: 603
join[001][b10]: 102
join[001][b11]: 102
join[001][b12]: j1-102
join[001][b20]: 202
join[001][b21]: 202
join[001][b22]: j2-202
join[001][b30]: 302
join[001][b31]: 302
join[001][b32]: j3-302
join[001][fun]: 606
join[002][b10]: 103
join[002][b11]: 103
join[002][b12]: j1-103
join[002][b20]: 203
join[002][b21]: 203
join[002][b22]: j2-203
join[002][b30]: 303
join[002][b31]: 303
join[002][b32]: j3-303
join[002][fun]: 609
join[003][b10]: 104
join[003][b11]: 104
join[003][b12]: j1-104
join[003][b20]: 204
join[003][b21]: 204
join[003][b22]: j2-204
join[003][b30]: 304
join[003][b31]: 304
join[003][b32]: j3-304
join[003][fun]: 612
join[004][b10]: 105
join[004][b11]: 105
join[004][b12]: j1-105
join[004][b20]: 205
join[004][b21]: 205
join[004][b22]: j2-205
join[004][b30]: 305
join[004][b31]: 305
join[004][b32]: j3-305
join[004][fun]: 615
join[005][b10]: 106
join[005][b11]: 106
join[005][b12]: j1-106
join[005][b20]: 206
join[005][b21]: 206
join[005][b22]: j2-206
join[005][b30]: 306
join[005][b31]: 306
join[005][b32]: j3-306
join[005][fun]: 618
join[006][b10]: 107
join[006][b11]: 107
join[006][b12]: j1-107
join[006][b20]: 207
join[006][b21]: 207
join[006][b22]: j2-207
join[006][b30]: 307
join[006][b31]: 307
join[006][b32]: j3-307
join[006][fun]: 621
join[007][b10]: 108
join[007][b11]: 108
join[007][b12]: j1-108
join[007][b20]: 208
join[007][b21]: 208
join[007][b22]: j2-208
join[007][b30]: 308
join[007][b31]: 308
join[007][b32]: j3-308
join[007][fun]: 624
join[008][b10]: 109
join[008][b11]: 109
join[008][b12]: j1-109
join[008][b20]: 209
join[008][b21]: 209
join[008][b22]: j2-209
join[008][b30]: 309
join[008][b31]: 309
join[008][b32]: j3-309
join[008][fun]: 627
join[009][b10]: 110
join[009][b11]: 110
join[009][b12]: j1-110
join[009][b20]: 210
join[009][b21]: 210
join[009][b22]: j2-210
join[009][b30]: 310
join[009][b31]: 310
join[009][b32]: j3-310
join[009][fun]: 630
Example (WithReadVarSelection)
package main

import (
	"fmt"
	"log"
	"strings"

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

func main() {

	get := func(fname, tname string) (rtree.Tree, func() error) {
		f, err := groot.Open(fname)
		if err != nil {
			log.Fatal(err)
		}
		t, err := f.Get(tname)
		if err != nil {
			_ = f.Close()
			log.Fatal(err)
		}
		return t.(rtree.Tree), f.Close
	}
	chk := func(f func() error) {
		err := f()
		if err != nil {
			log.Fatal(err)
		}
	}

	t1, f1 := get("../testdata/join1.root", "j1")
	defer chk(f1)

	t2, f2 := get("../testdata/join2.root", "j2")
	defer chk(f2)

	t3, f3 := get("../testdata/join3.root", "j3")
	defer chk(f3)

	join, err := rtree.Join(t1, t2, t3)
	if err != nil {
		log.Fatalf("could not join trees: %+v", err)
	}

	fmt.Printf("t1:   %s (nevts=%d)\n", t1.Name(), t1.Entries())
	fmt.Printf("t2:   %s (nevts=%d)\n", t2.Name(), t2.Entries())
	fmt.Printf("t3:   %s (nevts=%d)\n", t3.Name(), t3.Entries())
	fmt.Printf("join: %s\n", join.Name())
	fmt.Printf("entries: %d\n", join.Entries())

	rvars := []rtree.ReadVar{
		{Name: "b10", Value: new(float64)},
		{Name: "b20", Value: new(float64)},
	}

	r, err := rtree.NewReader(join, rvars, rtree.WithRange(3, 8))
	if err != nil {
		log.Fatalf("could not create reader for joined trees: %+v", err)
	}
	defer r.Close()

	rf1, err := r.FormulaFunc(
		[]string{"b12", "b32", "b22"},
		func(b1, b3, b2 string) string {
			return strings.Join([]string{b1, b3, b2}, ", ")
		},
	)
	if err != nil {
		log.Fatalf("could not bind formula: %+v", err)
	}
	fct1 := rf1.Func().(func() string)

	err = r.Read(func(rctx rtree.RCtx) error {
		for _, rv := range rvars {
			fmt.Printf("join[%03d][%s]: %v\n", rctx.Entry, rv.Name, rv.Deref())
		}
		fmt.Printf("join[%03d][fun]: %v\n", rctx.Entry, fct1())
		return nil
	})

	if err != nil {
		log.Fatalf("could not process events: %+v", err)
	}

}
Output:

t1:   j1 (nevts=10)
t2:   j2 (nevts=10)
t3:   j3 (nevts=10)
join: join_j1_j2_j3
entries: 10
join[003][b10]: 104
join[003][b20]: 204
join[003][fun]: j1-104, j3-304, j2-204
join[004][b10]: 105
join[004][b20]: 205
join[004][fun]: j1-105, j3-305, j2-205
join[005][b10]: 106
join[005][b20]: 206
join[005][fun]: j1-106, j3-306, j2-206
join[006][b10]: 107
join[006][b20]: 207
join[006][fun]: j1-107, j3-307, j2-207
join[007][b10]: 108
join[007][b20]: 208
join[007][fun]: j1-108, j3-308, j2-208

type WriteOption added in v0.21.0

type WriteOption func(opt *wopt) error

WriteOption configures how a ROOT tree (and its branches) should be created.

func WithBasketSize added in v0.21.0

func WithBasketSize(size int) WriteOption

WithBasketSize configures a ROOT tree to use 'size' (in bytes) as a basket buffer size. if size is <= 0, the default buffer size is used (DefaultBasketSize).

func WithLZ4 added in v0.21.0

func WithLZ4(level int) WriteOption

WithLZ4 configures a ROOT tree to use LZ4 as a compression mechanism.

func WithLZMA added in v0.21.0

func WithLZMA(level int) WriteOption

WithLZMA configures a ROOT tree to use LZMA as a compression mechanism.

func WithSplitLevel added in v0.28.0

func WithSplitLevel(lvl int) WriteOption

WithSplitLevel sets the maximum branch depth split level

func WithTitle added in v0.22.0

func WithTitle(title string) WriteOption

WithTitle sets the title of the tree writer.

func WithZlib added in v0.21.0

func WithZlib(level int) WriteOption

WithZlib configures a ROOT tree to use zlib as a compression mechanism.

func WithoutCompression added in v0.21.0

func WithoutCompression() WriteOption

WithoutCompression configures a ROOT tree to not use any compression mechanism.

type WriteVar added in v0.20.0

type WriteVar struct {
	Name  string      // name of the variable
	Value interface{} // pointer to the value to write
	Count string      // name of the branch holding the count-leaf value for slices
}

WriteVar describes a variable to be written out to a tree.

func WriteVarsFromStruct added in v0.21.0

func WriteVarsFromStruct(ptr interface{}, opts ...WriteOption) []WriteVar

WriteVarsFromStruct creates a slice of WriteVars from the ptr value. WriteVarsFromStruct panics if ptr is not a pointer to a struct value. WriteVarsFromStruct ignores fields that are not exported.

func WriteVarsFromTree added in v0.22.0

func WriteVarsFromTree(t Tree) []WriteVar

WriteVarsFromTree creates a slice of WriteVars from the tree value.

type Writer added in v0.20.0

type Writer interface {
	Tree

	// Write writes the event data to ROOT storage and returns the number
	// of bytes (before compression, if any) written.
	Write() (int, error)

	// Flush commits the current contents of the tree to stable storage.
	Flush() error

	// Close writes metadata and closes the tree.
	Close() error
}

Writer is the interface that wraps the Write method for Trees.

func NewWriter added in v0.20.0

func NewWriter(dir riofs.Directory, name string, vars []WriteVar, opts ...WriteOption) (Writer, error)

NewWriter creates a new Tree with the given name and under the given directory dir, ready to be filled with data.

Directories

Path Synopsis
Package rfunc provides types and funcs to implement user-provided formulae evaluated on data exposed by ROOT trees.
Package rfunc provides types and funcs to implement user-provided formulae evaluated on data exposed by ROOT trees.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL