Reporting (report)

On this page:

Elsewhere:

Introduction

See the discussion in the MESSAGEix docs about the stack. In short, for instance:

  • message_ix must not contain reporting code that references technology="coal_ppl", because not every model built on the MESSAGE framework will have a technology with this name.

  • Any model in the MESSAGEix-GLOBIOM family—built with message_ix_models and/or message_datashould, with few exceptions, have a technology="coal_ppl", since this appears in the common list of Technologies (technology.yaml). Reporting specific to this technology ID, as it is represented in this model family, should be in message_ix_models or user code.

The basic design pattern of message_ix_models.report is:

  • prepare_reporter() populates a new Reporter for a given Scenario with many keys to report all quantities of interest in a MESSAGEix-GLOBIOM–family model.

  • This function relies on callbacks defined in multiple submodules to add keys and tasks for general or tailored reporting calculations and actions. Additional modules should define callback functions and register them with register() when they are to be used. For example:

    1. The module message_ix_models.report.plot defines plot.callback() that adds standard plots to the Reporter.

    2. The module message_data.model.transport.report defines callback() that adds tasks specific to MESSAGEix-Transport.

    3. The module message_data.projects.navigate.report defines callback() that add tasks specific to the ‘NAVIGATE’ research project.

    The callback (1) is always registered, because these plots are always applicable and can be expected to function correctly for all models in the family. In contrast, (2) and (3) should only be registered and run for the specific model variants for which they are developed/intended.

    Modules with tailored reporting configuration may also be indicated on the command line by using the -m/--modules option: mix-models report -m model.transport.

  • A file global.yaml file (in YAML format) contains a description of some of the reporting computations needed for a MESSAGE-GLOBIOM model. prepare_reporter() uses the configuration handlers built into genno (and some extensions specific to message_ix_models) to handle the different sections of the file.

Features

By combining these genno, ixmp, message_ix, and message_ix_models features, the following functionality is provided.

Note

If any of this does not appear to work as advertised, file a bug!

Units

  • Are read automatically for ixmp parameters.

  • Pass through calculations/are derived automatically.

  • Are recognized based on the definitions of non-SI units from IAMconsortium/units.

  • Are discarded when inconsistent.

  • Can be overridden for entire parameters:

    units:
      apply:
        inv_cost: USD
    
  • Can be set explicitly when converting data to IAMC format:

    iamc:
    # 'value' will be in kJ; 'units' will be the string 'kJ'
    - variable: Variable Name
      base: example_var:a-b-c
      units: kJ
    

API reference

Config(from_file, _legacy, cli_output, ...)

Settings for message_ix_models.report.

prepare_reporter(context[, scenario, reporter])

Return a Reporter and key prepared to report a Scenario.

register(name_or_callback)

Register a callback function for prepare_reporter().

report(context, *args, **kwargs)

Report (post-process) solution data in a Scenario.

class message_ix_models.report.Config(from_file: dataclasses.InitVar[typing.Optional[pathlib.Path]] = PosixPath('/home/docs/checkouts/readthedocs.org/user_builds/iiasa-energy-program-message-ix-models/envs/latest/lib/python3.10/site-packages/message_ix_models/data/report/global.yaml'), _legacy: dataclasses.InitVar[typing.Optional[bool]] = False, cli_output: ~pathlib.Path | None = None, genno_config: ~typing.Dict = <factory>, key: KeyLike | None = None, output_dir: ~pathlib.Path | None = <factory>, use_scenario_path: bool = True, legacy: ~typing.Dict = <factory>)[source]

Settings for message_ix_models.report.

When initializing a new instance, the from_file and _legacy parameters are respected.

cli_output: Path | None = None

Path to write reporting outputs when invoked from the command line.

from_file: dataclasses.InitVar[Optional[pathlib.Path]] = PosixPath('/home/docs/checkouts/readthedocs.org/user_builds/iiasa-energy-program-message-ix-models/envs/latest/lib/python3.10/site-packages/message_ix_models/data/report/global.yaml')

Shorthand to call use_file() on a new instance.

genno_config: Dict

