Source code for pinefarm.external.nnlojet.runner

"""Provides a runner for NNLOJET."""

import rich
from yaml import safe_load

from .. import interface
from .runcardgen import YamlLOJET, generate_combine_ini, generate_runcard

# Reasonable default for warmup and production for DY
_DEFAULTS = {
    "warmup": {"iterations": 10, "events": int(5e6)},
    "production": {"iterations": 1, "events": int(1e6)},
}


[docs] class NNLOJET(interface.External): """Interface provider for NNLOJET.""" def __init__(self, pinecard, theorycard, *args, **kwargs): super().__init__(pinecard, theorycard, *args, **kwargs) pinecard = pinecard.replace("NNLOJET_", "") yaml_card = (self.source / pinecard).with_suffix(".yaml") # Save the yaml dictionary from the NNLOJET pinecard self._yaml_dict = safe_load(yaml_card.open("r"))
[docs] def preparation(self): """Run the preparation step for NNLOJET.""" # Update the yaml card according to the theory params = self._yaml_dict["parameters"] if self.theory.get("CKM", [1.0])[0] != 1.0: params["CKM"] = "FULL" translate = [("MZ", "MASS[Z]"), ("MW", "MASS[W]")] for nnpdf_key, nnlojet_key in translate: if nnpdf_key in self.theory: params[nnlojet_key] = self.theory[nnpdf_key] # Autodiscover scale if possible if (scdict := self._yaml_dict.get("scales")) is not None: for scale, key in scdict.items(): if isinstance(key, str) and key.upper() in self.theory: scdict[scale] = self.theory[key.upper()] # Select channels according to PTO order = self.theory.get("PTO") channels = ["LO"] if order > 0: channels += ["R", "V"] if order > 1: channels += ["RR", "RV", "VV"] if order > 2: raise NotImplementedError("N3LO still not working") pinedata = YamlLOJET(**self._yaml_dict) # Given the allowed channel, generate the possible channel choices active_channels = pinedata.active_channels(channels) self.dest.mkdir(exist_ok=True, parents=True) # If running manually, generate the whole set of runcards with reasonable defaults # otherwise, generate just a LO runcard for it to be used with the NNLOJET workflow if pinedata.manual: for level_name, level_channels in active_channels.items(): rich.print(f"Preparing {len(level_channels)} runcards for {level_name}") for mode in ["warmup", "production"]: nev = _DEFAULTS[mode]["events"] nit = _DEFAULTS[mode]["iterations"] for channel in level_channels: is_warmup = mode == "warmup" _ = generate_runcard( pinedata, channel, output=self.dest, is_warmup=is_warmup, events=nev, iterations=nit, ) generate_combine_ini(pinedata, active_channels, self.dest) else: runcard_path = self.dest / f"{pinedata.runname}.run" rfull = generate_runcard(pinedata, "LO", runcard_path=runcard_path) rich.print(f""" Runcard written to {runcard_path}. Prepare your NNLOJET run with ~$ nnlojet-run init {runcard_path} """) return True
[docs] def run(self): """Run the corresponding NNLOJET runcard.""" raise NotImplementedError("NNLOJET running not implemented outside of dry mode")
[docs] def collect_versions(self) -> dict: """NNLOJET version.""" return {"nnlojet_version": "secret"}
[docs] def generate_pineappl(self): """Not implemented.""" print("Not yet")
[docs] def results(self): """Not implemented.""" print("Good luck")