Skip to content

Commit dc81640

Browse files
committed
Add #451 to docs, whatsnew
1 parent bdbe796 commit dc81640

File tree

9 files changed

+140
-30
lines changed

9 files changed

+140
-30
lines changed

doc/api/report/index.rst

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,13 +139,37 @@ API reference
139139
.. automodule:: message_ix_models.report
140140
:members:
141141

142+
General-purpose code:
143+
142144
.. autosummary::
143145

144146
Config
147+
defaults
145148
prepare_reporter
146149
register
147150
report
148151

152+
The following submodules prepare reporting of specific measures or quantities:
153+
154+
.. autosummary::
155+
:toctree: _autosummary
156+
:template: autosummary-module.rst
157+
:recursive:
158+
159+
extraction
160+
161+
.. currentmodule:: message_ix_models.report.key
162+
163+
Keys
164+
----
165+
166+
.. automodule:: message_ix_models.report.key
167+
:members:
168+
169+
Pre-set :class:`genno.Key` instances
170+
and :class:`genno.Keys` in this module can be referenced across modules,
171+
instead of hand-typing the same strings in multiple places.
172+
149173
.. currentmodule:: message_ix_models.report.plot
150174

151175
Plots
@@ -167,17 +191,25 @@ Operators
167191

168192
.. autosummary::
169193

194+
broadcast_wildcard
195+
call
170196
codelist_to_groups
171197
compound_growth
172198
exogenous_data
173199
filter_ts
174200
from_url
201+
get_commodity_groups
175202
get_ts
176203
gwp_factors
177204
make_output_path
178205
model_periods
206+
node_glb
207+
nodes_world_agg
179208
remove_ts
209+
select_allow_empty
210+
select_expand
180211
share_curtailment
212+
zeros_like
181213

182214
The following functions, defined elsewhere,
183215
are exposed through :mod:`.operator`
@@ -186,6 +218,8 @@ Operators
186218
.. autosummary::
187219

188220
message_ix_models.util.add_par_data
221+
message_ix_models.util.merge_data
222+
message_ix_models.util.nodes_ex_world
189223

190224
Other operators or genno-compatible functions are provided by:
191225

@@ -219,6 +253,7 @@ Utilities
219253

220254
.. autosummary::
221255

256+
IAMCConversion
222257
add_replacements
223258
collapse
224259
collapse_gwp_info

doc/pkg-data/codelists.rst

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,18 @@ These codes have the following annotations:
1818
``units`` (mandatory)
1919
Units typically associated with this commodity.
2020
``iea-eweb-flow`` (optional)
21-
List of ``FLOW`` codes from the IEA :ref:`tools-iea-web` associated with this MESSAGEix-GLOBIOM commodity.
21+
List of ``FLOW`` codes from the IEA :ref:`tools-iea-web`
22+
associated with this MESSAGEix-GLOBIOM commodity.
2223
``iea-eweb-product`` (optional)
23-
List of ``PRODUCT`` codes from the IEA :ref:`tools-iea-web` associated with this MESSAGEix-GLOBIOM commodity.
24+
List of ``PRODUCT`` codes from the IEA :ref:`tools-iea-web`
25+
associated with this MESSAGEix-GLOBIOM commodity.
26+
``report`` (optional)
27+
English name for IAMC-structured reporting output.
28+
See :func:`.add_replacements`.
29+
``report-only`` (optional)
30+
:class:`bool`.
31+
If :any:`True`,
32+
the code is ignored by :func:`.bare.get_spec`.
2433

2534
.. literalinclude:: ../../message_ix_models/data/commodity.yaml
2635
:language: yaml

doc/whatsnew.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ Next release
1111
- New method :meth:`~.report.Config.iter_callbacks`.
1212

