File indexing completed on 2024-11-15 10:02:42
0001
0002
0003 import sys
0004 import argparse
0005
0006 class InvalidHepmc3Error(Exception):
0007 def __init__(this, *msg):
0008 print('InvalidHepmc3Error:', *msg, file=sys.stderr)
0009
0010 def warn(*msg):
0011 print('WARNING:', *msg, file=sys.stderr)
0012
0013
0014 class EventHeader:
0015 def __init__(this, line):
0016 if not line[0] == 'E':
0017 raise InvalidHepmc3Error('Expected event record, but found:', line)
0018 this.raw = line
0019 this.vertex = this._get_vertex_if_present(line)
0020 this.n_vertices = int(line.split(' ')[2])
0021 this.n_particles = int(line.split(' ')[3])
0022 this.vert_cnt = 0
0023 this.part_cnt = 0
0024 def get_record(this):
0025 if this.vert_cnt > this.n_vertices:
0026 warn('Too many vertices for event:', this.raw, "--> skipping event")
0027 return None
0028 if not this.part_cnt == this.n_particles:
0029 warn('Invalid particle count for event:', this.raw, "--> skipping event")
0030 return None
0031 if this.vertex and not '@' in this.raw:
0032 return '{} @{}'.format(this.raw[:-1], this.vertex)
0033 return this.raw
0034 def process_vertex(this, line):
0035 this.vert_cnt += 1
0036 if this.vert_cnt > this.n_vertices:
0037 warn('Too many vertices for event:', this.raw)
0038 return
0039 if not this.vertex:
0040 if '@' in line:
0041 this.vertex = this._get_vertex_if_present(line)
0042 def process_particle(this, line):
0043 this.part_cnt += 1
0044 if this.part_cnt > this.n_particles:
0045 warn('Too many particles for event:', this.raw)
0046 return
0047 def _get_vertex_if_present(this, line):
0048 if not '@' in line:
0049 return None
0050 return line.split('@')[1]
0051
0052 def flush_buffer(header, buffer):
0053 if header:
0054 event_record = header.get_record()
0055 if not event_record:
0056 warn('Skipped invalid event', header.raw)
0057 return
0058 sys.stdout.write(header.get_record())
0059 for line in buffer:
0060 sys.stdout.write(line)
0061
0062 if __name__ == '__main__':
0063 parser = argparse.ArgumentParser(
0064 description='Read HepMC3 input from stdin and sanitize the '
0065 'output (e.g. add vertex info to the event header '
0066 'if the event has a displaced starting vertex). '
0067 'Output is written to stdout.')
0068 args = parser.parse_args()
0069
0070 header = None
0071 buffer = []
0072 have_first_line = False
0073 have_second_line = False
0074 end_reached = False
0075
0076
0077 for line in sys.stdin:
0078 if len(line) == 0:
0079 continue
0080 if end_reached:
0081 warn("Ignoring lines after END_EVENT_LISTING was reached")
0082 continue
0083 if not have_first_line:
0084 if not 'HepMC::Version' in line:
0085 raise InvalidHepmc3Error('Not a valid HepMC3 file header:', line)
0086 have_first_line = True
0087 buffer.append(line)
0088 elif not have_second_line:
0089 if not 'HepMC::Asciiv3-START_EVENT_LISTING\n' == line:
0090 raise InvalidHepmc3Error('Not a valid HepMC3 file header:', line)
0091 have_second_line = True
0092 buffer.append(line)
0093 elif 'HepMC::Asciiv3-END_EVENT_LISTING\n' == line:
0094 end_reached = True
0095 buffer.append(line)
0096 elif line[0] in ['A','W','T','N']:
0097 buffer.append(line)
0098 elif line[0] == 'E':
0099 flush_buffer(header, buffer)
0100 header = EventHeader(line)
0101 buffer = []
0102 else:
0103 if header is None:
0104 raise InvalidHepmc3Error('Encountered invalid field before the first Event header:', line)
0105 if line[0] == 'V':
0106 header.process_vertex(line)
0107 elif line[0] == 'P':
0108 header.process_particle(line)
0109 elif line[0] not in ['W', 'A', 'U']:
0110 warn('Ignoring unknown field:', line)
0111 continue
0112 buffer.append(line)
0113 if not end_reached:
0114 warn("File does not end with END_EVENT_LISTING, appending")
0115 buffer.append('HepMC::Asciiv3-END_EVENT_LISTING\n')
0116
0117 flush_buffer(header, buffer)