Python API
The application programming interface (API) for MESSAGEix model developers is implemented in Python. The full API is also available from R; see Usage in R via reticulate.
ixmp
package
ixmp
provides three classes. These are fully described by the ixmp documentation, which is cross-linked from many places in the MESSAGEix documentation.
|
Instance of the modeling platform. |
|
Collection of data in time series format. |
|
Collection of model-related data. |
ixmp
also provides some utility classes and methods:
Configuration for ixmp. |
|
Mapping from names to available models. |
|
|
Return a model for name (or the default) with model_options. |
message_ix
package
MESSAGEix models are created using the message_ix.Scenario
class. Several utility methods are also provided in the module message_ix.util
.
- class message_ix.Scenario(mp, model, scenario=None, version=None, annotation=None, scheme=None, **kwargs)[source]
Bases:
Scenario
MESSAGEix Scenario.
See
ixmp.TimeSeries
for the meaning of arguments mp, model, scenario, version, and annotation. The scheme of a newly-created Scenario is always “MESSAGE”.This class extends
ixmp.Scenario
andixmp.TimeSeries
and inherits of the methods of those classes, shown below.message_ix.Scenario
adds or overrides the following methods specific to MESSAGEix:add_cat
(name, cat, keys[, is_unique])Map elements from keys to category cat within set name.
add_horizon
([year, firstmodelyear, data])Set the scenario time horizon via
year
and related categories.add_macro
(data[, scenario, check_convergence])Add MACRO parametrization to the Scenario and calibrate.
add_spatial_sets
(data)Add sets related to spatial dimensions of the model.
cat
(name, cat)Return a list of all set elements mapped to a category.
cat_list
(name)Return a list of all categories for a mapping set.
clone
(*args, **kwargs)Clone the current scenario and return the clone.
equ
(name[, filters])Return equation data.
The first model year of the scenario.
par
(name[, filters])Return parameter data.
rename
(name, mapping[, keep])Rename elements in the set name and transform data indexed by old name(s).
set
(name[, filters])Return elements of a set.
solve
([model, solve_options])Solve MESSAGE or MESSAGE-MACRO for the Scenario.
var
(name[, filters])Return variable data.
vintage_and_active_years
([ya_args, tl_only])Return matched pairs of vintage and active periods for use in data input.
Alias for
firstmodelyear
.years_active
(node, tec, yr_vtg)Return periods in which tec hnology of yr_vtg can be active in node.
ya
(node, tec, yr_vtg)Alias for
years_active()
.yv_ya
([ya_args, tl_only])Alias for
vintage_and_active_years()
.Inherited from
ixmp.Scenario
:Changed in version 3.0:
read_excel()
andto_excel()
are now methods ofixmp.Scenario
, but continue to work with message_ix.Scenario.add_par
(name[, key_or_data, value, unit, ...])Set the values of a parameter.
add_set
(name, key[, comment])Add elements to an existing set.
change_scalar
(name, val, unit[, comment])Set the value and unit of a scalar.
has_item
(name[, item_type])Check whether the Scenario has an item name of item_type.
Return
True
if the Scenario contains model solution data.idx_names
(name)Return the list of index names for an item (set, par, var, equ).
idx_sets
(name)Return the list of index sets for an item (set, par, var, equ).
init_item
(item_type, name[, idx_sets, idx_names])Initialize a new item name of type item_type.
init_scalar
(name, val, unit[, comment])Initialize a new scalar and set its value.
items
([type, filters, indexed_by, par_data])Iterate over model data items.
list_items
(item_type[, indexed_by])List all defined items of type item_type.
Load all Scenario data into memory.
read_excel
(path[, add_units, init_items, ...])Read a Microsoft Excel file into the Scenario.
remove_par
(name[, key])Remove parameter values or an entire parameter.
remove_set
(name[, key])Delete set elements or an entire set.
remove_solution
([first_model_year])Remove the solution from the scenario.
scalar
(name)Return the value and unit of a scalar.
to_excel
(path[, items, filters, max_row])Write Scenario to a Microsoft Excel file.
Inherited from
ixmp.TimeSeries
:add_geodata
(df)Add geodata.
add_timeseries
(df[, meta, year_lim])Add time series data.
check_out
([timeseries_only])Check out the Scenario.
commit
(comment)Commit all changed data to the database.
Discard all changes and reload from the database.
Fetch geodata and return it as dataframe.
get_meta
([name])Get Metadata for this object.
Get the timestamp of the last update/edit of this TimeSeries.
Preload timeseries data to in-memory cache.
read_file
(path[, firstyear, lastyear])Read time series data from a CSV or Microsoft Excel file.
remove_geodata
(df)Remove geodata from the TimeSeries instance.
Remove time series data.
run_id
()Get the run id of this TimeSeries.
Set the current
version
as the default.set_meta
(name_or_dict[, value])Set Metadata for this object.
timeseries
([region, variable, unit, year, ...])Retrieve time series data.
transact
([message, condition, discard_on_error])Context manager to wrap code in a 'transaction'.
URL fragment for the TimeSeries.
- add_macro(data: Mapping | PathLike, scenario=None, check_convergence=True, **kwargs)[source]
Add MACRO parametrization to the Scenario and calibrate.
Note
This method causes existing MACRO calibration data to be overwritten.
- Parameters:
data (
dict
oros.PathLike
) – Dictionary of required data for MACRO calibration (mappingstr
topandas.DataFrame
) or path to a file containing the data.scenario (
str
, optional) – Scenario name for calibrated Scenario. If not given, the name of scenario with “ macro” appended.check_convergence (
bool
, optional) – Confirm that the calibrated scenario solves in one iteration.kwargs – Solve options when solving the calibrated scenario.
- Returns:
A clone of scenario with MACRO calibrated.
- Return type:
See also
Warning
MACRO support via
add_macro()
is experimental in message_ix 3.0 and may not function as expected on all possible MESSAGEix models. See a list of known and pending issues on GitHub.
- add_cat(name, cat, keys, is_unique=False)[source]
Map elements from keys to category cat within set name.
- Parameters:
- add_geodata(df: DataFrame) None [source]
Add geodata.
- Parameters:
df (
pandas.DataFrame
) –Data to add. df must have the following columns:
region
variable
subannual
unit
year
value
meta
- add_horizon(year: Iterable[int] = [], firstmodelyear: int | None = None, data: dict | None = None) None [source]
Set the scenario time horizon via
year
and related categories.add_horizon()
acts likeadd_set("year", ...)
, except with additional conveniences:The firstmodelyear argument can be used to set the first period handled by the MESSAGE optimization. This is equivalent to:
scenario.add_cat("year", "firstmodelyear", ..., is_unique=True)
Parameter
duration_period
is assigned values based on year: The duration of periods is calculated as the interval between successive year elements, and the duration of the first period is set to value that appears most frequently.
See Years, periods, and time slices for a detailed terminology of years and periods in
message_ix
.- Parameters:
- Raises:
ValueError – If the
year
set of the Scenario is already populated. Changing the time periods of an existing Scenario can entail complex adjustments to data. For this purpose, adjust each set and parameter individually, or seetools.add_year
.
Examples
>>> s = message_ix.Scenario() # The following are equivalent >>> s.add_horizon(year=[2020, 2030, 2040], firstmodelyear=2020) >>> s.add_horizon([2020, 2030, 2040], 2020) >>> s.add_horizon([2020, 2030, 2040])
- add_par(name: str, key_or_data: int | str | Sequence[int | str] | dict | DataFrame | None = None, value=None, unit: str | None = None, comment: str | None = None) None [source]
Set the values of a parameter.
- Parameters:
name (
str
) – Name of the parameter.key_or_data (
str
orcollections.abc.Iterable
ofstr
orrange
ordict
orpandas.DataFrame
) – Element(s) to be added.value (
float
orcollections.abc.Iterable
offloat
, optional) – Values.unit (
str
orcollections.abc.Iterable
ofstr
, optional) – Unit symbols.comment (
str
orcollections.abc.Iterable
ofstr
, optional) – Comment(s) for the added values.
- add_set(name: str, key: int | str | Sequence[int | str] | dict | DataFrame, comment: str | Sequence[str] | None = None) None [source]
Add elements to an existing set.
- Parameters:
name (
str
) – Name of the set.key (
str
orcollections.abc.Iterable
ofstr
ordict
orpandas.DataFrame
) – Element(s) to be added. If name exists, the elements are appended to existing elements.comment (
str
orcollections.abc.Iterable
ofstr
, optional) – Comment describing the element(s). If given, there must be the same number of comments as elements.
- Raises:
KeyError – If the set name does not exist.
init_set()
must be called beforeadd_set()
.ValueError – For invalid forms or combinations of key and comment.
- add_spatial_sets(data)[source]
Add sets related to spatial dimensions of the model.
- Parameters:
data (
dict
) –Mapping of level → member. Each member may be:
A single label for elements.
An iterable of labels for elements.
A recursive
dict
following the same convention, defining sub-levels and their members.
Examples
>>> s = message_ix.Scenario() >>> s.add_spatial_sets({'country': 'Austria'}) >>> s.add_spatial_sets({'country': ['Austria', 'Germany']}) >>> s.add_spatial_sets({'country': { ... 'Austria': {'state': ['Vienna', 'Lower Austria']}}})
- add_timeseries(df: DataFrame, meta: bool = False, year_lim: tuple[int | None, int | None] = (None, None)) None [source]
Add time series data.
- Parameters:
df (
pandas.DataFrame
) –Data to add. df must have the following columns:
region or node
variable
unit
Additional column names may be either of:
year and value—long, or ‘tabular’, format.
one or more specific years—wide, or ‘IAMC’ format.
To support subannual temporal resolution of timeseries data, a column subannual is optional in df. The entries in this column must have been defined in the Platform instance using
add_timeslice()
beforehand. If no column subannual is included in df, the data is assumed to contain yearly values. Seetimeslices()
for a detailed description of the feature.meta (
bool
, optional) – IfTrue
, store df as metadata. Metadata is treated specially whenScenario.clone()
is called for Scenarios created withscheme='MESSAGE'
.year_lim (
tuple
, optional) – Respectively, earliest and latest years to add from df; data for other years is ignored.
- cat_list(name)[source]
Return a list of all categories for a mapping set.
- Parameters:
name (
str
) – Name of the set.
- change_scalar(name: str, val: Real, unit: str, comment: str | None = None) None [source]
Set the value and unit of a scalar.
- check_out(timeseries_only: bool = False) None [source]
Check out the Scenario.
- Raises:
ValueError – If
has_solution()
isTrue
.
See also
TimeSeries.check_out
,util.maybe_check_out
- clone(*args, **kwargs)[source]
Clone the current scenario and return the clone.
See
ixmp.Scenario.clone()
for other parameters.- Parameters:
keep_solution (
bool
, optional) – IfTrue
, include all time series and model solution (variable and equation) data from the current Scenario in the clone. Otherwise, only time series data marked asmeta=True
(seeixmp.TimeSeries.add_timeseries()
) or prior to first_model_year (seeixmp.TimeSeries.add_timeseries()
) are cloned.shift_first_model_year (
int
, optional) – If given, certain values of the model solution are transferred to correspondin gparametershistorical_*
, parameterresource_volume
is updated, and the first_model_year is shifted. The solution is then discarded (remove_solution()
).
- commit(comment: str) None [source]
Commit all changed data to the database.
If the TimeSeries was newly created (with
version='new'
),version
is updated with a new version number assigned by the backend. Otherwise,commit()
does not change theversion
.- Parameters:
comment (
str
) – Description of the changes being committed.
See also
util.maybe_commit
- delete_meta(*args, **kwargs) None [source]
Remove Metadata for this object.
Deprecated since version 3.1: Use
remove_meta()
.
- equ(name, filters=None)[source]
Return equation data.
Same as
ixmp.Scenario.equ()
, except columns indexed by the MESSAGEix setyear
are returned withint
dtype.- Parameters:
name (
str
) – Name of the equation.filters (
dict
, optional) – Filters for the dimensions of the equation. Seeixmp.Scenario.equ()
.
- Returns:
Filtered elements of the equation.
- Return type:
- classmethod from_url(url: str, errors: Literal['warn', 'raise'] = 'warn') tuple[TimeSeries | None, Platform] [source]
Instantiate a TimeSeries (or Scenario) given an
ixmp://
URL.The following are equivalent:
from ixmp import Platform, TimeSeries mp = Platform(name='example') scen = TimeSeries(mp 'model', 'scenario', version=42)
and:
from ixmp import TimeSeries scen, mp = TimeSeries.from_url('ixmp://example/model/scenario#42')
- Parameters:
url (
str
) – Seeparse_url
.errors (
'warn'
or'raise'
) – If ‘warn’, a failure to load the TimeSeries is logged as a warning, and the platform is still returned. If ‘raise’, the exception is raised.
- Returns:
with 2 elements:
The
TimeSeries
referenced by the url.The
Platform
referenced by the url, on which the first element is stored.
- Return type:
- get_geodata() DataFrame [source]
Fetch geodata and return it as dataframe.
- Returns:
Specified data.
- Return type:
- get_meta(name: str | None = None)[source]
Get Metadata for this object.
Metadata with the given name, attached to this (
model
name,scenario
name,version
), is retrieved.- Parameters:
name (
str
, optional) – Metadata name/identifier.
- has_item(name: str, item_type=<ItemType.MODEL: 30>) bool [source]
Check whether the Scenario has an item name of item_type.
In general, user code should call one of
has_equ()
,has_par()
,has_set()
, orhas_var()
instead of calling this method directly.See also
- idx_names(name: str) list[str] [source]
Return the list of index names for an item (set, par, var, equ).
- Parameters:
name (
str
) – name of the item
- idx_sets(name: str) list[str] [source]
Return the list of index sets for an item (set, par, var, equ).
- Parameters:
name (
str
) – name of the item
- init_equ(name: str, idx_sets: Sequence[str] | None = None, idx_names: Sequence[str] | None = None)[source]
- init_item(item_type: ItemType, name: str, idx_sets: Sequence[str] | None = None, idx_names: Sequence[str] | None = None)[source]
Initialize a new item name of type item_type.
In general, user code should call one of
init_set()
,init_par()
,init_var()
, orinit_equ()
instead of calling this method directly.- Parameters:
item_type (
ItemType
) – The type of the item.name (
str
) – Name of the item.idx_sets (
collections.abc.Sequence
ofstr
orstr
, optional) – Name(s) of index sets for a 1+-dimensional item. If none are given, the item is scalar (zero dimensional).idx_names (
collections.abc.Sequence
ofstr
orstr
, optional) – Names of the dimensions indexed by idx_sets. If given, they must be the same length as idx_sets.
- Raises:
if idx_names are given but do not match the length of idx_sets. - if an item with the same name, of any item_type, already exists.
RuntimeError – if the Scenario is not checked out (see
check_out()
).
- init_par(name: str, idx_sets: Sequence[str] | None = None, idx_names: Sequence[str] | None = None)[source]
- init_scalar(name: str, val: Real, unit: str, comment=None) None [source]
Initialize a new scalar and set its value.
- init_set(name: str, idx_sets: Sequence[str] | None = None, idx_names: Sequence[str] | None = None)[source]
- init_var(name: str, idx_sets: Sequence[str] | None = None, idx_names: Sequence[str] | None = None)[source]
- items(type: ~ixmp.backend.ItemType = <ItemType.PAR: 4>, filters: dict[str, ~collections.abc.Sequence[str]] | None = None, *, indexed_by: str | None = None, par_data: bool | None = None) Iterable[str] [source]
Iterate over model data items.
- Parameters:
type (
ItemType
, optional) – Types of items to iterate, for instanceItemType.PAR
for parameters.filters (
dict
, optional) – Filters for values along dimensions; same as the filters argument topar()
. Only value forItemType.PAR
.indexed_by (
str
, optional) – If given, only iterate over items where one of the item dimensions is indexed_by the set of this name.par_data (
bool
, optional) – IfTrue
(the default) and type isItemType.PAR
, also iterate over data for each parameter.
- Yields:
str
– if type is notItemType.PAR
, or par_data isFalse
: names of items.tuple
– if type isItemType.PAR
and par_data isTrue
: each tuple is (item name, item data).
- list_items(item_type: ItemType, indexed_by: str | None = None) list[str] [source]
List all defined items of type item_type.
See also
- load_scenario_data() None [source]
Load all Scenario data into memory.
- Raises:
ValueError – If the Scenario was instantiated with
cache=False
.
- par(name, filters=None)[source]
Return parameter data.
Same as
ixmp.Scenario.par()
, except columns indexed by the MESSAGEix setyear
are returned withint
dtype.- Parameters:
name (
str
) – Name of the parameter.filters (
dict
, optional) – Filters for the dimensions of the parameter. Seeixmp.Scenario.par()
.
- Returns:
Filtered elements of the parameter.
- Return type:
- preload_timeseries() None [source]
Preload timeseries data to in-memory cache. Useful for bulk updates.
- read_excel(path: PathLike, add_units: bool = False, init_items: bool = False, commit_steps: bool = False) None [source]
Read a Microsoft Excel file into the Scenario.
- Parameters:
path (
os.PathLike
) – File to read. Must have suffix ‘.xlsx’.add_units (
bool
, optional) – Add missing units, if any, to the Platform instance.init_items (
bool
, optional) – Initialize sets and parameters that do not already exist in the Scenario.commit_steps (
bool
, optional) – Commit changes after every data addition.
See also
- read_file(path: PathLike, firstyear: int | None = None, lastyear: int | None = None) None [source]
Read time series data from a CSV or Microsoft Excel file.
- Parameters:
path (
os.PathLike
) – File to read. Must have suffix ‘.csv’ or ‘.xlsx’.firstyear (
int
, optional) – Only read data from years equal to or later than this year.lastyear (
int
, optional) – Only read data from years equal to or earlier than this year.
See also
- remove_geodata(df: DataFrame) None [source]
Remove geodata from the TimeSeries instance.
- Parameters:
df (
pandas.DataFrame
) –Data to remove. df must have the following columns:
region
variable
unit
subannual
year
- remove_par(name: str, key=None) None [source]
Remove parameter values or an entire parameter.
- Parameters:
name (
str
) – Name of the parameter.key (
pandas.DataFrame
orlist
orstr
, optional) – Elements to be removed. If apandas.DataFrame
, must contain the same columns (indices/dimensions) as the parameter. If alist
, a single key for a single data point; the individual elements must correspond to the indices/dimensions of the parameter.
- remove_set(name: str, key: str | Sequence[str] | dict | DataFrame | None = None) None [source]
Delete set elements or an entire set.
- Parameters:
name (
str
) – Name of the set to remove (if key isNone
) or from which to remove elements.key (
pandas.DataFrame
orlist
ofstr
, optional) – Elements to be removed from set name.
- remove_solution(first_model_year: int | None = None) None [source]
Remove the solution from the scenario.
This function removes the solution (variables and equations) and timeseries data marked as meta=False from the scenario (see
add_timeseries()
).- Parameters:
first_model_year (
int
, optional) – If given, timeseries data marked as meta=False is removed only for years from first_model_year onwards.- Raises:
ValueError – If Scenario has no solution or if first_model_year is not int.
- remove_timeseries(df: DataFrame) None [source]
Remove time series data.
- Parameters:
df (
pandas.DataFrame
) –Data to remove. df must have the following columns:
region or node
variable
unit
year
- rename(name: str, mapping: Mapping[str, str], keep: bool = False) None [source]
Rename elements in the set name and transform data indexed by old name(s).
All new set element names per mapping are added to the set name, if not already present.
Data in all sets and parameters indexed by the set name is also either duplicated (if
keep=True
) or replaced (ifkeep=False
) with mapped keys.
- Parameters:
name (
str
) – Name of the set to change, for instance"technology"
. Note that renaming the “year” set may require further adjustments for a feasible scenario.mapping (
dict
) – Mapping from old/current to new set element names.keep (
bool
, optional) – IfFalse
(the default), old/current set element names are removed entirely from the Scenario. IfTrue
, old/current set elements and all parameter data indexed by them is retained.
- Raises:
KeyError – if name is the name of a different kind of item (for instance, a parameter) or of no known item.
ValueError – if name is a set indexed by 1 or more others.
- set(name, filters=None)[source]
Return elements of a set.
Same as
ixmp.Scenario.set()
, except columns for multi-dimensional sets indexed by the MESSAGEix setyear
are returned withint
dtype.- Parameters:
name (
str
) – Name of the set.filters (
dict
, optional) – Mapping of dimension_name → elements, where dimension_name is one of the idx_names given when the set was initialized (seeinit_set()
), and elements is an iterable of labels to include in the return value.
- Returns:
pandas.Series
– If name is an index set.pandas.DataFrame
– If name is a set defined over one or more other, index sets.
- set_meta(name_or_dict: str | dict[str, Any], value=None) None [source]
Set Metadata for this object.
- solve(model='MESSAGE', solve_options={}, **kwargs)[source]
Solve MESSAGE or MESSAGE-MACRO for the Scenario.
By default,
ixmp.Scenario.solve()
is called with ‘MESSAGE’ as the model argument. model may also be overwritten, e.g.:>>> s.solve(model='MESSAGE-MACRO')
- Parameters:
model (
'MESSAGE'
or'MACRO'
or'MESSAGE-MACRO'
, optional) – Model to solve.solve_options (
dict
, optional) – Mapping of (option → value) to use for GAMS CPLEX solver options file. See theMESSAGE
class andDEFAULT_CPLEX_OPTIONS
.kwargs – Other options control the execution of the underlying GAMS code; see the
MESSAGE_MACRO
class andGAMSModel
.
- timeseries(region: str | Sequence[str] | None = None, variable: str | Sequence[str] | None = None, unit: str | Sequence[str] | None = None, year: int | Sequence[int] | None = None, iamc: bool = False, subannual: bool | str = 'auto') DataFrame [source]
Retrieve time series data.
- Parameters:
iamc (
bool
, optional) – Return data in wide/’IAMC’ format. IfFalse
, return data in long format; seeadd_timeseries()
.region (
str
orlist
ofstr
, optional) – Regions to include in returned data.variable (
str
orlist
ofstr
, optional) – Variables to include in returned data.unit (
str
orlist
ofstr
, optional) – Units to include in returned data.year (
int
orlist
ofint
, optional) – Years to include in returned data.subannual (
bool
or'auto'
, optional) – Whether to include column for sub-annual specification (ifbool
); if ‘auto’, include column if sub-annual data (other than ‘Year’) exists in returned data frame.
- Raises:
ValueError – If subannual is
False
but Scenario has (filtered) sub-annual data.- Returns:
Specified data.
- Return type:
- to_excel(path: ~os.PathLike, items: ~ixmp.backend.ItemType = <ItemType.SET|PAR: 6>, filters: dict[str, ~collections.abc.Sequence[str] | ~ixmp.core.scenario.Scenario] | None = None, max_row: int | None = None) None [source]
Write Scenario to a Microsoft Excel file.
- Parameters:
path (
os.PathLike
) – File to write. Must have suffix.xlsx
.items (
ItemType
, optional) – Types of items to write. EitherSET
|PAR
(i.e. only sets and parameters), orMODEL
(also variables and equations, i.e. model solution data).filters (
dict
, optional) – Filters for values along dimensions; same as the filters argument topar()
.max_row (
int
, optional) – Maximum number of rows in each sheet. If the number of elements in an item exceeds this number orEXCEL_MAX_ROWS
, then an item is written to multiple sheets named, e.g. ‘foo’, ‘foo(2)’, ‘foo(3)’, etc.
See also
- transact(message: str = '', condition: bool = True, discard_on_error: bool = False)[source]
Context manager to wrap code in a ‘transaction’.
- Parameters:
message (
str
) – Commit message to use, if any commit is performed.condition (
bool
) –If
True
(the default):Before entering the code block, the TimeSeries (or
Scenario
) is checked out.On exiting the code block normally (without an exception), changes are committed with message.
If
False
, nothing occurs on entry or exit.discard_on_error (
bool
) – IfTrue
(defaultFalse
), then the anti-locking behaviour ofdiscard_on_error()
also applies to any exception raised in the block.
Example
>>> # `ts` is currently checked in/locked >>> with ts.transact(message="replace 'foo' with 'bar' in set x"): >>> # `ts` is checked out and may be modified >>> ts.remove_set("x", "foo") >>> ts.add_set("x", "bar") >>> # Changes to `ts` have been committed
- property url: str[source]
URL fragment for the TimeSeries.
This has the format
{model name}/{scenario name}#{version}
, with the same values passed when creating the TimeSeries instance.Examples
To form a complete URL (e.g. to use with
from_url()
), use a configuredixmp.Platform
name:>>> platform_name = "my-ixmp-platform" >>> mp = Platform(platform_name) >>> ts = TimeSeries(mp, "foo", "bar", 34) >>> ts.url "foo/bar#34" >>> f"ixmp://{platform_name}/{ts.url}" "ixmp://platform_name/foo/bar#34"
Note
Use caution: because Platform configuration is system-specific, other systems must have the same configuration for platform_name in order for the URL to refer to the same TimeSeries/Scenario.
- var(name, filters=None)[source]
Return variable data.
Same as
ixmp.Scenario.var()
, except columns indexed by the MESSAGEix setyear
are returned withint
dtype.- Parameters:
name (
str
) – Name of the variable.filters (
dict
, optional) – Filters for the dimensions of the variable. Seeixmp.Scenario.var()
.
- Returns:
Filtered elements of the variable.
- Return type:
- vintage_and_active_years(ya_args: tuple[str, str] | tuple[str, str, int | str] | None = None, tl_only: bool = True, **kwargs) DataFrame [source]
Return matched pairs of vintage and active periods for use in data input.
Each returned pair of (vintage period \(y^V\), active period \(y\)) satisfies all of the following conditions:
\(y^V, y \in Y\): both vintage and active period are in the
year
set of the Scenario.\(y^V \leq y\): a technology cannot be active before it is constructed.
If ya_args (node \(n\), technology \(t\), and optionally \(y^V\)) are given:
\(y^V\) is in the subset of \(Y\) for which \(\text{technical_lifetime}_{n,t,y^V}\) is defined (or the single, specified value).
\(y - y^V + \text{duration_period}_{n,t,y^V} < \text{technical_lifetime}_{n,t,y^V}\): the active period is partly or fully within the technical lifetime defined for that technology, node, and vintage. This is the same condition as
years_active()
.
If ya_args are given and tl_only is
True
(the default): \(y\) is in the subset of \(Y\) for which \(\text{technical_lifetime}_{n,t,y}\) is defined. [1](Deprecated) If in_horizon is
True
: \(y \geq y_0\), thefirstmodelyear
.
- Parameters:
ya_args (
tuple
, optional) – Either length 2 (node, technology) or length 3 (node, technology, year_vtg). Supplied directly toyears_active()
. If the third element is omitted,years_active()
is called repeatedly, once for each vintage for which a technical lifetime value is set (condition (3)).tl_only (
bool
, optional) – Condition (4), above.in_horizon (
bool
, optional) –Condition (5), above.
Deprecated since version 3.6: In
message_ix
4.0 or later, in_horizon will be removed, and the default behaviour ofvintage_and_active_years()
will change to the equivalent of in_horizon =False
.
- Returns:
with columns “year_vtg” and “year_act”, in which each row is a valid pair.
- Return type:
Examples
pandas.DataFrame.query()
can be used to further manipulate the data in the returned data frame. To limit the vintage periods included:>>> base = s.vintage_and_active_years(("node", "tech")) >>> df = base.query("2020 <= year_vtg")
Limit the active periods included:
>>> df = base.query("2040 < year_act")
Limit year_act to the first model year or later (same as deprecated in_horizon argument):
>>> df = base.query(f"{s.firstmodelyear} <= year_act")
More complex expressions and a chained pandas call:
>>> df = s.vintage_and_active_years( ... ("node", "tech"), tl_only=False ... ).query("2025 <= year_act or year_vtg < 2010")
- property y0[source]
Alias for
firstmodelyear
.
Model classes
|
Model class for MESSAGE. |
|
Model class for MACRO. |
|
Model class for MESSAGE_MACRO. |
|
Extended |
Solver options used by |
|
|
Description of an |
|
Type of data items in |
- message_ix.models.DEFAULT_CPLEX_OPTIONS = {'advind': 0, 'epopt': 1e-06, 'lpmethod': 4, 'threads': 4}
Solver options used by
Scenario.solve()
.These configure the GAMS CPLEX solver (or another solver, if selected); see the solver documentation for possible values.
- class message_ix.models.GAMSModel(name=None, **model_options)[source]
Extended
ixmp.model.gams.GAMSModel
for MESSAGE & MACRO.The
MESSAGE
,MACRO
, andMESSAGE_MACRO
child classes encapsulate the GAMS code for the core MESSAGE (or MACRO) mathematical formulation.The class receives model_options via
Scenario.solve()
. Some of these are passed on to the parent classixmp.model.gams.GAMSModel
(see there for a list); others are handled as described below.The “model_dir” option may be set in the user’s ixmp configuration file using the key “message model dir”. If not set, it defaults to “message_ix/model” below the directory where
message_ix
is installed.The “solve_options” option may be set in the user’s ixmp configuration file using the key “message solve options”. If not set, it defaults to
DEFAULT_CPLEX_OPTIONS
.For example, with the following configuration file:
{ "platform": { "default": "my-platform", "my-platform": {"backend": "jdbc", "etc": "etc"}, }, "message model dir": "/path/to/custom/gams/source/files", "message solve options": {"lpmethod": 4}, }
The following are equivalent:
# Model options given explicitly scen.solve( model_dir="/path/to/custom/gams/source/files", solve_options=dict(lpmethod=4), ) # Model options are read from configuration file scen.solve()
GDX input and output files generated using this class will contain a 2-dimensional set named
ixmp_version
, wherein the first element of each member is a package name from therecord_version_packages
parameter, and the second is its version according toimportlib.metadata.version()
. If the package is not installed, the string “(not installed)” is stored.The following tables list all model options:
Option
Usage
Default value
model_dir
Path to GAMS source files.
See above.
model_file
Path to GAMS source file.
"{model_dir}/{model_name}_run.gms"
in_file
Path to write GDX input file.
"{model_dir}/data/MsgData_{case}.gdx"
out_file
Path to read GDX output file.
"{model_dir}/output/MsgOutput_{case}.gdx"
solve_args
Arguments passed directly to GAMS.
[ '--in="{in_file}"', '--out="{out_file}"', '--iter="{model_dir}/output/MsgIterationReport_{case}.gdx"' ]
solve_options
Options for the GAMS LP solver.
record_version_packages
Python package versions to record.
["message_ix", "ixmp"]
Option
Default value
case
"{scenario.model}_{scenario.scenario}"
gams_args
["LogOption=4"]
check_solution
comment
equ_list
var_list
- items: Mapping[str, Item][source]
Mapping from model item (equation, parameter, set, or variable) names to
Item
describing the item.
- run(scenario)[source]
Execute the model.
GAMSModel creates a file named
cplex.opt
in the model directory containing the “solve_options”, as described above.Warning
GAMSModel can solve Scenarios in two or more Python processes simultaneously; but using different CPLEX options in each process may produce unexpected results.
- class message_ix.models.MESSAGE(name=None, **model_options)[source]
Bases:
GAMSModel
Model class for MESSAGE.
- items: MutableMapping[str, Item][source]
All equations, parameters, sets, and variables in the MESSAGE formulation.
Keys are the names of items (sets, parameters, variables, and equations); values are
Item
instances. These include all items listed in the MESSAGE mathematical specification, i.e. Sets and mappings and Parameter definition.
- class message_ix.models.MACRO(*args, **kwargs)[source]
Bases:
GAMSModel
Model class for MACRO.
- items: MutableMapping[str, Item][source]
All equations, parameters, sets, and variables in the MACRO formulation.
- class message_ix.models.MESSAGE_MACRO(*args, **kwargs)[source]
-
Model class for MESSAGE_MACRO.
MESSAGE_MACRO solves the MESSAGE and MACRO models iteratively, connecting changes in technology activity and resource demands (from MESSAGE) to changes in final demands and prices (from MACRO). This iteration continues until the solution converges; i.e. the two models reach a stable point for the values of these parameters.
MESSAGE_MACRO accepts three additional model_options that control the behaviour of this iteration algorithm:
max_adjustment (
float
, default 0.2): the maximum absolute relative change in final demands between iterations. If MACRO returns demands that have changed by more than a factor outside the range (1 - max_adjustment, 1 + max_adjustment) since the previous iteration, then the change is confined to the limits of that range for the next run of MESSAGE.convergence_criterion (
float
, default 0.01): threshold for model convergence. This option applies to the same value as max_adjustment: the relative change in final demands between two iterations. If the absolute relative change is less than convergence_criterion, the linked model run is complete.max_iteration (
int
, default 50): the maximum number of iterations between the two models. If the solution does not converge after this many iterations, the linked model run fails and no valid result is produced.
See also
- items: MutableMapping[str, Item][source]
All equations, parameters, sets, and variables in the MESSAGE-MACRO formulation.
- message_ix.models.DIMS = {'c': ('commodity', 'commodity'), 'e': ('emission', 'emission'), 'g': ('grade', 'grade'), 'h': ('time', 'time'), 'hd': ('time', 'time_dest'), 'ho': ('time', 'time_origin'), 'l': ('level', 'level'), 'm': ('mode', 'mode'), 'ms': ('mode', 'storage_mode'), 'n': ('node', 'node'), 'nd': ('node', 'node_dest'), 'nl': ('node', 'node_loc'), 'no': ('node', 'node_origin'), 'node_parent': ('node', 'node_parent'), 'nr': ('node', 'node_rel'), 'ns': ('node', 'node_share'), 'q': ('rating', 'rating'), 'r': ('relation', 'relation'), 's': ('land_scenario', 'land_scenario'), 't': ('technology', 'technology'), 'ta': ('technology', 'technology_addon'), 'time_parent': ('time', 'time_parent'), 'tp': ('technology', 'technology_primary'), 'ts': ('technology', 'storage_tec'), 'u': ('land_type', 'land_type'), 'y': ('year', 'year'), 'ya': ('year', 'year_act'), 'yr': ('year', 'year_rel'), 'yv': ('year', 'year_vtg')}
Common dimension name abbreviations mapped to tuples with:
the respective coordinate/index set, and
the full dimension name.
- class message_ix.models.Item(name: str, type: ~ixmp.backend.ItemType, expr: dataclasses.InitVar[str] = '', coords: tuple[str, ...] = <factory>, dims: tuple[str, ...] = <factory>, description: str | None = None)[source]
Description of an
ixmp
item: equation, parameter, set, or variable.Instances of this class carry only structural information, not data.
- coords: tuple[str, ...][source]
Coordinates of the item; that is, the names of sets that index its dimensions. The same set name may be repeated if it indexes multiple dimensions.
- expr: dataclasses.InitVar[str] = ''[source]
String expression for
coords
anddims
. Split on spaces and parsed usingDIMS
so that, for instance, “nl yv” results in entries for for “node”, “year” incoords
, and “node_loc”, “year_vtg” indims
.
- property ix_type: str[source]
“equ”, “par”, “set”, or “var”.
Read-only.
- Type:
Lower-case string form of
type
- type: ItemType[source]
Type of the item, for instance
ItemType.PAR
.
Utility methods
- message_ix.util.copy_model(path: Path, overwrite: bool = False, set_default: bool = False, quiet: bool = False, *, source_dir: Path | None = None) None [source]
Copy the MESSAGE GAMS files to a new path.
- message_ix.util.expand_dims(scenario: Scenario, name, **data)[source]
Expand dimensions of parameter name on scenario, filling with data.
This function is for use when an existing parameter name has dimensions that are a subset of those that would be created by
make_df()
, i.e. those given byMESSAGE.items
.This can occur when the underlying structure of MESSAGE and the model core is enhanced by adding dimensions to existing parameters. Existing scenario data in users’ databases can not then be automatically updated.
expand_dims()
helps users to update this data manually. It:Retrieves the existing parameter data for name.
Passes this existing data, plus any data given as keyword arguments, to
make_df()
. The result must be a data frame with no empty values; in other words, data must include all the dimensions to be added to name.Re-initializes the parameter name on scenario, with the dimensions given by
MESSAGE.items
.Adds the expanded data.
The modifications (steps 3 and 4) are wrapped using
transact()
.
- message_ix.util.make_df(name, **data)[source]
Return a data frame for parameter or indexed set name filled with data.
make_df()
always returns a data frame with the columns required by either:add_par()
: the dimensions of the parameter name, plus ‘value’ and ‘unit’.add_set()
: the dimensions of the indexed set name.
Columns not listed in data are left empty.
The data keyword arguments can be passed in many ways; see the Keyword Arguments and “Function Examples” sections of the Python introductory tutorial, or the examples below.
Examples
>>> make_df( ... "demand", node=["foo", "bar"], commodity="baz", value=[1.2, 3.4] ... ) node commodity level year time value unit 0 foo baz None None None 1.2 None 1 bar baz None None None 3.4 None
Pass some values as direct keyword arguments, and others by unpacking a dictionary:
>>> common = dict( ... commodity="light", ... level="useful", ... time="year", ... unit="GWa", ... ) >>> make_df( ... "demand", ... node=["Westeros", "Middle-earth"], ... year=[680, 700], ... value=[50, 80], ... # Use values from `common` as additional keyword args: ... **common, ... ) node commodity level year time value unit 0 Westeros light useful 680 year 50 GWa 1 Middle-earth light useful 700 year 50 GWa
Code that uses the deprecated signature, such as:
>>> base = {"year": [2020, 2021, 2022]} >>> make_df(base, value=1., unit="y") year value unit 0 1 1.0 y 1 2 1.0 y 2 3 1.0 y
or:
>>> base = dict( ... node=["Westeros", "Middle-earth"], ... year=[680, 700], ... time="year", ... unit="-", ... ) >>> make_df(base, mode="standard") node year time unit mode 0 Westeros 680 year - standard 1 Middle-earth 700 year - standard
…can either be adjusted to use the new signature:
>>> make_df("duration_period", **base, value=1., unit="y")
or, emulated using the
pandas.DataFrame.assign()
method:>>> pd.DataFrame(base).assign(value=1., unit="y")
The former is recommended, because it will ensure the result has the correct columns for the parameter.
- Parameters:
name (
str
) – Name of a parameter listed inMESSAGE.items
orMACRO.items
.data (optional) – Contents for dimensions of the parameter, its ‘value’, or ‘unit’. Other keys are ignored.
- Return type:
- Raises:
ValueError – if name is not the name of a MESSAGE or MACRO parameter; if arrays in data have uneven lengths.