152 extra_args=None):
153 """Invoke `pepper`, produce an event file, and return its path.
154
155 The default output is an uncompressed LHE file. Use
156 arrange_output() afterwards to hand it to the Gen_tf.py skeleton.
157
158 Parameters
159 ----------
160 process : Pepper process shortcut, e.g. "ppjj", "ppz1j", "pptt".
161 nevents : Minimum number of events to be written (passed to
162 pepper as --n-events). Pepper stops at the first batch
163 boundary after reaching it, so the file usually holds
164 slightly more.
165 seed : Random seed (typically runArgs.randomSeed).
166 ecm : Centre-of-mass energy in GeV (typically runArgs.ecmEnergy).
167 output : Output filename. Must end in one of .events[.gz],
168 .lhef[.gz], .hepmc3[.gz], .hdf5, or .debug.
169 batch_size : Phase-space points per batch. Throughput tuning only;
170 defaults to DEFAULT_BATCH_SIZE.
171 extra_args : List of additional CLI args to pass through.
172
173 Returns
174 -------
175 The absolute path of the event file in $PWD.
176 """
177 nevents = int(nevents)
178 if nevents < 1:
179 raise ValueError("run_pepper: nevents must be >= 1, got %d" % nevents)
180
181 exe = _resolve_pepper_executable()
182 data = _resolve_data_path(exe)
183
184 stem, user_ext = _split_ext(output)
185 pepper_ext = _EXT_MAP[user_ext]
186 pepper_output = stem + pepper_ext
187
188 if batch_size is None:
189 batch_size = DEFAULT_BATCH_SIZE
190
191 cmd = [exe,
192 "--process", str(process),
193 "--collision-energy", str(ecm),
194 "--seed", str(seed),
195 "--batch-size", str(batch_size),
196 "--n-events", str(nevents),
197 "--output", pepper_output]
198 if extra_args:
199 cmd += list(extra_args)
200
201 env = os.environ.copy()
202 env["PEPPER_DATA_PATH"] = data
203
204 env.setdefault("OMP_PROC_BIND", "spread")
205 env.setdefault("OMP_PLACES", "threads")
206
207
208 if os.path.lexists(pepper_output):
209 os.remove(pepper_output)
210
211 log.info("PEPPER_DATA_PATH = %s", data)
212 log.info("Pepper command: %s", " ".join(cmd))
213
214 rc = subprocess.call(cmd, env=env)
215 if rc != 0:
216 raise RuntimeError("pepper exited with rc=%d" % rc)
217 if not os.path.isfile(pepper_output):
218 raise RuntimeError("pepper succeeded but %s is missing" % pepper_output)
219
220 if pepper_ext in _LHE_EXTS:
221 nwritten = count_lhe_events(pepper_output)
222 log.info("Pepper wrote %d events to %s (%d requested)",
223 nwritten, pepper_output, nevents)
224 if nwritten < nevents:
225 raise RuntimeError(
226 "pepper wrote only %d events to %s, but %d were requested"
227 % (nwritten, pepper_output, nevents))
228 else:
229 log.info("Output format %s: number of written events not checked",
230 pepper_ext)
231
232
233
234
235 if output != pepper_output:
236 if os.path.lexists(output):
237 os.remove(output)
238 os.symlink(os.path.basename(pepper_output), output)
239 log.info("Linked %s -> %s", output, pepper_output)
240
241 return os.path.abspath(output)
242
243