go-hep.org/x/hep@v0.38.1/groot/gen.rhist.go (about) 1 // Copyright ©2018 The go-hep Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build ignore 6 7 package main 8 9 import ( 10 "fmt" 11 "log" 12 "os" 13 "text/template" 14 15 "go-hep.org/x/hep/groot/internal/genroot" 16 ) 17 18 func main() { 19 genH1() 20 genH2() 21 } 22 23 func genH1() { 24 fname := "./rhist/h1_gen.go" 25 year := genroot.ExtractYear(fname) 26 f, err := os.Create(fname) 27 if err != nil { 28 log.Fatal(err) 29 } 30 defer f.Close() 31 32 genroot.GenImports(year, "rhist", f, 33 "fmt", "math", "reflect", 34 "", 35 "go-hep.org/x/hep/hbook", 36 "go-hep.org/x/hep/groot/root", 37 "go-hep.org/x/hep/groot/rcont", 38 "go-hep.org/x/hep/groot/rbytes", 39 "go-hep.org/x/hep/groot/rtypes", 40 "go-hep.org/x/hep/groot/rvers", 41 ) 42 43 for i, typ := range []struct { 44 Name string 45 Type string 46 Elem string 47 }{ 48 { 49 Name: "H1F", 50 Type: "rcont.ArrayF", 51 Elem: "float32", 52 }, 53 { 54 Name: "H1D", 55 Type: "rcont.ArrayD", 56 Elem: "float64", 57 }, 58 { 59 Name: "H1I", 60 Type: "rcont.ArrayI", 61 Elem: "int32", 62 }, 63 } { 64 if i > 0 { 65 fmt.Fprintf(f, "\n") 66 } 67 tmpl := template.Must(template.New(typ.Name).Parse(h1Tmpl)) 68 err = tmpl.Execute(f, typ) 69 if err != nil { 70 log.Fatalf("error executing template for %q: %v\n", typ.Name, err) 71 } 72 } 73 74 err = f.Close() 75 if err != nil { 76 log.Fatal(err) 77 } 78 genroot.GoFmt(f) 79 } 80 81 func genH2() { 82 fname := "./rhist/h2_gen.go" 83 year := genroot.ExtractYear(fname) 84 f, err := os.Create(fname) 85 if err != nil { 86 log.Fatal(err) 87 } 88 defer f.Close() 89 90 genroot.GenImports(year, "rhist", f, 91 "fmt", "math", "reflect", 92 "", 93 "go-hep.org/x/hep/hbook", 94 "go-hep.org/x/hep/groot/root", 95 "go-hep.org/x/hep/groot/rcont", 96 "go-hep.org/x/hep/groot/rbytes", 97 "go-hep.org/x/hep/groot/rtypes", 98 "go-hep.org/x/hep/groot/rvers", 99 ) 100 101 for i, typ := range []struct { 102 Name string 103 Type string 104 Elem string 105 }{ 106 { 107 Name: "H2F", 108 Type: "rcont.ArrayF", 109 Elem: "float32", 110 }, 111 { 112 Name: "H2D", 113 Type: "rcont.ArrayD", 114 Elem: "float64", 115 }, 116 { 117 Name: "H2I", 118 Type: "rcont.ArrayI", 119 Elem: "int32", 120 }, 121 } { 122 if i > 0 { 123 fmt.Fprintf(f, "\n") 124 } 125 tmpl := template.Must(template.New(typ.Name).Parse(h2Tmpl)) 126 err = tmpl.Execute(f, typ) 127 if err != nil { 128 log.Fatalf("error executing template for %q: %v\n", typ.Name, err) 129 } 130 } 131 132 err = f.Close() 133 if err != nil { 134 log.Fatal(err) 135 } 136 genroot.GoFmt(f) 137 } 138 139 const h1Tmpl = `// {{.Name}} implements ROOT T{{.Name}} 140 type {{.Name}} struct { 141 th1 142 arr {{.Type}} 143 } 144 145 func new{{.Name}}() *{{.Name}} { 146 return &{{.Name}}{ 147 th1: *newH1(), 148 } 149 } 150 151 // New{{.Name}}From creates a new 1-dim histogram from hbook. 152 func New{{.Name}}From(h *hbook.H1D) *{{.Name}} { 153 var ( 154 hroot = new{{.Name}}() 155 bins = h.Binning.Bins 156 nbins = len(bins) 157 edges = make([]float64, 0, nbins+1) 158 uflow = h.Binning.Underflow() 159 oflow = h.Binning.Overflow() 160 ) 161 162 hroot.th1.entries = float64(h.Entries()) 163 hroot.th1.tsumw = h.SumW() 164 hroot.th1.tsumw2 = h.SumW2() 165 hroot.th1.tsumwx = h.SumWX() 166 hroot.th1.tsumwx2 = h.SumWX2() 167 hroot.th1.ncells = nbins+2 168 169 hroot.th1.xaxis.nbins = nbins 170 hroot.th1.xaxis.xmin = h.XMin() 171 hroot.th1.xaxis.xmax = h.XMax() 172 173 hroot.arr.Data = make([]{{.Elem}}, nbins+2) 174 hroot.th1.sumw2.Data = make([]float64, nbins+2) 175 176 for i, bin := range bins { 177 if i == 0 { 178 edges = append(edges, bin.XMin()) 179 } 180 edges = append(edges, bin.XMax()) 181 hroot.setDist1D(i+1, bin.Dist.SumW(), bin.Dist.SumW2()) 182 } 183 hroot.setDist1D(0, uflow.SumW(), uflow.SumW2()) 184 hroot.setDist1D(nbins+1, oflow.SumW(), oflow.SumW2()) 185 186 hroot.th1.SetName(h.Name()) 187 if v, ok := h.Annotation()["title"]; ok && v != nil { 188 hroot.th1.SetTitle(v.(string)) 189 } 190 hroot.th1.xaxis.xbins.Data = edges 191 return hroot 192 } 193 194 func (*{{.Name}}) RVersion() int16 { 195 return rvers.{{.Name}} 196 } 197 198 func (*{{.Name}}) isH1() {} 199 200 // Class returns the ROOT class name. 201 func (*{{.Name}}) Class() string { 202 return "T{{.Name}}" 203 } 204 205 func (h *{{.Name}}) MarshalROOT(w *rbytes.WBuffer) (int, error) { 206 if w.Err() != nil { 207 return 0, w.Err() 208 } 209 210 hdr := w.WriteHeader(h.Class(), h.RVersion()) 211 212 w.WriteObject(&h.th1) 213 w.WriteObject(&h.arr) 214 215 return w.SetHeader(hdr) 216 } 217 218 func (h *{{.Name}}) UnmarshalROOT(r *rbytes.RBuffer) error { 219 if r.Err() != nil { 220 return r.Err() 221 } 222 223 hdr := r.ReadHeader(h.Class(), h.RVersion()) 224 225 r.ReadObject(&h.th1) 226 r.ReadObject(&h.arr) 227 228 r.CheckHeader(hdr) 229 return r.Err() 230 } 231 232 func (h *{{.Name}}) RMembers() (mbrs []rbytes.Member) { 233 mbrs = append(mbrs, h.th1.RMembers()...) 234 mbrs = append(mbrs, rbytes.Member{ 235 Name: "fArray", Value: &h.arr.Data, 236 }) 237 return mbrs 238 } 239 240 func (h *{{.Name}}) Array() {{.Type}} { 241 return h.arr 242 } 243 244 // Rank returns the number of dimensions of this histogram. 245 func (h *{{.Name}}) Rank() int { 246 return 1 247 } 248 249 // NbinsX returns the number of bins in X. 250 func (h *{{.Name}}) NbinsX() int { 251 return h.th1.xaxis.nbins 252 } 253 254 // XAxis returns the axis along X. 255 func (h*{{.Name}}) XAxis() Axis { 256 return &h.th1.xaxis 257 } 258 259 // bin returns the regularized bin number given an x bin pair. 260 func (h *{{.Name}}) bin(ix int) int { 261 nx := h.th1.xaxis.nbins + 1 // overflow bin 262 switch { 263 case ix < 0: 264 ix = 0 265 case ix > nx: 266 ix = nx 267 } 268 return ix 269 } 270 271 // XBinCenter returns the bin center value in X. 272 func (h *{{.Name}}) XBinCenter(i int) float64 { 273 return float64(h.th1.xaxis.BinCenter(i)) 274 } 275 276 // XBinContent returns the bin content value in X. 277 func (h *{{.Name}}) XBinContent(i int) float64 { 278 ibin := h.bin(i) 279 return float64(h.arr.Data[ibin]) 280 } 281 282 // XBinError returns the bin error in X. 283 func (h *{{.Name}}) XBinError(i int) float64 { 284 ibin := h.bin(i) 285 if len(h.th1.sumw2.Data) > 0 { 286 return math.Sqrt(float64(h.th1.sumw2.Data[ibin])) 287 } 288 return math.Sqrt(math.Abs(float64(h.arr.Data[ibin]))) 289 } 290 291 // XBinLowEdge returns the bin lower edge value in X. 292 func (h *{{.Name}}) XBinLowEdge(i int) float64 { 293 return h.th1.xaxis.BinLowEdge(i) 294 } 295 296 // XBinWidth returns the bin width in X. 297 func (h *{{.Name}}) XBinWidth(i int) float64 { 298 return h.th1.xaxis.BinWidth(i) 299 } 300 301 func (h *{{.Name}}) dist1D(i int) hbook.Dist1D { 302 v := h.XBinContent(i) 303 err := h.XBinError(i) 304 n := h.entries(v, err) 305 sumw := h.arr.Data[i] 306 sumw2 := 0.0 307 if len(h.th1.sumw2.Data) > 0 { 308 sumw2 = h.th1.sumw2.Data[i] 309 } 310 return hbook.Dist1D{ 311 Dist: hbook.Dist0D{ 312 N: n, 313 SumW: float64(sumw), 314 SumW2: float64(sumw2), 315 }, 316 } 317 } 318 319 func (h *{{.Name}}) setDist1D(i int, sumw, sumw2 float64) { 320 h.arr.Data[i] = {{.Elem}}(sumw) 321 h.th1.sumw2.Data[i] = sumw2 322 } 323 324 func (h *{{.Name}}) entries(height, err float64) int64 { 325 if height <= 0 { 326 return 0 327 } 328 v := height / err 329 return int64(v*v+0.5) 330 } 331 332 // AsH1D creates a new hbook.H1D from this ROOT histogram. 333 func (h *{{.Name}}) AsH1D() *hbook.H1D { 334 var ( 335 nx = h.NbinsX() 336 hh = hbook.NewH1D(int(nx), h.XAxis().XMin(), h.XAxis().XMax()) 337 ) 338 hh.Ann = hbook.Annotation{ 339 "name": h.Name(), 340 "title": h.Title(), 341 } 342 343 hh.Binning.Dist = hbook.Dist1D{ 344 Dist: hbook.Dist0D{ 345 N: int64(h.Entries()), 346 SumW: float64(h.SumW()), 347 SumW2: float64(h.SumW2()), 348 }, 349 } 350 hh.Binning.Dist.Stats.SumWX = float64(h.SumWX()) 351 hh.Binning.Dist.Stats.SumWX2 = float64(h.SumWX2()) 352 353 hh.Binning.Outflows = [2]hbook.Dist1D{ 354 h.dist1D(0), // underflow 355 h.dist1D(nx + 1), // overflow 356 } 357 358 for i := 0; i < nx; i++ { 359 bin := &hh.Binning.Bins[i] 360 xmin := h.XBinLowEdge(i + 1) 361 xmax := h.XBinWidth(i+1) + xmin 362 bin.Dist = h.dist1D(i + 1) 363 bin.Range.Min = xmin 364 bin.Range.Max = xmax 365 hh.Binning.Bins[i].Dist = h.dist1D(i + 1) 366 } 367 368 return hh 369 } 370 371 // MarshalYODA implements the YODAMarshaler interface. 372 func (h *{{.Name}}) MarshalYODA() ([]byte, error) { 373 return h.AsH1D().MarshalYODA() 374 } 375 376 // UnmarshalYODA implements the YODAUnmarshaler interface. 377 func (h *{{.Name}}) UnmarshalYODA(raw []byte) error { 378 var hh hbook.H1D 379 err := hh.UnmarshalYODA(raw) 380 if err != nil { 381 return err 382 } 383 384 *h = *New{{.Name}}From(&hh) 385 return nil 386 } 387 388 func (h *{{.Name}}) ROOTMerge(src root.Object) error { 389 hsrc, ok := src.(*{{.Name}}) 390 if !ok { 391 return fmt.Errorf("rhist: object %q is not a *rhist.H1F (%T)", src.(root.Named).Name(), src) 392 } 393 394 var ( 395 h1 = h.AsH1D() 396 h2 = hsrc.AsH1D() 397 hadd = hbook.AddH1D(h1, h2) 398 ) 399 400 *h = *New{{.Name}}From(hadd) 401 return nil 402 } 403 404 func init() { 405 f := func() reflect.Value { 406 o := new{{.Name}}() 407 return reflect.ValueOf(o) 408 } 409 rtypes.Factory.Add("T{{.Name}}", f) 410 } 411 412 var ( 413 _ root.Object = (*{{.Name}})(nil) 414 _ root.Merger = (*{{.Name}})(nil) 415 _ root.Named = (*{{.Name}})(nil) 416 _ H1 = (*{{.Name}})(nil) 417 _ rbytes.Marshaler = (*{{.Name}})(nil) 418 _ rbytes.Unmarshaler = (*{{.Name}})(nil) 419 _ rbytes.RSlicer = (*{{.Name}})(nil) 420 ) 421 ` 422 423 const h2Tmpl = `// {{.Name}} implements ROOT T{{.Name}} 424 type {{.Name}} struct { 425 th2 426 arr {{.Type}} 427 } 428 429 func new{{.Name}}() *{{.Name}} { 430 return &{{.Name}}{ 431 th2: *newH2(), 432 } 433 } 434 435 // New{{.Name}}From creates a new {{.Name}} from hbook 2-dim histogram. 436 func New{{.Name}}From(h *hbook.H2D) *{{.Name}} { 437 var ( 438 hroot = new{{.Name}}() 439 bins = h.Binning.Bins 440 nxbins = h.Binning.Nx 441 nybins = h.Binning.Ny 442 xedges = make([]float64, 0, nxbins+1) 443 yedges = make([]float64, 0, nybins+1) 444 ) 445 446 hroot.th2.th1.entries = float64(h.Entries()) 447 hroot.th2.th1.tsumw = h.SumW() 448 hroot.th2.th1.tsumw2 = h.SumW2() 449 hroot.th2.th1.tsumwx = h.SumWX() 450 hroot.th2.th1.tsumwx2 = h.SumWX2() 451 hroot.th2.tsumwy = h.SumWY() 452 hroot.th2.tsumwy2 = h.SumWY2() 453 hroot.th2.tsumwxy = h.SumWXY() 454 455 ncells := (nxbins + 2) * (nybins + 2) 456 hroot.th2.th1.ncells = ncells 457 458 hroot.th2.th1.xaxis.nbins = nxbins 459 hroot.th2.th1.xaxis.xmin = h.XMin() 460 hroot.th2.th1.xaxis.xmax = h.XMax() 461 462 hroot.th2.th1.yaxis.nbins = nybins 463 hroot.th2.th1.yaxis.xmin = h.YMin() 464 hroot.th2.th1.yaxis.xmax = h.YMax() 465 466 hroot.arr.Data = make([]{{.Elem}}, ncells) 467 hroot.th2.th1.sumw2.Data = make([]float64, ncells) 468 469 ibin := func(ix, iy int) int { return iy*nxbins + ix } 470 471 for ix := 0; ix < h.Binning.Nx; ix++ { 472 for iy := 0; iy < h.Binning.Ny; iy++ { 473 i := ibin(ix, iy) 474 bin := bins[i] 475 if ix == 0 { 476 yedges = append(yedges, bin.YMin()) 477 } 478 if iy == 0 { 479 xedges = append(xedges, bin.XMin()) 480 } 481 hroot.setDist2D(ix+1, iy+1, bin.Dist.SumW(), bin.Dist.SumW2()) 482 } 483 } 484 485 oflows := h.Binning.Outflows[:] 486 for i, v := range []struct{ix,iy int}{ 487 {0, 0}, 488 {0, 1}, 489 {0, nybins+1}, 490 {nxbins + 1, 0}, 491 {nxbins + 1, 1}, 492 {nxbins + 1, nybins + 1}, 493 {1, 0}, 494 {1, nybins + 1}, 495 }{ 496 hroot.setDist2D(v.ix, v.iy, oflows[i].SumW(), oflows[i].SumW2()) 497 } 498 499 xedges = append(xedges, bins[ibin(h.Binning.Nx-1, 0)].XMax()) 500 yedges = append(yedges, bins[ibin(0, h.Binning.Ny-1)].YMax()) 501 502 hroot.th2.th1.SetName(h.Name()) 503 if v, ok := h.Annotation()["title"]; ok && v != nil { 504 hroot.th2.th1.SetTitle(v.(string)) 505 } 506 hroot.th2.th1.xaxis.xbins.Data = xedges 507 hroot.th2.th1.yaxis.xbins.Data = yedges 508 509 return hroot 510 } 511 512 func (*{{.Name}}) RVersion() int16 { 513 return rvers.{{.Name}} 514 } 515 516 func (*{{.Name}}) isH2() {} 517 518 // Class returns the ROOT class name. 519 func (*{{.Name}}) Class() string { 520 return "T{{.Name}}" 521 } 522 523 func (h *{{.Name}}) Array() {{.Type}} { 524 return h.arr 525 } 526 527 // Rank returns the number of dimensions of this histogram. 528 func (h *{{.Name}}) Rank() int { 529 return 2 530 } 531 532 // NbinsX returns the number of bins in X. 533 func (h *{{.Name}}) NbinsX() int { 534 return h.th1.xaxis.nbins 535 } 536 537 // XAxis returns the axis along X. 538 func (h*{{.Name}}) XAxis() Axis { 539 return &h.th1.xaxis 540 } 541 542 // XBinCenter returns the bin center value in X. 543 func (h *{{.Name}}) XBinCenter(i int) float64 { 544 return float64(h.th1.xaxis.BinCenter(i)) 545 } 546 547 // XBinContent returns the bin content value in X. 548 func (h *{{.Name}}) XBinContent(i int) float64 { 549 return float64(h.arr.Data[i]) 550 } 551 552 // XBinError returns the bin error in X. 553 func (h *{{.Name}}) XBinError(i int) float64 { 554 if len(h.th1.sumw2.Data) > 0 { 555 return math.Sqrt(float64(h.th1.sumw2.Data[i])) 556 } 557 return math.Sqrt(math.Abs(float64(h.arr.Data[i]))) 558 } 559 560 // XBinLowEdge returns the bin lower edge value in X. 561 func (h *{{.Name}}) XBinLowEdge(i int) float64 { 562 return h.th1.xaxis.BinLowEdge(i) 563 } 564 565 // XBinWidth returns the bin width in X. 566 func (h *{{.Name}}) XBinWidth(i int) float64 { 567 return h.th1.xaxis.BinWidth(i) 568 } 569 570 // NbinsY returns the number of bins in Y. 571 func (h *{{.Name}}) NbinsY() int { 572 return h.th1.yaxis.nbins 573 } 574 575 // YAxis returns the axis along Y. 576 func (h*{{.Name}}) YAxis() Axis { 577 return &h.th1.yaxis 578 } 579 580 // YBinCenter returns the bin center value in Y. 581 func (h *{{.Name}}) YBinCenter(i int) float64 { 582 return float64(h.th1.yaxis.BinCenter(i)) 583 } 584 585 // YBinContent returns the bin content value in Y. 586 func (h *{{.Name}}) YBinContent(i int) float64 { 587 return float64(h.arr.Data[i]) 588 } 589 590 // YBinError returns the bin error in Y. 591 func (h *{{.Name}}) YBinError(i int) float64 { 592 if len(h.th1.sumw2.Data) > 0 { 593 return math.Sqrt(float64(h.th1.sumw2.Data[i])) 594 } 595 return math.Sqrt(math.Abs(float64(h.arr.Data[i]))) 596 } 597 598 // YBinLowEdge returns the bin lower edge value in Y. 599 func (h *{{.Name}}) YBinLowEdge(i int) float64 { 600 return h.th1.yaxis.BinLowEdge(i) 601 } 602 603 // YBinWidth returns the bin width in Y. 604 func (h *{{.Name}}) YBinWidth(i int) float64 { 605 return h.th1.yaxis.BinWidth(i) 606 } 607 608 // bin returns the regularized bin number given an (x,y) bin index pair. 609 func (h *{{.Name}}) bin(ix, iy int) int { 610 nx := h.th1.xaxis.nbins + 1 // overflow bin 611 ny := h.th1.yaxis.nbins + 1 // overflow bin 612 switch { 613 case ix < 0: 614 ix = 0 615 case ix > nx: 616 ix = nx 617 } 618 switch { 619 case iy < 0: 620 iy = 0 621 case iy > ny: 622 iy = ny 623 } 624 return ix + (nx+1)*iy 625 } 626 627 func (h *{{.Name}}) dist2D(ix, iy int) hbook.Dist2D { 628 i := h.bin(ix, iy) 629 vx := h.XBinContent(i) 630 xerr := h.XBinError(i) 631 nx := h.entries(vx, xerr) 632 vy := h.YBinContent(i) 633 yerr := h.YBinError(i) 634 ny := h.entries(vy, yerr) 635 636 sumw := h.arr.Data[i] 637 sumw2 := 0.0 638 if len(h.th1.sumw2.Data) > 0 { 639 sumw2 = h.th1.sumw2.Data[i] 640 } 641 return hbook.Dist2D{ 642 X: hbook.Dist1D{ 643 Dist: hbook.Dist0D{ 644 N: nx, 645 SumW: float64(sumw), 646 SumW2: float64(sumw2), 647 }, 648 }, 649 Y: hbook.Dist1D{ 650 Dist: hbook.Dist0D{ 651 N: ny, 652 SumW: float64(sumw), 653 SumW2: float64(sumw2), 654 }, 655 }, 656 } 657 } 658 659 func (h *{{.Name}}) setDist2D(ix, iy int, sumw, sumw2 float64) { 660 i := h.bin(ix, iy) 661 h.arr.Data[i] = {{.Elem}}(sumw) 662 h.th1.sumw2.Data[i] = sumw2 663 } 664 665 func (h *{{.Name}}) entries(height, err float64) int64 { 666 if height <= 0 { 667 return 0 668 } 669 v := height / err 670 return int64(v*v + 0.5) 671 } 672 673 // AsH2D creates a new hbook.H2D from this ROOT histogram. 674 func (h *{{.Name}}) AsH2D() *hbook.H2D { 675 var ( 676 nx = h.NbinsX() 677 ny = h.NbinsY() 678 hh = hbook.NewH2D( 679 nx, h.XAxis().XMin(), h.XAxis().XMax(), 680 ny, h.YAxis().XMin(), h.YAxis().XMax(), 681 ) 682 xinrange = 1 683 yinrange = 1 684 ) 685 hh.Ann = hbook.Annotation{ 686 "name": h.Name(), 687 "title": h.Title(), 688 } 689 hh.Binning.Outflows = [8]hbook.Dist2D{ 690 h.dist2D(0, 0), 691 h.dist2D(0, yinrange), 692 h.dist2D(0, ny+1), 693 h.dist2D(nx+1, 0), 694 h.dist2D(nx+1, yinrange), 695 h.dist2D(nx+1, ny+1), 696 h.dist2D(xinrange, 0), 697 h.dist2D(xinrange, ny+1), 698 } 699 700 hh.Binning.Dist = hbook.Dist2D{ 701 X: hbook.Dist1D{ 702 Dist: hbook.Dist0D{ 703 N: int64(h.Entries()), 704 SumW: float64(h.SumW()), 705 SumW2: float64(h.SumW2()), 706 }, 707 }, 708 Y: hbook.Dist1D{ 709 Dist: hbook.Dist0D{ 710 N: int64(h.Entries()), 711 SumW: float64(h.SumW()), 712 SumW2: float64(h.SumW2()), 713 }, 714 }, 715 } 716 hh.Binning.Dist.X.Stats.SumWX = float64(h.SumWX()) 717 hh.Binning.Dist.X.Stats.SumWX2 = float64(h.SumWX2()) 718 hh.Binning.Dist.Y.Stats.SumWX = float64(h.SumWY()) 719 hh.Binning.Dist.Y.Stats.SumWX2 = float64(h.SumWY2()) 720 hh.Binning.Dist.Stats.SumWXY = h.SumWXY() 721 722 for ix := 0; ix < nx; ix++ { 723 for iy := 0; iy < ny; iy++ { 724 var ( 725 i = iy*nx + ix 726 xmin = h.XBinLowEdge(ix + 1) 727 xmax = h.XBinWidth(ix+1) + xmin 728 ymin = h.YBinLowEdge(iy + 1) 729 ymax = h.YBinWidth(iy+1) + ymin 730 bin = &hh.Binning.Bins[i] 731 ) 732 bin.XRange.Min = xmin 733 bin.XRange.Max = xmax 734 bin.YRange.Min = ymin 735 bin.YRange.Max = ymax 736 bin.Dist = h.dist2D(ix+1, iy+1) 737 } 738 } 739 740 return hh 741 } 742 743 // MarshalYODA implements the YODAMarshaler interface. 744 func (h *{{.Name}}) MarshalYODA() ([]byte, error) { 745 return h.AsH2D().MarshalYODA() 746 } 747 748 // UnmarshalYODA implements the YODAUnmarshaler interface. 749 func (h *{{.Name}}) UnmarshalYODA(raw []byte) error { 750 var hh hbook.H2D 751 err := hh.UnmarshalYODA(raw) 752 if err != nil { 753 return err 754 } 755 756 *h = *New{{.Name}}From(&hh) 757 return nil 758 } 759 760 func (h *{{.Name}}) MarshalROOT(w *rbytes.WBuffer) (int, error) { 761 if w.Err() != nil { 762 return 0, w.Err() 763 } 764 765 hdr := w.WriteHeader(h.Class(), h.RVersion()) 766 w.WriteObject(&h.th2) 767 w.WriteObject(&h.arr) 768 769 return w.SetHeader(hdr) 770 } 771 772 func (h *{{.Name}}) UnmarshalROOT(r *rbytes.RBuffer) error { 773 if r.Err() != nil { 774 return r.Err() 775 } 776 777 hdr := r.ReadHeader(h.Class(), h.RVersion()) 778 if hdr.Vers < 1 { 779 return fmt.Errorf("rhist: T{{.Name}} version too old (%d<1)", hdr.Vers) 780 } 781 782 r.ReadObject(&h.th2) 783 r.ReadObject(&h.arr) 784 785 r.CheckHeader(hdr) 786 return r.Err() 787 } 788 789 func (h *{{.Name}}) RMembers() (mbrs []rbytes.Member) { 790 mbrs = append(mbrs, h.th2.RMembers()...) 791 mbrs = append(mbrs, rbytes.Member{ 792 Name: "fArray", Value: &h.arr.Data, 793 }) 794 return mbrs 795 } 796 797 func init() { 798 f := func() reflect.Value { 799 o := new{{.Name}}() 800 return reflect.ValueOf(o) 801 } 802 rtypes.Factory.Add("T{{.Name}}", f) 803 } 804 805 var ( 806 _ root.Object = (*{{.Name}})(nil) 807 _ root.Named = (*{{.Name}})(nil) 808 _ H2 = (*{{.Name}})(nil) 809 _ rbytes.Marshaler = (*{{.Name}})(nil) 810 _ rbytes.Unmarshaler = (*{{.Name}})(nil) 811 _ rbytes.RSlicer = (*{{.Name}})(nil) 812 ) 813 `