1313
- New function :func:`.tools.iamc.compare` (:pull:`178`).
14+
- New module :mod:`.report.extraction` for reporting of resource extraction (:pull:`451`).
15+
- New reporting operators (:pull:`451`):
16+
:func:`.get_commodity_groups`,
17+
:func:`.node_glb`, and
18+
:func:`.zeros_like`.
1419
- Expand :doc:`api/report/index` documentation (:pull:`178`)
1520
to cover features implemented/not implemented by :mod:`genno`-based reporting.
1621
Module globals :data:`.NOT_IMPLEMENTED_MEASURE` and :data:`.NOT_IMPLEMENTED_IAMC`

message_ix_models/report/__init__.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"NOT_IMPLEMENTED_IAMC",
3030
"NOT_IMPLEMENTED_MEASURE",
3131
"Config",
32+
"defaults",
3233
"prepare_reporter",
3334
"register",
3435
"report",
@@ -327,6 +328,9 @@ def prepare_reporter(
327328
) -> tuple[Reporter, "KeyLike | None"]:
328329
"""Return a :class:`.Reporter` and `key` prepared to report a :class:`.Scenario`.
329330
331+
Every function returned by :attr:`.Config.iter_callbacks` is called, in order, to
332+
allow each to populate the `reporter` with additional tasks.
333+
330334
Parameters
331335
----------
332336
context : .Context
@@ -342,8 +346,8 @@ def prepare_reporter(
342346
Returns
343347
-------
344348
.Reporter
345-
Reporter prepared with MESSAGEix-GLOBIOM calculations; if `reporter` is given,
346-
this is a reference to the same object.
349+
Reporter prepared with tasks for reporting a MESSAGEix-GLOBIOM scenario; if
350+
`reporter` is given, this is a reference to the same object.
347351
348352
If :attr:`.cli_output` is given, a task with the key "cli-output" is added that
349353
writes the :attr:`.Config.key` to that path.
@@ -430,6 +434,16 @@ def prepare_reporter(
430434

431435

432436
def defaults(rep: Reporter, context: Context) -> None:
437+
"""Prepare default contents and configuration of `rep` for MESSAGEix-GLOBIOM.
438+
439+
This includes:
440+
441+
- Populate :data:`.key.coords` and :data:`.key.groups`.
442+
- Add a :func:`genno.operator.concat` task with no arguments at
443+
:data:`.key.all_iamc`.
444+
- Call :func:`.add_replacements` for members of the :ref:`commodity-yaml` and
445+
:ref:`technology-yaml` code lists
446+
"""
433447
from message_ix_models.model.structure import get_codes
434448

435449
from . import key as k

message_ix_models/report/config.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ def _default_callbacks() -> list[Callback]:
2828

2929
from . import defaults, extraction
3030

31+
# NB When updating this list, also update the docstring of Config.callback
3132
return [defaults, extraction.callback, plot.callback]
3233

3334

@@ -45,13 +46,17 @@ class Config(ConfigHelper):
4546
#: Shorthand to set :py:`legacy["use"]` on a new instance.
4647
_legacy: InitVar[bool | None] = False
4748

48-
#: List of callbacks for preparing the :class:`.Reporter`.
49+
#: List of callback functions for preparing the :class:`.Reporter`.
4950
#:
5051
#: Each registered function is called by :func:`~.report.prepare_reporter` in order
5152
#: to add or modify the task graph. Specific model variants and projects can
52-
#: register a callback to extend the reporting graph.
53+
#: register a callback to extend the reporting graph. The default list is:
5354
#:
54-
#: Callback functions **must** take two arguments: the Computer/Reporter, and a
55+
#: 1. :func:`.report.defaults`
56+
#: 2. :func:`.report.extraction.callback`
57+
#: 3. :func:`.report.plot.callback`
58+
#:
59+
#: A callback function **must** take two arguments: the Computer/Reporter, and a
5560
#: :class:`.Context`:
5661
#:
5762
#: .. code-block:: python
@@ -63,7 +68,7 @@ class Config(ConfigHelper):
6368
#: # Modify `rep` by calling its methods ...
6469
#: pass
6570
#:
66-
#: # Register this callback on an existing Context instance
71+
#: # Register this callback on an existing Context/report.Config instance
6772
#: context.report.register(cb)
6873
#:
6974
#: See also :attr:`modules`.
@@ -78,7 +83,7 @@ class Config(ConfigHelper):
7883
#: Key for the Quantity or computation to report.
7984
key: "KeyLike | None" = None
8085

81-
#: Names of modules with reporting callbacks. See also :attr:`callbacks` and
86+
#: Names of modules with reporting callbacks. See also :attr:`callback` and
8287
#: :meth:`iter_callbacks`.
8388
modules: list[str] = field(default_factory=list)
8489

@@ -106,8 +111,8 @@ def iter_callbacks(self) -> Generator[Callback, None, None]:
106111
"""Iterate over callback functions.
107112
108113
1. All module names in :attr:`modules` are passed to :meth:`register`, such that
109-
their callback functions are appended to :attr:`callbacks`.
110-
2. The :attr:`callbacks` are yielded iteratively.
114+
their callback functions are appended to :attr:`callback`.
115+
2. The :attr:`callback` are yielded iteratively.
111116
"""
112117
for name in self.modules:
113118
self.register(name)

message_ix_models/report/extraction.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""Report resource extraction."""
2+
13
from typing import TYPE_CHECKING
24

