hep: go-hep.org/x/hep/groot/riofs Index | Examples | Files | Directories

package riofs

import "go-hep.org/x/hep/groot/riofs"

Package riofs contains the types and low-level functions to deal with opening and creating ROOT files, and decoding the internal structure of ROOT files.

Users should prefer to use the groot package to open or create ROOT files instead of this one.

Code:

const fname = "../testdata/subdirs.root"
defer os.Remove(fname)

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

    dir1, err := w.Mkdir("dir1")
    if err != nil {
        log.Fatal(err)
    }

    dir11, err := dir1.Mkdir("dir11")
    if err != nil {
        log.Fatal(err)
    }

    err = dir11.Put("obj1", rbase.NewObjString("data-obj1"))
    if err != nil {
        log.Fatal(err)
    }

    dir2, err := w.Mkdir("dir2")
    if err != nil {
        log.Fatal(err)
    }

    err = dir2.Put("obj2", rbase.NewObjString("data-obj2"))
    if err != nil {
        log.Fatal(err)
    }

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

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

riofs.Walk(r, func(path string, obj root.Object, err error) error {
    fmt.Printf(">> %v\n", path)
    return err
})

Output:

>> ../testdata/subdirs.root
>> ../testdata/subdirs.root/dir1
>> ../testdata/subdirs.root/dir1/dir11
>> ../testdata/subdirs.root/dir1/dir11/obj1
>> ../testdata/subdirs.root/dir2
>> ../testdata/subdirs.root/dir2/obj2

Index

Examples

Package Files

blocks.go compress.go consts.go dir.go dobj.go file.go fileplugin.go key.go memfile.go riofs.go sizeof.go streamers.go time.go utils.go walk.go

Variables

var (
    ErrReadOnly = errors.New("riofs: file read-only")
)
var SkipDir = errors.New("riofs: skip this directory")

SkipDir is used as a return value from WalkFuncs to indicate that the directory named in the call is to be skipped. It is not returned as an error by any function.

func Drivers Uses

func Drivers() []string

Drivers returns a sorted list of the names of the registered plugins to open ROOT files.

func Register Uses

func Register(name string, f func(path string) (Reader, error))

Register registers a plugin to open ROOT files. Register panics if it is called twice with the same name of if the plugin function is nil.

func Walk Uses

func Walk(dir Directory, walkFn WalkFunc) error

Walk walks the ROOT file tree rooted at dir, calling walkFn for each ROOT object or Directory in the ROOT file tree, including dir.

Code:

f, err := riofs.Open("../testdata/dirs-6.14.00.root")
if err != nil {
    log.Fatal(err)
}
defer f.Close()

fmt.Printf("visit all ROOT file tree:\n")
err = riofs.Walk(f, func(path string, obj root.Object, err error) error {
    fmt.Printf("%s (%s)\n", path, obj.Class())
    return nil
})
if err != nil {
    log.Fatalf("could not walk through file: %v", err)
}

fmt.Printf("visit only dir1:\n")
err = riofs.Walk(f, func(path string, obj root.Object, err error) error {
    if !(strings.HasPrefix(path, stdpath.Join(f.Name(), "dir1")) || path == f.Name()) {
        return riofs.SkipDir
    }
    fmt.Printf("%s (%s)\n", path, obj.Class())
    return nil
})
if err != nil {
    log.Fatalf("could not walk through file: %v", err)
}

Output:

visit all ROOT file tree:
dirs-6.14.00.root (TFile)
dirs-6.14.00.root/dir1 (TDirectoryFile)
dirs-6.14.00.root/dir1/dir11 (TDirectoryFile)
dirs-6.14.00.root/dir1/dir11/h1 (TH1F)
dirs-6.14.00.root/dir2 (TDirectoryFile)
dirs-6.14.00.root/dir3 (TDirectoryFile)
visit only dir1:
dirs-6.14.00.root (TFile)
dirs-6.14.00.root/dir1 (TDirectoryFile)
dirs-6.14.00.root/dir1/dir11 (TDirectoryFile)
dirs-6.14.00.root/dir1/dir11/h1 (TH1F)

