go-hep.org/x/hep@v0.38.1/lcio/event.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 lcio
     6  
     7  import (
     8  	"fmt"
     9  	"reflect"
    10  	"sort"
    11  	"strings"
    12  	"text/tabwriter"
    13  	"time"
    14  
    15  	"go-hep.org/x/hep/sio"
    16  )
    17  
    18  // RunHeader provides metadata about a Run.
    19  type RunHeader struct {
    20  	RunNumber    int32
    21  	Detector     string
    22  	Descr        string
    23  	SubDetectors []string
    24  	Params       Params
    25  }
    26  
    27  func (hdr *RunHeader) String() string {
    28  	o := new(strings.Builder)
    29  	fmt.Fprintf(o, "%s\n", strings.Repeat("=", 80))
    30  	fmt.Fprintf(o, "        Run:   %d\n", hdr.RunNumber)
    31  	fmt.Fprintf(o, "%s\n", strings.Repeat("=", 80))
    32  	fmt.Fprintf(o, " description: %s\n", hdr.Descr)
    33  	fmt.Fprintf(o, " detector   : %s\n", hdr.Detector)
    34  	fmt.Fprintf(o, " sub-dets   : %v\n", hdr.SubDetectors)
    35  	fmt.Fprintf(o, " parameters :\n%v\n", hdr.Params)
    36  	return o.String()
    37  }
    38  
    39  func (*RunHeader) VersionSio() uint32 {
    40  	return Version
    41  }
    42  
    43  func (hdr *RunHeader) MarshalSio(w sio.Writer) error {
    44  	enc := sio.NewEncoder(w)
    45  	enc.Encode(&hdr.RunNumber)
    46  	enc.Encode(&hdr.Detector)
    47  	enc.Encode(&hdr.Descr)
    48  	enc.Encode(&hdr.SubDetectors)
    49  	enc.Encode(&hdr.Params)
    50  	return enc.Err()
    51  }
    52  
    53  func (hdr *RunHeader) UnmarshalSio(r sio.Reader) error {
    54  	dec := sio.NewDecoder(r)
    55  	dec.Decode(&hdr.RunNumber)
    56  	dec.Decode(&hdr.Detector)
    57  	dec.Decode(&hdr.Descr)
    58  	dec.Decode(&hdr.SubDetectors)
    59  	dec.Decode(&hdr.Params)
    60  	return dec.Err()
    61  }
    62  
    63  // EventHeader provides metadata about an Event.
    64  type EventHeader struct {
    65  	RunNumber   int32
    66  	EventNumber int32
    67  	TimeStamp   int64
    68  	Detector    string
    69  	Blocks      []BlockDescr
    70  	Params      Params
    71  }
    72  
    73  func (hdr *EventHeader) String() string {
    74  	o := new(strings.Builder)
    75  	fmt.Fprintf(o, "%s\n", strings.Repeat("=", 80))
    76  	fmt.Fprintf(o, "        Event  : %d - run:   %d - timestamp %v - weight %v\n",
    77  		hdr.EventNumber, hdr.RunNumber, hdr.TimeStamp, hdr.Weight(),
    78  	)
    79  	fmt.Fprintf(o, "%s\n", strings.Repeat("=", 80))
    80  	fmt.Fprintf(o, " date       %v\n", time.Unix(0, hdr.TimeStamp).UTC().Format("02.01.2006 15:04:05.999999999"))
    81  	fmt.Fprintf(o, " detector : %s\n", hdr.Detector)
    82  	fmt.Fprintf(o, " event parameters:\n%v", hdr.Params)
    83  
    84  	w := tabwriter.NewWriter(o, 8, 4, 1, ' ', 0)
    85  	for _, blk := range hdr.Blocks {
    86  		fmt.Fprintf(w, " collection name : %s\t(%s)\n", blk.Name, blk.Type)
    87  	}
    88  	w.Flush()
    89  
    90  	return o.String()
    91  }
    92  
    93  func (*EventHeader) VersionSio() uint32 {
    94  	return Version
    95  }
    96  
    97  func (hdr *EventHeader) MarshalSio(w sio.Writer) error {
    98  	enc := sio.NewEncoder(w)
    99  	enc.Encode(&hdr.RunNumber)
   100  	enc.Encode(&hdr.EventNumber)
   101  	enc.Encode(&hdr.TimeStamp)
   102  	enc.Encode(&hdr.Detector)
   103  	enc.Encode(&hdr.Blocks)
   104  	enc.Encode(&hdr.Params)
   105  	return enc.Err()
   106  }
   107  
   108  func (hdr *EventHeader) UnmarshalSio(r sio.Reader) error {
   109  	dec := sio.NewDecoder(r)
   110  	dec.Decode(&hdr.RunNumber)
   111  	dec.Decode(&hdr.EventNumber)
   112  	dec.Decode(&hdr.TimeStamp)
   113  	dec.Decode(&hdr.Detector)
   114  	dec.Decode(&hdr.Blocks)
   115  	dec.Decode(&hdr.Params)
   116  	return dec.Err()
   117  }
   118  
   119  func (hdr *EventHeader) Weight() float64 {
   120  	if v, ok := hdr.Params.Floats["_weight"]; ok {
   121  		return float64(v[0])
   122  	}
   123  	return 1.0
   124  }
   125  
   126  // BlockDescr describes a SIO block.
   127  // BlockDescr provides the name of the SIO block and the type name of the
   128  // data stored in that block.
   129  type BlockDescr struct {
   130  	Name string
   131  	Type string
   132  }
   133  
   134  type Params struct {
   135  	Ints    map[string][]int32
   136  	Floats  map[string][]float32
   137  	Strings map[string][]string
   138  }
   139  
   140  func (p Params) String() string {
   141  	o := new(strings.Builder)
   142  	{
   143  		keys := make([]string, 0, len(p.Ints))
   144  		for k := range p.Ints {
   145  			keys = append(keys, k)
   146  		}
   147  		sort.Strings(keys)
   148  		for _, k := range keys {
   149  			vec := p.Ints[k]
   150  			fmt.Fprintf(o, " parameter %s [int]: ", k)
   151  			if len(vec) == 0 {
   152  				fmt.Fprintf(o, " [empty] \n")
   153  			}
   154  			for _, v := range vec {
   155  				fmt.Fprintf(o, "%v, ", v)
   156  			}
   157  			fmt.Fprintf(o, "\n")
   158  		}
   159  	}
   160  	{
   161  		keys := make([]string, 0, len(p.Floats))
   162  		for k := range p.Floats {
   163  			keys = append(keys, k)
   164  		}
   165  		sort.Strings(keys)
   166  		for _, k := range keys {
   167  			vec := p.Strings[k]
   168  			fmt.Fprintf(o, " parameter %s [float]: ", k)
   169  			if len(vec) == 0 {
   170  				fmt.Fprintf(o, " [empty] \n")
   171  			}
   172  			for _, v := range vec {
   173  				fmt.Fprintf(o, "%v, ", v)
   174  			}
   175  			fmt.Fprintf(o, "\n")
   176  		}
   177  	}
   178  	{
   179  		keys := make([]string, 0, len(p.Strings))
   180  		for k := range p.Floats {
   181  			keys = append(keys, k)
   182  		}
   183  		sort.Strings(keys)
   184  		for _, k := range keys {
   185  			vec := p.Strings[k]
   186  			fmt.Fprintf(o, " parameter %s [string]: ", k)
   187  			if len(vec) == 0 {
   188  				fmt.Fprintf(o, " [empty] \n")
   189  			}
   190  			for _, v := range vec {
   191  				fmt.Fprintf(o, "%v, ", v)
   192  			}
   193  			fmt.Fprintf(o, "\n")
   194  		}
   195  	}
   196  	return o.String()
   197  }
   198  
   199  func (*Params) VersionSio() uint32 {
   200  	return Version
   201  }
   202  
   203  func (p *Params) MarshalSio(w sio.Writer) error {
   204  	enc := sio.NewEncoder(w)
   205  	{
   206  		data := p.Ints
   207  		enc.Encode(int32(len(data)))
   208  		if n := len(data); n > 0 {
   209  			keys := make([]string, 0, n)
   210  			for k := range data {
   211  				keys = append(keys, k)
   212  			}
   213  			sort.Strings(keys)
   214  			for _, k := range keys {
   215  				enc.Encode(&k)
   216  				v := data[k]
   217  				enc.Encode(&v)
   218  			}
   219  		}
   220  	}
   221  	{
   222  		data := p.Floats
   223  		enc.Encode(int32(len(data)))
   224  		if n := len(data); n > 0 {
   225  			keys := make([]string, 0, n)
   226  			for k := range data {
   227  				keys = append(keys, k)
   228  			}
   229  			sort.Strings(keys)
   230  			for _, k := range keys {
   231  				enc.Encode(&k)
   232  				v := data[k]
   233  				enc.Encode(&v)
   234  			}
   235  		}
   236  	}
   237  	{
   238  		data := p.Strings
   239  		enc.Encode(int32(len(data)))
   240  		if n := len(data); n > 0 {
   241  			keys := make([]string, 0, n)
   242  			for k := range data {
   243  				keys = append(keys, k)
   244  			}
   245  			sort.Strings(keys)
   246  			for _, k := range keys {
   247  				enc.Encode(&k)
   248  				v := data[k]
   249  				enc.Encode(&v)
   250  			}
   251  		}
   252  	}
   253  	return enc.Err()
   254  }
   255  
   256  func (p *Params) UnmarshalSio(r sio.Reader) error {
   257  	dec := sio.NewDecoder(r)
   258  	dec.Decode(&p.Ints)
   259  	dec.Decode(&p.Floats)
   260  	dec.Decode(&p.Strings)
   261  	return dec.Err()
   262  }
   263  
   264  // Event holds informations about an LCIO event.
   265  // Event also holds collection data for that event.
   266  type Event struct {
   267  	RunNumber   int32
   268  	EventNumber int32
   269  	TimeStamp   int64
   270  	Detector    string
   271  	Params      Params
   272  	colls       map[string]any
   273  	names       []string
   274  }
   275  
   276  // Names returns the event data labels that define this event.
   277  func (evt *Event) Names() []string {
   278  	return evt.names
   279  }
   280  
   281  // Get returns the event data labelled name.
   282  func (evt *Event) Get(name string) any {
   283  	return evt.colls[name]
   284  }
   285  
   286  // Has returns whether this event has data named name.
   287  func (evt *Event) Has(name string) bool {
   288  	_, ok := evt.colls[name]
   289  	return ok
   290  }
   291  
   292  // Add attaches the (pointer to the) data ptr to this event,
   293  // with the given name.
   294  // Add panics if there is already some data labelled with the same name.
   295  // Add panics if ptr is not a pointer to some data.
   296  func (evt *Event) Add(name string, ptr any) {
   297  	if _, dup := evt.colls[name]; dup {
   298  		panic(fmt.Errorf("lcio: duplicate key %q", name))
   299  	}
   300  	evt.names = append(evt.names, name)
   301  	if evt.colls == nil {
   302  		evt.colls = make(map[string]any)
   303  	}
   304  	if rv := reflect.ValueOf(ptr); rv.Type().Kind() != reflect.Ptr {
   305  		panic("lcio: expects a pointer to a value")
   306  	}
   307  	evt.colls[name] = ptr
   308  }
   309  
   310  func (evt *Event) String() string {
   311  	o := new(strings.Builder)
   312  	fmt.Fprintf(o, "%s\n", strings.Repeat("=", 80))
   313  	fmt.Fprintf(o, "        Event  : %d - run:   %d - timestamp %v - weight %v\n",
   314  		evt.EventNumber, evt.RunNumber, evt.TimeStamp, evt.Weight(),
   315  	)
   316  	fmt.Fprintf(o, "%s\n", strings.Repeat("=", 80))
   317  	fmt.Fprintf(o, " date       %v\n", time.Unix(0, evt.TimeStamp).UTC().Format("02.01.2006 15:04:05.999999999"))
   318  	fmt.Fprintf(o, " detector : %s\n", evt.Detector)
   319  	fmt.Fprintf(o, " event parameters:\n%v\n", evt.Params)
   320  
   321  	for _, name := range evt.names {
   322  		coll := evt.colls[name]
   323  		fmt.Fprintf(o, " collection name : %s\n parameters: \n%v\n", name, coll)
   324  	}
   325  	return o.String()
   326  }
   327  
   328  func (evt *Event) Weight() float64 {
   329  	if v, ok := evt.Params.Floats["_weight"]; ok {
   330  		return float64(v[0])
   331  	}
   332  	return 1.0
   333  }
   334  
   335  var (
   336  	_ sio.Versioner = (*RunHeader)(nil)
   337  	_ sio.Codec     = (*RunHeader)(nil)
   338  	_ sio.Versioner = (*EventHeader)(nil)
   339  	_ sio.Codec     = (*EventHeader)(nil)
   340  	_ sio.Versioner = (*Params)(nil)
   341  	_ sio.Codec     = (*Params)(nil)
   342  )