35
from genno import Keys

message_ix_models/report/key.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,28 @@
22

33
from genno import Key, Keys
44

5+
#: Gross domestic product.
56
GDP = Key("GDP", "ny")
67

7-
# NB genno ≤ 1.27.1 is sensitive to the order
8+
#: Commodity price.
9+
#:
10+
#: .. note:: genno ≤ 1.27.1 is sensitive to the dimension order; more recent versions
11+
#: are not.
812
PRICE_COMMODITY = Key("PRICE_COMMODITY", "nclyh")
913

1014
#: All IAMC-structured data.
1115
all_iamc = Key("all", (), "iamc")
1216

13-
#: Identifiers for coordinates.
17+
#: Identifiers for coordinates, including:
18+
#:
19+
#: - :py:`.n_glb`: the output of :func:`.node_glb`.
1420
coords = Keys(
1521
n_glb="n::glb",
1622
)
1723

18-
#: Identifiers for grouping/aggregation mappings.
24+
#: Identifiers for grouping/aggregation mappings, including:
25+
#:
26+
#: - :py:`.c`: the output of :func:`.get_commodity_groups`.
1927
groups = Keys(
2028
c="c::groups",
2129
)

message_ix_models/report/operator.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,19 @@ def filter_ts(df: pd.DataFrame, expr: re.Pattern, *, column="variable") -> pd.Da
165165