type Directory Uses

type Directory interface {
    // Get returns the object identified by namecycle
    //   namecycle has the format name;cycle
    //   name  = * is illegal, cycle = * is illegal
    //   cycle = "" or cycle = 9999 ==> apply to a memory object
    //
    //   examples:
    //     foo   : get object named foo in memory
    //             if object is not in memory, try with highest cycle from file
    //     foo;1 : get cycle 1 of foo on file
    Get(namecycle string) (root.Object, error)

    // Put puts the object v under the key with the given name.
    Put(name string, v root.Object) error

    // Keys returns the list of keys being held by this directory.
    Keys() []Key

    // Mkdir creates a new subdirectory
    Mkdir(name string) (Directory, error)
}

Directory describes a ROOT directory structure in memory.

func Dir Uses

func Dir(dir Directory) Directory

Dir wraps the given directory to handle fully specified directory names:

rdir := Dir(dir)
obj, err := rdir.Get("some/dir/object/name;1")

type File Uses

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

A ROOT file is a suite of consecutive data records (TKey's) with the following format (see also the TKey class). If the key is located past the 32 bit file limit (> 2 GB) then some fields will be 8 instead of 4 bytes:

1->4            Nbytes    = Length of compressed object (in bytes)
5->6            Version   = TKey version identifier
7->10           ObjLen    = Length of uncompressed object
11->14          Datime    = Date and time when object was written to file
15->16          KeyLen    = Length of the key structure (in bytes)
17->18          Cycle     = Cycle of key
19->22 [19->26] SeekKey   = Pointer to record itself (consistency check)
23->26 [27->34] SeekPdir  = Pointer to directory header
27->27 [35->35] lname     = Number of bytes in the class name
28->.. [36->..] ClassName = Object Class Name
..->..          lname     = Number of bytes in the object name
..->..          Name      = lName bytes with the name of the object
..->..          lTitle    = Number of bytes in the object title
..->..          Title     = Title of the object
----->          DATA      = Data bytes associated to the object

The first data record starts at byte fBEGIN (currently set to kBEGIN). Bytes 1->kBEGIN contain the file description, when fVersion >= 1000000 it is a large file (> 2 GB) and the offsets will be 8 bytes long and fUnits will be set to 8:

1->4            "root"      = Root file identifier
5->8            fVersion    = File format version
9->12           fBEGIN      = Pointer to first data record
13->16 [13->20] fEND        = Pointer to first free word at the EOF
17->20 [21->28] fSeekFree   = Pointer to FREE data record
21->24 [29->32] fNbytesFree = Number of bytes in FREE data record
25->28 [33->36] nfree       = Number of free data records
29->32 [37->40] fNbytesName = Number of bytes in TNamed at creation time
33->33 [41->41] fUnits      = Number of bytes for file pointers
34->37 [42->45] fCompress   = Compression level and algorithm
38->41 [46->53] fSeekInfo   = Pointer to TStreamerInfo record
42->45 [54->57] fNbytesInfo = Number of bytes in TStreamerInfo record
46->63 [58->75] fUUID       = Universal Unique ID

func Create Uses

func Create(name string, opts ...FileOption) (*File, error)

Create creates the named ROOT file for writing.

Code:

const fname = "objstring.root"
defer os.Remove(fname)

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

var (
    k   = "my-objstring"
    v   = rbase.NewObjString("Hello World from Go-HEP!")
)

err = w.Put(k, v)
if err != nil {
    log.Fatal(err)
}

fmt.Printf("wkeys: %d\n", len(w.Keys()))

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

r, err := groot.Open(fname)
if err != nil {
    log.Fatalf("could not open file: %v", err)
}
defer r.Close()

fmt.Printf("rkeys: %d\n", len(r.Keys()))

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

obj, err := r.Get(k)
if err != nil {
    log.Fatal(err)
}
rv := obj.(root.ObjString)
fmt.Printf("objstring=%q\n", rv)

Output:

wkeys: 1
rkeys: 1
key: name="my-objstring", type="TObjString"
objstring="Hello World from Go-HEP!"

Code:

const fname = "empty.root"
defer os.Remove(fname)

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

// empty file. close it.
err = w.Close()
if err != nil {
    log.Fatalf("could not close empty file: %v", err)
}

// read back.
r, err := groot.Open(fname)
if err != nil {
    log.Fatalf("could not open empty file: %v", err)
}
defer r.Close()

fmt.Printf("file: %q\n", r.Name())

Output:

file: "empty.root"

Code:

const fname = "objstring-zlib.root"
defer os.Remove(fname)

w, err := groot.Create(fname, riofs.WithZlib(flate.BestCompression))
if err != nil {
    log.Fatal(err)
}
defer w.Close()

var (
    k   = "my-objstring"
    v   = rbase.NewObjString("Hello World from Go-HEP!")
)

err = w.Put(k, v)
if err != nil {
    log.Fatal(err)
}

err = w.Close()
if err != nil {
    log.Fatalf("could not close writable file: %v", err)
}

r, err := groot.Open(fname)
if err != nil {
    log.Fatalf("could not open file: %v", err)
}
defer r.Close()

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

obj, err := r.Get(k)
if err != nil {
    log.Fatalf("could not get key %q: %v", k, err)
}
rv := obj.(root.ObjString)
fmt.Printf("objstring=%q\n", rv)

Output:

key: name="my-objstring", type="TObjString"
objstring="Hello World from Go-HEP!"

func NewReader Uses

func NewReader(r Reader) (*File, error)

NewReader creates a new ROOT file reader.

func Open Uses

func Open(path string) (*File, error)

Open opens the named ROOT file for reading. If successful, methods on the returned file can be used for reading; the associated file descriptor has mode os.O_RDONLY.

func (*File) Class Uses

func (f *File) Class() string

func (*File) Close Uses

func (f *File) Close() error

Close closes the File, rendering it unusable for I/O. It returns an error, if any.

func (*File) Get Uses

func (f *File) Get(namecycle string) (root.Object, error)

Get returns the object identified by namecycle

namecycle has the format name;cycle
name  = * is illegal, cycle = * is illegal
cycle = "" or cycle = 9999 ==> apply to a memory object

examples:
  foo   : get object named foo in memory
          if object is not in memory, try with highest cycle from file
  foo;1 : get cycle 1 of foo on file

func (*File) Keys Uses

func (f *File) Keys() []Key

Keys returns the list of keys this File contains

func (*File) Mkdir Uses

func (f *File) Mkdir(name string) (Directory, error)

Mkdir creates a new subdirectory

func (*File) Name Uses

func (f *File) Name() string

func (*File) Put Uses

func (f *File) Put(name string, v root.Object) error

Put puts the object v under the key with the given name.

func (*File) Read Uses

func (f *File) Read(p []byte) (int, error)

Read implements io.Reader

func (*File) ReadAt Uses

func (f *File) ReadAt(p []byte, off int64) (int, error)

ReadAt implements io.ReaderAt

func (*File) Seek Uses

func (f *File) Seek(offset int64, whence int) (int64, error)

Seek implements io.Seeker

func (*File) Stat Uses

func (f *File) Stat() (os.FileInfo, error)

Stat returns the os.FileInfo structure describing this file.

func (*File) StreamerInfo Uses

func (f *File) StreamerInfo(name string, version int) (rbytes.StreamerInfo, error)

StreamerInfo returns the named StreamerInfo. If version is negative, the latest version should be returned.

func (*File) StreamerInfos Uses

func (f *File) StreamerInfos() []rbytes.StreamerInfo

StreamerInfos returns the list of StreamerInfos of this file.

func (*File) Title Uses

func (f *File) Title() string

func (*File) Version Uses

func (f *File) Version() int

Version returns the ROOT version this file was created with.

type FileOption Uses

type FileOption func(f *File) error

FileOption configures internal states of a ROOT file.

func WithLZ4 Uses

func WithLZ4(level int) FileOption

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

func WithLZMA Uses

func WithLZMA(level int) FileOption

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

func WithZlib Uses

func WithZlib(level int) FileOption

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

func WithoutCompression Uses

func WithoutCompression() FileOption

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

type Key Uses

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

Key is a key (a label) in a ROOT file

The Key class includes functions to book space on a file,
 to create I/O buffers, to fill these buffers
 to compress/uncompress data buffers.

Before saving (making persistent) an object on a file, a key must
be created. The key structure contains all the information to
uniquely identify a persistent object on a file.
The Key class is used by ROOT:
  - to write an object in the Current Directory
  - to write a new ntuple buffer

func (*Key) Bytes Uses

func (k *Key) Bytes() ([]byte, error)

Bytes returns the buffer of bytes corresponding to the Key's value

func (*Key) Class Uses

func (*Key) Class() string

func (*Key) ClassName Uses

func (k *Key) ClassName() string

func (*Key) Cycle Uses

func (k *Key) Cycle() int

func (*Key) KeyLen Uses

func (k *Key) KeyLen() int32

func (*Key) Load Uses

func (k *Key) Load(buf []byte) ([]byte, error)

func (*Key) MarshalROOT Uses

func (k *Key) MarshalROOT(w *rbytes.WBuffer) (int, error)

MarshalROOT encodes the key to the provided buffer.

func (*Key) Name Uses

func (k *Key) Name() string

func (*Key) ObjLen Uses

func (k *Key) ObjLen() int32

func (*Key) Object Uses

func (k *Key) Object() (root.Object, error)

Object returns the (ROOT) object corresponding to the Key's value.

func (*Key) ObjectType Uses

func (k *Key) ObjectType() reflect.Type

ObjectType returns the Key's payload type.

ObjectType returns nil if the Key's payload type is not known to the registry of groot.

func (*Key) RVersion Uses

func (k *Key) RVersion() int16

func (*Key) SetBuffer Uses

func (k *Key) SetBuffer(buf []byte)

func (*Key) SetFile Uses

func (k *Key) SetFile(f *File)

func (*Key) Title Uses

func (k *Key) Title() string

func (*Key) UnmarshalROOT Uses

func (k *Key) UnmarshalROOT(r *rbytes.RBuffer) error

UnmarshalROOT decodes the content of data into the Key

func (*Key) Value Uses

func (k *Key) Value() interface{}

Value returns the data corresponding to the Key's value

type Reader Uses

type Reader interface {
    io.Reader
    io.ReaderAt
    io.Seeker
    io.Closer
}

type SetFiler Uses

type SetFiler interface {
    SetFile(f *File)
}

SetFiler is a simple interface to establish File ownership.

type WalkFunc Uses

type WalkFunc func(path string, obj root.Object, err error) error

WalkFunc is the type of the function called for each object or directory visited by Walk. The path argument contains the argument to Walk as a prefix; that is, if Walk is called with "dir", which is a directory containing the file "a", the walk function will be called with argument "dir/a". The obj argument is the root.Object for the named path.

If there was a problem walking to the file or directory named by path, the incoming error will describe the problem and the function can decide how to handle that error (and Walk will not descend into that directory). In the case of an error, the obj argument will be nil. If an error is returned, processing stops. The sole exception is when the function returns the special value SkipDir. If the function returns SkipDir when invoked on a directory, Walk skips the directory's contents entirely. If the function returns SkipDir when invoked on a non-directory root.Object, Walk skips the remaining keys in the containing directory.

type Writer Uses

type Writer interface {
    io.Writer
    io.WriterAt
    io.Seeker
    io.Closer
}

Directories

PathSynopsis
internal/rstreamersPackage rstreamers provides the StreamerInfo definitions for a bunch of core ROOT classes, to setup the bootstrap procedure of being able to create streamers from the Go side.
plugin/httpPackage http is a plugin for riofs.Open to support opening ROOT files over http(s).
plugin/xrootdPackage xrootd is a plugin for riofs.Open to support opening ROOT files over xrootd.

Package riofs imports 30 packages (graph) and is imported by 16 packages. Updated 2019-05-17. Refresh now. Tools for package owners.