27 """Helper function to count LHE events in a file.
28 Support for plain text, gz, tar.gz, tgz files.
29 Use chunked reading to avoid memory issues with large files.
31 def _count_in_stream(stream):
33 for chunk
in iter(
lambda: stream.read(1024 * 1024), b
""):
34 count_ev += chunk.count(b
"/event")
37 if lhe_file.endswith((
".tar.gz",
".tgz",
".tar")):
39 with tarfile.open(lhe_file,
"r:*")
as tar:
41 if not member.isfile():
43 extracted = tar.extractfile(member)
47 count_ev += _count_in_stream(extracted)
50 if lhe_file.endswith(
".gz"):
51 with gzip.open(lhe_file,
"rb")
as f:
52 return _count_in_stream(f)
54 with open(lhe_file,
"rb")
as f:
55 return _count_in_stream(f)
72 This function merges a list of input LHE files into one output file.
73 The header is taken from the first file, but the number of events is
74 updated to equal the total number of events in all input files.
76 if os.path.exists(outputFile):
77 print(
"outputFile", outputFile,
"already exists. Will rename to", outputFile +
".OLD")
78 os.rename(outputFile, outputFile +
".OLD")
81 for file
in listOfFiles:
85 with open(outputFile,
"w")
as output:
86 for file
in listOfFiles:
89 print(
"*** Starting file", file)
90 with open(file,
"r")
as infile:
93 if "<event" in line
and inHeader:
100 elif not inHeader
and "</LesHouchesEvents>" not in line:
105 if "nevents" in line:
107 parts = line.split(
"=")
109 line = line.replace(parts[0],
str(total_events), 1)
110 elif "numevts" in line:
114 line = line.replace(parts[1],
str(total_events), 1)
117 output.write(
"</LesHouchesEvents>\n")
121 """Helper for handling input files"""
122 from GeneratorConfig.GenConfigHelpers
import gens_lhef
123 is_lhe_input = gens_lhef(generators)
127 "Alpgen":
"alpgen.unw_events",
128 "Protos":
"protos.events",
129 "ProtosLHEF":
"protoslhef.events",
130 "BeamHaloGenerator":
"beamhalogen.events",
131 "HepMCAscii":
"events.hepmc",
132 "ReadMcAscii":
"events.hepmc",
135 for gen_name, out_file
in events_file_map.items():
136 if gen_name
in generators:
137 eventsFile = out_file
139 if eventsFile
is None:
141 eventsFile =
"events.lhe"
143 raise RuntimeError(f
"Unknown type of ME generator: {generators}")
145 genInputFiles = [f.strip()
for f
in flags.Generator.inputGeneratorFile.split(
",")
if f.strip()]
146 if not genInputFiles:
147 raise RuntimeError(
"Generator.inputGeneratorFile is empty while input handling is requested")
149 def _input_root(path, keep_suffix_after_underscore=False):
150 fname = os.path.basename(path)
151 if any(ext
in fname
for ext
in (
".tar.",
".tgz",
".gz")):
152 return re.split(
r"\.tar\.|\.tgz|\.gz", fname, maxsplit=1)[0]
153 parts = fname.split(
"._", 1)
154 if keep_suffix_after_underscore
and len(parts) > 1:
155 return parts[0] +
"._" + parts[1].
split(
".", 1)[0]
159 if len(genInputFiles) == 1:
160 inputroot = _input_root(genInputFiles[0], keep_suffix_after_underscore=
False)
161 if inputroot.endswith(
".events"):
162 inputroot = inputroot[:-7]
170 for file
in genInputFiles:
173 inputroot = _input_root(file, keep_suffix_after_underscore=
True)
174 evgenLog.info(
"inputroot = %s", inputroot)
177 with open(realEventsFile,
"r")
as f:
178 first_line = f.readline()
179 if "LesHouche" not in first_line:
180 raise RuntimeError(f
"{realEventsFile} is NOT a LesHouche file")
181 allFiles.append(realEventsFile)
188 """Helper function to validate and set sample properties"""
191 "keywords":
lambda v: isinstance(v, list)
and len(v) > 0,
192 "contact":
lambda v: isinstance(v, list)
and len(v) > 0,
193 "nEventsPerJob":
lambda v: v
is not None,
195 for field, validator
in required_rules.items():
196 value = getattr(sample, field,
None)
198 raise RuntimeError(f
"self.{field} should be set in Sample(EvgenConfig)")
200 input_files_per_job = getattr(sample,
"inputFilesPerJob", 0)
201 me_generator = getattr(sample,
"MEgenerator",
None)
203 if input_files_per_job < 0:
204 raise RuntimeError(
"self.inputFilesPerJob should be >= 0 in Sample(EvgenConfig)")
205 if input_files_per_job > 0
and not me_generator:
206 raise RuntimeError(
"self.MEgenerator should be set when self.inputFilesPerJob > 0 in Sample(EvgenConfig)")
207 if input_files_per_job == 0
and me_generator:
208 raise RuntimeError(
"self.MEgenerator should be empty when self.inputFilesPerJob == 0 in Sample(EvgenConfig)")