Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
d4ef495
Partly revert d86843e76ad08c5cc1fa709e543848a3742dfb38
khaeru Apr 26, 2026
46bdb54
Sort .cli.submodules
khaeru Apr 26, 2026
cc57558
Add TODO reduce complexity of prepare_data_B()
khaeru Apr 26, 2026
b174dc3
Use .transport.workflow.add_steps in .bmt.workflow
khaeru Feb 13, 2026
51e56f2
Update BMT workflow
yiyi1991 Feb 17, 2026
c953b01
Update material haircut vetting
yiyi1991 Feb 17, 2026
8a4d5e1
Update T in the BMT workflow
yiyi1991 Mar 9, 2026
8f143bf
Update T report TODO
yiyi1991 Mar 9, 2026
bdcaad6
Add add_macro and clean BMT config
yiyi1991 Mar 10, 2026
ddb38ed
Update add_macro for BMT
yiyi1991 Mar 10, 2026
947d043
Update add_macro_materials
yiyi1991 Mar 10, 2026
bb7f514
Add .report.operator.remove_zeros()
khaeru Aug 17, 2026
527430f
Replace transport.report 0 with blanks in y<y₀
yiyi1991 Mar 18, 2026
2209715
Add tests for IAMC zero-masking in transport report
yiyi1991 Jun 5, 2026
e7038ba
Fix IAMC zero-masking to preserve pyam variables
yiyi1991 Jun 5, 2026
414c05f
Revert "Fix IAMC zero-masking to preserve pyam variables"
khaeru Aug 17, 2026
b4c17cf
Revert "Add tests for IAMC zero-masking in transport report"
khaeru Aug 17, 2026
6e0a891
Revert "Replace transport.report 0 with blanks in y<y₀"
khaeru Aug 17, 2026
ae60980
Remove zeros in .transport.report.convert_iamc()
khaeru Aug 17, 2026
273bf36
Call transport report in BMT workflow
yiyi1991 Mar 18, 2026
ec1752d
Mute assert to run transport.report with y₀>2020
yiyi1991 Mar 18, 2026
0a40151
Update final setup for NGFS C1
yiyi1991 Mar 19, 2026
d1a1cff
Update BMT config
yiyi1991 Mar 22, 2026
e0c1022
Update test_bmt
yiyi1991 May 11, 2026
5361fcc
Update test_workflow for BMT
yiyi1991 May 11, 2026
a487ce3
Update BMT doc
yiyi1991 May 11, 2026
0636955
Improve build_PM and other tests
yiyi1991 May 12, 2026
b384f12
Add _floor_demolition to balance_equality
yiyi1991 May 12, 2026
46ec0e3
Update test for build_PM
yiyi1991 May 12, 2026
b602eb0
Modify clone in general workflow to set as default
yiyi1991 Apr 6, 2026
f51de2f
Handle non-standard CSV format in .buildings.build
yiyi1991 May 17, 2026
880465e
Floor only non-electr prices when linking to MixB
yiyi1991 May 17, 2026
2c4f1af
Update BMT default config
yiyi1991 May 17, 2026
ef58a52
Update invocation of message-ix-buildings scripts
yiyi1991 May 19, 2026
8a1ab16
Include 2110 demand filling and ruff fix
yiyi1991 May 25, 2026
47e5714
Add tests to cover workflow step functions
yiyi1991 Jun 5, 2026
64312db
Add tests to cover scripts calling MixB
yiyi1991 Jun 5, 2026
0055491
Add tests for BMT config
yiyi1991 Jun 5, 2026
3131961
Simplify tests of BMT config
khaeru Aug 17, 2026
be87075
Fix flaky inter_pipe tests and ruff format
yiyi1991 Jun 5, 2026
407a936
Simplify generate_vetting_csv() per review
khaeru Aug 17, 2026
957bd5d
Use .model.workflow.solve in .bmt.workflow
khaeru Aug 17, 2026
4a77612
Remove _message_buildings_install_dir(), tests
khaeru Aug 17, 2026
b1db497
Tidy docstrings, logging in .bmt.{config,workflow}
khaeru Aug 17, 2026
59b140c
Clarify content of bmt/config.yml / Config.code
khaeru Aug 17, 2026
6463a61
Improve type hints for #486
khaeru Aug 17, 2026
115107c
Add #486 to doc/whatsnew
khaeru Aug 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion doc/api/model-bmt.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@ that combines all 3 of the
:doc:`MESSAGEix-Transport </transport/index>` (**T**)
model variants.

