Belle II Software  release-08-01-10
hepmc_roundtrip.py
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 
4 """
5 Test HepMC reader and writer by reading in a hepmc file and writing out one
6 again and checking if they match.
7 
8 """
9 
10 import os
11 import sys
12 import math
13 import basf2 as b2
14 import modularAnalysis as ma
15 from tempfile import TemporaryDirectory
16 
17 # analogous to lhereader.py
18 input_filename = b2.find_file("generators/tests/event.hepmc")
19 if len(input_filename) == 0:
20  sys.stderr.write("TEST SKIPPED: input file " + input_filename + " not found.")
21  sys.exit(-1)
22 
23 with TemporaryDirectory() as tmp:
24 
25  output_filename = "event.hepmc.out"
26 
27  os.chdir(tmp)
28  path = ma.create_path()
29  path.add_module("HepMCInput", inputFileList=[input_filename], expNum=0, runNum=0)
30  path.add_module("HepMCOutput", OutputFilename=output_filename)
31  b2.process(path)
32 
33  def valid_line(li):
34  """
35  Check only lines that contain numbers
36 
37  HepMC lines look like this:
38  Letter Number Number Number Number ...
39 
40  with letters:
41  E: event, V: vertex, P: particle
42  """
43  return li.split()[0] in ["E", "V", "P"]
44 
45  def parse_line(li):
46  tokens = li.split()
47  start_index = 1
48  if tokens[0] == "E":
49  # For events, the first number is the event number
50  # We don't check this here, since it will be incremented in basf2
51  start_index = 2
52  return [float(t) for t in tokens[start_index:]]
53 
54  def get_nonempty_lines(f):
55  return [li for li in f if not li.isspace()]
56 
57  with open(input_filename) as inputfile, open(output_filename) as outputfile:
58  lines_input = get_nonempty_lines(inputfile)
59  lines_output = get_nonempty_lines(outputfile)
60  for line_input, line_output in zip(lines_input, lines_output):
61  if valid_line(line_input):
62  assert valid_line(line_output)
63  numbers_input = parse_line(line_input)
64  numbers_output = parse_line(line_output)
65  for number_input, number_output in zip(numbers_input, numbers_output):
66  assert math.isclose(number_input, number_output, rel_tol=1e-5)