go-hep.org/x/hep@v0.38.1/groot/rarrow/reader_test.go (about) 1 // Copyright ©2019 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 rarrow // import "go-hep.org/x/hep/groot/rarrow" 6 7 import ( 8 "fmt" 9 "os" 10 "strings" 11 "testing" 12 13 "git.sr.ht/~sbinet/go-arrow/array" 14 "git.sr.ht/~sbinet/go-arrow/memory" 15 "go-hep.org/x/hep/groot" 16 "go-hep.org/x/hep/groot/riofs" 17 "go-hep.org/x/hep/groot/rtree" 18 ) 19 20 func TestRecord(t *testing.T) { 21 for _, tc := range []struct { 22 file string 23 tree string 24 want string 25 }{ 26 { 27 file: "../testdata/simple.root", 28 tree: "tree", 29 want: "testdata/simple.root.txt", 30 }, 31 { 32 file: "../testdata/small-flat-tree.root", 33 tree: "tree", 34 want: "testdata/small-flat-tree.root.txt", 35 }, 36 { 37 file: "../testdata/small-evnt-tree-fullsplit.root", 38 tree: "tree", 39 want: "testdata/small-evnt-tree-fullsplit.root.txt", 40 }, 41 { 42 file: "../testdata/small-evnt-tree-nosplit.root", 43 tree: "tree", 44 want: "testdata/small-evnt-tree-nosplit.root.txt", 45 }, 46 { 47 // n-dim arrays 48 // FIXME(sbinet): arrays of Float16_t and Double32_t are flatten. 49 // This is because of: 50 // https://sft.its.cern.ch/jira/browse/ROOT-10149 51 file: "../testdata/ndim.root", 52 tree: "tree", 53 want: "testdata/ndim.root.txt", 54 }, 55 { 56 // slice of n-dim arrays 57 // FIXME(sbinet): arrays of Float16_t and Double32_t are flatten. 58 // This is because of: 59 // https://sft.its.cern.ch/jira/browse/ROOT-10149 60 file: "../testdata/ndim-slice.root", 61 tree: "tree", 62 want: "testdata/ndim-slice.root.txt", 63 }, 64 } { 65 t.Run(tc.file, func(t *testing.T) { 66 f, err := groot.Open(tc.file) 67 if err != nil { 68 t.Fatal(err) 69 } 70 defer f.Close() 71 72 o, err := riofs.Dir(f).Get(tc.tree) 73 if err != nil { 74 t.Fatal(err) 75 } 76 77 mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) 78 defer mem.AssertSize(t, 0) 79 80 tree := o.(rtree.Tree) 81 rec := NewRecord(tree, WithAllocator(mem)) 82 defer rec.Release() 83 84 if got, want := rec.NumCols(), int64(len(tree.Branches())); got != want { 85 t.Fatalf("invalid number of columns: got=%d, want=%d", got, want) 86 } 87 88 if got, want := rec.NumRows(), tree.Entries(); got != want { 89 t.Fatalf("invalid number of rows: got=%d, want=%d", got, want) 90 } 91 92 for i, branch := range tree.Branches() { 93 col := rec.Column(i) 94 if got, want := int64(col.Len()), rec.NumRows(); got != want { 95 t.Fatalf("invalid column size[%d]: got=%d, want=%d", i, got, want) 96 } 97 name := rec.ColumnName(i) 98 if got, want := name, branch.Name(); got != want { 99 t.Fatalf("invalid column name[%d]: got=%q, want=%q", i, got, want) 100 } 101 } 102 103 rec.Retain() 104 rec.Release() 105 106 for _, tc := range []struct{ beg, end, want int64 }{ 107 {0, rec.NumRows(), rec.NumRows()}, 108 {0, rec.NumRows() - 1, rec.NumRows() - 1}, 109 {0, 0, 0}, 110 {0, 1, 1}, 111 {0, 2, 2}, 112 {1, 2, 1}, 113 } { 114 t.Run(fmt.Sprintf("slice-%d-%d", tc.beg, tc.end), func(t *testing.T) { 115 sub := rec.NewSlice(tc.beg, tc.end) 116 defer sub.Release() 117 118 if got, want := sub.NumCols(), rec.NumCols(); got != want { 119 t.Fatalf("invalid number of sub-cols: got=%d, want=%d", got, want) 120 } 121 122 if got, want := sub.NumRows(), tc.want; got != want { 123 t.Fatalf("invalid number of sub-rows: got=%d, want=%d", got, want) 124 } 125 }) 126 } 127 128 rr, err := array.NewRecordReader(rec.Schema(), []array.Record{rec}) 129 if err != nil { 130 t.Fatal(err) 131 } 132 defer rr.Release() 133 134 recs := 0 135 out := new(strings.Builder) 136 fmt.Fprintf(out, "file: %s\n", tc.file) 137 for rr.Next() { 138 rec := rr.Record() 139 for i, col := range rec.Columns() { 140 fmt.Fprintf(out, "rec[%d][%s]: %v\n", recs, rec.Schema().Field(i).Name, col) 141 } 142 recs++ 143 } 144 145 want, err := os.ReadFile(tc.want) 146 if err != nil { 147 t.Fatal(err) 148 } 149 150 if got, want := out.String(), string(want); got != want { 151 t.Fatalf("invalid table\ngot:\n%s\nwant:\n%s\n", got, want) 152 } 153 }) 154 } 155 } 156 157 func TestRecordReader(t *testing.T) { 158 for _, tc := range []struct { 159 file string 160 tree string 161 chunk int64 162 want string 163 }{ 164 { 165 file: "../testdata/leaves.root", 166 tree: "tree", 167 chunk: -1, 168 want: "testdata/leaves.root.txt", 169 }, 170 { 171 file: "../testdata/simple.root", 172 tree: "tree", 173 chunk: -1, 174 want: "testdata/simple.root.txt", 175 }, 176 { 177 file: "../testdata/simple.root", 178 tree: "tree", 179 chunk: 0, 180 want: "testdata/simple.root.chunk=1.txt", 181 }, 182 { 183 file: "../testdata/simple.root", 184 tree: "tree", 185 chunk: 1, 186 want: "testdata/simple.root.chunk=1.txt", 187 }, 188 { 189 file: "../testdata/simple.root", 190 tree: "tree", 191 chunk: 2, 192 want: "testdata/simple.root.chunk=2.txt", 193 }, 194 { 195 file: "../testdata/simple.root", 196 tree: "tree", 197 chunk: 3, 198 want: "testdata/simple.root.chunk=3.txt", 199 }, 200 { 201 file: "../testdata/simple.root", 202 tree: "tree", 203 chunk: 4, 204 want: "testdata/simple.root.txt", 205 }, 206 { 207 file: "../testdata/small-flat-tree.root", 208 tree: "tree", 209 chunk: -1, 210 want: "testdata/small-flat-tree.root.txt", 211 }, 212 { 213 file: "../testdata/small-evnt-tree-fullsplit.root", 214 tree: "tree", 215 chunk: -1, 216 want: "testdata/small-evnt-tree-fullsplit.root.txt", 217 }, 218 { 219 file: "../testdata/small-evnt-tree-nosplit.root", 220 tree: "tree", 221 chunk: -1, 222 want: "testdata/small-evnt-tree-nosplit.root.txt", 223 }, 224 } { 225 t.Run(fmt.Sprintf("%s-with-chunk=%d", tc.file, tc.chunk), func(t *testing.T) { 226 f, err := groot.Open(tc.file) 227 if err != nil { 228 t.Fatal(err) 229 } 230 defer f.Close() 231 232 o, err := riofs.Dir(f).Get(tc.tree) 233 if err != nil { 234 t.Fatal(err) 235 } 236 237 mem := memory.NewCheckedAllocator(memory.NewGoAllocator()) 238 defer mem.AssertSize(t, 0) 239 240 tree := o.(rtree.Tree) 241 rr := NewRecordReader(tree, WithAllocator(mem), WithChunk(tc.chunk)) 242 defer rr.Release() 243 244 rr.Retain() 245 rr.Release() 246 247 recs := 0 248 out := new(strings.Builder) 249 fmt.Fprintf(out, "file: %s\n", tc.file) 250 for rr.Next() { 251 rec := rr.Record() 252 for i, col := range rec.Columns() { 253 fmt.Fprintf(out, "rec[%d][%s]: %v\n", recs, rec.Schema().Field(i).Name, col) 254 } 255 recs++ 256 } 257 258 want, err := os.ReadFile(tc.want) 259 if err != nil { 260 t.Fatal(err) 261 } 262 263 if got, want := out.String(), string(want); got != want { 264 t.Fatalf("invalid table\ngot:\n%s\nwant:\n%s\n", got, want) 265 } 266 }) 267 } 268 }