diff --git a/message_ix_models/util/scenarioinfo.py b/message_ix_models/util/scenarioinfo.py index 2f2309628..d1bcca26a 100644 --- a/message_ix_models/util/scenarioinfo.py +++ b/message_ix_models/util/scenarioinfo.py @@ -26,8 +26,8 @@ class ScenarioInfo: """Information about a :class:`.Scenario` object. Code that prepares data for a target Scenario can accept a ScenarioInfo instance. - This avoids the need to create or load an actual Scenario, which can be slow under - some conditions. + This avoids the need to create or load an actual Scenario or its data, which can be + a performance-limiting step. ScenarioInfo objects can also be used (for instance, by :func:`.apply_spec`) to describe the contents of a Scenario *before* it is created. @@ -293,6 +293,28 @@ def io_units( ) return c / t + def substitute_codes(self) -> None: + """Update the members of :attr:`set` using :func:`.get_codelist`. + + Members of the following set(s) that are :class:`str` are replaced with codes + loaded from the corresponding code list(s), including all annotations: + + - ``commodity`` + + .. todo:: Extend for other sets and cases where there are multiple code lists + (for instance ``year``, ``region``). + """ + from message_ix_models.model.structure import get_codelist + + for cl_id in ("commodity",): + cl = get_codelist(cl_id) + for i, value in enumerate(self.set[cl_id]): + if isinstance(value, str): + try: + self.set[cl_id][i] = cl[value] + except KeyError: + pass + def year_from_codes(self, codes: List[sdmx_model.Code]): """Update using a list of `codes`.