28 """Helper function to count LHE events in a file.
29 Support for plain text, gz, tar.gz, tgz files.
30 Use chunked reading to avoid memory issues with large files.
32 def _count_in_stream(stream):
34 for chunk
in iter(
lambda: stream.read(1024 * 1024), b
""):
35 count_ev += chunk.count(b
"/event")
38 if lhe_file.endswith((
".tar.gz",
".tgz",
".tar")):
40 with tarfile.open(lhe_file,
"r:*")
as tar:
42 if not member.isfile():
44 extracted = tar.extractfile(member)
48 count_ev += _count_in_stream(extracted)
51 if lhe_file.endswith(
".gz"):
52 with gzip.open(lhe_file,
"rb")
as f:
53 return _count_in_stream(f)
55 with open(lhe_file,
"rb")
as f:
56 return _count_in_stream(f)
73 Helper function to prepare LHE file for shower.
74 If the requested output file is uncompressed,
75 make a symlink to the input file.
76 If the requested output file is compressed,
77 compress the input file to the output file..
79 if not output_file.endswith(
".gz"):
83 if os.path.lexists(output_file):
84 os.remove(output_file)
85 evgenLog.info(
"Compressing %s to %s", input_file, output_file)
86 with open(input_file,
"rb")
as source:
87 with gzip.open(output_file,
"wb")
as destination:
88 shutil.copyfileobj(source, destination)
93 This function merges a list of input LHE files into one output file.
94 The header is taken from the first file, but the number of events is
95 updated to equal the total number of events in all input files.
97 if os.path.exists(outputFile):
98 print(
"outputFile", outputFile,
"already exists. Will rename to", outputFile +
".OLD")
99 os.rename(outputFile, outputFile +
".OLD")
102 for file
in listOfFiles:
107 output_opener = gzip.open
if outputFile.endswith(
".gz")
else open
108 with output_opener(outputFile,
"wt")
as output:
109 for file
in listOfFiles:
112 print(
"*** Starting file", file)
113 with open(file,
"r")
as infile:
116 if "<event" in line
and inHeader:
123 elif not inHeader
and "</LesHouchesEvents>" not in line:
128 if "nevents" in line:
130 parts = line.split(
"=")
132 line = line.replace(parts[0], str(total_events), 1)
133 elif "numevts" in line:
137 line = line.replace(parts[1], str(total_events), 1)
140 output.write(
"</LesHouchesEvents>\n")
144 """Helper for handling input files"""
145 from GeneratorConfig.GenConfigHelpers
import gens_lhef
146 is_lhe_input = gens_lhef(generators)
150 "Alpgen":
"alpgen.unw_events",
151 "Protos":
"protos.events",
152 "ProtosLHEF":
"protoslhef.events",
153 "BeamHaloGenerator":
"beamhalogen.events",
154 "HepMCAscii":
"events.hepmc",
155 "ReadMcAscii":
"events.hepmc",
158 for gen_name, out_file
in events_file_map.items():
159 if gen_name
in generators:
160 eventsFile = out_file
162 if eventsFile
is None:
164 eventsFile =
"events.lhe.gz" if flags.Generator.avoidExtracting
else "events.lhe"
166 raise RuntimeError(f
"Unknown type of ME generator: {generators}")
168 genInputFiles = [f.strip()
for f
in flags.Generator.inputGeneratorFile.split(
",")
if f.strip()]
169 if not genInputFiles:
170 raise RuntimeError(
"Generator.inputGeneratorFile is empty while input handling is requested")
172 def _input_root(path, keep_suffix_after_underscore=False):
173 fname = os.path.basename(path)
174 if any(ext
in fname
for ext
in (
".tar.",
".tgz",
".gz")):
175 fname = re.split(
r"\.tar\.|\.tgz|\.gz", fname, maxsplit=1)[0]
176 if fname.endswith(
".events"):
178 parts = fname.split(
"._", 1)
179 if keep_suffix_after_underscore
and len(parts) > 1:
180 return parts[0] +
"._" + parts[1].
split(
".", 1)[0]
184 if len(genInputFiles) == 1:
185 inputroot = _input_root(genInputFiles[0], keep_suffix_after_underscore=
False)
195 for file
in genInputFiles:
198 inputroot = _input_root(file, keep_suffix_after_underscore=
True)
199 evgenLog.info(
"inputroot = %s", inputroot)
202 with open(realEventsFile,
"r")
as f:
203 first_line = f.readline()
204 if "LesHouches" not in first_line:
205 raise RuntimeError(f
"{realEventsFile} is NOT a LesHouches file")
206 allFiles.append(realEventsFile)
213 """Helper function to validate and set sample properties"""
216 "keywords":
lambda v: isinstance(v, list)
and len(v) > 0,
217 "contact":
lambda v: isinstance(v, list)
and len(v) > 0,
218 "nEventsPerJob":
lambda v: v
is not None,
220 for field, validator
in required_rules.items():
221 value = getattr(sample, field,
None)
223 raise RuntimeError(f
"self.{field} should be set in Sample(EvgenConfig)")
225 input_files_per_job = getattr(sample,
"inputFilesPerJob", 0)
226 me_generator = getattr(sample,
"MEgenerator",
None)
228 if input_files_per_job < 0:
229 raise RuntimeError(
"self.inputFilesPerJob should be >= 0 in Sample(EvgenConfig)")
230 if input_files_per_job > 0
and not me_generator:
231 raise RuntimeError(
"self.MEgenerator should be set when self.inputFilesPerJob > 0 in Sample(EvgenConfig)")
232 if input_files_per_job == 0
and me_generator:
233 raise RuntimeError(
"self.MEgenerator should be empty when self.inputFilesPerJob == 0 in Sample(EvgenConfig)")