Skip to content

Commit

Permalink
add combine Fk tables
Browse files Browse the repository at this point in the history
  • Loading branch information
giacomomagni committed Feb 15, 2024
1 parent b6f9621 commit e7dbfb1
Show file tree
Hide file tree
Showing 2 changed files with 175 additions and 105 deletions.
176 changes: 74 additions & 102 deletions src/pineko/cli/fonll.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@
import pathlib

import click
import rich

from .. import configs, fonll, parser, theory, theory_card
from .. import configs, fonll, theory, theory_card
from ..fonll import TheoryCardError
from ._base import command
from .theory_ import theory_

logger = logging.getLogger(__name__)

Expand All @@ -23,29 +22,13 @@
)


class TheoryCardError(Exception):
"""Raised when asked for FONLL theory cards with an original tcard as input that is not asking for FONLL."""


class InconsistentInputsError(Exception):
"""Raised if the inputs are not consistent with FONLL."""


def cfgpath(name, grid):
"""Path of the fktable in 'name' called 'grid' if it exists, else None."""
path = configs.configs["paths"]["fktables"] / name / grid
return path if path.exists() else None


def grids_names(yaml_file):
"""Return the list of the grids in the yaml file."""
yaml_content = parser._load_yaml(yaml_file)
# Turn the operands and the members into paths (and check all of them exist)
ret = []
for operand in yaml_content["operands"]:
for member in operand:
ret.append(f"{member}.{parser.EXT}")
return ret
def load_config(cfg):
"""Iterate a subcommand on a given theory and list of datasets."""
path = configs.detect(cfg)
base_configs = configs.load(path)
configs.configs = configs.defaults(base_configs)
if cfg is not None:
print(f"Configurations loaded from '{path}'")


@command.command("combine_fonll")
Expand Down Expand Up @@ -74,100 +57,49 @@ def subcommand(
cfg,
):
"""Combine the different FKs needed to produce the FONLL prescription."""
path = configs.detect(cfg)
base_configs = configs.load(path)
configs.configs = configs.defaults(base_configs)
if cfg is not None:
print(f"Configurations loaded from '{path}'")

# Checks

if not ffns3 or not ffn03:
raise InconsistentInputsError("ffns3 and/or ffn03 is not provided.")

if ffns4til is None or ffns4bar is None:
raise InconsistentInputsError(
"At least one of ffns4til and ffns4bar should be provided."
)

# Do we consider two masses, i.e. mc and mb
if any([ffns5til, ffns5bar, ffn04]):
if (ffns5til is None and ffns5bar is None) or ffn04 is None:
raise InconsistentInputsError(
"To include nf5 contributions, ffn04 and at least one between ffns5til and ffns5bar are mandatory"
)

# Get theory info
tcard = theory_card.load(theoryid)
if tcard["DAMP"] == 1:
if not "DAMPPOWERc" in tcard or not "DAMPPOWERb" in tcard:
raise InconsistentInputsError(
"If DAMP is set, set also DAMPPOWERb and DAMPPOWERc"
)
else:
tcard["DAMPPOWERb"] = 0
tcard["DAMPPOWERc"] = 0
# Getting the paths to the grids
grids_name = grids_names(configs.configs["paths"]["ymldb"] / f"{dataset}.yaml")
for grid in grids_name:
# Checking if it already exists
new_fk_path = configs.configs["paths"]["fktables"] / str(theoryid) / grid
if new_fk_path.exists():
if not overwrite:
rich.print(
f"[green]Success:[/] skipping existing FK Table {new_fk_path}"
)
return
fonll.produce_combined_fk(
*(
cfgpath(str(name), grid)
for name in (
ffns3,
ffn03,
ffns4til,
ffns4bar,
ffn04,
ffns5til,
ffns5bar,
)
),
theoryid,
damp=(tcard["DAMP"], tcard["DAMPPOWERc"], tcard["DAMPPOWERb"]),
cfg=cfg,
)
if new_fk_path.exists():
rich.print(f"[green]Success:[/] Wrote FK table to {new_fk_path}")
else:
rich.print(f"[red]Failure:[/]")
load_config(cfg)
fonll.assembly_combined_fk(
theoryid,
dataset,
ffns3,
ffn03,
ffns4til,
ffns4bar,
ffn04,
ffns5til,
ffns5bar,
overwrite,
cfg,
)


