go-hep.org/x/hep@v0.38.1/lcio/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 lcio 6 7 import ( 8 "compress/flate" 9 10 "go-hep.org/x/hep/sio" 11 ) 12 13 // Create creates a new LCIO writer, saving data in file fname. 14 func Create(fname string) (*Writer, error) { 15 f, err := sio.Create(fname) 16 if err != nil { 17 return nil, err 18 } 19 w := &Writer{ 20 f: f, 21 clvl: flate.DefaultCompression, 22 } 23 w.err = w.init() 24 return w, w.err 25 } 26 27 // Writer provides a way to write LCIO RunHeaders and Events to an 28 // output SIO stream. 29 type Writer struct { 30 f *sio.Stream 31 clvl int 32 recs struct { 33 idx *sio.Record 34 rnd *sio.Record 35 rhdr *sio.Record 36 ehdr *sio.Record 37 evt *sio.Record 38 } 39 data struct { 40 idx Index 41 rnd RandomAccess 42 rhdr RunHeader 43 ehdr EventHeader 44 } 45 closed bool 46 err error 47 } 48 49 // Close closes the underlying output stream and makes it unavailable for 50 // further I/O operations. 51 // Close will synchronize and commit to disk any lingering data before closing 52 // the output stream. 53 func (w *Writer) Close() error { 54 if w.closed { 55 return w.err 56 } 57 w.err = w.f.Sync() 58 if w.err != nil { 59 return w.err 60 } 61 w.err = w.f.Close() 62 w.closed = true 63 return w.err 64 } 65 66 func (w *Writer) init() error { 67 var ( 68 err error 69 rec *sio.Record 70 ) 71 72 rec = w.f.Record(Records.Index) 73 if rec != nil { 74 err = rec.Connect(Blocks.Index, &w.data.idx) 75 if err != nil { 76 return err 77 } 78 } 79 w.recs.idx = rec 80 81 rec = w.f.Record(Records.RandomAccess) 82 if rec != nil { 83 err = rec.Connect(Blocks.RandomAccess, &w.data.rnd) 84 if err != nil { 85 return err 86 } 87 } 88 w.recs.rnd = rec 89 90 rec = w.f.Record(Records.RunHeader) 91 if rec != nil { 92 err = rec.Connect(Blocks.RunHeader, &w.data.rhdr) 93 if err != nil { 94 return err 95 } 96 } 97 w.recs.rhdr = rec 98 99 rec = w.f.Record(Records.EventHeader) 100 if rec != nil { 101 err = rec.Connect(Blocks.EventHeader, &w.data.ehdr) 102 if err != nil { 103 return err 104 } 105 } 106 w.recs.ehdr = rec 107 108 rec = w.f.Record(Records.Event) 109 w.recs.evt = rec 110 111 w.SetCompressionLevel(w.clvl) 112 return nil 113 } 114 115 // SetCompressionLevel sets the compression level to lvl. 116 // lvl must be a compress/flate compression value. 117 // SetCompressionLevel must be called before WriteRunHeader or WriteEvent. 118 func (w *Writer) SetCompressionLevel(lvl int) { 119 w.clvl = lvl 120 compress := w.clvl != flate.NoCompression 121 w.f.SetCompressionLevel(lvl) 122 for _, rec := range []*sio.Record{ 123 w.recs.idx, 124 w.recs.rnd, 125 w.recs.rhdr, 126 w.recs.ehdr, 127 w.recs.evt, 128 } { 129 if rec == nil { 130 continue 131 } 132 rec.SetCompress(compress) 133 } 134 } 135 136 func (w *Writer) WriteRunHeader(run *RunHeader) error { 137 if w.err != nil { 138 return w.err 139 } 140 w.data.rhdr = *run 141 w.data.rhdr.SubDetectors = make([]string, len(run.SubDetectors)) 142 copy(w.data.rhdr.SubDetectors, run.SubDetectors) 143 144 w.err = w.f.WriteRecord(w.recs.rhdr) 145 return w.err 146 } 147 148 func (w *Writer) WriteEvent(evt *Event) error { 149 if w.err != nil { 150 return w.err 151 } 152 w.data.ehdr.RunNumber = evt.RunNumber 153 w.data.ehdr.EventNumber = evt.EventNumber 154 w.data.ehdr.TimeStamp = evt.TimeStamp 155 w.data.ehdr.Detector = evt.Detector 156 w.data.ehdr.Blocks = make([]BlockDescr, len(evt.names)) 157 for i, n := range evt.names { 158 w.data.ehdr.Blocks[i] = BlockDescr{Name: n, Type: typeName(evt.colls[n])} 159 } 160 w.data.ehdr.Params = evt.Params 161 162 w.err = w.f.WriteRecord(w.recs.ehdr) 163 if w.err != nil { 164 return w.err 165 } 166 167 w.recs.evt.Disconnect() 168 169 for _, name := range evt.names { 170 coll := evt.colls[name] 171 w.err = w.recs.evt.Connect(name, coll) 172 if w.err != nil { 173 return w.err 174 } 175 } 176 177 w.err = w.f.WriteRecord(w.recs.evt) 178 if w.err != nil { 179 return w.err 180 } 181 182 return w.err 183 }