go-hep.org/x/hep@v0.38.1/groot/rhist/axis.go (about) 1 // Copyright ©2017 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 rhist 6 7 import ( 8 "fmt" 9 "reflect" 10 11 "go-hep.org/x/hep/groot/rbase" 12 "go-hep.org/x/hep/groot/rbytes" 13 "go-hep.org/x/hep/groot/rcont" 14 "go-hep.org/x/hep/groot/root" 15 "go-hep.org/x/hep/groot/rtypes" 16 "go-hep.org/x/hep/groot/rvers" 17 ) 18 19 type taxis struct { 20 rbase.Named 21 attaxis rbase.AttAxis 22 nbins int // number of bins 23 xmin float64 // low edge of first bin 24 xmax float64 // upper edge of last bin 25 xbins rcont.ArrayD // bin edges array in X 26 first int // first bin to display 27 last int // last bin to display 28 bits2 uint16 // second bit status word 29 time bool // on/off displaying time values instead of numerics 30 tfmt string // date&time format 31 labels *rcont.HashList // list of labels 32 modlabs *rcont.List // list of modified labels 33 } 34 35 func NewAxis(name string) *taxis { 36 return &taxis{ 37 Named: *rbase.NewNamed(name, ""), 38 attaxis: *rbase.NewAttAxis(), 39 nbins: 1, 40 xmin: 0, 41 xmax: 1, 42 } 43 } 44 45 func (*taxis) RVersion() int16 { 46 return rvers.Axis 47 } 48 49 func (a *taxis) Class() string { 50 return "TAxis" 51 } 52 53 func (a *taxis) XMin() float64 { 54 return a.xmin 55 } 56 57 func (a *taxis) XMax() float64 { 58 return a.xmax 59 } 60 61 func (a *taxis) NBins() int { 62 return a.nbins 63 } 64 65 func (a *taxis) XBins() []float64 { 66 return a.xbins.Data 67 } 68 69 func (a *taxis) BinCenter(i int) float64 { 70 if len(a.xbins.Data) == 0 || i < 1 || i > a.nbins { 71 width := (a.xmax - a.xmin) / float64(a.nbins) 72 return a.xmin + (float64(i)-0.5)*width 73 } 74 width := a.xbins.Data[i] - a.xbins.Data[i-1] 75 return a.xbins.Data[i-1] + 0.5*width 76 } 77 78 func (a *taxis) BinLowEdge(i int) float64 { 79 if len(a.xbins.Data) == 0 || i < 1 || i > a.nbins { 80 width := (a.xmax - a.xmin) / float64(a.nbins) 81 return a.xmin + float64(i-1)*width 82 } 83 return a.xbins.Data[i-1] 84 } 85 86 func (a *taxis) BinWidth(i int) float64 { 87 if a.nbins <= 0 { 88 return 0 89 } 90 if len(a.xbins.Data) <= 0 { 91 return (a.xmax - a.xmin) / float64(a.nbins) 92 } 93 if i > a.nbins { 94 i = a.nbins 95 } 96 if i < 1 { 97 i = 1 98 } 99 return a.xbins.Data[i] - a.xbins.Data[i-1] 100 } 101 102 func (a *taxis) MarshalROOT(w *rbytes.WBuffer) (int, error) { 103 if w.Err() != nil { 104 return 0, w.Err() 105 } 106 107 hdr := w.WriteHeader(a.Class(), a.RVersion()) 108 109 w.WriteObject(&a.Named) 110 w.WriteObject(&a.attaxis) 111 112 w.WriteI32(int32(a.nbins)) 113 w.WriteF64(a.xmin) 114 w.WriteF64(a.xmax) 115 w.WriteObject(&a.xbins) 116 w.WriteI32(int32(a.first)) 117 w.WriteI32(int32(a.last)) 118 w.WriteU16(a.bits2) 119 w.WriteBool(a.time) 120 w.WriteString(a.tfmt) 121 122 w.WriteObjectAny(a.labels) 123 if a.RVersion() >= 10 { 124 w.WriteObjectAny(a.modlabs) 125 } 126 127 return w.SetHeader(hdr) 128 } 129 130 func (a *taxis) UnmarshalROOT(r *rbytes.RBuffer) error { 131 if r.Err() != nil { 132 return r.Err() 133 } 134 135 hdr := r.ReadHeader(a.Class(), a.RVersion()) 136 const minVers = 6 137 if hdr.Vers < minVers { 138 return fmt.Errorf("rhist: TAxis version too old (%d<%d)", hdr.Vers, minVers) 139 } 140 141 r.ReadObject(&a.Named) 142 r.ReadObject(&a.attaxis) 143 144 a.nbins = int(r.ReadI32()) 145 a.xmin = r.ReadF64() 146 a.xmax = r.ReadF64() 147 r.ReadObject(&a.xbins) 148 a.first = int(r.ReadI32()) 149 a.last = int(r.ReadI32()) 150 if hdr.Vers >= 9 { 151 a.bits2 = r.ReadU16() 152 } 153 a.time = r.ReadBool() 154 a.tfmt = r.ReadString() 155 156 a.labels = nil 157 if hdr.Vers >= 9 { 158 labels := r.ReadObjectAny() 159 if labels != nil { 160 a.labels = labels.(*rcont.HashList) 161 } 162 } 163 164 a.modlabs = nil 165 if hdr.Vers >= 10 { 166 modlabs := r.ReadObjectAny() 167 if modlabs != nil { 168 a.modlabs = modlabs.(*rcont.List) 169 } 170 } 171 172 r.CheckHeader(hdr) 173 return r.Err() 174 } 175 176 func (a *taxis) RMembers() (mbrs []rbytes.Member) { 177 mbrs = append(mbrs, a.Named.RMembers()...) 178 mbrs = append(mbrs, a.attaxis.RMembers()...) 179 mbrs = append(mbrs, []rbytes.Member{ 180 {Name: "fNbins", Value: &a.nbins}, 181 {Name: "fXmin", Value: &a.xmin}, 182 {Name: "fXmax", Value: &a.xmax}, 183 {Name: "fXbins", Value: &a.xbins.Data}, 184 {Name: "fFirst", Value: &a.first}, 185 {Name: "fLast", Value: &a.last}, 186 {Name: "fBits2", Value: &a.bits2}, 187 {Name: "fTimeDisplay", Value: &a.time}, 188 {Name: "fTimeFormat", Value: &a.tfmt}, 189 {Name: "fLabels", Value: &a.labels}, 190 {Name: "fModLabs", Value: &a.modlabs}, 191 }...) 192 return mbrs 193 } 194 195 func init() { 196 { 197 f := func() reflect.Value { 198 o := NewAxis("") 199 return reflect.ValueOf(o) 200 } 201 rtypes.Factory.Add("TAxis", f) 202 } 203 } 204 205 var ( 206 _ root.Object = (*taxis)(nil) 207 _ root.Named = (*taxis)(nil) 208 _ Axis = (*taxis)(nil) 209 _ rbytes.Marshaler = (*taxis)(nil) 210 _ rbytes.Unmarshaler = (*taxis)(nil) 211 )