go-hep.org/x/hep@v0.38.1/hepevt/ascii_io.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 hepevt
     6  
     7  import (
     8  	"fmt"
     9  	"io"
    10  )
    11  
    12  // Encoder encodes ASCII files in the HEPEVT format.
    13  type Encoder struct {
    14  	w io.Writer
    15  }
    16  
    17  // NewEncoder create a new Encoder, writing to the provided io.Writer.
    18  func NewEncoder(w io.Writer) *Encoder {
    19  	return &Encoder{w: w}
    20  }
    21  
    22  // Encode encodes a full HEPEVT event to the underlying writer.
    23  func (enc *Encoder) Encode(evt *Event) error {
    24  	_, err := fmt.Fprintf(enc.w, "%d %d\n", evt.Nevhep, evt.Nhep)
    25  	if err != nil {
    26  		return fmt.Errorf("could not encode event header line: %w", err)
    27  	}
    28  
    29  	for i := range evt.Nhep {
    30  		_, err = fmt.Fprintf(
    31  			enc.w,
    32  			"%d %d %d %d %d %d %E %E %E %E %E %E %E %E %E\n",
    33  			evt.Isthep[i],
    34  			evt.Idhep[i],
    35  			// convert 0-based indices to 1-based ones
    36  			evt.Jmohep[i][0]+1, evt.Jmohep[i][1]+1,
    37  			evt.Jdahep[i][0]+1, evt.Jdahep[i][1]+1,
    38  			// <---
    39  			evt.Phep[i][0], evt.Phep[i][1], evt.Phep[i][2], evt.Phep[i][3],
    40  			evt.Phep[i][4],
    41  			evt.Vhep[i][0], evt.Vhep[i][1], evt.Vhep[i][2], evt.Vhep[i][3],
    42  		)
    43  		if err != nil {
    44  			return fmt.Errorf("could not encode event particle line[%d]: %w", i, err)
    45  		}
    46  	}
    47  	return nil
    48  }
    49  
    50  // Decoder decodes ASCII files in the HEPEVT format.
    51  type Decoder struct {
    52  	r io.Reader
    53  }
    54  
    55  // NewDecoder creates a new Decoder, reading from the provided io.Reader.
    56  func NewDecoder(r io.Reader) *Decoder {
    57  	return &Decoder{r: r}
    58  }
    59  
    60  // Decode decodes a full HEPEVT event from the underlying reader.
    61  func (dec *Decoder) Decode(evt *Event) error {
    62  	_, err := fmt.Fscanf(dec.r, "%d %d\n", &evt.Nevhep, &evt.Nhep)
    63  	if err != nil {
    64  		return fmt.Errorf("could not decode event header line: %w", err)
    65  	}
    66  
    67  	// resize
    68  	if len(evt.Isthep) > evt.Nhep {
    69  		evt.Isthep = evt.Isthep[:evt.Nhep]
    70  		evt.Idhep = evt.Idhep[:evt.Nhep]
    71  		evt.Jmohep = evt.Jmohep[:evt.Nhep]
    72  		evt.Jdahep = evt.Jdahep[:evt.Nhep]
    73  		evt.Phep = evt.Phep[:evt.Nhep]
    74  		evt.Vhep = evt.Vhep[:evt.Nhep]
    75  	} else {
    76  		sz := evt.Nhep - len(evt.Isthep)
    77  		evt.Isthep = append(evt.Isthep, make([]int, sz)...)
    78  		evt.Idhep = append(evt.Idhep, make([]int, sz)...)
    79  		evt.Jmohep = append(evt.Jmohep, make([][2]int, sz)...)
    80  		evt.Jdahep = append(evt.Jdahep, make([][2]int, sz)...)
    81  		evt.Phep = append(evt.Phep, make([][5]float64, sz)...)
    82  		evt.Vhep = append(evt.Vhep, make([][4]float64, sz)...)
    83  	}
    84  
    85  	for i := range evt.Nhep {
    86  		_, err = fmt.Fscanf(
    87  			dec.r,
    88  			"%d %d %d %d %d %d %E %E %E %E %E %E %E %E %E\n",
    89  			&evt.Isthep[i],
    90  			&evt.Idhep[i],
    91  			&evt.Jmohep[i][0], &evt.Jmohep[i][1],
    92  			&evt.Jdahep[i][0], &evt.Jdahep[i][1],
    93  			&evt.Phep[i][0], &evt.Phep[i][1], &evt.Phep[i][2], &evt.Phep[i][3],
    94  			&evt.Phep[i][4],
    95  			&evt.Vhep[i][0], &evt.Vhep[i][1], &evt.Vhep[i][2], &evt.Vhep[i][3],
    96  		)
    97  		if err != nil {
    98  			return fmt.Errorf("could not decode event line[%d]: %w", i, err)
    99  		}
   100  		// convert 0-based indices to 1-based ones
   101  		evt.Jmohep[i][0] -= 1
   102  		evt.Jmohep[i][1] -= 1
   103  		evt.Jdahep[i][0] -= 1
   104  		evt.Jdahep[i][1] -= 1
   105  	}
   106  	return nil
   107  }