rtree

package
v0.22.0 Latest Latest
Warning

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

Go to latest
Published: Dec 20, 2019 License: BSD-3-Clause Imports: 18 Imported by: 26

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

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Copy added in v0.22.0

func Copy(dst Writer, src Tree) (int64, error)

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.

func CopyN added in v0.22.0

func CopyN(dst Writer, src Tree, n int64) (int64, error)

Copy copies n events (or until an error) 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.

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

	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) ArrayDim

func (leaf *LeafB) ArrayDim() int

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 (*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) MaxIndex

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

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) 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

func (*LeafB) Value

func (leaf *LeafB) Value(i int) interface{}

Value returns the leaf value at index i.

type LeafC

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

LeafC implements ROOT TLeafC

func (*LeafC) ArrayDim

func (leaf *LeafC) ArrayDim() int

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 (*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) MaxIndex

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

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) 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

func (*LeafC) Value

func (leaf *LeafC) Value(i int) interface{}

Value returns the leaf value at index i.

type LeafD

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

LeafD implements ROOT TLeafD

func (*LeafD) ArrayDim

func (leaf *LeafD) ArrayDim() int

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 (*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) MaxIndex

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

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) 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

func (*LeafD) Value

func (leaf *LeafD) Value(i int) interface{}

Value returns the leaf value at index i.

type LeafF

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

LeafF implements ROOT TLeafF

func (*LeafF) ArrayDim

func (leaf *LeafF) ArrayDim() int

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 (*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) MaxIndex

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

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) 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

func (*LeafF) Value

func (leaf *LeafF) Value(i int) interface{}

Value returns the leaf value at index i.

type LeafI

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

LeafI implements ROOT TLeafI

func (*LeafI) ArrayDim

func (leaf *LeafI) ArrayDim() int

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 (*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) MaxIndex

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

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) 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

func (*LeafI) Value

func (leaf *LeafI) Value(i int) interface{}

Value returns the leaf value at index i.

type LeafL

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

LeafL implements ROOT TLeafL

func (*LeafL) ArrayDim

func (leaf *LeafL) ArrayDim() int

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 (*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) MaxIndex

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

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) 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

func (*LeafL) Value

func (leaf *LeafL) Value(i int) interface{}

Value returns the leaf value at index i.

type LeafO

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

LeafO implements ROOT TLeafO

func (*LeafO) ArrayDim

func (leaf *LeafO) ArrayDim() int

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 (*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) MaxIndex

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

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) 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

func (*LeafO) Value

func (leaf *LeafO) Value(i int) interface{}

Value returns the leaf value at index i.

type LeafS

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

LeafS implements ROOT TLeafS

func (*LeafS) ArrayDim

func (leaf *LeafS) ArrayDim() int

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 (*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) MaxIndex

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

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) 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

func (*LeafS) Value

func (leaf *LeafS) Value(i int) interface{}

Value returns the leaf value at index i.

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

func NewScanVars(t Tree) []ScanVar

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

func NewScanner(t Tree, ptr interface{}) (*Scanner, error)

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

func NewScannerVars(t Tree, vars ...ScanVar) (*Scanner, error)

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

func (s *Scanner) Close() error

Close closes the Scanner, preventing further iteration. Close is idempotent and does not affect the result of Err.

func (*Scanner) Entry

func (s *Scanner) Entry() int64

Entry returns the entry number of the last read row.

func (*Scanner) Err

func (s *Scanner) Err() error

Err returns the error, if any, that was encountered during iteration.

func (*Scanner) Next

func (s *Scanner) 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 (*Scanner) Scan

func (s *Scanner) Scan() error

Scan copies data loaded from the underlying Tree into the values the Scanner is bound to. The values bound to the Scanner are valid until the next call to Scan.

func (*Scanner) SeekEntry

func (s *Scanner) SeekEntry(i int64) error

SeekEntry points the scanner to the i-th entry, ready to call 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

func Chain(trees ...Tree) Tree

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

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 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

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.

Jump to

Keyboard shortcuts

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