Configuration to be handled by genno.config.

key: KeyLike | None = None

Key for the Quantity or computation to report.

legacy: Dict

Keyword arguments for report.legacy.iamc_report_hackathon.report(), plus the key “use”, which should be True if legacy reporting is to be used.

mkdir() None[source]

Ensure the output_dir exists.

output_dir: Path | None

Directory for output.

set_output_dir(arg: Path | None) None[source]

Set output_dir, the output directory.

The value is also stored to be passed to genno as the “output_dir” configuration key.

use_file(file_path: str | Path | None) None[source]

Use genno configuration from a (YAML) file at file_path.

See genno.config for the format of these files. The path is stored at .genno_config["path"], where it is picked up by genno’s configuration mechanism.

Parameters:

file_path (os.PathLike, optional) –

This may be:

  1. The complete path to any existing file.

  2. A stem like “global” or “other”. This is interpreted as referring to a file named, for instance, global.yaml.

  3. A partial path like “project/report.yaml”. This or (2) is interpreted as referring to a file within MESSAGE_MODELS_PATH/data/report/; that is, a file packaged and distributed with message_ix_models.

use_scenario_path: bool = True

True to use an output directory based on the scenario’s model name and name.

message_ix_models.report.prepare_reporter(context: Context, scenario: Scenario | None = None, reporter: Reporter | None = None) Tuple[Reporter, Key][source]

Return a Reporter and key prepared to report a Scenario.

Parameters:
  • context (Context) – The code responds to context.report, which is an instance of report.Config.

  • scenario (Scenario, optional) – Scenario to report. If not given, Context.get_scenario() is used to retrieve a Scenario.

  • reporter (Reporter, optional) – Existing reporter to extend with computations. If not given, it is created using message_ix.Reporter.from_scenario().

Returns:

  • Reporter – Reporter prepared with MESSAGEix-GLOBIOM calculations; if reporter is given, this is a reference to the same object.

    If cli_output is given, a task with the key “cli-output” is added that writes the Config.key to that path.

  • Key – Same as Config.key if any, but in full resolution; else either “default” or “cli-output” according to the other settings.

message_ix_models.report.register(name_or_callback: Callable | str) str | None[source]

Register a callback function for prepare_reporter().

Each registered function is called by prepare_reporter(), in order to add or modify reporting keys. Specific model variants and projects can register a callback to extend the reporting graph.

Callback functions must take two arguments: the Reporter, and a Context:

from message_ix.report import Reporter
from message_ix_models import Context
from message_ix_models.report import register

def cb(rep: Reporter, ctx: Context):
    # Modify `rep` by calling its methods ...
    pass

register(cb)
Parameters:

name_or_callback – If a string, this may be a submodule of message_ix_models, or message_data, in which case the function {message_data,message_ix_models}.{name}.report.callback is used. Or, it may be a fully-resolved package/module name, in which case {name}.callback is used. If a callable (function), it is used directly.

message_ix_models.report.report(context: Context, *args, **kwargs)[source]

Report (post-process) solution data in a Scenario.

This function provides a single, common interface to call both the genno -based (message_ix_models.report) and ‘legacy’ ( message_ix_models.report.legacy) reporting codes.

Parameters:

context (Context) –

The code responds to:

Plots

Plots for MESSAGEix-GLOBIOM reporting.

The current set functions on time series data stored on the scenario by message_ix_models.report or message_data legacy reporting.

class message_ix_models.report.plot.EmissionsCO2[source]

CO₂ Emissions.

basename = 'emission-CO2'

File name base for saving the plot.

generate(data: DataFrame, scenario: Scenario)[source]

Generate and return the plot.

A subclass of Plot must implement this method.

Parameters:

args (Sequence of pandas.DataFrame or other) –

One argument is given corresponding to each of the inputs.

Because plotnine operates on pandas data structures, save() automatically converts any Quantity inputs to pandas.DataFrame before they are passed to generate().

inputs: Sequence[str] = ['Emissions|CO2::iamc', 'scenario']

Keys referring to Quantities or other inputs accepted by generate().

