go-hep.org/x/hep@v0.38.1/hepmc/hepmc_test.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 hepmc_test 6 7 import ( 8 "bytes" 9 "fmt" 10 "io" 11 "log" 12 "os" 13 "testing" 14 15 "go-hep.org/x/hep/fmom" 16 "go-hep.org/x/hep/hepmc" 17 "go-hep.org/x/hep/internal/diff" 18 ) 19 20 func TestEventRW(t *testing.T) { 21 for _, table := range []struct { 22 fname string 23 outfname string 24 nevts int 25 }{ 26 {"testdata/small.hepmc", "out.small.hepmc", 1}, 27 {"testdata/test.hepmc", "out.hepmc", 6}, 28 {"out.hepmc", "rb.out.hepmc", 6}, 29 } { 30 t.Run(table.fname, func(t *testing.T) { 31 testEventRW(t, table.fname, table.outfname, table.nevts) 32 }) 33 } 34 35 // clean-up 36 for _, fname := range []string{"out.small.hepmc", "out.hepmc", "rb.out.hepmc"} { 37 err := os.Remove(fname) 38 if err != nil { 39 t.Fatal(err) 40 } 41 } 42 } 43 44 func testEventRW(t *testing.T, fname, outfname string, nevts int) { 45 f, err := os.Open(fname) 46 if err != nil { 47 t.Fatal(err) 48 } 49 defer f.Close() 50 51 dec := hepmc.NewDecoder(f) 52 if dec == nil { 53 t.Fatalf("hepmc.decoder: nil decoder") 54 } 55 56 const NEVTS = 10 57 evts := make([]*hepmc.Event, 0, NEVTS) 58 for ievt := range NEVTS { 59 var evt hepmc.Event 60 err = dec.Decode(&evt) 61 if err != nil { 62 if err == io.EOF && ievt == nevts { 63 break 64 } 65 t.Fatalf("file: %s. ievt=%d err=%v\n", fname, ievt, err) 66 } 67 evts = append(evts, &evt) 68 defer func() { 69 err = hepmc.Delete(&evt) 70 if err != nil { 71 t.Fatalf("error: %+v", err) 72 } 73 }() 74 } 75 76 o, err := os.Create(outfname) 77 if err != nil { 78 t.Fatal(err) 79 } 80 defer o.Close() 81 82 enc := hepmc.NewEncoder(o) 83 if enc == nil { 84 t.Fatal(fmt.Errorf("hepmc.encoder: nil encoder")) 85 } 86 for _, evt := range evts { 87 err = enc.Encode(evt) 88 if err != nil { 89 t.Fatalf("file: %s. err=%v\n", fname, err) 90 } 91 } 92 err = enc.Close() 93 if err != nil { 94 t.Fatalf("file: %s. err=%v\n", fname, err) 95 } 96 97 err = o.Close() 98 if err != nil { 99 t.Fatalf("error closing output file %q: %v", outfname, err) 100 } 101 102 // test output files 103 err = diff.Files(outfname, fname) 104 if err != nil { 105 t.Fatalf("file: %s\n%+v", fname, err) 106 } 107 } 108 109 type reader struct { 110 header []byte 111 footer []byte 112 data []byte 113 pos int 114 } 115 116 func newReader() *reader { 117 r := &reader{ 118 header: []byte(` 119 HepMC::Version 2.06.09 120 HepMC::IO_GenEvent-START_EVENT_LISTING 121 `), 122 data: []byte(`E 1 0 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 20 -3 4 0 0 0 0 123 U GEV MM 124 F 0 0 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 125 V -1 0 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1 1 0 126 P 1 2212 0.0000000000000000e+00 0.0000000000000000e+00 7.0000000000000000e+03 7.0000000000000000e+03 0.0000000000000000e+00 3 0.0000000000000000e+00 0.0000000000000000e+00 -1 0 127 P 3 1 7.5000000000000000e-01 -1.5690000000000000e+00 3.2191000000000003e+01 3.2238000000000000e+01 0.0000000000000000e+00 3 0.0000000000000000e+00 0.0000000000000000e+00 -3 0 128 V -2 0 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1 1 0 129 P 2 2212 0.0000000000000000e+00 0.0000000000000000e+00 -7.0000000000000000e+03 7.0000000000000000e+03 0.0000000000000000e+00 3 0.0000000000000000e+00 0.0000000000000000e+00 -2 0 130 P 4 -2 -3.0470000000000002e+00 -1.9000000000000000e+01 -5.4628999999999998e+01 5.7920000000000002e+01 0.0000000000000000e+00 3 0.0000000000000000e+00 0.0000000000000000e+00 -3 0 131 V -3 0 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 2 0 132 P 5 22 -3.8130000000000002e+00 1.1300000000000000e-01 -1.8330000000000000e+00 4.2329999999999997e+00 0.0000000000000000e+00 1 0.0000000000000000e+00 0.0000000000000000e+00 0 0 133 P 6 -24 1.5169999999999999e+00 -2.0680000000000000e+01 -2.0605000000000000e+01 8.5924999999999997e+01 0.0000000000000000e+00 3 0.0000000000000000e+00 0.0000000000000000e+00 -4 0 134 V -4 0 1.2000000000000000e-01 -2.9999999999999999e-01 5.0000000000000003e-02 4.0000000000000001e-03 0 2 0 135 P 7 1 -2.4449999999999998e+00 2.8815999999999999e+01 6.0819999999999999e+00 2.9552000000000000e+01 0.0000000000000000e+00 1 0.0000000000000000e+00 0.0000000000000000e+00 0 0 136 P 8 -2 3.9620000000000002e+00 -4.9497999999999998e+01 -2.6687000000000001e+01 5.6372999999999998e+01 0.0000000000000000e+00 1 0.0000000000000000e+00 0.0000000000000000e+00 0 0 137 `), 138 footer: []byte(`HepMC::IO_GenEvent-END_EVENT_LISTING 139 `), 140 } 141 142 return r 143 } 144 145 func (r *reader) Read(data []byte) (int, error) { 146 return r.read(data) 147 } 148 149 func (r *reader) read(dst []byte) (int, error) { 150 n := 0 151 for n < len(dst) { 152 // printf("::read - n=%d dst=%d...\n", n, len(dst)) 153 if len(r.header) > 0 { 154 // printf(":: header...\n") 155 sz := copy(dst, r.header) 156 n += sz 157 r.header = nil 158 } 159 end := len(dst[n:]) 160 if end > len(r.data[r.pos:]) { 161 end = len(r.data[r.pos:]) + r.pos 162 } 163 // printf(":: copy(dst[%d:], data[%d:%d])...\n", n, r.pos, end) 164 sz := copy(dst[n:], r.data[r.pos:end]) 165 // printf(":: copy(dst[%d:], data[%d:%d]) -> %d\n", n, r.pos, end, sz) 166 n += sz 167 if r.pos+sz >= len(r.data) { 168 r.pos = 0 169 } else { 170 r.pos += sz 171 } 172 } 173 return n, nil 174 } 175 176 func TestRead(t *testing.T) { 177 r := newReader() 178 dec := hepmc.NewDecoder(r) 179 if dec == nil { 180 t.Fatal(fmt.Errorf("hepmc.decoder: nil decoder")) 181 } 182 183 const NEVTS = 10 184 const fname = "small.hepmc" 185 for ievt := range NEVTS { 186 var evt hepmc.Event 187 err := dec.Decode(&evt) 188 if err != nil { 189 if err == io.EOF && ievt == NEVTS { 190 break 191 } 192 t.Fatalf("file: %s. ievt=%d err=%v\n", fname, ievt, err) 193 } 194 err = hepmc.Delete(&evt) 195 if err != nil { 196 t.Fatalf("error: %+v", err) 197 } 198 } 199 } 200 201 func BenchmarkDecode(b *testing.B) { 202 r := newReader() 203 dec := hepmc.NewDecoder(r) 204 if dec == nil { 205 b.Fatalf("hepmc.decoder: nil decoder") 206 } 207 208 const fname = "small.hepmc" 209 210 { 211 var evt hepmc.Event 212 err := dec.Decode(&evt) 213 if err != nil { 214 b.Fatalf("error: %v\n", err) 215 } 216 _ = hepmc.Delete(&evt) 217 } 218 219 b.ResetTimer() 220 221 for i := 0; i < b.N; i++ { 222 var evt hepmc.Event 223 err := dec.Decode(&evt) 224 if err != nil { 225 if err == io.EOF { 226 break 227 } 228 b.Fatalf("file: %s. ievt=%d err=%v\n", fname, i, err) 229 } 230 _ = hepmc.Delete(&evt) 231 } 232 233 } 234 235 // This example will place the following event into HepMC "by hand" 236 // 237 // name status pdg_id parent Px Py Pz Energy Mass 238 // 1 !p+! 3 2212 0,0 0.000 0.000 7000.000 7000.000 0.938 239 // 2 !p+! 3 2212 0,0 0.000 0.000-7000.000 7000.000 0.938 240 // 241 // ========================================================================= 242 // 243 // 3 !d! 3 1 1,1 0.750 -1.569 32.191 32.238 0.000 244 // 4 !u~! 3 -2 2,2 -3.047 -19.000 -54.629 57.920 0.000 245 // 5 !W-! 3 -24 1,2 1.517 -20.68 -20.605 85.925 80.799 246 // 6 !gamma! 1 22 1,2 -3.813 0.113 -1.833 4.233 0.000 247 // 7 !d! 1 1 5,5 -2.445 28.816 6.082 29.552 0.010 248 // 8 !u~! 1 -2 5,5 3.962 -49.498 -26.687 56.373 0.006 249 // 250 // now we build the graph, which will look like 251 // 252 // # p7 # 253 // # p1 / # 254 // # \v1__p3 p5---v4 # 255 // # \_v3_/ \ # 256 // # / \ p8 # 257 // # v2__p4 \ # 258 // # / p6 # 259 // # p2 # 260 // # # 261 func ExampleEvent_buildFromScratch() { 262 var err error 263 264 // first create the event container, with signal process 20, event number 1 265 evt := hepmc.Event{ 266 SignalProcessID: 20, 267 EventNumber: 1, 268 Particles: make(map[int]*hepmc.Particle), 269 Vertices: make(map[int]*hepmc.Vertex), 270 } 271 defer func() { 272 err = evt.Delete() 273 if err != nil { 274 log.Fatalf("could not clean-up event: %+v", err) 275 } 276 }() 277 278 // define the units 279 evt.MomentumUnit = hepmc.GEV 280 evt.LengthUnit = hepmc.MM 281 282 // create vertex 1 and 2, together with their in-particles 283 v1 := &hepmc.Vertex{} 284 err = evt.AddVertex(v1) 285 if err != nil { 286 log.Fatal(err) 287 } 288 289 err = v1.AddParticleIn(&hepmc.Particle{ 290 Momentum: fmom.NewPxPyPzE(0, 0, 7000, 7000), 291 PdgID: 2212, 292 Status: 3, 293 }) 294 if err != nil { 295 log.Fatal(err) 296 } 297 298 v2 := &hepmc.Vertex{} 299 err = evt.AddVertex(v2) 300 if err != nil { 301 log.Fatal(err) 302 } 303 304 err = v2.AddParticleIn(&hepmc.Particle{ 305 Momentum: fmom.NewPxPyPzE(0, 0, -7000, 7000), 306 PdgID: 2212, 307 Status: 3, 308 //Barcode: 2, 309 }) 310 if err != nil { 311 log.Fatal(err) 312 } 313 314 // create the outgoing particles of v1 and v2 315 p3 := &hepmc.Particle{ 316 Momentum: fmom.NewPxPyPzE(.750, -1.569, 32.191, 32.238), 317 PdgID: 1, 318 Status: 3, 319 // Barcode: 3, 320 } 321 err = v1.AddParticleOut(p3) 322 if err != nil { 323 log.Fatal(err) 324 } 325 326 p4 := &hepmc.Particle{ 327 Momentum: fmom.NewPxPyPzE(-3.047, -19., -54.629, 57.920), 328 PdgID: -2, 329 Status: 3, 330 // Barcode: 4, 331 } 332 err = v2.AddParticleOut(p4) 333 if err != nil { 334 log.Fatal(err) 335 } 336 337 // create v3 338 v3 := &hepmc.Vertex{} 339 err = evt.AddVertex(v3) 340 if err != nil { 341 log.Fatal(err) 342 } 343 344 err = v3.AddParticleIn(p3) 345 if err != nil { 346 log.Fatal(err) 347 } 348 349 err = v3.AddParticleIn(p4) 350 if err != nil { 351 log.Fatal(err) 352 } 353 354 err = v3.AddParticleOut(&hepmc.Particle{ 355 Momentum: fmom.NewPxPyPzE(-3.813, 0.113, -1.833, 4.233), 356 PdgID: 22, 357 Status: 1, 358 }) 359 if err != nil { 360 log.Fatal(err) 361 } 362 363 p5 := &hepmc.Particle{ 364 Momentum: fmom.NewPxPyPzE(1.517, -20.68, -20.605, 85.925), 365 PdgID: -24, 366 Status: 3, 367 } 368 err = v3.AddParticleOut(p5) 369 if err != nil { 370 log.Fatal(err) 371 } 372 373 // create v4 374 v4 := &hepmc.Vertex{ 375 Position: fmom.NewPxPyPzE(0.12, -0.3, 0.05, 0.004), 376 } 377 err = evt.AddVertex(v4) 378 if err != nil { 379 log.Fatal(err) 380 } 381 382 err = v4.AddParticleIn(p5) 383 if err != nil { 384 log.Fatal(err) 385 } 386 387 err = v4.AddParticleOut(&hepmc.Particle{ 388 Momentum: fmom.NewPxPyPzE(-2.445, 28.816, 6.082, 29.552), 389 PdgID: 1, 390 Status: 1, 391 }) 392 if err != nil { 393 log.Fatal(err) 394 } 395 396 err = v4.AddParticleOut(&hepmc.Particle{ 397 Momentum: fmom.NewPxPyPzE(3.962, -49.498, -26.687, 56.373), 398 PdgID: -2, 399 Status: 1, 400 }) 401 if err != nil { 402 log.Fatal(err) 403 } 404 405 evt.SignalVertex = v3 406 407 err = evt.Print(os.Stdout) 408 if err != nil { 409 log.Fatal(err) 410 } 411 412 out := new(bytes.Buffer) 413 enc := hepmc.NewEncoder(out) 414 err = enc.Encode(&evt) 415 if err != nil { 416 log.Fatal(err) 417 } 418 419 fmt.Printf("%s\n", out.Bytes()) 420 421 // Output: 422 // ________________________________________________________________________________ 423 // GenEvent: #0001 ID= 20 SignalProcessGenVertex Barcode: -3 424 // Momentum units: GEV Position units: MM 425 // Entries this event: 4 vertices, 8 particles. 426 // Beam Particles are not defined. 427 // RndmState(0)= 428 // Wgts(0)= 429 // EventScale 0.00000 [energy] alphaQCD=0.00000000 alphaQED=0.00000000 430 // GenParticle Legend 431 // Barcode PDG ID ( Px, Py, Pz, E ) Stat DecayVtx 432 // ________________________________________________________________________________ 433 // GenVertex: -1 ID: 0 (X,cT):0 434 // I: 1 1 2212 +0.00e+00,+0.00e+00,+7.00e+03,+7.00e+03 3 -1 435 // O: 1 3 1 +7.50e-01,-1.57e+00,+3.22e+01,+3.22e+01 3 -3 436 // GenVertex: -2 ID: 0 (X,cT):0 437 // I: 1 2 2212 +0.00e+00,+0.00e+00,-7.00e+03,+7.00e+03 3 -2 438 // O: 1 4 -2 -3.05e+00,-1.90e+01,-5.46e+01,+5.79e+01 3 -3 439 // GenVertex: -3 ID: 0 (X,cT):0 440 // I: 2 3 1 +7.50e-01,-1.57e+00,+3.22e+01,+3.22e+01 3 -3 441 // 4 -2 -3.05e+00,-1.90e+01,-5.46e+01,+5.79e+01 3 -3 442 // O: 2 5 22 -3.81e+00,+1.13e-01,-1.83e+00,+4.23e+00 1 443 // 6 -24 +1.52e+00,-2.07e+01,-2.06e+01,+8.59e+01 3 -4 444 // Vertex: -4 ID: 0 (X,cT)=+1.20e-01,-3.00e-01,+5.00e-02,+4.00e-03 445 // I: 1 6 -24 +1.52e+00,-2.07e+01,-2.06e+01,+8.59e+01 3 -4 446 // O: 2 7 1 -2.44e+00,+2.88e+01,+6.08e+00,+2.96e+01 1 447 // 8 -2 +3.96e+00,-4.95e+01,-2.67e+01,+5.64e+01 1 448 // ________________________________________________________________________________ 449 // 450 // HepMC::Version 2.06.09 451 // HepMC::IO_GenEvent-START_EVENT_LISTING 452 // E 1 0 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 20 -3 4 0 0 0 0 453 // U GEV MM 454 // F 0 0 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 0 455 // V -1 0 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1 1 0 456 // P 1 2212 0.0000000000000000e+00 0.0000000000000000e+00 7.0000000000000000e+03 7.0000000000000000e+03 0.0000000000000000e+00 3 0.0000000000000000e+00 0.0000000000000000e+00 -1 0 457 // P 3 1 7.5000000000000000e-01 -1.5690000000000000e+00 3.2191000000000003e+01 3.2238000000000000e+01 0.0000000000000000e+00 3 0.0000000000000000e+00 0.0000000000000000e+00 -3 0 458 // V -2 0 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 1 1 0 459 // P 2 2212 0.0000000000000000e+00 0.0000000000000000e+00 -7.0000000000000000e+03 7.0000000000000000e+03 0.0000000000000000e+00 3 0.0000000000000000e+00 0.0000000000000000e+00 -2 0 460 // P 4 -2 -3.0470000000000002e+00 -1.9000000000000000e+01 -5.4628999999999998e+01 5.7920000000000002e+01 0.0000000000000000e+00 3 0.0000000000000000e+00 0.0000000000000000e+00 -3 0 461 // V -3 0 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0.0000000000000000e+00 0 2 0 462 // P 5 22 -3.8130000000000002e+00 1.1300000000000000e-01 -1.8330000000000000e+00 4.2329999999999997e+00 0.0000000000000000e+00 1 0.0000000000000000e+00 0.0000000000000000e+00 0 0 463 // P 6 -24 1.5169999999999999e+00 -2.0680000000000000e+01 -2.0605000000000000e+01 8.5924999999999997e+01 0.0000000000000000e+00 3 0.0000000000000000e+00 0.0000000000000000e+00 -4 0 464 // V -4 0 1.2000000000000000e-01 -2.9999999999999999e-01 5.0000000000000003e-02 4.0000000000000001e-03 0 2 0 465 // P 7 1 -2.4449999999999998e+00 2.8815999999999999e+01 6.0819999999999999e+00 2.9552000000000000e+01 0.0000000000000000e+00 1 0.0000000000000000e+00 0.0000000000000000e+00 0 0 466 // P 8 -2 3.9620000000000002e+00 -4.9497999999999998e+01 -2.6687000000000001e+01 5.6372999999999998e+01 0.0000000000000000e+00 1 0.0000000000000000e+00 0.0000000000000000e+00 0 0 467 // 468 }