Skip to content

Commit bf21a8c

Browse files
committed
add autodiscovery for photon processes and rebase main
1 parent b6731e7 commit bf21a8c

File tree

3 files changed

+50
-19
lines changed

3 files changed

+50
-19
lines changed

src/pinefarm/external/nnlojet/nnpdf_interface.py

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
yaml.default_flow_style = False
2929
yaml.indent(sequence=4, offset=2, mapping=4)
3030

31-
HISTOGRAM_VARIABLES = {"y", "etay", "eta", "pT", "pT2", "M2"}
31+
HISTOGRAM_VARIABLES = {"y", "etay", "eta", "pT", "pT2", "M2", "ET"}
3232

3333

3434
def _legacy_nnpdf_translation(df, proc_type):
@@ -88,23 +88,28 @@ def _1d_histogram(kin_df, hist_var):
8888
def _nnlojet_observable(observable, process):
8989
"""Try to automatically understand the NNLOJET observables given the NNPDF process and obs."""
9090
observable = observable.lower()
91+
process = process.upper()
9192
if observable in ("eta", "y", "etay"):
92-
if process.upper().startswith("Z"):
93+
if process.startswith("Z"):
9394
return "yz"
94-
if process.upper().startswith("WP") and not process.upper().endswith("J"):
95+
if process.startswith("WP") and not process.endswith("J"):
9596
return "ylp"
96-
if process.upper().startswith("WM") and not process.upper().endswith("J"):
97+
if process.startswith("WM") and not process.endswith("J"):
9798
return "ylm"
99+
if process.startswith("GJ"):
100+
return "y_gam"
98101
if observable == "pt":
99-
if process.upper().startswith("Z"):
102+
if process.startswith("Z"):
100103
return "ptz"
101-
if process.upper().startswith("W"):
104+
if process.startswith("W"):
102105
return "ptw"
103-
if observable == "m" and process.upper().startswith("Z"):
106+
if observable == "m" and process.startswith("Z"):
104107
return "mll"
105108
if observable == "m2":
106109
print("\033[91m [WARNING] \033[0m Changed M2 to M in the selectors")
107110
return "mll"
111+
if observable == "et" and process.startswith("GJ"):
112+
return "pt_gam"
108113

109114
raise ValueError(f"Observable {observable} not recognized for process {process}")
110115

@@ -193,9 +198,17 @@ def _generate_nnlojet_pinecard(runname, process, energy, experiment, histograms)
193198
"""Generate a pinecard for NNLOJET runs from an NNPDF dataset."""
194199
selectors = select_selectors(experiment, process)
195200
histograms = deepcopy(histograms)
201+
photon = {}
196202

203+
# Digest the process variable
197204
if process.startswith("Z0"):
198205
process = process.replace("Z0", "Z")
206+
if process.startswith("G"):
207+
# Defaults for: 2302.00510
208+
photon = {
209+
"photon_isolation": "etsum[R=0.4, ETmax_const=4.8, ETmax_epsilon=0.0042, ET_threshold=0]",
210+
"photon_fragmentation": "BFG2",
211+
}
199212

200213
# Digest the histogram variable
201214
for histo in histograms:
@@ -204,7 +217,7 @@ def _generate_nnlojet_pinecard(runname, process, energy, experiment, histograms)
204217

205218
ret = {
206219
"runname": runname,
207-
"process": {"proc": process, "sqrts": energy},
220+
"process": {"proc": process, "sqrts": energy, **photon},
208221
"pdf": "NNPDF40_nnlo_as_01180",
209222
"techcut": 1e-7,
210223
"histograms": histograms,
@@ -227,11 +240,21 @@ def _generate_nnlojet_pinecard(runname, process, energy, experiment, histograms)
227240
},
228241
"selectors": selectors,
229242
}
243+
244+
# Add the scale
245+
if process.startswith("Z"):
246+
ret["scales"] = {"mur": "etz", "muf": "etz"}
247+
elif process.startswith("W"):
248+
ret["scales"] = {"mur": "etw", "muf": "etw"}
249+
elif process.startswith("G"):
250+
# Defaults for: 2302.00510 R=0.4
251+
ret["scales"] = {"mur": "pt_gam", "muf": "[pt_gam, 0.871*sqrt_pt_gam]"}
252+
230253
return ret
231254