static: List['plotnine.typing.PlotAddable'] = [<plotnine.themes.theme.theme object>, {'x': 'year', 'y': 'value', 'color': 'region'}, <plotnine.geoms.geom_line.geom_line object>, <plotnine.geoms.geom_point.geom_point object>, <plotnine.labels.labs object>]

list of plotnine objects that are not dynamic.

Type:

‘Static’ geoms

class message_ix_models.report.plot.FinalEnergy0[source]

Final Energy.

basename = 'fe0'

File name base for saving the plot.

inputs: Sequence[str] = ['Final Energy::iamc', 'scenario']

Keys referring to Quantities or other inputs accepted by generate().

class message_ix_models.report.plot.FinalEnergy1[source]

Final Energy.

basename = 'fe1'

File name base for saving the plot.

generate(data: DataFrame, scenario: Scenario)[source]

Generate and return the plot.

A subclass of Plot must implement this method.

Parameters:

args (Sequence of pandas.DataFrame or other) –

One argument is given corresponding to each of the inputs.

Because plotnine operates on pandas data structures, save() automatically converts any Quantity inputs to pandas.DataFrame before they are passed to generate().

inputs: Sequence[str] = ['fe1-0::iamc', 'scenario']

Keys referring to Quantities or other inputs accepted by generate().

inputs_regex: List[re.Pattern] = [re.compile('Final Energy\\|(Electricity|Gases|Geothermal|Heat|Hydrogen|Liquids|Solar|Solids)')]

List of regular expressions corresponding to inputs. These are passed as the expr argument to filter_ts() to filter the entire set of time series data.

static: List['plotnine.typing.PlotAddable'] = [<plotnine.themes.theme.theme object>, {'x': 'year', 'y': 'value', 'fill': 'variable'}, <plotnine.geoms.geom_bar.geom_bar object>, <plotnine.labels.labs object>]

list of plotnine objects that are not dynamic.

Type:

‘Static’ geoms

message_ix_models.report.plot.PLOTS = (<class 'message_ix_models.report.plot.EmissionsCO2'>, <class 'message_ix_models.report.plot.FinalEnergy0'>, <class 'message_ix_models.report.plot.FinalEnergy1'>, <class 'message_ix_models.report.plot.PrimaryEnergy0'>, <class 'message_ix_models.report.plot.PrimaryEnergy1'>)

All plot classes.

class message_ix_models.report.plot.Plot[source]

Base class for plots based on reported time-series data.

Subclasses should be used like:

class MyPlot(Plot):
    ...

c.add("plot myplot", MyPlot, "scenario")

…that is, giving “scenario” or another key that points to a Scenario object with stored time series data. See the examples in this file.

classmethod add_tasks(c: Computer, key: KeyLike, *inputs, strict: bool = False) KeyLike[source]

Add a task to c to generate and save the Plot.

Analogous to Operator.add_tasks().

ggtitle(value=None) ggtitle[source]

Return plotnine.ggtitle including the current date & time.

groupby_plot(data: DataFrame, *args)[source]

Combination of groupby and ggplot().

Groups by args and yields a series of plotnine.ggplot objects, one per group, with static geoms and ggtitle() appended to each.

inputs: Sequence[str] = []

Keys referring to Quantities or other inputs accepted by generate().

inputs_regex: List[Pattern] = []

List of regular expressions corresponding to inputs. These are passed as the expr argument to filter_ts() to filter the entire set of time series data.

static: List[plotnine.typing.PlotAddable] = [<plotnine.themes.theme.theme object>]

list of plotnine objects that are not dynamic.

Type:

‘Static’ geoms

title = None

Fixed plot title string. If not given, the first line of the class docstring is used.

unit = None

Units expression for plot title.

url: str | None = None

Scenario URL for plot title.

class message_ix_models.report.plot.PrimaryEnergy0[source]

Primary Energy.

basename = 'pe0'

File name base for saving the plot.

inputs: Sequence[str] = ['Primary Energy::iamc', 'scenario']

Keys referring to Quantities or other inputs accepted by generate().

