go-hep.org/x/hep@v0.38.1/groot/doc.go (about) 1 // Copyright ©2018 The go-hep Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package groot provides a pure-go read/write-access to ROOT files. 6 // 7 // A typical usage is as follows: 8 // 9 // f, err := groot.Open("ntup.root") 10 // if err != nil { 11 // log.Fatal(err) 12 // } 13 // defer f.Close() 14 // 15 // obj, err := f.Get("tree") 16 // if err != nil { 17 // log.Fatal(err) 18 // } 19 // tree := obj.(rtree.Tree) 20 // fmt.Printf("entries= %v\n", tree.Entries()) 21 // 22 // More complete examples on how to iterate over the content of a Tree can 23 // be found in the examples attached to groot.TreeScanner and groot.Scanner: 24 // https://godoc.org/go-hep.org/x/hep/groot/rtree#pkg-examples 25 // 26 // Another possibility is to look at: 27 // https://godoc.org/go-hep.org/x/hep/groot/cmd/root-ls, 28 // a command that inspects the content of ROOT files. 29 // 30 // # File layout 31 // 32 // ROOT files are a suite of consecutive data records. 33 // Each data record consists of a header part, called a TKey, and a payload 34 // whose content, length and meaning are described by the header. 35 // The current ROOT file format encodes all data in big endian. 36 // 37 // ROOT files initially only supported 32b addressing. 38 // Large files support (>4Gb) was added later on by migrating to a 64b addressing. 39 // 40 // The on-disk binary layout of a ROOT file header looks like this: 41 // 42 // Type | Record Name | Description 43 // =================+=============+=========================================== 44 // [4]byte | "root" | Root file identifier 45 // int32 | fVersion | File format version 46 // int32 | fBEGIN | Pointer to first data record 47 // int32 [int64] | fEND | Pointer to first free word at the EOF 48 // int32 [int64] | fSeekFree | Pointer to FREE data record 49 // int32 | fNbytesFree | Number of bytes in FREE data record 50 // int32 | nfree | Number of free data records 51 // int32 | fNbytesName | Number of bytes in TNamed at creation time 52 // byte | fUnits | Number of bytes for file pointers 53 // int32 | fCompress | Compression level and algorithm 54 // int32 [int64] | fSeekInfo | Pointer to TStreamerInfo record 55 // int32 | fNbytesInfo | Number of bytes in TStreamerInfo record 56 // [18]byte | fUUID | Universal Unique ID 57 // =================+=============+=========================================== 58 // 59 // This is followed by a sequence of data records, starting at the fBEGIN 60 // offset from the beginning of the file. 61 // 62 // The on-disk binary layout of a data record is: 63 // 64 // Type | Member Name | Description 65 // ===============+=============+=========================================== 66 // int32 | Nbytes | Length of compressed object (in bytes) 67 // int16 | Version | TKey version identifier 68 // int32 | ObjLen | Length of uncompressed object 69 // int32 | Datime | Date and time when object was written to file 70 // int16 | KeyLen | Length of the key structure (in bytes) 71 // int16 | Cycle | Cycle of key 72 // int32 [int64] | SeekKey | Pointer to record itself (consistency check) 73 // int32 [int64] | SeekPdir | Pointer to directory header 74 // byte | lname | Number of bytes in the class name 75 // []byte | ClassName | Object Class Name 76 // byte | lname | Number of bytes in the object name 77 // []byte | Name | Name of the object 78 // byte | lTitle | Number of bytes in the object title 79 // []byte | Title | Title of the object 80 // []byte | DATA | Data bytes associated to the object 81 // ===============+=============+=========================================== 82 // 83 // The high-level on-disk representation of a ROOT file is thus: 84 // 85 // +===============+ -- 0 86 // | | 87 // | File Header | 88 // | | 89 // +===============+ -- fBEGIN offset 90 // | | 91 // | Record Header | -->-+ 92 // | | | 93 // +---------------+ | 94 // | | | 95 // | Record Data | | Reference to next Record 96 // | Payload | | 97 // | | | 98 // +===============+ <---+ 99 // | | 100 // | Record Header | -->-+ 101 // | | | 102 // +---------------+ | 103 // | | | 104 // | Record Data | | Reference to next Record 105 // | Payload | | 106 // | | | 107 // +===============+ <---+ 108 // | | 109 // ... 110 // 111 // | | 112 // +===============+ -- fSeekInfo 113 // | | 114 // | Record Header | -->-+ 115 // | | | 116 // +---------------+ | 117 // | | | 118 // | Record Data | | Reference to next Record 119 // | Payload | | 120 // | | | 121 // +===============+ <---+ -- fEND offset 122 // 123 // Data records payloads and how to deserialize them are described by a TStreamerInfo. 124 // The list of all TStreamerInfos that are used to interpret the content of 125 // a ROOT file is stored at the end of that ROOT file, at offset fSeekInfo. 126 // 127 // # Data records 128 // 129 // Data records' payloads may be compressed. 130 // Detecting whether a payload is compressed is usually done by comparing 131 // the object length (ObjLen) field of the record header with the length 132 // of the compressed object (Nbytes) field. 133 // If they differ after having subtracted the record header length, then 134 // the payload has been compressed. 135 // 136 // A record data payload is itself split into multiple chunks of maximum 137 // size 16*1024*1024 bytes. 138 // Each chunk consists of: 139 // 140 // - the chunk header, 141 // - the chunk compressed payload. 142 // 143 // The chunk header: 144 // 145 // - 3 bytes to identify the compression algorithm and version, 146 // - 3 bytes to identify the deflated buffer size, 147 // - 3 bytes to identify the inflated buffer size. 148 // 149 // # Streamer informations 150 // 151 // Streamers describe how a given type, for a given version of that type, is 152 // written on disk. 153 // In C++/ROOT, a streamer is represented as a TStreamerInfo class that can 154 // give metadata about the type it's describing (version, name). 155 // When reading a file, all the streamer infos are read back in memory, from 156 // disk, by reading the data record at offset fSeekInfo. 157 // A streamer info is actually a list of streamer elements, one for each field 158 // and, in C++, base class (in Go, this is emulated as an embedded field.) 159 // 160 // # go generate groot 161 // 162 // groot is a pure-Go package, but to ensure two-way compatibility with ROOT/C++ 163 // (ie: groot can read files created with ROOT/C++ and ROOT/C++ can read files 164 // created with groot), the groot package may require a proper ROOT/C++ installation. 165 // This is the case, e.g., with the 'go generate go-hep.org/x/hep/groot' command. 166 // This command will invoke ROOT/C++ to create ROOT files and to inspect a 167 // ROOT/C++ installation for some metadata (ROOT version, TStreamerXXX versions, etc...) 168 // 169 // Installation of ROOT/C++ is documented here: 170 // 171 // https://root.cern/install/ 172 // 173 // groot should remain buildable without a ROOT/C++ installation. 174 package groot // import "go-hep.org/x/hep/groot"