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 }