Documentation ¶
Overview ¶
Package rtree contains the interfaces and types to decode, read, concatenate and iterate over ROOT Trees.
Example (CreateFlatNtuple) ¶
package main import ( "fmt" "io" "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) } 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) sc, err := rtree.NewTreeScanner(tree, &Data{}) if err != nil { log.Fatal(err) } defer sc.Close() for sc.Next() { var data Data err := sc.Scan(&data) if err != nil { log.Fatal(err) } fmt.Printf("entry[%d]: %+v\n", sc.Entry(), data) if sc.Entry() == 9 { break } } if err := sc.Err(); err != nil && err != io.EOF { 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" "io" "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) } 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) sc, err := rtree.NewTreeScanner(tree, &Data{}) if err != nil { log.Fatal(err) } defer sc.Close() for sc.Next() { var data Data err := sc.Scan(&data) if err != nil { log.Fatal(err) } fmt.Printf("entry[%d]: %+v\n", sc.Entry(), data) if sc.Entry() == 9 { break } } if err := sc.Err(); err != nil && err != io.EOF { 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" "io" "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) } 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) sc, err := rtree.NewTreeScanner(tree, &Data{}) if err != nil { log.Fatal(err) } defer sc.Close() for sc.Next() { var data Data err := sc.Scan(&data) if err != nil { log.Fatal(err) } fmt.Printf("entry[%d]: %+v\n", sc.Entry(), data) if sc.Entry() == 9 { break } } if err := sc.Err(); err != nil && err != io.EOF { 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 ¶
- func Copy(dst Writer, src Tree) (int64, error)
- func CopyN(dst Writer, src Tree, n int64) (int64, error)
- func FileOf(tree Tree) *riofs.File
- type Basket
- type Branch
- type Leaf
- type LeafB
- func (leaf *LeafB) ArrayDim() int
- func (leaf *LeafB) Branch() Branch
- func (leaf *LeafB) Class() string
- func (leaf *LeafB) HasRange() bool
- func (leaf *LeafB) IsUnsigned() bool
- func (*LeafB) Kind() reflect.Kind
- func (leaf *LeafB) LeafCount() Leaf
- func (leaf *LeafB) Len() int
- func (leaf *LeafB) LenType() int
- func (leaf *LeafB) MarshalROOT(w *rbytes.WBuffer) (int, error)
- func (leaf *LeafB) MaxIndex() []int
- func (leaf *LeafB) Maximum() int8
- func (leaf *LeafB) Minimum() int8
- func (leaf *LeafB) Name() string
- func (leaf *LeafB) Offset() int
- func (*LeafB) RVersion() int16
- func (leaf *LeafB) Title() string
- func (leaf *LeafB) Type() reflect.Type
- func (leaf *LeafB) TypeName() string
- func (leaf *LeafB) UnmarshalROOT(r *rbytes.RBuffer) error
- func (leaf *LeafB) Value(i int) interface{}
- type LeafC
- func (leaf *LeafC) ArrayDim() int
- func (leaf *LeafC) Branch() Branch
- func (leaf *LeafC) Class() string
- func (leaf *LeafC) HasRange() bool
- func (leaf *LeafC) IsUnsigned() bool
- func (*LeafC) Kind() reflect.Kind
- func (leaf *LeafC) LeafCount() Leaf
- func (leaf *LeafC) Len() int
- func (leaf *LeafC) LenType() int
- func (leaf *LeafC) MarshalROOT(w *rbytes.WBuffer) (int, error)
- func (leaf *LeafC) MaxIndex() []int
- func (leaf *LeafC) Maximum() int32
- func (leaf *LeafC) Minimum() int32
- func (leaf *LeafC) Name() string
- func (leaf *LeafC) Offset() int
- func (*LeafC) RVersion() int16
- func (leaf *LeafC) Title() string
- func (leaf *LeafC) Type() reflect.Type
- func (leaf *LeafC) TypeName() string
- func (leaf *LeafC) UnmarshalROOT(r *rbytes.RBuffer) error
- func (leaf *LeafC) Value(i int) interface{}
- type LeafD
- func (leaf *LeafD) ArrayDim() int
- func (leaf *LeafD) Branch() Branch
- func (leaf *LeafD) Class() string
- func (leaf *LeafD) HasRange() bool
- func (leaf *LeafD) IsUnsigned() bool
- func (*LeafD) Kind() reflect.Kind
- func (leaf *LeafD) LeafCount() Leaf
- func (leaf *LeafD) Len() int
- func (leaf *LeafD) LenType() int
- func (leaf *LeafD) MarshalROOT(w *rbytes.WBuffer) (int, error)
- func (leaf *LeafD) MaxIndex() []int
- func (leaf *LeafD) Maximum() float64
- func (leaf *LeafD) Minimum() float64
- func (leaf *LeafD) Name() string
- func (leaf *LeafD) Offset() int
- func (*LeafD) RVersion() int16
- func (leaf *LeafD) Title() string
- func (leaf *LeafD) Type() reflect.Type
- func (leaf *LeafD) TypeName() string
- func (leaf *LeafD) UnmarshalROOT(r *rbytes.RBuffer) error
- func (leaf *LeafD) Value(i int) interface{}
- type LeafF
- func (leaf *LeafF) ArrayDim() int
- func (leaf *LeafF) Branch() Branch
- func (leaf *LeafF) Class() string
- func (leaf *LeafF) HasRange() bool
- func (leaf *LeafF) IsUnsigned() bool
- func (*LeafF) Kind() reflect.Kind
- func (leaf *LeafF) LeafCount() Leaf
- func (leaf *LeafF) Len() int
- func (leaf *LeafF) LenType() int
- func (leaf *LeafF) MarshalROOT(w *rbytes.WBuffer) (int, error)
- func (leaf *LeafF) MaxIndex() []int
- func (leaf *LeafF) Maximum() float32
- func (leaf *LeafF) Minimum() float32
- func (leaf *LeafF) Name() string
- func (leaf *LeafF) Offset() int
- func (*LeafF) RVersion() int16
- func (leaf *LeafF) Title() string
- func (leaf *LeafF) Type() reflect.Type
- func (leaf *LeafF) TypeName() string
- func (leaf *LeafF) UnmarshalROOT(r *rbytes.RBuffer) error
- func (leaf *LeafF) Value(i int) interface{}
- type LeafI
- func (leaf *LeafI) ArrayDim() int
- func (leaf *LeafI) Branch() Branch
- func (leaf *LeafI) Class() string
- func (leaf *LeafI) HasRange() bool
- func (leaf *LeafI) IsUnsigned() bool
- func (*LeafI) Kind() reflect.Kind
- func (leaf *LeafI) LeafCount() Leaf
- func (leaf *LeafI) Len() int
- func (leaf *LeafI) LenType() int
- func (leaf *LeafI) MarshalROOT(w *rbytes.WBuffer) (int, error)
- func (leaf *LeafI) MaxIndex() []int
- func (leaf *LeafI) Maximum() int32
- func (leaf *LeafI) Minimum() int32
- func (leaf *LeafI) Name() string
- func (leaf *LeafI) Offset() int
- func (*LeafI) RVersion() int16
- func (leaf *LeafI) Title() string
- func (leaf *LeafI) Type() reflect.Type
- func (leaf *LeafI) TypeName() string
- func (leaf *LeafI) UnmarshalROOT(r *rbytes.RBuffer) error
- func (leaf *LeafI) Value(i int) interface{}
- type LeafL
- func (leaf *LeafL) ArrayDim() int
- func (leaf *LeafL) Branch() Branch
- func (leaf *LeafL) Class() string
- func (leaf *LeafL) HasRange() bool
- func (leaf *LeafL) IsUnsigned() bool
- func (*LeafL) Kind() reflect.Kind
- func (leaf *LeafL) LeafCount() Leaf
- func (leaf *LeafL) Len() int
- func (leaf *LeafL) LenType() int
- func (leaf *LeafL) MarshalROOT(w *rbytes.WBuffer) (int, error)
- func (leaf *LeafL) MaxIndex() []int
- func (leaf *LeafL) Maximum() int64
- func (leaf *LeafL) Minimum() int64
- func (leaf *LeafL) Name() string
- func (leaf *LeafL) Offset() int
- func (*LeafL) RVersion() int16
- func (leaf *LeafL) Title() string
- func (leaf *LeafL) Type() reflect.Type
- func (leaf *LeafL) TypeName() string
- func (leaf *LeafL) UnmarshalROOT(r *rbytes.RBuffer) error
- func (leaf *LeafL) Value(i int) interface{}
- type LeafO
- func (leaf *LeafO) ArrayDim() int
- func (leaf *LeafO) Branch() Branch
- func (leaf *LeafO) Class() string
- func (leaf *LeafO) HasRange() bool
- func (leaf *LeafO) IsUnsigned() bool
- func (*LeafO) Kind() reflect.Kind
- func (leaf *LeafO) LeafCount() Leaf
- func (leaf *LeafO) Len() int
- func (leaf *LeafO) LenType() int
- func (leaf *LeafO) MarshalROOT(w *rbytes.WBuffer) (int, error)
- func (leaf *LeafO) MaxIndex() []int
- func (leaf *LeafO) Maximum() bool
- func (leaf *LeafO) Minimum() bool
- func (leaf *LeafO) Name() string
- func (leaf *LeafO) Offset() int
- func (*LeafO) RVersion() int16
- func (leaf *LeafO) Title() string
- func (leaf *LeafO) Type() reflect.Type
- func (leaf *LeafO) TypeName() string
- func (leaf *LeafO) UnmarshalROOT(r *rbytes.RBuffer) error
- func (leaf *LeafO) Value(i int) interface{}
- type LeafS
- func (leaf *LeafS) ArrayDim() int
- func (leaf *LeafS) Branch() Branch
- func (leaf *LeafS) Class() string
- func (leaf *LeafS) HasRange() bool
- func (leaf *LeafS) IsUnsigned() bool
- func (*LeafS) Kind() reflect.Kind
- func (leaf *LeafS) LeafCount() Leaf
- func (leaf *LeafS) Len() int
- func (leaf *LeafS) LenType() int
- func (leaf *LeafS) MarshalROOT(w *rbytes.WBuffer) (int, error)
- func (leaf *LeafS) MaxIndex() []int
- func (leaf *LeafS) Maximum() int16
- func (leaf *LeafS) Minimum() int16
- func (leaf *LeafS) Name() string
- func (leaf *LeafS) Offset() int
- func (*LeafS) RVersion() int16
- func (leaf *LeafS) Title() string
- func (leaf *LeafS) Type() reflect.Type
- func (leaf *LeafS) TypeName() string
- func (leaf *LeafS) UnmarshalROOT(r *rbytes.RBuffer) error
- func (leaf *LeafS) Value(i int) interface{}
- type ScanVar
- type Scanner
- type Tree
- type TreeScanner
- type WriteOption
- type WriteVar
- type Writer
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Copy ¶ added in v0.22.0
Copy copies from src to dst until either the source tree is depleted or an error occurs. It returns the number of bytes copied and the first error encountered while copying, if any.
Types ¶
type Basket ¶
type Basket struct {
// contains filtered or unexported fields
}
func (*Basket) MarshalROOT ¶ added in v0.20.0
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 ArrayDim() int 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 MaxIndex() []int Offset() int Kind() reflect.Kind Type() reflect.Type Value(int) interface{} 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) IsUnsigned ¶
func (leaf *LeafB) IsUnsigned() bool
type LeafC ¶
type LeafC struct {
// contains filtered or unexported fields
}
LeafC implements ROOT TLeafC
func (*LeafC) IsUnsigned ¶
func (leaf *LeafC) IsUnsigned() bool
type LeafD ¶
type LeafD struct {
// contains filtered or unexported fields
}
LeafD implements ROOT TLeafD
func (*LeafD) IsUnsigned ¶
func (leaf *LeafD) IsUnsigned() bool
type LeafF ¶
type LeafF struct {
// contains filtered or unexported fields
}
LeafF implements ROOT TLeafF
func (*LeafF) IsUnsigned ¶
func (leaf *LeafF) IsUnsigned() bool
type LeafI ¶
type LeafI struct {
// contains filtered or unexported fields
}
LeafI implements ROOT TLeafI
func (*LeafI) IsUnsigned ¶
func (leaf *LeafI) IsUnsigned() bool
type LeafL ¶
type LeafL struct {
// contains filtered or unexported fields
}
LeafL implements ROOT TLeafL
func (*LeafL) IsUnsigned ¶
func (leaf *LeafL) IsUnsigned() bool
type LeafO ¶
type LeafO struct {
// contains filtered or unexported fields
}
LeafO implements ROOT TLeafO
func (*LeafO) IsUnsigned ¶
func (leaf *LeafO) IsUnsigned() bool
type LeafS ¶
type LeafS struct {
// contains filtered or unexported fields
}
LeafS implements ROOT TLeafS
func (*LeafS) IsUnsigned ¶
func (leaf *LeafS) IsUnsigned() bool
type ScanVar ¶
type ScanVar 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 }
ScanVar describes a variable to be read out of a tree during a scan.
func NewScanVars ¶ added in v0.19.0
NewScanVars returns the complete set of ScanVars to read all the data contained in the provided Tree.
type Scanner ¶
type Scanner struct {
// contains filtered or unexported fields
}
Scanner scans, selects and iterates over Tree entries. Scanner is bound to values the user provides, Scanner will then read data into these values during the tree scan.
Example (WithStruct) ¶
package main import ( "fmt" "io" "log" "go-hep.org/x/hep/groot/riofs" "go-hep.org/x/hep/groot/rtree" ) func main() { log.SetPrefix("groot: ") log.SetFlags(0) f, err := riofs.Open("../testdata/small-flat-tree.root") if err != nil { log.Fatal(err) } defer f.Close() obj, err := f.Get("tree") if err != nil { log.Fatal(err) } tree := obj.(rtree.Tree) // like for the encoding/json package, struct fields need to // be exported to be properly handled by rtree.Scanner. // Thus, if the ROOT branch name is lower-case, use the "groot" // struct-tag like shown below. type Data struct { I64 int64 `groot:"Int64"` F64 float64 `groot:"Float64"` Str string `groot:"Str"` ArrF64 [10]float64 `groot:"ArrayFloat64"` N int32 `groot:"N"` SliF64 []float64 `groot:"SliceFloat64"` } var data Data sc, err := rtree.NewScanner(tree, &data) if err != nil { log.Fatal(err) } defer sc.Close() for sc.Next() { err := sc.Scan() if err != nil { log.Fatal(err) } fmt.Printf("entry[%d]: %+v\n", sc.Entry(), data) if sc.Entry() == 9 { break } } if err := sc.Err(); err != nil && err != io.EOF { log.Fatal(err) } }
Output: entry[0]: {I64:0 F64:0 Str:evt-000 ArrF64:[0 0 0 0 0 0 0 0 0 0] N:0 SliF64:[]} entry[1]: {I64:1 F64:1 Str:evt-001 ArrF64:[1 1 1 1 1 1 1 1 1 1] N:1 SliF64:[1]} entry[2]: {I64:2 F64:2 Str:evt-002 ArrF64:[2 2 2 2 2 2 2 2 2 2] N:2 SliF64:[2 2]} entry[3]: {I64:3 F64:3 Str:evt-003 ArrF64:[3 3 3 3 3 3 3 3 3 3] N:3 SliF64:[3 3 3]} entry[4]: {I64:4 F64:4 Str:evt-004 ArrF64:[4 4 4 4 4 4 4 4 4 4] N:4 SliF64:[4 4 4 4]} entry[5]: {I64:5 F64:5 Str:evt-005 ArrF64:[5 5 5 5 5 5 5 5 5 5] N:5 SliF64:[5 5 5 5 5]} entry[6]: {I64:6 F64:6 Str:evt-006 ArrF64:[6 6 6 6 6 6 6 6 6 6] N:6 SliF64:[6 6 6 6 6 6]} entry[7]: {I64:7 F64:7 Str:evt-007 ArrF64:[7 7 7 7 7 7 7 7 7 7] N:7 SliF64:[7 7 7 7 7 7 7]} entry[8]: {I64:8 F64:8 Str:evt-008 ArrF64:[8 8 8 8 8 8 8 8 8 8] N:8 SliF64:[8 8 8 8 8 8 8 8]} entry[9]: {I64:9 F64:9 Str:evt-009 ArrF64:[9 9 9 9 9 9 9 9 9 9] N:9 SliF64:[9 9 9 9 9 9 9 9 9]}
Example (WithVars) ¶
package main import ( "fmt" "io" "log" "go-hep.org/x/hep/groot/riofs" "go-hep.org/x/hep/groot/rtree" ) func main() { log.SetPrefix("groot: ") log.SetFlags(0) f, err := riofs.Open("../testdata/small-flat-tree.root") if err != nil { log.Fatal(err) } defer f.Close() obj, err := f.Get("tree") if err != nil { log.Fatal(err) } tree := obj.(rtree.Tree) var ( i64 int64 f64 float64 str string arr [10]float64 n int32 sli []float64 ) scanVars := []rtree.ScanVar{ {Name: "Int64", Value: &i64}, {Name: "Float64", Value: &f64}, {Name: "Str", Value: &str}, {Name: "ArrayFloat64", Value: &arr}, {Name: "N", Value: &n}, {Name: "SliceFloat64", Value: &sli}, } sc, err := rtree.NewScannerVars(tree, scanVars...) if err != nil { log.Fatal(err) } defer sc.Close() for sc.Next() { err := sc.Scan() if err != nil { log.Fatal(err) } fmt.Printf( "entry[%d]: i64=%v f64=%v str=%q arr=%v n=%d sli=%v\n", sc.Entry(), i64, f64, str, arr, n, sli, ) if sc.Entry() == 9 { break } } if err := sc.Err(); err != nil && err != io.EOF { log.Fatal(err) } }
Output: entry[0]: i64=0 f64=0 str="evt-000" arr=[0 0 0 0 0 0 0 0 0 0] n=0 sli=[] entry[1]: i64=1 f64=1 str="evt-001" arr=[1 1 1 1 1 1 1 1 1 1] n=1 sli=[1] entry[2]: i64=2 f64=2 str="evt-002" arr=[2 2 2 2 2 2 2 2 2 2] n=2 sli=[2 2] entry[3]: i64=3 f64=3 str="evt-003" arr=[3 3 3 3 3 3 3 3 3 3] n=3 sli=[3 3 3] entry[4]: i64=4 f64=4 str="evt-004" arr=[4 4 4 4 4 4 4 4 4 4] n=4 sli=[4 4 4 4] entry[5]: i64=5 f64=5 str="evt-005" arr=[5 5 5 5 5 5 5 5 5 5] n=5 sli=[5 5 5 5 5] entry[6]: i64=6 f64=6 str="evt-006" arr=[6 6 6 6 6 6 6 6 6 6] n=6 sli=[6 6 6 6 6 6] entry[7]: i64=7 f64=7 str="evt-007" arr=[7 7 7 7 7 7 7 7 7 7] n=7 sli=[7 7 7 7 7 7 7] entry[8]: i64=8 f64=8 str="evt-008" arr=[8 8 8 8 8 8 8 8 8 8] n=8 sli=[8 8 8 8 8 8 8 8] entry[9]: i64=9 f64=9 str="evt-009" arr=[9 9 9 9 9 9 9 9 9 9] n=9 sli=[9 9 9 9 9 9 9 9 9]
func NewScanner ¶
NewScanner creates a new Scanner bound to a (pointer to a) struct value. Scanner will read the branches' data during Scan() and load them into the fields of the struct value.
func NewScannerVars ¶
NewScannerVars creates a new Scanner from a list of pairs (branch-name, target-address). Scanner will read the branches' data during Scan() and load them into these target-addresses.
func (*Scanner) Close ¶
Close closes the Scanner, preventing further iteration. Close is idempotent and does not affect the result of Err.
func (*Scanner) Next ¶
Next prepares the next result row for reading with the Scan method. It returns true on success, false if there is no next result row. Every call to Scan, even the first one, must be preceded by a call to Next.
type Tree ¶
type Tree interface { root.Named Entries() int64 TotBytes() int64 ZipBytes() int64 Branch(name string) Branch Branches() []Branch Leaf(name string) Leaf Leaves() []Leaf // contains filtered or unexported methods }
func Chain ¶
Chain returns a tchain 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"` } sc, err := rtree.NewTreeScanner(chain, &Data{}) if err != nil { log.Fatal(err) } defer sc.Close() for sc.Next() { var data Data err := sc.Scan(&data) if err != nil { log.Fatal(err) } fmt.Printf("entry[%02d]: beg=%q f64=%v\n", sc.Entry(), data.Event.Beg, data.Event.F64) } if err := sc.Err(); 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 ¶
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 closer() 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"` } sc, err := rtree.NewTreeScanner(chain, &Data{}) if err != nil { log.Fatal(err) } defer sc.Close() for sc.Next() { var data Data err := sc.Scan(&data) if err != nil { log.Fatal(err) } fmt.Printf("entry[%02d]: beg=%q f64=%v\n", sc.Entry(), data.Event.Beg, data.Event.F64) } if err := sc.Err(); 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
type TreeScanner ¶
type TreeScanner struct {
// contains filtered or unexported fields
}
TreeScanner scans, selects and iterates over Tree entries.
Example ¶
package main import ( "fmt" "io" "log" "go-hep.org/x/hep/groot/riofs" "go-hep.org/x/hep/groot/rtree" ) func main() { log.SetPrefix("groot: ") log.SetFlags(0) f, err := riofs.Open("../testdata/small-flat-tree.root") if err != nil { log.Fatal(err) } defer f.Close() obj, err := f.Get("tree") if err != nil { log.Fatal(err) } tree := obj.(rtree.Tree) // like for the encoding/json package, struct fields need to // be exported to be properly handled by rtree.Scanner. // Thus, if the ROOT branch name is lower-case, use the "groot" // struct-tag like shown below. type Data struct { I64 int64 `groot:"Int64"` F64 float64 `groot:"Float64"` Str string `groot:"Str"` ArrF64 [10]float64 `groot:"ArrayFloat64"` N int32 `groot:"N"` SliF64 []float64 `groot:"SliceFloat64"` } sc, err := rtree.NewTreeScanner(tree, &Data{}) if err != nil { log.Fatal(err) } defer sc.Close() for sc.Next() { var data Data err := sc.Scan(&data) if err != nil { log.Fatal(err) } fmt.Printf("entry[%d]: %+v\n", sc.Entry(), data) if sc.Entry() == 9 { break } } if err := sc.Err(); err != nil && err != io.EOF { log.Fatal(err) } }
Output: entry[0]: {I64:0 F64:0 Str:evt-000 ArrF64:[0 0 0 0 0 0 0 0 0 0] N:0 SliF64:[]} entry[1]: {I64:1 F64:1 Str:evt-001 ArrF64:[1 1 1 1 1 1 1 1 1 1] N:1 SliF64:[1]} entry[2]: {I64:2 F64:2 Str:evt-002 ArrF64:[2 2 2 2 2 2 2 2 2 2] N:2 SliF64:[2 2]} entry[3]: {I64:3 F64:3 Str:evt-003 ArrF64:[3 3 3 3 3 3 3 3 3 3] N:3 SliF64:[3 3 3]} entry[4]: {I64:4 F64:4 Str:evt-004 ArrF64:[4 4 4 4 4 4 4 4 4 4] N:4 SliF64:[4 4 4 4]} entry[5]: {I64:5 F64:5 Str:evt-005 ArrF64:[5 5 5 5 5 5 5 5 5 5] N:5 SliF64:[5 5 5 5 5]} entry[6]: {I64:6 F64:6 Str:evt-006 ArrF64:[6 6 6 6 6 6 6 6 6 6] N:6 SliF64:[6 6 6 6 6 6]} entry[7]: {I64:7 F64:7 Str:evt-007 ArrF64:[7 7 7 7 7 7 7 7 7 7] N:7 SliF64:[7 7 7 7 7 7 7]} entry[8]: {I64:8 F64:8 Str:evt-008 ArrF64:[8 8 8 8 8 8 8 8 8 8] N:8 SliF64:[8 8 8 8 8 8 8 8]} entry[9]: {I64:9 F64:9 Str:evt-009 ArrF64:[9 9 9 9 9 9 9 9 9 9] N:9 SliF64:[9 9 9 9 9 9 9 9 9]}
Example (WithVars) ¶
package main import ( "fmt" "io" "log" "go-hep.org/x/hep/groot/riofs" "go-hep.org/x/hep/groot/rtree" ) func main() { log.SetPrefix("groot: ") log.SetFlags(0) f, err := riofs.Open("../testdata/small-flat-tree.root") if err != nil { log.Fatal(err) } defer f.Close() obj, err := f.Get("tree") if err != nil { log.Fatal(err) } tree := obj.(rtree.Tree) scanVars := []rtree.ScanVar{ {Name: "Int64"}, {Name: "Float64"}, {Name: "Str"}, {Name: "ArrayFloat64"}, {Name: "N"}, {Name: "SliceFloat64"}, } sc, err := rtree.NewTreeScannerVars(tree, scanVars...) if err != nil { log.Fatal(err) } defer sc.Close() for sc.Next() { var ( i64 int64 f64 float64 str string arr [10]float64 n int32 sli []float64 ) err := sc.Scan(&i64, &f64, &str, &arr, &n, &sli) if err != nil { log.Fatal(err) } fmt.Printf( "entry[%d]: i64=%v f64=%v str=%q arr=%v n=%d sli=%v\n", sc.Entry(), i64, f64, str, arr, n, sli, ) if sc.Entry() == 9 { break } } if err := sc.Err(); err != nil && err != io.EOF { log.Fatal(err) } }
Output: entry[0]: i64=0 f64=0 str="evt-000" arr=[0 0 0 0 0 0 0 0 0 0] n=0 sli=[] entry[1]: i64=1 f64=1 str="evt-001" arr=[1 1 1 1 1 1 1 1 1 1] n=1 sli=[1] entry[2]: i64=2 f64=2 str="evt-002" arr=[2 2 2 2 2 2 2 2 2 2] n=2 sli=[2 2] entry[3]: i64=3 f64=3 str="evt-003" arr=[3 3 3 3 3 3 3 3 3 3] n=3 sli=[3 3 3] entry[4]: i64=4 f64=4 str="evt-004" arr=[4 4 4 4 4 4 4 4 4 4] n=4 sli=[4 4 4 4] entry[5]: i64=5 f64=5 str="evt-005" arr=[5 5 5 5 5 5 5 5 5 5] n=5 sli=[5 5 5 5 5] entry[6]: i64=6 f64=6 str="evt-006" arr=[6 6 6 6 6 6 6 6 6 6] n=6 sli=[6 6 6 6 6 6] entry[7]: i64=7 f64=7 str="evt-007" arr=[7 7 7 7 7 7 7 7 7 7] n=7 sli=[7 7 7 7 7 7 7] entry[8]: i64=8 f64=8 str="evt-008" arr=[8 8 8 8 8 8 8 8 8 8] n=8 sli=[8 8 8 8 8 8 8 8] entry[9]: i64=9 f64=9 str="evt-009" arr=[9 9 9 9 9 9 9 9 9 9] n=9 sli=[9 9 9 9 9 9 9 9 9]
func NewTreeScanner ¶
func NewTreeScanner(t Tree, ptr interface{}) (*TreeScanner, error)
NewTreeScanner creates a new Scanner connecting the pointer to some user provided type to the given Tree.
func NewTreeScannerVars ¶
func NewTreeScannerVars(t Tree, vars ...ScanVar) (*TreeScanner, error)
NewTreeScannerVars creates a new Scanner from a list of branches. It will return an error if the provided type does not match the type stored in the corresponding branch.
func (*TreeScanner) Close ¶
func (s *TreeScanner) Close() error
Close closes the TreeScanner, preventing further iteration. Close is idempotent and does not affect the result of Err.
func (*TreeScanner) Entry ¶
func (s *TreeScanner) Entry() int64
Entry returns the entry number of the last read row.
func (*TreeScanner) Err ¶
func (s *TreeScanner) Err() error
Err returns the error, if any, that was encountered during iteration.
func (*TreeScanner) Next ¶
func (s *TreeScanner) Next() bool
Next prepares the next result row for reading with the Scan method. It returns true on success, false if there is no next result row. Every call to Scan, even the first one, must be preceded by a call to Next.
func (*TreeScanner) Scan ¶
func (s *TreeScanner) Scan(args ...interface{}) (err error)
Scan copies data loaded from the underlying Tree into the values pointed at by args.
func (*TreeScanner) SeekEntry ¶
func (s *TreeScanner) SeekEntry(i int64) error
SeekEntry points the scanner to the i-th entry, ready to call Next.
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 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{}) []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
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.