ATLAS Offline Software
Loading...
Searching...
No Matches
python.EvgenHelpers Namespace Reference

Functions

 _mk_symlink (srcfile, dstfile)
 _count_lhe_events (lhe_file)
 _find_unique_file (pattern)
 _prepare_lhe_file (input_file, output_file)
 _merge_lhe_files (listOfFiles, outputFile)
 _handle_input_files (generators, flags)
 _validate_sample_properties (sample)
 _is_txt_only_run (flags)

Variables

 evgenLog = logging.getLogger("Gen_tf")

Function Documentation

◆ _count_lhe_events()

python.EvgenHelpers._count_lhe_events ( lhe_file)
protected
Helper function to count LHE events in a file.
Support for plain text, gz, tar.gz, tgz files.
Use chunked reading to avoid memory issues with large files.

Definition at line 27 of file EvgenHelpers.py.

27def _count_lhe_events(lhe_file):
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.
31 """
32 def _count_in_stream(stream):
33 count_ev = 0
34 for chunk in iter(lambda: stream.read(1024 * 1024), b""):
35 count_ev += chunk.count(b"/event")
36 return count_ev
37
38 if lhe_file.endswith((".tar.gz", ".tgz", ".tar")):
39 count_ev = 0
40 with tarfile.open(lhe_file, "r:*") as tar:
41 for member in tar:
42 if not member.isfile():
43 continue
44 extracted = tar.extractfile(member)
45 if extracted is None:
46 continue
47 with extracted:
48 count_ev += _count_in_stream(extracted)
49 return count_ev
50
51 if lhe_file.endswith(".gz"):
52 with gzip.open(lhe_file, "rb") as f:
53 return _count_in_stream(f)
54
55 with open(lhe_file, "rb") as f:
56 return _count_in_stream(f)
57
58

◆ _find_unique_file()

python.EvgenHelpers._find_unique_file ( pattern)
protected
Helper functions for finding input file

Definition at line 59 of file EvgenHelpers.py.

59def _find_unique_file(pattern):
60 """Helper functions for finding input file"""
61 import glob
62 files = glob.glob(pattern)
63 # Check that there is exactly 1 match
64 if not files:
65 raise RuntimeError(f"No {pattern} file found")
66 elif len(files) > 1:
67 raise RuntimeError(f"More than one {pattern} file found")
68 return files[0]
69
70

◆ _handle_input_files()

python.EvgenHelpers._handle_input_files ( generators,
flags )
protected
Helper for handling input files

Definition at line 143 of file EvgenHelpers.py.

143def _handle_input_files(generators, flags):
144 """Helper for handling input files"""
145 from GeneratorConfig.GenConfigHelpers import gens_lhef
146 is_lhe_input = gens_lhef(generators)
147
148 # Name of event files produced by various generators.
149 events_file_map = {
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",
156 }
157 eventsFile = None
158 for gen_name, out_file in events_file_map.items():
159 if gen_name in generators:
160 eventsFile = out_file
161 break
162 if eventsFile is None:
163 if is_lhe_input:
164 eventsFile = "events.lhe.gz" if flags.Generator.avoidExtracting else "events.lhe"
165 else:
166 raise RuntimeError(f"Unknown type of ME generator: {generators}")
167
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")
171
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"):
177 fname = fname[:-7]
178 parts = fname.split("._", 1)
179 if keep_suffix_after_underscore and len(parts) > 1:
180 return parts[0] + "._" + parts[1].split(".", 1)[0]
181 return parts[0]
182
183 # If there is a single file, make a symlink. If multiple files, merge them into one output eventsFile.
184 if len(genInputFiles) == 1:
185 inputroot = _input_root(genInputFiles[0], keep_suffix_after_underscore=False)
186 realEventsFile = _find_unique_file(f"*{inputroot}.*ev*ts")
187 if is_lhe_input:
188 # Compress or symlink the extracted input according to the flag.
189 _prepare_lhe_file(realEventsFile, eventsFile)
190 return _count_lhe_events(eventsFile)
191 _mk_symlink(realEventsFile, eventsFile)
192 return None
193
194 allFiles = []
195 for file in genInputFiles:
196 # Since we can have multiple files from the same task, include more of the filename
197 # to make the lookup unique in the plain-file case.
198 inputroot = _input_root(file, keep_suffix_after_underscore=True)
199 evgenLog.info("inputroot = %s", inputroot)
200 realEventsFile = _find_unique_file(f"*{inputroot}.*ev*ts")
201 # The only input format where merging is permitted is LHE.
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)
207 _merge_lhe_files(allFiles, eventsFile)
208
209 return _count_lhe_events(eventsFile)
210
211
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:179

◆ _is_txt_only_run()

python.EvgenHelpers._is_txt_only_run ( flags)
protected
Helper function to determine if this is LHE-only generation with no showering)

Definition at line 236 of file EvgenHelpers.py.

236def _is_txt_only_run(flags):
237 """Helper function to determine if this is LHE-only generation with no showering)"""
238 has_txt = bool(flags.Output.TXTFileName)
239 has_evnt = bool(flags.Output.EVNTFileName)
240 has_yoda =bool(flags.Generator.outputYODAFile)
241
242 return has_txt and not has_evnt and not has_yoda

◆ _merge_lhe_files()

python.EvgenHelpers._merge_lhe_files ( listOfFiles,
outputFile )
protected
This function merges a list of input LHE files into one output file.
The header is taken from the first file, but the number of events is
updated to equal the total number of events in all input files.

Definition at line 91 of file EvgenHelpers.py.

91def _merge_lhe_files(listOfFiles, outputFile):
92 """
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.
96 """
97 if os.path.exists(outputFile):
98 print("outputFile", outputFile, "already exists. Will rename to", outputFile + ".OLD")
99 os.rename(outputFile, outputFile + ".OLD")
100
101 total_events = 0
102 for file in listOfFiles:
103 total_events += _count_lhe_events(file)
104
105 wrote_header = False
106 # Produce a compressed merged file when avoidExtracting is True
107 output_opener = gzip.open if outputFile.endswith(".gz") else open
108 with output_opener(outputFile, "wt") as output:
109 for file in listOfFiles:
110 inHeader = True
111 header = ""
112 print("*** Starting file", file)
113 with open(file, "r") as infile:
114 for line in infile:
115 # Reading first event signals that we are done with all header information.
116 if "<event" in line and inHeader:
117 inHeader = False
118 if not wrote_header:
119 wrote_header = True
120 output.write(header)
121 output.write(line)
122 # Each input file ends with "</LesHouchesEvents>". We only write it once at the end.
123 elif not inHeader and "</LesHouchesEvents>" not in line:
124 output.write(line)
125
126 if inHeader:
127 # Format for storing number of events differs in MG and Powheg.
128 if "nevents" in line:
129 # MG5 format is "n = nevents".
130 parts = line.split("=")
131 if parts:
132 line = line.replace(parts[0], str(total_events), 1)
133 elif "numevts" in line:
134 # Powheg format is "numevts n".
135 parts = line.split()
136 if len(parts) > 1:
137 line = line.replace(parts[1], str(total_events), 1)
138 header += line
139
140 output.write("</LesHouchesEvents>\n")
141
142
void print(char *figname, TCanvas *c1)

◆ _mk_symlink()

python.EvgenHelpers._mk_symlink ( srcfile,
dstfile )
protected
Helper function to make symlinks.

Definition at line 14 of file EvgenHelpers.py.

14def _mk_symlink(srcfile, dstfile):
15 """Helper function to make symlinks."""
16 if dstfile:
17 if os.path.exists(dstfile) and not os.path.samefile(dstfile, srcfile):
18 os.remove(dstfile)
19 if not os.path.exists(dstfile):
20 evgenLog.info(f"Symlinking {srcfile} to {dstfile}")
21 print (f"Symlinking {srcfile} to {dstfile}")
22 os.symlink(srcfile, dstfile)
23 else:
24 evgenLog.debug(f"Symlinking: {dstfile} is already the same as {srcfile}")
25
26

◆ _prepare_lhe_file()

python.EvgenHelpers._prepare_lhe_file ( input_file,
output_file )
protected
Helper function to prepare LHE file for shower.
If the requested output file is uncompressed, 
make a symlink to the input file.
If the requested output file is compressed, 
compress the input file to the output file..

Definition at line 71 of file EvgenHelpers.py.

71def _prepare_lhe_file(input_file, output_file):
72 """
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..
78 """
79 if not output_file.endswith(".gz"):
80 _mk_symlink(input_file, output_file)
81 return
82
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)
89
90

◆ _validate_sample_properties()

python.EvgenHelpers._validate_sample_properties ( sample)
protected
Helper function to validate and set sample properties

Definition at line 212 of file EvgenHelpers.py.

212def _validate_sample_properties(sample):
213 """Helper function to validate and set sample properties"""
214 # Required fields with lightweight, explicit validators.
215 required_rules = {
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,
219 }
220 for field, validator in required_rules.items():
221 value = getattr(sample, field, None)
222 if not validator(value):
223 raise RuntimeError(f"self.{field} should be set in Sample(EvgenConfig)")
224
225 input_files_per_job = getattr(sample, "inputFilesPerJob", 0)
226 me_generator = getattr(sample, "MEgenerator", None)
227
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)")
234
235

Variable Documentation

◆ evgenLog

python.EvgenHelpers.evgenLog = logging.getLogger("Gen_tf")

Definition at line 11 of file EvgenHelpers.py.