232255

233256
def generate_pinecard_from_nnpdf(
234-
nnpdf_dataset, scale="etz", output_path=".", observables=None
257+
nnpdf_dataset, scale=None, output_path=".", observables=None
235258
):
236259
"""Generate a NNLOJET pinecard from an NNPDF dataset.
237260
@@ -277,6 +300,8 @@ def generate_pinecard_from_nnpdf(
277300
if "M2" in hist_vars:
278301
if len(kin_df["M2"]["mid"].unique()) == 1:
279302
hist_vars.remove("M2")
303+
elif process.startswith("PH"):
304+
process = process.replace("PH", "GJ")
280305

281306
# Create the histogram depending on whether this is a 1D or 2D distribution (or total)
282307
histograms = None
@@ -286,10 +311,10 @@ def generate_pinecard_from_nnpdf(
286311
elif len(hist_vars) == 2:
287312

288313
# Let's see whether we know how to do this 2D distribution
289-
if "M2" in hist_vars:
290-
svar = "M2"
291-
elif "y" in hist_vars:
292-
svar = "y"
314+
for var_i_know in ["M2", "y", "eta"]:
315+
if var_i_know in hist_vars:
316+
svar = var_i_know
317+
break
293318
else:
294319
raise NotImplementedError(f"Don't know how to do this 2D: {hist_vars}")
295320
hist_vars.remove(svar)
@@ -349,7 +374,7 @@ def generate_pinecard_from_nnpdf(
349374
processes = [process]
350375
if process.startswith("WPWM"):
351376
processes = [process.replace("WP", ""), process.replace("WM", "")]
352-
if process == "DY":
377+
elif process == "DY":
353378
processes = ["Z0", "WP", "WM"]
354379

355380
parent_folder = output_path.parent
@@ -360,7 +385,9 @@ def generate_pinecard_from_nnpdf(
360385
runname = nnpdf_dataset.replace(process, proc)
361386

362387
ret = _generate_nnlojet_pinecard(runname, proc, energy, experiment, histograms)
363-
ret["scales"] = {"mur": scale, "muf": scale}
388+
if scale is not None:
389+
# Default to etz
390+
ret["scales"] = {"mur": scale, "muf": scale}
364391

365392
# Beautify before dumping
366393
data = CommentedMap(ret)

src/pinefarm/external/nnlojet/runcardgen.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,15 +222,19 @@ def parse_input_yaml(yaml_path):
222222

223223

224224
def _fill_process(process):
225-
"""Fill process options."""
225+
"""Fill process block given the metadata for the process"""
226226
process_name = process["proc"]
227227
sqrts = process["sqrts"]
228228
jet = process.get("jet", "none[0]") # Can be None
229-
"""Fill process block given the metadata for the process"""
229+
fill_photon = ""
230+
if process_name.startswith("G"):
231+
fill_photon = f"""
232+
photon_isolation = {process['photon_isolation']}
233+
photon_fragmentation = {process['photon_fragmentation']}"""
230234
return f"""
231235
PROCESS {process_name}
232236
collider = pp sqrts = {sqrts}
233-
jet = {jet}
237+
jet = {jet}{fill_photon}
234238
decay_type = 1
235239
END_PROCESS
236240
"""
@@ -270,6 +274,7 @@ def _fill_parameters(theory_parameters):
270274
return f"""
271275
PARAMETERS
272276
{ptext}
277+
hard_photon_alpha0 = .true. ! only useful for GJ runs
273278
END_PARAMETERS
274279
"""
275280

src/pinefarm/install.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,6 @@ def lhapdf():
300300
301301
This is currently needed by every tool due to postprocessing requirements.
302302
"""
303-
304303
def installed():
305304
"""Define availability condition."""
306305
try:

0 commit comments

Comments
 (0)