class message_ix_models.report.plot.PrimaryEnergy1[source]

Primary Energy.

basename = 'pe1'

File name base for saving the plot.

inputs: Sequence[str] = ['pe1-0::iamc', 'scenario']

Keys referring to Quantities or other inputs accepted by generate().

inputs_regex: List[re.Pattern] = [re.compile('Primary Energy\\|((?!Fossil|Non-Biomass Renewables|Secondary Energy Trade)[^\\|]*)')]

List of regular expressions corresponding to inputs. These are passed as the expr argument to filter_ts() to filter the entire set of time series data.

message_ix_models.report.plot.callback(c: Computer, context: Context) None[source]

Add all PLOTS to c.

Also add a key “plot all” to triggers the generation of all plots.

Operators

Atomic reporting operations for MESSAGEix-GLOBIOM.

message_ix_models.report.operator provides the following:

codelist_to_groups(codes[, dim])

Convert codes into a mapping from parent items to their children.

compound_growth(qty, dim)

Compute compound growth along dim of qty.

exogenous_data

No action.

filter_ts(df, expr, *[, column])

Filter time series data in df.

from_url(url[, cls])

Return a ixmp.TimeSeries or subclass instance, given its url.

get_ts(scenario[, filters, iamc, subannual])

Retrieve timeseries data from scenario.

gwp_factors()

Use iam_units to generate a Quantity of GWP factors.

make_output_path(config, name)

Return a path under the "output_dir" Path from the reporter configuration.

model_periods(y, cat_year)

Return the elements of y beyond the firstmodelyear of cat_year.

remove_ts(scenario[, config, after, dump])

Remove all time series data from scenario.

share_curtailment(curt, *parts)

Apply a share of curt to the first of parts.

The following functions, defined elsewhere, are exposed through operator and so can also be referenced by name:

message_ix_models.util.add_par_data(...[, ...])

Add data to scenario.

Other operators or genno-compatible functions are provided by:

Any of these can be made available for a Computer instance using require_compat(), for instance:

# Indicate that a certain module contains functions to
# be referenced by name
c.require_compat("message_ix_models.model.emissions")

# Add computations to the graph by referencing functions
c.add("ef:c", "get_emission_factors", units="t C / kWa")
message_ix_models.report.operator.codelist_to_groups(codes: List[Code], dim: str = 'n') Mapping[str, Mapping[str, List[str]]][source]

Convert codes into a mapping from parent items to their children.

The returned value is suitable for use with genno.operator.aggregate().

If this is a list of nodes per get_codes(), then the mapping is from regions to the ISO 3166-1 alpha-3 codes of the countries within each region. The code for the region itself is also included in the values to be aggregated, so that already- aggregated data will pass through.

message_ix_models.report.operator.compound_growth(qty: AttrSeries, dim: str) AttrSeries[source]

Compute compound growth along dim of qty.

message_ix_models.report.operator.filter_ts(df: DataFrame, expr: Pattern, *, column='variable') DataFrame[source]

Filter time series data in df.

  1. Keep only rows in df where expr is a full match ( fullmatch()) for the entry in column.

  2. Retain only the first match group (”…(…)…”) from expr as the column entry.

message_ix_models.report.operator.from_url(url: str, cls=<class 'ixmp.core.timeseries.TimeSeries'>) TimeSeries[source]

Return a ixmp.TimeSeries or subclass instance, given its url.

Todo

Move upstream, to ixmp.report.

Parameters:

cls (type, optional) – Subclass to instantiate and return; for instance, Scenario.

message_ix_models.report.operator.get_ts(scenario: Scenario, filters: dict | None = None, iamc: bool = False, subannual: bool | str = 'auto')[source]

Retrieve timeseries data from scenario.

Corresponds to ixmp.Scenario.timeseries().

Todo

Move upstream, e.g. to ixmp alongside store_ts().

message_ix_models.report.operator.gwp_factors() AttrSeries[source]

Use iam_units to generate a Quantity of GWP factors.

