Skip to content

Commit

Permalink
Add check for #503
Browse files Browse the repository at this point in the history
  • Loading branch information
khaeru committed Aug 27, 2021
1 parent 6594133 commit fca5ae5
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 3 deletions.
32 changes: 32 additions & 0 deletions message_ix/tests/tools/test_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,38 @@ def test_check_westeros(test_mp):
assert not results[0]


def test_check_tl_integer(test_mp):
scen = make_westeros(test_mp)

# Minimal config to make Westeros reportable
config = {"units": {"replace": {"-": ""}}}

# Change one value
tl = "technical_lifetime"
with scen.transact():
scen.add_par(
tl,
make_df(
tl,
node_loc="Westeros",
technology="bulb",
year_vtg=700,
value=1.1,
unit="y",
),
)

# Checks fail
results = check(scen, config=config)
assert not results[0]

assert """FAIL Non-integer values for technical_lifetime:
See https://github.com/iiasa/message_ix/issues/503.
- 1.1 at indices: nl=Westeros t=bulb yv=700""" in map(
str, results
)


@pytest.mark.parametrize(
"url, config",
[
Expand Down
41 changes: 38 additions & 3 deletions message_ix/tools/_check.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from functools import partial
from inspect import getdoc
from logging import ERROR as FAIL
from logging import NOTSET as PASS
from logging import WARNING
Expand All @@ -11,12 +12,13 @@

def append(func):
CHECKS.append(func)
return func


class Result:
"""Container class for a check result and associated messages."""

desc: str
description: str
result: int
message: str = ""

Expand Down Expand Up @@ -95,6 +97,10 @@ def _(vc, input, output):
)


def key_str(dims, key):
return " ".join(f"{d}={k}" for d, k in zip(dims, key))


def check_gaps(qty, years, dim):
"""Check `qty` for gaps in data along `dim`."""
result = PASS
Expand Down Expand Up @@ -122,10 +128,9 @@ def check_gaps(qty, years, dim):
if len(gaps):
# At least 1 gap; format a message
result = WARNING
key_str = " ".join(f"{d}={k}" for d, k in zip(dims, key))
messages.extend(
[
f"- at indices: {key_str}",
f"- at indices: {key_str(dims, key)}",
f" for {dim}: {min(seen)} < {repr(gaps)} < {max(seen)}",
]
)
Expand All @@ -150,6 +155,36 @@ def gaps_tl(rep):
)


def munge_docstring(func):
"""Prepare Result.description and Result.messages from ``func.__doc__``."""
lines = getdoc(func).split("\n")
return lines[0].rstrip("."), lines[2:]


@append
def tl_integer(rep):
"""Non-integer values for technical_lifetime.
See https://github.com/iiasa/message_ix/issues/503.
"""

def _(tl):
# Quick check: convert all values to integer and look for changed values
mask = tl.astype(int) != tl
result = FAIL if mask.any() else PASS

desc, messages = munge_docstring(tl_integer)

# Process item-wise, only if there was some failure
for key, non_int in mask.groupby(list(tl.dims)) if result is FAIL else ():
if non_int.item():
messages.append(f"- {tl.loc[key]} at indices: {key_str(tl.dims, key)}")

return Result(desc, result, messages)

return rep.add("check tl integer", _, rep.full_key("technical_lifetime"))


# @append
def map_tec(rep):
def _(scen):
Expand Down

0 comments on commit fca5ae5

Please sign in to comment.