go-hep.org/x/hep@v0.38.1/groot/rtree/writer_example_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_test 6 7 import ( 8 "bytes" 9 "compress/flate" 10 "fmt" 11 "log" 12 "reflect" 13 14 "go-hep.org/x/hep/groot" 15 "go-hep.org/x/hep/groot/rcmd" 16 "go-hep.org/x/hep/groot/rdict" 17 "go-hep.org/x/hep/groot/rtree" 18 ) 19 20 func Example_createFlatNtuple() { 21 type Data struct { 22 I32 int32 23 F64 float64 24 Str string 25 ArrF64 [5]float64 26 N int32 27 SliF64 []float64 28 } 29 const ( 30 fname = "../testdata/groot-flat-ntuple.root" 31 nevts = 5 32 ) 33 func() { 34 f, err := groot.Create(fname) 35 if err != nil { 36 log.Fatalf("%+v", err) 37 } 38 defer f.Close() 39 40 var evt Data 41 42 wvars := []rtree.WriteVar{ 43 {Name: "I32", Value: &evt.I32}, 44 {Name: "F64", Value: &evt.F64}, 45 {Name: "Str", Value: &evt.Str}, 46 {Name: "ArrF64", Value: &evt.ArrF64}, 47 {Name: "N", Value: &evt.N}, 48 {Name: "SliF64", Value: &evt.SliF64, Count: "N"}, 49 } 50 tree, err := rtree.NewWriter(f, "mytree", wvars) 51 if err != nil { 52 log.Fatalf("could not create tree writer: %+v", err) 53 } 54 defer tree.Close() 55 56 fmt.Printf("-- created tree %q:\n", tree.Name()) 57 for i, b := range tree.Branches() { 58 fmt.Printf("branch[%d]: name=%q, title=%q\n", i, b.Name(), b.Title()) 59 } 60 61 for i := range nevts { 62 evt.I32 = int32(i) 63 evt.F64 = float64(i) 64 evt.Str = fmt.Sprintf("evt-%0d", i) 65 evt.ArrF64 = [5]float64{float64(i), float64(i + 1), float64(i + 2), float64(i + 3), float64(i + 4)} 66 evt.N = int32(i) 67 evt.SliF64 = []float64{float64(i), float64(i + 1), float64(i + 2), float64(i + 3), float64(i + 4)}[:i] 68 _, err = tree.Write() 69 if err != nil { 70 log.Fatalf("could not write event %d: %+v", i, err) 71 } 72 } 73 fmt.Printf("-- filled tree with %d entries\n", tree.Entries()) 74 75 err = tree.Close() 76 if err != nil { 77 log.Fatalf("could not write tree: %+v", err) 78 } 79 80 err = f.Close() 81 if err != nil { 82 log.Fatalf("could not close tree: %+v", err) 83 } 84 }() 85 86 func() { 87 fmt.Printf("-- read back ROOT file\n") 88 f, err := groot.Open(fname) 89 if err != nil { 90 log.Fatalf("could not open ROOT file: %+v", err) 91 } 92 defer f.Close() 93 94 obj, err := f.Get("mytree") 95 if err != nil { 96 log.Fatalf("%+v", err) 97 } 98 99 tree := obj.(rtree.Tree) 100 101 var data Data 102 r, err := rtree.NewReader(tree, rtree.ReadVarsFromStruct(&data)) 103 if err != nil { 104 log.Fatal(err) 105 } 106 defer r.Close() 107 108 err = r.Read(func(ctx rtree.RCtx) error { 109 fmt.Printf("entry[%d]: %+v\n", ctx.Entry, data) 110 return nil 111 }) 112 113 if err != nil { 114 log.Fatal(err) 115 } 116 }() 117 118 // Output: 119 // -- created tree "mytree": 120 // branch[0]: name="I32", title="I32/I" 121 // branch[1]: name="F64", title="F64/D" 122 // branch[2]: name="Str", title="Str/C" 123 // branch[3]: name="ArrF64", title="ArrF64[5]/D" 124 // branch[4]: name="N", title="N/I" 125 // branch[5]: name="SliF64", title="SliF64[N]/D" 126 // -- filled tree with 5 entries 127 // -- read back ROOT file 128 // entry[0]: {I32:0 F64:0 Str:evt-0 ArrF64:[0 1 2 3 4] N:0 SliF64:[]} 129 // entry[1]: {I32:1 F64:1 Str:evt-1 ArrF64:[1 2 3 4 5] N:1 SliF64:[1]} 130 // entry[2]: {I32:2 F64:2 Str:evt-2 ArrF64:[2 3 4 5 6] N:2 SliF64:[2 3]} 131 // entry[3]: {I32:3 F64:3 Str:evt-3 ArrF64:[3 4 5 6 7] N:3 SliF64:[3 4 5]} 132 // entry[4]: {I32:4 F64:4 Str:evt-4 ArrF64:[4 5 6 7 8] N:4 SliF64:[4 5 6 7]} 133 } 134 135 func Example_createFlatNtupleWithLZMA() { 136 type Data struct { 137 I32 int32 138 F64 float64 139 Str string 140 ArrF64 [5]float64 141 N int32 142 SliF64 []float64 143 } 144 const ( 145 fname = "../testdata/groot-flat-ntuple-with-lzma.root" 146 nevts = 5 147 ) 148 func() { 149 f, err := groot.Create(fname) 150 if err != nil { 151 log.Fatalf("%+v", err) 152 } 153 defer f.Close() 154 155 var evt Data 156 157 wvars := []rtree.WriteVar{ 158 {Name: "I32", Value: &evt.I32}, 159 {Name: "F64", Value: &evt.F64}, 160 {Name: "Str", Value: &evt.Str}, 161 {Name: "ArrF64", Value: &evt.ArrF64}, 162 {Name: "N", Value: &evt.N}, 163 {Name: "SliF64", Value: &evt.SliF64, Count: "N"}, 164 } 165 tree, err := rtree.NewWriter(f, "mytree", wvars, rtree.WithLZMA(flate.BestCompression), rtree.WithBasketSize(32*1024)) 166 if err != nil { 167 log.Fatalf("could not create tree writer: %+v", err) 168 } 169 defer tree.Close() 170 171 fmt.Printf("-- created tree %q:\n", tree.Name()) 172 for i, b := range tree.Branches() { 173 fmt.Printf("branch[%d]: name=%q, title=%q\n", i, b.Name(), b.Title()) 174 } 175 176 for i := range nevts { 177 evt.I32 = int32(i) 178 evt.F64 = float64(i) 179 evt.Str = fmt.Sprintf("evt-%0d", i) 180 evt.ArrF64 = [5]float64{float64(i), float64(i + 1), float64(i + 2), float64(i + 3), float64(i + 4)} 181 evt.N = int32(i) 182 evt.SliF64 = []float64{float64(i), float64(i + 1), float64(i + 2), float64(i + 3), float64(i + 4)}[:i] 183 _, err = tree.Write() 184 if err != nil { 185 log.Fatalf("could not write event %d: %+v", i, err) 186 } 187 } 188 fmt.Printf("-- filled tree with %d entries\n", tree.Entries()) 189 190 err = tree.Close() 191 if err != nil { 192 log.Fatalf("could not write tree: %+v", err) 193 } 194 195 err = f.Close() 196 if err != nil { 197 log.Fatalf("could not close tree: %+v", err) 198 } 199 }() 200 201 func() { 202 fmt.Printf("-- read back ROOT file\n") 203 f, err := groot.Open(fname) 204 if err != nil { 205 log.Fatalf("could not open ROOT file: %+v", err) 206 } 207 defer f.Close() 208 209 obj, err := f.Get("mytree") 210 if err != nil { 211 log.Fatalf("%+v", err) 212 } 213 214 tree := obj.(rtree.Tree) 215 216 var data Data 217 r, err := rtree.NewReader(tree, rtree.ReadVarsFromStruct(&data)) 218 if err != nil { 219 log.Fatal(err) 220 } 221 defer r.Close() 222 223 err = r.Read(func(ctx rtree.RCtx) error { 224 fmt.Printf("entry[%d]: %+v\n", ctx.Entry, data) 225 return nil 226 }) 227 228 if err != nil { 229 log.Fatal(err) 230 } 231 }() 232 233 // Output: 234 // -- created tree "mytree": 235 // branch[0]: name="I32", title="I32/I" 236 // branch[1]: name="F64", title="F64/D" 237 // branch[2]: name="Str", title="Str/C" 238 // branch[3]: name="ArrF64", title="ArrF64[5]/D" 239 // branch[4]: name="N", title="N/I" 240 // branch[5]: name="SliF64", title="SliF64[N]/D" 241 // -- filled tree with 5 entries 242 // -- read back ROOT file 243 // entry[0]: {I32:0 F64:0 Str:evt-0 ArrF64:[0 1 2 3 4] N:0 SliF64:[]} 244 // entry[1]: {I32:1 F64:1 Str:evt-1 ArrF64:[1 2 3 4 5] N:1 SliF64:[1]} 245 // entry[2]: {I32:2 F64:2 Str:evt-2 ArrF64:[2 3 4 5 6] N:2 SliF64:[2 3]} 246 // entry[3]: {I32:3 F64:3 Str:evt-3 ArrF64:[3 4 5 6 7] N:3 SliF64:[3 4 5]} 247 // entry[4]: {I32:4 F64:4 Str:evt-4 ArrF64:[4 5 6 7 8] N:4 SliF64:[4 5 6 7]} 248 } 249 250 func Example_createFlatNtupleFromStruct() { 251 type Data struct { 252 I32 int32 253 F64 float64 254 Str string 255 ArrF64 [5]float64 256 N int32 257 SliF64 []float64 `groot:"SliF64[N]"` 258 } 259 const ( 260 fname = "../testdata/groot-flat-ntuple-with-struct.root" 261 nevts = 5 262 ) 263 func() { 264 f, err := groot.Create(fname) 265 if err != nil { 266 log.Fatalf("%+v", err) 267 } 268 defer f.Close() 269 270 var evt Data 271 272 tree, err := rtree.NewWriter(f, "mytree", rtree.WriteVarsFromStruct(&evt)) 273 if err != nil { 274 log.Fatalf("could not create tree writer: %+v", err) 275 } 276 defer tree.Close() 277 278 fmt.Printf("-- created tree %q:\n", tree.Name()) 279 for i, b := range tree.Branches() { 280 fmt.Printf("branch[%d]: name=%q, title=%q\n", i, b.Name(), b.Title()) 281 } 282 283 for i := range nevts { 284 evt.I32 = int32(i) 285 evt.F64 = float64(i) 286 evt.Str = fmt.Sprintf("evt-%0d", i) 287 evt.ArrF64 = [5]float64{float64(i), float64(i + 1), float64(i + 2), float64(i + 3), float64(i + 4)} 288 evt.N = int32(i) 289 evt.SliF64 = []float64{float64(i), float64(i + 1), float64(i + 2), float64(i + 3), float64(i + 4)}[:i] 290 _, err = tree.Write() 291 if err != nil { 292 log.Fatalf("could not write event %d: %+v", i, err) 293 } 294 } 295 fmt.Printf("-- filled tree with %d entries\n", tree.Entries()) 296 297 err = tree.Close() 298 if err != nil { 299 log.Fatalf("could not write tree: %+v", err) 300 } 301 302 err = f.Close() 303 if err != nil { 304 log.Fatalf("could not close tree: %+v", err) 305 } 306 }() 307 308 func() { 309 fmt.Printf("-- read back ROOT file\n") 310 f, err := groot.Open(fname) 311 if err != nil { 312 log.Fatalf("could not open ROOT file: %+v", err) 313 } 314 defer f.Close() 315 316 obj, err := f.Get("mytree") 317 if err != nil { 318 log.Fatalf("%+v", err) 319 } 320 321 tree := obj.(rtree.Tree) 322 323 var data Data 324 r, err := rtree.NewReader(tree, rtree.ReadVarsFromStruct(&data)) 325 if err != nil { 326 log.Fatal(err) 327 } 328 defer r.Close() 329 330 err = r.Read(func(ctx rtree.RCtx) error { 331 fmt.Printf("entry[%d]: %+v\n", ctx.Entry, data) 332 return nil 333 }) 334 335 if err != nil { 336 log.Fatal(err) 337 } 338 }() 339 340 // Output: 341 // -- created tree "mytree": 342 // branch[0]: name="I32", title="I32/I" 343 // branch[1]: name="F64", title="F64/D" 344 // branch[2]: name="Str", title="Str/C" 345 // branch[3]: name="ArrF64", title="ArrF64[5]/D" 346 // branch[4]: name="N", title="N/I" 347 // branch[5]: name="SliF64", title="SliF64[N]/D" 348 // -- filled tree with 5 entries 349 // -- read back ROOT file 350 // entry[0]: {I32:0 F64:0 Str:evt-0 ArrF64:[0 1 2 3 4] N:0 SliF64:[]} 351 // entry[1]: {I32:1 F64:1 Str:evt-1 ArrF64:[1 2 3 4 5] N:1 SliF64:[1]} 352 // entry[2]: {I32:2 F64:2 Str:evt-2 ArrF64:[2 3 4 5 6] N:2 SliF64:[2 3]} 353 // entry[3]: {I32:3 F64:3 Str:evt-3 ArrF64:[3 4 5 6 7] N:3 SliF64:[3 4 5]} 354 // entry[4]: {I32:4 F64:4 Str:evt-4 ArrF64:[4 5 6 7 8] N:4 SliF64:[4 5 6 7]} 355 } 356 357 func Example_createEventNtupleNoSplit() { 358 type P4 struct { 359 Px float64 `groot:"px"` 360 Py float64 `groot:"py"` 361 Pz float64 `groot:"pz"` 362 E float64 `groot:"ene"` 363 } 364 365 type Particle struct { 366 ID int32 `groot:"id"` 367 P4 P4 `groot:"p4"` 368 } 369 370 type Event struct { 371 I32 int32 `groot:"i32"` 372 F64 float64 `groot:"f64"` 373 Str string `groot:"str"` 374 Arr [5]float64 `groot:"arr"` 375 Sli []float64 `groot:"sli"` 376 P4 P4 `groot:"p4"` 377 Ps []Particle `groot:"mc"` 378 } 379 380 // register streamers 381 for _, typ := range []reflect.Type{ 382 reflect.TypeOf(P4{}), 383 reflect.TypeOf(Particle{}), 384 reflect.TypeOf(Event{}), 385 } { 386 387 rdict.StreamerInfos.Add(rdict.StreamerOf( 388 rdict.StreamerInfos, 389 typ, 390 )) 391 } 392 393 const ( 394 fname = "../testdata/groot-event-ntuple-nosplit.root" 395 nevts = 5 396 ) 397 398 func() { 399 f, err := groot.Create(fname) 400 if err != nil { 401 log.Fatalf("could not create ROOT file: %+v", err) 402 } 403 defer f.Close() 404 405 var ( 406 evt Event 407 wvars = []rtree.WriteVar{ 408 {Name: "evt", Value: &evt}, 409 } 410 ) 411 412 tree, err := rtree.NewWriter(f, "mytree", wvars) 413 if err != nil { 414 log.Fatalf("could not create tree writer: %+v", err) 415 } 416 defer tree.Close() 417 418 fmt.Printf("-- created tree %q:\n", tree.Name()) 419 for i, b := range tree.Branches() { 420 fmt.Printf("branch[%d]: name=%q, title=%q\n", i, b.Name(), b.Title()) 421 } 422 423 for i := range nevts { 424 evt.I32 = int32(i) 425 evt.F64 = float64(i) 426 evt.Str = fmt.Sprintf("evt-%0d", i) 427 evt.Arr = [5]float64{float64(i), float64(i + 1), float64(i + 2), float64(i + 3), float64(i + 4)} 428 evt.Sli = []float64{float64(i), float64(i + 1), float64(i + 2), float64(i + 3), float64(i + 4)}[:i] 429 evt.P4 = P4{Px: float64(i), Py: float64(i + 1), Pz: float64(i + 2), E: float64(i + 3)} 430 evt.Ps = []Particle{ 431 {ID: int32(i), P4: evt.P4}, 432 {ID: int32(i + 1), P4: evt.P4}, 433 {ID: int32(i + 2), P4: evt.P4}, 434 {ID: int32(i + 3), P4: evt.P4}, 435 {ID: int32(i + 4), P4: evt.P4}, 436 }[:i] 437 438 _, err = tree.Write() 439 if err != nil { 440 log.Fatalf("could not write event %d: %+v", i, err) 441 } 442 } 443 fmt.Printf("-- filled tree with %d entries\n", tree.Entries()) 444 445 err = tree.Close() 446 if err != nil { 447 log.Fatalf("could not write tree: %+v", err) 448 } 449 450 err = f.Close() 451 if err != nil { 452 log.Fatalf("could not close tree: %+v", err) 453 } 454 }() 455 456 { 457 fmt.Printf("-- read back ROOT file\n") 458 out := new(bytes.Buffer) 459 err := rcmd.List(out, fname, rcmd.ListTrees(true)) 460 if err != nil { 461 log.Fatalf("could not list ROOT file content: %+v", err) 462 } 463 fmt.Printf("%s\n", out.String()) 464 } 465 466 { 467 var ( 468 deep = true 469 filter = func(name string) bool { return true } 470 ) 471 out := new(bytes.Buffer) 472 err := rcmd.Dump(out, fname, deep, filter) 473 if err != nil { 474 log.Fatalf("could not dump ROOT file: %+v", err) 475 } 476 fmt.Printf("%s\n", out.String()) 477 } 478 479 // Output: 480 // -- created tree "mytree": 481 // branch[0]: name="evt", title="evt" 482 // -- filled tree with 5 entries 483 // -- read back ROOT file 484 // === [../testdata/groot-event-ntuple-nosplit.root] === 485 // version: 63602 486 // TTree mytree (entries=5) 487 // evt "evt" TBranchElement 488 // 489 // key[000]: mytree;1 "" (TTree) 490 // [000][evt]: {0 0 evt-0 [0 1 2 3 4] [] {0 1 2 3} []} 491 // [001][evt]: {1 1 evt-1 [1 2 3 4 5] [1] {1 2 3 4} [{1 {1 2 3 4}}]} 492 // [002][evt]: {2 2 evt-2 [2 3 4 5 6] [2 3] {2 3 4 5} [{2 {2 3 4 5}} {3 {2 3 4 5}}]} 493 // [003][evt]: {3 3 evt-3 [3 4 5 6 7] [3 4 5] {3 4 5 6} [{3 {3 4 5 6}} {4 {3 4 5 6}} {5 {3 4 5 6}}]} 494 // [004][evt]: {4 4 evt-4 [4 5 6 7 8] [4 5 6 7] {4 5 6 7} [{4 {4 5 6 7}} {5 {4 5 6 7}} {6 {4 5 6 7}} {7 {4 5 6 7}}]} 495 496 } 497 498 func Example_createEventNtupleFullSplit() { 499 type P4 struct { 500 Px float64 `groot:"px"` 501 Py float64 `groot:"py"` 502 Pz float64 `groot:"pz"` 503 E float64 `groot:"ene"` 504 } 505 506 type Particle struct { 507 ID int32 `groot:"id"` 508 P4 P4 `groot:"p4"` 509 } 510 511 type Event struct { 512 I32 int32 `groot:"i32"` 513 F64 float64 `groot:"f64"` 514 Str string `groot:"str"` 515 Arr [5]float64 `groot:"arr"` 516 Sli []float64 `groot:"sli"` 517 P4 P4 `groot:"p4"` 518 Ps []Particle `groot:"mc"` 519 } 520 521 // register streamers 522 for _, typ := range []reflect.Type{ 523 reflect.TypeOf(P4{}), 524 reflect.TypeOf(Particle{}), 525 reflect.TypeOf(Event{}), 526 } { 527 528 rdict.StreamerInfos.Add(rdict.StreamerOf( 529 rdict.StreamerInfos, 530 typ, 531 )) 532 } 533 534 const ( 535 fname = "../testdata/groot-event-ntuple-fullsplit.root" 536 nevts = 5 537 ) 538 539 func() { 540 f, err := groot.Create(fname) 541 if err != nil { 542 log.Fatalf("could not create ROOT file: %+v", err) 543 } 544 defer f.Close() 545 546 var ( 547 evt Event 548 wvars = rtree.WriteVarsFromStruct(&evt) 549 ) 550 551 tree, err := rtree.NewWriter(f, "mytree", wvars) 552 if err != nil { 553 log.Fatalf("could not create tree writer: %+v", err) 554 } 555 defer tree.Close() 556 557 fmt.Printf("-- created tree %q:\n", tree.Name()) 558 for i, b := range tree.Branches() { 559 fmt.Printf("branch[%d]: name=%q, title=%q\n", i, b.Name(), b.Title()) 560 } 561 562 for i := range nevts { 563 evt.I32 = int32(i) 564 evt.F64 = float64(i) 565 evt.Str = fmt.Sprintf("evt-%0d", i) 566 evt.Arr = [5]float64{float64(i), float64(i + 1), float64(i + 2), float64(i + 3), float64(i + 4)} 567 evt.Sli = []float64{float64(i), float64(i + 1), float64(i + 2), float64(i + 3), float64(i + 4)}[:i] 568 evt.P4 = P4{Px: float64(i), Py: float64(i + 1), Pz: float64(i + 2), E: float64(i + 3)} 569 evt.Ps = []Particle{ 570 {ID: int32(i), P4: evt.P4}, 571 {ID: int32(i + 1), P4: evt.P4}, 572 {ID: int32(i + 2), P4: evt.P4}, 573 {ID: int32(i + 3), P4: evt.P4}, 574 {ID: int32(i + 4), P4: evt.P4}, 575 }[:i] 576 577 _, err = tree.Write() 578 if err != nil { 579 log.Fatalf("could not write event %d: %+v", i, err) 580 } 581 } 582 fmt.Printf("-- filled tree with %d entries\n", tree.Entries()) 583 584 err = tree.Close() 585 if err != nil { 586 log.Fatalf("could not write tree: %+v", err) 587 } 588 589 err = f.Close() 590 if err != nil { 591 log.Fatalf("could not close tree: %+v", err) 592 } 593 }() 594 595 { 596 fmt.Printf("-- read back ROOT file\n") 597 out := new(bytes.Buffer) 598 err := rcmd.List(out, fname, rcmd.ListTrees(true)) 599 if err != nil { 600 log.Fatalf("could not list ROOT file content: %+v", err) 601 } 602 fmt.Printf("%s\n", out.String()) 603 } 604 605 { 606 var ( 607 deep = true 608 filter = func(name string) bool { return true } 609 ) 610 out := new(bytes.Buffer) 611 err := rcmd.Dump(out, fname, deep, filter) 612 if err != nil { 613 log.Fatalf("could not dump ROOT file: %+v", err) 614 } 615 fmt.Printf("%s\n", out.String()) 616 } 617 618 // Output: 619 // -- created tree "mytree": 620 // branch[0]: name="i32", title="i32/I" 621 // branch[1]: name="f64", title="f64/D" 622 // branch[2]: name="str", title="str/C" 623 // branch[3]: name="arr", title="arr[5]/D" 624 // branch[4]: name="sli", title="sli" 625 // branch[5]: name="p4", title="p4" 626 // branch[6]: name="mc", title="mc" 627 // -- filled tree with 5 entries 628 // -- read back ROOT file 629 // === [../testdata/groot-event-ntuple-fullsplit.root] === 630 // version: 63602 631 // TTree mytree (entries=5) 632 // i32 "i32/I" TBranch 633 // f64 "f64/D" TBranch 634 // str "str/C" TBranch 635 // arr "arr[5]/D" TBranch 636 // sli "sli" TBranchElement 637 // p4 "p4" TBranchElement 638 // mc "mc" TBranchElement 639 // 640 // key[000]: mytree;1 "" (TTree) 641 // [000][i32]: 0 642 // [000][f64]: 0 643 // [000][str]: evt-0 644 // [000][arr]: [0 1 2 3 4] 645 // [000][sli]: [] 646 // [000][p4]: {0 1 2 3} 647 // [000][mc]: [] 648 // [001][i32]: 1 649 // [001][f64]: 1 650 // [001][str]: evt-1 651 // [001][arr]: [1 2 3 4 5] 652 // [001][sli]: [1] 653 // [001][p4]: {1 2 3 4} 654 // [001][mc]: [{1 {1 2 3 4}}] 655 // [002][i32]: 2 656 // [002][f64]: 2 657 // [002][str]: evt-2 658 // [002][arr]: [2 3 4 5 6] 659 // [002][sli]: [2 3] 660 // [002][p4]: {2 3 4 5} 661 // [002][mc]: [{2 {2 3 4 5}} {3 {2 3 4 5}}] 662 // [003][i32]: 3 663 // [003][f64]: 3 664 // [003][str]: evt-3 665 // [003][arr]: [3 4 5 6 7] 666 // [003][sli]: [3 4 5] 667 // [003][p4]: {3 4 5 6} 668 // [003][mc]: [{3 {3 4 5 6}} {4 {3 4 5 6}} {5 {3 4 5 6}}] 669 // [004][i32]: 4 670 // [004][f64]: 4 671 // [004][str]: evt-4 672 // [004][arr]: [4 5 6 7 8] 673 // [004][sli]: [4 5 6 7] 674 // [004][p4]: {4 5 6 7} 675 // [004][mc]: [{4 {4 5 6 7}} {5 {4 5 6 7}} {6 {4 5 6 7}} {7 {4 5 6 7}}] 676 }