The quantity is dimensionless, e.g. for converting [mass] to [mass], andhas dimensions:

  • ‘gwp metric’: the name of a GWP metric, e.g. ‘SAR’, ‘AR4’, ‘AR5’. All metrics are

    on a 100-year basis.

  • ‘e’: emissions species, as in MESSAGE. The entry ‘HFC’ is added as an alias for the species ‘HFC134a’ from iam_units.

  • ‘e equivalent’: GWP-equivalent species, always ‘CO2’.

message_ix_models.report.operator.make_output_path(config: Mapping, name: str) Path[source]

Return a path under the “output_dir” Path from the reporter configuration.

message_ix_models.report.operator.model_periods(y: List[int], cat_year: DataFrame) List[int][source]

Return the elements of y beyond the firstmodelyear of cat_year.

Todo

Move upstream, to message_ix.

message_ix_models.report.operator.nodes_ex_world(nodes: Sequence[str | Code]) List[str | Code][source]

Exclude “World” and anything containing “GLB” from nodes.

May also be used as a genno (reporting) operator.

message_ix_models.report.operator.remove_ts(scenario: Scenario, config: dict | None = None, after: int | None = None, dump: bool = False) None[source]

Remove all time series data from scenario.

Note that data stored with add_timeseries() using meta=True as a keyword argument cannot be removed using TimeSeries.remove_timeseries(), and thus also not with this operator.

Todo

Move upstream, to ixmp alongside store_ts().

message_ix_models.report.operator.share_curtailment(curt, *parts)[source]

Apply a share of curt to the first of parts.

If this is being used, it usually will indicate the need to split curt into multiple technologies; one for each of parts.

Utilities

add_replacements(dim, codes)

Update REPLACE_DIMS for dimension dim with values from codes.

as_quantity(info)

Convert values from a dict to Quantity.

collapse(df[, var])

Callback for the collapse argument to convert_pyam().

collapse_gwp_info(df, var)

collapse() helper for emissions data with GWP dimensions.

copy_ts(rep, other, filters)

Prepare rep to copy time series data from other to scenario.

message_ix_models.report.util.REPLACE_DIMS: Dict[str, Dict[str, str]] = {'c': {'Agri_Ch4': 'GLOBIOM|Emissions|CH4 Emissions Total'}, 'l': {'Final Energy': 'Final Energy|Residential'}, 't': {}}

Replacements used in collapse(). These are applied using pandas.DataFrame.replace() with regex=True; see the documentation of that method.

  • Applied to whole strings along each dimension.

  • These columns have str.title() applied before these replacements.

message_ix_models.report.util.REPLACE_VARS = {'(Emissions\\|CH4)\\|((Gases|Liquids|Solids|Elec|Heat)(.*))': '\\1|Energy|Supply|\\3|Fugitive\\4', '(Emissions\\|CH4)\\|Fugitive': '\\1|Energy|Supply|Fugitive', '(Secondary Energy\\|Solids)\\|Solids': '\\1', 'Import Energy\\|(Liquids\\|(Biomass|Oil))': 'Secondary Energy|\\1', 'Import Energy\\|Coal': 'Primary Energy|Coal', 'Import Energy\\|Lh2': 'Secondary Energy|Hydrogen', 'Import Energy\\|Lng': 'Primary Energy|Gas', 'Import Energy\\|Oil': 'Primary Energy|Oil', 'Residential\\|(Biomass|Coal)': 'Residential|Solids|\\1', 'Residential\\|Gas': 'Residential|Gases|Natural Gas', '^(land_out CH4.*\\|)Awm': '\\1Manure Management', '^land_out CH4\\|': '', '^land_out CH4\\|Emissions\\|Ch4\\|Land Use\\|Agriculture\\|': 'Emissions|CH4|AFOLU|Agriculture|Livestock|'}

Replacements used in collapse() after the ‘variable’ column is assembled. These are applied using pandas.DataFrame.replace() with regex=True; see the documentation of that method. For documentation of regular expressions, see https://docs.python.org/3/library/re.html and https://regex101.com.

Todo

These may be particular or idiosyncratic to a single “template”. The strings used to collapse multiple conceptual dimensions into the IAMC “variable” column are known to vary in poorly-documented ways across these templates.

