Source code for genno.compat.pyam
import logging
from functools import partial
from importlib import import_module
from importlib.util import find_spec
from typing import TYPE_CHECKING
from genno import Computer, Key
from genno.core.key import single_key
if TYPE_CHECKING:
from collections.abc import MutableMapping
log = logging.getLogger(__name__)
#: :class:`bool` indicating whether :mod:`pyam` is available. If either the package is
#: not installed, or it is installed but raises some exception on import, this will be
#: :any:`False`, and the operators and configuration handling in the current module will
#: be unavailable.
HAS_PYAM = False
if find_spec("pyam"):
try:
import_module("pyam")
except Exception as e:
# Handle pyam is installed but cannot be imported
log.warning(f"{__name__} unavailable due to {e}")
else:
HAS_PYAM = True
[docs]
def handle_config(c: Computer, info: "MutableMapping") -> None:
"""Handle one entry from the ``iamc:`` config section."""
try:
c.require_compat("pyam")
except ModuleNotFoundError: # pragma: no cover
if not HAS_PYAM:
log.warning("Missing pyam; configuration section 'iamc:' ignored")
return
else:
raise
from . import util
# For each quantity, use a chain of computations to prepare it
name = info.pop("variable")
# Chain of keys produced: first entry is the key for the base quantity
keys: list[Key] = [Key(info.pop("base"))]
# Second entry is a simple rename
keys.append(single_key(c.add_single(Key(name, keys[0].dims, keys[0].tag), keys[0])))
# Optionally select a subset of data from the base quantity
sel = info.get("select")
if sel:
keys.append(
single_key(
c.add_single(
keys[-1].add_tag("sel"),
(c.get_operator("select"), keys[-1], sel),
strict=True,
)
)
)
# Use a setting for the collapse callback function. This doesn't work from file,
# since no way to define a Python function in JSON or YAML
collapse_info = info.pop("collapse", {})
collapse_func = collapse_info.pop("callback", util.collapse)
# Use the Computer method to add the conversion step
# NB convert_pyam() returns a single key when applied to a single key
keys.append(
single_key(
c.add(
keys[-1],
"as_pyam",
rename=info.pop("rename", {}),
collapse=partial(collapse_func, **collapse_info),
replace=info.pop("replace", {}),
drop=set(info.pop("drop", [])) & set(keys[-1].dims),
unit=info.pop("unit", None),
)
)
)
log.info(f"Add {repr(keys[-1])} from {repr(keys[0])}")
log.debug(f" {len(keys)} keys total")
if HAS_PYAM:
# Register the configuration handler only if pyam is actually available
import genno.config
genno.config.handles("iamc")(handle_config)