go-hep.org/x/hep@v0.38.1/lcio/reader.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  
    10  	"go-hep.org/x/hep/sio"
    11  )
    12  
    13  func Open(fname string) (*Reader, error) {
    14  	f, err := sio.Open(fname)
    15  	if err != nil {
    16  		return nil, err
    17  	}
    18  	r := &Reader{
    19  		f: f,
    20  	}
    21  	err = r.init()
    22  	if err != nil {
    23  		return nil, err
    24  	}
    25  	return r, nil
    26  }
    27  
    28  type Reader struct {
    29  	f    *sio.Stream
    30  	idx  Index
    31  	rnd  RandomAccess
    32  	rhdr RunHeader
    33  	ehdr EventHeader
    34  	evt  Event
    35  	err  error
    36  }
    37  
    38  func (r *Reader) Close() error {
    39  	return r.f.Close()
    40  }
    41  
    42  func (r *Reader) init() error {
    43  	var (
    44  		err error
    45  		rec *sio.Record
    46  	)
    47  
    48  	rec = r.f.Record(Records.Index)
    49  	if rec != nil {
    50  		rec.SetUnpack(true)
    51  		err = rec.Connect(Blocks.Index, &r.idx)
    52  		if err != nil {
    53  			return err
    54  		}
    55  	}
    56  
    57  	rec = r.f.Record(Records.RandomAccess)
    58  	if rec != nil {
    59  		rec.SetUnpack(true)
    60  		err = rec.Connect(Blocks.RandomAccess, &r.rnd)
    61  		if err != nil {
    62  			return err
    63  		}
    64  	}
    65  
    66  	rec = r.f.Record(Records.RunHeader)
    67  	if rec != nil {
    68  		rec.SetUnpack(true)
    69  		err = rec.Connect(Blocks.RunHeader, &r.rhdr)
    70  		if err != nil {
    71  			return err
    72  		}
    73  	}
    74  
    75  	rec = r.f.Record(Records.EventHeader)
    76  	if rec != nil {
    77  		rec.SetUnpack(true)
    78  		err = rec.Connect(Blocks.EventHeader, &r.ehdr)
    79  		if err != nil {
    80  			return err
    81  		}
    82  	}
    83  
    84  	rec = r.f.Record(Records.Event)
    85  	if rec != nil {
    86  		rec.SetUnpack(true)
    87  	}
    88  
    89  	return nil
    90  }
    91  
    92  func (r *Reader) Next() bool {
    93  	if r.err != nil {
    94  		return false
    95  	}
    96  	rec, err := r.f.ReadRecord()
    97  	if err != nil {
    98  		r.err = err
    99  		return false
   100  	}
   101  	// log.Printf(">>> %q", rec.Name())
   102  	switch rec.Name() {
   103  	case Records.Index:
   104  		if !rec.Unpack() {
   105  			r.err = fmt.Errorf("lcio: expected record %q to unpack", rec.Name())
   106  			return false
   107  		}
   108  		return r.Next()
   109  
   110  	case Records.RandomAccess:
   111  		if !rec.Unpack() {
   112  			r.err = fmt.Errorf("lcio: expected record %q to unpack", rec.Name())
   113  			return false
   114  		}
   115  		return r.Next()
   116  
   117  	case Records.RunHeader:
   118  		if !rec.Unpack() {
   119  			r.err = fmt.Errorf("lcio: expected record %q to unpack", rec.Name())
   120  			return false
   121  		}
   122  		return r.Next()
   123  
   124  	case Records.EventHeader:
   125  		if !rec.Unpack() {
   126  			r.err = fmt.Errorf("lcio: expected record %q to unpack", rec.Name())
   127  			return false
   128  		}
   129  		err = r.remap()
   130  		if err != nil {
   131  			r.err = err
   132  			return false
   133  		}
   134  		return r.Next()
   135  
   136  	case Records.Event:
   137  		if !rec.Unpack() {
   138  			r.err = fmt.Errorf("lcio: expected record %q to unpack", rec.Name())
   139  		}
   140  	}
   141  	return true
   142  }
   143  
   144  func (r *Reader) remap() error {
   145  	var err error
   146  	rec := r.f.Record(Records.Event)
   147  	r.evt.colls = nil
   148  	r.evt.names = nil
   149  	if len(r.ehdr.Blocks) > 0 {
   150  		r.evt.colls = make(map[string]any, len(r.ehdr.Blocks))
   151  		r.evt.names = make([]string, 0, len(r.ehdr.Blocks))
   152  		for _, blk := range r.ehdr.Blocks {
   153  			ptr := typeFrom(blk.Type)
   154  			if ptr == nil {
   155  				continue
   156  			}
   157  			err = rec.Connect(blk.Name, ptr)
   158  			if err != nil {
   159  				r.err = err
   160  				return err
   161  			}
   162  			r.evt.colls[blk.Name] = ptr
   163  			r.evt.names = append(r.evt.names, blk.Name)
   164  		}
   165  	}
   166  	r.evt.RunNumber = r.ehdr.RunNumber
   167  	r.evt.EventNumber = r.ehdr.EventNumber
   168  	r.evt.TimeStamp = r.ehdr.TimeStamp
   169  	r.evt.Detector = r.ehdr.Detector
   170  	r.evt.Params = r.ehdr.Params
   171  	return err
   172  }
   173  
   174  func (r *Reader) RunHeader() RunHeader {
   175  	return r.rhdr
   176  }
   177  
   178  func (r *Reader) EventHeader() EventHeader {
   179  	return r.ehdr
   180  }
   181  
   182  func (r *Reader) Event() Event {
   183  	return r.evt
   184  }
   185  
   186  func (r *Reader) Err() error {
   187  	return r.err
   188  }