In :func:`.bmt.workflow.generate`, each variant is added as follows:

- **Materials (M)** — load a baseline that already includes MESSAGEix-Materials
(step ``M``); there is no separate materials build step yet.
- **Transport (T)** — build MESSAGEix-Transport on the cloned materials scenario
via :func:`.transport.workflow.add_steps` and :func:`.transport.build.main`,
using the ``transport`` section of :file:`data/bmt/config.yaml``.
- **Buildings (B)** — in step ``BMT built``, call :func:`.buildings.build.main`
(imported in :mod:`.bmt.workflow` as ``build_B``) on the ``MT solved`` scenario.
- **Other BMT extensions** — add power-sector material intensity with
:func:`.bmt.utils.build_PM` (``BMTX built``); later steps prepare MACRO
calibration and solve with MESSAGE-MACRO.

The current module :mod:`.model.bmt` includes:

- :func:`.bmt.workflow.generate` —generates a :class:`.Workflow`
Expand All @@ -17,7 +30,7 @@ The current module :mod:`.model.bmt` includes:
used to invoke the workflow.
For example::

mix-models bmt run --from="base" "glasgow+" --dry-run
mix-models bmt run --from="base" "BMTX baseline macro reported" --dry-run

See :program:`mix-models bmt run --help` for options.
- :mod:`.bmt.config` —handling for configuration,
Expand Down
1 change: 1 addition & 0 deletions doc/api/report/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ Operators
node_glb
nodes_world_agg
remove_ts
remove_zeros
select_allow_empty
select_expand
share_curtailment
Expand Down
2 changes: 1 addition & 1 deletion doc/whatsnew.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Next release
- Add IAMC code list :class:`~.iamc.structure.CL_SCENARIO_DIAGNOSTIC` (:pull:`501`).
- New module :ref:`tools-newclimate` (:pull:`499`).
- Add :class:`.model.water.Config` to collect water module settings (:pull:`509`).
- Add :doc:`/api/model-bmt` (:pull:`433`).
- Add :doc:`/api/model-bmt` (:pull:`433`, :pull:`486`).

- Add
:data:`.buildings.config.DEFAULT_DATA_PATHS`,
Expand Down
4 changes: 2 additions & 2 deletions message_ix_models/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,10 @@ def _log_threads(k: int, n: int):
#: Each of these should contain a function named ``cli`` decorated with @click.command
#: or @click.group.
submodules = [
"message_ix_models.model.bmt.cli",
"message_ix_models.model.buildings.cli",
"message_ix_models.model.cli",
"message_ix_models.model.material.cli",
"message_ix_models.model.structure",
"message_ix_models.model.transport.cli",
"message_ix_models.model.water.cli",
Expand All @@ -168,11 +170,9 @@ def _log_threads(k: int, n: int):
"message_ix_models.project.navigate.cli",
"message_ix_models.project.ssp.cli",
"message_ix_models.report.cli",
"message_ix_models.model.material.cli",
"message_ix_models.testing.cli",
"message_ix_models.util.pooch",
"message_ix_models.util.slurm",
"message_ix_models.model.bmt.cli",
]

try:
Expand Down
27 changes: 19 additions & 8 deletions message_ix_models/data/bmt/config.yaml
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
# BMT workflow configuration.
# Top-level keys are energy demand sectors; each is loaded into context (e.g. context.buildings).
# Paths under a sector are relative to private_data_path(sector) unless redefined.
# BMT workflow configuration

# Top-level keys: model_name, buildings, macro, transport, …
# apply_bmt_config sets context.bmt (full dict), context.buildings, context.macro,
# and context.transport (MESSAGEix-Transport Config from the transport section).

model_name: "MESSAGEix-GLOBIOM-GAINS 2.1-BMT-R12"

buildings:
# An ID from CL_SCENARIO_CIRCEULAR, e.g. "R" for "Reference"
code: "R"
Comment thread
khaeru marked this conversation as resolved.
data_paths:
# Input file names under private_data_path("buildings")
prices: "input_prices_R12.csv"
sturm_r: "report_MESSAGE_resid_SSP2_nopol_post.csv"
sturm_c: "report_MESSAGE_comm_SSP2_nopol_post.csv"
demand_static: "static_20251227.csv"
sturm_r: "resid_sturm_aligned_R.csv"
sturm_c: "comm_sturm_aligned_R.csv"
demand_static: "resid_comm_glance_aligned_R.csv"
# Whether to include materials (steel, cement, aluminum) in the buildings spec
with_materials: true
with_materials: False

macro: "macro_calibration_input_SSP2_bmt.xlsx"

transport:
# Scenario code id from the transport SDMX codelist
code: "SSP2" # or "M SSP2"
Comment thread
khaeru marked this conversation as resolved.

# transport: {}
# materials: {}
# others: {}
1 change: 0 additions & 1 deletion message_ix_models/data/buildings/commodity.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ comm_hotwater_gas:
description: Gas demand for commercial hotwater

# loil_rc
resid_cook_lightoil:
resid_cook_lightoil:
description: Light oil demand for residential cooking
resid_hotwater_lightoil:
Expand Down
Git LFS file not shown
85 changes: 57 additions & 28 deletions message_ix_models/model/bmt/config.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,4 @@
"""BMT workflow configuration.

This module loads a file :file:`data/bmt/config.yaml`. This YAML file has top-level
keys:

.. code-block:: yaml

buildings:
# ...
materials:
# ...
transport:
# ...

Of these, only the first is currently required; the latter two are omitted. The function
:func:`_load_yaml` reads each section and passes it to the corresponding
:class:`.Context` key, for instance :py:`Context.buildings`.
"""
"""BMT workflow configuration."""

from typing import TYPE_CHECKING

Expand All @@ -24,22 +7,68 @@
if TYPE_CHECKING:
from pathlib import Path

from message_ix_models.model.buildings import Config
from message_ix_models.util.context import Context


def apply_bmt_config(context: "Context", path: "Path | None" = None) -> None:
"""Load BMT configuration file into `context` (bmt, buildings, macro, transport).

The file given by `path` **must** be in YAML format and have the top-level keys:

.. code-block:: yaml

def load_buildings_config(path: "Path | None" = None) -> "Config":
"""Load the ``buildings`` section from :file:`data/bmt/config.yaml` for
:attr:`context.buildings`.
model_name: "..."
buildings:
# ...
macro: "..."
materials: # Optional
# ...
transport: # Optional
# ...

Missing keys in the ``buildings`` section are filled from
:data:`BUILDINGS_DEFAULTS`. If the section is missing, all defaults are used.
All data from the file is stored at the key :py:`context.bmt` as a :class:`dict`.
The function then sets or converts other values:

- :attr:`context.buildings`: an instance of :class:`~.buildings.config.Config`
(including :attr:`.Config.data_paths`, :attr`~code`` for STURM, etc.) from the
``buildings`` mapping.
- :attr:`context.macro`: ``macro`` string (macro calibration workbook).
- :attr:`context.transport`: and instance of :class:`transport.config.Config` using
:meth:`~.transport.config.Config.from_context`, with the YAML ``transport``
mapping passed as `options` (e.g. ``code: "M SSP2"``).

