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