106 extra_args=None):
107 """Invoke `pepper`, produce an event file, and return its path.
108
109 The default output is `.events.gz` to match the convention used by
110 AthGeneration's `Gen_tf.py` for upstream-generator input files
111 (`Pythia8_LHEF` and the transform's post-job validator both look
112 for `*.events*`). Internally we invoke pepper with the
113 corresponding `.lhef[.gz]` extension and create the `.events[.gz]`
114 name as a symlink.
115
116 Parameters
117 ----------
118 process : Pepper process shortcut, e.g. "ppjj", "ppz1j", "pptt".
119 nevents : Approximate number of unweighted events wanted.
120 seed : Random seed (typically runArgs.randomSeed).
121 ecm : Centre-of-mass energy in GeV (typically runArgs.ecmEnergy).
122 output : Output filename. Must end in one of .events[.gz],
123 .lhef[.gz], .hepmc3[.gz], .hdf5, or .debug.
124 batch_size : Pepper batch size. Defaults to min(nevents, 5000).
125 n_batches : Number of batches. Defaults so that we usually
126 overshoot the requested nevents after accounting for
127 unweighting efficiency.
128 extra_args : List of additional CLI args to pass through.
129
130 Returns
131 -------
132 The absolute path of the event file in $PWD.
133 """
134 exe = _resolve_pepper_executable()
135 data = _resolve_data_path(exe)
136
137 stem, user_ext = _split_ext(output)
138 pepper_ext = _EXT_MAP[user_ext]
139 pepper_output = stem + pepper_ext
140
141 if batch_size is None:
142 batch_size =
min(nevents, 5000)
143 if n_batches is None:
144
145
146 n_batches =
max(1, (2 * nevents + batch_size - 1) // batch_size)
147
148 cmd = [exe,
149 "--process", str(process),
150 "--collision-energy", str(ecm),
151 "--seed", str(seed),
152 "--batch-size", str(batch_size),
153 "--n-batches", str(n_batches),
154 "--output", pepper_output]
155 if extra_args:
156 cmd += list(extra_args)
157
158 env = os.environ.copy()
159 env["PEPPER_DATA_PATH"] = data
160
161 env.setdefault("OMP_PROC_BIND", "spread")
162 env.setdefault("OMP_PLACES", "threads")
163
164 log.info("PEPPER_DATA_PATH = %s", data)
165 log.info("Pepper command: %s", " ".join(cmd))
166
167 rc = subprocess.call(cmd, env=env)
168 if rc != 0:
169 raise RuntimeError("pepper exited with rc=%d" % rc)
170 if not os.path.isfile(pepper_output):
171 raise RuntimeError("pepper succeeded but %s is missing" % pepper_output)
172
173
174
175
176 if output != pepper_output:
177 if os.path.lexists(output):
178 os.remove(output)
179 os.symlink(os.path.basename(pepper_output), output)
180 log.info("Linked %s -> %s", output, pepper_output)
181
182 return os.path.abspath(output)