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)
 _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 26 of file EvgenHelpers.py.

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

◆ _find_unique_file()

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

Definition at line 58 of file EvgenHelpers.py.

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

◆ _handle_input_files()

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

Definition at line 120 of file EvgenHelpers.py.

120def _handle_input_files(generators, flags):
121 """Helper for handling input files"""
122 from GeneratorConfig.GenConfigHelpers import gens_lhef
123 is_lhe_input = gens_lhef(generators)
124
125 # Name of event files produced by various generators.
126 events_file_map = {
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",
133 }
134 eventsFile = None
135 for gen_name, out_file in events_file_map.items():
136 if gen_name in generators:
137 eventsFile = out_file
138 break
139 if eventsFile is None:
140 if is_lhe_input:
141 eventsFile = "events.lhe"
142 else:
143 raise RuntimeError(f"Unknown type of ME generator: {generators}")
144
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")
148
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]
156 return parts[0]
157
158 # If there is a single file, make a symlink. If multiple files, merge them into one output eventsFile.
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]
163 realEventsFile = _find_unique_file(f"*{inputroot}.*ev*ts")
164 _mk_symlink(realEventsFile, eventsFile)
165 if is_lhe_input:
166 return _count_lhe_events(eventsFile)
167 return None
168
169 allFiles = []
170 for file in genInputFiles:
171 # Since we can have multiple files from the same task, include more of the filename
172 # to make the lookup unique in the plain-file case.
173 inputroot = _input_root(file, keep_suffix_after_underscore=True)
174 evgenLog.info("inputroot = %s", inputroot)
175 realEventsFile = _find_unique_file(f"*{inputroot}.*ev*ts")
176 # The only input format where merging is permitted is LHE.
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)
182 _merge_lhe_files(allFiles, eventsFile)
183
184 return _count_lhe_events(eventsFile)
185
186
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 211 of file EvgenHelpers.py.

211def _is_txt_only_run(flags):
212 """Helper function to determine if this is LHE-only generation with no showering)"""
213 has_txt = bool(flags.Output.TXTFileName)
214 has_evnt = bool(flags.Output.EVNTFileName)
215 has_yoda =bool(flags.Generator.outputYODAFile)
216
217 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 70 of file EvgenHelpers.py.

70def _merge_lhe_files(listOfFiles, outputFile):
71 """
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.
75 """
76 if os.path.exists(outputFile):
77 print("outputFile", outputFile, "already exists. Will rename to", outputFile + ".OLD")
78 os.rename(outputFile, outputFile + ".OLD")
79
80 total_events = 0
81 for file in listOfFiles:
82 total_events += _count_lhe_events(file)
83
84 wrote_header = False
85 with open(outputFile, "w") as output:
86 for file in listOfFiles:
87 inHeader = True
88 header = ""
89 print("*** Starting file", file)
90 with open(file, "r") as infile:
91 for line in infile:
92 # Reading first event signals that we are done with all header information.
93 if "<event" in line and inHeader:
94 inHeader = False
95 if not wrote_header:
96 wrote_header = True
97 output.write(header)
98 output.write(line)
99 # Each input file ends with "</LesHouchesEvents>". We only write it once at the end.
100 elif not inHeader and "</LesHouchesEvents>" not in line:
101 output.write(line)
102
103 if inHeader:
104 # Format for storing number of events differs in MG and Powheg.
105 if "nevents" in line:
106 # MG5 format is "n = nevents".
107 parts = line.split("=")
108 if parts:
109 line = line.replace(parts[0], str(total_events), 1)
110 elif "numevts" in line:
111 # Powheg format is "numevts n".
112 parts = line.split()
113 if len(parts) > 1:
114 line = line.replace(parts[1], str(total_events), 1)
115 header += line
116
117 output.write("</LesHouchesEvents>\n")
118
119
void print(char *figname, TCanvas *c1)

◆ _mk_symlink()

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

Definition at line 13 of file EvgenHelpers.py.

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

◆ _validate_sample_properties()

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

Definition at line 187 of file EvgenHelpers.py.

187def _validate_sample_properties(sample):
188 """Helper function to validate and set sample properties"""
189 # Required fields with lightweight, explicit validators.
190 required_rules = {
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,
194 }
195 for field, validator in required_rules.items():
196 value = getattr(sample, field, None)
197 if not validator(value):
198 raise RuntimeError(f"self.{field} should be set in Sample(EvgenConfig)")
199
200 input_files_per_job = getattr(sample, "inputFilesPerJob", 0)
201 me_generator = getattr(sample, "MEgenerator", None)
202
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)")
209
210

Variable Documentation

◆ evgenLog

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

Definition at line 10 of file EvgenHelpers.py.