go-hep.org/x/hep@v0.38.1/groot/rtree/rw_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 rtree 6 7 import ( 8 "compress/flate" 9 "fmt" 10 "io" 11 "math/rand" 12 "os" 13 "path" 14 "path/filepath" 15 "reflect" 16 "strings" 17 "testing" 18 19 "go-hep.org/x/hep/groot/internal/rtests" 20 "go-hep.org/x/hep/groot/rbase" 21 "go-hep.org/x/hep/groot/rbytes" 22 "go-hep.org/x/hep/groot/rdict" 23 "go-hep.org/x/hep/groot/riofs" 24 "go-hep.org/x/hep/groot/root" 25 "go-hep.org/x/hep/groot/rtypes" 26 "go-hep.org/x/hep/internal/diff" 27 ) 28 29 func TestBasketRW(t *testing.T) { 30 tmp, err := os.MkdirTemp("", "groot-rtree-") 31 if err != nil { 32 t.Fatalf("could not create temporary directory: %v", err) 33 } 34 f, err := riofs.Create(filepath.Join(tmp, "basket.root")) 35 if err != nil { 36 t.Fatalf("could not create temporary file: %v", err) 37 } 38 defer f.Close() 39 defer os.RemoveAll(tmp) 40 41 dir, err := f.Mkdir("data") 42 if err != nil { 43 t.Fatalf("could not create TDirectory: %v", err) 44 } 45 46 var ( 47 signed = false 48 branch = &tbranch{ 49 named: *rbase.NewNamed("b1", "branch1"), 50 } 51 leaf = newLeafI(branch, "I32", nil, signed, nil) 52 ) 53 branch.leaves = append(branch.leaves, leaf) 54 55 for _, tc := range []struct { 56 basket Basket 57 }{ 58 { 59 basket: Basket{ 60 key: riofs.KeyFromDir(dir, "empty", "title", "TBasket"), 61 branch: branch, 62 }, 63 }, 64 { 65 basket: Basket{ 66 key: riofs.KeyFromDir(dir, "simple", "title", "TBasket"), 67 bufsize: 5, 68 nevsize: 4, 69 nevbuf: 3, 70 last: 0, 71 branch: branch, 72 }, 73 }, 74 { 75 basket: Basket{ 76 key: riofs.KeyFromDir(dir, "with-iobits", "title", "TBasket"), 77 bufsize: 5, 78 nevsize: 4, 79 nevbuf: 3, 80 last: 0, 81 iobits: 1, 82 branch: branch, 83 }, 84 }, 85 { 86 basket: Basket{ 87 key: riofs.KeyFromDir(dir, "with-offsets", "title", "TBasket"), 88 bufsize: 5, 89 nevsize: 4, 90 nevbuf: 4, 91 last: 0, 92 iobits: 1, 93 offsets: []int32{1, 2, 3, 4}, 94 branch: branch, 95 }, 96 }, 97 { 98 basket: Basket{ 99 key: riofs.KeyFromDir(dir, "with-offsets-displ", "title", "TBasket"), 100 bufsize: 5, 101 nevsize: 4, 102 nevbuf: 4, 103 last: 0, 104 iobits: 1, 105 displ: []int32{0x11, 0x12, 0x13, 0x14}, 106 offsets: []int32{1, 2, 3, 4}, 107 branch: branch, 108 }, 109 }, 110 { 111 basket: Basket{ 112 key: riofs.KeyFromDir(dir, "with-buffer-ref", "title", "TBasket"), 113 bufsize: 5, 114 nevsize: 4, 115 nevbuf: 4, 116 last: 1, 117 iobits: 1, 118 branch: branch, 119 wbuf: rbytes.NewWBuffer([]byte{42}, nil, 0, nil), 120 }, 121 }, 122 } { 123 t.Run(tc.basket.Name(), func(t *testing.T) { 124 wbuf := rbytes.NewWBuffer(nil, nil, 0, nil) 125 126 var wantBufRef []byte 127 if tc.basket.wbuf != nil { 128 tc.basket.wbuf.SetPos(int64(tc.basket.last)) 129 want := tc.basket.wbuf.Bytes() 130 wantBufRef = make([]byte, len(want)) 131 copy(wantBufRef, want) 132 } 133 134 n, err := tc.basket.MarshalROOT(wbuf) 135 if err != nil { 136 t.Fatalf("could not marshal basket: n=%d err=%v", n, err) 137 } 138 139 rbuf := rbytes.NewRBuffer(wbuf.Bytes(), nil, 0, nil) 140 var b Basket 141 err = b.UnmarshalROOT(rbuf) 142 if err != nil { 143 t.Fatalf("could not unmarshal basket: %v", err) 144 } 145 b.branch = branch 146 147 for _, tt := range []struct { 148 name string 149 got, want any 150 }{ 151 {"bufsize", b.bufsize, tc.basket.bufsize}, 152 {"nevsize", b.nevsize, tc.basket.nevsize}, 153 {"nevbuf", b.nevbuf, tc.basket.nevbuf}, 154 {"last", b.last, tc.basket.last}, 155 {"header", b.header, tc.basket.header}, 156 {"iobits", b.iobits, tc.basket.iobits}, 157 {"displ", b.displ, tc.basket.displ}, 158 {"offsets", b.offsets, tc.basket.offsets}, 159 } { 160 if !reflect.DeepEqual(tt.got, tt.want) { 161 t.Fatalf("invalid round-trip for %s:\ngot= %#v\nwant=%#v", tt.name, tt.got, tt.want) 162 } 163 } 164 165 if wantBufRef != nil { 166 raw, err := b.key.Bytes() 167 if err != nil { 168 t.Fatalf("could not unpack key payload: %v", err) 169 } 170 if got, want := raw, wantBufRef; !reflect.DeepEqual(got, want) { 171 t.Fatalf("invalid-roundtrip for wbuf:\ngot= %v\nwant=%v", got, want) 172 } 173 } 174 }) 175 } 176 177 } 178 179 func TestIOFeaturesRW(t *testing.T) { 180 for _, tc := range []struct { 181 name string 182 want tioFeatures 183 }{ 184 {"io-0x00", 0x00}, 185 {"io-0x01", 0x01}, 186 {"io-0x02", 0x02}, 187 {"io-0x03", 0x03}, 188 {"io-0xff", 0xff}, 189 } { 190 t.Run(tc.name, func(t *testing.T) { 191 wbuf := rbytes.NewWBuffer(nil, nil, 0, nil) 192 193 n, err := tc.want.MarshalROOT(wbuf) 194 if err != nil { 195 t.Fatalf("could not marshal IOFeatures: n=%d err=%v", n, err) 196 } 197 198 rbuf := rbytes.NewRBuffer(wbuf.Bytes(), nil, 0, nil) 199 var got tioFeatures 200 err = got.UnmarshalROOT(rbuf) 201 if err != nil { 202 t.Fatalf("could not unmarshal IOFeatures: %v", err) 203 } 204 205 if !reflect.DeepEqual(tc.want, got) { 206 t.Fatalf("invalid round-trip: got=%x, want=%x", got, tc.want) 207 } 208 }) 209 } 210 } 211 212 func TestBranchRW(t *testing.T) { 213 const ( 214 unsigned = true 215 signed = false 216 ) 217 218 tmp, err := os.MkdirTemp("", "groot-rtree-") 219 if err != nil { 220 t.Fatalf("could not create temporary directory: %v", err) 221 } 222 f, err := riofs.Create(filepath.Join(tmp, "basket.root")) 223 if err != nil { 224 t.Fatalf("could not create temporary file: %v", err) 225 } 226 defer f.Close() 227 defer os.RemoveAll(tmp) 228 229 dir, err := f.Mkdir("data") 230 if err != nil { 231 t.Fatalf("could not create TDirectory: %v", err) 232 } 233 234 for _, tc := range []struct { 235 name string 236 want rtests.ROOTer 237 }{ 238 { 239 name: "TBranch", 240 want: &tbranch{ 241 named: *rbase.NewNamed("branch", "leaf1/I"), 242 attfill: *rbase.NewAttFill(), 243 compress: 1, 244 basketSize: defaultBasketSize, 245 entryOffsetLen: 0, 246 writeBasket: 1, 247 entryNumber: 4, 248 iobits: 0, 249 offset: 0, 250 maxBaskets: 10, 251 splitLevel: 1, 252 entries: 4, 253 firstEntry: 0, 254 totBytes: 86, 255 zipBytes: 86, 256 branches: []Branch{}, 257 leaves: []Leaf{}, 258 baskets: []Basket{}, 259 basketBytes: []int32{86}, 260 basketEntry: []int64{0, 4}, 261 basketSeek: []int64{304}, 262 fname: "foo.root", 263 264 // 265 ctx: basketCtx{ 266 entry: -1, 267 first: -1, 268 next: -1, 269 }, 270 }, 271 }, 272 { 273 name: "TBranch-with-leaves", 274 want: &tbranch{ 275 named: *rbase.NewNamed("branch", "leaf1/I:leaf2/L:leaf3/G"), 276 attfill: *rbase.NewAttFill(), 277 compress: 1, 278 basketSize: defaultBasketSize, 279 entryOffsetLen: 0, 280 writeBasket: 1, 281 entryNumber: 4, 282 iobits: 0, 283 offset: 0, 284 maxBaskets: 10, 285 splitLevel: 1, 286 entries: 4, 287 firstEntry: 0, 288 totBytes: 86, 289 zipBytes: 86, 290 branches: []Branch{}, 291 leaves: []Leaf{ 292 newLeafI(nil, "leaf1", nil, signed, nil), 293 newLeafL(nil, "leaf2", nil, signed, nil), 294 newLeafG(nil, "leaf3", nil, signed, nil), 295 }, 296 baskets: []Basket{}, 297 basketBytes: []int32{86}, 298 basketEntry: []int64{0, 4}, 299 basketSeek: []int64{304}, 300 fname: "foo.root", 301 302 // 303 ctx: basketCtx{ 304 entry: -1, 305 first: -1, 306 next: -1, 307 }, 308 }, 309 }, 310 { 311 name: "TBranch-with-baskets", 312 want: &tbranch{ 313 named: *rbase.NewNamed("branch", "leaf1/I:leaf2/L:leaf3/G"), 314 attfill: *rbase.NewAttFill(), 315 compress: 1, 316 basketSize: defaultBasketSize, 317 entryOffsetLen: 0, 318 writeBasket: 1, 319 entryNumber: 4, 320 iobits: 0, 321 offset: 0, 322 maxBaskets: 10, 323 splitLevel: 1, 324 entries: 4, 325 firstEntry: 0, 326 totBytes: 86, 327 zipBytes: 86, 328 branches: []Branch{}, 329 leaves: []Leaf{ 330 newLeafI(nil, "leaf1", nil, signed, nil), 331 newLeafL(nil, "leaf2", nil, signed, nil), 332 newLeafG(nil, "leaf3", nil, signed, nil), 333 }, 334 baskets: []Basket{ 335 { 336 key: riofs.KeyFromDir(dir, "with-offsets", "title", "TBasket"), 337 bufsize: 5, 338 nevsize: 4, 339 nevbuf: 4, 340 last: 0, 341 iobits: 1, 342 offsets: []int32{1, 2, 3, 4}, 343 branch: nil, 344 }, 345 }, 346 basketBytes: []int32{86}, 347 basketEntry: []int64{0, 4}, 348 basketSeek: []int64{304}, 349 fname: "foo.root", 350 351 // 352 ctx: basketCtx{ 353 entry: -1, 354 first: -1, 355 next: -1, 356 }, 357 }, 358 }, 359 { 360 name: "TBranchElement", 361 want: &tbranchElement{ 362 tbranch: tbranch{ 363 named: *rbase.NewNamed("branch", "leaf1/I:leaf2/L:leaf3/G"), 364 attfill: *rbase.NewAttFill(), 365 compress: 1, 366 basketSize: defaultBasketSize, 367 entryOffsetLen: 0, 368 writeBasket: 1, 369 entryNumber: 4, 370 iobits: 0, 371 offset: 0, 372 maxBaskets: 10, 373 splitLevel: 1, 374 entries: 4, 375 firstEntry: 0, 376 totBytes: 86, 377 zipBytes: 86, 378 branches: []Branch{}, 379 leaves: []Leaf{ 380 newLeafI(nil, "leaf1", nil, signed, nil), 381 newLeafL(nil, "leaf2", nil, signed, nil), 382 newLeafG(nil, "leaf3", nil, signed, nil), 383 }, 384 baskets: []Basket{ 385 { 386 key: riofs.KeyFromDir(dir, "with-offsets", "title", "TBasket"), 387 bufsize: 5, 388 nevsize: 4, 389 nevbuf: 4, 390 last: 0, 391 iobits: 1, 392 offsets: []int32{1, 2, 3, 4}, 393 branch: nil, 394 }, 395 }, 396 basketBytes: []int32{86}, 397 basketEntry: []int64{0, 4}, 398 basketSeek: []int64{304}, 399 fname: "foo.root", 400 401 // 402 ctx: basketCtx{ 403 entry: -1, 404 first: -1, 405 next: -1, 406 }, 407 }, 408 class: "myclass", 409 parent: "parentclass", 410 clones: "clones", 411 chksum: 123456789, 412 clsver: 42, 413 id: 3, 414 btype: 4, 415 stype: 5, 416 max: 42, 417 //stltyp: 45, 418 }, 419 }, 420 { 421 name: "TBranchElement-with-bcount1", 422 want: &tbranchElement{ 423 tbranch: tbranch{ 424 named: *rbase.NewNamed("branch", "leaf1/I:leaf2/L:leaf3/G"), 425 attfill: *rbase.NewAttFill(), 426 compress: 1, 427 basketSize: defaultBasketSize, 428 entryOffsetLen: 0, 429 writeBasket: 1, 430 entryNumber: 4, 431 iobits: 0, 432 offset: 0, 433 maxBaskets: 10, 434 splitLevel: 1, 435 entries: 4, 436 firstEntry: 0, 437 totBytes: 86, 438 zipBytes: 86, 439 branches: []Branch{}, 440 leaves: []Leaf{ 441 newLeafI(nil, "leaf1", nil, signed, nil), 442 newLeafL(nil, "leaf2", nil, signed, nil), 443 newLeafG(nil, "leaf3", nil, signed, nil), 444 }, 445 baskets: []Basket{ 446 { 447 key: riofs.KeyFromDir(dir, "with-offsets", "title", "TBasket"), 448 bufsize: 5, 449 nevsize: 4, 450 nevbuf: 4, 451 last: 0, 452 iobits: 1, 453 offsets: []int32{1, 2, 3, 4}, 454 branch: nil, 455 }, 456 }, 457 basketBytes: []int32{86}, 458 basketEntry: []int64{0, 4}, 459 basketSeek: []int64{304}, 460 fname: "foo.root", 461 462 // 463 ctx: basketCtx{ 464 entry: -1, 465 first: -1, 466 next: -1, 467 }, 468 }, 469 class: "myclass", 470 parent: "parentclass", 471 clones: "clones", 472 chksum: 123456789, 473 clsver: 42, 474 id: 3, 475 btype: 4, 476 stype: 5, 477 max: 42, 478 //stltyp: 45, 479 bcount1: &tbranchElement{ 480 tbranch: tbranch{ 481 named: *rbase.NewNamed("count", "leaf1/I"), 482 attfill: *rbase.NewAttFill(), 483 compress: 1, 484 basketSize: defaultBasketSize, 485 entryOffsetLen: 0, 486 writeBasket: 1, 487 entryNumber: 4, 488 iobits: 0, 489 offset: 0, 490 maxBaskets: 10, 491 splitLevel: 1, 492 entries: 4, 493 firstEntry: 0, 494 totBytes: 86, 495 zipBytes: 86, 496 branches: []Branch{}, 497 leaves: []Leaf{ 498 newLeafI(nil, "leaf1", nil, signed, nil), 499 }, 500 baskets: []Basket{ 501 { 502 key: riofs.KeyFromDir(dir, "with-offsets", "title", "TBasket"), 503 bufsize: 5, 504 nevsize: 4, 505 nevbuf: 4, 506 last: 0, 507 iobits: 1, 508 offsets: []int32{1, 2, 3, 4}, 509 branch: nil, 510 }, 511 }, 512 basketBytes: []int32{86}, 513 basketEntry: []int64{0, 4}, 514 basketSeek: []int64{304}, 515 fname: "foo.root", 516 517 // 518 ctx: basketCtx{ 519 entry: -1, 520 first: -1, 521 next: -1, 522 }, 523 }, 524 class: "myotherclass", 525 parent: "parentclass", 526 clones: "clones", 527 chksum: 123456789, 528 clsver: 42, 529 id: 3, 530 btype: 4, 531 stype: 5, 532 max: 42, 533 // stltyp: 45, 534 }, 535 }, 536 }, 537 } { 538 t.Run(tc.name, func(t *testing.T) { 539 { 540 wbuf := rbytes.NewWBuffer(nil, nil, 0, nil) 541 wbuf.SetErr(io.EOF) 542 _, err := tc.want.MarshalROOT(wbuf) 543 if err == nil { 544 t.Fatalf("expected an error") 545 } 546 if err != io.EOF { 547 t.Fatalf("got=%v, want=%v", err, io.EOF) 548 } 549 } 550 551 asTBranch := func(b any) *tbranch { 552 switch b := b.(type) { 553 case *tbranch: 554 return b 555 case *tbranchElement: 556 return &b.tbranch 557 } 558 panic("impossible") 559 } 560 561 setupInput := func(b any) { 562 if b := asTBranch(b); len(b.leaves) != 0 { 563 for i := range b.leaves { 564 b.leaves[i].setBranch(b) 565 } 566 } 567 if b := asTBranch(tc.want); len(b.baskets) != 0 { 568 for i := range b.baskets { 569 b.baskets[i].branch = b 570 } 571 } 572 573 } 574 575 setupInput(tc.want) 576 577 if b, ok := tc.want.(*tbranchElement); ok { 578 if b.bcount1 != nil { 579 setupInput(b.bcount1) 580 } 581 } 582 583 wbuf := rbytes.NewWBuffer(nil, nil, 0, nil) 584 _, err := tc.want.MarshalROOT(wbuf) 585 if err != nil { 586 t.Fatalf("could not marshal ROOT: %v", err) 587 } 588 589 rbuf := rbytes.NewRBuffer(wbuf.Bytes(), nil, 0, nil) 590 class := tc.want.Class() 591 obj := rtypes.Factory.Get(class)().Interface().(rbytes.Unmarshaler) 592 { 593 rbuf.SetErr(io.EOF) 594 err = obj.UnmarshalROOT(rbuf) 595 if err == nil { 596 t.Fatalf("expected an error") 597 } 598 if err != io.EOF { 599 t.Fatalf("got=%v, want=%v", err, io.EOF) 600 } 601 rbuf.SetErr(nil) 602 } 603 err = obj.UnmarshalROOT(rbuf) 604 if err != nil { 605 t.Fatalf("could not unmarshal ROOT: %v", err) 606 } 607 608 if b := asTBranch(obj); len(b.baskets) != 0 { 609 for i := range b.baskets { 610 b.baskets[i].branch = b 611 b.baskets[i].key = asTBranch(tc.want).baskets[i].key 612 } 613 } 614 615 if b, ok := obj.(*tbranchElement); ok { 616 617 want := tc.want.(*tbranchElement) 618 if want.bcount1 != nil { 619 for i := range b.bcount1.baskets { 620 b.bcount1.baskets[i].branch = want.bcount1.baskets[i].branch 621 b.bcount1.baskets[i].key = want.bcount1.baskets[i].key 622 } 623 } 624 625 var cmpTBE func(n string, got, want *tbranchElement) 626 cmpTBE = func(n string, got, want *tbranchElement) { 627 if got == nil && want == nil { 628 return 629 } 630 if got == nil && want != nil { 631 t.Fatalf("got=%v, want=%v", got, want) 632 } 633 if got != nil && want == nil { 634 t.Fatalf("got=%v, want=%v", got, want) 635 } 636 637 for i, v := range []struct { 638 got, want any 639 }{ 640 {got.tbranch, want.tbranch}, 641 {got.class, want.class}, 642 {got.parent, want.parent}, 643 {got.clones, want.clones}, 644 {got.chksum, want.chksum}, 645 {got.clsver, want.clsver}, 646 {got.id, want.id}, 647 {got.btype, want.btype}, 648 {got.stype, want.stype}, 649 {got.max, want.max}, 650 {got.stltyp, want.stltyp}, 651 {got.streamer, want.streamer}, 652 {got.estreamer, want.estreamer}, 653 } { 654 if !reflect.DeepEqual(v.got, v.want) { 655 t.Fatalf("error[%s-%d]\ngot= %+v\nwant=%+v\n", n, i, v.got, v.want) 656 } 657 } 658 cmpTBE("bcount1", got.bcount1, want.bcount1) 659 cmpTBE("bcount2", got.bcount2, want.bcount2) 660 } 661 cmpTBE("master", b, want) 662 return 663 } 664 665 if !reflect.DeepEqual(obj, tc.want) { 666 t.Fatalf("error\ngot= %+v\nwant=%+v\n", obj, tc.want) 667 } 668 }) 669 } 670 } 671 672 func TestTreeRW(t *testing.T) { 673 tmp, err := os.MkdirTemp("", "groot-rtree-") 674 if err != nil { 675 t.Fatalf("could not create dir: %v", err) 676 } 677 defer os.RemoveAll(tmp) 678 679 const ( 680 treeName = "mytree" 681 ) 682 683 for _, tc := range []struct { 684 name string 685 skip bool 686 wopts []WriteOption 687 nevts int64 688 wvars []WriteVar 689 btitles []string 690 ltitles []string 691 total int 692 want func(i int) any 693 scan []string // list of branches to use for ROOT TTree::Scan 694 cxx string // expected ROOT-TTree::Scan 695 }{ 696 { 697 name: "empty", 698 nevts: 5, 699 wvars: []WriteVar{}, 700 btitles: []string{}, 701 ltitles: []string{}, 702 total: 5 * (0), 703 want: func(i int) any { return nil }, 704 cxx: `************ 705 * Row * 706 ************ 707 * 0 * 708 * 1 * 709 * 2 * 710 * 3 * 711 * 4 * 712 ************ 713 `, 714 }, 715 { 716 name: "simple", 717 nevts: 5, 718 wvars: []WriteVar{ 719 {Name: "i32", Value: new(int32)}, 720 {Name: "f64", Value: new(float64)}, 721 }, 722 btitles: []string{"i32/I", "f64/D"}, 723 ltitles: []string{"i32", "f64"}, 724 total: 5 * (4 + 8), 725 want: func(i int) any { 726 return struct { 727 I32 int32 728 F64 float64 729 }{ 730 I32: int32(i), 731 F64: float64(i), 732 } 733 }, 734 cxx: `************************************ 735 * Row * i32.i32 * f64.f64 * 736 ************************************ 737 * 0 * 0 * 0 * 738 * 1 * 1 * 1 * 739 * 2 * 2 * 2 * 740 * 3 * 3 * 3 * 741 * 4 * 4 * 4 * 742 ************************************ 743 `, 744 }, 745 { 746 name: "builtins", 747 nevts: 5, 748 wvars: []WriteVar{ 749 {Name: "B", Value: new(bool)}, 750 {Name: "I8", Value: new(int8)}, 751 {Name: "I16", Value: new(int16)}, 752 {Name: "I32", Value: new(int32)}, 753 {Name: "I64", Value: new(int64)}, 754 {Name: "U8", Value: new(uint8)}, 755 {Name: "U16", Value: new(uint16)}, 756 {Name: "U32", Value: new(uint32)}, 757 {Name: "U64", Value: new(uint64)}, 758 {Name: "F32", Value: new(float32)}, 759 {Name: "F64", Value: new(float64)}, 760 {Name: "D16", Value: new(root.Float16)}, 761 {Name: "D32", Value: new(root.Double32)}, 762 }, 763 btitles: []string{ 764 "B/O", 765 "I8/B", "I16/S", "I32/I", "I64/L", 766 "U8/b", "U16/s", "U32/i", "U64/l", 767 "F32/F", "F64/D", "D16/f", "D32/d", 768 }, 769 ltitles: []string{ 770 "B", 771 "I8", "I16", "I32", "I64", 772 "U8", "U16", "U32", "U64", 773 "F32", "F64", "D16", "D32", 774 }, 775 total: 5 * 50, 776 want: func(i int) any { 777 return struct { 778 B bool 779 I8 int8 780 I16 int16 781 I32 int32 782 I64 int64 783 U8 uint8 784 U16 uint16 785 U32 uint32 786 U64 uint64 787 F32 float32 788 F64 float64 789 D16 root.Float16 790 D32 root.Double32 791 }{ 792 B: bool(i%2 == 0), 793 I8: int8(i), 794 I16: int16(i), 795 I32: int32(i), 796 I64: int64(i), 797 U8: uint8(i), 798 U16: uint16(i), 799 U32: uint32(i), 800 U64: uint64(i), 801 F32: float32(i), 802 F64: float64(i), 803 D16: root.Float16(i), 804 D32: root.Double32(i), 805 } 806 }, 807 cxx: `************************************************************************************************************************************************************************ 808 * Row * B.B * I8.I8 * I16.I16 * I32.I32 * I64.I64 * U8.U8 * U16.U16 * U32.U32 * U64.U64 * F32.F32 * F64.F64 * D16.D16 * D32.D32 * 809 ************************************************************************************************************************************************************************ 810 * 0 * 1 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 811 * 1 * 0 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 812 * 2 * 1 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 813 * 3 * 0 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 814 * 4 * 1 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 815 ************************************************************************************************************************************************************************ 816 `, 817 }, 818 { 819 name: "strings", 820 nevts: 5, 821 wvars: []WriteVar{ 822 {Name: "i32", Value: new(int32)}, 823 {Name: "f64", Value: new(float64)}, 824 {Name: "str", Value: new(string)}, 825 }, 826 btitles: []string{"i32/I", "f64/D", "str/C"}, 827 ltitles: []string{"i32", "f64", "str"}, 828 total: 5 * (4 + 8 + (3 + 1)), // 3: strings are "xxx" + 1:string-size 829 want: func(i int) any { 830 return struct { 831 I32 int32 832 F64 float64 833 Str string 834 }{ 835 I32: int32(i), 836 F64: float64(i), 837 Str: fmt.Sprintf("%03d", i), 838 } 839 }, 840 cxx: `************************************************ 841 * Row * i32.i32 * f64.f64 * str.str * 842 ************************************************ 843 * 0 * 0 * 0 * 000 * 844 * 1 * 1 * 1 * 001 * 845 * 2 * 2 * 2 * 002 * 846 * 3 * 3 * 3 * 003 * 847 * 4 * 4 * 4 * 004 * 848 ************************************************ 849 `, 850 }, 851 { 852 name: "strings-empty", 853 nevts: 5, 854 wvars: []WriteVar{ 855 {Name: "s1", Value: new(string)}, 856 {Name: "s2", Value: new(string)}, 857 }, 858 btitles: []string{"s1/C", "s2/C"}, 859 ltitles: []string{"s1", "s2"}, 860 total: 30, 861 want: func(i int) any { 862 return struct { 863 S1 string 864 S2 string 865 }{ 866 S1: strings.Repeat("x", 4-i), 867 S2: strings.Repeat("x", i), 868 } 869 }, 870 cxx: `************************************ 871 * Row * s1.s1 * s2.s2 * 872 ************************************ 873 * 0 * xxxx * * 874 * 1 * xxx * x * 875 * 2 * xx * xx * 876 * 3 * x * xxx * 877 * 4 * * xxxx * 878 ************************************ 879 `, 880 }, 881 { 882 name: "arrays", 883 nevts: 5, 884 wvars: []WriteVar{ 885 {Name: "ArrB", Value: new([5]bool)}, 886 {Name: "ArrI8", Value: new([5]int8)}, 887 {Name: "ArrI16", Value: new([5]int16)}, 888 {Name: "ArrI32", Value: new([5]int32)}, 889 {Name: "ArrI64", Value: new([5]int64)}, 890 {Name: "ArrU8", Value: new([5]uint8)}, 891 {Name: "ArrU16", Value: new([5]uint16)}, 892 {Name: "ArrU32", Value: new([5]uint32)}, 893 {Name: "ArrU64", Value: new([5]uint64)}, 894 {Name: "ArrF32", Value: new([5]float32)}, 895 {Name: "ArrF64", Value: new([5]float64)}, 896 }, 897 btitles: []string{ 898 "ArrB[5]/O", 899 "ArrI8[5]/B", "ArrI16[5]/S", "ArrI32[5]/I", "ArrI64[5]/L", 900 "ArrU8[5]/b", "ArrU16[5]/s", "ArrU32[5]/i", "ArrU64[5]/l", 901 "ArrF32[5]/F", "ArrF64[5]/D", 902 }, 903 ltitles: []string{ 904 "ArrB[5]", 905 "ArrI8[5]", "ArrI16[5]", "ArrI32[5]", "ArrI64[5]", 906 "ArrU8[5]", "ArrU16[5]", "ArrU32[5]", "ArrU64[5]", 907 "ArrF32[5]", "ArrF64[5]", 908 }, 909 total: 5 * 215, 910 want: func(i int) any { 911 return struct { 912 ArrBool [5]bool 913 ArrI8 [5]int8 914 ArrI16 [5]int16 915 ArrI32 [5]int32 916 ArrI64 [5]int64 917 ArrU8 [5]uint8 918 ArrU16 [5]uint16 919 ArrU32 [5]uint32 920 ArrU64 [5]uint64 921 ArrF32 [5]float32 922 ArrF64 [5]float64 923 }{ 924 ArrBool: [5]bool{bool(i%2 == 0), bool((i+1)%2 == 0), bool((i+2)%2 == 0), bool((i+3)%2 == 0), bool((i+4)%2 == 0)}, 925 ArrI8: [5]int8{'a' + int8(i), int8('a' + i + 1), int8('a' + i + 2), int8('a' + i + 3), int8(0)}, 926 ArrI16: [5]int16{int16(i), int16(i + 1), int16(i + 2), int16(i + 3), int16(i + 4)}, 927 ArrI32: [5]int32{int32(i), int32(i + 1), int32(i + 2), int32(i + 3), int32(i + 4)}, 928 ArrI64: [5]int64{int64(i), int64(i + 1), int64(i + 2), int64(i + 3), int64(i + 4)}, 929 ArrU8: [5]uint8{uint8(i), uint8(i + 1), uint8(i + 2), uint8(i + 3), uint8(i + 4)}, 930 ArrU16: [5]uint16{uint16(i), uint16(i + 1), uint16(i + 2), uint16(i + 3), uint16(i + 4)}, 931 ArrU32: [5]uint32{uint32(i), uint32(i + 1), uint32(i + 2), uint32(i + 3), uint32(i + 4)}, 932 ArrU64: [5]uint64{uint64(i), uint64(i + 1), uint64(i + 2), uint64(i + 3), uint64(i + 4)}, 933 ArrF32: [5]float32{float32(i), float32(i + 1), float32(i + 2), float32(i + 3), float32(i + 4)}, 934 ArrF64: [5]float64{float64(i), float64(i + 1), float64(i + 2), float64(i + 3), float64(i + 4)}, 935 } 936 }, 937 scan: []string{ 938 "ArrB", 939 "ArrI8", "ArrI16", "ArrI32", "ArrI64", 940 "ArrU8", "ArrU16", "ArrU32", "ArrU64", 941 "ArrF32", "ArrF64", 942 }, 943 cxx: `*********************************************************************************************************************************************************** 944 * Row * Instance * ArrB * ArrI8 * ArrI16 * ArrI32 * ArrI64 * ArrU8 * ArrU16 * ArrU32 * ArrU64 * ArrF32 * ArrF64 * 945 *********************************************************************************************************************************************************** 946 * 0 * 0 * 1 * abcd * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 947 * 0 * 1 * 0 * abcd * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 948 * 0 * 2 * 1 * abcd * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 949 * 0 * 3 * 0 * abcd * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 950 * 0 * 4 * 1 * abcd * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 951 * 1 * 0 * 0 * bcde * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 952 * 1 * 1 * 1 * bcde * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 953 * 1 * 2 * 0 * bcde * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 954 * 1 * 3 * 1 * bcde * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 955 * 1 * 4 * 0 * bcde * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 956 * 2 * 0 * 1 * cdef * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 957 * 2 * 1 * 0 * cdef * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 958 * 2 * 2 * 1 * cdef * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 959 * 2 * 3 * 0 * cdef * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 960 * 2 * 4 * 1 * cdef * 6 * 6 * 6 * 6 * 6 * 6 * 6 * 6 * 6 * 961 * 3 * 0 * 0 * defg * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 962 * 3 * 1 * 1 * defg * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 963 * 3 * 2 * 0 * defg * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 964 * 3 * 3 * 1 * defg * 6 * 6 * 6 * 6 * 6 * 6 * 6 * 6 * 6 * 965 * 3 * 4 * 0 * defg * 7 * 7 * 7 * 7 * 7 * 7 * 7 * 7 * 7 * 966 * 4 * 0 * 1 * efgh * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 967 * 4 * 1 * 0 * efgh * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 968 * 4 * 2 * 1 * efgh * 6 * 6 * 6 * 6 * 6 * 6 * 6 * 6 * 6 * 969 * 4 * 3 * 0 * efgh * 7 * 7 * 7 * 7 * 7 * 7 * 7 * 7 * 7 * 970 * 4 * 4 * 1 * efgh * 8 * 8 * 8 * 8 * 8 * 8 * 8 * 8 * 8 * 971 *********************************************************************************************************************************************************** 972 `, 973 }, 974 { 975 name: "arrays-2d", 976 nevts: 5, 977 wvars: []WriteVar{ 978 {Name: "ArrB", Value: new([2][3]bool)}, 979 {Name: "ArrI8", Value: new([2][3]int8)}, 980 {Name: "ArrI16", Value: new([2][3]int16)}, 981 {Name: "ArrI32", Value: new([2][3]int32)}, 982 {Name: "ArrI64", Value: new([2][3]int64)}, 983 {Name: "ArrU8", Value: new([2][3]uint8)}, 984 {Name: "ArrU16", Value: new([2][3]uint16)}, 985 {Name: "ArrU32", Value: new([2][3]uint32)}, 986 {Name: "ArrU64", Value: new([2][3]uint64)}, 987 {Name: "ArrF32", Value: new([2][3]float32)}, 988 {Name: "ArrF64", Value: new([2][3]float64)}, 989 }, 990 btitles: []string{ 991 "ArrB[2][3]/O", 992 "ArrI8[2][3]/B", "ArrI16[2][3]/S", "ArrI32[2][3]/I", "ArrI64[2][3]/L", 993 "ArrU8[2][3]/b", "ArrU16[2][3]/s", "ArrU32[2][3]/i", "ArrU64[2][3]/l", 994 "ArrF32[2][3]/F", "ArrF64[2][3]/D", 995 }, 996 ltitles: []string{ 997 "ArrB[2][3]", 998 "ArrI8[2][3]", "ArrI16[2][3]", "ArrI32[2][3]", "ArrI64[2][3]", 999 "ArrU8[2][3]", "ArrU16[2][3]", "ArrU32[2][3]", "ArrU64[2][3]", 1000 "ArrF32[2][3]", "ArrF64[2][3]", 1001 }, 1002 total: 5 * 258, 1003 want: func(i int) any { 1004 return struct { 1005 ArrBool [2][3]bool 1006 ArrI8 [2][3]int8 1007 ArrI16 [2][3]int16 1008 ArrI32 [2][3]int32 1009 ArrI64 [2][3]int64 1010 ArrU8 [2][3]uint8 1011 ArrU16 [2][3]uint16 1012 ArrU32 [2][3]uint32 1013 ArrU64 [2][3]uint64 1014 ArrF32 [2][3]float32 1015 ArrF64 [2][3]float64 1016 }{ 1017 ArrBool: [2][3]bool{ 1018 {bool(i%2 == 0), bool((i+1)%2 == 0), bool((i+2)%2 == 0)}, 1019 {bool((i+3)%2 == 0), bool((i+4)%2 == 0), bool((i+4)%2 == 0)}, 1020 }, 1021 ArrI8: [2][3]int8{ 1022 {int8(i + 0), int8(i + 1), int8(i + 2)}, 1023 {int8(i + 3), int8(i + 4), int8(i + 5)}, 1024 }, 1025 ArrI16: [2][3]int16{ 1026 {int16(i + 0), int16(i + 1), int16(i + 2)}, 1027 {int16(i + 3), int16(i + 4), int16(i + 5)}, 1028 }, 1029 ArrI32: [2][3]int32{ 1030 {int32(i + 0), int32(i + 1), int32(i + 2)}, 1031 {int32(i + 3), int32(i + 4), int32(i + 5)}, 1032 }, 1033 ArrI64: [2][3]int64{ 1034 {int64(i + 0), int64(i + 1), int64(i + 2)}, 1035 {int64(i + 3), int64(i + 4), int64(i + 5)}, 1036 }, 1037 ArrU8: [2][3]uint8{ 1038 {uint8(i + 0), uint8(i + 1), uint8(i + 2)}, 1039 {uint8(i + 3), uint8(i + 4), uint8(i + 5)}, 1040 }, 1041 ArrU16: [2][3]uint16{ 1042 {uint16(i), uint16(i + 1), uint16(i + 2)}, 1043 {uint16(i + 3), uint16(i + 4), uint16(i + 5)}, 1044 }, 1045 ArrU32: [2][3]uint32{ 1046 {uint32(i + 0), uint32(i + 1), uint32(i + 2)}, 1047 {uint32(i + 3), uint32(i + 4), uint32(i + 5)}, 1048 }, 1049 ArrU64: [2][3]uint64{ 1050 {uint64(i + 0), uint64(i + 1), uint64(i + 2)}, 1051 {uint64(i + 3), uint64(i + 4), uint64(i + 5)}, 1052 }, 1053 ArrF32: [2][3]float32{ 1054 {float32(i + 0), float32(i + 1), float32(i + 2)}, 1055 {float32(i + 3), float32(i + 4), float32(i + 5)}, 1056 }, 1057 ArrF64: [2][3]float64{ 1058 {float64(i + 0), float64(i + 1), float64(i + 2)}, 1059 {float64(i + 3), float64(i + 4), float64(i + 5)}, 1060 }, 1061 } 1062 }, 1063 scan: []string{ 1064 "ArrB", 1065 "ArrI8+0", "ArrI16", "ArrI32", "ArrI64", 1066 "ArrU8", "ArrU16", "ArrU32", "ArrU64", 1067 "ArrF32", "ArrF64", 1068 }, 1069 cxx: `*********************************************************************************************************************************************************** 1070 * Row * Instance * ArrB * ArrI8+0 * ArrI16 * ArrI32 * ArrI64 * ArrU8 * ArrU16 * ArrU32 * ArrU64 * ArrF32 * ArrF64 * 1071 *********************************************************************************************************************************************************** 1072 * 0 * 0 * 1 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 1073 * 0 * 1 * 0 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1074 * 0 * 2 * 1 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 1075 * 0 * 3 * 0 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 1076 * 0 * 4 * 1 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 1077 * 0 * 5 * 1 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 1078 * 1 * 0 * 0 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1 * 1079 * 1 * 1 * 1 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 1080 * 1 * 2 * 0 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 1081 * 1 * 3 * 1 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 1082 * 1 * 4 * 0 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 1083 * 1 * 5 * 0 * 6 * 6 * 6 * 6 * 6 * 6 * 6 * 6 * 6 * 6 * 1084 * 2 * 0 * 1 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 1085 * 2 * 1 * 0 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 1086 * 2 * 2 * 1 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 1087 * 2 * 3 * 0 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 1088 * 2 * 4 * 1 * 6 * 6 * 6 * 6 * 6 * 6 * 6 * 6 * 6 * 6 * 1089 * 2 * 5 * 1 * 7 * 7 * 7 * 7 * 7 * 7 * 7 * 7 * 7 * 7 * 1090 * 3 * 0 * 0 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 3 * 1091 * 3 * 1 * 1 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 1092 * 3 * 2 * 0 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 1093 * 3 * 3 * 1 * 6 * 6 * 6 * 6 * 6 * 6 * 6 * 6 * 6 * 6 * 1094 * 3 * 4 * 0 * 7 * 7 * 7 * 7 * 7 * 7 * 7 * 7 * 7 * 7 * 1095 * 3 * 5 * 0 * 8 * 8 * 8 * 8 * 8 * 8 * 8 * 8 * 8 * 8 * 1096 * 4 * 0 * 1 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 4 * 1097 * 4 * 1 * 0 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 1098 * 4 * 2 * 1 * 6 * 6 * 6 * 6 * 6 * 6 * 6 * 6 * 6 * 6 * 1099 * 4 * 3 * 0 * 7 * 7 * 7 * 7 * 7 * 7 * 7 * 7 * 7 * 7 * 1100 * 4 * 4 * 1 * 8 * 8 * 8 * 8 * 8 * 8 * 8 * 8 * 8 * 8 * 1101 * 4 * 5 * 1 * 9 * 9 * 9 * 9 * 9 * 9 * 9 * 9 * 9 * 9 * 1102 *********************************************************************************************************************************************************** 1103 `, 1104 }, 1105 { 1106 name: "slices-uint", 1107 nevts: 5, 1108 wvars: []WriteVar{ 1109 {Name: "N", Value: new(int32)}, 1110 {Name: "SliU8", Value: new([]uint8), Count: "N"}, 1111 {Name: "SliU16", Value: new([]uint16), Count: "N"}, 1112 {Name: "SliU32", Value: new([]uint32), Count: "N"}, 1113 {Name: "SliU64", Value: new([]uint64), Count: "N"}, 1114 }, 1115 btitles: []string{ 1116 "N/I", 1117 "SliU8[N]/b", "SliU16[N]/s", "SliU32[N]/i", "SliU64[N]/l", 1118 }, 1119 ltitles: []string{ 1120 "N", 1121 "SliU8[N]", "SliU16[N]", "SliU32[N]", "SliU64[N]", 1122 }, 1123 total: 170, 1124 want: func(i int) any { 1125 type Data struct { 1126 N int32 1127 SliU8 []uint8 1128 SliU16 []uint16 1129 SliU32 []uint32 1130 SliU64 []uint64 1131 } 1132 return Data{ 1133 N: int32(i), 1134 SliU8: []uint8{uint8(i), uint8(i + 1), uint8(i + 2), uint8(i + 3), uint8(i + 4)}[:i], 1135 SliU16: []uint16{uint16(i), uint16(i + 1), uint16(i + 2), uint16(i + 3), uint16(i + 4)}[:i], 1136 SliU32: []uint32{uint32(i), uint32(i + 1), uint32(i + 2), uint32(i + 3), uint32(i + 4)}[:i], 1137 SliU64: []uint64{uint64(i), uint64(i + 1), uint64(i + 2), uint64(i + 3), uint64(i + 4)}[:i], 1138 } 1139 }, 1140 scan: []string{ 1141 "N", 1142 "SliU8", "SliU16", "SliU32", "SliU64", 1143 }, 1144 cxx: `*********************************************************************************** 1145 * Row * Instance * N * SliU8 * SliU16 * SliU32 * SliU64 * 1146 *********************************************************************************** 1147 * 0 * 0 * 0 * * * * * 1148 * 1 * 0 * 1 * 1 * 1 * 1 * 1 * 1149 * 2 * 0 * 2 * 2 * 2 * 2 * 2 * 1150 * 2 * 1 * 2 * 3 * 3 * 3 * 3 * 1151 * 3 * 0 * 3 * 3 * 3 * 3 * 3 * 1152 * 3 * 1 * 3 * 4 * 4 * 4 * 4 * 1153 * 3 * 2 * 3 * 5 * 5 * 5 * 5 * 1154 * 4 * 0 * 4 * 4 * 4 * 4 * 4 * 1155 * 4 * 1 * 4 * 5 * 5 * 5 * 5 * 1156 * 4 * 2 * 4 * 6 * 6 * 6 * 6 * 1157 * 4 * 3 * 4 * 7 * 7 * 7 * 7 * 1158 *********************************************************************************** 1159 `, 1160 }, 1161 { 1162 name: "slices-int", 1163 nevts: 5, 1164 wvars: []WriteVar{ 1165 {Name: "N", Value: new(int32)}, 1166 {Name: "SliI16", Value: new([]int16), Count: "N"}, 1167 {Name: "SliI32", Value: new([]int32), Count: "N"}, 1168 {Name: "SliI64", Value: new([]int64), Count: "N"}, 1169 }, 1170 btitles: []string{ 1171 "N/I", 1172 "SliI16[N]/S", "SliI32[N]/I", "SliI64[N]/L", 1173 }, 1174 ltitles: []string{ 1175 "N", 1176 "SliI16[N]", "SliI32[N]", "SliI64[N]", 1177 }, 1178 total: 160, 1179 want: func(i int) any { 1180 type Data struct { 1181 N int32 1182 SliI16 []int16 1183 SliI32 []int32 1184 SliI64 []int64 1185 } 1186 return Data{ 1187 N: int32(i), 1188 SliI16: []int16{int16(i), int16(i + 1), int16(i + 2), int16(i + 3), int16(i + 4)}[:i], 1189 SliI32: []int32{int32(i), int32(i + 1), int32(i + 2), int32(i + 3), int32(i + 4)}[:i], 1190 SliI64: []int64{int64(i), int64(i + 1), int64(i + 2), int64(i + 3), int64(i + 4)}[:i], 1191 } 1192 }, 1193 scan: []string{ 1194 "N", 1195 "SliI16", "SliI32", "SliI64", 1196 }, 1197 cxx: `*********************************************************************** 1198 * Row * Instance * N * SliI16 * SliI32 * SliI64 * 1199 *********************************************************************** 1200 * 0 * 0 * 0 * * * * 1201 * 1 * 0 * 1 * 1 * 1 * 1 * 1202 * 2 * 0 * 2 * 2 * 2 * 2 * 1203 * 2 * 1 * 2 * 3 * 3 * 3 * 1204 * 3 * 0 * 3 * 3 * 3 * 3 * 1205 * 3 * 1 * 3 * 4 * 4 * 4 * 1206 * 3 * 2 * 3 * 5 * 5 * 5 * 1207 * 4 * 0 * 4 * 4 * 4 * 4 * 1208 * 4 * 1 * 4 * 5 * 5 * 5 * 1209 * 4 * 2 * 4 * 6 * 6 * 6 * 1210 * 4 * 3 * 4 * 7 * 7 * 7 * 1211 *********************************************************************** 1212 `, 1213 }, 1214 { 1215 name: "slices-int8", 1216 skip: true, 1217 nevts: 5, 1218 wvars: []WriteVar{ 1219 {Name: "N", Value: new(int32)}, 1220 {Name: "SliI8", Value: new([]int8), Count: "N"}, 1221 }, 1222 btitles: []string{ 1223 "N/I", "SliI8[N]/B", 1224 }, 1225 ltitles: []string{ 1226 "N", "SliI8[N]", 1227 }, 1228 total: 30, 1229 want: func(i int) any { 1230 type Data struct { 1231 N int32 1232 SliI8 []int8 1233 } 1234 return Data{ 1235 N: int32(i), 1236 SliI8: []int8{int8('a' + i), int8('a' + i + 1), int8('a' + i + 2), int8('a' + i + 3), int8(0)}[:i], 1237 } 1238 }, 1239 scan: []string{ 1240 "N", "SliI8", 1241 }, 1242 cxx: `*********************************************** 1243 * Row * Instance * N * SliI8 * 1244 *********************************************** 1245 * 0 * 0 * 0 * * 1246 * 1 * 0 * 1 * b * 1247 * 2 * 0 * 2 * cd * 1248 * 2 * 1 * 2 * cd * 1249 * 3 * 0 * 3 * def * 1250 * 3 * 1 * 3 * def * 1251 * 3 * 2 * 3 * def * 1252 * 4 * 0 * 4 * efgh * 1253 * 4 * 1 * 4 * efgh * 1254 * 4 * 2 * 4 * efgh * 1255 * 4 * 3 * 4 * efgh * 1256 *********************************************** 1257 `, 1258 }, 1259 { 1260 name: "slices-bool-floats", 1261 nevts: 5, 1262 wvars: []WriteVar{ 1263 {Name: "N", Value: new(int32)}, 1264 {Name: "SliB", Value: new([]bool), Count: "N"}, 1265 {Name: "SliF32", Value: new([]float32), Count: "N"}, 1266 {Name: "SliF64", Value: new([]float64), Count: "N"}, 1267 }, 1268 btitles: []string{ 1269 "N/I", 1270 "SliB[N]/O", 1271 "SliF32[N]/F", "SliF64[N]/D", 1272 }, 1273 ltitles: []string{ 1274 "N", 1275 "SliB[N]", 1276 "SliF32[N]", "SliF64[N]", 1277 }, 1278 total: 150, 1279 want: func(i int) any { 1280 type Data struct { 1281 N int32 1282 SliBool []bool 1283 SliF32 []float32 1284 SliF64 []float64 1285 } 1286 return Data{ 1287 N: int32(i), 1288 SliBool: []bool{bool(i%2 == 0), bool((i+1)%2 == 0), bool((i+2)%2 == 0), bool((i+3)%2 == 0), bool((i+4)%2 == 0)}[:i], 1289 SliF32: []float32{float32(i), float32(i + 1), float32(i + 2), float32(i + 3), float32(i + 4)}[:i], 1290 SliF64: []float64{float64(i), float64(i + 1), float64(i + 2), float64(i + 3), float64(i + 4)}[:i], 1291 } 1292 }, 1293 scan: []string{ 1294 "N", 1295 "SliB", 1296 "SliF32", "SliF64", 1297 }, 1298 cxx: `*********************************************************************** 1299 * Row * Instance * N * SliB * SliF32 * SliF64 * 1300 *********************************************************************** 1301 * 0 * 0 * 0 * * * * 1302 * 1 * 0 * 1 * 0 * 1 * 1 * 1303 * 2 * 0 * 2 * 1 * 2 * 2 * 1304 * 2 * 1 * 2 * 0 * 3 * 3 * 1305 * 3 * 0 * 3 * 0 * 3 * 3 * 1306 * 3 * 1 * 3 * 1 * 4 * 4 * 1307 * 3 * 2 * 3 * 0 * 5 * 5 * 1308 * 4 * 0 * 4 * 1 * 4 * 4 * 1309 * 4 * 1 * 4 * 0 * 5 * 5 * 1310 * 4 * 2 * 4 * 1 * 6 * 6 * 1311 * 4 * 3 * 4 * 0 * 7 * 7 * 1312 *********************************************************************** 1313 `, 1314 }, 1315 { 1316 name: "slices-multi-baskets", 1317 nevts: 10000, 1318 wvars: []WriteVar{ 1319 {Name: "N", Value: new(int32)}, 1320 {Name: "SliI64", Value: new([]int64), Count: "N"}, 1321 }, 1322 btitles: []string{ 1323 "N/I", 1324 "SliI64[N]/L", 1325 }, 1326 ltitles: []string{ 1327 "N", 1328 "SliI64[N]", 1329 }, 1330 total: 400000, 1331 want: func(i int) any { 1332 type Data struct { 1333 N int32 1334 SliI64 []int64 1335 } 1336 n := i % 10 1337 d := Data{ 1338 N: int32(n), 1339 SliI64: make([]int64, n), 1340 } 1341 for j := range d.SliI64 { 1342 d.SliI64[j] = int64(j + 1) 1343 } 1344 return d 1345 }, 1346 }, 1347 { 1348 name: "compr-no-compression", 1349 wopts: []WriteOption{WithoutCompression()}, 1350 nevts: 500, 1351 wvars: []WriteVar{ 1352 {Name: "i32", Value: new(int32)}, 1353 {Name: "f64", Value: new(float64)}, 1354 }, 1355 btitles: []string{"i32/I", "f64/D"}, 1356 ltitles: []string{"i32", "f64"}, 1357 total: 500 * (4 + 8), 1358 want: func(i int) any { 1359 return struct { 1360 I32 int32 1361 F64 float64 1362 }{ 1363 I32: int32(i), 1364 F64: float64(i), 1365 } 1366 }, 1367 }, 1368 { 1369 name: "compr-lz4-default", 1370 wopts: []WriteOption{WithLZ4(flate.DefaultCompression)}, 1371 nevts: 500, 1372 wvars: []WriteVar{ 1373 {Name: "i32", Value: new(int32)}, 1374 {Name: "f64", Value: new(float64)}, 1375 }, 1376 btitles: []string{"i32/I", "f64/D"}, 1377 ltitles: []string{"i32", "f64"}, 1378 total: 500 * (4 + 8), 1379 want: func(i int) any { 1380 return struct { 1381 I32 int32 1382 F64 float64 1383 }{ 1384 I32: int32(i), 1385 F64: float64(i), 1386 } 1387 }, 1388 }, 1389 { 1390 name: "compr-lzma-default", 1391 wopts: []WriteOption{WithLZMA(flate.DefaultCompression)}, 1392 nevts: 500, 1393 wvars: []WriteVar{ 1394 {Name: "i32", Value: new(int32)}, 1395 {Name: "f64", Value: new(float64)}, 1396 }, 1397 btitles: []string{"i32/I", "f64/D"}, 1398 ltitles: []string{"i32", "f64"}, 1399 total: 500 * (4 + 8), 1400 want: func(i int) any { 1401 return struct { 1402 I32 int32 1403 F64 float64 1404 }{ 1405 I32: int32(i), 1406 F64: float64(i), 1407 } 1408 }, 1409 }, 1410 { 1411 name: "compr-zlib-2", 1412 wopts: []WriteOption{WithZlib(2)}, 1413 nevts: 500, 1414 wvars: []WriteVar{ 1415 {Name: "i32", Value: new(int32)}, 1416 {Name: "f64", Value: new(float64)}, 1417 }, 1418 btitles: []string{"i32/I", "f64/D"}, 1419 ltitles: []string{"i32", "f64"}, 1420 total: 500 * (4 + 8), 1421 want: func(i int) any { 1422 return struct { 1423 I32 int32 1424 F64 float64 1425 }{ 1426 I32: int32(i), 1427 F64: float64(i), 1428 } 1429 }, 1430 }, 1431 { 1432 name: "compr-zlib-default", 1433 wopts: []WriteOption{WithZlib(flate.DefaultCompression)}, 1434 nevts: 500, 1435 wvars: []WriteVar{ 1436 {Name: "i32", Value: new(int32)}, 1437 {Name: "f64", Value: new(float64)}, 1438 }, 1439 btitles: []string{"i32/I", "f64/D"}, 1440 ltitles: []string{"i32", "f64"}, 1441 total: 500 * (4 + 8), 1442 want: func(i int) any { 1443 return struct { 1444 I32 int32 1445 F64 float64 1446 }{ 1447 I32: int32(i), 1448 F64: float64(i), 1449 } 1450 }, 1451 }, 1452 } { 1453 t.Run(tc.name, func(t *testing.T) { 1454 fname := filepath.Join(tmp, tc.name+".root") 1455 1456 if tc.skip { 1457 t.Skipf("skipping %s...", tc.name) 1458 } 1459 1460 func() { 1461 f, err := riofs.Create(fname) 1462 if err != nil { 1463 t.Fatalf("could not create write ROOT file %q: %v", fname, err) 1464 } 1465 defer f.Close() 1466 1467 tw, err := NewWriter(f, treeName, tc.wvars, tc.wopts...) 1468 if err != nil { 1469 t.Fatalf("could not create tree writer: %v", err) 1470 } 1471 defer tw.Close() 1472 1473 for i, b := range tw.Branches() { 1474 if got, want := b.Name(), tc.wvars[i].Name; got != want { 1475 t.Fatalf("branch[%d]: got=%q, want=%q", i, got, want) 1476 } 1477 if got, want := b.Title(), tc.btitles[i]; got != want { 1478 t.Fatalf("branch[%d]: got=%q, want=%q", i, got, want) 1479 } 1480 } 1481 1482 for i, leaf := range tw.Leaves() { 1483 if got, want := leaf.Name(), tc.wvars[i].Name; got != want { 1484 t.Fatalf("leaf[%d]: got=%q, want=%q", i, got, want) 1485 } 1486 if got, want := leaf.Title(), tc.ltitles[i]; got != want { 1487 t.Fatalf("leaf[%d]: got=%q, want=%q", i, got, want) 1488 } 1489 } 1490 1491 total := 0 1492 for i := range int(tc.nevts) { 1493 want := tc.want(i) 1494 for j, wvar := range tc.wvars { 1495 v := reflect.ValueOf(wvar.Value).Elem() 1496 want := reflect.ValueOf(want).Field(j) 1497 v.Set(want) 1498 } 1499 n, err := tw.Write() 1500 if err != nil { 1501 t.Fatalf("could not write event %d: %v", i, err) 1502 } 1503 total += n 1504 } 1505 1506 if got, want := tw.Entries(), tc.nevts; got != want { 1507 t.Fatalf("invalid number of entries: got=%d, want=%d", got, want) 1508 } 1509 if got, want := total, tc.total; got != want { 1510 t.Errorf("invalid number of bytes written: got=%d, want=%d", got, want) 1511 } 1512 1513 err = tw.Close() 1514 if err != nil { 1515 t.Fatalf("could not close tree writer: %v", err) 1516 } 1517 1518 err = f.Close() 1519 if err != nil { 1520 t.Fatalf("could not close write ROOT file %q: %v", fname, err) 1521 } 1522 }() 1523 1524 func() { 1525 f, err := riofs.Open(fname) 1526 if err != nil { 1527 t.Fatalf("could not opend read ROOT file %q: %+v", fname, err) 1528 } 1529 defer f.Close() 1530 1531 obj, err := f.Get(treeName) 1532 if err != nil { 1533 t.Fatalf("could not get ROOT tree %q: %+v", treeName, err) 1534 } 1535 tree := obj.(Tree) 1536 1537 if got, want := tree.Entries(), tc.nevts; got != want { 1538 t.Fatalf("invalid number of events: got=%v, want=%v", got, want) 1539 } 1540 1541 for i, b := range tree.Branches() { 1542 if got, want := b.Name(), tc.wvars[i].Name; got != want { 1543 t.Fatalf("branch[%d]: got=%q, want=%q", i, got, want) 1544 } 1545 if got, want := b.Title(), tc.btitles[i]; got != want { 1546 t.Fatalf("branch[%d]: got=%q, want=%q", i, got, want) 1547 } 1548 } 1549 1550 for i, leaf := range tree.Leaves() { 1551 if got, want := leaf.Name(), tc.wvars[i].Name; got != want { 1552 t.Fatalf("leaf[%d]: got=%q, want=%q", i, got, want) 1553 } 1554 if got, want := leaf.Title(), tc.ltitles[i]; got != want { 1555 t.Fatalf("leaf[%d]: got=%q, want=%q", i, got, want) 1556 } 1557 } 1558 1559 if len(tc.wvars) == 0 { 1560 return 1561 } 1562 1563 rvars := NewReadVars(tree) 1564 if len(rvars) != len(tc.wvars) { 1565 t.Fatalf("invalid number of read-vars: got=%d, want=%d", len(rvars), len(tc.wvars)) 1566 } 1567 1568 for i, rvar := range rvars { 1569 wvar := tc.wvars[i] 1570 if got, want := rvar.Name, wvar.Name; got != want { 1571 t.Fatalf("invalid name for rvar[%d]: got=%q, want=%q", i, got, want) 1572 } 1573 wtyp := reflect.TypeOf(wvar.Value) 1574 rtyp := reflect.TypeOf(rvar.Value) 1575 if got, want := rtyp, wtyp; got != want { 1576 t.Fatalf("invalid type for rvar[%d]: got=%v, want=%v", i, got, want) 1577 } 1578 } 1579 1580 r, err := NewReader(tree, rvars) 1581 if err != nil { 1582 t.Fatalf("could not create reader: %+v", err) 1583 } 1584 defer r.Close() 1585 1586 nn := 0 1587 err = r.Read(func(ctx RCtx) error { 1588 i := int(ctx.Entry) 1589 want := tc.want(i) 1590 for i, rvar := range rvars { 1591 var ( 1592 want = reflect.ValueOf(want).Field(i).Interface() 1593 got = reflect.ValueOf(rvar.Value).Elem().Interface() 1594 ) 1595 if !reflect.DeepEqual(got, want) { 1596 return fmt.Errorf( 1597 "entry[%d]: invalid scan-value[%s]: got=%v, want=%v", 1598 ctx.Entry, tc.wvars[i].Name, got, want, 1599 ) 1600 } 1601 } 1602 nn++ 1603 return nil 1604 }) 1605 if err != nil { 1606 t.Fatalf("could not read tree: %+v", err) 1607 } 1608 1609 if got, want := nn, int(tc.nevts); got != want { 1610 t.Fatalf("invalid number of events: got=%d, want=%d", got, want) 1611 } 1612 }() 1613 if rtests.HasROOT && tc.cxx != "" { 1614 code := `#include <iostream> 1615 #include "TFile.h" 1616 #include "TTree.h" 1617 #include "TTreePlayer.h" 1618 1619 void scan(const char* fname, const char* tree, const char *list, const char *oname) { 1620 auto f = TFile::Open(fname); 1621 auto t = (TTree*)f->Get(tree); 1622 if (!t) { 1623 std::cerr << "could not fetch TTree [" << tree << "] from file [" << fname << "]\n"; 1624 exit(1); 1625 } 1626 auto player = dynamic_cast<TTreePlayer*>(t->GetPlayer()); 1627 player->SetScanRedirect(kTRUE); 1628 player->SetScanFileName(oname); 1629 t->SetScanField(0); 1630 t->Scan(list); 1631 } 1632 ` 1633 1634 scan := []string{"*"} 1635 if len(tc.scan) != 0 { 1636 scan = tc.scan 1637 } 1638 1639 ofile := filepath.Join(tmp, tc.name+".txt") 1640 out, err := rtests.RunCxxROOT("scan", []byte(code), fname, treeName, strings.Join(scan, ":"), ofile) 1641 if err != nil { 1642 t.Fatalf("could not run C++ ROOT: %+v\noutput:\n%s", err, out) 1643 } 1644 1645 got, err := os.ReadFile(ofile) 1646 if err != nil { 1647 t.Fatalf("could not read C++ ROOT scan file %q: %+v\noutput:\n%s", ofile, err, out) 1648 } 1649 1650 if got, want := string(got), tc.cxx; got != want { 1651 t.Fatalf("invalid ROOT scan:\ngot:\n%v\nwant:\n%v\noutput:\n%s\n%s", got, want, out, diff.Format(got, want)) 1652 } 1653 } 1654 }) 1655 } 1656 } 1657 1658 func TestNestedTreeRW(t *testing.T) { 1659 tmp, err := os.MkdirTemp("", "groot-rtree-") 1660 if err != nil { 1661 t.Fatalf("could not create dir: %v", err) 1662 } 1663 defer os.RemoveAll(tmp) 1664 1665 const ( 1666 treeName = "mytree" 1667 ) 1668 1669 sictx := rdict.StreamerInfos 1670 1671 for _, tc := range []struct { 1672 name string 1673 skip bool 1674 wopts []WriteOption 1675 nevts int64 1676 wvars []WriteVar 1677 rvars []ReadVar 1678 btitles []string 1679 ltitles []string 1680 total int 1681 want func(i int) any 1682 macro string // ROOT macro to execute to read back ROOT file 1683 cxx string // expected ROOT-TTree::Scan 1684 sinfos []rbytes.StreamerInfo 1685 }{ 1686 { 1687 name: "struct-with-struct", 1688 wopts: []WriteOption{ 1689 WithZlib(flate.DefaultCompression), 1690 WithSplitLevel(0), 1691 }, 1692 nevts: 10, 1693 wvars: []WriteVar{ 1694 {Name: "evt", Value: new(TNestedStruct1)}, 1695 }, 1696 rvars: []ReadVar{ 1697 {Name: "evt", Value: new(TNestedStruct1)}, 1698 }, 1699 btitles: []string{"evt"}, 1700 ltitles: []string{"evt"}, 1701 total: 460, 1702 want: func(i int) any { 1703 var evt struct { 1704 Data TNestedStruct1 1705 } 1706 evt.Data.RunNbr = 10 + int64(i) 1707 evt.Data.EvtNbr = int64(i) 1708 evt.Data.P3.Px = float64(i + 10) 1709 evt.Data.P3.Py = float64(i + 20) 1710 evt.Data.P3.Pz = float64(i + 30) 1711 return evt 1712 }, 1713 macro: ` 1714 #include "TFile.h" 1715 #include "TTree.h" 1716 1717 #include <vector> 1718 #include <fstream> 1719 1720 struct TNestedStruct1P3 { 1721 double px,py,pz; 1722 }; 1723 1724 struct TNestedStruct1 { 1725 Long64_t runnbr; 1726 Long64_t evtnbr; 1727 TNestedStruct1P3 p3; 1728 }; 1729 1730 1731 void scan(const char *fname, const char *tname, const char *oname) { 1732 auto o = std::fstream(oname, std::ofstream::out); 1733 auto f = TFile::Open(fname, "READ"); 1734 auto t = (TTree*)f->Get(tname); 1735 t->Print(); 1736 1737 TNestedStruct1 *evt = nullptr; 1738 t->SetBranchAddress("evt", &evt); 1739 1740 auto n = t->GetEntries(); 1741 o << "entries: " << n << "\n"; 1742 for (int i = 0; i < n; i++) { 1743 t->GetEntry(i); 1744 o << "evt[" << i << "]:" 1745 << " run=" << evt->runnbr << "," 1746 << " evt=" << evt->evtnbr << "," 1747 << " p3(" << evt->p3.px << ", " << evt->p3.py << ", " << evt->p3.pz << ")" 1748 << "\n"; 1749 } 1750 o.flush(); 1751 } 1752 `, 1753 cxx: `entries: 10 1754 evt[0]: run=10, evt=0, p3(10, 20, 30) 1755 evt[1]: run=11, evt=1, p3(11, 21, 31) 1756 evt[2]: run=12, evt=2, p3(12, 22, 32) 1757 evt[3]: run=13, evt=3, p3(13, 23, 33) 1758 evt[4]: run=14, evt=4, p3(14, 24, 34) 1759 evt[5]: run=15, evt=5, p3(15, 25, 35) 1760 evt[6]: run=16, evt=6, p3(16, 26, 36) 1761 evt[7]: run=17, evt=7, p3(17, 27, 37) 1762 evt[8]: run=18, evt=8, p3(18, 28, 38) 1763 evt[9]: run=19, evt=9, p3(19, 29, 39) 1764 `, 1765 sinfos: []rbytes.StreamerInfo{ 1766 rdict.StreamerOf(sictx, reflect.TypeOf(TNestedStruct1P3{})), 1767 rdict.StreamerOf(sictx, reflect.TypeOf(TNestedStruct1{})), 1768 }, 1769 }, 1770 { 1771 name: "large-struct-with-struct", 1772 wopts: []WriteOption{ 1773 WithZlib(flate.DefaultCompression), 1774 WithSplitLevel(0), 1775 }, 1776 nevts: 1000, 1777 wvars: []WriteVar{ 1778 {Name: "evt", Value: new(TNestedStruct1)}, 1779 }, 1780 rvars: []ReadVar{ 1781 {Name: "evt", Value: new(TNestedStruct1)}, 1782 }, 1783 btitles: []string{"evt"}, 1784 ltitles: []string{"evt"}, 1785 total: 46 * 1000, 1786 want: func(i int) any { 1787 var evt struct { 1788 Data TNestedStruct1 1789 } 1790 evt.Data.RunNbr = 10 + int64(i) 1791 evt.Data.EvtNbr = int64(i) 1792 evt.Data.P3.Px = float64(i + 10) 1793 evt.Data.P3.Py = float64(i + 20) 1794 evt.Data.P3.Pz = float64(i + 30) 1795 return evt 1796 }, 1797 sinfos: []rbytes.StreamerInfo{ 1798 rdict.StreamerOf(sictx, reflect.TypeOf(TNestedStruct1P3{})), 1799 rdict.StreamerOf(sictx, reflect.TypeOf(TNestedStruct1{})), 1800 }, 1801 }, 1802 { 1803 name: "struct-with-struct+slice", 1804 wopts: []WriteOption{ 1805 WithZlib(flate.DefaultCompression), 1806 WithSplitLevel(0), 1807 }, 1808 nevts: 10, 1809 wvars: []WriteVar{ 1810 {Name: "evt", Value: new(TNestedStruct2)}, 1811 }, 1812 rvars: []ReadVar{ 1813 {Name: "evt", Value: new(TNestedStruct2)}, 1814 }, 1815 btitles: []string{"evt"}, 1816 ltitles: []string{"evt"}, 1817 total: 740, 1818 want: func(i int) any { 1819 var evt struct { 1820 Data TNestedStruct2 1821 } 1822 evt.Data.RunNbr = 10 + int64(i) 1823 evt.Data.EvtNbr = int64(i) 1824 evt.Data.P3.Px = float64(i + 10) 1825 evt.Data.P3.Py = float64(i + 20) 1826 evt.Data.P3.Pz = float64(i + 30) 1827 switch i { 1828 case 0: 1829 evt.Data.F32s = nil 1830 default: 1831 evt.Data.F32s = make([]float32, 0, i) 1832 } 1833 for j := range i { 1834 evt.Data.F32s = append(evt.Data.F32s, float32((i+1)*10+j)) 1835 } 1836 1837 return evt 1838 }, 1839 macro: ` 1840 #include "TFile.h" 1841 #include "TTree.h" 1842 1843 #include <vector> 1844 #include <fstream> 1845 1846 struct TNestedStruct1P3 { 1847 double px,py,pz; 1848 }; 1849 1850 struct TNestedStruct2 { 1851 Long64_t runnbr; 1852 Long64_t evtnbr; 1853 TNestedStruct1P3 p3; 1854 std::vector<float> f32s; 1855 }; 1856 1857 template<class T> 1858 std::string printVec(const std::vector<T>& v) { 1859 std::stringstream o; 1860 int i = 0; 1861 o << "["; 1862 for (auto e : v) { 1863 if (i > 0) { 1864 o << ", "; 1865 } 1866 o << e; 1867 i++; 1868 } 1869 o << "]"; 1870 return o.str(); 1871 } 1872 1873 void scan(const char *fname, const char *tname, const char *oname) { 1874 auto o = std::fstream(oname, std::ofstream::out); 1875 auto f = TFile::Open(fname, "READ"); 1876 auto t = (TTree*)f->Get(tname); 1877 t->Print(); 1878 1879 TNestedStruct2 *evt = nullptr; 1880 t->SetBranchAddress("evt", &evt); 1881 1882 auto n = t->GetEntries(); 1883 o << "entries: " << n << "\n"; 1884 for (int i = 0; i < n; i++) { 1885 t->GetEntry(i); 1886 o << "evt[" << i << "]:" 1887 << " run=" << evt->runnbr << "," 1888 << " evt=" << evt->evtnbr << "," 1889 << " p3(" << evt->p3.px << ", " << evt->p3.py << ", " << evt->p3.pz << ")" 1890 << " f32s(" << printVec(evt->f32s) << ")" 1891 << "\n"; 1892 } 1893 o.flush(); 1894 } 1895 `, 1896 cxx: `entries: 10 1897 evt[0]: run=10, evt=0, p3(10, 20, 30) f32s([]) 1898 evt[1]: run=11, evt=1, p3(11, 21, 31) f32s([20]) 1899 evt[2]: run=12, evt=2, p3(12, 22, 32) f32s([30, 31]) 1900 evt[3]: run=13, evt=3, p3(13, 23, 33) f32s([40, 41, 42]) 1901 evt[4]: run=14, evt=4, p3(14, 24, 34) f32s([50, 51, 52, 53]) 1902 evt[5]: run=15, evt=5, p3(15, 25, 35) f32s([60, 61, 62, 63, 64]) 1903 evt[6]: run=16, evt=6, p3(16, 26, 36) f32s([70, 71, 72, 73, 74, 75]) 1904 evt[7]: run=17, evt=7, p3(17, 27, 37) f32s([80, 81, 82, 83, 84, 85, 86]) 1905 evt[8]: run=18, evt=8, p3(18, 28, 38) f32s([90, 91, 92, 93, 94, 95, 96, 97]) 1906 evt[9]: run=19, evt=9, p3(19, 29, 39) f32s([100, 101, 102, 103, 104, 105, 106, 107, 108]) 1907 `, 1908 sinfos: []rbytes.StreamerInfo{ 1909 rdict.StreamerOf(sictx, reflect.TypeOf(TNestedStruct1P3{})), 1910 rdict.StreamerOf(sictx, reflect.TypeOf(TNestedStruct2{})), 1911 }, 1912 }, 1913 { 1914 name: "struct+slice", 1915 wopts: []WriteOption{ 1916 WithZlib(flate.DefaultCompression), 1917 WithSplitLevel(0), 1918 }, 1919 nevts: 10, 1920 wvars: []WriteVar{ 1921 {Name: "runnbr", Value: new(int64)}, 1922 {Name: "evtnbr", Value: new(int64)}, 1923 {Name: "p3", Value: new(TNestedStruct1P3)}, 1924 {Name: "f32s", Value: new([]float32)}, 1925 }, 1926 rvars: []ReadVar{ 1927 {Name: "runnbr", Value: new(int64)}, 1928 {Name: "evtnbr", Value: new(int64)}, 1929 {Name: "p3", Value: new(TNestedStruct1P3)}, 1930 {Name: "f32s", Value: new([]float32)}, 1931 }, 1932 btitles: []string{"runnbr/L", "evtnbr/L", "p3", "f32s"}, 1933 ltitles: []string{"runnbr", "evtnbr", "p3", "f32s"}, 1934 total: 680, 1935 want: func(i int) any { 1936 var evt struct { 1937 Data TNestedStruct3 1938 } 1939 evt.Data.RunNbr = 10 + int64(i) 1940 evt.Data.EvtNbr = int64(i) 1941 evt.Data.P3.Px = float64(i + 10) 1942 evt.Data.P3.Py = float64(i + 20) 1943 evt.Data.P3.Pz = float64(i + 30) 1944 switch i { 1945 case 0: 1946 evt.Data.F32s = nil 1947 default: 1948 evt.Data.F32s = make([]float32, 0, i) 1949 } 1950 for j := range i { 1951 evt.Data.F32s = append(evt.Data.F32s, float32((i+1)*10+j)) 1952 } 1953 1954 return evt.Data 1955 }, 1956 macro: ` 1957 #include "TFile.h" 1958 #include "TTree.h" 1959 1960 #include <vector> 1961 #include <fstream> 1962 1963 struct TNestedStruct1P3 { 1964 double px,py,pz; 1965 }; 1966 1967 struct TNestedStruct3 { 1968 Long64_t runnbr; 1969 Long64_t evtnbr; 1970 TNestedStruct1P3 p3; 1971 std::vector<float> f32s; 1972 }; 1973 1974 template<class T> 1975 std::string printVec(const std::vector<T>& v) { 1976 std::stringstream o; 1977 int i = 0; 1978 o << "["; 1979 for (auto e : v) { 1980 if (i > 0) { 1981 o << ", "; 1982 } 1983 o << e; 1984 i++; 1985 } 1986 o << "]"; 1987 return o.str(); 1988 } 1989 1990 void scan(const char *fname, const char *tname, const char *oname) { 1991 auto o = std::fstream(oname, std::ofstream::out); 1992 auto f = TFile::Open(fname, "READ"); 1993 auto t = (TTree*)f->Get(tname); 1994 t->Print(); 1995 1996 Long64_t runnbr; 1997 t->SetBranchAddress("runnbr", &runnbr); 1998 1999 Long64_t evtnbr; 2000 t->SetBranchAddress("evtnbr", &evtnbr); 2001 2002 TNestedStruct1P3 *p3 = nullptr; 2003 t->SetBranchAddress("p3", &p3); 2004 2005 std::vector<float> *f32s = nullptr; 2006 t->SetBranchAddress("f32s", &f32s); 2007 2008 auto n = t->GetEntries(); 2009 o << "entries: " << n << "\n"; 2010 for (int i = 0; i < n; i++) { 2011 t->GetEntry(i); 2012 o << "evt[" << i << "]:" 2013 << " run=" << runnbr << "," 2014 << " evt=" << evtnbr << "," 2015 << " p3(" << p3->px << ", " << p3->py << ", " << p3->pz << ")" 2016 << " f32s(" << printVec(*f32s) << ")" 2017 << "\n"; 2018 } 2019 o.flush(); 2020 } 2021 `, 2022 cxx: `entries: 10 2023 evt[0]: run=10, evt=0, p3(10, 20, 30) f32s([]) 2024 evt[1]: run=11, evt=1, p3(11, 21, 31) f32s([20]) 2025 evt[2]: run=12, evt=2, p3(12, 22, 32) f32s([30, 31]) 2026 evt[3]: run=13, evt=3, p3(13, 23, 33) f32s([40, 41, 42]) 2027 evt[4]: run=14, evt=4, p3(14, 24, 34) f32s([50, 51, 52, 53]) 2028 evt[5]: run=15, evt=5, p3(15, 25, 35) f32s([60, 61, 62, 63, 64]) 2029 evt[6]: run=16, evt=6, p3(16, 26, 36) f32s([70, 71, 72, 73, 74, 75]) 2030 evt[7]: run=17, evt=7, p3(17, 27, 37) f32s([80, 81, 82, 83, 84, 85, 86]) 2031 evt[8]: run=18, evt=8, p3(18, 28, 38) f32s([90, 91, 92, 93, 94, 95, 96, 97]) 2032 evt[9]: run=19, evt=9, p3(19, 29, 39) f32s([100, 101, 102, 103, 104, 105, 106, 107, 108]) 2033 `, 2034 sinfos: []rbytes.StreamerInfo{ 2035 rdict.StreamerOf(sictx, reflect.TypeOf(TNestedStruct1P3{})), 2036 rdict.StreamerOf(sictx, reflect.TypeOf(TNestedStruct3{})), 2037 }, 2038 }, 2039 { 2040 name: "vector+slice", 2041 wopts: []WriteOption{ 2042 WithZlib(flate.DefaultCompression), 2043 WithSplitLevel(0), 2044 }, 2045 nevts: 10, 2046 wvars: []WriteVar{ 2047 {Name: "N", Value: new(int32)}, 2048 {Name: "vec", Value: new([]float32)}, 2049 // {Name: "sli", Value: new([]float32), Count: "N"}, 2050 }, 2051 rvars: []ReadVar{ 2052 {Name: "N", Value: new(int32)}, 2053 {Name: "vec", Value: new([]float32)}, 2054 // {Name: "sli", Value: new([]float32)}, 2055 }, 2056 btitles: []string{"N/I", "vec"}, // "sli[N]/F"}, 2057 ltitles: []string{"N", "vec"}, // "sli[N]"}, 2058 total: 360, 2059 want: func(i int) any { 2060 var evt struct { 2061 N int32 2062 Vec []float32 2063 // Sli []float32 `groot:"sli[N]"` 2064 } 2065 2066 evt.N = int32(i) + 1 2067 evt.Vec = make([]float32, evt.N) 2068 // evt.Sli = make([]float32, evt.N) 2069 for j := range int(evt.N) { 2070 evt.Vec[j] = -float32((i+1)*10 + j) 2071 // evt.Sli[j] = +float32((i+1)*10 + j) 2072 } 2073 2074 return evt 2075 }, 2076 macro: ` 2077 #include "TFile.h" 2078 #include "TTree.h" 2079 2080 #include <vector> 2081 #include <fstream> 2082 2083 template<class T> 2084 std::string printVec(const std::vector<T>& v) { 2085 std::stringstream o; 2086 int i = 0; 2087 o << "["; 2088 for (auto e : v) { 2089 if (i > 0) { 2090 o << " "; 2091 } 2092 o << e; 2093 i++; 2094 } 2095 o << "]"; 2096 return o.str(); 2097 } 2098 2099 template<class T> 2100 std::string printSli(int32_t n, const T *v) { 2101 std::stringstream o; 2102 o << "["; 2103 for (int i = 0; i < n; i++) { 2104 auto e = v[i]; 2105 if (i > 0) { 2106 o << " "; 2107 } 2108 o << e; 2109 } 2110 o << "]"; 2111 return o.str(); 2112 } 2113 2114 void scan(const char *fname, const char *tname, const char *oname) { 2115 auto o = std::fstream(oname, std::ofstream::out); 2116 auto f = TFile::Open(fname, "READ"); 2117 auto t = (TTree*)f->Get(tname); 2118 t->Print(); 2119 2120 int32_t n; 2121 t->SetBranchAddress("N", &n); 2122 2123 std::vector<float> *vec = nullptr; 2124 t->SetBranchAddress("vec", &vec); 2125 2126 // float *sli = nullptr; 2127 // t->SetBranchAddress("sli", &sli); 2128 2129 auto nevts = t->GetEntries(); 2130 o << "entries: " << nevts << "\n"; 2131 for (int i = 0; i < nevts; i++) { 2132 t->GetEntry(i); 2133 o << "evt[" << i << "]:" 2134 << " " << n 2135 << " " << printVec(*vec) 2136 // << " " << printSli(n, sli) 2137 << "\n"; 2138 } 2139 o.flush(); 2140 } 2141 `, 2142 cxx: `entries: 10 2143 evt[0]: 1 [-10] 2144 evt[1]: 2 [-20 -21] 2145 evt[2]: 3 [-30 -31 -32] 2146 evt[3]: 4 [-40 -41 -42 -43] 2147 evt[4]: 5 [-50 -51 -52 -53 -54] 2148 evt[5]: 6 [-60 -61 -62 -63 -64 -65] 2149 evt[6]: 7 [-70 -71 -72 -73 -74 -75 -76] 2150 evt[7]: 8 [-80 -81 -82 -83 -84 -85 -86 -87] 2151 evt[8]: 9 [-90 -91 -92 -93 -94 -95 -96 -97 -98] 2152 evt[9]: 10 [-100 -101 -102 -103 -104 -105 -106 -107 -108 -109] 2153 `, 2154 sinfos: []rbytes.StreamerInfo{ 2155 rdict.StreamerOf(sictx, reflect.TypeOf([]float32{})), 2156 }, 2157 }, 2158 { 2159 name: "event-nosplit", 2160 wopts: []WriteOption{ 2161 WithZlib(flate.DefaultCompression), 2162 WithSplitLevel(0), 2163 }, 2164 nevts: 10, 2165 wvars: []WriteVar{ 2166 {Name: "evt", Value: new(TNestedEvent1)}, 2167 }, 2168 rvars: []ReadVar{ 2169 {Name: "evt", Value: new(TNestedEvent1)}, 2170 }, 2171 btitles: []string{"evt"}, 2172 ltitles: []string{"evt"}, 2173 total: 25520, 2174 want: func(i int) any { 2175 var evt struct { 2176 Event TNestedEvent1 2177 } 2178 2179 evt.Event = TNestedEvent1{}.want(int64(i)) 2180 2181 return evt 2182 }, 2183 macro: ` 2184 #include "TFile.h" 2185 #include "TTree.h" 2186 #include "TString.h" 2187 #include "TObjString.h" 2188 2189 #include <vector> 2190 #include <fstream> 2191 2192 const int ARRAYSZ = 10; 2193 const int MAXSLICE = 20; 2194 const int MAXSTR = 32; 2195 2196 #define OFFSET 0 2197 2198 struct TNestedP2 { 2199 double px; 2200 float py; 2201 }; 2202 2203 2204 template<class T> 2205 std::string printV(T v) { 2206 std::stringstream o; 2207 o << v; 2208 return o.str(); 2209 } 2210 2211 template<> 2212 std::string printV(TNestedP2 v) { 2213 std::stringstream o; 2214 o << "{" << v.px << " " << v.py << "}"; 2215 return o.str(); 2216 } 2217 2218 template<> 2219 std::string printV(bool v) { 2220 if (v) { 2221 return "true"; 2222 } 2223 return "false"; 2224 } 2225 2226 template<> 2227 std::string printV(int8_t v) { 2228 std::stringstream o; 2229 o << int(v); 2230 return o.str(); 2231 } 2232 2233 template<> 2234 std::string printV(uint8_t v) { 2235 std::stringstream o; 2236 o << int(v); 2237 return o.str(); 2238 } 2239 2240 template<> 2241 std::string printV(TString v) { 2242 std::stringstream o; 2243 o << v.Data(); 2244 return o.str(); 2245 } 2246 2247 template<> 2248 std::string printV(TObjString v) { 2249 std::stringstream o; 2250 o << v.GetString().Data(); 2251 return o.str(); 2252 } 2253 2254 template<> 2255 std::string printV(std::string v) { 2256 return v; 2257 } 2258 2259 template<class T> 2260 std::string printArr(const T *v) { 2261 std::stringstream o; 2262 o << "["; 2263 for (int i = 0; i < ARRAYSZ; i++) { 2264 auto e = v[i]; 2265 if (i > 0) { 2266 o << " "; 2267 } 2268 o << printV(e); 2269 } 2270 o << "]"; 2271 return o.str(); 2272 } 2273 2274 //template<> 2275 std::string printArrCStr(char *v[ARRAYSZ]) { 2276 std::stringstream o; 2277 o << "["; 2278 for (int i = 0; i < ARRAYSZ; i++) { 2279 auto e = v[i]; 2280 if (i > 0) { 2281 o << " "; 2282 } 2283 o << e; 2284 } 2285 o << "]"; 2286 return o.str(); 2287 } 2288 2289 template<class T> 2290 std::string printSli(int32_t n, const T *v) { 2291 std::stringstream o; 2292 o << "["; 2293 for (int i = 0; i < n; i++) { 2294 auto e = v[i]; 2295 if (i > 0) { 2296 o << " "; 2297 } 2298 o << printV(e); 2299 } 2300 o << "]"; 2301 return o.str(); 2302 } 2303 2304 std::string printSliStr(int32_t n, char *v[ARRAYSZ]) { 2305 std::stringstream o; 2306 o << "["; 2307 for (int i = 0; i < n; i++) { 2308 auto e = v[i]; 2309 if (i > 0) { 2310 o << " "; 2311 } 2312 o << e; 2313 } 2314 o << "]"; 2315 return o.str(); 2316 } 2317 2318 template<class T> 2319 std::string printVec(const std::vector<T>& v) { 2320 std::stringstream o; 2321 int i = 0; 2322 o << "["; 2323 for (auto e : v) { 2324 if (i > 0) { 2325 o << " "; 2326 } 2327 o << printV(e); 2328 i++; 2329 } 2330 o << "]"; 2331 return o.str(); 2332 } 2333 2334 template<class T> 2335 std::string printVecVec(const std::vector<std::vector<T> >& v) { 2336 std::stringstream o; 2337 int i = 0; 2338 o << "["; 2339 for (auto e : v) { 2340 if (i > 0) { 2341 o << " "; 2342 } 2343 o << printVec(e); 2344 i++; 2345 } 2346 o << "]"; 2347 return o.str(); 2348 } 2349 2350 struct TNestedEvent1 { 2351 bool Bool; 2352 //char Str[MAXSTR]; 2353 //char *Str; 2354 std::string Str; 2355 int8_t I8; 2356 int16_t I16; 2357 int32_t I32; 2358 int64_t I64; 2359 uint8_t U8; 2360 uint16_t U16; 2361 uint32_t U32; 2362 uint64_t U64; 2363 float F32; 2364 double F64; 2365 2366 Float16_t D16; 2367 Double32_t D32; 2368 2369 TNestedP2 P2; 2370 TObjString Obj; 2371 2372 bool ArrBs[ARRAYSZ]; 2373 // TString ArrStr[ARRAYSZ]; 2374 int8_t ArrI8[ARRAYSZ]; 2375 int16_t ArrI16[ARRAYSZ]; 2376 int32_t ArrI32[ARRAYSZ]; 2377 int64_t ArrI64[ARRAYSZ]; 2378 uint8_t ArrU8[ARRAYSZ]; 2379 uint16_t ArrU16[ARRAYSZ]; 2380 uint32_t ArrU32[ARRAYSZ]; 2381 uint64_t ArrU64[ARRAYSZ]; 2382 float ArrF32[ARRAYSZ]; 2383 double ArrF64[ARRAYSZ]; 2384 2385 Float16_t ArrD16[ARRAYSZ]; 2386 Double32_t ArrD32[ARRAYSZ]; 2387 2388 TNestedP2 ArrP2[ARRAYSZ]; 2389 TObjString ArrObj[ARRAYSZ]; 2390 2391 int32_t N; 2392 bool *SliBs; //[N] 2393 // char* *SliStr; //[N] 2394 int8_t *SliI8; //[N] 2395 int16_t *SliI16; //[N] 2396 int32_t *SliI32; //[N] 2397 int64_t *SliI64; //[N] 2398 uint8_t *SliU8; //[N] 2399 uint16_t *SliU16; //[N] 2400 uint32_t *SliU32; //[N] 2401 uint64_t *SliU64; //[N] 2402 float *SliF32; //[N] 2403 double *SliF64; //[N] 2404 2405 Float16_t *SliD16; //[N] 2406 Double32_t *SliD32; //[N] 2407 // TNestedP2 *SliP2; //[N] 2408 // TObjString *SliObj; //[N] 2409 2410 std::vector<bool> StdVecBs; 2411 std::vector<std::string> StdVecStr; 2412 std::vector<int8_t> StdVecI8; 2413 std::vector<int16_t> StdVecI16; 2414 std::vector<int32_t> StdVecI32; 2415 std::vector<int64_t> StdVecI64; 2416 std::vector<uint8_t> StdVecU8; 2417 std::vector<uint16_t> StdVecU16; 2418 std::vector<uint32_t> StdVecU32; 2419 std::vector<uint64_t> StdVecU64; 2420 std::vector<float> StdVecF32; 2421 std::vector<double> StdVecF64; 2422 2423 std::vector<Float16_t> StdVecD16; 2424 std::vector<Double32_t> StdVecD32; 2425 std::vector<TNestedP2> StdVecP2; 2426 std::vector<TObjString> StdVecObj; 2427 2428 std::vector<std::vector<double> > StdVecVecF64; 2429 std::vector<std::vector<std::string> > StdVecVecStr; 2430 std::vector<std::vector<TNestedP2> > StdVecVecP2; 2431 }; 2432 2433 TNestedEvent1 *newEvent() { 2434 auto *evt = new TNestedEvent1; 2435 evt->SliBs = (bool*)malloc(sizeof(bool)*0); 2436 // evt->SliStr = (char**)malloc(sizeof(char*)*0); 2437 evt->SliI8 = (int8_t*)malloc(sizeof(int8_t)*0); 2438 evt->SliI16 = (int16_t*)malloc(sizeof(int16_t)*0); 2439 evt->SliI32 = (int32_t*)malloc(sizeof(int32_t)*0); 2440 evt->SliI64 = (int64_t*)malloc(sizeof(int64_t)*0); 2441 evt->SliU8 = (uint8_t*)malloc(sizeof(uint8_t)*0); 2442 evt->SliU16 = (uint16_t*)malloc(sizeof(uint16_t)*0); 2443 evt->SliU32 = (uint32_t*)malloc(sizeof(uint32_t)*0); 2444 evt->SliU64 = (uint64_t*)malloc(sizeof(uint64_t)*0); 2445 evt->SliF32 = (float*)malloc(sizeof(float)*0); 2446 evt->SliF64 = (double*)malloc(sizeof(double)*0); 2447 2448 evt->SliD16 = (Float16_t*)malloc(sizeof(Float16_t)*0); 2449 evt->SliD32 = (Double32_t*)malloc(sizeof(Double32_t)*0); 2450 // evt->SliP2 = (TNestedP2*)malloc(sizeof(TNestedP2)*0); 2451 // evt->SliObj = (TObjString*)malloc(sizeof(TObjString)*0); 2452 2453 return evt; 2454 } 2455 2456 2457 void scan(const char *fname, const char *tname, const char *oname) { 2458 auto o = std::fstream(oname, std::ofstream::out); 2459 auto f = TFile::Open(fname, "READ"); 2460 auto t = (TTree*)f->Get(tname); 2461 t->Print(); 2462 2463 TNestedEvent1 *evt = newEvent(); 2464 t->SetBranchAddress("evt", &evt); 2465 2466 o << "key[000]: " << tname << ";1 \"\" (TTree)\n"; 2467 2468 auto n = t->GetEntries(); 2469 for (int i = 0; i < n; i++) { 2470 t->GetEntry(i); 2471 o << "[00" << i << "][evt]: " 2472 << "{" << printV(evt->Bool) 2473 << " " << printV(evt->Str) 2474 << " " << printV(int(evt->I8)) 2475 << " " << printV(evt->I16) 2476 << " " << printV(evt->I32) 2477 << " " << printV(evt->I64) 2478 << " " << printV(int(evt->U8)) 2479 << " " << printV(evt->U16) 2480 << " " << printV(evt->U32) 2481 << " " << printV(evt->U64) 2482 << " " << printV(evt->F32) 2483 << " " << printV(evt->F64) 2484 << " " << printV(evt->D16) 2485 << " " << printV(evt->D32) 2486 << " " << printV(evt->P2) 2487 << " " << printV(evt->Obj) 2488 2489 << " " << printArr(evt->ArrBs) 2490 // << " " << printArr(evt->ArrStr) 2491 << " " << printArr(evt->ArrI8) 2492 << " " << printArr(evt->ArrI16) 2493 << " " << printArr(evt->ArrI32) 2494 << " " << printArr(evt->ArrI64) 2495 << " " << printArr(evt->ArrU8) 2496 << " " << printArr(evt->ArrU16) 2497 << " " << printArr(evt->ArrU32) 2498 << " " << printArr(evt->ArrU64) 2499 << " " << printArr(evt->ArrF32) 2500 << " " << printArr(evt->ArrF64) 2501 << " " << printArr(evt->ArrD16) 2502 << " " << printArr(evt->ArrD32) 2503 << " " << printArr(evt->ArrP2) 2504 << " " << printArr(evt->ArrObj) 2505 2506 << " " << evt->N 2507 << " " << printSli(evt->N, evt->SliBs) 2508 // << " " << printSli(evt->N, evt->SliStr) 2509 << " " << printSli(evt->N, evt->SliI8) 2510 << " " << printSli(evt->N, evt->SliI16) 2511 << " " << printSli(evt->N, evt->SliI32) 2512 << " " << printSli(evt->N, evt->SliI64) 2513 << " " << printSli(evt->N, evt->SliU8) 2514 << " " << printSli(evt->N, evt->SliU16) 2515 << " " << printSli(evt->N, evt->SliU32) 2516 << " " << printSli(evt->N, evt->SliU64) 2517 << " " << printSli(evt->N, evt->SliF32) 2518 << " " << printSli(evt->N, evt->SliF64) 2519 << " " << printSli(evt->N, evt->SliD16) 2520 << " " << printSli(evt->N, evt->SliD32) 2521 // << " " << printSli(evt->N, evt->SliP2) 2522 // << " " << printSli(evt->N, evt->SliObj) 2523 2524 << " " << printVec(evt->StdVecBs) 2525 << " " << printVec(evt->StdVecStr) 2526 << " " << printVec(evt->StdVecI8) 2527 << " " << printVec(evt->StdVecI16) 2528 << " " << printVec(evt->StdVecI32) 2529 << " " << printVec(evt->StdVecI64) 2530 << " " << printVec(evt->StdVecU8) 2531 << " " << printVec(evt->StdVecU16) 2532 << " " << printVec(evt->StdVecU32) 2533 << " " << printVec(evt->StdVecU64) 2534 << " " << printVec(evt->StdVecF32) 2535 << " " << printVec(evt->StdVecF64) 2536 << " " << printVec(evt->StdVecD16) 2537 << " " << printVec(evt->StdVecD32) 2538 << " " << printVec(evt->StdVecP2) 2539 << " " << printVec(evt->StdVecObj) 2540 2541 << " " << printVecVec(evt->StdVecVecF64) 2542 << " " << printVecVec(evt->StdVecVecStr) 2543 << " " << printVecVec(evt->StdVecVecP2) 2544 << "}\n"; 2545 } 2546 o.flush(); 2547 } 2548 `, 2549 cxx: `key[000]: mytree;1 "" (TTree) 2550 [000][evt]: {true str-000 0 0 0 0 0 0 0 0 0 0 0 0 {0 0} obj-0 [true false false false false false false false false false] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0] [{0 0} {0 0} {0 0} {0 0} {0 0} {0 0} {0 0} {0 0} {0 0} {0 0}] [obj-0 obj-0 obj-0 obj-0 obj-0 obj-0 obj-0 obj-0 obj-0 obj-0] 0 [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] []} 2551 [001][evt]: {false str-001 -1 -1 -1 -1 1 1 1 1 1 1 1 1 {1 1} obj-1 [false true false false false false false false false false] [-1 -1 -1 -1 -1 -1 -1 -1 -1 -1] [-1 -1 -1 -1 -1 -1 -1 -1 -1 -1] [-1 -1 -1 -1 -1 -1 -1 -1 -1 -1] [-1 -1 -1 -1 -1 -1 -1 -1 -1 -1] [1 1 1 1 1 1 1 1 1 1] [1 1 1 1 1 1 1 1 1 1] [1 1 1 1 1 1 1 1 1 1] [1 1 1 1 1 1 1 1 1 1] [1 1 1 1 1 1 1 1 1 1] [1 1 1 1 1 1 1 1 1 1] [1 1 1 1 1 1 1 1 1 1] [1 1 1 1 1 1 1 1 1 1] [{1 1} {1 1} {1 1} {1 1} {1 1} {1 1} {1 1} {1 1} {1 1} {1 1}] [obj-1 obj-1 obj-1 obj-1 obj-1 obj-1 obj-1 obj-1 obj-1 obj-1] 1 [true] [-1] [-1] [-1] [-1] [1] [1] [1] [1] [1] [1] [1] [1] [true] [std-001] [-1] [-1] [-1] [-1] [1] [1] [1] [1] [1] [1] [1] [1] [{1 1}] [obj-001] [[0 1 2 3]] [[vec-001 vec-002 vec-003 vec-004]] [[{1 1} {2 2} {3 3} {4 4}]]} 2552 [002][evt]: {true str-002 -2 -2 -2 -2 2 2 2 2 2 2 2 2 {2 2} obj-2 [false false true false false false false false false false] [-2 -2 -2 -2 -2 -2 -2 -2 -2 -2] [-2 -2 -2 -2 -2 -2 -2 -2 -2 -2] [-2 -2 -2 -2 -2 -2 -2 -2 -2 -2] [-2 -2 -2 -2 -2 -2 -2 -2 -2 -2] [2 2 2 2 2 2 2 2 2 2] [2 2 2 2 2 2 2 2 2 2] [2 2 2 2 2 2 2 2 2 2] [2 2 2 2 2 2 2 2 2 2] [2 2 2 2 2 2 2 2 2 2] [2 2 2 2 2 2 2 2 2 2] [2 2 2 2 2 2 2 2 2 2] [2 2 2 2 2 2 2 2 2 2] [{2 2} {2 2} {2 2} {2 2} {2 2} {2 2} {2 2} {2 2} {2 2} {2 2}] [obj-2 obj-2 obj-2 obj-2 obj-2 obj-2 obj-2 obj-2 obj-2 obj-2] 2 [false true] [-2 -2] [-2 -2] [-2 -2] [-2 -2] [2 2] [2 2] [2 2] [2 2] [2 2] [2 2] [2 2] [2 2] [false true] [std-002 std-002] [-2 -2] [-2 -2] [-2 -2] [-2 -2] [2 2] [2 2] [2 2] [2 2] [2 2] [2 2] [2 2] [2 2] [{2 2} {2 2}] [obj-002 obj-002] [[0 1 2 3] [1 2 3 4]] [[vec-002 vec-003 vec-004 vec-005] [vec-002 vec-003 vec-004 vec-005]] [[{2 2} {3 3} {4 4} {5 5}] [{2 2} {3 3} {4 4} {5 5}]]} 2553 [003][evt]: {false str-003 -3 -3 -3 -3 3 3 3 3 3 3 3 3 {3 3} obj-3 [false false false true false false false false false false] [-3 -3 -3 -3 -3 -3 -3 -3 -3 -3] [-3 -3 -3 -3 -3 -3 -3 -3 -3 -3] [-3 -3 -3 -3 -3 -3 -3 -3 -3 -3] [-3 -3 -3 -3 -3 -3 -3 -3 -3 -3] [3 3 3 3 3 3 3 3 3 3] [3 3 3 3 3 3 3 3 3 3] [3 3 3 3 3 3 3 3 3 3] [3 3 3 3 3 3 3 3 3 3] [3 3 3 3 3 3 3 3 3 3] [3 3 3 3 3 3 3 3 3 3] [3 3 3 3 3 3 3 3 3 3] [3 3 3 3 3 3 3 3 3 3] [{3 3} {3 3} {3 3} {3 3} {3 3} {3 3} {3 3} {3 3} {3 3} {3 3}] [obj-3 obj-3 obj-3 obj-3 obj-3 obj-3 obj-3 obj-3 obj-3 obj-3] 3 [false false true] [-3 -3 -3] [-3 -3 -3] [-3 -3 -3] [-3 -3 -3] [3 3 3] [3 3 3] [3 3 3] [3 3 3] [3 3 3] [3 3 3] [3 3 3] [3 3 3] [false false true] [std-003 std-003 std-003] [-3 -3 -3] [-3 -3 -3] [-3 -3 -3] [-3 -3 -3] [3 3 3] [3 3 3] [3 3 3] [3 3 3] [3 3 3] [3 3 3] [3 3 3] [3 3 3] [{3 3} {3 3} {3 3}] [obj-003 obj-003 obj-003] [[0 1 2 3] [1 2 3 4] [2 3 4 5]] [[vec-003 vec-004 vec-005 vec-006] [vec-003 vec-004 vec-005 vec-006] [vec-003 vec-004 vec-005 vec-006]] [[{3 3} {4 4} {5 5} {6 6}] [{3 3} {4 4} {5 5} {6 6}] [{3 3} {4 4} {5 5} {6 6}]]} 2554 [004][evt]: {true str-004 -4 -4 -4 -4 4 4 4 4 4 4 4 4 {4 4} obj-4 [false false false false true false false false false false] [-4 -4 -4 -4 -4 -4 -4 -4 -4 -4] [-4 -4 -4 -4 -4 -4 -4 -4 -4 -4] [-4 -4 -4 -4 -4 -4 -4 -4 -4 -4] [-4 -4 -4 -4 -4 -4 -4 -4 -4 -4] [4 4 4 4 4 4 4 4 4 4] [4 4 4 4 4 4 4 4 4 4] [4 4 4 4 4 4 4 4 4 4] [4 4 4 4 4 4 4 4 4 4] [4 4 4 4 4 4 4 4 4 4] [4 4 4 4 4 4 4 4 4 4] [4 4 4 4 4 4 4 4 4 4] [4 4 4 4 4 4 4 4 4 4] [{4 4} {4 4} {4 4} {4 4} {4 4} {4 4} {4 4} {4 4} {4 4} {4 4}] [obj-4 obj-4 obj-4 obj-4 obj-4 obj-4 obj-4 obj-4 obj-4 obj-4] 4 [false false false true] [-4 -4 -4 -4] [-4 -4 -4 -4] [-4 -4 -4 -4] [-4 -4 -4 -4] [4 4 4 4] [4 4 4 4] [4 4 4 4] [4 4 4 4] [4 4 4 4] [4 4 4 4] [4 4 4 4] [4 4 4 4] [false false false true] [std-004 std-004 std-004 std-004] [-4 -4 -4 -4] [-4 -4 -4 -4] [-4 -4 -4 -4] [-4 -4 -4 -4] [4 4 4 4] [4 4 4 4] [4 4 4 4] [4 4 4 4] [4 4 4 4] [4 4 4 4] [4 4 4 4] [4 4 4 4] [{4 4} {4 4} {4 4} {4 4}] [obj-004 obj-004 obj-004 obj-004] [[0 1 2 3] [1 2 3 4] [2 3 4 5] [3 4 5 6]] [[vec-004 vec-005 vec-006 vec-007] [vec-004 vec-005 vec-006 vec-007] [vec-004 vec-005 vec-006 vec-007] [vec-004 vec-005 vec-006 vec-007]] [[{4 4} {5 5} {6 6} {7 7}] [{4 4} {5 5} {6 6} {7 7}] [{4 4} {5 5} {6 6} {7 7}] [{4 4} {5 5} {6 6} {7 7}]]} 2555 [005][evt]: {false str-005 -5 -5 -5 -5 5 5 5 5 5 5 5 5 {5 5} obj-5 [false false false false false true false false false false] [-5 -5 -5 -5 -5 -5 -5 -5 -5 -5] [-5 -5 -5 -5 -5 -5 -5 -5 -5 -5] [-5 -5 -5 -5 -5 -5 -5 -5 -5 -5] [-5 -5 -5 -5 -5 -5 -5 -5 -5 -5] [5 5 5 5 5 5 5 5 5 5] [5 5 5 5 5 5 5 5 5 5] [5 5 5 5 5 5 5 5 5 5] [5 5 5 5 5 5 5 5 5 5] [5 5 5 5 5 5 5 5 5 5] [5 5 5 5 5 5 5 5 5 5] [5 5 5 5 5 5 5 5 5 5] [5 5 5 5 5 5 5 5 5 5] [{5 5} {5 5} {5 5} {5 5} {5 5} {5 5} {5 5} {5 5} {5 5} {5 5}] [obj-5 obj-5 obj-5 obj-5 obj-5 obj-5 obj-5 obj-5 obj-5 obj-5] 5 [false false false false true] [-5 -5 -5 -5 -5] [-5 -5 -5 -5 -5] [-5 -5 -5 -5 -5] [-5 -5 -5 -5 -5] [5 5 5 5 5] [5 5 5 5 5] [5 5 5 5 5] [5 5 5 5 5] [5 5 5 5 5] [5 5 5 5 5] [5 5 5 5 5] [5 5 5 5 5] [false false false false true] [std-005 std-005 std-005 std-005 std-005] [-5 -5 -5 -5 -5] [-5 -5 -5 -5 -5] [-5 -5 -5 -5 -5] [-5 -5 -5 -5 -5] [5 5 5 5 5] [5 5 5 5 5] [5 5 5 5 5] [5 5 5 5 5] [5 5 5 5 5] [5 5 5 5 5] [5 5 5 5 5] [5 5 5 5 5] [{5 5} {5 5} {5 5} {5 5} {5 5}] [obj-005 obj-005 obj-005 obj-005 obj-005] [[0 1 2 3] [1 2 3 4] [2 3 4 5] [3 4 5 6] [4 5 6 7]] [[vec-005 vec-006 vec-007 vec-008] [vec-005 vec-006 vec-007 vec-008] [vec-005 vec-006 vec-007 vec-008] [vec-005 vec-006 vec-007 vec-008] [vec-005 vec-006 vec-007 vec-008]] [[{5 5} {6 6} {7 7} {8 8}] [{5 5} {6 6} {7 7} {8 8}] [{5 5} {6 6} {7 7} {8 8}] [{5 5} {6 6} {7 7} {8 8}] [{5 5} {6 6} {7 7} {8 8}]]} 2556 [006][evt]: {true str-006 -6 -6 -6 -6 6 6 6 6 6 6 6 6 {6 6} obj-6 [false false false false false false true false false false] [-6 -6 -6 -6 -6 -6 -6 -6 -6 -6] [-6 -6 -6 -6 -6 -6 -6 -6 -6 -6] [-6 -6 -6 -6 -6 -6 -6 -6 -6 -6] [-6 -6 -6 -6 -6 -6 -6 -6 -6 -6] [6 6 6 6 6 6 6 6 6 6] [6 6 6 6 6 6 6 6 6 6] [6 6 6 6 6 6 6 6 6 6] [6 6 6 6 6 6 6 6 6 6] [6 6 6 6 6 6 6 6 6 6] [6 6 6 6 6 6 6 6 6 6] [6 6 6 6 6 6 6 6 6 6] [6 6 6 6 6 6 6 6 6 6] [{6 6} {6 6} {6 6} {6 6} {6 6} {6 6} {6 6} {6 6} {6 6} {6 6}] [obj-6 obj-6 obj-6 obj-6 obj-6 obj-6 obj-6 obj-6 obj-6 obj-6] 6 [false false false false false true] [-6 -6 -6 -6 -6 -6] [-6 -6 -6 -6 -6 -6] [-6 -6 -6 -6 -6 -6] [-6 -6 -6 -6 -6 -6] [6 6 6 6 6 6] [6 6 6 6 6 6] [6 6 6 6 6 6] [6 6 6 6 6 6] [6 6 6 6 6 6] [6 6 6 6 6 6] [6 6 6 6 6 6] [6 6 6 6 6 6] [false false false false false true] [std-006 std-006 std-006 std-006 std-006 std-006] [-6 -6 -6 -6 -6 -6] [-6 -6 -6 -6 -6 -6] [-6 -6 -6 -6 -6 -6] [-6 -6 -6 -6 -6 -6] [6 6 6 6 6 6] [6 6 6 6 6 6] [6 6 6 6 6 6] [6 6 6 6 6 6] [6 6 6 6 6 6] [6 6 6 6 6 6] [6 6 6 6 6 6] [6 6 6 6 6 6] [{6 6} {6 6} {6 6} {6 6} {6 6} {6 6}] [obj-006 obj-006 obj-006 obj-006 obj-006 obj-006] [[0 1 2 3] [1 2 3 4] [2 3 4 5] [3 4 5 6] [4 5 6 7] [5 6 7 8]] [[vec-006 vec-007 vec-008 vec-009] [vec-006 vec-007 vec-008 vec-009] [vec-006 vec-007 vec-008 vec-009] [vec-006 vec-007 vec-008 vec-009] [vec-006 vec-007 vec-008 vec-009] [vec-006 vec-007 vec-008 vec-009]] [[{6 6} {7 7} {8 8} {9 9}] [{6 6} {7 7} {8 8} {9 9}] [{6 6} {7 7} {8 8} {9 9}] [{6 6} {7 7} {8 8} {9 9}] [{6 6} {7 7} {8 8} {9 9}] [{6 6} {7 7} {8 8} {9 9}]]} 2557 [007][evt]: {false str-007 -7 -7 -7 -7 7 7 7 7 7 7 7 7 {7 7} obj-7 [false false false false false false false true false false] [-7 -7 -7 -7 -7 -7 -7 -7 -7 -7] [-7 -7 -7 -7 -7 -7 -7 -7 -7 -7] [-7 -7 -7 -7 -7 -7 -7 -7 -7 -7] [-7 -7 -7 -7 -7 -7 -7 -7 -7 -7] [7 7 7 7 7 7 7 7 7 7] [7 7 7 7 7 7 7 7 7 7] [7 7 7 7 7 7 7 7 7 7] [7 7 7 7 7 7 7 7 7 7] [7 7 7 7 7 7 7 7 7 7] [7 7 7 7 7 7 7 7 7 7] [7 7 7 7 7 7 7 7 7 7] [7 7 7 7 7 7 7 7 7 7] [{7 7} {7 7} {7 7} {7 7} {7 7} {7 7} {7 7} {7 7} {7 7} {7 7}] [obj-7 obj-7 obj-7 obj-7 obj-7 obj-7 obj-7 obj-7 obj-7 obj-7] 7 [false false false false false false true] [-7 -7 -7 -7 -7 -7 -7] [-7 -7 -7 -7 -7 -7 -7] [-7 -7 -7 -7 -7 -7 -7] [-7 -7 -7 -7 -7 -7 -7] [7 7 7 7 7 7 7] [7 7 7 7 7 7 7] [7 7 7 7 7 7 7] [7 7 7 7 7 7 7] [7 7 7 7 7 7 7] [7 7 7 7 7 7 7] [7 7 7 7 7 7 7] [7 7 7 7 7 7 7] [false false false false false false true] [std-007 std-007 std-007 std-007 std-007 std-007 std-007] [-7 -7 -7 -7 -7 -7 -7] [-7 -7 -7 -7 -7 -7 -7] [-7 -7 -7 -7 -7 -7 -7] [-7 -7 -7 -7 -7 -7 -7] [7 7 7 7 7 7 7] [7 7 7 7 7 7 7] [7 7 7 7 7 7 7] [7 7 7 7 7 7 7] [7 7 7 7 7 7 7] [7 7 7 7 7 7 7] [7 7 7 7 7 7 7] [7 7 7 7 7 7 7] [{7 7} {7 7} {7 7} {7 7} {7 7} {7 7} {7 7}] [obj-007 obj-007 obj-007 obj-007 obj-007 obj-007 obj-007] [[0 1 2 3] [1 2 3 4] [2 3 4 5] [3 4 5 6] [4 5 6 7] [5 6 7 8] [6 7 8 9]] [[vec-007 vec-008 vec-009 vec-010] [vec-007 vec-008 vec-009 vec-010] [vec-007 vec-008 vec-009 vec-010] [vec-007 vec-008 vec-009 vec-010] [vec-007 vec-008 vec-009 vec-010] [vec-007 vec-008 vec-009 vec-010] [vec-007 vec-008 vec-009 vec-010]] [[{7 7} {8 8} {9 9} {10 10}] [{7 7} {8 8} {9 9} {10 10}] [{7 7} {8 8} {9 9} {10 10}] [{7 7} {8 8} {9 9} {10 10}] [{7 7} {8 8} {9 9} {10 10}] [{7 7} {8 8} {9 9} {10 10}] [{7 7} {8 8} {9 9} {10 10}]]} 2558 [008][evt]: {true str-008 -8 -8 -8 -8 8 8 8 8 8 8 8 8 {8 8} obj-8 [false false false false false false false false true false] [-8 -8 -8 -8 -8 -8 -8 -8 -8 -8] [-8 -8 -8 -8 -8 -8 -8 -8 -8 -8] [-8 -8 -8 -8 -8 -8 -8 -8 -8 -8] [-8 -8 -8 -8 -8 -8 -8 -8 -8 -8] [8 8 8 8 8 8 8 8 8 8] [8 8 8 8 8 8 8 8 8 8] [8 8 8 8 8 8 8 8 8 8] [8 8 8 8 8 8 8 8 8 8] [8 8 8 8 8 8 8 8 8 8] [8 8 8 8 8 8 8 8 8 8] [8 8 8 8 8 8 8 8 8 8] [8 8 8 8 8 8 8 8 8 8] [{8 8} {8 8} {8 8} {8 8} {8 8} {8 8} {8 8} {8 8} {8 8} {8 8}] [obj-8 obj-8 obj-8 obj-8 obj-8 obj-8 obj-8 obj-8 obj-8 obj-8] 8 [false false false false false false false true] [-8 -8 -8 -8 -8 -8 -8 -8] [-8 -8 -8 -8 -8 -8 -8 -8] [-8 -8 -8 -8 -8 -8 -8 -8] [-8 -8 -8 -8 -8 -8 -8 -8] [8 8 8 8 8 8 8 8] [8 8 8 8 8 8 8 8] [8 8 8 8 8 8 8 8] [8 8 8 8 8 8 8 8] [8 8 8 8 8 8 8 8] [8 8 8 8 8 8 8 8] [8 8 8 8 8 8 8 8] [8 8 8 8 8 8 8 8] [false false false false false false false true] [std-008 std-008 std-008 std-008 std-008 std-008 std-008 std-008] [-8 -8 -8 -8 -8 -8 -8 -8] [-8 -8 -8 -8 -8 -8 -8 -8] [-8 -8 -8 -8 -8 -8 -8 -8] [-8 -8 -8 -8 -8 -8 -8 -8] [8 8 8 8 8 8 8 8] [8 8 8 8 8 8 8 8] [8 8 8 8 8 8 8 8] [8 8 8 8 8 8 8 8] [8 8 8 8 8 8 8 8] [8 8 8 8 8 8 8 8] [8 8 8 8 8 8 8 8] [8 8 8 8 8 8 8 8] [{8 8} {8 8} {8 8} {8 8} {8 8} {8 8} {8 8} {8 8}] [obj-008 obj-008 obj-008 obj-008 obj-008 obj-008 obj-008 obj-008] [[0 1 2 3] [1 2 3 4] [2 3 4 5] [3 4 5 6] [4 5 6 7] [5 6 7 8] [6 7 8 9] [7 8 9 10]] [[vec-008 vec-009 vec-010 vec-011] [vec-008 vec-009 vec-010 vec-011] [vec-008 vec-009 vec-010 vec-011] [vec-008 vec-009 vec-010 vec-011] [vec-008 vec-009 vec-010 vec-011] [vec-008 vec-009 vec-010 vec-011] [vec-008 vec-009 vec-010 vec-011] [vec-008 vec-009 vec-010 vec-011]] [[{8 8} {9 9} {10 10} {11 11}] [{8 8} {9 9} {10 10} {11 11}] [{8 8} {9 9} {10 10} {11 11}] [{8 8} {9 9} {10 10} {11 11}] [{8 8} {9 9} {10 10} {11 11}] [{8 8} {9 9} {10 10} {11 11}] [{8 8} {9 9} {10 10} {11 11}] [{8 8} {9 9} {10 10} {11 11}]]} 2559 [009][evt]: {false str-009 -9 -9 -9 -9 9 9 9 9 9 9 9 9 {9 9} obj-9 [false false false false false false false false false true] [-9 -9 -9 -9 -9 -9 -9 -9 -9 -9] [-9 -9 -9 -9 -9 -9 -9 -9 -9 -9] [-9 -9 -9 -9 -9 -9 -9 -9 -9 -9] [-9 -9 -9 -9 -9 -9 -9 -9 -9 -9] [9 9 9 9 9 9 9 9 9 9] [9 9 9 9 9 9 9 9 9 9] [9 9 9 9 9 9 9 9 9 9] [9 9 9 9 9 9 9 9 9 9] [9 9 9 9 9 9 9 9 9 9] [9 9 9 9 9 9 9 9 9 9] [9 9 9 9 9 9 9 9 9 9] [9 9 9 9 9 9 9 9 9 9] [{9 9} {9 9} {9 9} {9 9} {9 9} {9 9} {9 9} {9 9} {9 9} {9 9}] [obj-9 obj-9 obj-9 obj-9 obj-9 obj-9 obj-9 obj-9 obj-9 obj-9] 9 [false false false false false false false false true] [-9 -9 -9 -9 -9 -9 -9 -9 -9] [-9 -9 -9 -9 -9 -9 -9 -9 -9] [-9 -9 -9 -9 -9 -9 -9 -9 -9] [-9 -9 -9 -9 -9 -9 -9 -9 -9] [9 9 9 9 9 9 9 9 9] [9 9 9 9 9 9 9 9 9] [9 9 9 9 9 9 9 9 9] [9 9 9 9 9 9 9 9 9] [9 9 9 9 9 9 9 9 9] [9 9 9 9 9 9 9 9 9] [9 9 9 9 9 9 9 9 9] [9 9 9 9 9 9 9 9 9] [false false false false false false false false true] [std-009 std-009 std-009 std-009 std-009 std-009 std-009 std-009 std-009] [-9 -9 -9 -9 -9 -9 -9 -9 -9] [-9 -9 -9 -9 -9 -9 -9 -9 -9] [-9 -9 -9 -9 -9 -9 -9 -9 -9] [-9 -9 -9 -9 -9 -9 -9 -9 -9] [9 9 9 9 9 9 9 9 9] [9 9 9 9 9 9 9 9 9] [9 9 9 9 9 9 9 9 9] [9 9 9 9 9 9 9 9 9] [9 9 9 9 9 9 9 9 9] [9 9 9 9 9 9 9 9 9] [9 9 9 9 9 9 9 9 9] [9 9 9 9 9 9 9 9 9] [{9 9} {9 9} {9 9} {9 9} {9 9} {9 9} {9 9} {9 9} {9 9}] [obj-009 obj-009 obj-009 obj-009 obj-009 obj-009 obj-009 obj-009 obj-009] [[0 1 2 3] [1 2 3 4] [2 3 4 5] [3 4 5 6] [4 5 6 7] [5 6 7 8] [6 7 8 9] [7 8 9 10] [8 9 10 11]] [[vec-009 vec-010 vec-011 vec-012] [vec-009 vec-010 vec-011 vec-012] [vec-009 vec-010 vec-011 vec-012] [vec-009 vec-010 vec-011 vec-012] [vec-009 vec-010 vec-011 vec-012] [vec-009 vec-010 vec-011 vec-012] [vec-009 vec-010 vec-011 vec-012] [vec-009 vec-010 vec-011 vec-012] [vec-009 vec-010 vec-011 vec-012]] [[{9 9} {10 10} {11 11} {12 12}] [{9 9} {10 10} {11 11} {12 12}] [{9 9} {10 10} {11 11} {12 12}] [{9 9} {10 10} {11 11} {12 12}] [{9 9} {10 10} {11 11} {12 12}] [{9 9} {10 10} {11 11} {12 12}] [{9 9} {10 10} {11 11} {12 12}] [{9 9} {10 10} {11 11} {12 12}] [{9 9} {10 10} {11 11} {12 12}]]} 2560 `, 2561 sinfos: []rbytes.StreamerInfo{ 2562 rdict.StreamerOf(sictx, reflect.TypeOf([]float64{})), 2563 rdict.StreamerOf(sictx, reflect.TypeOf([]string{})), 2564 rdict.StreamerOf(sictx, reflect.TypeOf([][]float64{})), 2565 rdict.StreamerOf(sictx, reflect.TypeOf([][]string{})), 2566 rdict.StreamerOf(sictx, reflect.TypeOf(TNestedP2{})), 2567 rdict.StreamerOf(sictx, reflect.TypeOf([]TNestedP2{})), 2568 rdict.StreamerOf(sictx, reflect.TypeOf([][]TNestedP2{})), 2569 rdict.StreamerOf(sictx, reflect.TypeOf(TNestedEvent1{})), 2570 }, 2571 }, 2572 } { 2573 t.Run(tc.name, func(t *testing.T) { 2574 fname := filepath.Join(tmp, tc.name+".root") 2575 2576 if tc.skip { 2577 t.Skipf("skipping %s...", tc.name) 2578 } 2579 2580 for i := range tc.sinfos { 2581 rdict.StreamerInfos.Add(tc.sinfos[i]) 2582 } 2583 2584 func() { 2585 f, err := riofs.Create(fname) 2586 if err != nil { 2587 t.Fatalf("could not create write ROOT file %q: %v", fname, err) 2588 } 2589 defer f.Close() 2590 2591 tw, err := NewWriter(f, treeName, tc.wvars, tc.wopts...) 2592 if err != nil { 2593 t.Fatalf("could not create tree writer: %v", err) 2594 } 2595 defer tw.Close() 2596 2597 if got, want := len(tw.Branches()), len(tc.wvars); got != want { 2598 t.Fatalf("invalid number of branches: got=%d, want=%d", got, want) 2599 } 2600 2601 for i, b := range tw.Branches() { 2602 if got, want := b.Name(), tc.wvars[i].Name; got != want { 2603 t.Fatalf("branch[%d]: got=%q, want=%q", i, got, want) 2604 } 2605 if got, want := b.Title(), tc.btitles[i]; got != want { 2606 t.Fatalf("branch[%d]: got=%q, want=%q", i, got, want) 2607 } 2608 } 2609 2610 if got, want := len(tw.Leaves()), len(tc.wvars); got != want { 2611 leaves := make([]string, got) 2612 for i, l := range tw.Leaves() { 2613 leaves[i] = l.Name() 2614 } 2615 t.Fatalf("invalid number of leaves: got=%d, want=%d (leaves: %q)", got, want, leaves) 2616 } 2617 2618 for i, leaf := range tw.Leaves() { 2619 if got, want := leaf.Name(), tc.wvars[i].Name; got != want { 2620 t.Fatalf("leaf[%d]: got=%q, want=%q", i, got, want) 2621 } 2622 if got, want := leaf.Title(), tc.ltitles[i]; got != want { 2623 t.Fatalf("leaf[%d]: got=%q, want=%q", i, got, want) 2624 } 2625 } 2626 2627 total := 0 2628 for i := range int(tc.nevts) { 2629 want := tc.want(i) 2630 for j, wvar := range tc.wvars { 2631 v := reflect.ValueOf(wvar.Value).Elem() 2632 o := reflect.ValueOf(want).Field(j) 2633 v.Set(o) 2634 } 2635 n, err := tw.Write() 2636 if err != nil { 2637 t.Fatalf("could not write event %d: %v", i, err) 2638 } 2639 total += n 2640 } 2641 2642 if got, want := tw.Entries(), tc.nevts; got != want { 2643 t.Fatalf("invalid number of entries: got=%d, want=%d", got, want) 2644 } 2645 if got, want := total, tc.total; got != want { 2646 t.Errorf("invalid number of bytes written: got=%d, want=%d", got, want) 2647 } 2648 2649 err = tw.Close() 2650 if err != nil { 2651 t.Fatalf("could not close tree writer: %v", err) 2652 } 2653 2654 err = f.Close() 2655 if err != nil { 2656 t.Fatalf("could not close write ROOT file %q: %v", fname, err) 2657 } 2658 }() 2659 2660 func() { 2661 f, err := riofs.Open(fname) 2662 if err != nil { 2663 t.Fatalf("could not opend read ROOT file %q: %+v", fname, err) 2664 } 2665 defer f.Close() 2666 2667 obj, err := f.Get(treeName) 2668 if err != nil { 2669 t.Fatalf("could not get ROOT tree %q: %+v", treeName, err) 2670 } 2671 tree := obj.(Tree) 2672 2673 if got, want := tree.Entries(), tc.nevts; got != want { 2674 t.Fatalf("invalid number of events: got=%v, want=%v", got, want) 2675 } 2676 2677 for i, b := range tree.Branches() { 2678 if got, want := b.Name(), tc.wvars[i].Name; got != want { 2679 t.Fatalf("branch[%d]: got=%q, want=%q", i, got, want) 2680 } 2681 if got, want := b.Title(), tc.btitles[i]; got != want { 2682 t.Fatalf("branch[%d]: got=%q, want=%q", i, got, want) 2683 } 2684 } 2685 2686 for i, leaf := range tree.Leaves() { 2687 if got, want := leaf.Name(), tc.wvars[i].Name; got != want { 2688 t.Fatalf("leaf[%d]: got=%q, want=%q", i, got, want) 2689 } 2690 if got, want := leaf.Title(), tc.ltitles[i]; got != want { 2691 t.Fatalf("leaf[%d]: got=%q, want=%q", i, got, want) 2692 } 2693 } 2694 2695 rvars := tc.rvars 2696 if len(rvars) != len(tc.wvars) { 2697 t.Fatalf("invalid number of read-vars: got=%d, want=%d", len(rvars), len(tc.wvars)) 2698 } 2699 2700 for i, rvar := range rvars { 2701 wvar := tc.wvars[i] 2702 if got, want := rvar.Name, wvar.Name; got != want { 2703 t.Fatalf("invalid name for rvar[%d]: got=%q, want=%q", i, got, want) 2704 } 2705 wtyp := reflect.TypeOf(wvar.Value) 2706 rtyp := reflect.TypeOf(rvar.Value) 2707 if got, want := rtyp, wtyp; got != want { 2708 t.Fatalf("invalid type for rvar[%d]: got=%v, want=%v", i, got, want) 2709 } 2710 } 2711 2712 r, err := NewReader(tree, rvars) 2713 if err != nil { 2714 t.Fatalf("could not create reader: %+v", err) 2715 } 2716 defer r.Close() 2717 2718 nn := 0 2719 err = r.Read(func(ctx RCtx) error { 2720 i := int(ctx.Entry) 2721 want := tc.want(i) 2722 for i, rvar := range rvars { 2723 var ( 2724 want = reflect.ValueOf(want).Field(i).Interface() 2725 got = reflect.ValueOf(rvar.Value).Elem().Interface() 2726 ) 2727 if !reflect.DeepEqual(got, want) { 2728 return fmt.Errorf( 2729 "entry[%d]: invalid scan-value[%s]:\ngot= %v\nwant=%v", 2730 ctx.Entry, tc.wvars[i].Name, got, want, 2731 ) 2732 } 2733 } 2734 nn++ 2735 return nil 2736 }) 2737 if err != nil { 2738 t.Fatalf("could not read tree: %+v", err) 2739 } 2740 2741 if got, want := nn, int(tc.nevts); got != want { 2742 t.Fatalf("invalid number of events: got=%d, want=%d", got, want) 2743 } 2744 }() 2745 2746 if rtests.HasROOT && len(tc.macro) != 0 { 2747 ofile := filepath.Join(tmp, tc.name+".txt") 2748 out, err := rtests.RunCxxROOT("scan", []byte(tc.macro), fname, treeName, ofile) 2749 if err != nil { 2750 t.Fatalf("could not run C++ ROOT: %+v\noutput:\n%s", err, out) 2751 } 2752 2753 got, err := os.ReadFile(ofile) 2754 if err != nil { 2755 t.Fatalf("could not read C++ ROOT scan file %q: %+v\noutput:\n%s", ofile, err, out) 2756 } 2757 2758 if got, want := string(got), tc.cxx; got != want { 2759 t.Fatalf("invalid ROOT scan:\ngot:\n%v\nwant:\n%v\noutput:\n%s", got, want, out) 2760 } 2761 } 2762 }) 2763 } 2764 } 2765 2766 func TestTreeWriteSubdir(t *testing.T) { 2767 tmp, err := os.MkdirTemp("", "groot-rtree-") 2768 if err != nil { 2769 t.Fatalf("could not create dir: %v", err) 2770 } 2771 defer os.RemoveAll(tmp) 2772 2773 fname := filepath.Join(tmp, "tree-subdir.root") 2774 2775 f, err := riofs.Create(fname) 2776 if err != nil { 2777 t.Fatalf("%+v", err) 2778 } 2779 defer f.Close() 2780 2781 dir, err := riofs.Dir(f).Mkdir("dir-1/dir-11/dir-111") 2782 if err != nil { 2783 t.Fatalf("could not create sub-dir hierarchy: %+v", err) 2784 } 2785 2786 var data struct { 2787 I32 int32 `groot:"i32"` 2788 F64 float64 `groot:"f64"` 2789 } 2790 2791 ntup, err := NewWriter(dir, "ntup", WriteVarsFromStruct(&data)) 2792 if err != nil { 2793 t.Fatalf("could not create tree: %+v", err) 2794 } 2795 defer ntup.Close() 2796 2797 for i := range 5 { 2798 data.I32 = int32(i) 2799 data.F64 = float64(i) 2800 _, err = ntup.Write() 2801 if err != nil { 2802 t.Fatalf("could not write event %d: %+v", i, err) 2803 } 2804 } 2805 2806 err = ntup.Close() 2807 if err != nil { 2808 t.Fatalf("could not close tree: %+v", err) 2809 } 2810 2811 err = f.Close() 2812 if err != nil { 2813 t.Fatalf("could not close file: %+v", err) 2814 } 2815 2816 if !rtests.HasROOT { 2817 return 2818 } 2819 2820 code := `#include <iostream> 2821 #include "TDirectory.h" 2822 #include "TFile.h" 2823 #include "TTree.h" 2824 #include "TTreePlayer.h" 2825 2826 void scan(const char *fname, const char *tree, const char *oname) { 2827 auto f = TFile::Open(fname); 2828 gDirectory->cd("dir-1"); 2829 gDirectory->cd("dir-11"); 2830 gDirectory->cd("dir-111"); 2831 2832 auto t = (TTree*)gDirectory->Get(tree); 2833 if (!t) { 2834 std::cerr << "could not fetch TTree [" << tree << "] from file [" << fname << "]\n"; 2835 exit(1); 2836 } 2837 auto player = dynamic_cast<TTreePlayer*>(t->GetPlayer()); 2838 player->SetScanRedirect(kTRUE); 2839 player->SetScanFileName(oname); 2840 t->SetScanField(0); 2841 t->Scan("i32:f64"); 2842 } 2843 ` 2844 ofile := filepath.Join(tmp, "tree-subdir.txt") 2845 out, err := rtests.RunCxxROOT("scan", []byte(code), fname, "ntup", ofile) 2846 if err != nil { 2847 t.Fatalf("could not run C++ ROOT: %+v\noutput:\n%s", err, out) 2848 } 2849 2850 got, err := os.ReadFile(ofile) 2851 if err != nil { 2852 t.Fatalf("could not read C++ ROOT scan file %q: %+v\noutput:\n%s", ofile, err, out) 2853 } 2854 2855 want := `************************************ 2856 * Row * i32 * f64 * 2857 ************************************ 2858 * 0 * 0 * 0 * 2859 * 1 * 1 * 1 * 2860 * 2 * 2 * 2 * 2861 * 3 * 3 * 3 * 2862 * 4 * 4 * 4 * 2863 ************************************ 2864 ` 2865 if got, want := string(got), want; got != want { 2866 t.Fatalf("invalid ROOT scan:\ngot:\n%v\nwant:\n%v\noutput:\n%s", got, want, out) 2867 } 2868 2869 } 2870 2871 var sumBenchReadTreeF64 = 0.0 2872 2873 func BenchmarkReadTreeF64(b *testing.B) { 2874 tmp, err := os.MkdirTemp("", "groot-rtree-read-tree-f64-") 2875 if err != nil { 2876 b.Fatal(err) 2877 } 2878 defer os.RemoveAll(tmp) 2879 2880 const nevts = 10000 2881 2882 fname := path.Join(tmp, "f64.root") 2883 func() { 2884 b.StopTimer() 2885 defer b.StartTimer() 2886 2887 f, err := riofs.Create(fname, riofs.WithoutCompression()) 2888 if err != nil { 2889 b.Fatal(err) 2890 } 2891 defer f.Close() 2892 2893 var data struct { 2894 F64 float64 2895 } 2896 wvars := []WriteVar{ 2897 {Name: "F64", Value: &data.F64}, 2898 } 2899 tree, err := NewWriter(f, "tree", wvars, WithoutCompression()) 2900 if err != nil { 2901 b.Fatal(err) 2902 } 2903 defer tree.Close() 2904 2905 rnd := rand.New(rand.NewSource(1234)) 2906 for range nevts { 2907 data.F64 = rnd.Float64() * 10 2908 2909 _, err = tree.Write() 2910 if err != nil { 2911 b.Fatal(err) 2912 } 2913 } 2914 2915 err = tree.Close() 2916 if err != nil { 2917 b.Fatal(err) 2918 } 2919 2920 err = f.Close() 2921 if err != nil { 2922 b.Fatal(err) 2923 } 2924 }() 2925 2926 b.StopTimer() 2927 f, err := riofs.Open(fname) 2928 if err != nil { 2929 b.Fatal(err) 2930 } 2931 defer f.Close() 2932 2933 o, err := f.Get("tree") 2934 if err != nil { 2935 b.Fatal(err) 2936 } 2937 2938 tree := o.(Tree) 2939 2940 var data struct { 2941 F64 float64 2942 } 2943 2944 rvars := ReadVarsFromStruct(&data) 2945 r, err := NewReader(tree, rvars) 2946 if err != nil { 2947 b.Fatal(err) 2948 } 2949 defer r.Close() 2950 2951 b.StartTimer() 2952 b.ReportAllocs() 2953 b.ResetTimer() 2954 2955 for i := 0; i < b.N; i++ { 2956 b.StopTimer() 2957 r.r.reset() 2958 b.StartTimer() 2959 2960 err = r.Read(func(RCtx) error { 2961 sumBenchReadTreeF64 += data.F64 2962 return nil 2963 }) 2964 if err != nil { 2965 b.Fatal(err) 2966 } 2967 } 2968 } 2969 2970 var sumBenchReadTreeSliF64 = 0 2971 2972 func BenchmarkReadTreeSliF64(b *testing.B) { 2973 tmp, err := os.MkdirTemp("", "groot-rtree-read-tree-sli-f64s-") 2974 if err != nil { 2975 b.Fatal(err) 2976 } 2977 defer os.RemoveAll(tmp) 2978 2979 const nevts = 1000 2980 2981 for _, sz := range []int{0, 1, 2, 4, 8, 16, 64, 128, 512, 1024, 1024 * 1024} { 2982 fname := path.Join(tmp, fmt.Sprintf("f64s-%d.root", sz)) 2983 func() { 2984 b.StopTimer() 2985 defer b.StartTimer() 2986 2987 f, err := riofs.Create(fname, riofs.WithoutCompression()) 2988 if err != nil { 2989 b.Fatal(err) 2990 } 2991 defer f.Close() 2992 2993 var data struct { 2994 N int32 2995 Sli []float64 2996 } 2997 wvars := []WriteVar{ 2998 {Name: "N", Value: &data.N}, 2999 {Name: "Sli", Value: &data.Sli, Count: "N"}, 3000 } 3001 tree, err := NewWriter(f, "tree", wvars, WithoutCompression()) 3002 if err != nil { 3003 b.Fatal(err) 3004 } 3005 defer tree.Close() 3006 3007 rnd := rand.New(rand.NewSource(1234)) 3008 for range nevts { 3009 data.N = int32(rnd.Float64() * 100) 3010 data.Sli = make([]float64, int(data.N)) 3011 for j := range data.Sli { 3012 data.Sli[j] = rnd.Float64() * 10 3013 } 3014 3015 _, err = tree.Write() 3016 if err != nil { 3017 b.Fatal(err) 3018 } 3019 } 3020 3021 err = tree.Close() 3022 if err != nil { 3023 b.Fatal(err) 3024 } 3025 3026 err = f.Close() 3027 if err != nil { 3028 b.Fatal(err) 3029 } 3030 }() 3031 3032 b.Run(fmt.Sprintf("%d", sz), func(b *testing.B) { 3033 b.StopTimer() 3034 f, err := riofs.Open(fname) 3035 if err != nil { 3036 b.Fatal(err) 3037 } 3038 defer f.Close() 3039 3040 o, err := f.Get("tree") 3041 if err != nil { 3042 b.Fatal(err) 3043 } 3044 3045 tree := o.(Tree) 3046 3047 var data struct { 3048 N int32 3049 Sli []float64 3050 } 3051 3052 rvars := ReadVarsFromStruct(&data) 3053 r, err := NewReader(tree, rvars) 3054 if err != nil { 3055 b.Fatal(err) 3056 } 3057 defer r.Close() 3058 3059 b.StartTimer() 3060 b.ReportAllocs() 3061 b.ResetTimer() 3062 3063 for i := 0; i < b.N; i++ { 3064 b.StopTimer() 3065 r.r.reset() 3066 data.N = 0 3067 data.Sli = data.Sli[:0] 3068 b.StartTimer() 3069 3070 err = r.Read(func(RCtx) error { 3071 sumBenchReadTreeSliF64 += len(data.Sli) 3072 return nil 3073 }) 3074 if err != nil { 3075 b.Fatal(err) 3076 } 3077 } 3078 }) 3079 } 3080 } 3081 3082 type TNestedStruct1 struct { 3083 RunNbr int64 `groot:"runnbr"` 3084 EvtNbr int64 `groot:"evtnbr"` 3085 P3 TNestedStruct1P3 `groot:"p3"` 3086 } 3087 3088 type TNestedStruct1P3 struct { 3089 Px float64 `groot:"px"` 3090 Py float64 `groot:"py"` 3091 Pz float64 `groot:"pz"` 3092 } 3093 3094 type TNestedStruct2 struct { 3095 RunNbr int64 `groot:"runnbr"` 3096 EvtNbr int64 `groot:"evtnbr"` 3097 P3 TNestedStruct1P3 `groot:"p3"` 3098 F32s []float32 `groot:"f32s"` 3099 } 3100 3101 type TNestedStruct3 struct { 3102 RunNbr int64 `groot:"runnbr"` 3103 EvtNbr int64 `groot:"evtnbr"` 3104 P3 TNestedStruct1P3 `groot:"p3"` 3105 F32s []float32 `groot:"f32s"` 3106 } 3107 3108 type TNestedP2 struct { 3109 Px float64 `groot:"px"` 3110 Py float32 `groot:"py"` 3111 } 3112 3113 type TNestedEvent1 struct { 3114 B bool `groot:"Bool"` 3115 Str string `groot:"Str"` 3116 I8 int8 `groot:"I8"` 3117 I16 int16 `groot:"I16"` 3118 I32 int32 `groot:"I32"` 3119 I64 int64 `groot:"I64"` 3120 U8 uint8 `groot:"U8"` 3121 U16 uint16 `groot:"U16"` 3122 U32 uint32 `groot:"U32"` 3123 U64 uint64 `groot:"U64"` 3124 F32 float32 `groot:"F32"` 3125 F64 float64 `groot:"F64"` 3126 D16 root.Float16 `groot:"D16"` 3127 D32 root.Double32 `groot:"D32"` 3128 P2 TNestedP2 `groot:"P2"` 3129 Obj rbase.ObjString `groot:"Obj"` 3130 3131 ArrBs [10]bool `groot:"ArrBs[10]"` 3132 //ArrStr [10]string `groot:"ArrStr[10]"` 3133 ArrI8 [10]int8 `groot:"ArrI8[10]"` 3134 ArrI16 [10]int16 `groot:"ArrI16[10]"` 3135 ArrI32 [10]int32 `groot:"ArrI32[10]"` 3136 ArrI64 [10]int64 `groot:"ArrI64[10]"` 3137 ArrU8 [10]uint8 `groot:"ArrU8[10]"` 3138 ArrU16 [10]uint16 `groot:"ArrU16[10]"` 3139 ArrU32 [10]uint32 `groot:"ArrU32[10]"` 3140 ArrU64 [10]uint64 `groot:"ArrU64[10]"` 3141 ArrF32 [10]float32 `groot:"ArrF32[10]"` 3142 ArrF64 [10]float64 `groot:"ArrF64[10]"` 3143 ArrD16 [10]root.Float16 `groot:"ArrD16[10]"` 3144 ArrD32 [10]root.Double32 `groot:"ArrD32[10]"` 3145 ArrP2 [10]TNestedP2 `groot:"ArrP2[10]"` 3146 ArrObj [10]rbase.ObjString `groot:"ArrObj[10]"` 3147 3148 N int32 `groot:"N"` 3149 SliBs []bool `groot:"SliBs[N]"` 3150 // SliStr []string `groot:"SliStr[N]"` 3151 SliI8 []int8 `groot:"SliI8[N]"` 3152 SliI16 []int16 `groot:"SliI16[N]"` 3153 SliI32 []int32 `groot:"SliI32[N]"` 3154 SliI64 []int64 `groot:"SliI64[N]"` 3155 SliU8 []uint8 `groot:"SliU8[N]"` 3156 SliU16 []uint16 `groot:"SliU16[N]"` 3157 SliU32 []uint32 `groot:"SliU32[N]"` 3158 SliU64 []uint64 `groot:"SliU64[N]"` 3159 SliF32 []float32 `groot:"SliF32[N]"` 3160 SliF64 []float64 `groot:"SliF64[N]"` 3161 SliD16 []root.Float16 `groot:"SliD16[N]"` 3162 SliD32 []root.Double32 `groot:"SliD32[N]"` 3163 // SliP2 []TNestedP2 `groot:"SliP2[N]"` // FIXME(sbinet): var-len-array of non-builtins has extra bytes in front 3164 // SliObj []rbase.ObjString `groot:"SliObj[N]"` // FIXME(sbinet): var-len-array of non-builtins has extra bytes in front 3165 3166 StdVecBs []bool `groot:"StdVecBs"` 3167 StdVecStr []string `groot:"StdVecStr"` 3168 StdVecI8 []int8 `groot:"StdVecI8"` 3169 StdVecI16 []int16 `groot:"StdVecI16"` 3170 StdVecI32 []int32 `groot:"StdVecI32"` 3171 StdVecI64 []int64 `groot:"StdVecI64"` 3172 StdVecU8 []uint8 `groot:"StdVecU8"` 3173 StdVecU16 []uint16 `groot:"StdVecU16"` 3174 StdVecU32 []uint32 `groot:"StdVecU32"` 3175 StdVecU64 []uint64 `groot:"StdVecU64"` 3176 StdVecF32 []float32 `groot:"StdVecF32"` 3177 StdVecF64 []float64 `groot:"StdVecF64"` 3178 StdVecD16 []root.Float16 `groot:"StdVecD16"` 3179 StdVecD32 []root.Double32 `groot:"StdVecD32"` 3180 StdVecP2 []TNestedP2 `groot:"StdVecP2"` 3181 StdVecObj []rbase.ObjString `groot:"StdVecObj"` 3182 3183 StdVecVecF64 [][]float64 `groot:"StdVecVecF64"` 3184 StdVecVecStr [][]string `groot:"StdVecVecStr"` 3185 StdVecVecP2 [][]TNestedP2 `groot:"StdVecVecP2"` 3186 } 3187 3188 func (TNestedEvent1) want(i int64) (data TNestedEvent1) { 3189 data.B = i%2 == 0 3190 data.Str = fmt.Sprintf("str-%03d", i) 3191 data.I8 = int8(-i) 3192 data.I16 = int16(-i) 3193 data.I32 = int32(-i) 3194 data.I64 = int64(-i) 3195 data.U8 = uint8(i) 3196 data.U16 = uint16(i) 3197 data.U32 = uint32(i) 3198 data.U64 = uint64(i) 3199 data.F32 = float32(i) 3200 data.F64 = float64(i) 3201 data.D16 = root.Float16(i) 3202 data.D32 = root.Double32(i) 3203 data.P2 = TNestedP2{Px: float64(i), Py: float32(i)} 3204 data.Obj = *rbase.NewObjString(fmt.Sprintf("obj-%d", i)) 3205 3206 for ii := range data.ArrI32 { 3207 data.ArrBs[ii] = ii == int(i) 3208 //data.ArrStr[ii] = fmt.Sprintf("arr-%03d", i) 3209 data.ArrI8[ii] = int8(-i) 3210 data.ArrI16[ii] = int16(-i) 3211 data.ArrI32[ii] = int32(-i) 3212 data.ArrI64[ii] = int64(-i) 3213 data.ArrU8[ii] = uint8(i) 3214 data.ArrU16[ii] = uint16(i) 3215 data.ArrU32[ii] = uint32(i) 3216 data.ArrU64[ii] = uint64(i) 3217 data.ArrF32[ii] = float32(i) 3218 data.ArrF64[ii] = float64(i) 3219 data.ArrD16[ii] = root.Float16(i) 3220 data.ArrD32[ii] = root.Double32(i) 3221 data.ArrP2[ii] = TNestedP2{ 3222 Px: float64(i), 3223 Py: float32(i), 3224 } 3225 data.ArrObj[ii] = *rbase.NewObjString(fmt.Sprintf("obj-%d", i)) 3226 } 3227 data.N = int32(i) % 10 3228 3229 switch data.N { 3230 case 0: 3231 data.SliBs = nil 3232 // data.SliStr = nil 3233 data.SliI8 = nil 3234 data.SliI16 = nil 3235 data.SliI32 = nil 3236 data.SliI64 = nil 3237 data.SliU8 = nil 3238 data.SliU16 = nil 3239 data.SliU32 = nil 3240 data.SliU64 = nil 3241 data.SliF32 = nil 3242 data.SliF64 = nil 3243 data.SliD16 = nil 3244 data.SliD32 = nil 3245 // data.SliP2 = nil 3246 // data.SliObj = nil 3247 default: 3248 data.SliBs = make([]bool, int(data.N)) 3249 // data.SliStr = make([]string, int(data.N)) 3250 data.SliI8 = make([]int8, int(data.N)) 3251 data.SliI16 = make([]int16, int(data.N)) 3252 data.SliI32 = make([]int32, int(data.N)) 3253 data.SliI64 = make([]int64, int(data.N)) 3254 data.SliU8 = make([]uint8, int(data.N)) 3255 data.SliU16 = make([]uint16, int(data.N)) 3256 data.SliU32 = make([]uint32, int(data.N)) 3257 data.SliU64 = make([]uint64, int(data.N)) 3258 data.SliF32 = make([]float32, int(data.N)) 3259 data.SliF64 = make([]float64, int(data.N)) 3260 data.SliD16 = make([]root.Float16, int(data.N)) 3261 data.SliD32 = make([]root.Double32, int(data.N)) 3262 // data.SliP2 = make([]TNestedP2, int(data.N)) 3263 // data.SliObj = make([]rbase.ObjString, int(data.N)) 3264 } 3265 for ii := range int(data.N) { 3266 data.SliBs[ii] = (ii + 1) == int(i) 3267 // data.SliStr[ii] = fmt.Sprintf("sli-%03d", i) 3268 data.SliI8[ii] = int8(-i) 3269 data.SliI16[ii] = int16(-i) 3270 data.SliI32[ii] = int32(-i) 3271 data.SliI64[ii] = int64(-i) 3272 data.SliU8[ii] = uint8(i) 3273 data.SliU16[ii] = uint16(i) 3274 data.SliU32[ii] = uint32(i) 3275 data.SliU64[ii] = uint64(i) 3276 data.SliF32[ii] = float32(i) 3277 data.SliF64[ii] = float64(i) 3278 data.SliD16[ii] = root.Float16(i) 3279 data.SliD32[ii] = root.Double32(i) 3280 // data.SliP2[ii] = TNestedP2{ 3281 // Px: float64(i), 3282 // Py: float32(i), 3283 // } 3284 // data.SliObj[ii] = *rbase.NewObjString(fmt.Sprintf("obj-%03d", i)) 3285 } 3286 3287 switch data.N { 3288 case 0: 3289 data.StdVecBs = nil 3290 data.StdVecStr = nil 3291 data.StdVecI8 = nil 3292 data.StdVecI16 = nil 3293 data.StdVecI32 = nil 3294 data.StdVecI64 = nil 3295 data.StdVecU8 = nil 3296 data.StdVecU16 = nil 3297 data.StdVecU32 = nil 3298 data.StdVecU64 = nil 3299 data.StdVecF32 = nil 3300 data.StdVecF64 = nil 3301 data.StdVecD16 = nil 3302 data.StdVecD32 = nil 3303 data.StdVecP2 = nil 3304 data.StdVecObj = nil 3305 default: 3306 data.StdVecBs = make([]bool, int(data.N)) 3307 data.StdVecStr = make([]string, int(data.N)) 3308 data.StdVecI8 = make([]int8, int(data.N)) 3309 data.StdVecI16 = make([]int16, int(data.N)) 3310 data.StdVecI32 = make([]int32, int(data.N)) 3311 data.StdVecI64 = make([]int64, int(data.N)) 3312 data.StdVecU8 = make([]uint8, int(data.N)) 3313 data.StdVecU16 = make([]uint16, int(data.N)) 3314 data.StdVecU32 = make([]uint32, int(data.N)) 3315 data.StdVecU64 = make([]uint64, int(data.N)) 3316 data.StdVecF32 = make([]float32, int(data.N)) 3317 data.StdVecF64 = make([]float64, int(data.N)) 3318 data.StdVecD16 = make([]root.Float16, int(data.N)) 3319 data.StdVecD32 = make([]root.Double32, int(data.N)) 3320 data.StdVecP2 = make([]TNestedP2, int(data.N)) 3321 data.StdVecObj = make([]rbase.ObjString, int(data.N)) 3322 } 3323 for ii := range int(data.N) { 3324 data.StdVecBs[ii] = (ii + 1) == int(i) 3325 data.StdVecStr[ii] = fmt.Sprintf("std-%03d", i) 3326 data.StdVecI8[ii] = int8(-i) 3327 data.StdVecI16[ii] = int16(-i) 3328 data.StdVecI32[ii] = int32(-i) 3329 data.StdVecI64[ii] = int64(-i) 3330 data.StdVecU8[ii] = uint8(i) 3331 data.StdVecU16[ii] = uint16(i) 3332 data.StdVecU32[ii] = uint32(i) 3333 data.StdVecU64[ii] = uint64(i) 3334 data.StdVecF32[ii] = float32(i) 3335 data.StdVecF64[ii] = float64(i) 3336 data.StdVecD16[ii] = root.Float16(i) 3337 data.StdVecD32[ii] = root.Double32(i) 3338 data.StdVecP2[ii] = TNestedP2{ 3339 Px: float64(i), 3340 Py: float32(i), 3341 } 3342 data.StdVecObj[ii] = *rbase.NewObjString(fmt.Sprintf("obj-%03d", i)) 3343 } 3344 3345 switch data.N { 3346 case 0: 3347 data.StdVecVecF64 = nil 3348 data.StdVecVecStr = nil 3349 data.StdVecVecP2 = nil 3350 default: 3351 data.StdVecVecF64 = make([][]float64, data.N) 3352 data.StdVecVecStr = make([][]string, data.N) 3353 data.StdVecVecP2 = make([][]TNestedP2, data.N) 3354 } 3355 for ii := range int(data.N) { 3356 data.StdVecVecF64[ii] = []float64{ 3357 float64(ii), 3358 float64(ii + 1), 3359 float64(ii + 2), 3360 float64(ii + 3), 3361 } 3362 data.StdVecVecStr[ii] = []string{ 3363 fmt.Sprintf("vec-%03d", i), 3364 fmt.Sprintf("vec-%03d", i+1), 3365 fmt.Sprintf("vec-%03d", i+2), 3366 fmt.Sprintf("vec-%03d", i+3), 3367 } 3368 data.StdVecVecP2[ii] = []TNestedP2{ 3369 {Px: float64(i), Py: float32(i)}, 3370 {Px: float64(i + 1), Py: float32(i + 1)}, 3371 {Px: float64(i + 2), Py: float32(i + 2)}, 3372 {Px: float64(i + 3), Py: float32(i + 3)}, 3373 } 3374 } 3375 3376 return data 3377 }