go-hep.org/x/hep@v0.38.1/lhef/writer.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 lhef
     6  
     7  import (
     8  	"fmt"
     9  	"io"
    10  	"sync"
    11  )
    12  
    13  // Encoder encodes a LHEF event to the underlying writer, following the
    14  // Les Houches Event File format.
    15  type Encoder struct {
    16  	w      io.Writer
    17  	once   sync.Once
    18  	Run    HEPRUP // User process run common block
    19  	Header []byte // header block data
    20  
    21  }
    22  
    23  // NewEncoder creates a new Encoder connected to the given writer.
    24  func NewEncoder(w io.Writer) (*Encoder, error) {
    25  	enc := &Encoder{
    26  		w: w,
    27  	}
    28  	return enc, nil
    29  }
    30  
    31  func (e *Encoder) init() error {
    32  
    33  	var err error
    34  	run := &e.Run
    35  
    36  	version := 1.0
    37  	if run.XSecInfo.Neve > 0 {
    38  		version = 2.0
    39  		panic("not implemented")
    40  	}
    41  	_, err = fmt.Fprintf(
    42  		e.w,
    43  		"<LesHouchesEvents version=\"%0.1f\">\n",
    44  		version,
    45  	)
    46  
    47  	if err != nil {
    48  		return err
    49  	}
    50  
    51  	if len(e.Header) > 0 {
    52  		hdr := string(e.Header)
    53  		if hdr[len(hdr)-1] == '\n' {
    54  			hdr = hdr[:len(hdr)-1]
    55  		}
    56  		_, err = fmt.Fprintf(
    57  			e.w,
    58  			"<header>\n%v\n</header>\n",
    59  			hdr,
    60  		)
    61  		if err != nil {
    62  			return err
    63  		}
    64  	}
    65  
    66  	_, err = fmt.Fprintf(
    67  		e.w,
    68  		"<init>\n %7d %7d %13.6E %13.6E %5d %5d %5d %5d %5d %5d\n",
    69  		run.IDBMUP[0], run.IDBMUP[1],
    70  		run.EBMUP[0], run.EBMUP[1],
    71  		run.PDFGUP[0], run.PDFGUP[1],
    72  		run.PDFSUP[0], run.PDFSUP[1],
    73  		run.IDWTUP, run.NPRUP,
    74  	)
    75  	if err != nil {
    76  		return err
    77  	}
    78  
    79  	for i := range int(run.NPRUP) {
    80  		_, err = fmt.Fprintf(
    81  			e.w,
    82  			" %13.6E %13.6E %13.6E %5d\n",
    83  			run.XSECUP[i],
    84  			run.XERRUP[i],
    85  			run.XMAXUP[i],
    86  			run.LPRUP[i],
    87  		)
    88  		if err != nil {
    89  			return err
    90  		}
    91  	}
    92  
    93  	if run.XSecInfo.Neve <= 0 {
    94  		_, err = fmt.Fprintf(
    95  			e.w,
    96  			"#%s\n</init>\n",
    97  			"",
    98  		)
    99  		return err
   100  	}
   101  
   102  	return err
   103  }
   104  
   105  func (e *Encoder) Encode(evt *HEPEUP) error {
   106  	var err error
   107  	e.once.Do(func() { err = e.init() })
   108  	if err != nil {
   109  		return err
   110  	}
   111  
   112  	if len(evt.SubEvents.Events) > 0 {
   113  		_, err = fmt.Fprintf(e.w, "<eventgroup")
   114  		if err != nil {
   115  			return err
   116  		}
   117  		if evt.SubEvents.Nreal > 0 {
   118  			_, err = fmt.Fprintf(e.w, " nreal=\"%d\"", evt.SubEvents.Nreal)
   119  			if err != nil {
   120  				return err
   121  			}
   122  		}
   123  		if evt.SubEvents.Ncounter > 0 {
   124  			_, err = fmt.Fprintf(e.w, " ncounter=\"%d\"", evt.SubEvents.Ncounter)
   125  			if err != nil {
   126  				return err
   127  			}
   128  		}
   129  		_, err = fmt.Fprintf(e.w, "</eventgroup>\n")
   130  		if err != nil {
   131  			return err
   132  		}
   133  	}
   134  
   135  	_, err = fmt.Fprintf(
   136  		e.w,
   137  		"<event>\n %5d %5d %13.6E %13.6E %13.6E %13.6E\n",
   138  		evt.NUP,
   139  		evt.IDPRUP,
   140  		evt.XWGTUP,
   141  		evt.SCALUP,
   142  		evt.AQEDUP,
   143  		evt.AQCDUP,
   144  	)
   145  	if err != nil {
   146  		return err
   147  	}
   148  
   149  	for i := range int(evt.NUP) {
   150  		_, err = fmt.Fprintf(
   151  			e.w,
   152  			" %7d %4d %4d %4d %4d %4d %17.10E %17.10E %17.10E %17.10E %17.10E %1.f. %1.f.\n",
   153  			evt.IDUP[i],
   154  			evt.ISTUP[i],
   155  			evt.MOTHUP[i][0], evt.MOTHUP[i][1],
   156  			evt.ICOLUP[i][0], evt.ICOLUP[i][1],
   157  			evt.PUP[i][0], evt.PUP[i][1], evt.PUP[i][2], evt.PUP[i][3], evt.PUP[i][4],
   158  			evt.VTIMUP[i],
   159  			evt.SPINUP[i],
   160  		)
   161  		if err != nil {
   162  			return err
   163  		}
   164  	}
   165  
   166  	if e.Run.XSecInfo.Neve > 0 {
   167  		panic("not implemented")
   168  	}
   169  
   170  	_, err = fmt.Fprintf(
   171  		e.w,
   172  		"#%s\n</event>\n",
   173  		"",
   174  	)
   175  
   176  	return err
   177  }
   178  
   179  func (e *Encoder) Close() error {
   180  
   181  	_, err := fmt.Fprintf(
   182  		e.w,
   183  		"</LesHouchesEvents>\n",
   184  	)
   185  	if err != nil {
   186  		return err
   187  	}
   188  
   189  	if w, ok := e.w.(io.WriteCloser); ok {
   190  		err = w.Close()
   191  	}
   192  	return err
   193  }