This setting is currently applied universally. To improve, specify a different mapping with the replacements needed for each individual template, and load the correct one when reporting scenarios to that template.

message_ix_models.report.util.add_replacements(dim: str, codes: Iterable[Code]) None[source]

Update REPLACE_DIMS for dimension dim with values from codes.

message_ix_models.report.util.as_quantity(info: dict | float | str) AttrSeries[source]

Convert values from a dict to Quantity.

Todo

move upstream, to genno.

message_ix_models.report.util.collapse(df: DataFrame, var=[]) DataFrame[source]

Callback for the collapse argument to convert_pyam().

Replacements from REPLACE_DIMS and REPLACE_VARS are applied. The dimensions listed in the var arguments are automatically dropped from the returned pyam.IamDataFrame. If var[0] contains the word “emissions”, then collapse_gwp_info() is invoked.

Adapted from genno.compat.pyam.collapse().

Parameters:

var (list of str, optional) – Strings or dimensions to concatenate to the ‘Variable’ column. The first of these is usually a string value used to populate the column. These are joined using the pipe (‘|’) character.

See also

REPLACE_DIMS, REPLACE_VARS, collapse_gwp_info, test_collapse

message_ix_models.report.util.collapse_gwp_info(df, var)[source]

collapse() helper for emissions data with GWP dimensions.

The dimensions ‘e equivalent’, and ‘gwp metric’ dimensions are combined with the ‘e’ dimension, using a format like:

'{e} ({e equivalent}-equivalent, {GWP metric} metric)'

For example:

'SF6 (CO2-equivalent, AR5 metric)'
message_ix_models.report.util.copy_ts(rep: Reporter, other: str, filters: dict | None) Key[source]

Prepare rep to copy time series data from other to scenario.

Parameters:
  • other_url (str) – URL of the other scenario from which to copy time series data.

  • filters (dict, optional) – Filters; passed via store_ts() to ixmp.TimeSeries.timeseries().

Returns:

Key for the copy operation.

Return type:

str

Compatibility with report.legacy

Compatibility code that emulates legacy reporting.

report.compat prepares a Reporter to perform the same calculations as report.legacy, except using genno.

Warning

This code is under development and incomplete. It is not yet a full or exact replacement for report.legacy. Use with caution.

Main API:

TECH_FILTERS

Filters for determining subsets of technologies.

callback(rep, context)

Partially duplicate the behaviour of default_tables.retr_CO2emi().

prepare_techs(c, technologies)

Prepare sets of technologies in c.

get_techs(c, prefix[, kinds])

Return a list of technologies.

Utility functions:

inp(c, technologies, *[, name, filters, ...])

eff(c, technologies[, filters_in, filters_out])

Throughput efficiency (input / output) for technologies.

emi(c, technologies, *[, name, filters, ...])

out(c, technologies, *[, name, filters, ...])

message_ix_models.report.compat.TECH_FILTERS = {'gas all': "c_in == 'gas' and l_in in 'secondary final' and '_ccs' not in id", 'gas extra': 'False', 'rc gas': "sector == 'residential/commercial' and c_in == 'gas'", 'trp coal': "sector == 'transport' and c_in == 'coal'", 'trp foil': "sector == 'transport' and c_in == 'fueloil'", 'trp gas': "sector == 'transport' and c_in == 'gas'", 'trp loil': "sector == 'transport' and c_in == 'lightoil'", 'trp meth': "sector == 'transport' and c_in == 'methanol'"}

Filters for determining subsets of technologies.

Each value is a Python expression eval()’d in an environment containing variables derived from the annotations on Codes for each technology. If the expression evaluates to True, then the code belongs to the set identified by the key.

message_ix_models.report.compat.callback(rep: Reporter, context: Context) None[source]

Partially duplicate the behaviour of default_tables.retr_CO2emi().

Currently, this prepares the following keys and the necessary preceding calculations:

  • “transport emissions full::iamc”: data for the IAMC variable “Emissions|CO2|Energy|Demand|Transportation|Road Rail and Domestic Shipping”