.. note:: The :py:`context.transport` key must be an instance of that class,
because :mod:`.model.transport` code expects its various attributes.

Parameters
----------
path :
Configuration file path. If not given, defaults to :file:`data/bmt/config.yaml`.
This file **must** be in YAML format has top-leve
"""
from message_ix_models.model.buildings.config import METHOD, Config
import yaml

from message_ix_models.model.buildings.config import METHOD
from message_ix_models.model.buildings.config import Config as BuildingsConfig
from message_ix_models.model.transport.config import Config as TransportConfig

p = path or package_data_path("bmt", "config.yaml")

# Create a buildings Config
result = Config(sturm_scenario="NONE", method=METHOD.B)
result = BuildingsConfig(sturm_scenario="NONE", method=METHOD.B)
context.buildings = result

# Update from the "buildings:" key in the YAML file
result.read_file(path or package_data_path("bmt", "config.yaml"), key="buildings")
result.read_file(p, key="buildings")

# Read the entire file
with open(p) as f:
data = yaml.safe_load(f) or {}

# Store data, MACRO data directly on `context`
context.bmt = data
context.macro = data.get("macro")

return result
# Create a .transport.Config object, overriding defaults with values from the
# "transport:" key in the file
TransportConfig.from_context(context, options=data.get("transport", {}))
Loading
Loading