@command.command("fonll_tcards")
@click.argument("theoryID", type=int)
@config_setting
def fonll_tcards(theoryid, cfg):
"""Produce the FONLL tcards starting from the original tcard given by the theoryID."""
path = configs.detect(cfg)
base_configs = configs.load(path)
configs.configs = configs.defaults(base_configs)
load_config(cfg)

tcard = theory_card.load(theoryid)
tcard_parent_path = theory_card.path(theoryid).parent
if "FONLL" not in tcard["FNS"]:
raise TheoryCardError("The theorycard does not correspond to an FONLL scheme.")
fonll.dump_tcards(tcard, tcard_parent_path, theoryid)


@theory_.command()
@click.argument("theoryID", type=click.INT)
@click.argument("datasets", type=click.STRING, nargs=-1)
@click.option("--overwrite", is_flag=True, help="Allow files to be overwritten")
def fonll_ekos(theoryid, datasets, overwrite):
@config_setting
def fonll_ekos(theoryid, datasets, overwrite, cfg):
"""Command to generate numerical FONLL ekos.
1. Produce the 7 theory cards that are needed for numerical FONLL.
2. Creates the 3 opcards for the different flavor patches.
3. Runs the 3 ekos for the different flavor pathces.
1. Produce the 7 theory cards needed for numerical FONLL.
2. Create the 3 operator cards for the different flavor patches.
3. Run the 3 ekos for the different flavor patches.
4. Inherit the ekos.
"""
load_config(cfg)

# create the 7 theory cards
tcard = theory_card.load(theoryid)
Expand All @@ -193,20 +125,60 @@ def fonll_ekos(theoryid, datasets, overwrite):

# now inherit ekos
# nf=3
logger.info(f"Inherit nf=3 from theory {theoryid}00")
logger.info("Inherit nf=3 from theory %i00", theoryid)
theory.TheoryBuilder(f"{theoryid}00", datasets, overwrite=overwrite).inherit_ekos(
f"{theoryid}01"
)
# nf=4
logger.info(f"Inherit nf=4 from theory {theoryid}04")
logger.info("Inherit nf=4 from theory %i04", theoryid)
theory.TheoryBuilder(f"{theoryid}04", datasets, overwrite=overwrite).inherit_ekos(
f"{theoryid}02"
)
theory.TheoryBuilder(f"{theoryid}04", datasets, overwrite=overwrite).inherit_ekos(
f"{theoryid}03"
)
# nf=5
logger.info(f"Inherit nf=5 from theory {theoryid}05")
logger.info("Inherit nf=5 from theory %i05", theoryid)
theory.TheoryBuilder(f"{theoryid}05", datasets, overwrite=overwrite).inherit_ekos(
f"{theoryid}06"
)


@click.argument("theoryID", type=click.INT)
@click.argument("datasets", type=click.STRING, nargs=-1)
@click.option("--pdf", "-p", default=None, help="PDF set used for comparison")
@click.option("--overwrite", is_flag=True, help="Allow files to be overwritten")
@config_setting
def fonll_fks(theoryid, datasets, pdf, overwrite, cfg):
"""Command to generate numerical FONLL FK tables.
1. Produce the 7 FK tables needed for numerical FONLL.
2. Combine the FKtables into a single one.
"""
load_config(cfg)

# create the 7 FK tables
for th_suffix in range(0, 7):
theory.TheoryBuilder(
f"{theoryid}0{th_suffix}",
datasets,
silent=False,
clear_logs=True,
overwrite=overwrite,
).fks(pdf)

# combine
for dataset in datasets:
fonll.assembly_combined_fk(
theoryid,
dataset,
ffns3=f"{theoryid}00",
ffn03=f"{theoryid}01",
ffns4til=f"{theoryid}02",
ffns4bar=f"{theoryid}03",
ffn04=f"{theoryid}04",
ffns5til=f"{theoryid}05",
ffns5bar=f"{theoryid}06",
overwrite=overwrite,
cfg=cfg,
)
104 changes: 101 additions & 3 deletions src/pineko/fonll.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@
from pathlib import Path