message_ix_models.report.compat.eff(c: Computer, technologies: List[str], filters_in: dict | None = None, filters_out: dict | None = None) Key[source]

Throughput efficiency (input / output) for technologies.

Equivalent to PostProcess.eff().

Parameters:
  • filters_in (dict, optional) – Passed as the filters parameter to inp().

  • filters_out (dict, optional) – Passed as the filters parameter to out().

message_ix_models.report.compat.get_techs(c: Computer, prefix: str, kinds: str | None = None) List[str][source]

Return a list of technologies.

The list is assembled from lists in c with keys like “t::{prefix} {kind}”, with one kind for each space-separated item in kinds. If no kinds are supplied, “t::{prefix}” is used.

See also

prepare_techs

message_ix_models.report.compat.prepare_techs(c: Computer, technologies: List[Code]) None[source]

Prepare sets of technologies in c.

For each keyexpr in TECH_FILTERS and each technology Code t in technologies:

  • Apply the filter expression expr to information about t.

  • If the expression evaluates to True, add it to a list in c at “t::{key}”.

These lists of technologies can be used directly or retrieve with get_techs().

Command-line interface

$ mix-models report --help

Usage: mix-models report [OPTIONS] [KEY]

  Postprocess results.

  KEY defaults to the comprehensive report 'message::default', but may also be
  the name of a specific model quantity, e.g. 'output'.

  --config can give either the absolute path to a reporting configuration
  file, or the stem (i.e. name without .yaml extension) of a file in
  data/report.

  With --from-file, read multiple Scenario identifiers from FILE, and report
  each one. In this usage, --output-path may only be a directory.

Options:
  --dry-run             Only show what would be done.
  --config TEXT         Path or stem for reporting config file.  [default:
                        global]
  -L, --legacy          Invoke legacy reporting.
  -m, --module MODULES  Add extra reporting for MODULES.
  -o, --output PATH     Write output to file instead of console.
  --from-file FILE      Report multiple Scenarios listed in FILE.
  --help                Show this message and exit.

Testing

Simulated solution data for testing report.

message_ix_models.report.sim.add_simulated_solution(rep: Reporter, info: ScenarioInfo, data: Dict | None = None, path: Path | None = None)[source]

Add a simulated model solution to rep.

Parameters:
  • data (dict or pandas.DataFrame, optional) – If given, a mapping from MESSAGE item (set, parameter, or variable) names to inputs that are passed to simulate_qty().

  • path (Path, optional) – If given, a path to a directory containing one or more files with names like ACT.csv.gz. These files are taken as containing “simulated” model solution data for the MESSAGE variable with the same name. See data_from_file().

message_ix_models.report.sim.data_from_file(path: Path, *, name: str, dims: Sequence[str]) AttrSeries[source]

Read simulated solution data for item name from path.

For variables and equations (name in upper case), the file must have columns corresponding to dims followed by “Val”, “Marginal”, “Upper”, and “Scale”. The “Val” column is returned.

For parameters, the file must have columns corresponding to dims followed by “value” and “unit”. The “value” column is returned.

message_ix_models.report.sim.simulate_qty(name: str, dims: List[str], item_data: dict | DataFrame) AttrSeries[source]

Return simulated data for item name.

Parameters:
  • dims – Dimensions of the resulting quantity.

  • item_data – Optional data for the quantity.

message_ix_models.report.sim.to_simulate()[source]

Return items to be included in a simulated solution.

Continuous reporting

As part of the Test suite (message_ix_models.tests), reporting is run on the same events (pushes and daily schedule) on publicly-available model snapshots. One goal of these tests inter alia is to ensure that adjustments and improvements to the reporting code do not disturb manually-verified model outputs.

As part of the (private) message_data test suite, multiple workflows run on regular schedules; some of these include a combination of message_ix_models-based and ‘legacy’ reporting. These workflows:

  • Operate on specific scenarios within IIASA databases.

  • Create files in CSV, Excel, and/or PDF formats that are that are preserved and made available as ‘build artifacts’ via the GitHub Actions web interface and API.