166166
@cache
167167
def get_commodity_groups() -> dict[Literal["c"], dict[str, list[str]]]:
168-
"""Return groups of commodities for reporting of extraction.
169-
170-
The structure is retrieved from :ref:`commodity-yaml` using :func:`.leaf_ids`.
168+
"""Return groups of commodities for aggregation.
169+
170+
The structure is retrieved from :ref:`commodity-yaml` using :func:`.leaf_ids`. The
171+
group IDs include only those commodities from the code list with children. The
172+
group members include only 'leaf' codes via :func:`.leaf_ids`; any intermediate
173+
codes that have children are expanded to the list of those children.
174+
175+
Returns
176+
-------
177+
dict
178+
with one top-level key, 'c', and at the second level mapping from group IDs to
179+
their components. This is suitable for use as the :py:`groups` argument to
180+
:func:`genno.operator.aggregate`.
171181
"""
172182
cl = get_codelist("commodity")
173183
return {"c": {c.id: leaf_ids(c) for c in filter(lambda c: len(c.child), cl)}}

message_ix_models/report/util.py

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#:
2525
#: - Applied to whole strings along each dimension.
2626
#: - These columns have :meth:`str.title` applied before these replacements.
27+
#:
28+
#: See also :func:`add_replacements`.
2729
REPLACE_DIMS: dict[str, dict[str, str]] = {
2830
"c": {
2931
# in land_out, for CH4 emissions from GLOBIOM
@@ -36,14 +38,15 @@
3638
"t": dict(),
3739
}
3840

39-
#: Replacements used in :meth:`collapse` after the 'variable' column is assembled.
40-
#: These are applied using :meth:`pandas.DataFrame.replace` with ``regex=True``; see
41-
#: the documentation of that method. For documentation of regular expressions, see
41+
#: Replacements used in :func:`collapse` after 'variable' labels are constructed. These
42+
#: are applied using :meth:`pandas.DataFrame.replace` with ``regex=True``; see the
43+
#: documentation of that method. For documentation of regular expressions, see
4244
#: https://docs.python.org/3/library/re.html and https://regex101.com.
4345
#:
44-
#: .. todo:: These may be particular or idiosyncratic to a single "template". The
45-
#: strings used to collapse multiple conceptual dimensions into the IAMC "variable"
46-
#: column are known to vary in poorly-documented ways across these templates.
46+
#: .. todo:: These may be particular or idiosyncratic to a single 'template'. The
47+
#: strings used to collapse multiple conceptual dimensions into the IAMC 'variable'
48+
#: dimension are known to vary across these templates, in ways that are sometimes not
49+
#: documented.
4750
#:
4851
#: This setting is currently applied universally. To improve, specify a different
4952
#: mapping with the replacements needed for each individual template, and load the
@@ -212,18 +215,19 @@ def collapse(df: pd.DataFrame, var=[]) -> pd.DataFrame:
212215
"""Callback for the `collapse` argument to :meth:`~.Reporter.convert_pyam`.
213216
214217
Replacements from :data:`REPLACE_DIMS` and :data:`REPLACE_VARS` are applied.
215-
The dimensions listed in the `var` arguments are automatically dropped from the
216-
returned :class:`pyam.IamDataFrame`. If ``var[0]`` contains the word "emissions",
217-
then :meth:`collapse_gwp_info` is invoked.
218+
The dimensions listed in the `var` argument are automatically dropped from the
219+
returned :class:`pyam.IamDataFrame`. If :py:`var[0]` contains the word "emissions",
220+
then :func:`collapse_gwp_info` is invoked.
218221
219222
Adapted from :func:`genno.compat.pyam.collapse`.
220223
221224
Parameters
222225
----------
223226
var : list of str, optional
224-
Strings or dimensions to concatenate to the 'Variable' column. The first of
225-
these is usually a string value used to populate the column. These are joined
226-
using the pipe ('|') character.
227+
Strings or dimensions to concatenate to a 'variable' string. The first of these
228+
usually a :class:`str` used to populate the column; others may be fixed strings
229+
or the IDs of dimensions in the input data. The components are joined using the
230+
pipe ('|') character.
227231
228232
See also
229233
--------
@@ -314,7 +318,25 @@ def copy_ts(rep: Reporter, other: str, filters: dict | None) -> Key:
314318

315319

316320
def add_replacements(dim: str, codes: Iterable[Code]) -> None:
317-
"""Update :data:`REPLACE_DIMS` for dimension `dim` with values from `codes`."""
321+
"""Update :data:`REPLACE_DIMS` for dimension `dim` with values from `codes`.
322+
323+
For every code in `codes` that has an annotation with the ID ``report``, the code
324+
ID is mapped to the value of the annotation. For example, the following in one of
325+
the :doc:`/pkg-data/codelists`:
326+
327+
.. code-block:: yaml
328+
329+
foo:
330+
report: fOO
331+
332+
bar:
333+
report: Baz
334+
335+
qux: {} # No "report" annotation → no mapping
336+
337+
…results in entries :py:`{"foo": "fOO", "bar": "Baz"}` added to :data:`REPLACE_DIMS`
338+
and used by :func:`collapse`.
339+
"""
318340
for code in codes:
319341
try:
320342
label = str(code.get_annotation(id="report").text)

0 commit comments

Comments
 (0)