import pineappl
import rich
import yaml

from . import configs
from . import configs, theory_card, parser

logger = logging.getLogger(__name__)

Expand All @@ -36,6 +35,14 @@
"""FNS schemes to be subtracted during the FONLL procedure."""


class TheoryCardError(Exception):
"""Raised when asked for FONLL theory cards with an original tcard as input that is not asking for FONLL."""


class InconsistentInputsError(Exception):
"""Raised if the inputs are not consistent with FONLL."""


class FONLLInfo:
"""Class containing all the information for FONLL predictions."""

Expand Down Expand Up @@ -157,6 +164,97 @@ def combine(fk_dict, dampings=None):
return combined_fk


def grids_names(yaml_file):
"""Return the list of the grids in the yaml file."""
yaml_content = parser._load_yaml(yaml_file)
# Turn the operands and the members into paths (and check all of them exist)
ret = []
for operand in yaml_content["operands"]:
for member in operand:
ret.append(f"{member}.{parser.EXT}")
return ret


def cfgpath(name, grid):
"""Path of the fktable in 'name' called 'grid' if it exists, else None."""
path = configs.configs["paths"]["fktables"] / name / grid
return path if path.exists() else None


def assembly_combined_fk(
theoryid,
dataset,
ffns3,
ffn03,
ffns4til,
ffns4bar,
ffn04,
ffns5til,
ffns5bar,
overwrite,
cfg,
):
"""Perform consistency checks and combine the FONLL FK tables into one single FK table."""
# Checks
if not ffns3 or not ffn03:
raise InconsistentInputsError("ffns3 and/or ffn03 is not provided.")

if ffns4til is None or ffns4bar is None:
raise InconsistentInputsError(
"At least one of ffns4til and ffns4bar should be provided."
)

# Do we consider two masses, i.e. mc and mb
if any([ffns5til, ffns5bar, ffn04]):
if (ffns5til is None and ffns5bar is None) or ffn04 is None:
raise InconsistentInputsError(
"To include nf5 contributions, ffn04 and at least one between ffns5til and ffns5bar are mandatory"
)

# Get theory info
tcard = theory_card.load(theoryid)
if tcard["DAMP"] == 1:
if not "DAMPPOWERc" in tcard or not "DAMPPOWERb" in tcard:
raise InconsistentInputsError(
"If DAMP is set, set also DAMPPOWERb and DAMPPOWERc"
)
else:
tcard["DAMPPOWERb"] = 0
tcard["DAMPPOWERc"] = 0
# Getting the paths to the grids
grids_name = grids_names(configs.configs["paths"]["ymldb"] / f"{dataset}.yaml")
for grid in grids_name:
# Checking if it already exists
new_fk_path = configs.configs["paths"]["fktables"] / str(theoryid) / grid
if new_fk_path.exists():
if not overwrite:
logger.info(
"[green]Success:[/] skipping existing FK Table %s", str(new_fk_path)
)
return
produce_combined_fk(
*(
cfgpath(str(name), grid)
for name in (
ffns3,
ffn03,
ffns4til,
ffns4bar,
ffn04,
ffns5til,
ffns5bar,
)
),
theoryid,
damp=(tcard["DAMP"], tcard["DAMPPOWERc"], tcard["DAMPPOWERb"]),
cfg=cfg,
)
if new_fk_path.exists():
logger.info("[green]Success:[/] Wrote FK table to %s", str(new_fk_path))
else:
logger.info("[red]Failure:[/]")


def produce_combined_fk(
ffns3,
ffn03,
Expand Down Expand Up @@ -264,5 +362,5 @@ def dump_tcards(tcard, tcard_parent_path, theoryid):
with open(theorycard_path, "w", encoding="UTF-8") as f:
yaml.safe_dump(theorycard, f)
paths_list.append(theorycard_path)
rich.print(f"[green]Wrote theory card to {theorycard_path}")
logger.info("[green]Wrote theory card to %s", str(theorycard_path))
return paths_list

0 comments on commit e7dbfb1

Please sign in to comment.