diff --git a/.github/workflows/transport.yaml b/.github/workflows/transport.yaml index 0e5f7eef5b..fc5728c723 100644 --- a/.github/workflows/transport.yaml +++ b/.github/workflows/transport.yaml @@ -6,6 +6,10 @@ env: target-ref: dev target-workflow: transport + # Ref to clone in the workflow. + # Default: use github.ref, e.g. 'main' for the schedule trigger. + ref: "main" + # Starting point of the workflow. # # Use this value to build from a certain scenario: @@ -22,40 +26,14 @@ env: # 'mix-models transport run'. Each label triggers 1 job in the target-repo/ # target-workflow. # - # - Delete lines to disable some runs. # - Ensure there is NO trailing comma on the last line. labels: >- [ - "SSP1", - "SSP1 exo price", - "SSP1 tax", "SSP2", - "SSP2 exo price", - "SSP2 tax", - "SSP3", - "SSP3 exo price", - "SSP3 tax", - "SSP4", - "SSP4 exo price", - "SSP4 tax", - "SSP5", - "SSP5 exo price", - "SSP5 tax", - "DIGSY-BEST-C", - "DIGSY-BEST-S", - "DIGSY-WORST-C", - "DIGSY-WORST-S", - "EDITS-CA", - "EDITS-HA", - "LED-SSP1", - "LED-SSP2" + "SSP2 exo price c59e", + "SSP2 tax" ] - # Currently disabled: - # [ - # - # ] - on: # Uncomment these lines for debugging, but leave them commented on 'main' # pull_request: @@ -79,7 +57,7 @@ jobs: - name: Assemble JSON payload run: | echo '{ - "ref": "${{ github.ref }}", + "ref": "${{ env.ref || github.ref }}", "base": "${{ env.base }}", "from-step": "${{ env.from-step }}", "labels": ${{ env.labels }} diff --git a/doc/transport/input.rst b/doc/transport/input.rst index 5ed0ec810f..ea47f5745a 100644 --- a/doc/transport/input.rst +++ b/doc/transport/input.rst @@ -113,7 +113,7 @@ The :program:`git` history of files, or the GitHub "blame" view can also be used Quick links to each of the data flows: :data:`~.data.act_non_ldv` :data:`~.data.activity_freight` -:data:`~.data.activity_ldv` +:class:`~.data.ActivityVehicle` :data:`~.data.age_ldv` :data:`~.data.cap_new_ldv` :data:`~.data.class_ldv` @@ -136,9 +136,10 @@ Quick links to each of the data flows: :data:`~.data.input_cap_new` :data:`~.data.input_ref_ldv` :data:`~.data.input_share` -:data:`~.data.lifetime_ldv` -:data:`~.data.load_factor_ldv` -:data:`~.data.load_factor_nonldv` +:class:`~.data.Lifetime` +:data:`~.data.load_factor_f` +:data:`~.data.load_factor_p` +:class:`~.data.LoadFactorLDV` :data:`~.data.mer_to_ppp` :data:`~.data.mode_share_freight` :data:`~.data.pdt_cap_proj` @@ -153,7 +154,7 @@ Quick links to each of the data flows: .. autodata:: message_ix_models.model.transport.data.act_non_ldv .. autodata:: message_ix_models.model.transport.data.activity_freight -.. autodata:: message_ix_models.model.transport.data.activity_ldv +.. autoclass:: message_ix_models.model.transport.data.ActivityVehicle node = R12_AFR [1]_ Obtained from literature, based on estimates from South Africa. The reported value for South Africa is lower (18000 km/year, `source `__) than the one for Kenya (22000 km/year, `source `__). @@ -232,8 +233,10 @@ Quick links to each of the data flows: .. autodata:: message_ix_models.model.transport.data.input_cap_new .. autodata:: message_ix_models.model.transport.data.input_ref_ldv .. autodata:: message_ix_models.model.transport.data.input_share -.. autodata:: message_ix_models.model.transport.data.lifetime_ldv -.. autodata:: message_ix_models.model.transport.data.load_factor_ldv +.. autoclass:: message_ix_models.model.transport.data.Lifetime +.. autodata:: message_ix_models.model.transport.data.load_factor_f +.. autodata:: message_ix_models.model.transport.data.load_factor_p +.. autoclass:: message_ix_models.model.transport.data.LoadFactorLDV The code that handles this file interpolates on the |y| dimension. @@ -243,8 +246,7 @@ Quick links to each of the data flows: .. todo:: Transcribe the method into this document. -.. autodata:: message_ix_models.model.transport.data.load_factor_nonldv -.. autodata:: message_ix_models.model.transport.data.mer_to_ppp + .. autodata:: message_ix_models.model.transport.data.mer_to_ppp .. autodata:: message_ix_models.model.transport.data.mode_share_freight .. _transport-pdt-cap-proj: diff --git a/doc/transport/output.rst b/doc/transport/output.rst index 3cadc30f50..444123d40f 100644 --- a/doc/transport/output.rst +++ b/doc/transport/output.rst @@ -20,13 +20,13 @@ Data flows Quick links to each of the data flows: :data:`~.data.activity_passenger` -:data:`~.data.activity_vehicle` +:data:`~.data.activity_vehicle_out` :data:`~.data.fe_transport` :data:`~.data.gdp_in` :data:`~.data.population_in` .. autodata:: message_ix_models.model.transport.data.activity_passenger -.. autodata:: message_ix_models.model.transport.data.activity_vehicle +.. autodata:: message_ix_models.model.transport.data.activity_vehicle_out .. autodata:: message_ix_models.model.transport.data.fe_transport .. autodata:: message_ix_models.model.transport.data.gdp_in .. autodata:: message_ix_models.model.transport.data.population_in diff --git a/doc/whatsnew.rst b/doc/whatsnew.rst index 179d3ab75b..08e57cd53b 100644 --- a/doc/whatsnew.rst +++ b/doc/whatsnew.rst @@ -4,18 +4,89 @@ What's new Next release ============ -- :mod:`message_ix_models` supports and is tested against `Pandas 3.0.0 `_, +- :mod:`message_ix_models` supports and is tested against + `Pandas 3.0.0 `_, released 2026-01-21 (:pull:`470`). -- New module :mod:`tools.bilateralize ` +- New module :mod:`.tools.bilateralize` to change scenarios to a bilateral representation of trade (:pull:`438`). - -- Add reduced basin filtering for water module with ``--reduced-basin`` and - demand/supply stress-based selection via ``--basin-selection stress`` - (:pull:`432`, :issue:`414`). - -- Fix water module parameter bugs and refactor cooling (:pull:`405`): - infrastructure M1/Mf mode fixes, regional average shares for cooling allocation, - water supply level hierarchy corrections, and test suite improvements. +- New function :func:`.workflow.from_codelist` (:pull:`471`) + to generate a :class:`.Workflow` from a list of SDMX codes + by inspection of their IDs and annotations. +- Improve :mod:`~message_ix_models.report` (:pull:`471`): + + - :func:`~.report.report` updates the :class:`.Context` + with additional keyword arguments. + - New reporting operator :func:`.broadcast_wildcard2`. + - New utility :func:`.report.util.store_write_ts`, + generalized from :py:`transport.report.add_iamc_store_write()`. + +- New class :class:`.testing.check.InRange` (:pull:`471`). +- :meth:`.ConfigHelper.update` canonicalizes arguments; + accepts an optional ConfigHelper or dict as first positional argument (:pull:`471`). +- :meth:`.Context.update` invokes :meth:`.ConfigHelper.update` on sub-instances (:pull:`471`). +- Improve :doc:`/transport/index` (:pull:`471`): + + - Update data flows: + + - :class:`.ActivityVehicle`: new :class:`.ExoDataSource` class + inclusive of all modes and technologies; + replaces :py:`ldv_activity` that was specific to LDVs. + - :data:`.activity_vehicle_out`: rename from :py:`activity_vehicle`. + - :class:`.Lifetime`: new :class:`.ExoDataSource` class, + replaces :py:`lifetime_Ldv` that was specific to LDVs. + - :data:`.load_factor_f`: new. + This data flow is kept separate from :data:`.load_factor_p` because the units + of activity/service differ (tonne- vs. passenger-kilometre). + - :class:`.LoadFactorLDV`: add units "passenger / vehicle". + - :data:`.load_factor_p`: rename from :py:`load_factor_non_ldv`. + - :data:`.freight_activity`: change units Gt km → Gt km / year. + + - Expand transport technology code list: + + - Distinguish names and reporting aliases for all vehicle technologies. + - Add ``ntnu-vmi-technology`` annotations for :mod:`.transport.material`. + + - New functions and methods: + + :meth:`.transport.config.Config.get_target_url` + replacing :py:`transport.workflow.scenario_url()`, + + :func:`.transport.material.get_groups`, and + + :func:`~.transport.structure.get_commodity_groups`. + + - Harmonize :mod:`genno` keys used for structural information, + coordinates, etc. during build and reporting in :mod:`.transport.key`. + - New CLI command :program:`mix-models transport export-price`. + - Bump Codelist=IIASA_ECE:CL_TRANSPORT_SCENARIO to version 1.4.0. + + - Add additional exogenous price trajectories. + - Bump :attr:`.CL_SCENARIO.base_url` to v6.5 of the ScenarioMIP scenarios. + + - Add and apply :data:`.transport.material.OUTPUT_SHARE`. + - Improve reporting output (:mod:`.transport.report`): + align IAMC ‘variable’ codes with common definitions. + - New module :mod:`.transport.vehicle` for operational parameters + (capacity factor, technical lifetime) and stock of vehicles, + both passenger and freight. + + - Transfer and generalize stock-related calculations from :mod:`.transport.ldv`. + - Remove module :py:`transport.stock`. + + - New function :func:`.transport.workflow.add_steps` adds + transport-related steps to any Workflow + given a Code with :class:`.ScenarioCodeAnnotations`. + +- Improve :doc:`/water/index`: + + - Add reduced basin filtering with :program:`--reduced-basin` + and demand/supply stress-based selection via :program:`--basin-selection stress` + (:pull:`432`, :issue:`414`). + - Fix parameter bugs and refactor cooling (:pull:`405`): + infrastructure M1/Mf mode fixes, + regional average shares for cooling allocation, + water supply level hierarchy corrections, + and test suite improvements. v2026.1.15 ========== @@ -75,7 +146,7 @@ Projects and model variants --------------------------- - Add :doc:`/project/circeular` code list :class:`~.circeular.structure.CL_TRANSPORT_SCENARIO` (:pull:`447`). -- Improve :mod:`.model.transport` (:pull:`447`). +- Improve :doc:`/transport/index` (:pull:`447`). - Add :meth:`Config.use_modules <.transport.config.Config.use_modules>`. - Bump Codelist=IIASA_ECE:CL_TRANSPORT_SCENARIO to version 1.3.0. @@ -119,7 +190,7 @@ v2025.10.31 to read input data from distinct files according to scenario label. - New :class:`LoadFactorLDV`, replacing :py:`load_factor_ldv` and allowing a distinct file according to scenario label. - - New submodule :mod:`~.transport.stock` and input data flow :data:`.stock_cap`. + - New submodule :py:`transport.stock` and input data flow :data:`.stock_cap`. - Add technology dimension to :data:`.elasticity_f`. - Document :class:`.ScenarioCodeAnnotations`. @@ -408,7 +479,7 @@ Update :doc:`/transport/index` (:pull:`259`, :pull:`289`, :pull:`300`, :pull:`32 :data:`.mode_share_freight`, :data:`.pdt_cap_ref`, and :data:`.speed`. -- Add LED-specific parametrization for :data:`.activity_ldv`, +- Add LED-specific parametrization for :class:`activity_ldv <.ActivityVehicle>`, :data:`.lifetime_ldv`, :py:`load_factor_ldv`, and :data:`.pdt_cap_proj`. @@ -416,7 +487,8 @@ Update :doc:`/transport/index` (:pull:`259`, :pull:`289`, :pull:`300`, :pull:`32 - Generate SDMX-ML structural metadata, including data flow definitions, and SDMX-{CSV,ML} data outputs for certain reported quantities. - New input data flow :data:`.input_share`. - - Add :py:`scenario` dimension to :data:`.activity_ldv`, :data:`.lifetime_ldv`, input data flow and files. + - Add :py:`scenario` dimension to :class:`activity_ldv <.ActivityVehicle>`, + :data:`.lifetime_ldv`, input data flow and files. - Expand use of fixed/shared keys from :mod:`.transport.key`. - Improve documentation: diff --git a/message_ix_models/cli.py b/message_ix_models/cli.py index 5e0e104e6c..335246752c 100644 --- a/message_ix_models/cli.py +++ b/message_ix_models/cli.py @@ -206,7 +206,9 @@ def _log_threads(k: int, n: int): try: __import__(name) except ImportError as e: - print(e) + print(f"{name} not available: {e}") + continue + cmd = getattr(sys.modules[name], "cli") # Avoid replacing message-ix-models CLI with message_data CLI diff --git a/message_ix_models/data/commodity.yaml b/message_ix_models/data/commodity.yaml index 965ee26d2d..cdf53a7a57 100644 --- a/message_ix_models/data/commodity.yaml +++ b/message_ix_models/data/commodity.yaml @@ -112,7 +112,8 @@ fueloil: iea-eweb-product: [BITUMEN, PARWAX, PETCOKE, RESFUEL] gas: - name: Natural Gas + name: Natural gas + report: Gas units: GWa ipcc-1996-name: "Natural Gas (Dry)" iea-eweb-product: [NATGAS] diff --git a/message_ix_models/data/sdmx/IIASA_ECE_CL_TRANSPORT_SCENARIO(1.4.0).xml b/message_ix_models/data/sdmx/IIASA_ECE_CL_TRANSPORT_SCENARIO(1.4.0).xml new file mode 100644 index 0000000000..ea946d7cbd --- /dev/null +++ b/message_ix_models/data/sdmx/IIASA_ECE_CL_TRANSPORT_SCENARIO(1.4.0).xml @@ -0,0 +1,9532 @@ + + + + none + false + 2026-04-07T19:56:16.015127 + + Generated by message_ix_models 2026.1.16.dev379+g9cf763f5f + + + + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + None + + + [] + + + SSP1 baseline + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + None + + + ['material'] + + + SSP1 baseline with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + TaxEmission(value=1000.0) + + + [] + + + SSP1 with tax + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + TaxEmission(value=1000.0) + + + ['material'] + + + SSP1 with tax with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP1_v5.3.1/INDC2030i_SSP1 - Low Emissions_a#1') + + + [] + + + SSP1 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP1_v5.3.1/INDC2030i_SSP1 - Low Emissions_a#1') + + + ['material'] + + + SSP1 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP1_v5.3.1/INDC2030i_SSP1 - Very Low Emissions#1') + + + [] + + + SSP1 with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP1_v5.3.1/INDC2030i_SSP1 - Very Low Emissions#1') + + + ['material'] + + + SSP1 with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP1_v5.3.1/SSP1 - Low Emissions#2') + + + [] + + + SSP1 with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP1_v5.3.1/SSP1 - Low Emissions#2') + + + ['material'] + + + SSP1 with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP1_v5.3.1/SSP1 - Very Low Emissions#2') + + + [] + + + SSP1 with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP1_v5.3.1/SSP1 - Very Low Emissions#2') + + + ['material'] + + + SSP1 with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP1_v5.3.1/INDC2030i_SSP1 - Low Emissions#1') + + + [] + + + SSP1 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP1_v5.3.1/INDC2030i_SSP1 - Low Emissions#1') + + + ['material'] + + + SSP1 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP1_v6.5/SSP1 - Very Low Emissions#2') + + + [] + + + SSP1 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP1_v6.5/SSP1 - Very Low Emissions#2') + + + ['material'] + + + SSP1 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP1_v6.5/SSP1 - Low Emissions#2') + + + [] + + + SSP1 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP1_v6.5/SSP1 - Low Emissions#2') + + + ['material'] + + + SSP1 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP1_v5.3.1/SSP1 - Low Emissions_a#2') + + + [] + + + SSP1 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP1_v5.3.1/SSP1 - Low Emissions_a#2') + + + ['material'] + + + SSP1 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP1_v6.5/SSP1 - High Emissions#1') + + + [] + + + SSP1 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP1_v6.5/SSP1 - High Emissions#1') + + + ['material'] + + + SSP1 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP1_v5.3.1/baseline_1000f#1') + + + [] + + + SSP1 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP1_v5.3.1/baseline_1000f#1') + + + ['material'] + + + SSP1 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + None + + + [] + + + SSP2 baseline + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + None + + + ['material'] + + + SSP2 baseline with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + TaxEmission(value=1000.0) + + + [] + + + SSP2 with tax + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + TaxEmission(value=1000.0) + + + ['material'] + + + SSP2 with tax with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_5#3') + + + [] + + + SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_5#3') + + + ['material'] + + + SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Low Overshoot#2') + + + [] + + + SSP2 with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Low Overshoot#2') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Low Overshootf#3') + + + [] + + + SSP2 with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Low Overshootf#3') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/INDC2030i_SSP2 - Low Emissions_a#1') + + + [] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/INDC2030i_SSP2 - Low Emissions_a#1') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/npiref2035_low_dem_scen2#1') + + + [] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/npiref2035_low_dem_scen2#1') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_50#1') + + + [] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_50#1') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/INDC2030i_SSP2 - Low Emissions#1') + + + [] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/INDC2030i_SSP2 - Low Emissions#1') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Medium-Low Emissionsf#1') + + + [] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Medium-Low Emissionsf#1') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium Emissions#2') + + + [] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium Emissions#2') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPIREF_price_cap_5$_bkp#1') + + + [] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPIREF_price_cap_5$_bkp#1') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF#10') + + + [] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF#10') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Overshoot#2') + + + [] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Overshoot#2') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baseline_1000f#2') + + + [] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baseline_1000f#2') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_15#1') + + + [] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_15#1') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_20#1') + + + [] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_20#1') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.6/SSP2 - Medium Emissions#1') + + + [] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.6/SSP2 - Medium Emissions#1') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Low Emissions#2') + + + [] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Low Emissions#2') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Emissions#2') + + + [] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Emissions#2') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_110#1') + + + [] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_110#1') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - High Emissions#1') + + + [] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - High Emissions#1') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium-Low Emissions#2') + + + [] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium-Low Emissions#2') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_25#1') + + + [] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_25#1') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Low Overshootf_price_cap_5$_bkp#1') + + + [] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Low Overshootf_price_cap_5$_bkp#1') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Medium-Low Emissions#2') + + + [] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Medium-Low Emissions#2') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Emissions_a#2') + + + [] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Emissions_a#2') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_10#1') + + + [] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_10#1') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium Emissions_a#2') + + + [] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium Emissions_a#2') + + + ['material'] + + + SSP2 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).3' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP3_v6.5/baseline_DEFAULT_step_13' + + + None + + + [] + + + SSP3 baseline + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).3' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP3_v6.5/baseline_DEFAULT_step_13' + + + None + + + ['material'] + + + SSP3 baseline with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).3' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP3_v6.5/baseline_DEFAULT_step_13' + + + TaxEmission(value=1000.0) + + + [] + + + SSP3 with tax + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).3' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP3_v6.5/baseline_DEFAULT_step_13' + + + TaxEmission(value=1000.0) + + + ['material'] + + + SSP3 with tax with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).3' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP3_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP3_v6.5/SSP3 - High Emissions#2') + + + [] + + + SSP3 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).3' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP3_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP3_v6.5/SSP3 - High Emissions#2') + + + ['material'] + + + SSP3 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).3' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP3_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP3_v6.5/SSP3 - Medium-Low Emissions_a#1') + + + [] + + + SSP3 with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).3' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP3_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP3_v6.5/SSP3 - Medium-Low Emissions_a#1') + + + ['material'] + + + SSP3 with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).3' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP3_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP3_v5.3.1/baseline_1000f#1') + + + [] + + + SSP3 with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).3' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP3_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP3_v5.3.1/baseline_1000f#1') + + + ['material'] + + + SSP3 with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).4' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP4_v6.5/baseline_DEFAULT_step_13' + + + None + + + [] + + + SSP4 baseline + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).4' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP4_v6.5/baseline_DEFAULT_step_13' + + + None + + + ['material'] + + + SSP4 baseline with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).4' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP4_v6.5/baseline_DEFAULT_step_13' + + + TaxEmission(value=1000.0) + + + [] + + + SSP4 with tax + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).4' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP4_v6.5/baseline_DEFAULT_step_13' + + + TaxEmission(value=1000.0) + + + ['material'] + + + SSP4 with tax with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).4' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP4_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP4_v6.5/SSP4 - High Emissions#1') + + + [] + + + SSP4 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).4' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP4_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP4_v6.5/SSP4 - High Emissions#1') + + + ['material'] + + + SSP4 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).4' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP4_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP4_v5.3.1/baseline_1000f#1') + + + [] + + + SSP4 with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).4' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP4_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP4_v5.3.1/baseline_1000f#1') + + + ['material'] + + + SSP4 with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).4' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP4_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP4_v6.5/SSP4 - Low Overshoot#2') + + + [] + + + SSP4 with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).4' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP4_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP4_v6.5/SSP4 - Low Overshoot#2') + + + ['material'] + + + SSP4 with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).4' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP4_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP4_v5.3.1/SSP4 - Low Overshoot#2') + + + [] + + + SSP4 with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).4' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP4_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP4_v5.3.1/SSP4 - Low Overshoot#2') + + + ['material'] + + + SSP4 with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).4' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP4_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP4_v5.3.1/NPi2030#1') + + + [] + + + SSP4 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).4' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP4_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP4_v5.3.1/NPi2030#1') + + + ['material'] + + + SSP4 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).4' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP4_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP4_v5.3.1/NPiREF_SSP4 - Low Overshootf#1') + + + [] + + + SSP4 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).4' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP4_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP4_v5.3.1/NPiREF_SSP4 - Low Overshootf#1') + + + ['material'] + + + SSP4 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).4' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP4_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP4_v5.3.1/NPiREF#1') + + + [] + + + SSP4 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).4' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP4_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP4_v5.3.1/NPiREF#1') + + + ['material'] + + + SSP4 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).5' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP5_v6.5/baseline_DEFAULT_step_13' + + + None + + + [] + + + SSP5 baseline + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).5' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP5_v6.5/baseline_DEFAULT_step_13' + + + None + + + ['material'] + + + SSP5 baseline with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).5' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP5_v6.5/baseline_DEFAULT_step_13' + + + TaxEmission(value=1000.0) + + + [] + + + SSP5 with tax + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).5' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP5_v6.5/baseline_DEFAULT_step_13' + + + TaxEmission(value=1000.0) + + + ['material'] + + + SSP5 with tax with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).5' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP5_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP5_v6.5/SSP5 - High Emissions#2') + + + [] + + + SSP5 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).5' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP5_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP5_v6.5/SSP5 - High Emissions#2') + + + ['material'] + + + SSP5 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).5' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP5_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP5_v6.5/SSP5 - Medium-Low Emissions_a#1') + + + [] + + + SSP5 with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).5' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP5_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP5_v6.5/SSP5 - Medium-Low Emissions_a#1') + + + ['material'] + + + SSP5 with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).5' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP5_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP5_v5.3.1/baseline_1000f#2') + + + [] + + + SSP5 with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).5' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP5_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP5_v5.3.1/baseline_1000f#2') + + + ['material'] + + + SSP5 with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).5' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP5_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP5_v5.3.1/NPiREF#1') + + + [] + + + SSP5 with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).5' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP5_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP5_v5.3.1/NPiREF#1') + + + ['material'] + + + SSP5 with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).5' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP5_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP5_v5.3.1/baseline2060_low_dem_scen#2') + + + [] + + + SSP5 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).5' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP5_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP5_v5.3.1/baseline2060_low_dem_scen#2') + + + ['material'] + + + SSP5 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).5' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP5_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP5_v5.3.1/baseline2055_low_dem_scen#1') + + + [] + + + SSP5 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).5' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP5_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP5_v5.3.1/baseline2055_low_dem_scen#1') + + + ['material'] + + + SSP5 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).5' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP5_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP5_v5.3.1/NPiREF_SSP5 - Low Overshootf#1') + + + [] + + + SSP5 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).5' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP5_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP5_v5.3.1/NPiREF_SSP5 - Low Overshootf#1') + + + ['material'] + + + SSP5 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).5' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP5_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP5_v5.3.1/NPi2030#1') + + + [] + + + SSP5 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).5' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP5_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP5_v5.3.1/NPi2030#1') + + + ['material'] + + + SSP5 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).5' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP5_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP5_v6.5/SSP5 - Low Overshoot#2') + + + [] + + + SSP5 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).5' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP5_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP5_v6.5/SSP5 - Low Overshoot#2') + + + ['material'] + + + SSP5 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).5' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP5_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP5_v5.3.1/SSP5 - Low Overshoot#2') + + + [] + + + SSP5 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).5' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP5_v6.5/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP5_v5.3.1/SSP5 - Low Overshoot#2') + + + ['material'] + + + SSP5 with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + True + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + None + + + [] + + + Low Energy Demand/High-with-Low scenario with SSP1 demographics + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).1' + + + True + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP1_v6.5/baseline_DEFAULT_step_13' + + + None + + + ['material'] + + + Low Energy Demand/High-with-Low scenario with SSP1 demographics with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + True + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + None + + + [] + + + Low Energy Demand/High-with-Low scenario with SSP2 demographics + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + True + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + None + + + ['material'] + + + Low Energy Demand/High-with-Low scenario with SSP2 demographics with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2).BEST-C' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + None + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2).BEST-C' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + None + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_5#3') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_5#3') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Low Overshoot#2') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Low Overshoot#2') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Low Overshootf#3') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Low Overshootf#3') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/INDC2030i_SSP2 - Low Emissions_a#1') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/INDC2030i_SSP2 - Low Emissions_a#1') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/npiref2035_low_dem_scen2#1') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/npiref2035_low_dem_scen2#1') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_50#1') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_50#1') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/INDC2030i_SSP2 - Low Emissions#1') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/INDC2030i_SSP2 - Low Emissions#1') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Medium-Low Emissionsf#1') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Medium-Low Emissionsf#1') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium Emissions#2') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium Emissions#2') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPIREF_price_cap_5$_bkp#1') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPIREF_price_cap_5$_bkp#1') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF#10') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF#10') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Overshoot#2') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Overshoot#2') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baseline_1000f#2') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baseline_1000f#2') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_15#1') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_15#1') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_20#1') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_20#1') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.6/SSP2 - Medium Emissions#1') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.6/SSP2 - Medium Emissions#1') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Low Emissions#2') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Low Emissions#2') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Emissions#2') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Emissions#2') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_110#1') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_110#1') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - High Emissions#1') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - High Emissions#1') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium-Low Emissions#2') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium-Low Emissions#2') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_25#1') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_25#1') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Low Overshootf_price_cap_5$_bkp#1') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Low Overshootf_price_cap_5$_bkp#1') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Medium-Low Emissions#2') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Medium-Low Emissions#2') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Emissions_a#2') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Emissions_a#2') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_10#1') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_10#1') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium Emissions_a#2') + + + [] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium Emissions_a#2') + + + ['material'] + + + DIGSY 'BEST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2).BEST-S' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + None + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2).BEST-S' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + None + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_5#3') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_5#3') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Low Overshoot#2') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Low Overshoot#2') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Low Overshootf#3') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Low Overshootf#3') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/INDC2030i_SSP2 - Low Emissions_a#1') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/INDC2030i_SSP2 - Low Emissions_a#1') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/npiref2035_low_dem_scen2#1') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/npiref2035_low_dem_scen2#1') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_50#1') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_50#1') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/INDC2030i_SSP2 - Low Emissions#1') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/INDC2030i_SSP2 - Low Emissions#1') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Medium-Low Emissionsf#1') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Medium-Low Emissionsf#1') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium Emissions#2') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium Emissions#2') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPIREF_price_cap_5$_bkp#1') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPIREF_price_cap_5$_bkp#1') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF#10') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF#10') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Overshoot#2') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Overshoot#2') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baseline_1000f#2') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baseline_1000f#2') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_15#1') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_15#1') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_20#1') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_20#1') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.6/SSP2 - Medium Emissions#1') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.6/SSP2 - Medium Emissions#1') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Low Emissions#2') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Low Emissions#2') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Emissions#2') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Emissions#2') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_110#1') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_110#1') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - High Emissions#1') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - High Emissions#1') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium-Low Emissions#2') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium-Low Emissions#2') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_25#1') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_25#1') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Low Overshootf_price_cap_5$_bkp#1') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Low Overshootf_price_cap_5$_bkp#1') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Medium-Low Emissions#2') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Medium-Low Emissions#2') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Emissions_a#2') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Emissions_a#2') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_10#1') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_10#1') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium Emissions_a#2') + + + [] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium Emissions_a#2') + + + ['material'] + + + DIGSY 'BEST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2).WORST-C' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + None + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2).WORST-C' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + None + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_5#3') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_5#3') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Low Overshoot#2') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Low Overshoot#2') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Low Overshootf#3') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Low Overshootf#3') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/INDC2030i_SSP2 - Low Emissions_a#1') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/INDC2030i_SSP2 - Low Emissions_a#1') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/npiref2035_low_dem_scen2#1') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/npiref2035_low_dem_scen2#1') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_50#1') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_50#1') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/INDC2030i_SSP2 - Low Emissions#1') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/INDC2030i_SSP2 - Low Emissions#1') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Medium-Low Emissionsf#1') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Medium-Low Emissionsf#1') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium Emissions#2') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium Emissions#2') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPIREF_price_cap_5$_bkp#1') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPIREF_price_cap_5$_bkp#1') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF#10') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF#10') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Overshoot#2') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Overshoot#2') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baseline_1000f#2') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baseline_1000f#2') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_15#1') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_15#1') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_20#1') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_20#1') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.6/SSP2 - Medium Emissions#1') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.6/SSP2 - Medium Emissions#1') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Low Emissions#2') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Low Emissions#2') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Emissions#2') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Emissions#2') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_110#1') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_110#1') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - High Emissions#1') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - High Emissions#1') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium-Low Emissions#2') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium-Low Emissions#2') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_25#1') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_25#1') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Low Overshootf_price_cap_5$_bkp#1') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Low Overshootf_price_cap_5$_bkp#1') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Medium-Low Emissions#2') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Medium-Low Emissions#2') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Emissions_a#2') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Emissions_a#2') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_10#1') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_10#1') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium Emissions_a#2') + + + [] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium Emissions_a#2') + + + ['material'] + + + DIGSY 'WORST-C' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2).WORST-S' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + None + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2).WORST-S' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + None + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_5#3') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_5#3') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Low Overshoot#2') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Low Overshoot#2') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Low Overshootf#3') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Low Overshootf#3') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/INDC2030i_SSP2 - Low Emissions_a#1') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/INDC2030i_SSP2 - Low Emissions_a#1') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/npiref2035_low_dem_scen2#1') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/npiref2035_low_dem_scen2#1') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_50#1') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_50#1') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/INDC2030i_SSP2 - Low Emissions#1') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/INDC2030i_SSP2 - Low Emissions#1') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Medium-Low Emissionsf#1') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Medium-Low Emissionsf#1') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium Emissions#2') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium Emissions#2') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPIREF_price_cap_5$_bkp#1') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPIREF_price_cap_5$_bkp#1') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF#10') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF#10') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Overshoot#2') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Overshoot#2') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baseline_1000f#2') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baseline_1000f#2') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_15#1') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_15#1') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_20#1') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_20#1') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.6/SSP2 - Medium Emissions#1') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.6/SSP2 - Medium Emissions#1') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Low Emissions#2') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Low Emissions#2') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Emissions#2') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Emissions#2') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_110#1') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_110#1') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - High Emissions#1') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - High Emissions#1') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium-Low Emissions#2') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium-Low Emissions#2') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_25#1') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_25#1') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Low Overshootf_price_cap_5$_bkp#1') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/NPiREF_SSP2 - Low Overshootf_price_cap_5$_bkp#1') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Medium-Low Emissions#2') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Medium-Low Emissions#2') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Emissions_a#2') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Low Emissions_a#2') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_10#1') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/baselineS_10#1') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium Emissions_a#2') + + + [] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1)._Z' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + ExogenousEmissionPrice(source_url='ixmp://ixmp-dev/SSP_SSP2_v5.3.1/SSP2 - Medium Emissions_a#2') + + + ['material'] + + + DIGSY 'WORST-S' scenario with SSP2 with exogenous price with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1).CA' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + None + + + [] + + + EDITS scenario with ITF PASTA 'CA' activity + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1).CA' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + None + + + ['material'] + + + EDITS scenario with ITF PASTA 'CA' activity with materials + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1).HA' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + None + + + [] + + + EDITS scenario with ITF PASTA 'HA' activity + + + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=ICONICS:SSP(2024).2' + + + False + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:DIGSY_SCENARIO(0.2)._Z' + + + 'urn:sdmx:org.sdmx.infomodel.codelist.Code=IIASA_ECE:EDITS_MCE_SCENARIO(0.1).HA' + + + 'ixmp://ixmp-dev/SSP_SSP2_v6.6/baseline_DEFAULT_step_13' + + + None + + + ['material'] + + + EDITS scenario with ITF PASTA 'HA' activity with materials + + + + + diff --git a/message_ix_models/data/test/transport/MESSAGEix-GLOBIOM_2.2-BMT-R12_baseline_BM_20260216/demand.csv b/message_ix_models/data/test/transport/MESSAGEix-GLOBIOM_2.2-BMT-R12_baseline_BM_20260216/demand.csv new file mode 100644 index 0000000000..290d28de5b --- /dev/null +++ b/message_ix_models/data/test/transport/MESSAGEix-GLOBIOM_2.2-BMT-R12_baseline_BM_20260216/demand.csv @@ -0,0 +1,344 @@ +# Test data from ixmp://ixmp-dev/MESSAGEix-GLOBIOM 2.2-BMT-R12/baseline_BM_20260216 +# +# The units given below match what appears in the database, +# but are likely incorrect and should instead be "Mt". +# +# Units: t +# +node,commodity,level,year,time,value +R12_AFR,steel,demand,2020,year,14.49368 +R12_AFR,steel,demand,2025,year,14.49368 +R12_AFR,steel,demand,2030,year,14.168 +R12_AFR,steel,demand,2035,year,40.0476 +R12_AFR,steel,demand,2040,year,60.6188 +R12_AFR,steel,demand,2045,year,99.2404 +R12_AFR,steel,demand,2050,year,142.7288 +R12_AFR,steel,demand,2055,year,211.9128 +R12_AFR,steel,demand,2060,year,279.6892 +R12_AFR,steel,demand,2070,year,433.78 +R12_AFR,steel,demand,2080,year,571.642 +R12_AFR,steel,demand,2090,year,694.83 +R12_AFR,steel,demand,2100,year,809.3884 +R12_AFR,steel,demand,2110,year,809.3884 +R12_AFR,aluminum,demand,2020,year,2.74966163484653 +R12_AFR,aluminum,demand,2025,year,3.39049440411999 +R12_AFR,aluminum,demand,2030,year,3.41432097024767 +R12_AFR,aluminum,demand,2035,year,3.51178337969508 +R12_AFR,aluminum,demand,2040,year,3.38434379431125 +R12_AFR,aluminum,demand,2045,year,3.28217843644309 +R12_AFR,aluminum,demand,2050,year,3.60055188392637 +R12_AFR,aluminum,demand,2055,year,4.76576841711365 +R12_AFR,aluminum,demand,2060,year,7.16875878523775 +R12_AFR,aluminum,demand,2070,year,16.7613672539 +R12_AFR,aluminum,demand,2080,year,32.8023109318924 +R12_AFR,aluminum,demand,2090,year,53.3163478692439 +R12_AFR,aluminum,demand,2100,year,75.2367919962744 +R12_AFR,aluminum,demand,2110,year,98.6684059858436 +R12_EEU,steel,demand,2020,year,31.5441 +R12_EEU,steel,demand,2025,year,31.581 +R12_EEU,steel,demand,2030,year,31.581 +R12_EEU,steel,demand,2035,year,33.273 +R12_EEU,steel,demand,2040,year,32.904 +R12_EEU,steel,demand,2045,year,32.121 +R12_EEU,steel,demand,2050,year,31.734 +R12_EEU,steel,demand,2055,year,31.428 +R12_EEU,steel,demand,2060,year,31.131 +R12_EEU,steel,demand,2070,year,30.375 +R12_EEU,steel,demand,2080,year,29.214 +R12_EEU,steel,demand,2090,year,28.278 +R12_EEU,steel,demand,2100,year,27.342 +R12_EEU,steel,demand,2110,year,27.342 +R12_EEU,aluminum,demand,2020,year,5.29958883267973 +R12_EEU,aluminum,demand,2025,year,5.70400458763263 +R12_EEU,aluminum,demand,2030,year,5.92103375295703 +R12_EEU,aluminum,demand,2035,year,5.80242182184509 +R12_EEU,aluminum,demand,2040,year,5.42254445250959 +R12_EEU,aluminum,demand,2045,year,4.9400532365558 +R12_EEU,aluminum,demand,2050,year,4.51164775816695 +R12_EEU,aluminum,demand,2055,year,4.19130522730181 +R12_EEU,aluminum,demand,2060,year,3.9751416672614 +R12_EEU,aluminum,demand,2070,year,3.74160922815117 +R12_EEU,aluminum,demand,2080,year,3.62090055037246 +R12_EEU,aluminum,demand,2090,year,3.55120420501844 +R12_EEU,aluminum,demand,2100,year,3.50766119964727 +R12_EEU,aluminum,demand,2110,year,3.46617192256995 +R12_LAM,steel,demand,2020,year,53.3763 +R12_LAM,steel,demand,2025,year,64.8 +R12_LAM,steel,demand,2030,year,72.792 +R12_LAM,steel,demand,2035,year,110.844 +R12_LAM,steel,demand,2040,year,136.827 +R12_LAM,steel,demand,2045,year,157.284 +R12_LAM,steel,demand,2050,year,176.544 +R12_LAM,steel,demand,2055,year,189.603 +R12_LAM,steel,demand,2060,year,201.294 +R12_LAM,steel,demand,2070,year,216.945 +R12_LAM,steel,demand,2080,year,224.001 +R12_LAM,steel,demand,2090,year,225.567 +R12_LAM,steel,demand,2100,year,223.056 +R12_LAM,steel,demand,2110,year,223.056 +R12_LAM,aluminum,demand,2020,year,2.60008440679671 +R12_LAM,aluminum,demand,2025,year,3.92917152614197 +R12_LAM,aluminum,demand,2030,year,5.30490819218595 +R12_LAM,aluminum,demand,2035,year,7.03144119919714 +R12_LAM,aluminum,demand,2040,year,9.15178266439931 +R12_LAM,aluminum,demand,2045,year,11.516278985294 +R12_LAM,aluminum,demand,2050,year,13.9459142267265 +R12_LAM,aluminum,demand,2055,year,16.3197494580619 +R12_LAM,aluminum,demand,2060,year,18.5466518180047 +R12_LAM,aluminum,demand,2070,year,22.4244441980128 +R12_LAM,aluminum,demand,2080,year,25.2866993755641 +R12_LAM,aluminum,demand,2090,year,27.1575871272148 +R12_LAM,aluminum,demand,2100,year,28.2673397105002 +R12_LAM,aluminum,demand,2110,year,29.0787484203409 +R12_MEA,steel,demand,2020,year,62.10828 +R12_MEA,steel,demand,2025,year,69 +R12_MEA,steel,demand,2030,year,77.7676 +R12_MEA,steel,demand,2035,year,112.5252 +R12_MEA,steel,demand,2040,year,140.1528 +R12_MEA,steel,demand,2045,year,162.0672 +R12_MEA,steel,demand,2050,year,185.9964 +R12_MEA,steel,demand,2055,year,204.9668 +R12_MEA,steel,demand,2060,year,224.8664 +R12_MEA,steel,demand,2070,year,254.104 +R12_MEA,steel,demand,2080,year,273.5252 +R12_MEA,steel,demand,2090,year,287.2792 +R12_MEA,steel,demand,2100,year,296.608 +R12_MEA,steel,demand,2110,year,296.608 +R12_MEA,aluminum,demand,2020,year,2.20039765674893 +R12_MEA,aluminum,demand,2025,year,3.46029608341049 +R12_MEA,aluminum,demand,2030,year,5.32742950075796 +R12_MEA,aluminum,demand,2035,year,7.67515454314301 +R12_MEA,aluminum,demand,2040,year,10.5536676757249 +R12_MEA,aluminum,demand,2045,year,13.6862647160816 +R12_MEA,aluminum,demand,2050,year,16.8520671365669 +R12_MEA,aluminum,demand,2055,year,19.9461908209164 +R12_MEA,aluminum,demand,2060,year,22.9020664204434 +R12_MEA,aluminum,demand,2070,year,28.1280742717591 +R12_MEA,aluminum,demand,2080,year,32.2654669819869 +R12_MEA,aluminum,demand,2090,year,35.5083941226939 +R12_MEA,aluminum,demand,2100,year,37.9704898966942 +R12_MEA,aluminum,demand,2110,year,40.2048364191876 +R12_NAM,steel,demand,2020,year,78.71935 +R12_NAM,steel,demand,2025,year,93.5 +R12_NAM,steel,demand,2030,year,96.9935 +R12_NAM,steel,demand,2035,year,104.55 +R12_NAM,steel,demand,2040,year,111.503 +R12_NAM,steel,demand,2045,year,117.64 +R12_NAM,steel,demand,2050,year,123.2415 +R12_NAM,steel,demand,2055,year,127.976 +R12_NAM,steel,demand,2060,year,132.039 +R12_NAM,steel,demand,2070,year,138.0995 +R12_NAM,steel,demand,2080,year,141.814 +R12_NAM,steel,demand,2090,year,143.99 +R12_NAM,steel,demand,2100,year,145.1375 +R12_NAM,steel,demand,2110,year,145.1375 +R12_NAM,aluminum,demand,2020,year,13.9999285342406 +R12_NAM,aluminum,demand,2025,year,15.1611473921284 +R12_NAM,aluminum,demand,2030,year,16.0202992789882 +R12_NAM,aluminum,demand,2035,year,16.7378030570288 +R12_NAM,aluminum,demand,2040,year,17.3449987646736 +R12_NAM,aluminum,demand,2045,year,17.8830906060463 +R12_NAM,aluminum,demand,2050,year,18.3935596634726 +R12_NAM,aluminum,demand,2055,year,18.8842043489018 +R12_NAM,aluminum,demand,2060,year,19.3807008617894 +R12_NAM,aluminum,demand,2070,year,20.3667641918489 +R12_NAM,aluminum,demand,2080,year,21.2146240419358 +R12_NAM,aluminum,demand,2090,year,21.8083485334632 +R12_NAM,aluminum,demand,2100,year,22.1839536188971 +R12_NAM,aluminum,demand,2110,year,22.5350499390702 +R12_SAS,steel,demand,2020,year,94.28344 +R12_SAS,steel,demand,2025,year,142.6 +R12_SAS,steel,demand,2030,year,161.6256 +R12_SAS,steel,demand,2035,year,297.9604 +R12_SAS,steel,demand,2040,year,384.1736 +R12_SAS,steel,demand,2045,year,443.348 +R12_SAS,steel,demand,2050,year,515.1908 +R12_SAS,steel,demand,2055,year,553.4168 +R12_SAS,steel,demand,2060,year,606.9516 +R12_SAS,steel,demand,2070,year,670.0728 +R12_SAS,steel,demand,2080,year,703.5332 +R12_SAS,steel,demand,2090,year,720.4612 +R12_SAS,steel,demand,2100,year,727.2876 +R12_SAS,steel,demand,2110,year,727.2876 +R12_SAS,aluminum,demand,2020,year,4.79947232521726 +R12_SAS,aluminum,demand,2025,year,6.40069200339453 +R12_SAS,aluminum,demand,2030,year,9.27976550971231 +R12_SAS,aluminum,demand,2035,year,13.2007558091847 +R12_SAS,aluminum,demand,2040,year,17.9586864995716 +R12_SAS,aluminum,demand,2045,year,23.5685113474604 +R12_SAS,aluminum,demand,2050,year,29.9989251698545 +R12_SAS,aluminum,demand,2055,year,37.0932479549381 +R12_SAS,aluminum,demand,2060,year,44.539458618742 +R12_SAS,aluminum,demand,2070,year,59.0051971467932 +R12_SAS,aluminum,demand,2080,year,71.0098930875013 +R12_SAS,aluminum,demand,2090,year,79.7267876373874 +R12_SAS,aluminum,demand,2100,year,85.6516923330805 +R12_SAS,aluminum,demand,2110,year,90.6121694091066 +R12_WEU,steel,demand,2020,year,117.09345 +R12_WEU,steel,demand,2025,year,131.75 +R12_WEU,steel,demand,2030,year,135.0735 +R12_WEU,steel,demand,2035,year,144.9675 +R12_WEU,steel,demand,2040,year,152.0565 +R12_WEU,steel,demand,2045,year,158.8565 +R12_WEU,steel,demand,2050,year,163.9565 +R12_WEU,steel,demand,2055,year,168.096 +R12_WEU,steel,demand,2060,year,170.833 +R12_WEU,steel,demand,2070,year,174.1055 +R12_WEU,steel,demand,2080,year,173.6295 +R12_WEU,steel,demand,2090,year,172.5585 +R12_WEU,steel,demand,2100,year,169.7025 +R12_WEU,steel,demand,2110,year,169.7025 +R12_WEU,aluminum,demand,2020,year,6.00085662437608 +R12_WEU,aluminum,demand,2025,year,7.67868025548736 +R12_WEU,aluminum,demand,2030,year,8.90760758538225 +R12_WEU,aluminum,demand,2035,year,10.5585893455211 +R12_WEU,aluminum,demand,2040,year,12.6359050084323 +R12_WEU,aluminum,demand,2045,year,14.8249264771741 +R12_WEU,aluminum,demand,2050,year,16.8045739967204 +R12_WEU,aluminum,demand,2055,year,18.4306387862293 +R12_WEU,aluminum,demand,2060,year,19.7074850014359 +R12_WEU,aluminum,demand,2070,year,21.4244111961004 +R12_WEU,aluminum,demand,2080,year,22.4178748483023 +R12_WEU,aluminum,demand,2090,year,22.9586736624652 +R12_WEU,aluminum,demand,2100,year,23.1642851702228 +R12_WEU,aluminum,demand,2110,year,23.3185561174193 +R12_FSU,steel,demand,2020,year,49.9392 +R12_FSU,steel,demand,2025,year,49.995 +R12_FSU,steel,demand,2030,year,51.489 +R12_FSU,steel,demand,2035,year,65.079 +R12_FSU,steel,demand,2040,year,69.777 +R12_FSU,steel,demand,2045,year,72.216 +R12_FSU,steel,demand,2050,year,76.446 +R12_FSU,steel,demand,2055,year,80.217 +R12_FSU,steel,demand,2060,year,84.312 +R12_FSU,steel,demand,2070,year,89.856 +R12_FSU,steel,demand,2080,year,92.781 +R12_FSU,steel,demand,2090,year,95.337 +R12_FSU,steel,demand,2100,year,96.516 +R12_FSU,steel,demand,2110,year,96.516 +R12_FSU,aluminum,demand,2020,year,4.84968756775019 +R12_FSU,aluminum,demand,2025,year,5.41748507334742 +R12_FSU,aluminum,demand,2030,year,5.86522690591112 +R12_FSU,aluminum,demand,2035,year,6.37779265857682 +R12_FSU,aluminum,demand,2040,year,6.69823559682082 +R12_FSU,aluminum,demand,2045,year,6.91707632176842 +R12_FSU,aluminum,demand,2050,year,7.15076502209288 +R12_FSU,aluminum,demand,2055,year,7.48476010533571 +R12_FSU,aluminum,demand,2060,year,7.93657375751533 +R12_FSU,aluminum,demand,2070,year,8.97194530219384 +R12_FSU,aluminum,demand,2080,year,9.95163943219347 +R12_FSU,aluminum,demand,2090,year,10.8332440149553 +R12_FSU,aluminum,demand,2100,year,11.5717104679913 +R12_FSU,aluminum,demand,2110,year,12.2112611326823 +R12_PAO,steel,demand,2020,year,49.1113 +R12_PAO,steel,demand,2025,year,49.113 +R12_PAO,steel,demand,2030,year,48.0335 +R12_PAO,steel,demand,2035,year,47.6595 +R12_PAO,steel,demand,2040,year,46.2995 +R12_PAO,steel,demand,2045,year,45.5175 +R12_PAO,steel,demand,2050,year,44.846 +R12_PAO,steel,demand,2055,year,44.353 +R12_PAO,steel,demand,2060,year,43.826 +R12_PAO,steel,demand,2070,year,42.9165 +R12_PAO,steel,demand,2080,year,41.4375 +R12_PAO,steel,demand,2090,year,39.78 +R12_PAO,steel,demand,2100,year,38.1055 +R12_PAO,steel,demand,2110,year,38.1055 +R12_PAO,aluminum,demand,2020,year,3.60010076844248 +R12_PAO,aluminum,demand,2025,year,3.90374192259837 +R12_PAO,aluminum,demand,2030,year,4.13374454951351 +R12_PAO,aluminum,demand,2035,year,4.40267981187414 +R12_PAO,aluminum,demand,2040,year,4.68452129221248 +R12_PAO,aluminum,demand,2045,year,4.96385503268694 +R12_PAO,aluminum,demand,2050,year,5.21043415134317 +R12_PAO,aluminum,demand,2055,year,5.40472203989015 +R12_PAO,aluminum,demand,2060,year,5.54664769128425 +R12_PAO,aluminum,demand,2070,year,5.68805831363484 +R12_PAO,aluminum,demand,2080,year,5.69992072473573 +R12_PAO,aluminum,demand,2090,year,5.65775270187358 +R12_PAO,aluminum,demand,2100,year,5.55646328379756 +R12_PAO,aluminum,demand,2110,year,5.44798874180773 +R12_PAS,steel,demand,2020,year,110.1258 +R12_PAS,steel,demand,2025,year,110.1258 +R12_PAS,steel,demand,2030,year,118.224 +R12_PAS,steel,demand,2035,year,149.085 +R12_PAS,steel,demand,2040,year,166.203 +R12_PAS,steel,demand,2045,year,178.641 +R12_PAS,steel,demand,2050,year,190.287 +R12_PAS,steel,demand,2055,year,195.606 +R12_PAS,steel,demand,2060,year,202.437 +R12_PAS,steel,demand,2070,year,211.248 +R12_PAS,steel,demand,2080,year,213.858 +R12_PAS,steel,demand,2090,year,212.49 +R12_PAS,steel,demand,2100,year,207.702 +R12_PAS,steel,demand,2110,year,207.702 +R12_PAS,aluminum,demand,2020,year,4.800174208708 +R12_PAS,aluminum,demand,2025,year,6.76016645889741 +R12_PAS,aluminum,demand,2030,year,9.41828590532265 +R12_PAS,aluminum,demand,2035,year,11.7570568044041 +R12_PAS,aluminum,demand,2040,year,13.9511093553672 +R12_PAS,aluminum,demand,2045,year,15.9757156904768 +R12_PAS,aluminum,demand,2050,year,17.7855789256735 +R12_PAS,aluminum,demand,2055,year,19.4037332884306 +R12_PAS,aluminum,demand,2060,year,20.829801292015 +R12_PAS,aluminum,demand,2070,year,23.1285696767395 +R12_PAS,aluminum,demand,2080,year,24.7075352319659 +R12_PAS,aluminum,demand,2090,year,25.6561054573989 +R12_PAS,aluminum,demand,2100,year,26.0903604952366 +R12_PAS,aluminum,demand,2110,year,26.3904473346956 +R12_CHN,steel,demand,2020,year,898.3566 +R12_CHN,steel,demand,2025,year,787.5 +R12_CHN,steel,demand,2030,year,723.888 +R12_CHN,steel,demand,2035,year,666.909 +R12_CHN,steel,demand,2040,year,590.337 +R12_CHN,steel,demand,2045,year,523.53 +R12_CHN,steel,demand,2050,year,474.93 +R12_CHN,steel,demand,2055,year,434.826 +R12_CHN,steel,demand,2060,year,407.331 +R12_CHN,steel,demand,2070,year,366.957 +R12_CHN,steel,demand,2080,year,332.982 +R12_CHN,steel,demand,2090,year,304.245 +R12_CHN,steel,demand,2100,year,277.083 +R12_CHN,steel,demand,2110,year,277.083 +R12_CHN,aluminum,demand,2020,year,27.2984446468399 +R12_CHN,aluminum,demand,2025,year,34.6184960626711 +R12_CHN,aluminum,demand,2030,year,40.0382152412497 +R12_CHN,aluminum,demand,2035,year,43.4302526653914 +R12_CHN,aluminum,demand,2040,year,44.5705539541717 +R12_CHN,aluminum,demand,2045,year,44.891745615895 +R12_CHN,aluminum,demand,2050,year,44.8741194995006 +R12_CHN,aluminum,demand,2055,year,44.6289520209487 +R12_CHN,aluminum,demand,2060,year,44.3924579841476 +R12_CHN,aluminum,demand,2070,year,43.5395962580639 +R12_CHN,aluminum,demand,2080,year,41.8116672158444 +R12_CHN,aluminum,demand,2090,year,39.5520778773728 +R12_CHN,aluminum,demand,2100,year,37.1672856258216 +R12_CHN,aluminum,demand,2110,year,34.7884782867452 +R12_RCPA,steel,demand,2020,year,22.2318 +R12_RCPA,steel,demand,2025,year,22.2272 +R12_RCPA,steel,demand,2030,year,22.08 +R12_RCPA,steel,demand,2035,year,30.5348 +R12_RCPA,steel,demand,2040,year,33.0556 +R12_RCPA,steel,demand,2045,year,34.5184 +R12_RCPA,steel,demand,2050,year,36.754 +R12_RCPA,steel,demand,2055,year,38.042 +R12_RCPA,steel,demand,2060,year,40.1488 +R12_RCPA,steel,demand,2070,year,42.7248 +R12_RCPA,steel,demand,2080,year,43.976 +R12_RCPA,steel,demand,2090,year,44.5188 +R12_RCPA,steel,demand,2100,year,44.1232 +R12_RCPA,steel,demand,2110,year,44.1232 +R12_RCPA,aluminum,demand,2020,year,1.99976722146765 +R12_RCPA,aluminum,demand,2025,year,2.20976490805966 +R12_RCPA,aluminum,demand,2030,year,2.66413925860674 +R12_RCPA,aluminum,demand,2035,year,3.09977715100009 +R12_RCPA,aluminum,demand,2040,year,3.39057152208613 +R12_RCPA,aluminum,demand,2045,year,3.59199956735501 +R12_RCPA,aluminum,demand,2050,year,3.78597611505884 +R12_RCPA,aluminum,demand,2055,year,4.01968730528238 +R12_RCPA,aluminum,demand,2060,year,4.29109041933336 +R12_RCPA,aluminum,demand,2070,year,4.85905917694507 +R12_RCPA,aluminum,demand,2080,year,5.30255915385771 +R12_RCPA,aluminum,demand,2090,year,5.60469202852908 +R12_RCPA,aluminum,demand,2100,year,5.80190869285345 +R12_RCPA,aluminum,demand,2110,year,5.9488910021113 diff --git a/message_ix_models/data/transport/R11/activity-vehicle.csv b/message_ix_models/data/transport/R11/activity-vehicle.csv new file mode 100644 index 0000000000..7c40e9c4b7 --- /dev/null +++ b/message_ix_models/data/transport/R11/activity-vehicle.csv @@ -0,0 +1,73 @@ +# Activity (driving distance) per light-duty vehicle +# +# Source: Extracted from ldv-cost-efficiency.xlsx by D.L. McCollum; +# see also comments in that file, most of which are copied here: +# +# - “Note: Modest and Frequent mileages for all non-NAM regions are +# scaled relative to the NAM values from MA3T. This is because we +# only have driving data for the average driver (supplied by Page +# Kyle of the GCAM team in March 2014).” +# +# Unit: kilometre / year +# +scenario, technology, node, year, value +# driver_type="M" (moderate) +# *, LDV, R11_NAM, 2020, 13930 +# *, LDV, R11_NAM, 2110, 13930 +# driver_type="A" (average) +*, LDV, R11_NAM, 2020, 25860 +*, LDV, R11_NAM, 2110, 25860 +# driver_type="F" (frequent) +# *, LDV, R11_NAM, 2020, 45550 +# *, LDV, R11_NAM, 2110, 45550 +# DLM: “See the "vkt_veh_yr_GCAM.xlsx" spreadsheet that Page Kyle sent +# me in late-March 2014. The value in this cell is an average of GCAM's +# Brazil and Latin America regions.” +*, LDV, R11_LAM, 2020, 14600 +*, LDV, R11_LAM, 2110, 14600 +# “…GCAM's Western Europe region.” +*, LDV, R11_WEU, 2020, 11646 +*, LDV, R11_WEU, 2110, 11646 +# “…GCAM's Eastern Europe region.” +*, LDV, R11_EEU, 2020, 8962 +*, LDV, R11_EEU, 2110, 8962 +# “…GCAM's Former Soviet Union region.” +*, LDV, R11_FSU, 2020, 11482 +*, LDV, R11_FSU, 2110, 11482 +# “…GCAM's Middle East region.” +*, LDV, R11_MEA, 2020, 14000 +*, LDV, R11_MEA, 2110, 14000 +# “…GCAM's Africa region.” +*, LDV, R11_AFR, 2020, 10391 +*, LDV, R11_AFR, 2110, 10391 +# “…GCAM's China region. Actually, GCAM assumes an average value of +# ~20500 km/yr for China, which seems too high in my opinion, so I +# revised this value downwards. I made an assumption that the value +# should be 20% lower, an estimate I arrived at based on the +# consideration that GCAM assumes that average annual driving distances +# in the US are 20% lower than what MA3T shows for the average driver +# (19200 in GCAM vs. 25860 in MA3T). +*, LDV, R11_CPA, 2020, 16000 +*, LDV, R11_CPA, 2110, 16000 +# “…GCAM's Japan and Australia-NZ regions.” +*, LDV, R11_PAO, 2020, 10000 +*, LDV, R11_PAO, 2110, 10000 +# “…GCAM's Korea and Southeast Asia regions.” +*, LDV, R11_PAS, 2020, 12000 +*, LDV, R11_PAS, 2110, 12000 +# “…GCAM's India region.” +*, LDV, R11_SAS, 2020, 10400 +*, LDV, R11_SAS, 2110, 10400 + +*, AIR, *, 2020, 10000 +*, AIR, *, 2110, 10000 +*, 2W, *, 2020, 10000 +*, 2W, *, 2110, 10000 +*, BUS, *, 2020, 10000 +*, BUS, *, 2110, 10000 +*, P RAIL, *, 2020, 10000 +*, P RAIL, *, 2110, 10000 +*, F RAIL, *, 2020, 10000 +*, F RAIL, *, 2110, 10000 +*, F ROAD, *, 2020, 10000 +*, F ROAD, *, 2110, 10000 diff --git a/message_ix_models/data/transport/R11/freight-activity.csv b/message_ix_models/data/transport/R11/freight-activity.csv index b883b80b41..7af6dbef53 100644 --- a/message_ix_models/data/transport/R11/freight-activity.csv +++ b/message_ix_models/data/transport/R11/freight-activity.csv @@ -2,7 +2,7 @@ # # Source: placeholder; extracted from ADVANCE database # -# Units: Gt km +# Units: Gt km / a # node, value R11_AFR, 1210.1 diff --git a/message_ix_models/data/transport/R11/ldv-activity.csv b/message_ix_models/data/transport/R11/ldv-activity.csv deleted file mode 100644 index 49c7055b7e..0000000000 --- a/message_ix_models/data/transport/R11/ldv-activity.csv +++ /dev/null @@ -1,60 +0,0 @@ -# Activity (driving distance) per light-duty vehicle -# -# Source: Extracted from ldv-cost-efficiency.xlsx by D.L. McCollum; -# see also comments in that file, most of which are copied here: -# -# - “Note: Modest and Frequent mileages for all non-NAM regions are -# scaled relative to the NAM values from MA3T. This is because we -# only have driving data for the average driver (supplied by Page -# Kyle of the GCAM team in March 2014).” -# -# Unit: kilometre / year -# -scenario, node, year, value -# driver_type="M" (moderate) -# *, R11_NAM, 2020, 13930 -# *, R11_NAM, 2110, 13930 -# driver_type="A" (average) -*, R11_NAM, 2020, 25860 -*, R11_NAM, 2110, 25860 -# driver_type="F" (frequent) -# *, R11_NAM, 2020, 45550 -# *, R11_NAM, 2110, 45550 -# DLM: “See the "vkt_veh_yr_GCAM.xlsx" spreadsheet that Page Kyle sent -# me in late-March 2014. The value in this cell is an average of GCAM's -# Brazil and Latin America regions.” -*, R11_LAM, 2020, 14600 -*, R11_LAM, 2110, 14600 -# “…GCAM's Western Europe region.” -*, R11_WEU, 2020, 11646 -*, R11_WEU, 2110, 11646 -# “…GCAM's Eastern Europe region.” -*, R11_EEU, 2020, 8962 -*, R11_EEU, 2110, 8962 -# “…GCAM's Former Soviet Union region.” -*, R11_FSU, 2020, 11482 -*, R11_FSU, 2110, 11482 -# “…GCAM's Middle East region.” -*, R11_MEA, 2020, 14000 -*, R11_MEA, 2110, 14000 -# “…GCAM's Africa region.” -*, R11_AFR, 2020, 10391 -*, R11_AFR, 2110, 10391 -# “…GCAM's China region. Actually, GCAM assumes an average value of -# ~20500 km/yr for China, which seems too high in my opinion, so I -# revised this value downwards. I made an assumption that the value -# should be 20% lower, an estimate I arrived at based on the -# consideration that GCAM assumes that average annual driving distances -# in the US are 20% lower than what MA3T shows for the average driver -# (19200 in GCAM vs. 25860 in MA3T). -*, R11_CPA, 2020, 16000 -*, R11_CPA, 2110, 16000 -# “…GCAM's Japan and Australia-NZ regions.” -*, R11_PAO, 2020, 10000 -*, R11_PAO, 2110, 10000 -# “…GCAM's Korea and Southeast Asia regions.” -*, R11_PAS, 2020, 12000 -*, R11_PAS, 2110, 12000 -# “…GCAM's India region.” -*, R11_SAS, 2020, 10400 -*, R11_SAS, 2110, 10400 diff --git a/message_ix_models/data/transport/R11/load-factor-ldv/SSP_2024_2.csv b/message_ix_models/data/transport/R11/load-factor-ldv/SSP_2024_2.csv index 713cce77a5..9e37d193bd 100644 --- a/message_ix_models/data/transport/R11/load-factor-ldv/SSP_2024_2.csv +++ b/message_ix_models/data/transport/R11/load-factor-ldv/SSP_2024_2.csv @@ -4,6 +4,8 @@ # Original source unknown. The values appear to assume similarity # between certain regions. # +# Units: passenger / vehicle +# scenario, node, year, value SSP(2024).2, R11_AFR, 2020, 1.807 SSP(2024).2, R11_CPA, 2020, 1.892 diff --git a/message_ix_models/data/transport/R12/activity-vehicle.csv b/message_ix_models/data/transport/R12/activity-vehicle.csv new file mode 100644 index 0000000000..7aec03c4bc --- /dev/null +++ b/message_ix_models/data/transport/R12/activity-vehicle.csv @@ -0,0 +1,152 @@ +# Activity (driving distance) per light-duty vehicle +# +# Sources: +# +# - Values commented "TH 2024-04-11": calculation by T. Hara, shared at +# https://iiasa-ece.slack.com/archives/CCFHDNA6P/p1712831476181449 +# - R12_AFR, R12_FSU, R12_NAM, R12_PAO, R12_PAS, R12_SAS: see the documentation +# at https://docs.messageix.org/projects/models/en/latest/transport/input.html +# - All others: +# +# - Duplicate of R11/ldv-activity.csv; see comments there. +# - R11_CPA value repeated for R12_RCPA and R12_CHN. +# - scenario=LED: SharePoint ECE.prog > Documents > Transport > LED Scenario > +# input files > ldv-act per veh-LDV.xlsx as of 2025-03-18. +# +# Unit: kilometre / year +# +scenario, technology, node, year, value +# *, LDV, R12_AFR, 2020, 11000 # TH low +# *, LDV, R12_AFR, 2110, 11000 # TH low +*, LDV, R12_AFR, 2020, 15500 +*, LDV, R12_AFR, 2110, 15500 +# *, LDV, R12_AFR, 2020, 19000 # TH high +# *, LDV, R12_AFR, 2110, 19000 # TH high + +# *, LDV, R12_CHN, 2020, 9500 # TH low +# *, LDV, R12_CHN, 2110, 9500 # TH low +*, LDV, R12_CHN, 2020, 15000 # TH high +*, LDV, R12_CHN, 2110, 15000 # TH high +# *, LDV, R12_CHN, 2020, 16000 # Previous value +# *, LDV, R12_CHN, 2110, 16000 # Previous value + +# *, LDV, R12_EEU, 2020, 8962 # Previous value +# *, LDV, R12_EEU, 2110, 8962 # Previous value +*, LDV, R12_EEU, 2020, 9000 # TH low +*, LDV, R12_EEU, 2110, 9000 # TH low +# *, LDV, R12_EEU, 2020, 10000 # TH high +# *, LDV, R12_EEU, 2110, 10000 # TH high +# *, LDV, R12_EEU, 2020, 12500 # Experimental #392 +# *, LDV, R12_EEU, 2110, 15000 # Experimental #392 + +# *, LDV, R12_FSU, 2020, 11000 # TH low +# *, LDV, R12_FSU, 2110, 11000 # TH low +*, LDV, R12_FSU, 2020, 13000 # TH high = previous value +*, LDV, R12_FSU, 2110, 13000 # TH high = previous value + +# *, LDV, R12_LAM, 2020, 13000 # TH low +# *, LDV, R12_LAM, 2110, 13000 # TH low +*, LDV, R12_LAM, 2020, 13500 +*, LDV, R12_LAM, 2110, 13500 +# *, LDV, R12_LAM, 2020, 15000 # TH high +# *, LDV, R12_LAM, 2110, 15000 # TH high + +# *, LDV, R12_MEA, 2020, 13000 # TH low +# *, LDV, R12_MEA, 2110, 13000 # TH low +*, LDV, R12_MEA, 2020, 14500 +*, LDV, R12_MEA, 2110, 14500 +# *, LDV, R12_MEA, 2020, 16000 # TH high +# *, LDV, R12_MEA, 2110, 16000 # TH high + +# *, LDV, R12_NAM, 2020, 16000 # TH low +# *, LDV, R12_NAM, 2110, 16000 # TH low +*, LDV, R12_NAM, 2020, 18400 +*, LDV, R12_NAM, 2110, 18400 +# *, LDV, R12_NAM, 2020, 19000 # TH high +# *, LDV, R12_NAM, 2110, 19000 # TH high + +*, LDV, R12_PAO, 2020, 9000 # TH low = previous value +*, LDV, R12_PAO, 2110, 9000 # TH low = previous value +# *, LDV, R12_PAO, 2020, 10000 # TH high +# *, LDV, R12_PAO, 2110, 10000 # TH high +# *, LDV, R12_PAO, 2020, 10000 # Experimental #392 +# *, LDV, R12_PAO, 2110, 13000 # Experimental #392 + +# *, LDV, R12_PAS, 2020, 11000 # TH low +# *, LDV, R12_PAS, 2110, 11000 # TH low +*, LDV, R12_PAS, 2020, 13000 # TH high = previous value +*, LDV, R12_PAS, 2110, 13000 # TH high = previous value + +# *, LDV, R12_RCPA, 2020, 11000 # TH low +# *, LDV, R12_RCPA, 2110, 11000 # TH low +*, LDV, R12_RCPA, 2020, 12000 # TH high +*, LDV, R12_RCPA, 2110, 12000 # TH high +# *, LDV, R12_RCPA, 2020, 15000 # Experimental #392 +# *, LDV, R12_RCPA, 2110, 15000 # Experimental #392 +# *, LDV, R12_RCPA, 2020, 16000 # Previous value +# *, LDV, R12_RCPA, 2110, 16000 # Previous value + +*, LDV, R12_SAS, 2020, 12000 # TH low = previous value +*, LDV, R12_SAS, 2110, 12000 # TH low = previous value +# *, LDV, R12_SAS, 2020, 15000 # TH high +# *, LDV, R12_SAS, 2110, 15000 # TH high +# *, LDV, R12_SAS, 2020, 18000 # Experimental #392 +# *, LDV, R12_SAS, 2110, 18000 # Experimental #392 + +# *, LDV, R12_WEU, 2020, 11000 # TH low +# *, LDV, R12_WEU, 2110, 11000 # TH low +*, LDV, R12_WEU, 2020, 11700 +*, LDV, R12_WEU, 2110, 11700 +# *, LDV, R12_WEU, 2020, 12000 # TH high +# *, LDV, R12_WEU, 2110, 12000 # TH high +# *, LDV, R12_WEU, 2110, 15000 # Experimental #392 + +LED, LDV, R12_AFR, 2020, 15500 +LED, LDV, R12_AFR, 2050, 15113 +LED, LDV, R12_AFR, 2110, 15113 +LED, LDV, R12_CHN, 2020, 15000 +LED, LDV, R12_CHN, 2050, 15113 +LED, LDV, R12_CHN, 2110, 15113 +LED, LDV, R12_EEU, 2020, 9000 +LED, LDV, R12_EEU, 2050, 14087 +LED, LDV, R12_EEU, 2110, 14087 +LED, LDV, R12_FSU, 2020, 13000 +LED, LDV, R12_FSU, 2050, 14087 +LED, LDV, R12_FSU, 2110, 14087 +LED, LDV, R12_LAM, 2020, 13500 +LED, LDV, R12_LAM, 2050, 15113 +LED, LDV, R12_LAM, 2110, 15113 +LED, LDV, R12_MEA, 2020, 14500 +LED, LDV, R12_MEA, 2050, 15113 +LED, LDV, R12_MEA, 2110, 15113 +LED, LDV, R12_NAM, 2020, 18400 +LED, LDV, R12_NAM, 2050, 14087 +LED, LDV, R12_NAM, 2110, 14087 +LED, LDV, R12_PAO, 2020, 9000 +LED, LDV, R12_PAO, 2050, 14087 +LED, LDV, R12_PAO, 2110, 14087 +LED, LDV, R12_PAS, 2020, 13000 +LED, LDV, R12_PAS, 2050, 15113 +LED, LDV, R12_PAS, 2110, 15113 +LED, LDV, R12_RCPA, 2020, 12000 +LED, LDV, R12_RCPA, 2050, 15113 +LED, LDV, R12_RCPA, 2110, 15113 +LED, LDV, R12_SAS, 2020, 12000 +LED, LDV, R12_SAS, 2050, 15113 +LED, LDV, R12_SAS, 2110, 15113 +LED, LDV, R12_WEU, 2020, 11700 +LED, LDV, R12_WEU, 2050, 14087 +LED, LDV, R12_WEU, 2110, 14087 + +*, AIR, *, 2020, 10000 +*, AIR, *, 2110, 10000 +*, 2W, *, 2020, 10000 +*, 2W, *, 2110, 10000 +*, BUS, *, 2020, 10000 +*, BUS, *, 2110, 10000 +*, P RAIL, *, 2020, 10000 +*, P RAIL, *, 2110, 10000 +*, F RAIL, *, 2020, 10000 +*, F RAIL, *, 2110, 10000 +*, F ROAD, *, 2020, 10000 +*, F ROAD, *, 2110, 10000 diff --git a/message_ix_models/data/transport/R12/freight-activity.csv b/message_ix_models/data/transport/R12/freight-activity.csv index 55603b581b..f0e4011c0c 100644 --- a/message_ix_models/data/transport/R12/freight-activity.csv +++ b/message_ix_models/data/transport/R12/freight-activity.csv @@ -7,7 +7,7 @@ # to get estimate of R12_CHN freight demand.” # - All others: manually adapted from R11/freight-activity.csv. # -# Units: Gt km +# Units: Gt km / a # node, value R12_AFR, 730 diff --git a/message_ix_models/data/transport/R12/ldv-activity.csv b/message_ix_models/data/transport/R12/ldv-activity.csv deleted file mode 100644 index 8c3572e64b..0000000000 --- a/message_ix_models/data/transport/R12/ldv-activity.csv +++ /dev/null @@ -1,139 +0,0 @@ -# Activity (driving distance) per light-duty vehicle -# -# Sources: -# -# - Values commented "TH 2024-04-11": calculation by T. Hara, shared at -# https://iiasa-ece.slack.com/archives/CCFHDNA6P/p1712831476181449 -# - R12_AFR, R12_FSU, R12_NAM, R12_PAO, R12_PAS, R12_SAS: see the documentation -# at https://docs.messageix.org/projects/models/en/latest/transport/input.html -# - All others: -# -# - Duplicate of R11/ldv-activity.csv; see comments there. -# - R11_CPA value repeated for R12_RCPA and R12_CHN. -# - scenario=LED: SharePoint ECE.prog > Documents > Transport > LED Scenario > -# input files > ldv-act per veh-LDV.xlsx as of 2025-03-18. -# -# Unit: kilometre / year -# -scenario, node, year, value -# *, R12_AFR, 2020, 11000 # TH low -# *, R12_AFR, 2110, 11000 # TH low -*, R12_AFR, 2020, 15500 -*, R12_AFR, 2110, 15500 -# *, R12_AFR, 2020, 19000 # TH high -# *, R12_AFR, 2110, 19000 # TH high - -# *, R12_CHN, 2020, 9500 # TH low -# *, R12_CHN, 2110, 9500 # TH low -*, R12_CHN, 2020, 15000 # TH high -*, R12_CHN, 2110, 15000 # TH high -# *, R12_CHN, 2020, 16000 # Previous value -# *, R12_CHN, 2110, 16000 # Previous value - -# *, R12_EEU, 2020, 8962 # Previous value -# *, R12_EEU, 2110, 8962 # Previous value -*, R12_EEU, 2020, 9000 # TH low -*, R12_EEU, 2110, 9000 # TH low -# *, R12_EEU, 2020, 10000 # TH high -# *, R12_EEU, 2110, 10000 # TH high -# *, R12_EEU, 2020, 12500 # Experimental #392 -# *, R12_EEU, 2110, 15000 # Experimental #392 - -# *, R12_FSU, 2020, 11000 # TH low -# *, R12_FSU, 2110, 11000 # TH low -*, R12_FSU, 2020, 13000 # TH high = previous value -*, R12_FSU, 2110, 13000 # TH high = previous value - -# *, R12_LAM, 2020, 13000 # TH low -# *, R12_LAM, 2110, 13000 # TH low -*, R12_LAM, 2020, 13500 -*, R12_LAM, 2110, 13500 -# *, R12_LAM, 2020, 15000 # TH high -# *, R12_LAM, 2110, 15000 # TH high - -# *, R12_MEA, 2020, 13000 # TH low -# *, R12_MEA, 2110, 13000 # TH low -*, R12_MEA, 2020, 14500 -*, R12_MEA, 2110, 14500 -# *, R12_MEA, 2020, 16000 # TH high -# *, R12_MEA, 2110, 16000 # TH high - -# *, R12_NAM, 2020, 16000 # TH low -# *, R12_NAM, 2110, 16000 # TH low -*, R12_NAM, 2020, 18400 -*, R12_NAM, 2110, 18400 -# *, R12_NAM, 2020, 19000 # TH high -# *, R12_NAM, 2110, 19000 # TH high - -*, R12_PAO, 2020, 9000 # TH low = previous value -*, R12_PAO, 2110, 9000 # TH low = previous value -# *, R12_PAO, 2020, 10000 # TH high -# *, R12_PAO, 2110, 10000 # TH high -# *, R12_PAO, 2020, 10000 # Experimental #392 -# *, R12_PAO, 2110, 13000 # Experimental #392 - -# *, R12_PAS, 2020, 11000 # TH low -# *, R12_PAS, 2110, 11000 # TH low -*, R12_PAS, 2020, 13000 # TH high = previous value -*, R12_PAS, 2110, 13000 # TH high = previous value - -# *, R12_RCPA, 2020, 11000 # TH low -# *, R12_RCPA, 2110, 11000 # TH low -*, R12_RCPA, 2020, 12000 # TH high -*, R12_RCPA, 2110, 12000 # TH high -# *, R12_RCPA, 2020, 15000 # Experimental #392 -# *, R12_RCPA, 2110, 15000 # Experimental #392 -# *, R12_RCPA, 2020, 16000 # Previous value -# *, R12_RCPA, 2110, 16000 # Previous value - -*, R12_SAS, 2020, 12000 # TH low = previous value -*, R12_SAS, 2110, 12000 # TH low = previous value -# *, R12_SAS, 2020, 15000 # TH high -# *, R12_SAS, 2110, 15000 # TH high -# *, R12_SAS, 2020, 18000 # Experimental #392 -# *, R12_SAS, 2110, 18000 # Experimental #392 - -# *, R12_WEU, 2020, 11000 # TH low -# *, R12_WEU, 2110, 11000 # TH low -*, R12_WEU, 2020, 11700 -*, R12_WEU, 2110, 11700 -# *, R12_WEU, 2020, 12000 # TH high -# *, R12_WEU, 2110, 12000 # TH high -# *, R12_WEU, 2110, 15000 # Experimental #392 - -LED, R12_AFR, 2020, 15500 -LED, R12_AFR, 2050, 15113 -LED, R12_AFR, 2110, 15113 -LED, R12_CHN, 2020, 15000 -LED, R12_CHN, 2050, 15113 -LED, R12_CHN, 2110, 15113 -LED, R12_EEU, 2020, 9000 -LED, R12_EEU, 2050, 14087 -LED, R12_EEU, 2110, 14087 -LED, R12_FSU, 2020, 13000 -LED, R12_FSU, 2050, 14087 -LED, R12_FSU, 2110, 14087 -LED, R12_LAM, 2020, 13500 -LED, R12_LAM, 2050, 15113 -LED, R12_LAM, 2110, 15113 -LED, R12_MEA, 2020, 14500 -LED, R12_MEA, 2050, 15113 -LED, R12_MEA, 2110, 15113 -LED, R12_NAM, 2020, 18400 -LED, R12_NAM, 2050, 14087 -LED, R12_NAM, 2110, 14087 -LED, R12_PAO, 2020, 9000 -LED, R12_PAO, 2050, 14087 -LED, R12_PAO, 2110, 14087 -LED, R12_PAS, 2020, 13000 -LED, R12_PAS, 2050, 15113 -LED, R12_PAS, 2110, 15113 -LED, R12_RCPA, 2020, 12000 -LED, R12_RCPA, 2050, 15113 -LED, R12_RCPA, 2110, 15113 -LED, R12_SAS, 2020, 12000 -LED, R12_SAS, 2050, 15113 -LED, R12_SAS, 2110, 15113 -LED, R12_WEU, 2020, 11700 -LED, R12_WEU, 2050, 14087 -LED, R12_WEU, 2110, 14087 diff --git a/message_ix_models/data/transport/R12/lifetime-ldv.csv b/message_ix_models/data/transport/R12/lifetime-ldv.csv deleted file mode 100644 index ba353d3d34..0000000000 --- a/message_ix_models/data/transport/R12/lifetime-ldv.csv +++ /dev/null @@ -1,71 +0,0 @@ -# Technical lifetime (maximum age) of LDVs -# -# Sources -# - scenario=*: see https://github.com/iiasa/message-ix-models/pull/213 -# - scenario=LED: SharePoint ECE.prog > Documents > Transport > LED Scenario > -# input files > lifetime-ldv-LED.xlsx as of 2025-03-18. -# -# Units: year -# -scenario, node_loc, technology, year_vtg, value -*, R12_AFR, *, 1990, 25 -*, R12_AFR, *, 2110, 25 -*, R12_CHN, *, 1990, 18 -*, R12_CHN, *, 2110, 18 -*, R12_EEU, *, 1990, 28 -*, R12_EEU, *, 2110, 28 -*, R12_FSU, *, 1990, 15 -*, R12_FSU, *, 2110, 15 -*, R12_LAM, *, 1990, 25 -*, R12_LAM, *, 2110, 25 -*, R12_MEA, *, 1990, 15 -*, R12_MEA, *, 2110, 15 -*, R12_NAM, *, 1990, 18 -*, R12_NAM, *, 2110, 18 -*, R12_PAO, *, 1990, 15 -*, R12_PAO, *, 2110, 15 -*, R12_PAS, *, 1990, 15 -*, R12_PAS, *, 2110, 15 -*, R12_RCPA, *, 1990, 15 -*, R12_RCPA, *, 2110, 15 -*, R12_SAS, *, 1990, 25 -*, R12_SAS, *, 2110, 25 -*, R12_WEU, *, 1990, 20 -*, R12_WEU, *, 2110, 20 - -LED, R12_AFR, *, 1990, 25 -LED, R12_AFR, *, 2050, 19.36 -LED, R12_AFR, *, 2110, 19.36 -LED, R12_CHN, *, 1990, 15 -LED, R12_CHN, *, 2050, 19.36 -LED, R12_CHN, *, 2110, 19.36 -LED, R12_EEU, *, 1990, 28 -LED, R12_EEU, *, 2050, 19.55 -LED, R12_EEU, *, 2110, 19.55 -LED, R12_FSU, *, 1990, 15 -LED, R12_FSU, *, 2050, 19.55 -LED, R12_FSU, *, 2110, 19.55 -LED, R12_LAM, *, 1990, 25 -LED, R12_LAM, *, 2050, 19.36 -LED, R12_LAM, *, 2110, 19.36 -LED, R12_MEA, *, 1990, 15 -LED, R12_MEA, *, 2050, 19.36 -LED, R12_MEA, *, 2110, 19.36 -LED, R12_NAM, *, 1990, 18 -LED, R12_NAM, *, 2050, 19.55 -LED, R12_NAM, *, 2110, 19.55 -LED, R12_PAO, *, 1990, 13 -LED, R12_PAO, *, 2050, 19.55 -LED, R12_PAO, *, 2110, 19.55 -LED, R12_PAS, *, 1990, 13 -LED, R12_PAS, *, 2050, 19.36 -LED, R12_PAS, *, 2110, 19.36 -LED, R12_RCPA, *, 1990, 15 -LED, R12_RCPA, *, 2050, 19.36 -LED, R12_RCPA, *, 2110, 19.36 -LED, R12_SAS, *, 1990, 25 -LED, R12_SAS, *, 2050, 19.36 -LED, R12_SAS, *, 2110, 19.36 -LED, R12_WEU, *, 1990, 20 -LED, R12_WEU, *, 2050, 19.55 -LED, R12_WEU, *, 2110, 19.55 diff --git a/message_ix_models/data/transport/R12/lifetime.csv b/message_ix_models/data/transport/R12/lifetime.csv new file mode 100644 index 0000000000..19388350c1 --- /dev/null +++ b/message_ix_models/data/transport/R12/lifetime.csv @@ -0,0 +1,82 @@ +# Technical lifetime (maximum age) of vehicles +# +# Sources +# - scenario=*: see https://github.com/iiasa/message-ix-models/pull/213 +# - scenario=LED: SharePoint ECE.prog > Documents > Transport > LED Scenario > +# input files > lifetime-ldv-LED.xlsx as of 2025-03-18. +# +# Units: year +# +scenario, technology, node_loc, year_vtg, value +*, LDV, R12_AFR, 1990, 25 +*, LDV, R12_AFR, 2110, 25 +*, LDV, R12_CHN, 1990, 18 +*, LDV, R12_CHN, 2110, 18 +*, LDV, R12_EEU, 1990, 28 +*, LDV, R12_EEU, 2110, 28 +*, LDV, R12_FSU, 1990, 15 +*, LDV, R12_FSU, 2110, 15 +*, LDV, R12_LAM, 1990, 25 +*, LDV, R12_LAM, 2110, 25 +*, LDV, R12_MEA, 1990, 15 +*, LDV, R12_MEA, 2110, 15 +*, LDV, R12_NAM, 1990, 18 +*, LDV, R12_NAM, 2110, 18 +*, LDV, R12_PAO, 1990, 15 +*, LDV, R12_PAO, 2110, 15 +*, LDV, R12_PAS, 1990, 15 +*, LDV, R12_PAS, 2110, 15 +*, LDV, R12_RCPA, 1990, 15 +*, LDV, R12_RCPA, 2110, 15 +*, LDV, R12_SAS, 1990, 25 +*, LDV, R12_SAS, 2110, 25 +*, LDV, R12_WEU, 1990, 20 +*, LDV, R12_WEU, 2110, 20 + +LED, LDV, R12_AFR, 1990, 25 +LED, LDV, R12_AFR, 2050, 19.36 +LED, LDV, R12_AFR, 2110, 19.36 +LED, LDV, R12_CHN, 1990, 15 +LED, LDV, R12_CHN, 2050, 19.36 +LED, LDV, R12_CHN, 2110, 19.36 +LED, LDV, R12_EEU, 1990, 28 +LED, LDV, R12_EEU, 2050, 19.55 +LED, LDV, R12_EEU, 2110, 19.55 +LED, LDV, R12_FSU, 1990, 15 +LED, LDV, R12_FSU, 2050, 19.55 +LED, LDV, R12_FSU, 2110, 19.55 +LED, LDV, R12_LAM, 1990, 25 +LED, LDV, R12_LAM, 2050, 19.36 +LED, LDV, R12_LAM, 2110, 19.36 +LED, LDV, R12_MEA, 1990, 15 +LED, LDV, R12_MEA, 2050, 19.36 +LED, LDV, R12_MEA, 2110, 19.36 +LED, LDV, R12_NAM, 1990, 18 +LED, LDV, R12_NAM, 2050, 19.55 +LED, LDV, R12_NAM, 2110, 19.55 +LED, LDV, R12_PAO, 1990, 13 +LED, LDV, R12_PAO, 2050, 19.55 +LED, LDV, R12_PAO, 2110, 19.55 +LED, LDV, R12_PAS, 1990, 13 +LED, LDV, R12_PAS, 2050, 19.36 +LED, LDV, R12_PAS, 2110, 19.36 +LED, LDV, R12_RCPA, 1990, 15 +LED, LDV, R12_RCPA, 2050, 19.36 +LED, LDV, R12_RCPA, 2110, 19.36 +LED, LDV, R12_SAS, 1990, 25 +LED, LDV, R12_SAS, 2050, 19.36 +LED, LDV, R12_SAS, 2110, 19.36 +LED, LDV, R12_WEU, 1990, 20 +LED, LDV, R12_WEU, 2050, 19.55 +LED, LDV, R12_WEU, 2110, 19.55 + +*, 2W, *, 1990, 15 +*, 2W, *, 2110, 15 +*, AIR, *, 1990, 15 +*, AIR, *, 2110, 15 +*, BUS, *, 1990, 15 +*, BUS, *, 2110, 15 +*, F RAIL, *, 1990, 15 +*, F RAIL, *, 2110, 15 +*, F ROAD, *, 1990, 15 +*, F ROAD, *, 2110, 15 diff --git a/message_ix_models/data/transport/R12/load-factor-ldv/DIGSY-BEST-C.csv b/message_ix_models/data/transport/R12/load-factor-ldv/DIGSY-BEST-C.csv index b91f8852c9..d94f20f82a 100644 --- a/message_ix_models/data/transport/R12/load-factor-ldv/DIGSY-BEST-C.csv +++ b/message_ix_models/data/transport/R12/load-factor-ldv/DIGSY-BEST-C.csv @@ -2,8 +2,7 @@ # # Source: Constructed by @r-aneeque # -# Units: dimensionless -# (Implicitly passengers per vehicle.) +# Units: passenger / vehicle # node, year, value R12_AFR, 2020, 2.10 diff --git a/message_ix_models/data/transport/R12/load-factor-ldv/DIGSY-BEST-S.csv b/message_ix_models/data/transport/R12/load-factor-ldv/DIGSY-BEST-S.csv index 7012c14115..790439373a 100644 --- a/message_ix_models/data/transport/R12/load-factor-ldv/DIGSY-BEST-S.csv +++ b/message_ix_models/data/transport/R12/load-factor-ldv/DIGSY-BEST-S.csv @@ -2,8 +2,7 @@ # # Source: Constructed by @r-aneeque # -# Units: dimensionless -# (Implicitly passengers per vehicle.) +# Units: passenger / vehicle # node, year, value R12_AFR, 2020, 2.10 diff --git a/message_ix_models/data/transport/R12/load-factor-ldv/DIGSY-WORST-S.csv b/message_ix_models/data/transport/R12/load-factor-ldv/DIGSY-WORST-S.csv index 8306a2f26a..bae0ad540b 100644 --- a/message_ix_models/data/transport/R12/load-factor-ldv/DIGSY-WORST-S.csv +++ b/message_ix_models/data/transport/R12/load-factor-ldv/DIGSY-WORST-S.csv @@ -2,8 +2,7 @@ # # Source: Constructed by @r-aneeque # -# Units: dimensionless -# (Implicitly passengers per vehicle.) +# Units: passenger / vehicle # node, year, value R12_AFR, 2020, 2.1 diff --git a/message_ix_models/data/transport/R12/load-factor-ldv/EDITS-CA.csv b/message_ix_models/data/transport/R12/load-factor-ldv/EDITS-CA.csv index 99b145584e..a5b3427ec1 100644 --- a/message_ix_models/data/transport/R12/load-factor-ldv/EDITS-CA.csv +++ b/message_ix_models/data/transport/R12/load-factor-ldv/EDITS-CA.csv @@ -5,8 +5,7 @@ # > PASTA data-20250822T114700Z-1-001 > PASTA data # > load-factor-ldv.csv, rows with scenario="EDITS_BAU" # -# Units: dimensionless -# (Implicitly passengers per vehicle.) +# Units: passenger / vehicle # node, year, value R12_AFR, 2015, 2.206028607 diff --git a/message_ix_models/data/transport/R12/load-factor-ldv/EDITS-HA.csv b/message_ix_models/data/transport/R12/load-factor-ldv/EDITS-HA.csv index 6a6f417cb7..58ad6c1317 100644 --- a/message_ix_models/data/transport/R12/load-factor-ldv/EDITS-HA.csv +++ b/message_ix_models/data/transport/R12/load-factor-ldv/EDITS-HA.csv @@ -5,8 +5,7 @@ # > PASTA data-20250822T114700Z-1-001 > PASTA data # > load-factor-ldv.csv, rows with scenario="EDITS_HWL_v_0.01" # -# Units: dimensionless -# (Implicitly passengers per vehicle.) +# Units: passenger / vehicle # node, year, value R12_AFR, 2015, 2.206012863 diff --git a/message_ix_models/data/transport/R12/load-factor-ldv/LED.csv b/message_ix_models/data/transport/R12/load-factor-ldv/LED.csv index a1ed781ba9..3a58b28a36 100644 --- a/message_ix_models/data/transport/R12/load-factor-ldv/LED.csv +++ b/message_ix_models/data/transport/R12/load-factor-ldv/LED.csv @@ -3,8 +3,7 @@ # Source: Duplicate of R11/load-factor-ldv.csv; R12_CHN and R12_RCPA values # filled from R11_CPA. # -# Units: dimensionless -# (Implicitly passengers per vehicle.) +# Units: passenger / vehicle # node, year, value # “Global South” diff --git a/message_ix_models/data/transport/R12/load-factor-ldv/SSP_2024_1.csv b/message_ix_models/data/transport/R12/load-factor-ldv/SSP_2024_1.csv index 1c75249ec8..d98a5b828d 100644 --- a/message_ix_models/data/transport/R12/load-factor-ldv/SSP_2024_1.csv +++ b/message_ix_models/data/transport/R12/load-factor-ldv/SSP_2024_1.csv @@ -3,8 +3,7 @@ # Source: Duplicate of R11/load-factor-ldv.csv; R12_CHN and R12_RCPA values # filled from R11_CPA. # -# Units: dimensionless -# (Implicitly passengers per vehicle.) +# Units: passenger / vehicle # node, year, value R12_AFR, 2020, 2.1 diff --git a/message_ix_models/data/transport/R12/load-factor-ldv/SSP_2024_2.csv b/message_ix_models/data/transport/R12/load-factor-ldv/SSP_2024_2.csv index f6c902a02b..0f09c53ec8 100644 --- a/message_ix_models/data/transport/R12/load-factor-ldv/SSP_2024_2.csv +++ b/message_ix_models/data/transport/R12/load-factor-ldv/SSP_2024_2.csv @@ -3,8 +3,7 @@ # Source: Duplicate of R11/load-factor-ldv.csv; R12_CHN and R12_RCPA values # filled from R11_CPA. # -# Units: dimensionless -# (Implicitly passengers per vehicle.) +# Units: passenger / vehicle # node, year, value R12_AFR, 2020, 2.10 diff --git a/message_ix_models/data/transport/R12/load-factor-ldv/SSP_2024_3.csv b/message_ix_models/data/transport/R12/load-factor-ldv/SSP_2024_3.csv index db6bb7d4c3..d62a804dfe 100644 --- a/message_ix_models/data/transport/R12/load-factor-ldv/SSP_2024_3.csv +++ b/message_ix_models/data/transport/R12/load-factor-ldv/SSP_2024_3.csv @@ -3,8 +3,7 @@ # Source: Duplicate of R11/load-factor-ldv.csv; R12_CHN and R12_RCPA values # filled from R11_CPA. # -# Units: dimensionless -# (Implicitly passengers per vehicle.) +# Units: passenger / vehicle # node, year, value R12_AFR, 2020, 2.1 diff --git a/message_ix_models/data/transport/R12/load-factor-ldv/SSP_2024_4.csv b/message_ix_models/data/transport/R12/load-factor-ldv/SSP_2024_4.csv index dcc5cb64a2..14ee3a469d 100644 --- a/message_ix_models/data/transport/R12/load-factor-ldv/SSP_2024_4.csv +++ b/message_ix_models/data/transport/R12/load-factor-ldv/SSP_2024_4.csv @@ -3,8 +3,7 @@ # Source: Duplicate of R11/load-factor-ldv.csv; R12_CHN and R12_RCPA values # filled from R11_CPA. # -# Units: dimensionless -# (Implicitly passengers per vehicle.) +# Units: passenger / vehicle # node, year, value R12_AFR, 2020, 2.1 diff --git a/message_ix_models/data/transport/R12/load-factor-ldv/SSP_2024_5.csv b/message_ix_models/data/transport/R12/load-factor-ldv/SSP_2024_5.csv index 35509239b1..833482ee04 100644 --- a/message_ix_models/data/transport/R12/load-factor-ldv/SSP_2024_5.csv +++ b/message_ix_models/data/transport/R12/load-factor-ldv/SSP_2024_5.csv @@ -3,8 +3,7 @@ # Source: Duplicate of R11/load-factor-ldv.csv; R12_CHN and R12_RCPA values # filled from R11_CPA. # -# Units: dimensionless -# (Implicitly passengers per vehicle.) +# Units: passenger / vehicle # node, year, value R12_AFR, 2020, 2.1 diff --git a/message_ix_models/data/transport/R12/price-emission/SSP_LED_v6.5_LED - High Emissions_v3.csv b/message_ix_models/data/transport/R12/price-emission/SSP_LED_v6.5_LED - High Emissions_v3.csv new file mode 100644 index 0000000000..987bb5bb0f --- /dev/null +++ b/message_ix_models/data/transport/R12/price-emission/SSP_LED_v6.5_LED - High Emissions_v3.csv @@ -0,0 +1,10 @@ +# Exported using: +# mix-models --url="ixmp://ixmp-dev/SSP_LED_v6.5/LED - High Emissions" transport export-price +# at 2026-04-07T19:24:22.872482 +# +node,type_emission,type_tec,year,lvl,mrg +R12_GLB,CO2_shipping_IMO,bunkers,2060,5492.357908799743,0.0 +R12_GLB,CO2_shipping_IMO,bunkers,2070,269.0486426257295,0.0 +R12_GLB,CO2_shipping_IMO,bunkers,2080,313.2632000474355,0.0 +R12_GLB,CO2_shipping_IMO,bunkers,2090,490.8628883500824,0.0 +R12_GLB,CO2_shipping_IMO,bunkers,2110,219.3127211855239,0.0 diff --git a/message_ix_models/data/transport/R12/price-emission/SSP_LED_v6.5_SSP2 - Very Low Emissions_v3.csv b/message_ix_models/data/transport/R12/price-emission/SSP_LED_v6.5_SSP2 - Very Low Emissions_v3.csv new file mode 100644 index 0000000000..560f7f5164 --- /dev/null +++ b/message_ix_models/data/transport/R12/price-emission/SSP_LED_v6.5_SSP2 - Very Low Emissions_v3.csv @@ -0,0 +1,16 @@ +# Exported using: +# mix-models --url="ixmp://ixmp-dev/SSP_LED_v6.5/SSP2 - Very Low Emissions" transport export-price +# at 2026-04-07T19:26:21.921651 +# +node,type_emission,type_tec,year,lvl,mrg +World,TCE,all,2035,365.61880670519434,0.0 +World,TCE,all,2040,423.596572648762,0.0 +World,TCE,all,2045,491.20695234454087,0.0 +World,TCE,all,2050,569.261963287646,0.0 +World,TCE,all,2055,660.0400992843945,0.0 +World,TCE,all,2060,765.2859275753157,0.0 +World,TCE,all,2070,765.2859275753157,0.0 +World,TCE,all,2080,765.2859275753157,0.0 +World,TCE,all,2090,765.2859275753158,0.0 +World,TCE,all,2100,765.2859275753157,0.0 +World,TCE,all,2110,765.2859275753157,0.0 diff --git a/message_ix_models/data/transport/R12/price-emission/SSP_SSP1_v6.5_SSP1 - High Emissions_v1.csv b/message_ix_models/data/transport/R12/price-emission/SSP_SSP1_v6.5_SSP1 - High Emissions_v1.csv new file mode 100644 index 0000000000..c499ce3de7 --- /dev/null +++ b/message_ix_models/data/transport/R12/price-emission/SSP_SSP1_v6.5_SSP1 - High Emissions_v1.csv @@ -0,0 +1,12 @@ +# Exported using: +# mix-models --url="ixmp://ixmp-dev/SSP_SSP1_v6.5/SSP1 - High Emissions" transport export-price +# at 2026-04-07T19:27:11.494219 +# +node,type_emission,type_tec,year,lvl,mrg +R12_GLB,CO2_shipping_IMO,bunkers,2055,5284.612225974673,0.0 +R12_GLB,CO2_shipping_IMO,bunkers,2060,330.82231727551,0.0 +R12_GLB,CO2_shipping_IMO,bunkers,2070,332.1572884799681,0.0 +R12_GLB,CO2_shipping_IMO,bunkers,2080,337.9294736703953,0.0 +R12_GLB,CO2_shipping_IMO,bunkers,2090,392.2513710834383,0.0 +R12_GLB,CO2_shipping_IMO,bunkers,2100,342.0181312146865,0.0 +R12_GLB,CO2_shipping_IMO,bunkers,2110,326.3373130149824,0.0 diff --git a/message_ix_models/data/transport/R12/price-emission/SSP_SSP1_v6.5_SSP1 - Low Emissions_v2.csv b/message_ix_models/data/transport/R12/price-emission/SSP_SSP1_v6.5_SSP1 - Low Emissions_v2.csv new file mode 100644 index 0000000000..336186fbe1 --- /dev/null +++ b/message_ix_models/data/transport/R12/price-emission/SSP_SSP1_v6.5_SSP1 - Low Emissions_v2.csv @@ -0,0 +1,148 @@ +# Exported using: +# mix-models --url="ixmp://ixmp-dev/SSP_SSP1_v6.5/SSP1 - Low Emissions" transport export-price +# at 2026-04-07T19:28:01.143829 +# +node,type_emission,type_tec,year,lvl,mrg +R12_AFR,TCE,all,2035,27.986206720799046,0.0 +R12_AFR,TCE,all,2040,467.35267961138027,0.0 +R12_AFR,TCE,all,2045,444.5070441895579,0.0 +R12_AFR,TCE,all,2050,311.55643015397334,0.0 +R12_AFR,TCE,all,2055,422.78661070120506,0.0 +R12_AFR,TCE,all,2060,501.2019227503621,0.0 +R12_AFR,TCE,all,2070,322.69109219078086,0.0 +R12_AFR,TCE,all,2080,813.7065004041036,0.0 +R12_AFR,TCE,all,2090,283.2237440386424,0.0 +R12_AFR,TCE,all,2100,349.3235759372356,0.0 +R12_AFR,TCE,all,2110,391.42089075696026,0.0 +R12_EEU,TCE,all,2035,511.6312835286653,0.0 +R12_EEU,TCE,all,2040,425.5848369045436,0.0 +R12_EEU,TCE,all,2045,409.51882625905307,0.0 +R12_EEU,TCE,all,2050,1845.882528017128,0.0 +R12_EEU,TCE,all,2055,717.774921366223,0.0 +R12_EEU,TCE,all,2060,800.3242158967148,0.0 +R12_EEU,TCE,all,2070,1030.9060814821876,0.0 +R12_EEU,TCE,all,2080,1651.924312788974,0.0 +R12_EEU,TCE,all,2090,536.0220701273116,0.0 +R12_EEU,TCE,all,2100,461.2192537455781,0.0 +R12_EEU,TCE,all,2110,501.6761418755649,0.0 +R12_GLB,TCE,all,2035,340.239213661948,0.0 +R12_GLB,TCE,all,2040,450.6053842655253,0.0 +R12_GLB,TCE,all,2045,657.7941953375512,0.0 +R12_GLB,TCE,all,2050,1570.8502759050039,0.0 +R12_GLB,TCE,all,2055,4676.034426542131,0.0 +R12_GLB,TCE,all,2060,3343.2100489082222,0.0 +R12_GLB,TCE,all,2070,1194.9656610391576,0.0 +R12_GLB,TCE,all,2080,1404.7128455811344,0.0 +R12_GLB,TCE,all,2090,1546.0219248138126,0.0 +R12_GLB,TCE,all,2100,1187.178727613958,0.0 +R12_GLB,TCE,all,2110,1057.595474936114,0.0 +R12_LAM,TCE,all,2035,104.35956921758698,0.0 +R12_LAM,TCE,all,2040,34.36530431101274,0.0 +R12_LAM,TCE,all,2045,150.41146248532553,0.0 +R12_LAM,TCE,all,2050,70.66413911022997,0.0 +R12_LAM,TCE,all,2055,215.70938549273615,0.0 +R12_LAM,TCE,all,2060,500.78316716420227,0.0 +R12_LAM,TCE,all,2070,322.12831969990657,0.0 +R12_LAM,TCE,all,2080,571.0962259015375,0.0 +R12_LAM,TCE,all,2090,282.2073143203114,0.0 +R12_LAM,TCE,all,2100,347.9575793903185,0.0 +R12_LAM,TCE,all,2110,389.5851056234308,0.0 +R12_MEA,TCE,all,2035,42.44930741342586,0.0 +R12_MEA,TCE,all,2040,119.73946308509876,0.0 +R12_MEA,TCE,all,2045,163.2261479931304,0.0 +R12_MEA,TCE,all,2050,113.03373822668294,0.0 +R12_MEA,TCE,all,2055,216.07060773967356,0.0 +R12_MEA,TCE,all,2060,501.2019227503621,0.0 +R12_MEA,TCE,all,2070,366.9391983609653,0.0 +R12_MEA,TCE,all,2080,1064.9362568410152,0.0 +R12_MEA,TCE,all,2090,615.1496227361866,0.0 +R12_MEA,TCE,all,2100,614.2603491656861,0.0 +R12_MEA,TCE,all,2110,608.2140472193071,0.0 +R12_NAM,TCE,all,2035,23.874635191993924,0.0 +R12_NAM,TCE,all,2040,32.00111496722509,0.0 +R12_NAM,TCE,all,2045,56.87145993746946,0.0 +R12_NAM,TCE,all,2050,70.35254562690982,0.0 +R12_NAM,TCE,all,2055,227.00659759331748,0.0 +R12_NAM,TCE,all,2060,3931.161318243292,0.0 +R12_NAM,TCE,all,2070,337.2331939361697,0.0 +R12_NAM,TCE,all,2080,571.0962259015375,0.0 +R12_NAM,TCE,all,2090,283.22374403864103,0.0 +R12_NAM,TCE,all,2100,347.95757939031864,0.0 +R12_NAM,TCE,all,2110,389.5851056234308,0.0 +R12_SAS,TCE,all,2035,23.874635191993924,0.0 +R12_SAS,TCE,all,2040,52.07247934280867,0.0 +R12_SAS,TCE,all,2045,170.91923438721378,0.0 +R12_SAS,TCE,all,2050,111.37291032814153,0.0 +R12_SAS,TCE,all,2055,216.07060773967,0.0 +R12_SAS,TCE,all,2060,501.20192275035924,0.0 +R12_SAS,TCE,all,2070,1260.297844016243,0.0 +R12_SAS,TCE,all,2080,1113.4385863813409,0.0 +R12_SAS,TCE,all,2090,1651.184594654968,0.0 +R12_SAS,TCE,all,2100,1610.6891276473384,0.0 +R12_SAS,TCE,all,2110,1606.5989398789113,0.0 +R12_WEU,TCE,all,2035,23.874635191993907,0.0 +R12_WEU,TCE,all,2040,32.00111496722509,0.0 +R12_WEU,TCE,all,2045,56.87145993746946,0.0 +R12_WEU,TCE,all,2050,286.6994115472846,0.0 +R12_WEU,TCE,all,2055,13431.39375424236,0.0 +R12_WEU,TCE,all,2060,994.5939086303134,0.0 +R12_WEU,TCE,all,2070,586.7812874955271,0.0 +R12_WEU,TCE,all,2080,804.8925400764435,0.0 +R12_WEU,TCE,all,2090,662.4936285403586,0.0 +R12_WEU,TCE,all,2100,777.222047152305,0.0 +R12_WEU,TCE,all,2110,834.6102275908969,0.0 +R12_FSU,TCE,all,2035,23.874635191993953,0.0 +R12_FSU,TCE,all,2040,32.00111496722509,0.0 +R12_FSU,TCE,all,2045,56.87145993746946,0.0 +R12_FSU,TCE,all,2050,70.35254562690982,0.0 +R12_FSU,TCE,all,2055,215.70938549273615,0.0 +R12_FSU,TCE,all,2060,500.78316716443123,0.0 +R12_FSU,TCE,all,2070,322.12831969990657,0.0 +R12_FSU,TCE,all,2080,571.8525450698678,0.0 +R12_FSU,TCE,all,2090,283.2237440386422,0.0 +R12_FSU,TCE,all,2100,349.3235759372356,0.0 +R12_FSU,TCE,all,2110,389.58510562343093,0.0 +R12_PAO,TCE,all,2035,23.87463519199389,0.0 +R12_PAO,TCE,all,2040,32.00111496722509,0.0 +R12_PAO,TCE,all,2045,56.87145993746946,0.0 +R12_PAO,TCE,all,2050,592.7504895208199,0.0 +R12_PAO,TCE,all,2055,215.70938549273615,0.0 +R12_PAO,TCE,all,2060,500.78316716443123,0.0 +R12_PAO,TCE,all,2070,322.12831969990657,0.0 +R12_PAO,TCE,all,2080,571.0962259015375,0.0 +R12_PAO,TCE,all,2090,282.2073143203114,0.0 +R12_PAO,TCE,all,2100,347.9575793903185,0.0 +R12_PAO,TCE,all,2110,389.5851056234308,0.0 +R12_PAS,TCE,all,2035,31.567995869449643,0.0 +R12_PAS,TCE,all,2040,37.70276442682179,0.0 +R12_PAS,TCE,all,2045,57.14024321333827,0.0 +R12_PAS,TCE,all,2050,70.66413911022997,0.0 +R12_PAS,TCE,all,2055,215.70938549273615,0.0 +R12_PAS,TCE,all,2060,500.78316716443123,0.0 +R12_PAS,TCE,all,2070,322.69109219078086,0.0 +R12_PAS,TCE,all,2080,571.8525450698676,0.0 +R12_PAS,TCE,all,2090,393.7592109608249,0.0 +R12_PAS,TCE,all,2100,375.01031923432356,0.0 +R12_PAS,TCE,all,2110,391.42089075696026,0.0 +R12_CHN,TCE,all,2035,24.074635191993888,0.0 +R12_CHN,TCE,all,2040,32.23296978208509,0.0 +R12_CHN,TCE,all,2045,56.87145993746946,0.0 +R12_CHN,TCE,all,2050,70.35254562690982,0.0 +R12_CHN,TCE,all,2055,215.70938549273615,0.0 +R12_CHN,TCE,all,2060,4492.830710061616,0.0 +R12_CHN,TCE,all,2070,539.9303935721902,0.0 +R12_CHN,TCE,all,2080,785.1300410703798,0.0 +R12_CHN,TCE,all,2090,865.6317437515081,0.0 +R12_CHN,TCE,all,2100,873.1148049803113,0.0 +R12_CHN,TCE,all,2110,710.2662085157774,0.0 +R12_RCPA,TCE,all,2035,31.75083275873066,0.0 +R12_RCPA,TCE,all,2040,34.42431290638738,0.0 +R12_RCPA,TCE,all,2045,102.03817912206848,0.0 +R12_RCPA,TCE,all,2050,1497.8216676998738,0.0 +R12_RCPA,TCE,all,2055,516.4112167054008,0.0 +R12_RCPA,TCE,all,2060,501.2019227503621,0.0 +R12_RCPA,TCE,all,2070,381.76557244749864,0.0 +R12_RCPA,TCE,all,2080,571.8525450698678,0.0 +R12_RCPA,TCE,all,2090,531.8782459029042,0.0 +R12_RCPA,TCE,all,2100,558.544335266056,0.0 +R12_RCPA,TCE,all,2110,503.2742296147667,0.0 diff --git a/message_ix_models/data/transport/R12/price-emission/SSP_SSP1_v6.5_SSP1 - Very Low Emissions_v2.csv b/message_ix_models/data/transport/R12/price-emission/SSP_SSP1_v6.5_SSP1 - Very Low Emissions_v2.csv new file mode 100644 index 0000000000..de39d9d033 --- /dev/null +++ b/message_ix_models/data/transport/R12/price-emission/SSP_SSP1_v6.5_SSP1 - Very Low Emissions_v2.csv @@ -0,0 +1,16 @@ +# Exported using: +# mix-models --url="ixmp://ixmp-dev/SSP_SSP1_v6.5/SSP1 - Very Low Emissions" transport export-price +# at 2026-04-07T19:28:51.651269 +# +node,type_emission,type_tec,year,lvl,mrg +World,TCE,all,2035,309.12822607474226,0.0 +World,TCE,all,2040,358.290036725829,0.0 +World,TCE,all,2045,415.1807800485379,0.0 +World,TCE,all,2050,481.71096641354427,0.0 +World,TCE,all,2055,558.3300109638068,0.0 +World,TCE,all,2060,647.4038454754583,0.0 +World,TCE,all,2070,720.7009669862907,0.0 +World,TCE,all,2080,720.7009669862907,0.0 +World,TCE,all,2090,720.7009669862908,0.0 +World,TCE,all,2100,720.7009669862907,0.0 +World,TCE,all,2110,720.7009669862907,0.0 diff --git a/message_ix_models/data/transport/R12/price-emission/SSP_SSP2_v6.5_SSP2 - High Emissions_v1.csv b/message_ix_models/data/transport/R12/price-emission/SSP_SSP2_v6.5_SSP2 - High Emissions_v1.csv new file mode 100644 index 0000000000..65bd79f00c --- /dev/null +++ b/message_ix_models/data/transport/R12/price-emission/SSP_SSP2_v6.5_SSP2 - High Emissions_v1.csv @@ -0,0 +1,8 @@ +# Exported using: +# mix-models --url="ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - High Emissions" transport export-price +# at 2026-04-07T19:29:46.255758 +# +node,type_emission,type_tec,year,lvl,mrg +R12_GLB,CO2_shipping_IMO,bunkers,2090,4537.274658706932,0.0 +R12_GLB,CO2_shipping_IMO,bunkers,2100,384.621641518828,0.0 +R12_GLB,CO2_shipping_IMO,bunkers,2110,390.60386370178253,0.0 diff --git a/message_ix_models/data/transport/R12/price-emission/SSP_SSP2_v6.5_SSP2 - Low Emissions_v2.csv b/message_ix_models/data/transport/R12/price-emission/SSP_SSP2_v6.5_SSP2 - Low Emissions_v2.csv new file mode 100644 index 0000000000..a5d0296935 --- /dev/null +++ b/message_ix_models/data/transport/R12/price-emission/SSP_SSP2_v6.5_SSP2 - Low Emissions_v2.csv @@ -0,0 +1,148 @@ +# Exported using: +# mix-models --url="ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Low Emissions" transport export-price +# at 2026-04-07T19:33:08.711752 +# +node,type_emission,type_tec,year,lvl,mrg +R12_AFR,TCE,all,2035,457.4718018905821,0.0 +R12_AFR,TCE,all,2040,1044.2424970470915,0.0 +R12_AFR,TCE,all,2045,695.5933085573403,0.0 +R12_AFR,TCE,all,2050,783.485558888148,0.0 +R12_AFR,TCE,all,2055,375.8835799422166,0.0 +R12_AFR,TCE,all,2060,352.01143511147194,0.0 +R12_AFR,TCE,all,2070,558.7541010289455,0.0 +R12_AFR,TCE,all,2080,595.4158550412619,0.0 +R12_AFR,TCE,all,2090,659.1544278579487,0.0 +R12_AFR,TCE,all,2100,682.859274139953,0.0 +R12_AFR,TCE,all,2110,652.2118201954781,0.0 +R12_EEU,TCE,all,2035,300.0334677026974,0.0 +R12_EEU,TCE,all,2040,366.74658162955154,0.0 +R12_EEU,TCE,all,2045,212.21698441945432,0.0 +R12_EEU,TCE,all,2050,256.4056702374348,0.0 +R12_EEU,TCE,all,2055,1143.849996386085,0.0 +R12_EEU,TCE,all,2060,467.8707189112857,0.0 +R12_EEU,TCE,all,2070,558.7541010289457,0.0 +R12_EEU,TCE,all,2080,669.8040049823541,0.0 +R12_EEU,TCE,all,2090,889.0274687223167,0.0 +R12_EEU,TCE,all,2100,982.3986012814297,0.0 +R12_EEU,TCE,all,2110,930.9318059536477,0.0 +R12_GLB,TCE,all,2035,310.5034931815895,0.0 +R12_GLB,TCE,all,2040,991.6928453698773,0.0 +R12_GLB,TCE,all,2045,760.7612037990809,0.0 +R12_GLB,TCE,all,2050,611.7080234700634,0.0 +R12_GLB,TCE,all,2055,948.9114976202475,0.0 +R12_GLB,TCE,all,2060,2091.890133993212,0.0 +R12_GLB,TCE,all,2070,1193.5900053210642,0.0 +R12_GLB,TCE,all,2080,971.2704678188609,0.0 +R12_GLB,TCE,all,2090,1054.3769427258392,0.0 +R12_GLB,TCE,all,2100,1052.4556650577229,0.0 +R12_GLB,TCE,all,2110,1683.0420876986182,0.0 +R12_LAM,TCE,all,2035,117.59794753271454,0.0 +R12_LAM,TCE,all,2040,118.56464338118082,0.0 +R12_LAM,TCE,all,2045,179.28964325264167,0.0 +R12_LAM,TCE,all,2050,156.97212996773533,0.0 +R12_LAM,TCE,all,2055,249.8309221925368,0.0 +R12_LAM,TCE,all,2060,351.33416412329206,0.0 +R12_LAM,TCE,all,2070,557.6508979554274,0.0 +R12_LAM,TCE,all,2080,595.4158550412619,0.0 +R12_LAM,TCE,all,2090,656.2273016746739,0.0 +R12_LAM,TCE,all,2100,678.0912940281173,0.0 +R12_LAM,TCE,all,2110,644.4452830107269,0.0 +R12_MEA,TCE,all,2035,309.42983118891175,0.0 +R12_MEA,TCE,all,2040,361.3070734143141,0.0 +R12_MEA,TCE,all,2045,321.0407879795653,0.0 +R12_MEA,TCE,all,2050,237.6450606752094,0.0 +R12_MEA,TCE,all,2055,281.4562451715461,0.0 +R12_MEA,TCE,all,2060,352.01143511147194,0.0 +R12_MEA,TCE,all,2070,558.7541010289457,0.0 +R12_MEA,TCE,all,2080,597.2128565999604,0.0 +R12_MEA,TCE,all,2090,659.1544278579487,0.0 +R12_MEA,TCE,all,2100,682.8592741399534,0.0 +R12_MEA,TCE,all,2110,652.3648186916367,0.0 +R12_NAM,TCE,all,2035,71.16954123913058,0.0 +R12_NAM,TCE,all,2040,118.3093870686808,0.0 +R12_NAM,TCE,all,2045,178.96386432728616,0.0 +R12_NAM,TCE,all,2050,156.5563443318546,0.0 +R12_NAM,TCE,all,2055,249.30026265150792,0.0 +R12_NAM,TCE,all,2060,351.33416412329206,0.0 +R12_NAM,TCE,all,2070,557.6508979554274,0.0 +R12_NAM,TCE,all,2080,597.2128565999604,0.0 +R12_NAM,TCE,all,2090,656.2273016746739,0.0 +R12_NAM,TCE,all,2100,678.0912940281165,0.0 +R12_NAM,TCE,all,2110,644.4452830107269,0.0 +R12_SAS,TCE,all,2035,71.36954123913078,0.0 +R12_SAS,TCE,all,2040,138.2277592568608,0.0 +R12_SAS,TCE,all,2045,224.30853917988748,0.0 +R12_SAS,TCE,all,2050,225.69010500899475,0.0 +R12_SAS,TCE,all,2055,249.8309221925368,0.0 +R12_SAS,TCE,all,2060,417.97376140399297,0.0 +R12_SAS,TCE,all,2070,760.8381096764655,0.0 +R12_SAS,TCE,all,2080,964.027671622367,0.0 +R12_SAS,TCE,all,2090,1084.3589254739054,0.0 +R12_SAS,TCE,all,2100,1740.103999191822,0.0 +R12_SAS,TCE,all,2110,2326.3640771163823,0.0 +R12_WEU,TCE,all,2035,287.6514158052839,0.0 +R12_WEU,TCE,all,2040,271.36257339335805,0.0 +R12_WEU,TCE,all,2045,258.00450553757776,0.0 +R12_WEU,TCE,all,2050,419.6670915739226,0.0 +R12_WEU,TCE,all,2055,626.1066150566011,0.0 +R12_WEU,TCE,all,2060,2391.9047516645705,0.0 +R12_WEU,TCE,all,2070,558.7541010289457,0.0 +R12_WEU,TCE,all,2080,599.8063903388241,0.0 +R12_WEU,TCE,all,2090,779.6384436171959,0.0 +R12_WEU,TCE,all,2100,932.626312881825,0.0 +R12_WEU,TCE,all,2110,1483.7206832583656,0.0 +R12_FSU,TCE,all,2035,71.16954123913064,0.0 +R12_FSU,TCE,all,2040,118.3093870686808,0.0 +R12_FSU,TCE,all,2045,178.96386432728616,0.0 +R12_FSU,TCE,all,2050,156.5563443318546,0.0 +R12_FSU,TCE,all,2055,249.30026265150792,0.0 +R12_FSU,TCE,all,2060,351.33416412329206,0.0 +R12_FSU,TCE,all,2070,557.6508979554274,0.0 +R12_FSU,TCE,all,2080,595.4158550412619,0.0 +R12_FSU,TCE,all,2090,656.2273016746739,0.0 +R12_FSU,TCE,all,2100,678.0912940281171,0.0 +R12_FSU,TCE,all,2110,644.4452830107269,0.0 +R12_PAO,TCE,all,2035,71.16954123913064,0.0 +R12_PAO,TCE,all,2040,118.3093870686808,0.0 +R12_PAO,TCE,all,2045,178.96386432728667,0.0 +R12_PAO,TCE,all,2050,156.9721299677369,0.0 +R12_PAO,TCE,all,2055,508.6297430534355,0.0 +R12_PAO,TCE,all,2060,352.01143511147194,0.0 +R12_PAO,TCE,all,2070,557.6508979554274,0.0 +R12_PAO,TCE,all,2080,595.4158550412619,0.0 +R12_PAO,TCE,all,2090,656.2273016746739,0.0 +R12_PAO,TCE,all,2100,678.0912940281171,0.0 +R12_PAO,TCE,all,2110,644.4452830107269,0.0 +R12_PAS,TCE,all,2035,71.16954123913064,0.0 +R12_PAS,TCE,all,2040,118.3093870686808,0.0 +R12_PAS,TCE,all,2045,178.96386432728616,0.0 +R12_PAS,TCE,all,2050,156.5563443318546,0.0 +R12_PAS,TCE,all,2055,249.30026265150792,0.0 +R12_PAS,TCE,all,2060,351.33416412329206,0.0 +R12_PAS,TCE,all,2070,557.6508979554274,0.0 +R12_PAS,TCE,all,2080,595.4158550412619,0.0 +R12_PAS,TCE,all,2090,656.2273016746735,0.0 +R12_PAS,TCE,all,2100,678.0912940281171,0.0 +R12_PAS,TCE,all,2110,644.4452830107269,0.0 +R12_CHN,TCE,all,2035,71.16954123913064,0.0 +R12_CHN,TCE,all,2040,118.3093870686808,0.0 +R12_CHN,TCE,all,2045,178.96386432728616,0.0 +R12_CHN,TCE,all,2050,156.5563443318546,0.0 +R12_CHN,TCE,all,2055,249.30026265150792,0.0 +R12_CHN,TCE,all,2060,351.33416412329206,0.0 +R12_CHN,TCE,all,2070,1256.6719938689396,0.0 +R12_CHN,TCE,all,2080,681.8576121660878,0.0 +R12_CHN,TCE,all,2090,832.090471658559,0.0 +R12_CHN,TCE,all,2100,1197.0993274910345,0.0 +R12_CHN,TCE,all,2110,1854.000470201083,0.0 +R12_RCPA,TCE,all,2035,86.05404913960399,0.0 +R12_RCPA,TCE,all,2040,141.2604436642539,0.0 +R12_RCPA,TCE,all,2045,217.34103674073936,0.0 +R12_RCPA,TCE,all,2050,306.72494481145304,0.0 +R12_RCPA,TCE,all,2055,588.4447013776846,0.0 +R12_RCPA,TCE,all,2060,352.01143511147194,0.0 +R12_RCPA,TCE,all,2070,558.7541010289457,0.0 +R12_RCPA,TCE,all,2080,597.2128565999604,0.0 +R12_RCPA,TCE,all,2090,659.1544278579487,0.0 +R12_RCPA,TCE,all,2100,707.5196545267625,0.0 +R12_RCPA,TCE,all,2110,1150.2790547291677,0.0 diff --git a/message_ix_models/data/transport/R12/price-emission/SSP_SSP2_v6.5_SSP2 - Low Overshoot_v2.csv b/message_ix_models/data/transport/R12/price-emission/SSP_SSP2_v6.5_SSP2 - Low Overshoot_v2.csv new file mode 100644 index 0000000000..d0badf1173 --- /dev/null +++ b/message_ix_models/data/transport/R12/price-emission/SSP_SSP2_v6.5_SSP2 - Low Overshoot_v2.csv @@ -0,0 +1,15 @@ +# Exported using: +# mix-models --url="ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Low Overshoot" transport export-price +# at 2026-04-07T19:30:36.614016 +# +node,type_emission,type_tec,year,lvl,mrg +World,TCE,all,2040,217.81660994945733,0.0 +World,TCE,all,2045,277.9953232847465,0.0 +World,TCE,all,2050,354.8003055695489,0.0 +World,TCE,all,2055,452.82508836778146,0.0 +World,TCE,all,2060,577.9323113212328,0.0 +World,TCE,all,2070,827.1303972767862,0.0 +World,TCE,all,2080,1347.3082597684481,0.0 +World,TCE,all,2090,2194.6231849496917,0.0 +World,TCE,all,2100,3574.809913765749,0.0 +World,TCE,all,2110,5822.98866028376,0.0 diff --git a/message_ix_models/data/transport/R12/price-emission/SSP_SSP2_v6.5_SSP2 - Medium-Low Emissions_v2.csv b/message_ix_models/data/transport/R12/price-emission/SSP_SSP2_v6.5_SSP2 - Medium-Low Emissions_v2.csv new file mode 100644 index 0000000000..038a16ac1b --- /dev/null +++ b/message_ix_models/data/transport/R12/price-emission/SSP_SSP2_v6.5_SSP2 - Medium-Low Emissions_v2.csv @@ -0,0 +1,14 @@ +# Exported using: +# mix-models --url="ixmp://ixmp-dev/SSP_SSP2_v6.5/SSP2 - Medium-Low Emissions" transport export-price +# at 2026-04-07T19:32:18.075825 +# +node,type_emission,type_tec,year,lvl,mrg +World,TCE,all,2045,38.849018814864,0.0 +World,TCE,all,2050,49.58228643462654,0.0 +World,TCE,all,2055,63.28095800310772,0.0 +World,TCE,all,2060,80.76431995670322,0.0 +World,TCE,all,2070,115.58901058647753,0.0 +World,TCE,all,2080,188.28231825883412,0.0 +World,TCE,all,2090,306.6920565290152,0.0 +World,TCE,all,2100,499.5690429554364,0.0 +World,TCE,all,2110,813.7453297744595,0.0 diff --git a/message_ix_models/data/transport/R12/price-emission/SSP_SSP2_v6.6_SSP2 - Medium Emissions_v1.csv b/message_ix_models/data/transport/R12/price-emission/SSP_SSP2_v6.6_SSP2 - Medium Emissions_v1.csv new file mode 100644 index 0000000000..ca1be2aff3 --- /dev/null +++ b/message_ix_models/data/transport/R12/price-emission/SSP_SSP2_v6.6_SSP2 - Medium Emissions_v1.csv @@ -0,0 +1,104 @@ +# Exported using: +# mix-models --url="ixmp://ixmp-dev/SSP_SSP2_v6.6/SSP2 - Medium Emissions" transport export-price +# at 2026-04-07T19:31:26.682604 +# +node,type_emission,type_tec,year,lvl,mrg +R12_AFR,TCE,all,2035,1.116,0.0 +R12_AFR,TCE,all,2040,1.116,0.0 +R12_AFR,TCE,all,2045,1.116,0.0 +R12_AFR,TCE,all,2050,1.116,0.0 +R12_AFR,TCE,all,2055,1.116,0.0 +R12_AFR,TCE,all,2060,1.116,0.0 +R12_AFR,TCE,all,2070,1.116,0.0 +R12_AFR,TCE,all,2080,1.116,0.0 +R12_AFR,TCE,all,2090,1.116,0.0 +R12_AFR,TCE,all,2100,1.116,0.0 +R12_AFR,TCE,all,2110,1.116,0.0 +R12_EEU,TCE,all,2035,200.162,0.0 +R12_EEU,TCE,all,2040,200.162,0.0 +R12_EEU,TCE,all,2045,200.162,0.0 +R12_EEU,TCE,all,2050,200.16199999999998,0.0 +R12_EEU,TCE,all,2055,200.162,0.0 +R12_EEU,TCE,all,2060,200.162,0.0 +R12_EEU,TCE,all,2070,200.162,0.0 +R12_EEU,TCE,all,2080,200.162,0.0 +R12_EEU,TCE,all,2090,200.162,0.0 +R12_EEU,TCE,all,2100,200.162,0.0 +R12_EEU,TCE,all,2110,200.162,0.0 +R12_LAM,TCE,all,2035,29.212,0.0 +R12_LAM,TCE,all,2040,29.212,0.0 +R12_LAM,TCE,all,2045,29.212,0.0 +R12_LAM,TCE,all,2050,29.212000000000003,0.0 +R12_LAM,TCE,all,2055,29.212,0.0 +R12_LAM,TCE,all,2060,29.212,0.0 +R12_LAM,TCE,all,2070,29.212,0.0 +R12_LAM,TCE,all,2080,29.212,0.0 +R12_LAM,TCE,all,2090,29.212,0.0 +R12_LAM,TCE,all,2100,29.212,0.0 +R12_LAM,TCE,all,2110,29.212,0.0 +R12_NAM,TCE,all,2035,155.91,0.0 +R12_NAM,TCE,all,2040,155.91,0.0 +R12_NAM,TCE,all,2045,155.91,0.0 +R12_NAM,TCE,all,2050,155.91,0.0 +R12_NAM,TCE,all,2055,155.91,0.0 +R12_NAM,TCE,all,2060,155.91,0.0 +R12_NAM,TCE,all,2070,155.91,0.0 +R12_NAM,TCE,all,2080,155.91,0.0 +R12_NAM,TCE,all,2090,155.91,0.0 +R12_NAM,TCE,all,2100,155.91,0.0 +R12_NAM,TCE,all,2110,155.91,0.0 +R12_SAS,TCE,all,2035,0.045,0.0 +R12_SAS,TCE,all,2040,0.045,0.0 +R12_SAS,TCE,all,2045,0.045,0.0 +R12_SAS,TCE,all,2050,0.045,0.0 +R12_SAS,TCE,all,2055,0.045,0.0 +R12_SAS,TCE,all,2060,0.045,0.0 +R12_SAS,TCE,all,2070,0.045,0.0 +R12_SAS,TCE,all,2080,0.045,0.0 +R12_SAS,TCE,all,2090,0.045000000000000005,0.0 +R12_SAS,TCE,all,2100,0.045,0.0 +R12_SAS,TCE,all,2110,0.045,0.0 +R12_WEU,TCE,all,2035,252.422,0.0 +R12_WEU,TCE,all,2040,252.42199999999997,0.0 +R12_WEU,TCE,all,2045,252.422,0.0 +R12_WEU,TCE,all,2050,252.422,0.0 +R12_WEU,TCE,all,2055,252.422,0.0 +R12_WEU,TCE,all,2060,252.422,0.0 +R12_WEU,TCE,all,2070,252.422,0.0 +R12_WEU,TCE,all,2080,252.422,0.0 +R12_WEU,TCE,all,2090,252.422,0.0 +R12_WEU,TCE,all,2100,252.422,0.0 +R12_WEU,TCE,all,2110,252.42199999999997,0.0 +R12_PAO,TCE,all,2035,0.094,0.0 +R12_PAO,TCE,all,2040,0.094,0.0 +R12_PAO,TCE,all,2045,0.094,0.0 +R12_PAO,TCE,all,2050,0.09399999999999999,0.0 +R12_PAO,TCE,all,2055,0.094,0.0 +R12_PAO,TCE,all,2060,0.094,0.0 +R12_PAO,TCE,all,2070,0.094,0.0 +R12_PAO,TCE,all,2080,0.094,0.0 +R12_PAO,TCE,all,2090,0.094,0.0 +R12_PAO,TCE,all,2100,0.094,0.0 +R12_PAO,TCE,all,2110,0.094,0.0 +R12_PAS,TCE,all,2035,14.101,0.0 +R12_PAS,TCE,all,2040,14.101,0.0 +R12_PAS,TCE,all,2045,14.101,0.0 +R12_PAS,TCE,all,2050,14.101,0.0 +R12_PAS,TCE,all,2055,14.101,0.0 +R12_PAS,TCE,all,2060,14.101000000000003,0.0 +R12_PAS,TCE,all,2070,14.101,0.0 +R12_PAS,TCE,all,2080,14.101,0.0 +R12_PAS,TCE,all,2090,14.101,0.0 +R12_PAS,TCE,all,2100,14.101,0.0 +R12_PAS,TCE,all,2110,14.100999999999999,0.0 +R12_RCPA,TCE,all,2035,0.023,0.0 +R12_RCPA,TCE,all,2040,0.023,0.0 +R12_RCPA,TCE,all,2045,0.023,0.0 +R12_RCPA,TCE,all,2050,0.023,0.0 +R12_RCPA,TCE,all,2055,0.023,0.0 +R12_RCPA,TCE,all,2060,0.022999999999999996,0.0 +R12_RCPA,TCE,all,2070,0.023,0.0 +R12_RCPA,TCE,all,2080,0.023,0.0 +R12_RCPA,TCE,all,2090,0.023,0.0 +R12_RCPA,TCE,all,2100,0.023,0.0 +R12_RCPA,TCE,all,2110,0.023,0.0 diff --git a/message_ix_models/data/transport/R12/price-emission/SSP_SSP3_v6.5_SSP3 - High Emissions_v2.csv b/message_ix_models/data/transport/R12/price-emission/SSP_SSP3_v6.5_SSP3 - High Emissions_v2.csv new file mode 100644 index 0000000000..de1b880ba9 --- /dev/null +++ b/message_ix_models/data/transport/R12/price-emission/SSP_SSP3_v6.5_SSP3 - High Emissions_v2.csv @@ -0,0 +1,5 @@ +# Exported using: +# mix-models --url="ixmp://ixmp-dev/SSP_SSP3_v6.5/SSP3 - High Emissions" transport export-price +# at 2026-04-07T19:33:58.993258 +# +node,type_emission,type_tec,year,lvl,mrg diff --git a/message_ix_models/data/transport/R12/price-emission/SSP_SSP3_v6.5_SSP3 - Medium-Low Emissions_a_v1.csv b/message_ix_models/data/transport/R12/price-emission/SSP_SSP3_v6.5_SSP3 - Medium-Low Emissions_a_v1.csv new file mode 100644 index 0000000000..5dde1edb59 --- /dev/null +++ b/message_ix_models/data/transport/R12/price-emission/SSP_SSP3_v6.5_SSP3 - Medium-Low Emissions_a_v1.csv @@ -0,0 +1,10 @@ +# Exported using: +# mix-models --url="ixmp://ixmp-dev/SSP_SSP3_v6.5/SSP3 - Medium-Low Emissions_a" transport export-price +# at 2026-04-07T19:34:51.945187 +# +node,type_emission,type_tec,year,lvl,mrg +World,TCE,all,2070,1682.0469667125099,0.0 +World,TCE,all,2080,2739.877266065302,0.0 +World,TCE,all,2090,4462.971356723439,0.0 +World,TCE,all,2100,7269.71006242844,0.0 +World,TCE,all,2110,11841.591658919591,0.0 diff --git a/message_ix_models/data/transport/R12/price-emission/SSP_SSP4_v6.5_SSP4 - High Emissions_v1.csv b/message_ix_models/data/transport/R12/price-emission/SSP_SSP4_v6.5_SSP4 - High Emissions_v1.csv new file mode 100644 index 0000000000..d6e3ff464a --- /dev/null +++ b/message_ix_models/data/transport/R12/price-emission/SSP_SSP4_v6.5_SSP4 - High Emissions_v1.csv @@ -0,0 +1,5 @@ +# Exported using: +# mix-models --url="ixmp://ixmp-dev/SSP_SSP4_v6.5/SSP4 - High Emissions" transport export-price +# at 2026-04-07T19:35:43.226663 +# +node,type_emission,type_tec,year,lvl,mrg diff --git a/message_ix_models/data/transport/R12/price-emission/SSP_SSP4_v6.5_SSP4 - Low Overshoot_v2.csv b/message_ix_models/data/transport/R12/price-emission/SSP_SSP4_v6.5_SSP4 - Low Overshoot_v2.csv new file mode 100644 index 0000000000..dc4599e71a --- /dev/null +++ b/message_ix_models/data/transport/R12/price-emission/SSP_SSP4_v6.5_SSP4 - Low Overshoot_v2.csv @@ -0,0 +1,15 @@ +# Exported using: +# mix-models --url="ixmp://ixmp-dev/SSP_SSP4_v6.5/SSP4 - Low Overshoot" transport export-price +# at 2026-04-07T19:36:33.741874 +# +node,type_emission,type_tec,year,lvl,mrg +World,TCE,all,2040,146.23157631247022,0.0 +World,TCE,all,2045,186.6326647029175,0.0 +World,TCE,all,2050,238.1958289205782,0.0 +World,TCE,all,2055,304.0049447157383,0.0 +World,TCE,all,2060,387.99590584952864,0.0 +World,TCE,all,2070,555.2954930196108,0.0 +World,TCE,all,2080,904.5178448533748,0.0 +World,TCE,all,2090,1473.3642573059742,0.0 +World,TCE,all,2100,2399.9551220116377,0.0 +World,TCE,all,2110,3909.2740027517575,0.0 diff --git a/message_ix_models/data/transport/R12/price-emission/SSP_SSP5_v6.5_SSP5 - High Emissions_v2.csv b/message_ix_models/data/transport/R12/price-emission/SSP_SSP5_v6.5_SSP5 - High Emissions_v2.csv new file mode 100644 index 0000000000..6fba054c16 --- /dev/null +++ b/message_ix_models/data/transport/R12/price-emission/SSP_SSP5_v6.5_SSP5 - High Emissions_v2.csv @@ -0,0 +1,5 @@ +# Exported using: +# mix-models --url="ixmp://ixmp-dev/SSP_SSP5_v6.5/SSP5 - High Emissions" transport export-price +# at 2026-04-07T19:37:23.616510 +# +node,type_emission,type_tec,year,lvl,mrg diff --git a/message_ix_models/data/transport/R12/price-emission/SSP_SSP5_v6.5_SSP5 - Low Overshoot_v2.csv b/message_ix_models/data/transport/R12/price-emission/SSP_SSP5_v6.5_SSP5 - Low Overshoot_v2.csv new file mode 100644 index 0000000000..7a51983e76 --- /dev/null +++ b/message_ix_models/data/transport/R12/price-emission/SSP_SSP5_v6.5_SSP5 - Low Overshoot_v2.csv @@ -0,0 +1,15 @@ +# Exported using: +# mix-models --url="ixmp://ixmp-dev/SSP_SSP5_v6.5/SSP5 - Low Overshoot" transport export-price +# at 2026-04-07T19:38:15.358906 +# +node,type_emission,type_tec,year,lvl,mrg +World,TCE,all,2040,671.1788403289141,0.0 +World,TCE,all,2045,856.6131790519247,0.0 +World,TCE,all,2050,1093.2796066184828,0.0 +World,TCE,all,2055,1395.332604584423,0.0 +World,TCE,all,2060,1780.8372767862022,0.0 +World,TCE,all,2070,2548.7148155223163,0.0 +World,TCE,all,2080,4151.5878681923605,0.0 +World,TCE,all,2090,6762.499171092952,0.0 +World,TCE,all,2100,11015.398563380215,0.0 +World,TCE,all,2110,17942.92353170199,0.0 diff --git a/message_ix_models/data/transport/R12/price-emission/SSP_SSP5_v6.5_SSP5 - Medium-Low Emissions_a_v1.csv b/message_ix_models/data/transport/R12/price-emission/SSP_SSP5_v6.5_SSP5 - Medium-Low Emissions_a_v1.csv new file mode 100644 index 0000000000..2a513d992d --- /dev/null +++ b/message_ix_models/data/transport/R12/price-emission/SSP_SSP5_v6.5_SSP5 - Medium-Low Emissions_a_v1.csv @@ -0,0 +1,10 @@ +# Exported using: +# mix-models --url="ixmp://ixmp-dev/SSP_SSP5_v6.5/SSP5 - Medium-Low Emissions_a" transport export-price +# at 2026-04-07T19:39:06.461627 +# +node,type_emission,type_tec,year,lvl,mrg +World,TCE,all,2070,157.05140601954372,0.0 +World,TCE,all,2080,255.8201913930772,0.0 +World,TCE,all,2090,416.7041351813603,0.0 +World,TCE,all,2100,678.7671267528586,0.0 +World,TCE,all,2110,1105.6401256008944,0.0 diff --git a/message_ix_models/data/transport/R14/activity-vehicle.csv b/message_ix_models/data/transport/R14/activity-vehicle.csv new file mode 100644 index 0000000000..00052d13c8 --- /dev/null +++ b/message_ix_models/data/transport/R14/activity-vehicle.csv @@ -0,0 +1,49 @@ +# Activity (driving distance) per light-duty vehicle +# +# Source: duplicate of R11/ldv-activity.csv; see comments there. The +# value for R11_FSU is repeated for R14_{CAS,RUS,SCS,UBM}. +# +# Unit: kilometre / year +# +scenario, technology, node, year, value +*, LDV, R14_AFR, 2020, 10391 +*, LDV, R14_AFR, 2110, 10391 +*, LDV, R14_CPA, 2020, 16000 +*, LDV, R14_CPA, 2110, 16000 +*, LDV, R14_EEU, 2020, 8962 +*, LDV, R14_EEU, 2110, 8962 +*, LDV, R14_LAM, 2020, 14600 +*, LDV, R14_LAM, 2110, 14600 +*, LDV, R14_MEA, 2020, 14000 +*, LDV, R14_MEA, 2110, 14000 +*, LDV, R14_NAM, 2020, 25860 +*, LDV, R14_NAM, 2110, 25860 +*, LDV, R14_PAO, 2020, 10000 +*, LDV, R14_PAO, 2110, 10000 +*, LDV, R14_PAS, 2020, 12000 +*, LDV, R14_PAS, 2110, 12000 +*, LDV, R14_RUS, 2020, 11482 +*, LDV, R14_RUS, 2110, 11482 +*, LDV, R14_SAS, 2020, 10400 +*, LDV, R14_SAS, 2110, 10400 +*, LDV, R14_WEU, 2020, 11646 +*, LDV, R14_WEU, 2110, 11646 +*, LDV, R14_CAS, 2020, 11482 +*, LDV, R14_CAS, 2110, 11482 +*, LDV, R14_SCS, 2020, 11482 +*, LDV, R14_SCS, 2110, 11482 +*, LDV, R14_UBM, 2020, 11482 +*, LDV, R14_UBM, 2110, 11482 + +*, AIR, *, 2020, 10000 +*, AIR, *, 2110, 10000 +*, 2W, *, 2020, 10000 +*, 2W, *, 2110, 10000 +*, BUS, *, 2020, 10000 +*, BUS, *, 2110, 10000 +*, P RAIL, *, 2020, 10000 +*, P RAIL, *, 2110, 10000 +*, F RAIL, *, 2020, 10000 +*, F RAIL, *, 2110, 10000 +*, F ROAD, *, 2020, 10000 +*, F ROAD, *, 2110, 10000 diff --git a/message_ix_models/data/transport/R14/freight-activity.csv b/message_ix_models/data/transport/R14/freight-activity.csv index 8cd66594a2..2948b8d576 100644 --- a/message_ix_models/data/transport/R14/freight-activity.csv +++ b/message_ix_models/data/transport/R14/freight-activity.csv @@ -5,7 +5,7 @@ # - Duplicated manually from the corresponding R11 file. # - Data for R11_FSU split evenly across R14_{CAS,RUS,SCS,UBM}. # -# Units: Gt km +# Units: Gt km / a # node, value R14_AFR, 1210.1 diff --git a/message_ix_models/data/transport/R14/ldv-activity.csv b/message_ix_models/data/transport/R14/ldv-activity.csv deleted file mode 100644 index 27cd475809..0000000000 --- a/message_ix_models/data/transport/R14/ldv-activity.csv +++ /dev/null @@ -1,36 +0,0 @@ -# Activity (driving distance) per light-duty vehicle -# -# Source: duplicate of R11/ldv-activity.csv; see comments there. The -# value for R11_FSU is repeated for R14_{CAS,RUS,SCS,UBM}. -# -# Unit: kilometre / year -# -scenario, node, year, value -*, R14_AFR, 2020, 10391 -*, R14_AFR, 2110, 10391 -*, R14_CPA, 2020, 16000 -*, R14_CPA, 2110, 16000 -*, R14_EEU, 2020, 8962 -*, R14_EEU, 2110, 8962 -*, R14_LAM, 2020, 14600 -*, R14_LAM, 2110, 14600 -*, R14_MEA, 2020, 14000 -*, R14_MEA, 2110, 14000 -*, R14_NAM, 2020, 25860 -*, R14_NAM, 2110, 25860 -*, R14_PAO, 2020, 10000 -*, R14_PAO, 2110, 10000 -*, R14_PAS, 2020, 12000 -*, R14_PAS, 2110, 12000 -*, R14_RUS, 2020, 11482 -*, R14_RUS, 2110, 11482 -*, R14_SAS, 2020, 10400 -*, R14_SAS, 2110, 10400 -*, R14_WEU, 2020, 11646 -*, R14_WEU, 2110, 11646 -*, R14_CAS, 2020, 11482 -*, R14_CAS, 2110, 11482 -*, R14_SCS, 2020, 11482 -*, R14_SCS, 2110, 11482 -*, R14_UBM, 2020, 11482 -*, R14_UBM, 2110, 11482 diff --git a/message_ix_models/data/transport/R14/load-factor-ldv/SSP_2024_2.csv b/message_ix_models/data/transport/R14/load-factor-ldv/SSP_2024_2.csv index 0530ef8294..d297b5d8a5 100644 --- a/message_ix_models/data/transport/R14/load-factor-ldv/SSP_2024_2.csv +++ b/message_ix_models/data/transport/R14/load-factor-ldv/SSP_2024_2.csv @@ -5,6 +5,8 @@ # - Duplicated manually from the corresponding R11 file. # - Data for R11_FSU duplicated for R14_{CAS,RUS,SCS,UBM}. # +# Units: passenger / vehicle +# scenario, node, year, value SSP(2024).2, R14_AFR, 2020, 1.807 SSP(2024).2, R14_CAS, 2020, 1.807 diff --git a/message_ix_models/data/transport/constraint-dynamic.csv b/message_ix_models/data/transport/constraint-dynamic.csv index 112bef7ef7..c35c9ffc5a 100644 --- a/message_ix_models/data/transport/constraint-dynamic.csv +++ b/message_ix_models/data/transport/constraint-dynamic.csv @@ -49,8 +49,8 @@ ICE_L_ptrp, *, growth_new_capacity_up, 0.0192 # mode. LDV, *, initial_new_capacity_up, 10.0 -LDV usage, *, growth_activity_up, 0.0539 -LDV usage, *, initial_activity_up, 1000000 +usage LDV, *, growth_activity_up, 0.0539 +usage LDV, *, initial_activity_up, 1000000 P ex LDV, *, growth_activity_lo, -0.0192 P ex LDV, electr, growth_activity_lo, 0.0 diff --git a/message_ix_models/data/transport/lifetime-ldv.csv b/message_ix_models/data/transport/lifetime-ldv.csv deleted file mode 100644 index e0d4a339ff..0000000000 --- a/message_ix_models/data/transport/lifetime-ldv.csv +++ /dev/null @@ -1,7 +0,0 @@ -# Technical lifetime (maximum age) of LDVs -# -# Units: year -# -scenario, node_loc, technology, year_vtg, value -*, *, *, 1960, 15 -*, *, *, 2110, 15 diff --git a/message_ix_models/data/transport/lifetime.csv b/message_ix_models/data/transport/lifetime.csv new file mode 100644 index 0000000000..177ba0bdb8 --- /dev/null +++ b/message_ix_models/data/transport/lifetime.csv @@ -0,0 +1,7 @@ +# Technical lifetime (maximum age) of vehicles +# +# Units: year +# +scenario, technology, node_loc, year_vtg, value +*, *, *, 1960, 15 +*, *, *, 2110, 15 diff --git a/message_ix_models/data/transport/load-factor-f.csv b/message_ix_models/data/transport/load-factor-f.csv new file mode 100644 index 0000000000..31ced11610 --- /dev/null +++ b/message_ix_models/data/transport/load-factor-f.csv @@ -0,0 +1,9 @@ +# Load factor of freight vehicles +# +# Units: tonne / vehicle +# +# Source: placeholder +# +technology, value +F RAIL, 1.0 +F ROAD, 1.0 diff --git a/message_ix_models/data/transport/load-factor-nonldv.csv b/message_ix_models/data/transport/load-factor-p.csv similarity index 59% rename from message_ix_models/data/transport/load-factor-nonldv.csv rename to message_ix_models/data/transport/load-factor-p.csv index f515cb530f..1ce93ba8d5 100644 --- a/message_ix_models/data/transport/load-factor-nonldv.csv +++ b/message_ix_models/data/transport/load-factor-p.csv @@ -1,4 +1,4 @@ -# Load factor (occupancy) of non-LDV vehicles +# Load factor (occupancy) of passenger vehicles except LDVs # # Source: transcribed from MESSAGE (V) Transport .chn files # Original source unknown. @@ -7,8 +7,8 @@ # technology, value # Urban public rail transport (agg. of metro, trams, regional trains, etc.) -# rail_pub,80 -2W,1.0 -RAIL,200 -AIR,115 -BUS,20.9 +# rail_pub, 80 +2W, 1.0 +RAIL, 200 +AIR, 115 +BUS, 20.9 diff --git a/message_ix_models/data/transport/set.yaml b/message_ix_models/data/transport/set.yaml index 5215664259..898b274669 100644 --- a/message_ix_models/data/transport/set.yaml +++ b/message_ix_models/data/transport/set.yaml @@ -226,6 +226,7 @@ unit: Gp / Gv: passengers per vehicle Gt km: 10⁹ tonne-kilometre Gt * km: 10⁹ tonne-kilometre + Gt * km / a: 10⁹ tonne-kilometre per year Gv km: 10⁹ vehicle kilometre Gv * km: 10⁹ vehicle kilometre Mm / a: 10³ kilometre per year @@ -255,6 +256,9 @@ unit: # tax_emission USD / t: USD per tonne carbon-equivalent; same as "USD/tC" + # Transport—Materials integration + Mt / Mv: megatonne of material per 10⁶ vehicles + # MA3T sets census_division: add: diff --git a/message_ix_models/data/transport/technology.yaml b/message_ix_models/data/transport/technology.yaml index 340d454c21..bb56c0a643 100644 --- a/message_ix_models/data/transport/technology.yaml +++ b/message_ix_models/data/transport/technology.yaml @@ -21,7 +21,7 @@ # # - 'input': same as in message-ix-models: mapping including 'commodity' and/or # 'level' keys indicating the technology's inputs. -# - 'message-v-report': these appeared in the US-TIMES–MA³T input data, but were +# - 'message-v-id': these appeared in the US-TIMES–MA³T input data, but were # apparently not used in MESSAGE-(V)-Transport. # - 'report': are picked up by add_replacements() for reporting. @@ -30,175 +30,220 @@ ELC_100: description: >- Battery-electric light-duty vehicle using electricity only (100-mile all-electric range) - report: BEV input: {commodity: electr} - message-v-report: LDV_ELE + report: Light-Duty Vehicle|Battery-Electric + message-v-id: LDV_ELE + ntnu-vmi-technology: BEV gfei-2017-technology: Electric HFC_ptrp: - report: FCEV + name: Hydrogen fuel cell LDV description: Hybridized fuel cell light-duty vehicle using hydrogen input: {commodity: hydrogen} - message-v-report: LDV_HFC + report: Light-Duty Vehicle|Fuel-Cell-Electric + message-v-id: LDV_HFC + ntnu-vmi-technology: ICE gfei-2017-technology: Hydrogen IAHe_ptrp: - report: Biofuel hybrid + name: Biofuel hybrid LDV description: >- Hybridized internal combustion engine light-duty vehicle using biofuels input: {commodity: ethanol} - message-v-report: LDV_EHYB + report: Light-Duty Vehicle|Biofuel hybrid + message-v-id: LDV_EHYB + ntnu-vmi-technology: ICE IAHm_ptrp: - report: Methanol hybrid + name: Methanol hybrid LDV description: >- Hybridized internal combustion engine light-duty vehicle using methanol/ synthetic fossil liquids input: {commodity: methanol} - message-v-report: LDV_MHYB + report: Light-Duty Vehicle|Methanol hybrid + message-v-id: LDV_MHYB + ntnu-vmi-technology: ICE ICAe_ffv: - report: Biofuel ICEV + name: Biofuel ICE LDV description: >- Internal combustion engine light-duty vehicle using biofuels. Although real-world flex-fuel vehicles are run on varying mix of ethanol and lightoil, this technology uses only ethanol. input: {commodity: ethanol} - message-v-report: LDV_ffv + report: Light-Duty Vehicle|Biofuel + message-v-id: LDV_ffv + ntnu-vmi-technology: ICE gfei-2017-technology: Diesel ICAm_ptrp: - report: Synfuel ICEV + name: Synfuel ICE LDV description: >- Internal combustion engine light-duty vehicle using methanol/synthetic fossil liquids input: {commodity: methanol} - message-v-report: LDV_meth + report: Light-Duty Vehicle|Synfuel + message-v-id: LDV_meth + ntnu-vmi-technology: ICE gfei-2017-technology: Flexfuel ICE_conv: - report: ICEV + report: ICE LDV description: >- Future (2005 and after) medium/high-efficiency internal combustion engine light-duty vehicle using gasoline/diesel input: {commodity: lightoil} - message-v-report: LDV_conv + report: Light-Duty Vehicle|Light oil combustion + message-v-id: LDV_conv + ntnu-vmi-technology: ICE gfei-2017-technology: Petrol ICE_L_ptrp: - report: ICEV (pre-2005) + name: ICE LDV (pre-2005) description: >- Historical (2005 and before) Low-efficiency internal combustion engine light-duty vehicle using gasoline/diesel input: {commodity: lightoil} + report: Light-Duty Vehicle|Light oil combustion (2005 and before) historical-only: True - message-v-report: LDV_ICE_L + message-v-id: LDV_ICE_L + ntnu-vmi-technology: ICE ICE_nga: - report: Gas ICEV + name: Gas ICE LDVV description: >- Internal combustion engine light-duty vehicle using natural gas input: {commodity: gas} - message-v-report: LDV_NGA + report: Light-Duty Vehicle|Gas combustion + message-v-id: LDV_NGA gfei-2017-technology: [CNG, LPG] + ntnu-vmi-technology: ICE ICH_chyb: - report: Hybrid + name: Hybrid LDV description: >- Hybridized internal combustion engine light-duty vehicle using gasoline/diesel input: {commodity: lightoil} - message-v-report: LDV_CHYB + report: Light-Duty Vehicle|Light-oil hybrid + message-v-id: LDV_CHYB + ntnu-vmi-technology: ICE gfei-2017-technology: Hybrid IGH_ghyb: - report: Gas hybrid + name: Gas hybrid LDV description: >- Hybridized internal combustion engine light-duty vehicle using natural gas input: {commodity: gas} - message-v-report: LDV_GHYB + report: Light-Duty Vehicle|Gas hybrid + message-v-id: LDV_GHYB + ntnu-vmi-technology: ICE PHEV_ptrp: - report: PHEV + report: PHE LDV description: >- Plug-in hybrid-electric light-duty vehicle using gasoline/diesel (40-mile all-electric range) input: {commodity: [electr, lightoil]} - message-v-report: LDV_PHEV + report: Light-Duty Vehicle|Plug-in Hybrid + message-v-id: LDV_PHEV + ntnu-vmi-technology: PHEV gfei-2017-technology: Plug-in ICE_H_moto: - report: ICEV + name: ICE 2- and 3-wheeler description: >- High-efficiency internal combustion engine two-wheeler/motorcycle using gasoline/diesel input: {commodity: lightoil} - report: 2W_ICE_H + report: 2W|Combustion + message-v-id: 2W_ICE_H ELE_moto: - report: BEV + name: Battery-electric 2- and 3-wheeler description: >- Battery-electric two-wheeler/motorcycle using electricity-only input: {commodity: electr} - report: 2W_ELE + report: 2W|Battery-electric + message-v-id: 2W_ELE ICE_H_bus: + name: High-efficiency internal combustion bus description: High-efficiency internal combustion engine bus using gasoline/diesel input: {commodity: lightoil} - report: BUS_ICE_H + report: Bus|Combustion light oil high efficiency + message-v-id: BUS_ICE_H ICE_M_bus: + name: Medium-efficiency internal combustion bus description: >- Medium-efficiency internal combustion engine bus using gasoline/diesel input: {commodity: lightoil} - report: BUS_ICE_M + report: Bus|Combustion light oil + message-v-id: BUS_ICE_M ICG_bus: + name: Natural gas bus description: Internal combustion engine bus using natural gas input: {commodity: gas} - report: BUS_ICG + report: Bus|Combustion gas + message-v-id: BUS_ICG ICAe_bus: + name: Biofuel bus description: Internal combustion engine bus using biofuels input: {commodity: ethanol} - report: BUS_ICAe + report: Bus|Combustion biofuel + message-v-id: BUS_ICAe ICH_bus: + name: Hybridized internal combustion bus description: >- Hybridized internal combustion engine bus using gasoline/diesel input: {commodity: lightoil} # hybridized, but not plug-in, so only oil input - report: BUS_ICH + report: Bus|Hybrid combustion + message-v-id: BUS_ICH FC_bus: + name: Hybridized hydrogen fuel cell bus description: Hybridized fuel cell bus using hydrogen input: {commodity: hydrogen} - report: BUS_HFC + report: Bus|Hybrid fuel cell hydrogen + message-v-id: BUS_HFC FCg_bus: + name: Hybridized natural gas fuel cell bus description: >- Hybridized fuel cell bus using natural gas via steam reformation input: {commodity: gas} - report: BUS_GFC + report: Bus|Hybrid fuel cell gas + message-v-id: BUS_GFC FCm_bus: + name: Hybridized synfuel cell bus description: >- Hybridized fuel cell bus using methanol/synthetic fossil liquids via steam reformation input: {commodity: methanol} - report: BUS_MFC + report: Bus|Hybrid fuel cell synfuel + message-v-id: BUS_MFC Trolley_bus: + name: Electric trolley-bus description: Electric trolleybus connected to power cables input: {commodity: electr} - report: BUS_ELEtr + report: Bus|Trolley + message-v-id: BUS_ELEtr PHEV_bus: + name: Plug-in hybrid-electric bus description: Plug-in hybrid-electric bus using gasoline/diesel input: commodity: [electr, lightoil] - report: BUS_PHEV + report: Bus|Plug-in Hybrid + message-v-id: BUS_PHEV # BEV_bus: # description: Battery-electric bus using electricity only @@ -206,102 +251,126 @@ PHEV_bus: # report: BUS_BEV con_ar: + name: Kerosene aircraft description: >- Conventional jet engine passenger aircraft using light oil petroleum products (kerosene jet fuel) input: {commodity: lightoil} - report: AIRp_JF + report: Air|Kerosene + message-v-id: AIRp_JF conh_ar: + name: Hydrogen aircraft description: Conventional jet engine passenger aircraft using hydrogen input: {commodity: hydrogen} - report: AIRp_H2 + report: Air|Hydrogen + message-v-id: AIRp_H2 conm_ar: + name: Synfuel aircraft description: >- Conventional jet engine passenger aircraft using methanol/synthetic fossil liquids input: {commodity: methanol} - report: AIRp_MET + report: Air|Synfuel + message-v-id: AIRp_MET conE_ar: + name: Biofuel aircraft description: Conventional jet engine passenger aircraft using biofuels input: {commodity: ethanol} - report: AIRp_BIO + report: Air|Biofuel + message-v-id: AIRp_BIO FR_ICE_H: + name: High-efficiency light oil truck description: >- High-efficiency internal combustion engine freight truck using gasoline/diesel input: {commodity: lightoil, level: final} - report: FRT_ICE_H + report: Truck|Combustion light oil high efficiency + message-v-id: FRT_ICE_H FR_ICE_M: + name: Medium-efficiency light oil truck description: >- Medium-efficiency internal combustion engine freight truck using gasoline/diesel input: {commodity: lightoil} - report: FRT_ICE_M + report: Truck|Combustion light oil medium efficiency + message-v-id: FRT_ICE_M FR_ICE_L: + name: Low-efficiency light oil truck description: >- Low-efficiency internal combustion engine freight truck using gasoline/diesel input: {commodity: lightoil} - report: FRT_ICE_L + report: Truck|Combustion light oil low efficiency + message-v-id: FRT_ICE_L FR_ICAe: + name: Biofuel truck description: Internal combustion engine freight truck using biofuels input: {commodity: ethanol} - report: FRT_ICAe + report: Truck|Biofuel + message-v-id: FRT_ICAe FR_ICH: + name: Hybrid ICE truck description: >- Hybridized internal combustion engine freight truck using gasoline/diesel input: {commodity: lightoil} - report: FRT_ICH + report: Truck|Hybrid combustion + message-v-id: FRT_ICH FR_FCH: + name: Fuel cell truck description: Hybridized fuel cell freight truck using hydrogen input: {commodity: hydrogen} - report: FRT_HFC + report: Truck|Fuel cell hydrogen + message-v-id: FRT_HFC f road electr: name: Freight road vehicle powered by electricity input: {commodity: electr} + report: Truck|Battery-Electric f road gas fc: + name: Gas fuel cell truck description: >- Hybridized fuel cell freight truck using natural gas via steam reformation. Previous ID: FR_FCg. input: {commodity: gas} - report: FRT_GFC + report: Truck|Fuel cell gas + message-v-id: FRT_GFC f road gas ic: - description: >- - Internal combustion engine freight truck using natural gas. - - Previous ID: FR_ICG. + name: Gas combustion truck + description: Internal combustion engine freight truck using natural gas. input: {commodity: gas} - report: FRT_ICG + report: Truck|Gas combustion + message-v-id: [FR_ICG, FRT_ICG] f road methanol: + name: Synfuel truck description: >- Hybridized fuel cell freight truck using methanol/synthetic fossil liquids via steam reformation. - - Previous ID: FR_FCm input: {commodity: methanol} - report: FRT_MFC + report: Truck|Fuel cell synfuel + message-v-id: [FR_FCm, FRT_MFC] f rail electr: name: Freight rail powered by electricity input: {commodity: electr} + report: Rail|Freight|Electric f rail lightoil: name: Freight rail powered by light oil input: {commodity: lightoil} + report: Rail|Freight|Combustion F RAIL: name: Freight rail @@ -310,40 +379,47 @@ F RAIL: - f rail lightoil units: Gv km output: {commodity: transport F RAIL vehicle, level: useful} + report: Rail|Freight iea-eweb-flow: [RAIL] crail_pub: + name: Coal train description: >- Coal-powered urban public rail transport: aggregate of metro/underground, streetcars/trams, commuter trains, and regional trains - report: RAIL_urban_COAL + name: Passenger|Rail|Coal dMspeed_rai: + name: Diesel train description: Diesel-powered long-distance medium-speed rail transport input: {commodity: lightoil} - report: RAIL_ldm_DSL + report: Passenger|Rail|Diesel drail_pub: + name: Diesel urban train description: Diesel-powered urban public rail transport input: {commodity: lightoil} - report: RAIL_urban_DSL + report: Passenger|Rail|Diesel urban Hspeed_rai: + name: Electric high-speed train description: Electrically-powered long-distance high-speed rail transport input: {commodity: electr} - report: RAIL_ldh_ELE + report: Passenger|Rail|Electric high-speed Mspeed_rai: + name: Electric train description: Electrically-powered long-distance medium-speed rail transport input: {commodity: electr} - report: RAIL_ldm_ELE + report: Passenger|Rail|Electric rail_pub: + name: Electric urban train description: >- Electrically-powered urban public rail transport: aggregate of metro/ underground, streetcars/trams, commuter trains, and regional trains input: {commodity: electr} - report: RAIL_urban_ELE + report: Passenger|Rail|Electric urban transport F RAIL usage: description: >- @@ -488,6 +564,7 @@ AIR: BUS: name: Urban public transit + report: Bus description: >- Buses and other forms of urban public transit. diff --git a/message_ix_models/model/transport/base.py b/message_ix_models/model/transport/base.py index ccf77173f0..d2d6371e69 100644 --- a/message_ix_models/model/transport/base.py +++ b/message_ix_models/model/transport/base.py @@ -13,8 +13,7 @@ from message_ix_models.util import minimum_version -from .key import gdp_exo -from .key import report as k_report +from . import key as K from .util import EXTRAPOLATE if TYPE_CHECKING: @@ -203,7 +202,7 @@ def prepare_reporter(rep: "message_ix.Reporter") -> str: # below added to the list rep.add(TARGET, []) # Add this result key to the list of all reporting keys - rep.graph[k_report.all].append(TARGET) + rep.graph[K.report.all] += (TARGET,) # Create output subdirectory for base model files rep.graph["config"]["output_dir"].joinpath("base").mkdir( @@ -214,7 +213,7 @@ def prepare_reporter(rep: "message_ix.Reporter") -> str: e_iea = Key("energy:n-y-product-flow:iea") e_fnp = Key(e_iea.drop("y")) e_cnlt = Key("energy:c-nl-t:iea+0") - k = Key("in:nl-t-ya-c-l-h:transport+units") # MESSAGE solution values + k = Key("in:nl-t-ya-c-l-h:T") # MESSAGE solution values # First period y0 = rep.get("y0") @@ -302,7 +301,9 @@ def prepare_reporter(rep: "message_ix.Reporter") -> str: ) # Compute for file and plot: transport final energy intensity of GDP PPP - k_gdp = rep.add("gdp:nl-ya", "rename_dims", gdp_exo, quote({"n": "nl", "y": "ya"})) + k_gdp = rep.add( + "gdp:nl-ya", "rename_dims", K.gdp_exo, name_dict={"n": "nl", "y": "ya"} + ) k_fei = single_key(rep.add("fe intensity", "div", k["s2"] / tuple("chlt"), k_gdp)) rep.add(k_fei + "units", "convert_units", k_fei, units="MJ / USD") rep.apply(to_csv, k_fei + "units", name="fe intensity") diff --git a/message_ix_models/model/transport/build.py b/message_ix_models/model/transport/build.py index 481da014ea..7f658465a4 100644 --- a/message_ix_models/model/transport/build.py +++ b/message_ix_models/model/transport/build.py @@ -27,9 +27,10 @@ from message_ix_models.util._logging import mark_time from message_ix_models.util.graphviz import HAS_GRAPHVIZ -from . import Config, key, plot +from . import Config, plot +from . import key as K from .operator import indexer_scenario -from .structure import get_technology_groups +from .structure import get_commodity_groups, get_technology_groups if TYPE_CHECKING: from typing import TypedDict @@ -72,13 +73,13 @@ def add_debug(c: Computer) -> None: c.add(e.cnlt, "rename_dims", e.fnp[1], quote(dict(flow="t", n="nl", product="c"))) # Write some intermediate calculations from the build process to file - k_debug = copy(key.debug) # Make a copy so the original does not collect .generated + k_debug = copy(K.debug) # Make a copy so the original does not collect .generated for i, (k, stem) in enumerate( ( - (key.gdp_cap, "gdp-ppp-cap"), - (key.pdt_nyt, "pdt"), - (key.pdt_nyt + "capita+post", "pdt-cap"), - (key.ms, "mode-share"), + (K.gdp_cap, "gdp-ppp-cap"), + (K.pdt_nyt, "pdt"), + (K.pdt_nyt + "capita+post", "pdt-cap"), + (K.ms, "mode-share"), (e.fnp[0], "energy-iea-0"), (e.cnlt, "energy-iea-1"), ) @@ -135,7 +136,6 @@ def add_exogenous_data(c: Computer, info: ScenarioInfo) -> None: from message_ix_models.tools.iea.web import IEA_EWEB, TRANSFORM from message_ix_models.util.sdmx import Dataflow - # Ensure that the MERtoPPP data provider is available from . import data # Added keys @@ -170,6 +170,12 @@ def add_exogenous_data(c: Computer, info: ScenarioInfo) -> None: for kw in source_kw: keys[kw["measure"]] = cls.add_tasks(c, source=config.ssp.urn, **kw, **c_s) + # Miscellaneous data + kw = dict(nodes=context.model.regions, config=config) + data.ActivityVehicle.add_tasks(c, **kw, **c_s) + data.Lifetime.add_tasks(c, **kw, **c_s) + data.LoadFactorLDV.add_tasks(c, **kw, **c_s) + # Add data for MERtoPPP kw = dict(measure="MERtoPPP", nodes=context.model.regions) data.MERtoPPP.add_tasks(c, **kw, **c_s) @@ -205,10 +211,10 @@ def add_exogenous_data(c: Computer, info: ScenarioInfo) -> None: if False: pass # Solved scenario that already has this key else: - c.add(key.GDP, keys["GDP"][0]) + c.add(K.GDP, keys["GDP"][0]) # Ensure correct units - c.add(key.pop, "mul", "pop:n-y", genno.Quantity(1.0, units="passenger")) + c.add(K.pop, "mul", "pop:n-y", genno.Quantity(1.0, units="passenger")) # FIXME Adjust to derive PRICE_COMMODITY c=transport from solved scenario with # MESSAGEix-Transport detail, then uncomment the following line @@ -216,10 +222,10 @@ def add_exogenous_data(c: Computer, info: ScenarioInfo) -> None: if False: # Alias PRICE_COMMODITY:… to PRICE_COMMODITY:*:transport, e.g. solved scenario # that already has this key - c.add(key.price[0], key.price.base - "transport") + c.add(K.price[0], K.price.base - "transport") else: # Not solved scenario → dummy prices - c.add(key.price[0], "dummy_prices", keys["GDP"][0], sums=True) + c.add(K.price[0], "dummy_prices", keys["GDP"][0], sums=True) # Data from files @@ -236,10 +242,6 @@ def add_exogenous_data(c: Computer, info: ScenarioInfo) -> None: for _, f in filter(lambda x: x[1].intent & Dataflow.FLAG.IN, data.iter_files()): c.add("", f, context=context) - data.LoadFactorLDV.add_tasks( - c, context=context, strict=False, nodes=context.model.regions, config=config - ) - #: :mod:`genno` tasks for model structure information that are 'static'—that is, do not #: change based on :class:`~.transport.config.Config` settings. See @@ -270,7 +272,7 @@ def add_exogenous_data(c: Computer, info: ScenarioInfo) -> None: #: See :func:`.nodes_world_agg`. STRUCTURE_STATIC: tuple[tuple, ...] = ( ("add transport data", []), - (key.report.all, []), + (K.report.all, "summarize"), ("info", lambda c: c.transport.base_model_info, "context"), ( "transport info", @@ -278,26 +280,22 @@ def add_exogenous_data(c: Computer, info: ScenarioInfo) -> None: "context", ), ( - key.demand_base, + K.demand_base, partial(data_for_quantity, "par", "demand", "value"), "scenario", "config", ), ("dry_run", lambda c: c.core.dry_run, "context"), ("e::codelist", partial(get_codelist, "emission")), - ("groups::iea eweb", "groups_iea_eweb", "t::transport"), + ("groups::iea eweb", "groups_iea_eweb", K.t), ("groups::iea to transport", itemgetter(0), "groups::iea eweb"), ("groups::transport to iea", itemgetter(1), "groups::iea eweb"), ("indexers::iea to transport", itemgetter(2), "groups::iea eweb"), ("indexers:scenario", partial(indexer_scenario, with_LED=False), "config"), ("indexers:scenario:LED", partial(indexer_scenario, with_LED=True), "config"), - ("indexers::usage", "indexers_usage", "t::transport"), - ("n::ex world", "nodes_ex_world", "n"), - ( - "n:n:ex world", - lambda n: genno.Quantity([1.0] * len(n), coords={"n": n}), - "n::ex world", - ), + ("indexers::usage", "indexers_usage", K.t), + (K.n, "nodes_ex_world", "n"), + ("n:n:ex world", lambda n: genno.Quantity([1.0] * len(n), coords={"n": n}), K.n), ("n::ex world+code", "nodes_ex_world", "nodes"), ("nl::world agg", "nodes_world_agg", "config"), ("scenario::all", "scenario_codes"), @@ -359,6 +357,7 @@ def add_structure(c: Computer) -> None: config: "Config" = c.graph["context"].transport # .model.transport.Config object info = config.base_model_info # ScenarioInfo describing the base scenario spec = config.spec # Specification for MESSAGEix-Transport structure to be built + c_groups = get_commodity_groups(spec) # Commodity groups/hierarchy t_groups = get_technology_groups(spec) # Technology groups/hierarchy # Update RENAME_DIMS with transport-specific concepts/dimensions. This allows to use @@ -384,7 +383,7 @@ def add_structure(c: Computer) -> None: "cat_year", pd.DataFrame([["firstmodelyear", info.y0]], columns=["type_year", "year"]), ), - (key.y, "model_periods", "y", "cat_year"), + (K.y, "model_periods", "y", "cat_year"), ("y0", itemgetter(0), "y::model"), ("y::y0", lambda v: dict(y=v[0]), "y::model"), ): @@ -394,12 +393,38 @@ def add_structure(c: Computer) -> None: # log.debug(f"Use existing {c.describe(task[0])}") pass - # Assemble a queue of tasks - # - `Static` tasks - # - Single 'dynamic' tasks based on config, info, spec, and/or t_groups - # - Multiple static and dynamic tasks generated in loops etc. - tasks: list[tuple] = list(STRUCTURE_STATIC) + [ - ("c::transport", quote(spec.add.set["commodity"])), + # Assemble a queue of tasks; first, `static` tasks + tasks: list[tuple] = list(STRUCTURE_STATIC) + + # Commodity and technology coordinates + for name, groups in ("commodity", c_groups), ("technology", t_groups): + dim = name[0] # Dimension short ID ← first letter of set name + # Reference existing keys from .key module + k0 = Keys( + list=getattr(K, dim), agg=getattr(K.agg, dim), coord=getattr(K.coord, dim) + ) + + # 1. Flat list of all Codes. + # 2. Coordinates: dimension ID as the top-level key, then list of str. + # 3. Aggregator: dimension ID as the top-level key, then all groups. + # 4. Groups as top-level keys. + tasks += [ + (k0.list, quote(spec.add.set[name])), + (k0.coord, quote({dim: groups["_T"]})), + (k0.agg, quote({dim: groups})), + (f"groups:{dim}:T", quote(groups)), + ] + + # Each group individually + for group_id, members in groups.items(): + # Flat list of members as Codes + codes = sorted(filter(members.__contains__, spec.add.set[name])) + tasks.append((k0.list[group_id], quote(codes))) + # Coordinates + tasks.append((k0.coord[group_id], quote({dim: members}))) + + # Single 'dynamic' tasks based on config, info, spec, and/or t_groups + tasks += [ # Convert to str to avoid TypeError in broadcast_wildcard → sorted() # TODO Remove once sdmx.model.common.Code is sortable with str ( @@ -414,10 +439,7 @@ def add_structure(c: Computer) -> None: ("cg", quote(spec.add.set["consumer_group"])), ("indexers:cg", spec.add.set["consumer_group indexers"]), ("nodes", quote(info.set["node"])), - ("t::transport", quote(spec.add.set["technology"])), - ("t::transport agg", quote(dict(t=t_groups))), - ("t::transport all", quote(dict(t=spec.add.set["technology"]))), - (key.t_modes, quote(config.demand_modes)), + (K.t_modes, quote(config.demand_modes)), ("t::transport modes 0", quote(dict(t=list(t_groups.keys())))), ( "t::transport modes 1", @@ -425,34 +447,25 @@ def add_structure(c: Computer) -> None: ), ] + # Multiple static and dynamic tasks generated in loops etc. # Quantities for broadcasting (t,) to (t, c, l) dimensions tasks.extend( ( - getattr(key.bcast_tcl, kind), + getattr(K.bcast_tcl, kind), partial(broadcast_t_c_l, kind=kind, default_level="final"), - "t::transport", + K.t, "c::transport+base", ) for kind in ("input", "output") ) # Quantities for broadcasting y to (yv, ya) - for k, base, method in ( - (key.bcast_y.all, "y", "product"), # All periods - (key.bcast_y.model, "y::model", "product"), # Model periods only - (key.bcast_y.no_vintage, "y::model", "zip"), # Model periods with no vintaging + for k1, base, method in ( + (K.bcast_y.all, "y", "product"), # All periods + (K.bcast_y.model, K.y, "product"), # Model periods only + (K.bcast_y.no_vintage, K.y, "zip"), # Model periods with no vintaging ): - tasks.append((k, partial(broadcast_y_yv_ya, method=method), base, base)) - - # Groups of technologies and indexers - tasks.append(("t::transport groups", quote(t_groups))) - - # FIXME Combine or disambiguate these keys - for id, techs in t_groups.items(): - # Indexer-form of technology groups - tasks.append((f"t::transport {id}", quote(dict(t=techs)))) - # List form of technology groups - tasks.append((f"t::{id}", quote(techs))) + tasks.append((k1, partial(broadcast_y_yv_ya, method=method), base, base)) # - Change each task from single-tuple form to (args, kwargs) with strict=True. # - Add all to the Computer, making 2 passes. @@ -462,11 +475,33 @@ def add_structure(c: Computer) -> None: c.add( "t::transport map", MappingAdapter.from_dicts, - "t::transport groups", + "groups:t:T", dims=("t",), on_missing="raise", ) + # Identify the subset of periods up to and including y0 + c.add( + K.y_.historical, + lambda periods, y0: list(filter(lambda y: y < y0, periods)), + "y", + "y0", + ) + c.add( + K.y_.to_y0, + lambda periods, y0: dict(y=list(filter(lambda y: y <= y0, periods))), + "y", + "y0", + ) + # Convert duration_period to Quantity + c.add("duration_period:y", "duration_period", "info") + # Duration_period up to and including y0 + c.add("duration_period:y:to y0", "select", "duration_period:y", K.y_.to_y0) + # Groups for aggregating annual to period data + c.add(K.y_.annual_agg, "groups_y_annual", "duration_period:y") + # Indexers + c.add(K.coord.yv_hist, lambda periods: dict(yv=periods), K.y_.historical) + @minimum_version("genno 1.28") def get_computer( @@ -634,7 +669,7 @@ def _add_data(s, **kw): log.info(f"Added {sum_numeric(result)} total obs") if context.core.dry_run: - return c.get(key.debug) + return c.get(K.debug) # First strip existing emissions data strip_emissions_data(scenario, context) diff --git a/message_ix_models/model/transport/check.py b/message_ix_models/model/transport/check.py index 8414b81eb3..fe02f0597f 100644 --- a/message_ix_models/model/transport/check.py +++ b/message_ix_models/model/transport/check.py @@ -13,6 +13,7 @@ other, passenger, policy, + vehicle, ) from message_ix_models.model.transport.testing import assert_units from message_ix_models.testing.check import ( @@ -20,6 +21,7 @@ ContainsDataForParameters, HasCoords, HasUnits, + InRange, NoDuplicates, NoneMissing, NonNegative, @@ -190,7 +192,7 @@ def run(self, obj): "pdt factor:n-y-t": (HasUnits(""),), # "fv factor:n-y": (HasUnits(""),), # Fails: this key no longer exists # "fv:n:advance": (HasUnits(""),), # Fails: only fuzzed data in message-ix-models - key.fv_cny: (HasUnits("Gt km"),), + key.fv_cny: (HasUnits("Gt km / a"),), # # Exogenous demand calculation succeeds "transport demand::ixmp": ( @@ -209,8 +211,6 @@ def run(self, obj): # .disutility.prepare_computer() "disutility:n-cg-t-y": (Size(dict(cg=27 * 12)),), disutility.TARGET: (ContainsDataForParameters({"input"}),), - # - "historical_new_capacity::LDV+ixmp": (HasUnits("million * v / a"),), # The following partly replicates .test_ldv.test_get_ldv_data() # NB Cannot use NoDuplicates here yet due to: # - inv_cost: 50076 duplicated keys @@ -219,17 +219,13 @@ def run(self, obj): ldv.TARGET: ( ContainsDataForParameters( { - "bound_new_capacity_lo", - "bound_new_capacity_up", "capacity_factor", "emission_factor", "fix_cost", - "historical_new_capacity", "input", "inv_cost", "output", "relation_activity", - "technical_lifetime", "var_cost", } ), @@ -262,6 +258,23 @@ def run(self, obj): # No structure in base scenarios to accommodate these values → discard HasCoords({"type_emission": ["CO2_shipping_IMO"]}, inverse=True), ), + vehicle.TARGET: ( + ContainsDataForParameters( + { + "bound_new_capacity_lo", + "bound_new_capacity_up", + "historical_new_capacity", + "capacity_factor", + "technical_lifetime", + } + ), + ), + "capacity_factor::P ex LDV+ixmp": (HasCoords({"technology": ["ICE_H_bus"]}),), + "capacity_factor::F+ixmp": (HasCoords({"technology": ["f rail electr"]}),), + "historical_new_capacity::LDV+ixmp": (HasUnits("million * v / a"),), + "technical_lifetime::vehicle+ixmp": ( + HasCoords({"technology": ["ICE_H_bus", "f rail electr"]}), + ), } CHECKS_CONDITIONAL: dict[str, dict["KeyLike", tuple[Check, ...]]] = { @@ -272,11 +285,17 @@ def run(self, obj): ), ) }, - 'context.transport.modules == "FOO"': { + '"material" in context.transport.modules': { material.TARGET: ( ContainsDataForParameters({"demand", "input_cap_new", "output_cap_ret"}), NoDuplicates(), ), + # Share of non-transport demand in the total must be in the range (0.2, 1.0) + "demand:c-h-l-n-y:MT+share": (InRange(min=0.2, max=1.0),), + # This key/quantity is the computed total demand for materials for transport + # vehicles. The adjusted `demand` values that actually enter the model cannot + # be computed without dummy or real data in the base scenario used for testing. + "demand:c-h-l-n-y:MT+1": (HasCoords({"commodity": ["aluminum", "steel"]}),), }, } diff --git a/message_ix_models/model/transport/cli.py b/message_ix_models/model/transport/cli.py index b4ebdc5aab..711fadb60a 100644 --- a/message_ix_models/model/transport/cli.py +++ b/message_ix_models/model/transport/cli.py @@ -8,6 +8,7 @@ import logging from pathlib import Path +from typing import TYPE_CHECKING import click @@ -16,6 +17,9 @@ from message_ix_models.util.click import PARAMS, common_params, exec_cb from message_ix_models.workflow import make_click_command +if TYPE_CHECKING: + from message_ix_models import Context + log = logging.getLogger(__name__) @@ -109,6 +113,50 @@ def export_emissions_factors(context, path_stem): df.to_csv(path, mode="a", index=False) +@cli.command("export-price") +@click.pass_obj +def export_price_emission(context: "Context") -> None: # pragma: no cover + """Export PRICE_EMISSION values from base model scenarios. + + The --url option MUST be given. Values are exported to a CSV file at a path like: + + message_ix_models/data/transport/{nodes}/price-emission/{B}.csv + + …where {nodes} is the ID of the node codelist, and {B} is derived from the --url. + """ + # TODO Add a test; requires a solved scenario on the platform used by the + # mix_models_cli fixture + from datetime import datetime + + from message_ix_models.util import identify_nodes, package_data_path + + # Load the targeted scenario + scenario = context.get_scenario() + + # Identify the node codelist + nodes = identify_nodes(scenario) + + # Output path. + # NB Cannot use .with_suffix() here, as this replaces from the first "." in the file + # name, not the last. + info = ScenarioInfo.from_url(scenario.url) + path = package_data_path("transport", nodes, "price-emission", f"{info.path}.csv") + path.parent.mkdir(exist_ok=True, parents=True) + + df = scenario.var("PRICE_EMISSION") + log.info(f"Write {len(df)} rows to {path}") + + # Write header + path.write_text(f"""# Exported using: +# mix-models --url="{context.url}" transport export-price +# at {datetime.today().isoformat()} +# +""") + + # Write data + df.to_csv(path, mode="a", index=False) + + @cli.command() @common_params("dest") @click.option( diff --git a/message_ix_models/model/transport/config.py b/message_ix_models/model/transport/config.py index fbc1ce4f6c..b39f7d6a01 100644 --- a/message_ix_models/model/transport/config.py +++ b/message_ix_models/model/transport/config.py @@ -11,12 +11,11 @@ from message_ix_models.project.navigate import T35_POLICY as NAVIGATE_SCENARIO from message_ix_models.project.ssp import SSP_2024, ssp_field from message_ix_models.project.transport_futures import SCENARIO as FUTURES_SCENARIO -from message_ix_models.util import package_data_path +from message_ix_models.util import package_data_path, short_hash from message_ix_models.util.config import ConfigHelper from message_ix_models.util.sdmx import AnnotationsMixIn, StructureFactory from .policy import ExogenousEmissionPrice, TaxEmission -from .util import short_hash if TYPE_CHECKING: from sdmx.model import common @@ -189,8 +188,8 @@ class Config(ConfigHelper): #: List of modules containing model-building calculations. modules: list[str] = field( default_factory=lambda: ( - "groups demand constraint freight ikarus ldv disutility other passenger " - "data stock policy" + "data groups demand constraint freight ikarus ldv other passenger vehicle " + "disutility policy" ).split() ) @@ -393,6 +392,50 @@ def check(self): if all(map(lambda s: s.value > 0, [s1, s2])): raise ValueError(f"Scenario settings {s1} and {s2} are not compatible") + def get_target_url(self, context: "Context") -> str: + """Construct a target URL for a built MESSAGEix-Transport scenario. + + If the :attr:`.dest` URL is set on `context` (for instance, provided via the + :program:`--dest` CLI option), this URL returned with `label` appended to the + scenario name. + + If not, a form is used like: + + - :py:`model = "MESSAGEix-GLOBIOM 1.1-T-{regions}"`. Any value of the "model" + key from :attr:`.core.Config.dest_scenario` is appended. + - :py:`scenario = "{label}"`. Any value of the "scenario" key from + :attr:`.core.Config.dest_scenario` is appended; if this is not set, then + either "policy" (if :attr:`.transport.Config.policy` is set) or "baseline". + """ + if context.core.dest: + raise NotImplementedError + # Value from --dest CLI option + # TODO Check that this works if a version # is specified + return f"{context.dest} {self.label or ''}".strip() + else: + # Model name + model_name = ( + "MESSAGEix-GLOBIOM 1.1-" + + ("MT" if "material" in self.modules else "T") + + f"-{context.model.regions} " + # Append value from --model-extra CLI option + + context.core.dest_scenario.get("model", "") + ).rstrip() + + # Scenario name + scenario_name = ( + f"{self.label or ''} " + # Append value from --scenario-extra CLI option + + ( + context.core.dest_scenario.get("scenario") + or ("" if self.policy else "baseline") + ) + ).rstrip() + # Strip leading "M ", which is reflected in `model_name` + scenario_name = re.sub("^M ", "", scenario_name) + + return f"{model_name}/{scenario_name}" + def set_futures_scenario(self, value: str | None) -> None: """Update :attr:`project` from a string indicating a Transport Futures scenario. @@ -487,18 +530,23 @@ class CL_SCENARIO(StructureFactory["common.Codelist"]): """ urn = "IIASA_ECE:CL_TRANSPORT_SCENARIO" - version = "1.3.0" + version = "1.4.0" - #: - Model name: + #: Base scenario URL, including model name and scenario name. + #: + #: - **Model name**: + #: #: - 2024-11-25: use _v1.1 per a Microsoft Teams message. #: - 2025-02-20: update to _v2.1 per discussion with OF. At this point _v2.3 is #: the latest appearing in the database. #: - 2025-05-05: update to _v5.0. #: - 2025-06-24: update to _v6.1. - #: - The scenario names appear to form a sequence from "baseline_DEFAULT" to + #: - 2026-04-07: update to _v6.5. See also _append_code() for a special override. + #: + #: - The **scenario names** appear to form a sequence from "baseline_DEFAULT" to #: "baseline_DEFAULT_step_15" and finally "baseline". The one used below is the #: latest in this sequence for which y₀=2020, rather than 2030. - base_url = "ixmp://ixmp-dev/SSP_SSP{}_v6.1/baseline_DEFAULT_step_13" + base_url = "ixmp://ixmp-dev/SSP_SSP{}_v6.5/baseline_DEFAULT_step_13" @classmethod def create(cls) -> "common.Codelist": @@ -514,6 +562,7 @@ def create(cls) -> "common.Codelist": cl_edits = message_ix_models.project.edits.structure.get_cl_scenario() cl_digsy = message_ix_models.project.digsy.structure.get_cl_scenario() + # Create an empty code list cl: "common.Codelist" = common.Codelist( id="CL_TRANSPORT_SCENARIO", maintainer=IIASA_ECE, @@ -522,63 +571,71 @@ def create(cls) -> "common.Codelist": is_final=True, ) - def _append_code( + def _append_codes( id: str, name: str, ssp: str, led: bool = False, edits: str = "_Z", digsy: str = "_Z", - policy=None, + policy: "Policy | None" = None, ) -> None: - """Shorthand for creating a code.""" - for modules, id_prefix, name_suffix in ( + """Shorthand to append Codes to `cl` with the given setttings. + + For each call, 2 codes are appended. One has the ID ``"M {id}"``, and + includes settings for using :mod:`.transport.material`. + """ + # Construct an SCA instance to transform settings to SDMX Annotations + sca = ScenarioCodeAnnotations( + cl_ssp_2024[ssp].urn, # Expand e.g. "1" to a full URN + led, + cl_digsy[digsy].urn, + cl_edits[edits].urn, + # Format base scenario URL + # - For SSP2 only, use v6.6 in the base model name + cls.base_url.format(ssp).replace( + "v6.5", "v6.6" if ssp == "2" else "v6.5" + ), + policy, + ) + + for sca.extra_modules, id_prefix, name_suffix in ( ([], "", ""), (["material"], "M ", " with materials"), ): - sca = ScenarioCodeAnnotations( - cl_ssp_2024[ssp].urn, # Expand e.g. "1" to a full URN - led, - cl_digsy[digsy].urn, - cl_edits[edits].urn, - cls.base_url.format(ssp), # Format base scenario URL - policy, - modules, - ) - code = common.Code( - id=id_prefix + id, - name=name + name_suffix, - **sca.get_annotations(dict), - ) + # Prepare annotations + anno = sca.get_annotations(dict) + # Construct and store a code + code = common.Code(id=id_prefix + id, name=name + name_suffix, **anno) cl.append(code) # Baselines and policy scenarios for each SSP te = TaxEmission(1000.0) for ssp in "12345": id_ = name = f"SSP{ssp}" - _append_code(id_, name + " baseline", ssp) + _append_codes(id_, name + " baseline", ssp) # Simple carbon tax - _append_code(id_ + " tax", name + " with tax", ssp, policy=te) + _append_codes(id_ + " tax", name + " with tax", ssp, policy=te) # PRICE_EMISSION from exogenous data file for eep, hash in iter_price_emission("R12", f"SSP{ssp}"): name += " with exogenous price" - _append_code(f"{id_} exo price {hash}", name, ssp, policy=eep) + _append_codes(f"{id_} exo price {hash}", name, ssp, policy=eep) # LED name = "Low Energy Demand/High-with-Low scenario with SSP{} demographics" for ssp in "12": - _append_code(f"LED-SSP{ssp}", name.format(ssp), ssp, led=True) + _append_codes(f"LED-SSP{ssp}", name.format(ssp), ssp, led=True) # DIGSY ssp, name = "2", "DIGSY {!r} scenario with SSP2" for id_ in ("BEST-C", "BEST-S", "WORST-C", "WORST-S"): - _append_code(f"DIGSY-{id_}", name.format(id_), ssp, digsy=id_) + _append_codes(f"DIGSY-{id_}", name.format(id_), ssp, digsy=id_) # PRICE_EMISSION from exogenous data file for eep, hash in iter_price_emission("R12", f"SSP{ssp}"): - _append_code( + _append_codes( f"DIGSY-{id_} exo price {hash}", name.format(id_) + " with exogenous price", ssp, @@ -588,7 +645,7 @@ def _append_code( # EDITS ssp, name = "2", "EDITS scenario with ITF PASTA {!r} activity" for id_ in ("CA", "HA"): - _append_code(f"EDITS-{id_}", name.format(id_), ssp, edits=id_) + _append_codes(f"EDITS-{id_}", name.format(id_), ssp, edits=id_) return cl diff --git a/message_ix_models/model/transport/constraint.py b/message_ix_models/model/transport/constraint.py index 0858b77360..c91120b3df 100644 --- a/message_ix_models/model/transport/constraint.py +++ b/message_ix_models/model/transport/constraint.py @@ -41,24 +41,24 @@ def prepare_computer(c: "Computer") -> None: from message_ix_models.util.genno import Collector - from .key import bcast_tcl, exo + from . import key as K collect = Collector(TARGET, "{}::constraint+ixmp".format) collect.computer = c c.add("transport_data", __name__, key=TARGET) - k = Keys(a=Key("constraints", exo.constraint_dynamic.dims, "transport")) + k = Keys(a=Key("constraints", K.exo.constraint_dynamic.dims, "transport")) k.b = k.a * tuple("lny") # 't'echnology dimension: broadcast labels like "F ROAD" to full lists of techs - c.add(k.a[0], "call", "t::transport map", exo.constraint_dynamic) + c.add(k.a[0], "call", "t::transport map", K.exo.constraint_dynamic) # 'c'ommodity dimension: broadcast "*" values to full lists of transport commodities c.add(k.a[1], "call", "c::transport wildcard", k.a[0]) # Keep only the (t, c) combinations which are actual inputs to specific transport # techs - c.add(k.a[2] * "l", "mul", k.a[1], bcast_tcl.input) + c.add(k.a[2] * "l", "mul", k.a[1], K.bcast_tcl.input) # Add and broadcast over: # - 'n'ode dimension including all nodes diff --git a/message_ix_models/model/transport/data.py b/message_ix_models/model/transport/data.py index 67347be8e5..0494a7e18d 100644 --- a/message_ix_models/model/transport/data.py +++ b/message_ix_models/model/transport/data.py @@ -17,6 +17,7 @@ import pandas as pd from genno import Computer, Key from genno.core.key import single_key +from genno.operator import load_file from ixmp.report.common import RENAME_DIMS from message_ix import make_df @@ -35,7 +36,8 @@ ) from message_ix_models.util.sdmx import DATAFLOW, STORE, Dataflow -from .util import EXTRAPOLATE +from . import key as K +from .util import EXTRAPOLATE, region_path_fallback if TYPE_CHECKING: import sdmx.message @@ -61,6 +63,50 @@ ] +class ActivityVehicle(ExoDataSource): + """Activity (distance) per vehicle per year.""" + + @dataclass + class Options(BaseOptions): + #: Transport configuration. + config: "Config | None" = None + + #: ID of the node code list. + nodes: str = "" + + options: Options + + filename = "activity-vehicle.csv" + key = Key("activity:n-t-y:vehicle") + + def __init__(self, *args, **kwargs) -> None: + self.options = self.Options.from_args(self, *args, **kwargs) + self.path = region_path_fallback(self.options.nodes, self.filename) + + def get(self) -> "AnyQuantity": + return load_file(self.path, dims=RENAME_DIMS | dict(scenario="scenario")) + + def transform(self, c: "Computer", base_key: Key) -> Key: + k = base_key + + # Convert units + c.add(k[0], "convert_units", base_key, units="Mm/year") + + # Broadcast to all scenarios and nodes + coords = ["scenario::all", "n::ex world"] + dim = ("scenario", "n") + c.add(k[1], "broadcast_wildcard2", k[0], *coords, dim=dim) + + # Select values for the current scenario; drop the 'scenario' dimension + c.add(k[2], "select", k[1], "indexers:scenario:LED") + + # Interpolate on "y" dimension + c.add(self.key, "interpolate", k[2], "y::coords", **EXTRAPOLATE) + + # TODO Broadcast technology groups → individual technology IDs + return self.key + + class IEA_Future_of_Trucks(ExoDataSource): """Retrieve IEA “Future of Trucks” data. @@ -94,8 +140,6 @@ def __init__(self, *args, **kwargs) -> None: super().__init__() def get(self) -> "AnyQuantity": - from genno.operator import load_file - return load_file(self.path, dims=RENAME_DIMS) def transform(self, c: "Computer", base_key: Key) -> Key: @@ -142,6 +186,58 @@ def transform(self, c: "Computer", base_key: Key) -> Key: return single_key(result) +class Lifetime(ExoDataSource): + """Technical lifetime (maximum age) of vehicles. + + Values are interpolated across the model horizon. In MESSAGE(V)-Transport, this + quantity had the additional dimension of driver_type, and values for t=LDV were 20 + years for driver_type='average', 15 y for 'moderate', and 10 y for 'frequent'. + """ + + @dataclass + class Options(BaseOptions): + #: Transport configuration. + config: "Config | None" = None + + #: ID of the node code list. + nodes: str = "" + + options: Options + + filename = "lifetime.csv" + key = Key("lifetime:nl-t-yv:exo") + + def __init__(self, *args, **kwargs) -> None: + self.options = self.Options.from_args(self, *args, **kwargs) + self.path = region_path_fallback(self.options.nodes, self.filename) + + def get(self) -> "AnyQuantity": + return load_file(self.path, dims=RENAME_DIMS | dict(scenario="scenario")) + + def transform(self, c: "Computer", base_key: Key) -> Key: + k = base_key + + # Interpolate on "y" dimension + c.add(k[0], "interpolate", base_key, "yv::coords", **EXTRAPOLATE) + + # Broadcast to all scenarios and nodes + coords = ["scenario::all", "n::ex world"] + c.add(k[1], "broadcast_wildcard2", k[0], *coords, dim=("scenario", "nl")) + + # Select values for the current scenario; drop the 'scenario' dimension + c.add(k[2], "select", k[1], "indexers:scenario:LED") + + # Expand from "t" modes to all actual technologies + c.add(k[3], "call", "t::transport map", k[2]) + + # Convert to integer + # NB This is required because the MESSAGEix GAMS implementation cannot handle + # non-integer values. + c.add(self.key, lambda qty: qty.astype(int), k[3]) + + return self.key + + class MaybeAdaptR11Source(ExoDataSource): """Source of transport data, possibly adapted from R11 for other node code lists. @@ -201,8 +297,6 @@ def __init__(self, *args, **kwargs) -> None: raise NotImplementedError(msg) def get(self) -> "AnyQuantity": - from genno.operator import load_file - return load_file(self.path, dims=self.dims, name=self.options.measure) def __repr__(self) -> str: @@ -273,8 +367,6 @@ def __init__(self, *args, **kwargs) -> None: raise FileNotFoundError(msg) def get(self) -> "AnyQuantity": - from genno.operator import load_file - return load_file( self.path, dims=RENAME_DIMS, name=self.key.name, units=self.units ) @@ -294,14 +386,12 @@ class LoadFactorLDV(MultiFile): This source locates data in files named, for instance, :file:`message_ix_models/data/transport/{nodes}/load-factor-ldv/{scenario}.csv`. - - Units are implicitly passengers per vehicle. """ key = Key("load factor ldv:n-y:exo") dirname = "load-factor-ldv" - units = "dimensionless" + units = "passenger / vehicle" @property def filename(self) -> str: @@ -313,7 +403,10 @@ def filename(self) -> str: ("^M ", ""), # No distinction for materials scenarios ("^DIGSY-WORST-C", str(self.options.config.ssp)), # Use the respective SSP ("^(LED)-SSP.$", r"\1"), # For LED-SSP labels, use common 'LED - (r"^(SSP_\d+)\.(\d)", r"\1_\2"), # "SSP_2024.1" → "SSP_2024_1" + ( # "ICONICS:SSP(2024).1" or "SSP_2024.1" → "SSP_2024_1" + r"^(?:ICONICS:SSP\(|SSP_)(\d+)\)?\.(\d)", + r"SSP_\1_\2", + ), (r"^((SSP|DIGSY)[\w-]+)( \w*)*$", r"\1"), # Remove trailing suffix (" foo") ): label = re.sub(pattern, repl, label) @@ -348,13 +441,11 @@ def filename(self) -> str: return re.sub("^(LED)-SSP.$", r"\1", self.options.config.label) + ".csv" def transform(self, c: "Computer", base_key: Key) -> Key: - from .key import pdt_nyt, pop - # This is the key used by subsequent steps in demand.py - target = pdt_nyt[0] + target = K.pdt_nyt[0] # Multiply by population for the total - c.add(target, "mul", base_key, pop) + c.add(target, "mul", base_key, K.pop) return target @@ -595,12 +686,11 @@ def navigate_ele( def prepare_computer(c: Computer): """Add miscellaneous transport data.""" # Data-generating calculations - n, y = "n::ex world", "y::model" for comp in ( - (conversion, n, y, "config"), - (misc, "info", n, y), - (dummy_supply, "t::transport", "info", "config"), - (navigate_ele, n, "t::transport", "t::transport agg", y, "config"), + (conversion, K.n, K.y, "config"), + (misc, "info", K.n, K.y), + (dummy_supply, K.t, "info", "config"), + (navigate_ele, K.n, K.t, K.agg.t, K.y, "config"), ): # Add 2 computations: one to generate the data name = getattr(comp[0], "__name__") @@ -645,13 +735,7 @@ def _input_dataflow(**kwargs) -> "Dataflow": activity_freight = _input_dataflow( key="freight activity:n:exo", name="Freight transport activity", - units="Gt / km", -) - -activity_ldv = _input_dataflow( - key="ldv activity:scenario-n-y:exo", - name="Activity (driving distance) per light duty vehicle", - units="km / year", + units="Gt km / a", ) age_ldv = _input_dataflow( @@ -829,19 +913,18 @@ def _input_dataflow(**kwargs) -> "Dataflow": units="dimensionless", ) -lifetime_ldv = _input_dataflow( - key="lifetime:scenario-nl-t-yv:ldv+exo", - path="lifetime-ldv", - name="Technical lifetime (maximum age) of LDVs", - description="""Values are interpolated across the model horizon. In MESSAGE(V)- -Transport, this quantity had the additional dimension of driver_type, and values were 20 -years for driver_type='average', 15 y for 'moderate', and 10 y for 'frequent'.""", - units="year", + +load_factor_f = _input_dataflow( + key="load factor:t:F+exo", + name="Load factor of freight vehicles", + path="load-factor-f.csv", + units="tonne / vehicle", ) -load_factor_nonldv = _input_dataflow( - key="load factor nonldv:t:exo", - name="Load factor (occupancy) of non-LDV passenger vehicles", +load_factor_p = _input_dataflow( + key="load factor:t:P+exo", + name="Load factor (occupancy) of passenger vehicles ex LDV", + path="load-factor-p.csv", units="passenger / vehicle", ) @@ -913,7 +996,7 @@ def _input_dataflow(**kwargs) -> "Dataflow": path="stock-cap", name="Vehicle stock per capita", description="", - units="vehicle/capita", + units="vehicle / passenger", ) t_share_ldv = _input_dataflow( @@ -952,17 +1035,17 @@ def _output_dataflow(**kwargs) -> "Dataflow": key="pdt:n-y-t", units="dimensionless", ) -activity_vehicle = _output_dataflow( +activity_vehicle_out = _output_dataflow( id="ACTIVITY_VEHICLE", name="Vehicle activity", description='Same as the IAMC ‘variable’ code "Energy Service|Transportation".', - key="out:nl-t-ya-c:transport+units", + key="out:nl-t-ya-c:T", ) fe_transport = _output_dataflow( id="FE_TRANSPORT", name="Final energy", description='Same as the IAMC ‘variable’ code "Final Energy|Transportation".', - key="in:nl-t-ya-c:transport+units", + key="in:nl-t-ya-c:T", ) gdp_in = _output_dataflow( id="GDP_IN", diff --git a/message_ix_models/model/transport/demand.py b/message_ix_models/model/transport/demand.py index 593fece99b..5ce156260e 100644 --- a/message_ix_models/model/transport/demand.py +++ b/message_ix_models/model/transport/demand.py @@ -13,28 +13,8 @@ from message_ix_models.util import broadcast from . import factor +from . import key as K from .data import PDT_CAP -from .key import ( - cg, - cost, - exo, - gdp_cap, - gdp_ppp, - ldv_cny, - ldv_ny, - ldv_nycg, - ms, - n, - pdt_cap, - pdt_cny, - pdt_ny, - pdt_nyt, - pop, - price, - sw, - t_modes, - y, -) from .util import EXTRAPOLATE if TYPE_CHECKING: @@ -96,60 +76,60 @@ def dummy( (("lambda:", "quantity_from_config", "config"), dict(name="lamda")), (("y::conv", "quantity_from_config", "config"), dict(name="year_convergence")), # Base passenger mode share (exogenous/reference data) - (ms + "base", "base_shares", "mode share:n-t:exo", n, t_modes, y), + (K.ms + "base", "base_shares", "mode share:n-t:exo", K.n, K.t_modes, K.y), # GDP expressed in PPP. The in the SSP(2024) input files, this conversion is already # applied, so no need to multiply by a mer_to_ppp factor here → simple alias. - (gdp_ppp, GDP), + (K.gdp_ppp, GDP), # GDP PPP per capita - (gdp_cap, "div", gdp_ppp, pop), + (K.gdp_cap, "div", K.gdp_ppp, K.pop), # # Total PDT (n, y) = product of PDT / capita and population. See pdt_per_capita() # that sets up the calculation of `pdt_cap + "adj"` - (pdt_ny, "mul", pdt_cap + "adj", pop), + (K.pdt_ny, "mul", K.pdt_cap + "adj", K.pop), # Value-of-time multiplier # ("votm:n-y", "votm", gdp_cap + "adj"), # use the original GDP path for votm calculations - ("votm:n-y", "votm", gdp_cap), + ("votm:n-y", "votm", K.gdp_cap), # Select only the price of transport services # FIXME should be the full set of prices - ((price[1], "select", price[0]), dict(indexers=dict(c="transport"), drop=True)), - (price[2], "price_units", price[1]), + ((K.price[1], "select", K.price[0]), dict(indexers=dict(c="transport"), drop=True)), + (K.price[2], "price_units", K.price[1]), # Smooth prices to avoid zig-zag in share projections - (price, "smooth", price[2]), + (K.price, "smooth", K.price[2]), # Interpolate speed data - (("speed:scenario-n-t-y:0", "interpolate", exo.speed, "y::coords"), EXTRAPOLATE), + (("speed:scenario-n-t-y:0", "interpolate", K.exo.speed, "y::coords"), EXTRAPOLATE), # Select speed data ("speed:n-t-y", "select", "speed:scenario-n-t-y:0", "indexers:scenario"), # Cost of transport (n, t, y) - (cost, "cost", price, gdp_cap, "whour:", "speed:n-t-y", "votm:n-y", y), + (K.cost, "cost", K.price, K.gdp_cap, "whour:", "speed:n-t-y", "votm:n-y", K.y), # Share weights (n, t, y) ( - sw, + K.sw, "share_weight", - ms + "base", - gdp_cap, - cost, + K.ms + "base", + K.gdp_cap, + K.cost, "lambda:", - t_modes, - y, + K.t_modes, + K.y, "config", ), # Mode shares - ((ms, "logit", cost, sw, "lambda:", y), dict(dim="t")), + ((K.ms, "logit", K.cost, K.sw, "lambda:", K.y), dict(dim="t")), # Total PDT (n, t, y), with modes for the 't' dimension - (pdt_nyt[0], "mul", pdt_ny, ms), + (K.pdt_nyt[0], "mul", K.pdt_ny, K.ms), # Scenario-specific adjustment factors - ("pdt factor:n-y-t", "factor_pdt", n, y, t_modes, "config"), + ("pdt factor:n-y-t", "factor_pdt", K.n, K.y, K.t_modes, "config"), # Only the LDV values ( ("ldv pdt factor:n-y", "select", "pdt factor:n-y-t"), dict(indexers=dict(t="LDV"), drop=True), ), - (pdt_nyt, "mul", pdt_nyt[0], "pdt factor:n-y-t"), + (K.pdt_nyt, "mul", K.pdt_nyt[0], "pdt factor:n-y-t"), # Per capita (for validation) - (pdt_nyt + "capita+post", "div", pdt_nyt, pop), + (K.pdt_nyt + "capita+post", "div", K.pdt_nyt, K.pop), # LDV PDT only (n, y) - ((ldv_ny + "ref", "select", pdt_nyt), dict(indexers=dict(t="LDV"), drop=True)), + ((K.ldv_ny + "ref", "select", K.pdt_nyt), dict(indexers=dict(t="LDV"), drop=True)), # commented: The following computes LDV PDT as base-year values from the ADVANCE # database × an index of the top-down (Schäfer) LDV PDT versus base-year values # # Indexed to base year @@ -160,25 +140,28 @@ def dummy( # (ldv_ny + "total", "mul", ldv_ny + "total+0", "ldv pdt factor:n-y"), # # Apply the scenario-specific adjustment factor - (ldv_ny + "total", "mul", ldv_ny + "ref", "ldv pdt factor:n-y"), + (K.ldv_ny + "total", "mul", K.ldv_ny + "ref", "ldv pdt factor:n-y"), # LDV PDT shared out by consumer group (cg, n, y) - (ldv_nycg, "mul", ldv_ny + "total", cg), + (K.ldv_nycg, "mul", K.ldv_ny + "total", K.cg), # Select only non-LDV PDT - ((pdt_nyt[1], "select", pdt_nyt), dict(indexers=dict(t=["LDV"]), inverse=True)), + ((K.pdt_nyt[1], "select", K.pdt_nyt), dict(indexers=dict(t=["LDV"]), inverse=True)), # Relabel PDT ( - (pdt_cny[0], "relabel2", pdt_nyt[1]), + (K.pdt_cny[0], "relabel2", K.pdt_nyt[1]), dict(new_dims={"c": "transport pax {t.lower()}"}), ), - (pdt_cny, "convert_units", pdt_cny[0], "Gp km / a"), + (K.pdt_cny, "convert_units", K.pdt_cny[0], "Gp km / a"), # Convert to ixmp format - (("demand::P+ixmp", "as_message_df", pdt_cny), _DEMAND_KW), + (("demand::P+ixmp", "as_message_df", K.pdt_cny), _DEMAND_KW), # Relabel ldv pdt:n-y-cg - ((ldv_cny[0], "relabel2", ldv_nycg), dict(new_dims={"c": "transport pax {cg}"})), - (ldv_cny, "convert_units", ldv_cny[0], "Gp km / a"), - (("demand::LDV+ixmp", "as_message_df", ldv_cny), _DEMAND_KW), + ( + (K.ldv_cny[0], "relabel2", K.ldv_nycg), + dict(new_dims={"c": "transport pax {cg}"}), + ), + (K.ldv_cny, "convert_units", K.ldv_cny[0], "Gp km / a"), + (("demand::LDV+ixmp", "as_message_df", K.ldv_cny), _DEMAND_KW), # Dummy demands, if these are configured - ("demand::dummy+ixmp", dummy, "c::transport", "nodes::ex world", y, "config"), + ("demand::dummy+ixmp", dummy, "c::transport", "nodes::ex world", K.y, "config"), # Merge all data together ( "transport demand::ixmp", @@ -211,7 +194,7 @@ def pdt_per_capita(c: "Computer") -> None: c.add(gdp["PPP"], gdp) # GDP PPP per capita - c.add(gdp["capita"], "div", gdp["PPP"], pop) + c.add(gdp["capita"], "div", gdp["PPP"], K.pop) # Add `y` dimension. Here for the future fixed point we use y=2 * max(y), e.g. # 4220 for y=2110. The value doesn't matter, we just need to avoid overlap with y @@ -254,8 +237,8 @@ def _delta(qty: "AnyQuantity", y0: int) -> "AnyQuantity": c.add("pdt slope:n", "div", pdt["delta"] / "y", gdp["delta"] / "y") # Select 'elasticity' from "elasticity:scenario-n-y:P+exo" - k_e = genno.Key(exo.elasticity_p.name, "ny") - c.add(k_e[0], "select", exo.elasticity_p, "indexers:scenario") + k_e = genno.Key(K.exo.elasticity_p.name, "ny") + c.add(k_e[0], "select", K.exo.elasticity_p, "indexers:scenario") # Interpolate on "y" dimension c.add(k_e[1], "interpolate", k_e[0], "y::coords", **EXTRAPOLATE) @@ -281,10 +264,10 @@ def _delta(qty: "AnyQuantity", y0: int) -> "AnyQuantity": c.add(x[6], "assign_units", x[5], units=units) # Alias the last step to the target key - c.add(pdt_cap, pdt[6]) + c.add(K.pdt_cap, pdt[6]) # Provide a key for the adjusted GDP - c.add(gdp_cap + "adj", gdp[6]) + c.add(K.gdp_cap + "adj", gdp[6]) def prepare_computer(c: "Computer") -> None: @@ -301,7 +284,7 @@ def prepare_computer(c: "Computer") -> None: c.apply(pdt_per_capita) # Insert a scaling factor that varies according to SSP setting - c.apply(factor.insert, pdt_cap, name="pdt non-active", target=pdt_cap + "adj") + c.apply(factor.insert, K.pdt_cap, name="pdt non-active", target=K.pdt_cap + "adj") # Add other tasks for demand calculation c.add_queue(TASKS) diff --git a/message_ix_models/model/transport/disutility.py b/message_ix_models/model/transport/disutility.py index c617721fe7..8f64c6f49a 100644 --- a/message_ix_models/model/transport/disutility.py +++ b/message_ix_models/model/transport/disutility.py @@ -2,8 +2,8 @@ from genno import Key, Quantity, quote +from . import key as K from . import util -from .key import activity_ldv_full, exo from .util import EXTRAPOLATE if TYPE_CHECKING: @@ -29,12 +29,12 @@ def prepare_computer(c: "Computer") -> None: # Interpolate to ensure all y::model are covered # NB "y::coords" is not equivalent here; includes all y, not just y::model c.add("y::model+coords", lambda years: dict(y=years), "y::model") - c.add(k[1], "interpolate", exo.disutility, "y::model+coords", **EXTRAPOLATE) + c.add(k[1], "interpolate", K.exo.disutility, "y::model+coords", **EXTRAPOLATE) # Divide disutility per vehicle by annual driving distance per vehicle → disutility # per vehicle-km; convert to preferred units # TODO add "cg" dimension to ldv activity - k2 = c.add(k[2], "div", k[1], activity_ldv_full) + k2 = c.add(k[2], "div", k[1], (K.exo.activity_vehicle + "LDV") / "t") k3 = c.add(k[3], "mul", k2, Quantity(1.0, units="vehicle / year")) k4 = c.add(k[4], "convert_units", k3, units="USD / km") diff --git a/message_ix_models/model/transport/factor.py b/message_ix_models/model/transport/factor.py index 2adcf6a514..1591975d28 100644 --- a/message_ix_models/model/transport/factor.py +++ b/message_ix_models/model/transport/factor.py @@ -462,14 +462,10 @@ def insert(c: Computer, key, *, name: str, target: Key, dims: str = "ny"): Use via :meth:`genno.Computer.apply`. """ - k_target = Key(target) + from . import key as K - dim_coord = { - "n": "n::ex world", - "t": "t::transport", - "y": "y::model", - } - coords = [dim_coord[d] for d in dims] + k_target = Key(target) + coords = [{"n": K.n, "t": K.t, "y": K.y}[d] for d in dims] se = "config['transport'].ssp" # Quantify the factor diff --git a/message_ix_models/model/transport/freight.py b/message_ix_models/model/transport/freight.py index 5faaa9f77f..4a1a426842 100644 --- a/message_ix_models/model/transport/freight.py +++ b/message_ix_models/model/transport/freight.py @@ -13,9 +13,9 @@ from message_ix_models.util import convert_units, make_matched_dfs, same_node, same_time from message_ix_models.util.genno import Collector +from . import key as K from . import util from .demand import _DEMAND_KW -from .key import bcast_tcl, bcast_y, exo, fv, fv_cny, n, y from .util import COMMON, EXTRAPOLATE, wildcard if TYPE_CHECKING: @@ -40,8 +40,8 @@ def demand(c: "Computer") -> None: # commented: Base freight activity from IEA EEI # c.add("iea_eei_fv", "fv:n-y:historical", quote("tonne-kilometres"), "config") # Base year freight activity from file (n, t), with modes for the 't' dimension - c.add("fv:n-t:historical", "mul", exo.mode_share_freight, exo.activity_freight) - c.add(fv["log y0"], np.log, "fv:n-t:historical") + c.add("fv:n-t:historical", "mul", K.exo.mode_share_freight, K.exo.activity_freight) + c.add(K.fv["log y0"], np.log, "fv:n-t:historical") ### Apply pseudo 'elasticity' of freight activity @@ -57,12 +57,13 @@ def demand(c: "Computer") -> None: c.add(gdp[1], "sub", gdp[0], genno.Quantity(1.0)) ### Prepare exo.elasticity_f - k_e = Key(exo.elasticity_f.name, "ny", "F") + k_e = Key(K.exo.elasticity_f.name, "ny", "F") # Broadcast elasticity to all (node, technology, scenario) - coords = ["scenario::all", "n::ex world", quote(["F RAIL", "F ROAD"])] + freight_modes = ["F RAIL", "F ROAD"] + coords = ["scenario::all", K.n, quote(freight_modes)] dim = ("scenario", "n", "t") - c.add(k_e[0], "broadcast_wildcard", exo.elasticity_f, *coords, dim=dim) + c.add(k_e[0], "broadcast_wildcard", K.exo.elasticity_f, *coords, dim=dim) # Select values for the current scenario c.add(k_e[1], "select", k_e[0], "indexers:scenario:LED") @@ -76,33 +77,32 @@ def demand(c: "Computer") -> None: c.add(gdp[2], "mul", gdp[1], k_e[2]) # Projected delta log freight activity is exactly the same - c.add(fv[0], gdp[2]) + c.add(K.fv[0], gdp[2]) # Reverse the transformation - c.add(fv[1], "add", fv[0], genno.Quantity(1.0)) - c.add(fv[2], "mul", fv[1], fv["log y0"]) - c.add(fv[3], np.exp, fv[2]) + c.add(K.fv[1], "add", K.fv[0], genno.Quantity(1.0)) + c.add(K.fv[2], "mul", K.fv[1], K.fv["log y0"]) + c.add(K.fv[3], np.exp, K.fv[2]) # (NAVIGATE) Scenario-specific adjustment factor for freight activity - c.add("fv factor:n-t-y", "factor_fv", n, y, "config") + c.add("fv factor:n-t-y", "factor_fv", K.n, K.y, "config") # Apply the adjustment factor - c.add(fv[4], "mul", fv[3], "fv factor:n-t-y") + c.add(K.fv[4], "mul", K.fv[3], "fv factor:n-t-y") # Select certain modes. NB Do not drop so 't' labels can be used for 'c', next. - freight_techs = ["F RAIL", "F ROAD"] - c.add(fv[5], "select", fv[4], indexers=dict(t=freight_techs)) + c.add(K.fv, "select", K.fv[4], indexers=dict(t=freight_modes)) # Relabel - c.add(fv_cny, "relabel2", fv[5], new_dims={"c": "transport {t}"}) + c.add(K.fv_cny, "relabel2", K.fv, new_dims={"c": "transport {t}"}) # Convert to ixmp format - collect("demand", "as_message_df", fv_cny, **_DEMAND_KW) + collect("demand", "as_message_df", K.fv_cny, **_DEMAND_KW) # Compute indices, e.g. for use in .other.prepare_computer() - for t in freight_techs: - c.add(fv[5][t], "select", fv[5], indexers=dict(t=t)) - c.add(fv[f"{t} index"], "index_to", fv[5][t], literal("y"), "y0") + for t in freight_modes: + c.add(K.fv[t], "select", K.fv, indexers=dict(t=t)) + c.add(K.fv[f"{t} index"], "index_to", K.fv[t], literal("y"), "y0") def prepare_computer(c: "Computer") -> None: @@ -125,10 +125,9 @@ def tech_econ(c: "Computer") -> None: # Add a technology dimension with certain labels to the energy intensity of VDT # NB "energy intensity of VDT" actually has dimension (n,) only - t_F_ROAD = "t::transport F ROAD" - c.add(k[0], "expand_dims", "energy intensity of VDT:n-y", t_F_ROAD) + c.add(k[0], "expand_dims", "energy intensity of VDT:n-y", K.coord.t["F ROAD"]) # Broadcast over dimensions (c, l, y, yv, ya) - prev = c.add(k[1], "mul", k[0], bcast_tcl.input, bcast_y.model) + prev = c.add(k[1], "mul", k[0], K.bcast_tcl.input, K.bcast_y.model) # Convert MESSAGE data structure c.add(k[2], "as_message_df", prev, name="input", dims=DIMS, common=COMMON) # Convert units; add to `TARGET` @@ -139,10 +138,9 @@ def tech_econ(c: "Computer") -> None: # Create base quantity c.add(k[0], wildcard(1.0, "dimensionless", NTY)) - coords = ["n::ex world", "t::F", "y::model"] - c.add(k[1], "broadcast_wildcard", k[0], *coords, dim=NTY) + c.add(k[1], "broadcast_wildcard", k[0], K.n, K.t["F"], K.y, dim=NTY) # Broadcast over dimensions (c, l, y, yv, ya) - prev = c.add(k[2], "mul", k[1], bcast_tcl.output, bcast_y.all) + prev = c.add(k[2], "mul", k[1], K.bcast_tcl.output, K.bcast_y.all) # Convert to MESSAGE data structure prev = c.add(k[3], "as_message_df", prev, name="output", dims=DIMS, common=COMMON) # Convert units; add to `TARGET` @@ -176,14 +174,13 @@ def usage(c: "Computer") -> None: # Base values c.add(k[0], "freight_usage_output", "context") # Broadcast from (t,) → (t, c, l) dimensions - prev = c.add(k[1], "mul", k[0], bcast_tcl.output) + prev = c.add(k[1], "mul", k[0], K.bcast_tcl.output) # Broadcast over the (n, yv, ya) dimensions - d = bcast_tcl.output.dims + tuple("ny") + d = K.bcast_tcl.output.dims + tuple("ny") prev = c.add(k[2] * d, "expand_dims", prev, dim=dict(n=["*"], y=["*"])) - coords = ["n::ex world", "y::model"] - prev = c.add(k[3] * d, "broadcast_wildcard", prev, *coords, dim=tuple("ny")) - prev = c.add(k[4], "mul", prev, bcast_y.no_vintage) + prev = c.add(k[3] * d, "broadcast_wildcard", prev, K.n, K.y, dim=tuple("ny")) + prev = c.add(k[4], "mul", prev, K.bcast_y.no_vintage) # Convert to MESSAGE data structure c.add(k[5], "as_message_df", prev, name="output", dims=DIMS, common=COMMON) # Fill node_dest, time_dest key values @@ -196,7 +193,7 @@ def usage(c: "Computer") -> None: coords = ["n::ex world", "t::F usage", "y::model"] c.add(k[1], "broadcast_wildcard", k[0], *coords, dim=NTY) # Broadcast (t,) → (t, c, l) and (y,) → (yv, ya) dimensions - prev = c.add(k[2], "mul", k[1], bcast_tcl.input, bcast_y.no_vintage) + prev = c.add(k[2], "mul", k[1], K.bcast_tcl.input, K.bcast_y.no_vintage) # Convert to MESSAGE data structure collect( "usage input", "as_message_df", prev, name="input", dims=DIMS, common=COMMON diff --git a/message_ix_models/model/transport/groups.py b/message_ix_models/model/transport/groups.py index 0f0bdb7869..374a0ea439 100644 --- a/message_ix_models/model/transport/groups.py +++ b/message_ix_models/model/transport/groups.py @@ -1,4 +1,4 @@ -"""Consumer groups data.""" +"""Consumer groups.""" import logging from copy import deepcopy @@ -16,19 +16,19 @@ def prepare_computer(c: "Computer") -> None: """Prepare `rep` for calculating transport consumer groups.""" - from .key import cg, exo, pop, pop_at + from . import key as K c.add("indexers:n-cd", "indexers_n_cd", "config") # Population shares by area_type - c.add(pop_at, urban_rural_shares, pop, "config") + c.add(K.pop_at, urban_rural_shares, K.pop, "config") # Exogenous data for consumer group sizes keys = [ - exo.population_suburb_share, - exo.pop_share_attitude, - exo.pop_share_driver, - exo.pop_share_cd_at, + K.exo.population_suburb_share, + K.exo.pop_share_attitude, + K.exo.pop_share_driver, + K.exo.pop_share_cd_at, ] - c.add(cg, cg_shares, pop_at, *keys, "indexers:n-cd", "indexers:cg") + c.add(K.cg, cg_shares, K.pop_at, *keys, "indexers:n-cd", "indexers:cg") def cg_shares( diff --git a/message_ix_models/model/transport/ikarus.py b/message_ix_models/model/transport/ikarus.py index 9ee5ceb725..f6e68a5023 100644 --- a/message_ix_models/model/transport/ikarus.py +++ b/message_ix_models/model/transport/ikarus.py @@ -22,7 +22,7 @@ same_time, ) -from .key import bcast_tcl, bcast_y +from . import key as K from .passenger import UNITS if TYPE_CHECKING: @@ -245,7 +245,7 @@ def prepare_computer(c: Computer): # NB this (harmlessly) duplicates an addition in .ldv.prepare_computer() # TODO deduplicate k_fi = Key("transport input factor:t-y") - c.add(k_fi, "factor_input", "y", "t::transport", "t::transport agg", "config") + c.add(k_fi, "factor_input", "y", K.t, K.agg.t, "config") parameters = ["fix_cost", "input", "inv_cost", "technical_lifetime", "var_cost"] @@ -296,7 +296,7 @@ def prepare_computer(c: Computer): # Drop existing "c" dimension prev = c.add(prev / "c", "drop_vars", prev, quote("c")) # Fill (c, l) dimensions based on t - prev = c.add(k[6], "mul", prev, bcast_tcl.input) + prev = c.add(k[6], "mul", prev, K.bcast_tcl.input) elif name == "technical_lifetime": # Round up technical_lifetime values due to incompatibility in handling # non-integer values in the GAMS code @@ -307,7 +307,7 @@ def prepare_computer(c: Computer): if name in ("fix_cost", "input", "var_cost"): # Broadcast across valid (yv, ya) pairs - prev = c.add(k[8], "mul", prev, bcast_y.model) + prev = c.add(k[8], "mul", prev, K.bcast_y.model) # Convert to target units try: @@ -344,9 +344,7 @@ def prepare_computer(c: Computer): # Derive "output" data from "input" prev = "transport nonldv output::ixmp" - final["output"] = c.add( - prev, make_output, "transport nonldv input::ixmp", "t::transport" - ) + final["output"] = c.add(prev, make_output, "transport nonldv input::ixmp", K.t) # Merge all data together c.add(TARGET, "merge_data", *final.values()) diff --git a/message_ix_models/model/transport/key.py b/message_ix_models/model/transport/key.py index b808753503..4e099d0b5c 100644 --- a/message_ix_models/model/transport/key.py +++ b/message_ix_models/model/transport/key.py @@ -7,11 +7,13 @@ from message_ix_models.report.key import GDP, PRICE_COMMODITY from message_ix_models.util.genno import Keys -from .data import LoadFactorLDV, iter_files +from .data import ActivityVehicle, Lifetime, LoadFactorLDV, iter_files __all__ = [ - "activity_ldv_full", + "agg", + "c", "cg", + "coord", "cost", "exo", "fv_cny", @@ -33,6 +35,7 @@ "pop", "price", "sw", + "t", "t_modes", "y", ] @@ -43,6 +46,15 @@ # Keys for new quantities +#: Structures for aggregation. Each refers to a :py:`dict[str, dict[str, list[str]]]`. +#: Top-level keys are dimension IDs. Second-level keys are coordinates along the +#: respective dimension to be created by aggregation. Second-level values are lists of +#: coordinates to be aggregated. +agg = Keys( + c="agg:c:T", + t="agg:t:T", +) + #: Quantities for broadcasting (t) to (t, c, l). See :func:`.broadcast_t_c_l`. #: #: - :py:`.input`: Quantity for broadcasting (all values 1) from every transport |t| @@ -67,9 +79,21 @@ no_vintage="broadcast:y-yv-ya:no vintage", ) +#: List of all transport commodities. +c = Key("c::T") + #: Shares of population with consumer group (`cg`) dimension. cg = Key("cg share:n-y-cg") +#: Coordinates for indexing and selecting. Each refers to a :py:`dict[str, list[str]`. +#: Keys are dimension IDs. Values are lists of coordinates along the respective +#: dimension to index or select. +coord = Keys( + c="coords:c:T", + t="coords:t:T", + yv_hist="coords:yv:T+historical", +) + cost = Key("cost", "nyct") debug = Key("transport debug") @@ -126,15 +150,24 @@ # Keys for (partial or full) sets or indexers -#: List of nodes excepting "World" or "*_GLB". +#: List of nodes, excepting "World" or "*_GLB". n = "n::ex world" +#: List of all transport technologies. +t = Key("t::T") + #: List of transport modes. t_modes = "t::transport modes" #: Model periods. y = "y::model" +y_ = Keys( + annual_agg="y::annual agg", + historical="y::historical", + to_y0="y::to y0", +) + #: Keys referring to loaded input data flows (exogenous data loaded from files). #: Attributes correspond to the members of :mod:`.transport.data`; see #: :doc:`/transport/input` for a complete list. @@ -144,9 +177,11 @@ #: >>> from message_ix_models.model.transport.key import exo #: >>> exo.act_non_ldv #: -exo = Keys(load_factor_ldv=LoadFactorLDV.key) +exo = Keys( + activity_vehicle=ActivityVehicle.key, + lifetime=Lifetime.key, + load_factor_ldv=LoadFactorLDV.key, +) for name, df in iter_files(): setattr(exo, name, df.key) - -activity_ldv_full = exo.activity_ldv / "scenario" + "full" diff --git a/message_ix_models/model/transport/ldv.py b/message_ix_models/model/transport/ldv.py index 01f9fd5b79..813bfe8d3a 100644 --- a/message_ix_models/model/transport/ldv.py +++ b/message_ix_models/model/transport/ldv.py @@ -3,11 +3,10 @@ import logging from collections.abc import Mapping from operator import itemgetter -from typing import TYPE_CHECKING, Any, cast +from typing import TYPE_CHECKING, cast import genno from genno import Computer, Key, Keys -from genno.core.key import single_key from message_ix import make_df from sdmx.model.common import Code @@ -22,11 +21,11 @@ ) from message_ix_models.util.genno import Collector +from . import key as K from . import util from .data import MaybeAdaptR11Source from .emission import ef_for_input -from .key import activity_ldv_full, bcast_tcl, bcast_y, exo -from .util import COMMON, EXTRAPOLATE, wildcard +from .util import COMMON, wildcard if TYPE_CHECKING: from genno.types import AnyQuantity @@ -92,19 +91,19 @@ def prepare_computer(c: Computer): from . import factor + # Collect data in `TARGET` and connect to the "add transport data" key collect.computer = c + c.add("transport_data", __name__, key=TARGET) context = c.graph["context"] config: "Config" = context.transport - info = config.base_model_info # Some keys/shorthand k = Keys( - fe=Key("fuel economy:n-t-y:LDV"), - eff=Key("efficiency:t-y-n:LDV"), - factor_input=Key("input:t-y:LDV+factor"), + fe="fuel economy:n-t-y:LDV", + eff="efficiency:t-y-n:LDV", + factor_input="input:t-y:LDV+factor", ) - t_ldv = "t::transport LDV" # Use .tools.exo_data.prepare_computer() to add tasks that load, adapt, and select # the appropriate data @@ -114,7 +113,7 @@ def prepare_computer(c: Computer): # Insert a scaling factor that varies according to SSP c.apply( - factor.insert, k.fe + "exo", name="ldv fuel economy", target=k.fe, dims="nty" + factor.insert, k.fe["exo"], name="ldv fuel economy", target=k.fe, dims="nty" ) # Reciprocal value, i.e. from Gv km / GW a → GW a / Gv km @@ -122,68 +121,18 @@ def prepare_computer(c: Computer): # Compute the input efficiency adjustment factor for the NAVIGATE project # TODO Move this to project-specific code - c.add( - k.factor_input, - "factor_input", - "y", - "t::transport", - "t::transport agg", - "config", - ) + c.add(k.factor_input, "factor_input", "y", K.t, K.agg.t, "config") # Product of NAVIGATE input efficiency factor and LDV efficiency c.add(k.eff[1], "mul", k.factor_input, k.eff[0]) # Multiply by values from ldv-input-adj.csv. See file comment. Drop the 'scenario' # dimension; there is only one value in the file per 'n'. - c.add("input:n:LDV+adj", "sum", exo.input_adj_ldv, dimensions=["scenario"]) + c.add("input:n:LDV+adj", "sum", K.exo.input_adj_ldv, dimensions=["scenario"]) c.add(k.eff[2], "mul", k.eff[1], "input:n:LDV+adj") # Apply the function usage_data() for further processing - collect( - "usage", usage_data, exo.load_factor_ldv, "cg", "n::ex world", t_ldv, "y::model" - ) - - ### Technical lifetime - tl, k_tl = "technical_lifetime", exo.lifetime_ldv - - # Interpolate on "yv" dimension - c.add(k_tl[0], "interpolate", k_tl, "yv::coords", **EXTRAPOLATE) - - # Broadcast to all nodes, scenarios, and LDV technologies - coords = ["scenario::all", "n::ex world", "t::LDV"] - c.add(k_tl[1], "broadcast_wildcard", k_tl[0], *coords, dim=("scenario", "nl", "t")) - - # Select values for the current scenario - c.add(k_tl[2] / "scenario", "select", k_tl[1], "indexers:scenario:LED") - - # Convert to integer - # NB This is required because the MESSAGEix GAMS implementation cannot handle non- - # integer values - c.add(k_tl[3] / "scenario", lambda qty: qty.astype(int), k_tl[2] / "scenario") - - # Convert to MESSAGE data structure - dims = dict(node_loc="nl", technology="t", year_vtg="yv") - collect(tl, "as_message_df", k_tl[3] / "scenario", name=tl, dims=dims, common={}) - - ### Capacity factor - cf, k_cf_s = "capacity_factor", exo.activity_ldv - k_cf = k_cf_s / "scenario" - # Convert units - c.add(k_cf_s[0], "convert_units", k_cf_s, units="Mm/year") - # Broadcast to all scenarios - c.add(k_cf_s[1], "broadcast_wildcard", k_cf_s[0], "scenario::all", dim="scenario") - # Select values for the current scenario - c.add(k_cf[2], "select", k_cf_s[1], "indexers:scenario:LED") - # Interpolate on "y" dimension - c.add(k_cf["full"], "interpolate", k_cf[2], "y::coords", **EXTRAPOLATE) - assert k_cf["full"] == activity_ldv_full - # Add dimension "t" indexing all LDV technologies - prev = c.add(k_cf[4] * "t", "expand_dims", k_cf["full"], "t::transport LDV") - # Broadcast y → (yV, yA) - prev = c.add(k_cf[5], "mul", prev, bcast_y.all) - # Convert to MESSAGE data structure - collect(cf, "as_message_df", prev, name=cf, dims=DIMS, common=COMMON) + collect("usage", usage_data, K.exo.load_factor_ldv, "cg", K.n, K.t["LDV"], K.y) # Add further keys for MESSAGE-structured data # Techno-economic attributes @@ -206,37 +155,8 @@ def prepare_computer(c: Computer): except KeyError: k.stock = Key("") # No such file in this configuration elif config.ldv_stock_method == "B": - k.stock = single_key(c.apply(stock)) - - if k.stock: - # Convert units - c.add(k.stock[0], "convert_units", k.stock, units="million * vehicle / year") - - # historical_new_capacity: select only data prior to y₀ - kw1: dict[str, Any] = dict( - common={}, - dims=dict(node_loc="nl", technology="t", year_vtg="yv"), - name="historical_new_capacity", - ) - y_historical = list(filter(lambda y: y < info.y0, info.set["year"])) - c.add(k.stock[1], "select", k.stock[0], indexers=dict(yv=y_historical)) - collect(kw1["name"], "as_message_df", k.stock[1], **kw1) - - # CAP_NEW/bound_new_capacity_{lo,up} - # - Select only data from y₀ and later. - # - Discard values for ICE_conv. - # TODO Do not hard code this label; instead, identify the technology with the - # largest share and avoid setting constraints on it. - # - Add both upper and lower constraints to ensure the solution contains exactly - # the given value. - c.add(k.stock[2], "select", k.stock[0], indexers=dict(yv=info.Y)) - indexers = dict(t=["ICE_conv"]) - c.add(k.stock[3], "select", k.stock[2], indexers=indexers, inverse=True) - for kw1["name"] in map("bound_new_capacity_{}".format, ("lo", "up")): - collect(kw1["name"], "as_message_df", k.stock[3], **kw1) - - # Add the data to the target scenario - c.add("transport_data", __name__, key=TARGET) + # Now handled in .vehicle + pass def prepare_tech_econ( @@ -256,24 +176,23 @@ def prepare_tech_econ( c.add(k[0], wildcard(1.0, "Gv km", k.dims)) # Broadcast over (n, t, y) dimensions - coords = ["n::ex world", "t::LDV", "y::model"] - c.add(k[1], "broadcast_wildcard", k[0], *coords, dim=k.dims) + c.add(k[1], "broadcast_wildcard", k[0], K.n, K.t["LDV"], K.y, dim=k.dims) # Broadcast `exo.input_share` over (c, t) dimensions. This produces a large Quantity # with 1.0 everywhere except explicit entries in the input data file. # NB Order matters here - k = exo.input_share - coords = ["t::LDV", "c::transport+base", "y"] # NB include historical periods + k = K.exo.input_share + coords = [K.t["LDV"], "c::transport+base", "y"] # NB include historical periods c.add(k[0], "broadcast_wildcard", k, *coords, dim=k.dims) # Multiply by `bcast_tcl.input` to keep only the entries that correspond to actual # input commodities of particular technologies. - input_bcast = c.add("input broadcast::LDV", "mul", k[0], bcast_tcl.input) + input_bcast = c.add("input broadcast::LDV", "mul", k[0], K.bcast_tcl.input) ### Convert input and output to MESSAGE data structure for par_name, base, bcast in ( ("input", efficiency, input_bcast), - ("output", output_base[1], bcast_tcl.output), + ("output", output_base[1], K.bcast_tcl.output), ): k = Key(par_name, base.dims, "LDV") @@ -282,7 +201,7 @@ def prepare_tech_econ( # Broadcast from (y) to (yv, ya) dims to produce the full quantity for # input/output efficiency - prev = c.add(k[1], "mul", k[0], bcast, bcast_y.all) + prev = c.add(k[1], "mul", k[0], bcast, K.bcast_y.all) # Convert to ixmp/MESSAGEix-structured pd.DataFrame c.add(k[2], "as_message_df", prev, name=par_name, dims=DIMS, common=COMMON) @@ -294,7 +213,7 @@ def prepare_tech_econ( kw = dict(fill_value="extrapolate") for name, base in (("fix_cost", fix_cost), ("inv_cost", inv_cost)): prev = c.add(f"{name}::LDV+0", "interpolate", base, "y::coords", kwargs=kw) - prev = c.add(f"{name}::LDV+1", "mul", prev, bcast_y.all) + prev = c.add(f"{name}::LDV+1", "mul", prev, K.bcast_y.all) collect(name, "as_message_df", prev, name=name, dims=DIMS, common=COMMON) ### Compute CO₂ emissions factors @@ -348,70 +267,11 @@ def get_dummy(context) -> "ParameterData": return data -def stock(c: Computer, *, margin: float = 0.2) -> Key: - """Prepare `c` to compute base-period stock and historical sales. - - Parameters - ---------- - margin : - Fractional margin by which to increase the resulting sales values. Because these - values are used to compute ``historical_new_capacity`` and - ``bound_new_capacity_{lo,up}``, this relaxes the resulting constraints on LDV - technologies in the first model period. - """ - from .key import ldv_ny - - k = Keys(stock="stock:n-y:LDV", sales="sales:n-t-y:LDV", result="sales:nl-t-yv:LDV") - - # - Divide total LDV activity by (1) annual driving distance per vehicle and (2) - # load factor (occupancy) to obtain implied stock. - # - Correct units: "load factor ldv:n-y" is dimensionless, should be - # passenger/vehicle - # - Select only the base-period value. - c.add(k.stock[0], "div", ldv_ny + "total", activity_ldv_full) - c.add(k.stock[1], "div", k.stock[0], exo.load_factor_ldv / "scenario") - c.add(k.stock[2], "div", k.stock[1], genno.Quantity(1.0, units="passenger/vehicle")) - c.add(k.stock[3] / "y", "select", k.stock[2], "y0::coord") - - # Multiply by exogenous technology shares to obtain stock with (n, t) dimensions - c.add(k.stock, "mul", k.stock[3] / "y", exo.t_share_ldv) - - # TODO Move the following 4 calls to .build.add_structure() or similar - # Identify the subset of periods up to and including y0 - c.add( - "y::to y0", - lambda periods, y0: dict(y=list(filter(lambda y: y <= y0, periods))), - "y", - "y0", - ) - # Convert duration_period to Quantity - c.add("duration_period:y", "duration_period", "info") - # Duration_period up to and including y0 - c.add("duration_period:y:to y0", "select", "duration_period:y", "y::to y0") - # Groups for aggregating annual to period data - c.add("y::annual agg", "groups_y_annual", "duration_period:y") - - # Fraction of sales in preceding years (annual, not MESSAGE 'year' referring to - # multi-year periods) - c.add(k.sales["fraction"], "sales_fraction_annual", exo.age_ldv) - # Absolute sales in preceding years - c.add(k.sales["annual"], "mul", k.stock, k.sales["fraction"], 1.0 + margin) - # Aggregate to model periods; total sales across the period - c.add(k.sales["total"], "aggregate", k.sales["annual"], "y::annual agg", keep=False) - # Divide by duration_period for the equivalent of CAP_NEW/historical_new_capacity - c.add(k.sales, "div", k.sales["total"], "duration_period:y") - - # Rename dimensions to match those expected in prepare_computer(), above - c.add(k.result, "rename_dims", k.sales, name_dict={"n": "nl", "y": "yv"}) - - return k.result - - def usage_data( load_factor: "AnyQuantity", cg: list["Code"], nodes: list[str], - t_ldv: Mapping[str, list], + technologies: list["Code"], years: list, ) -> "ParameterData": """Generate data for LDV “usage pseudo-technologies”. @@ -428,7 +288,7 @@ def usage_data( info = ScenarioInfo(set={"node": nodes, "year": years}) # Regenerate the Spec for the disutility formulation - spec = disutility.get_spec(groups=cg, technologies=t_ldv["t"], template=TEMPLATE) + spec = disutility.get_spec(groups=cg, technologies=technologies, template=TEMPLATE) data = disutility.data_conversion(info, spec) diff --git a/message_ix_models/model/transport/material.py b/message_ix_models/model/transport/material.py index 64707566ee..5bb2df770f 100644 --- a/message_ix_models/model/transport/material.py +++ b/message_ix_models/model/transport/material.py @@ -13,9 +13,11 @@ from collections import defaultdict from typing import TYPE_CHECKING -from genno import Keys +import genno +from genno import Key, Keys from genno.core.key import single_key +from message_ix_models.util import minimum_version from message_ix_models.util.genno import Collector from . import key, util @@ -23,11 +25,13 @@ if TYPE_CHECKING: from genno import Computer + from .config import Config + #: Target key that collects all data generated in this module. -TARGET = "transport::material+ixmp" +TARGET = "transport::MT+ixmp" -collect = Collector(TARGET, "{}::material+ixmp".format) +collect = Collector(TARGET, "{}::MT+ixmp".format) # FIXME Do not hard-code this. Instead, use 1 or more of: # - Labels in input_cap_new.csv that align with .model.materials. @@ -50,22 +54,6 @@ # "zinc": "", # Missing } -# FIXME Do not hard code this -TECHNOLOGY = { - "BEV": {"ELC_100"}, - "ICE": { - "IAHe_ptrp", - "IAHm_ptrp", - "ICAe_ptrp", - "ICE_conv", - "ICE_nga", - "ICEm_ptrp", - "ICH_chyb", - "IGH_ghyb", - }, - "PHEV": {"PHEV_ptrp"}, -} - DIMS = dict( commodity="c", node_loc="n", @@ -75,18 +63,60 @@ technology="t", ) +#: Portion of the ``input_cap_new`` that is available as ``output_cap_ret`` at the end +#: of lifetime of a technology. Dimensionless. +#: +#: .. todo:: Retrieve from a file. +OUTPUT_SHARE = 0.8 + # Keyword arguments for as_message_df() for different parameters -_DEMAND_KW = dict(name="demand", dims=DIMS, common=dict()) +_DEMAND_KW = dict(name="demand", dims=util.DIMS, common=util.COMMON) _ICN_KW = dict( name="input_cap_new", dims=DIMS, common=util.COMMON | dict(level="demand") ) _OCR_KW = dict( - name="output_cap_ret", dims=DIMS, common=util.COMMON | dict(level="scrap") + name="output_cap_ret", dims=DIMS, common=util.COMMON | dict(level="end_of_life") ) +def get_groups(config: "Config") -> dict[str, dict[str, list[str]]]: + """Return groups for a :func:`~genno.operator.aggregate` operation on NTNU VMI data. + + These include: + + - ``c`` (commodity) dimension: 1 or more original (NTNU VMI) commodity IDs + aggregated to :mod:`.model.material` commodity IDs. + - ``t`` (technology) dimension: 1:1 from original (NTNU VMI) technology IDs to + :mod:`.model.transport` technology IDs. This effects rename and broadcast + operations simultaneously. + """ + + # Aggregate ≥1 original commodity IDs into .model.material commodity IDs + c_groups = defaultdict(list) + for c_original, c_model in COMMODITY_INFO.items(): + c_groups[c_model].append(c_original) + + # Retrieve all codes for LDV technologies + t_all = config.spec.add.set["technology"] + t_LDV = t_all[t_all.index("LDV")].child + + # Aggregate each original technology ID into 1 or more 'groups' of length 1 + # (this is equivalent to a broadcast operation) + t_groups = {} + for t_model in t_LDV: + t_groups[t_model.id] = [ + str(t_model.get_annotation(id="ntnu-vmi-technology").text) + ] + + return dict(c=c_groups, t=t_groups) + + +@minimum_version("message_ix 3.11.2.dev0") # NB Actually 3.12 def prepare_computer(c: "Computer") -> None: """Prepare `c` to calculate and add data for materiality of transport.""" + # Retrieve transport configuration + config = c.graph["context"].transport + # Collect data in `TARGET` and connect to the "add transport data" key collect.computer = c c.add("transport_data", __name__, key=TARGET) @@ -96,7 +126,7 @@ def prepare_computer(c: "Computer") -> None: # Same key as used in .transport.ldv.stock # TODO Move to .key sales="sales:n-t-y:LDV", - demand=key.demand_base + "MT", + demand=Key("demand", key.demand_base.dims, "MT"), ) # From input_cap_new.csv, select: @@ -105,26 +135,20 @@ def prepare_computer(c: "Computer") -> None: indexers = dict(scenario="_CT_C_D_D") c.add(k.exo[0], "select", key.exo.input_cap_new, indexers=indexers) - # Aggregate ≥1 original commodity IDs into .model.material commodity IDs - c_groups = defaultdict(list) - for c_original, c_model in COMMODITY_INFO.items(): - c_groups[c_model].append(c_original) - # Aggregate each original technology ID into 1 or more 'groups' of length 1 - # (this is equivalent to a broadcast operation) - t_groups = {} - for t_original, t_model in TECHNOLOGY.items(): - t_groups.update({t: [t_original] for t in t_model}) - - c.add( - k.exo[1], "aggregate", k.exo[0], groups=dict(c=c_groups, t=t_groups), keep=False - ) + # Transform VMI data labels to MESSAGE -MT- labels + c.add(k.exo[1], "aggregate", k.exo[0], groups=get_groups(config), keep=False) # Convert units: (material commodities [Mt]) / (transport CAP/CAP_NEW [Mvehicle]) c.add(k.exo[2], "convert_units", k.exo[1], units="Mt / Mvehicle") - # Convert data to MESSAGE-format data frames + # Convert to MESSAGE-format data frame collect("input_cap_new", "as_message_df", k.exo[2], **_ICN_KW) - collect("output_cap_ret", "as_message_df", k.exo[2], **_OCR_KW) + + # Reduce share available for recycling + c.add(k.exo[3], "mul", k.exo[2], OUTPUT_SHARE) + + # Convert to MESSAGE-format data frame + collect("output_cap_ret", "as_message_df", k.exo[3], **_OCR_KW) # Multiply base-period LDV sales by material intensity tmp = single_key(c.add("demand::MT+0", "mul", k.exo[2], k.sales, sums=True)) @@ -135,11 +159,24 @@ def prepare_computer(c: "Computer") -> None: # Convert units: material commodities demand [Mt/year] c.add(k.demand[1], "convert_units", k.demand[0], units="Mt / year") + # Force units for existing model data + # FIXME Adjust to trust the base model's units + c.add(k.demand[2], "apply_units", key.demand_base, units="Mt / year") + # Share of this transport total in existing material demand as of y₀ - c.add(k.demand["share"], "div", key.demand_base, k.demand[1]) + c.add(k.demand[3], "div", k.demand[1], k.demand[2]) + + # Clip values to be in (0, 0.8) + c.add(k.demand[4], lambda q: q.clip(0.0, 0.8), k.demand[3]) + + # Difference with 1.0: should be in range (0.2, 1.0) + c.add(k.demand[5], "sub", genno.Quantity(1.0, units=""), k.demand[4]) + + # Select only values for y0 + c.add(k.demand["share"], "select", k.demand[5], "y0::coord") # Multiply existing material demand by this share - c.add(k.demand["adj"], "mul", key.demand_base, k.demand["share"]) + c.add(k.demand["adj"], "mul", k.demand[2], k.demand["share"]) # Convert data to MESSAGE-format data frame collect("demand", "as_message_df", k.demand["adj"], **_DEMAND_KW) diff --git a/message_ix_models/model/transport/operator.py b/message_ix_models/model/transport/operator.py index 82b19ca1dd..195b765e57 100644 --- a/message_ix_models/model/transport/operator.py +++ b/message_ix_models/model/transport/operator.py @@ -14,7 +14,6 @@ import xarray as xr from genno import Computer, Key, Operator, quote from genno.operator import apply_units, as_quantity, rename_dims -from genno.testing import assert_qty_allclose, assert_units from scipy import integrate from sdmx.model.common import Code, Codelist @@ -145,6 +144,7 @@ def base_shares( def broadcast_advance(data: "AnyQuantity", y0: int, config: dict) -> "AnyQuantity": """Broadcast ADVANCE `data` from native `n` coords to :py:`config["regions"]`.""" from genno.operator import sum + from genno.testing import assert_qty_allclose assert "R12" == config["regions"], "ADVANCE data mapping only for R12 regions" @@ -1121,7 +1121,10 @@ def transport_data(*args): def transport_check(scenario: "Scenario", ACT: "AnyQuantity") -> pd.Series: - """Reporting operator for :func:`.check`.""" + """Reporting operator for :func:`.check`. + + .. todo:: Replace with use of :mod:`.testing.check`. + """ info = ScenarioInfo(scenario) # Mapping from check name → bool @@ -1152,7 +1155,7 @@ def votm(gdp_ppp_cap: "AnyQuantity") -> "AnyQuantity": from genno.operator import assign_units u = gdp_ppp_cap.units - assert_units(gdp_ppp_cap, "kUSD / passenger / year") + # assert_units(gdp_ppp_cap, "kUSD / passenger / year") # DEBUG n = gdp_ppp_cap.coords["n"].data result = 1 / ( @@ -1164,7 +1167,7 @@ def votm(gdp_ppp_cap: "AnyQuantity") -> "AnyQuantity": units="", ) ) - assert_units(result, "") + result.units == "dimensionless" return result diff --git a/message_ix_models/model/transport/other.py b/message_ix_models/model/transport/other.py index 89036f2297..33809a00b0 100644 --- a/message_ix_models/model/transport/other.py +++ b/message_ix_models/model/transport/other.py @@ -7,8 +7,8 @@ import pandas as pd from genno import Key, quote +from . import key as K from . import util -from .key import exo, fv if TYPE_CHECKING: from genno import Computer @@ -34,7 +34,7 @@ def prepare_computer(c: "Computer") -> None: """Generate MESSAGE parameter data for ``transport other *`` technologies.""" # Keys - base = exo.energy_other + base = K.exo.energy_other assert {"c", "n"} == set(base.dims) bcast = Key("broadcast:c-t:other transport") k_cnt = (base + "0") * "t" # with added dimension "t" @@ -61,11 +61,11 @@ def broadcast_other_transport(technologies) -> "AnyQuantity": pd.DataFrame(rows, columns=cols).set_index(cols[:-1])[cols[-1]] ) - c.add(bcast, broadcast_other_transport, "t::transport") + c.add(bcast, broadcast_other_transport, K.t) c.add(k_cnt, "mul", base, bcast) # Project values across y using same trajectory as road freight activity - c.add(k_cnty[0], "mul", k_cnt, fv["F ROAD index"]) + c.add(k_cnty[0], "mul", k_cnt, K.fv["F ROAD index"]) # Convert units to GWa c.add(k_cnty[1], "convert_units", k_cnty[0], units="GWa") diff --git a/message_ix_models/model/transport/passenger.py b/message_ix_models/model/transport/passenger.py index 75584dcf14..0b3f31236c 100644 --- a/message_ix_models/model/transport/passenger.py +++ b/message_ix_models/model/transport/passenger.py @@ -21,7 +21,7 @@ ) from message_ix_models.util.genno import Collector -from .key import exo +from . import key as K if TYPE_CHECKING: from message_ix_models import Context @@ -63,8 +63,6 @@ def prepare_computer(c: Computer): - from .key import n, t_modes, y - context: "Context" = c.graph["context"] # Collect data in `TARGET` and connect to the "add transport data" key @@ -92,7 +90,7 @@ def prepare_computer(c: Computer): # keys.append(k + "emi") # Data for usage pseudo-technologies - collect("usage", usage_data, exo.load_factor_nonldv, t_modes, n, y) + collect("usage", usage_data, K.exo.load_factor_p, K.t_modes, K.n, K.y) #### NB lines below duplicated from .transport.base e_iea = Key("energy:n-y-product-flow:iea") @@ -171,7 +169,7 @@ def get_2w_dummies(context) -> "ParameterData": def bound_activity(c: "Computer") -> None: """Constrain activity of non-LDV technologies based on :file:`act-non_ldv.csv`.""" - base = exo.act_non_ldv + base = K.exo.act_non_ldv # Produce MESSAGE parameters bound_activity_{lo,up}:nl-t-ya-m-h kw = dict( @@ -220,7 +218,7 @@ def _(nodes, technologies, y0, config: dict) -> Quantity: ) k = Key("bound_activity_lo:n-t-y:transport minimum") - c.add(next(k), _, "n::ex world", "t::transport", "y0", "config") + c.add(next(k), _, K.n, K.t, "y0", "config") # Produce MESSAGE parameter bound_activity_lo:nl-t-ya-m-h kw = dict( diff --git a/message_ix_models/model/transport/plot.py b/message_ix_models/model/transport/plot.py index f88a76e01a..bcc93e927d 100644 --- a/message_ix_models/model/transport/plot.py +++ b/message_ix_models/model/transport/plot.py @@ -10,7 +10,7 @@ from message_ix_models.model.workflow import STAGE from message_ix_models.report.plot import COMMON, LabelFirst, Plot, PlotFromIAMC -from . import key +from . import key as K #: Common, static settings STATIC = [ @@ -403,7 +403,7 @@ class DemandCap(Plot): """Transport demand per capita [km / a].""" basename = "demand-capita" - inputs = ["demand:n-c-y:capita", "c::transport", "cg"] + inputs = ["demand:n-c-y:capita", K.c, "cg"] static = STATIC + [ p9.aes(x="y", y="value", fill="c"), p9.geom_bar(stat="identity", width=4), @@ -434,7 +434,7 @@ class DemandExo(Plot): basename = "demand-exo" stage = STAGE.BUILD - inputs = [key.pdt_nyt] + inputs = [K.pdt_nyt] static = STATIC + [ p9.aes(x="y", y="value", fill="t"), p9.geom_bar(stat="identity", width=4), @@ -456,7 +456,7 @@ class DemandExoCap0(Plot): basename = "demand-exo-capita" stage = STAGE.BUILD - inputs = [key.pdt_nyt + "capita+post"] + inputs = [K.pdt_nyt + "capita+post"] static = STATIC + [ p9.aes(x="y", y="value", fill="t"), p9.geom_bar(stat="identity", width=4), @@ -481,7 +481,7 @@ class DemandExoCap1(DemandExoCap0): basename = "demand-exo-capita-gdp" stage = STAGE.BUILD - inputs = [key.pdt_nyt + "capita+post", key.gdp_cap] + inputs = [K.pdt_nyt + "capita+post", K.gdp_cap] static = PDT_CAP_GDP_STATIC def generate(self, df_pdt, df_gdp): diff --git a/message_ix_models/model/transport/report.py b/message_ix_models/model/transport/report.py index 2b69f66672..291a13e3d3 100644 --- a/message_ix_models/model/transport/report.py +++ b/message_ix_models/model/transport/report.py @@ -6,7 +6,7 @@ from typing import TYPE_CHECKING import pandas as pd -from genno import Computer, Key, Keys, MissingKeyError +from genno import Computer, Key, Keys from genno.core.key import single_key from message_ix import Reporter @@ -14,9 +14,12 @@ from message_ix_models.report import STAGE, add_plots from message_ix_models.report.util import add_replacements -from . import Config, key, plot +from . import Config, plot +from . import key as K if TYPE_CHECKING: + from message_ix import Scenario + from message_ix_models import Spec log = logging.getLogger(__name__) @@ -26,26 +29,26 @@ #: the legacy reporting to properly handle the result. _FE_UNIT = "EJ/yr" - +#: Quantities to convert to IAMC. See :func:`convert_iamc`. CONVERT_IAMC = ( # NB these are currently tailored to produce the variable names expected for the # NGFS project dict( - variable="transport activity", - base="out:nl-t-ya-c:transport+units", + variable="T activity", + base="out:nl-t-ya-c:T", var=["Energy Service|Transportation", "t", "c"], - sums=["c", "t", "c-t"], + sums=["c"], ), dict( - variable="transport stock", - base="CAP:nl-t-ya:ldv+units", - var=["Transport|Stock|Road|Passenger|LDV", "t"], + variable="T stock", + base="CAP:nl-t-ya:T", + var=["Stocks|Transportation", "t"], unit="Mvehicle", ), dict( - variable="transport sales", - base="CAP_NEW:nl-t-yv:ldv+units", - var=["Transport|Sales|Road|Passenger|LDV", "t"], + variable="T sales", + base="CAP_NEW:nl-t-yv:T", + var=["Sales|Transportation", "t"], unit="Mvehicle", ), # Final energy @@ -53,18 +56,12 @@ # The following are 4 different partial sums of in::transport, in which # individual technologies are already aggregated to modes dict( - variable="transport fe", - base="in:nl-t-ya-c:transport+units", + variable="T final energy", + base="in:nl-t-ya-c:T", var=["Final Energy|Transportation", "t", "c"], - sums=["c", "t", "c-t"], + sums=["c"], unit=_FE_UNIT, ), - dict( - variable="transport fe ldv", - base="in:nl-t-ya-c:ldv+units", - var=["Final Energy|Transportation|Road|Passenger|LDV", "t", "c"], - unit="EJ/yr", - ), # Emissions using MESSAGEix emission_factor parameter # base: auto-sum over dimensions yv, m, h # var: Same as in data/report/global.yaml @@ -96,11 +93,11 @@ ) -#: Quantities in which to select transport technologies only. See -#: :func:`select_transport_techs`. -SELECT = [ +#: Quantities in which to select transport technologies only. See :func:`callback`. +QUANTITY = [ "CAP_NEW", "CAP", + "emi", "fix_cost", "historical_new_capacity", "in", @@ -110,122 +107,108 @@ "var_cost", ] - -# TODO Type c as (string) "Computer" once genno supports this -def add_iamc_store_write(c: Computer, base_key) -> "Key": - """Write `base_key` to CSV, XLSX, and/or both; and/or store on "scenario". - - If `base_key` is, for instance, "foo::iamc", this function adds the following keys: - - - "foo::iamc+all": both of: - - - "foo::iamc+file": both of: - - - "foo::iamc+csv": write the data in `base_key` to a file named :file:`foo.csv`. - - "foo::iamc+xlsx": write the data in `base_key` to a file named - :file:`foo.xlsx`. - - The files are created in a subdirectory using :func:`make_output_path`—that is, - including a path component given by the scenario URL. - - - "foo::iamc+store" store the data in `base_key` as time series data on the - scenario identified by the key "scenario". - - .. todo:: Move upstream, to :mod:`message_ix_models`. - """ - k = Key(base_key) - - file_keys = [] - for suffix in ("csv", "xlsx"): - # Create the path - path = c.add( - k[f"{suffix} path"], "make_output_path", "config", name=f"{k.name}.{suffix}" - ) - # Write `key` to the path - file_keys.append(c.add(k[suffix], "write_report", base_key, path)) - - # Write all files - c.add(k["file"], file_keys) - - # Store data on "scenario" - c.add(k["store"], "store_ts", "scenario", base_key) - - # Both write and store - return single_key(c.add(k["all"], [k["file"], k["store"]])) - - -def aggregate(c: "Computer") -> None: - """Aggregate individual transport technologies to modes.""" - from genno.operator import aggregate as func - - config: Config = c.graph["config"]["transport"] - - for k in map(lambda s: Key(c.infer_keys(s)), "emi in out".split()): - try: - # Reference the function to avoid the genno magic which would treat as sum() - # NB aggregation on the nl dimension *could* come first, but this can use a - # lot of memory when applied to e.g. out:*: for a full global model. - c.add(k[0], func, k, "t::transport agg", keep=False) - c.add(k[1], func, k[0], "nl::world agg", keep=False) - c.add(k["transport"], "select", k[1], "t::transport modes 1", sums=True) - except MissingKeyError: - if config.with_solution: - raise +#: Units to apply or assign to specific quantities. See :func:`callback`. +#: +#: - Previously ``CAP:nl-t-ya:non-ldv`` was converted to "v**2 Tm / a". +#: - For ``emi``, units of ``ACT`` are not carried, so a correction is needed: +#: +#: - Add [time]: -1 +#: - Remove [vehicle]: -1, [distance]: -1 +#: +#: When run together with global.yaml reporting, emi:* is assigned units of +#: "Mt / year". Using apply_units() causes these to be *converted* to kt/a, i.e. +#: increasing the magnitude; so use assign_units() instead. +UNITS = { + "CAP": ("apply", "Mv"), + "CAP_NEW": ("apply", "Mv"), + "emi": ("assign", "kt / a"), + "in": ("apply", "GWa / a"), + "out": ("apply", "Tm / a"), +} def callback(rep: Reporter, context: Context) -> None: """:meth:`.prepare_reporter` callback for MESSAGEix-Transport. - Among others, adds: - - - ``{in,out}::transport``: with outputs aggregated by technology group or - "mode". - - ``transport plots``: the plots from :mod:`.transport.plot`. - - If the scenario to be reported is not solved, only a subset of plots are added. - - :data:`.key.report.all`: all of the above. + `rep` is extended with tasks for transport reporting. Among others, these include: + + 1. Select subsets of transport technologies. For each input quantity in + :data:`SELECT`, for example ``CAP_NEW:*``, tasks are added to compute: + + - ``CAP_NEW:*:transport all`` —selects only the technologies in + ``t::transport all``. + - ``CAP_NEW:*:ldv`` —selects only the technologies in ``t::transport LDV``. + - ``CAP_NEW:*:non-ldv`` —selects only the technologies in + ``t::transport P ex LDV``. + + 2. (Re) apply units. :func:`.ixmp.report.operator.data_for_quantity` drops units for + most data extracted from a MESSAGEix-GLOBIOM :class:`.Scenario`, because the data + contain a mix of inconsistent units. + + For every item in :data:`UNITS`, add a task to apply or assign units to selected + subsets of data that are guaranteed to have those units. + + 3. Aggregate in 3 stages, using :data:`key.agg.t <.transport.key.agg>` and + ``nl::world agg``, ``t::transport modes 1``, producing keys like ``emi:*:T``. + These values are aggregated by technology group and/or mode. + 4. Invoke :func:`misc`. + 5. Invoke :func:`convert_iamc`. + 6. Invoke :func:`convert_sdmx`. + 7. Add plots from :mod:`.transport.plot` using :func:`.report.add_plots`. These + appear at :data:`key.report.plot <.transport.key.report>`. If the scenario to be + reported is not solved, only a subset of plots are added. + 8. Invoke :func:`.transport.base.prepare_reporter`. + 9. :data:`key.report.all <.transport.key.report>` which includes all of the above. """ + from genno.operator import aggregate + from . import base, build - N_keys = len(rep.graph) + N_keys = len(rep.graph) # Number of keys prior to additions - # - Configure MESSAGEix-Transport. - # - Add structure and other information. + # - Configure MESSAGEix-Transport, if not already configured. + # - Add structure and other information from `scenario`. # - Call, inter alia: # - demand.prepare_computer() for ex-post mode and demand calculations. - check = build.get_computer( - context, obj=rep, visualize=False, scenario=rep.graph.get("scenario") - ) - - assert check is rep # Same `rep` was returned - - if False: - log.info("Filter out non-transport technologies") - - # Plain "transport" from the base model, for e.g. prices - t_filter = {"transport"} - # MESSAGEix-Transport -specific technologies - t_filter.update(map(str, rep.get("t::transport").copy())) - # # Required commodities (e.g. fuel) from the base model - # t_filter.update(spec.require.set["commodity"]) + # - Check that the same Reporter object is returned. + s: "Scenario | None" = rep.graph.get("scenario") + assert build.get_computer(context, obj=rep, visualize=False, scenario=s) is rep + + # Apply common steps for each of QUANTITY + # - Infer the full dimensionality of each key to be selected + for k_base in rep.infer_keys(QUANTITY): + k = k_base["T"] # Target key + + # 1. Select all transport technologies + rep.add(k[0], "select", k_base, K.coord.t, sums=True) + + # 2. Apply units + if k.name in UNITS: + op, units = UNITS[k.name] + rep.add(k[1], f"{op}_units", k[0], units=units, sums=True) + else: + rep.add(k[1], k[0]) # Simple alias / no-op - rep.set_filters(t=sorted(t_filter)) + # 1. Select further subsets of transport technologies. + rep.add(k["ldv"], "select", k[1], K.coord.t["LDV"], sums=True) + rep.add(k["non-ldv"], "select", k[1], K.coord.t["P ex LDV"], sums=True) - # Configure replacements for conversion to IAMC data structure - add_replacements("t", context.transport.spec.add.set["technology"]) + # 3. Aggregate according to groups + # Reference the function to avoid the genno magic which would treat as sum() + # NB aggregation on the nl dimension *could* come first, but this can use a + # lot of memory when applied to e.g. out:*: for a full global model. + rep.add(k[2], aggregate, k[1], K.agg.t, keep=True) + rep.add(k, aggregate, k[2], "nl::world agg", keep=False, sums=True) + rep.add(k["modes"], "select", k, "t::transport modes 1", sums=True) # Apply some functions that prepare further tasks. Order matters here. - aggregate(rep) - select_transport_techs(rep) - reapply_units(rep) misc(rep) convert_iamc(rep) # Adds to key.report.all convert_sdmx(rep) # Adds to key.report.all - add_plots(rep, plot, key.report.plot) + add_plots(rep, plot, K.report.plot) base.prepare_reporter(rep) # Tasks that prepare data to parametrize the base model log.info(f"Added {len(rep.graph) - N_keys} keys") - # TODO Write an SVG visualization of reporting calculations def check(scenario): @@ -306,9 +289,14 @@ def convert_iamc(c: "Computer") -> None: from message_ix_models.report import iamc as handle_iamc from message_ix_models.report import util - from .key import report as k_report + # Configure replacements for technology IDs in conversion to IAMC data structure + cfg: Config = c.graph["context"].transport + add_replacements("t", cfg.spec.add.set["technology"]) - util.REPLACE_VARS.update({r"^CAP\|(Transport)": r"\1"}) + # Update replacements for fully-constructed IAMC variable codes + # - Quantity.name is prepended automatically; this occurs with quantities derived + # from CAP and CAP_NEW. Remove the prefix. + util.REPLACE_VARS.update({r"^CAP(_NEW)?\|(S(ale|tock)s\|Transportation)": r"\2"}) keys = [] for info in CONVERT_IAMC: @@ -320,14 +308,13 @@ def convert_iamc(c: "Computer") -> None: c.add(k, "concat", *keys) # Add tasks for writing IAMC-structured data to file and storing on the scenario - c.apply(add_iamc_store_write, k) + c.apply(util.store_write_ts, k) - c.graph[k_report.all].append( - # Use ths line to both store and write to file IAMC structured-data - k + "all" - # Use this line for "transport::iamc+file" instead of "transport::iamc+all" - # k + " file" - ) + # Use this line to both store and write to file IAMC structured-data + c.graph[K.report.all] += (k + "all",) + # Use this line for "transport::iamc+file" instead of "transport::iamc+all", i.e. to + # write IAMC-structured data to file but *not* store on scenario + # c.graph[K.report.all] += (k + "file",) def convert_sdmx(c: "Computer") -> None: @@ -336,7 +323,6 @@ def convert_sdmx(c: "Computer") -> None: from message_ix_models.util.sdmx import DATAFLOW, Dataflow - from .key import report as k_report from .operator import write_sdmx_data # Directory for SDMX output @@ -354,10 +340,10 @@ def convert_sdmx(c: "Computer") -> None: c.add(keys[-1], write_sdmx_data, df.key, sm, "scenario", dir_, df_urn=df.df.urn) # Collect all the keys *then* write the collected structures to file - c.add(k_report.sdmx, "write_sdmx_structures", sm, dir_, *keys) + c.add(K.report.sdmx, "write_sdmx_structures", sm, dir_, *keys) # Connect to the main report key - c.graph[k_report.all].append(k_report.sdmx) + c.graph[K.report.all] += (K.report.sdmx,) def misc(c: "Computer") -> None: @@ -371,17 +357,18 @@ def misc(c: "Computer") -> None: # Configuration for :func:`check`. Adds a single key, 'transport check', that # depends on others and returns a :class:`pandas.Series` of :class:`bool`. + # TODO Replace with use of message_ix_models.testing.check c.add("transport check", "transport_check", "scenario", "ACT:nl-t-yv-va-m-h") # Exogenous data c.add("distance:nl:non-ldv", "distance_nonldv", "config") # Demand per capita - c.add("demand::capita", "divdemand:n-c-y", key.pop) + c.add("demand::capita", "divdemand:n-c-y", K.pop) # Adjustment factor for LDV calibration: fuel economy ratio - k_num = Key("in:nl-t-ya-c:transport+units") / "c" # As in CONVERT_IAMC - k_denom = Key("out:nl-t-ya-c:transport+units") / "c" # As in CONVERT_IAMC + k_num = Key("in:nl-t-ya-c:T") / "c" # As in CONVERT_IAMC + k_denom = Key("out:nl-t-ya-c:T") / "c" # As in CONVERT_IAMC k_check = single_key(c.add("fuel economy::check", "div", k_num, k_denom)) c.add( k_check + "sel", @@ -392,7 +379,7 @@ def misc(c: "Computer") -> None: ) k_ratio = single_key( - c.add("fuel economy::ratio", "div", key.exo.input_ref_ldv, k_check + "sel") + c.add("fuel economy::ratio", "div", K.exo.input_ref_ldv, k_check + "sel") ) c.add("calibrate fe path", "make_output_path", "config", name="calibrate-fe.csv") hc = "\n\n".join( @@ -455,50 +442,3 @@ def multi(context: Context, targets: list[str], *, use_platform: bool = False) - add_plots(c, plot, "multi", stage=STAGE.REPORT, single=False) return c.get("multi") - - -def reapply_units(c: "Computer") -> None: - """Apply units to transport quantities. - - :func:`.ixmp.report.operator.data_for_quantity` drops units for most data extracted - from a MESSAGEix-GLOBIOM :class:`.Scenario`, because the data contain a mix of - inconsistent units. - - Here, add tasks to reapply units to selected subsets of data that are guaranteed to - have certain units. - """ - # TODO Infer these values from technology.yaml etc. - for base, (op, units) in { - # Vehicle stocks - # FIXME should not need the extra [vehicle] in the numerator - "CAP:nl-t-ya:non-ldv": ("apply", "v**2 Tm / a"), - "CAP:*:ldv": ("apply", "Mv"), - "CAP_NEW:*:ldv": ("apply", "Mv"), - # NB these units are correct for final energy only - "in:*:transport": ("apply", "GWa / a"), - "in:*:ldv": ("apply", "GWa / a"), - "out:*:transport": ("apply", "Tm / a"), - "out:*:ldv": ("apply", "Tm / a"), - # Units of ACT are not carried, so must correct here: - # - Add [time]: -1 - # - Remove [vehicle]: -1, [distance]: -1 - # - # When run together with global.yaml reporting, emi:* is assigned units of - # "Mt / year". Using apply_units() causes these to be *converted* to kt/a, i.e. - # increasing the magnitude; so use assign_units() instead. - "emi:*:transport": ("assign", "kt / a"), - }.items(): - key = c.infer_keys(base) - c.add(key + "units", f"{op}_units", key, units=units, sums=True) - - -def select_transport_techs(c: "Computer") -> None: - """Select subsets of transport technologies. - - Applied to the quantities in :data:`SELECT`. - """ - # Infer the full dimensionality of each key to be selected - for k in map(lambda name: c.infer_keys(f"{name}:*"), SELECT): - c.add(k + "transport all", "select", k, "t::transport all", sums=True) - c.add(k + "ldv", "select", k, "t::transport LDV", sums=True) - c.add(k + "non-ldv", "select", k, "t::transport P ex LDV", sums=True) diff --git a/message_ix_models/model/transport/stock.py b/message_ix_models/model/transport/stock.py deleted file mode 100644 index 16681d76ce..0000000000 --- a/message_ix_models/model/transport/stock.py +++ /dev/null @@ -1,39 +0,0 @@ -"""First-period stock of non-LDV modes.""" - -import logging -from typing import TYPE_CHECKING - -from genno import Key - -from . import util -from .key import exo, pop - -if TYPE_CHECKING: - from genno import Computer - -log = logging.getLogger(__name__) - -Si = "stock+ixmp" -TARGET = f"transport::{Si}" - - -def prepare_computer(c: "Computer") -> None: - # total stock = stock per capita × total population - stock_total = exo.stock_cap - "cap" - c[stock_total] = "mul", exo.stock_cap, pop - - # Convert to data for MESSAGE parameters "bound_total_capacity_{lo,up}" - keys = [] - kw = dict(dims=util.DIMS | dict(node_loc="n", year_act="y"), common=util.COMMON) - for par_name in "bound_total_capacity_lo", "bound_total_capacity_up": - keys.append(Key(par_name, (), Si)) - c[keys[-1]] = "as_message_df", stock_total, dict(name=par_name) | kw - - # Merge parameter data - c[TARGET] = "merge_data", *keys - - log.warning(f"Disabled: add {__name__} data") - return - - # Connect `TARGET` to the "add transport data" key - c.add("transport_data", __name__, key=TARGET) diff --git a/message_ix_models/model/transport/structure.py b/message_ix_models/model/transport/structure.py index 95914d1dd1..45ff2c18a2 100644 --- a/message_ix_models/model/transport/structure.py +++ b/message_ix_models/model/transport/structure.py @@ -1,3 +1,4 @@ +from collections import defaultdict from collections.abc import Sequence from copy import deepcopy from typing import Any @@ -39,6 +40,63 @@ ) +def _code_list( + key: str, data: Spec | ScenarioInfo | Sequence["Code"] +) -> Sequence["Code"]: + """Handle input for :func:`get_commodity_groups`, :func:`get_technology_groups`.""" + match data: + case Spec(): + return data.add.set[key] + case ScenarioInfo(): + return data.set[key] + case _: + return data + + +def get_commodity_groups( + commodities: Spec | ScenarioInfo | Sequence["Code"], +) -> dict[str, list[str]]: + """Subsets of transport commodities for aggregation, mapping, and filtering. + + Returns + ------- + dict + Values are lists of transport commodities (|c|) that appear in the model. + Keys include: + + - "activity F": commodities measuring freight activity. + - "activity P": commodities measuring passenger activity. + - "disutility": the disutility commodity. + - "vehicle activity": commodities measuring vehicle activity + - "_T": total or all; union of the above 4 groups. + """ + result: dict[str, list[str]] = defaultdict(list) + + for c in _code_list("commodity", commodities): + result["_T"].append(c.id) + if c.id == "disutility": + result["disutility"].append(c.id) + continue + + match c.id.split()[1:]: + case ("vehicle", *_) | (*_, "vehicle"): + result["vehicle activity"].append(c.id) + case ("pax", *_): + result["activity P"].append(c.id) + case ("F", *_): + result["activity F"].append(c.id) + case _: + raise ValueError(c) + + # Check consistency + assert {"activity F", "activity P", "disutility", "vehicle activity", "_T"} == set( + result + ) + + # Convert to a non-defaultdict, so incorrect lookups fail + return dict(result) + + def get_technology_groups( technologies: Spec | ScenarioInfo | Sequence["Code"], ) -> dict[str, list[str]]: @@ -50,34 +108,37 @@ def get_technology_groups( Values are lists of transport technologies (|t|) that appear in the model. Keys include: - - Codes from :file:`transport/technology.yaml` with children. These can be - modes, services, groups of either, or other groups of technologies. Children - are processed recursively to obtain |t| elements. - - "historical-only": includes technologies where this annotation exists and - is set to :any:`True`. - - "LDV usage": includes the technologies generated using :data:`TEMPLATE`. - See :func:`make_spec`. + - Codes from :file:`transport/technology.yaml` with children. These can be + modes, services, groups of either, or other groups of technologies. Children + are processed recursively to obtain |t| elements. + - "historical-only": includes technologies where this annotation exists and is + set to :any:`True`. + - "usage": all 'usage' pseudo-technologies that transform vehicle activity into + freight or passenger activity. + - "usage LDV": includes the technologies generated using :data:`TEMPLATE`. See + :func:`make_spec`. + - "vehicle": all vehicle technologies that transform energy inputs into vehicle + activity. + - "_T": total or all; the list of all technologies. """ - if isinstance(technologies, Spec): - t_list: Sequence["Code"] = technologies.add.set["technology"] - elif isinstance(technologies, ScenarioInfo): - t_list = technologies.set["technology"] - else: - t_list = technologies - - result: dict[str, list[str]] = {"historical-only": [], "LDV usage": []} + result: dict[str, list[str]] = defaultdict(list) - for tech in t_list: - if len(tech.child): + for t in _code_list("technology", technologies): + if len(t.child): # Code with child codes → a group of technologies → store all the leaf IDs - result[tech.id] = leaf_ids(tech) - elif tech.eval_annotation(id="historical-only") is True: + techs = result[t.id] = leaf_ids(t) + # Add to either "usage" or "vehicle" group + result["usage" if "usage" in t.id else "vehicle"].extend(techs) + # Add to catch-all group + result["_T"].extend(techs) + elif t.eval_annotation(id="historical-only") is True: # Code without children = an individual technology → add to certain groups - result["historical-only"].append(tech.id) - elif tech.eval_annotation(id="is-disutility") is True: - result["LDV usage"].append(tech.id) + result["historical-only"].append(t.id) + elif t.eval_annotation(id="is-disutility") is True: + result["usage LDV"].append(t.id) - return result + # Convert to a non-defaultdict, so incorrect lookups fail + return dict(result) def make_spec(regions: str) -> Spec: diff --git a/message_ix_models/model/transport/testing.py b/message_ix_models/model/transport/testing.py index 392d1e426c..1b22ac86f1 100644 --- a/message_ix_models/model/transport/testing.py +++ b/message_ix_models/model/transport/testing.py @@ -15,9 +15,9 @@ from message_ix_models import ScenarioInfo, testing from message_ix_models.report.sim import add_simulated_solution from message_ix_models.testing import GHA, SOLVE_OPTIONS, bare_res -from message_ix_models.util import silence_log +from message_ix_models.util import package_data_path, silence_log -from . import build +from . import build, key from .config import CL_SCENARIO, Config if TYPE_CHECKING: @@ -41,7 +41,7 @@ reason="Currently only possible with regions=R12 input data/config", ), 3: pytest.mark.xfail( - raises=NotImplementedError, + raises=FileNotFoundError, reason="Missing ISR/mer-to-ppp.csv + not supported by MaybeAdaptR11Source", ), 4: pytest.mark.xfail(reason="Currently unsupported"), @@ -62,8 +62,7 @@ ), "gh": lambda f: pytest.mark.xfail( condition=GHA, - reason=f"Temporary, for https://github.com/iiasa/message-ix-models/pull/{f}:" - " fails on GHA, but not locally", + reason=f"Temporary, for https://github.com/iiasa/message-ix-models/pull/{f}", ), } @@ -91,14 +90,19 @@ def assert_units( def configure_build( - test_context: "Context", + context: "Context", regions: str, years: str, tmp_path: Path | None = None, + with_base: "pytest.FixtureRequest | None" = None, **kwargs, ) -> tuple["Computer", ScenarioInfo]: """:func:`.transport.build.get_computer` wrapper for testing.""" - test_context.update(regions=regions, years=years, output_path=tmp_path) + context.update(regions=regions, years=years, output_path=tmp_path) + + # Fixture: a base scenario with the given `regions` and `years` + if with_base is not None: + kwargs.setdefault("scenario", bare_res(with_base, context)) # Set defaults for some arguments to get_computer kwargs.setdefault("visualize", False) @@ -109,13 +113,14 @@ def configure_build( # Use scenario code "SSP2" options.setdefault("code", _default_scenario_code()) - # Omit plots for shorter test run times + # - Call prepare_computer() in this module to add test-specific data + # - Omit plots for shorter test run times options.setdefault("extra_modules", []) - options["extra_modules"].append("-plot") + options["extra_modules"].extend(["testing", "-plot"]) - c = build.get_computer(test_context, **kwargs) + c = build.get_computer(context, **kwargs) - return c, test_context.transport.base_model_info + return c, context.transport.base_model_info def built_transport( @@ -181,6 +186,34 @@ def built_transport( return result +def prepare_computer(c: "Computer") -> None: + """Adjust the transport build computer `c` for tests. + + Data used by :mod:`.transport.material` is read from a file instead of the base + scenario. + """ + from ixmp.report.common import RENAME_DIMS + + context = c.graph["context"] + + if context.transport.with_scenario and context.model.regions == "R12": + # Remove existing task to load data from the base scenario + c.graph.pop(key.demand_base) + + # Replace with data from a file + c.add( + "load_file", + package_data_path( + "test", + "transport", + "MESSAGEix-GLOBIOM_2.2-BMT-R12_baseline_BM_20260216", + "demand.csv", + ), + key=key.demand_base, + dims=RENAME_DIMS, + ) + + @cache def _default_scenario_code() -> "Code": """Return a default scenario code for :meth:`.configure_build`.""" diff --git a/message_ix_models/model/transport/util.py b/message_ix_models/model/transport/util.py index b571763273..fb041b9f44 100644 --- a/message_ix_models/model/transport/util.py +++ b/message_ix_models/model/transport/util.py @@ -2,7 +2,6 @@ import logging from collections.abc import Hashable, Iterable, Sequence -from hashlib import blake2s from pathlib import Path from typing import TYPE_CHECKING @@ -23,7 +22,9 @@ #: Mapping from :mod:`message_ix` parameter dimensions to source dimensions in some #: quantities. DIMS = dict( + node="n", node_loc="nl", + year="y", year_vtg="yv", year_act="ya", technology="t", @@ -71,11 +72,6 @@ def region_path_fallback(context_or_regions: Context | str, *parts) -> Path: raise FileNotFoundError(candidates) -def short_hash(value: str, len: int = 3) -> str: - """Return a short (length `len`) hash of `value`.""" - return blake2s(value.encode()).hexdigest()[:len] - - def sum_numeric(iterable: Iterable, /, start=0) -> "numbers.Real": """Sum only the numeric values in `iterable`.""" result = start diff --git a/message_ix_models/model/transport/vehicle.py b/message_ix_models/model/transport/vehicle.py new file mode 100644 index 0000000000..24dfe1abf9 --- /dev/null +++ b/message_ix_models/model/transport/vehicle.py @@ -0,0 +1,167 @@ +"""Operational parameters (capacity factor, technical lifetime) and stock of vehicles. + +Some calculations for LDVs are more complex, and are handled in :mod:`.transport.ldv`. +""" + +import logging +from typing import TYPE_CHECKING, Any + +from genno import Key, Keys + +from message_ix_models.util.genno import Collector + +from . import key as K +from .util import COMMON, DIMS + +if TYPE_CHECKING: + from genno import Computer + + from message_ix_models.model.transport import Config + +log = logging.getLogger(__name__) + +# Shorthand +Vi = "vehicle+ixmp" + +#: Target key that collects all data generated in this module. +TARGET = f"transport::{Vi}" + + +collect = Collector(TARGET, "{}+ixmp".format) + + +def prepare_computer(c: "Computer") -> None: + # Collect data in `TARGET` and connect to the "add transport data" key + collect.computer = c + c.add("transport_data", __name__, key=TARGET) + + context = c.graph["context"] + techs = context.transport.spec.add.set["technology"] + k = K.exo.activity_vehicle + + for mode in "F", "P ex LDV", "LDV": + # Select only the "t" dimension coords according to `mode` + mode_code = techs[techs.index(mode)] + modes = ["LDV"] if mode == "LDV" else list(map(str, mode_code.child)) + + # One of the sums is used in .disutility.prepare_computer() + c.add(k[mode], "select", k, indexers={"t": modes}, sums=True) + + # Further operations based on k[mode] + capacity_factor(c, mode) + stock(c, mode) + + # Add data for MESSAGE parameter ``technical_lifetime`` + tl = "technical_lifetime" + # Convert to MESSAGE data structure + collect( + f"{tl}::vehicle", "as_message_df", K.exo.lifetime, name=tl, dims=DIMS, common={} + ) + + # # total stock = stock per capita × total population + # stock_total = exo.stock_cap - "cap" + # c[stock_total] = "mul", exo.stock_cap, pop + # + # # Convert to data for MESSAGE parameters "bound_total_capacity_{lo,up}" + # keys = [] + # kw = dict(dims=util.DIMS | dict(node_loc="n", year_act="y"), common=util.COMMON) + # for par_name in "bound_total_capacity_lo", "bound_total_capacity_up": + # keys.append(Key(par_name, (), Vi)) + # c[keys[-1]] = "as_message_df", stock_total, dict(name=par_name) | kw + + +def capacity_factor(c: "Computer", mode: str) -> None: + """Add data for MESSAGE parameter ``capacity_factor``.""" + cf = "capacity_factor" + k = Key(cf, K.exo.activity_vehicle.dims, mode) + + # Expand from "t" modes to all actual technologies + c.add(k[0], "call", "t::transport map", K.exo.activity_vehicle[mode]) + + # Broadcast y → (yV, yA) + prev = c.add(k[1], "mul", k[0], K.bcast_y.all) + + # Convert to MESSAGE data structure + dims = DIMS | dict(node_loc="n") + collect(f"{cf}::{mode}", "as_message_df", prev, name=cf, dims=dims, common=COMMON) + + +def stock(c: "Computer", mode: str, *, margin: float = 0.2) -> None: + """Prepare `c` to compute base-period stock and historical sales for `mode`. + + Parameters + ---------- + margin : + Fractional margin by which to increase the resulting sales values. Because these + values are used to compute ``historical_new_capacity`` and + ``bound_new_capacity_{lo,up}``, this relaxes the resulting constraints on LDV + technologies in the first model period. + """ + context = c.graph["context"] + config: "Config" = context.transport + info = config.base_model_info + + k = Keys( + stock=f"stock:n-t-y:{mode}", + sales_nty=f"sales:n-t-y:{mode}", + sales=f"sales:nl-t-yv:{mode}", + ) + + k_total_activity, k_load_factor = { + "F": (K.fv, K.exo.load_factor_f), + "P ex LDV": (K.pdt_nyt, K.exo.load_factor_p), + "LDV": (K.ldv_ny + "total", K.exo.load_factor_ldv), + }[mode] + + # - Divide total activity by (1) annual driving distance per vehicle and (2) load + # factor (occupancy) to obtain implied stock. + # - Correct units: "load factor ldv:n-y" is dimensionless, should be + # passenger/vehicle + # - Select only the base-period value. + c.add(k.stock[0], "div", k_total_activity, K.exo.activity_vehicle[mode]) + c.add(k.stock[1], "div", k.stock[0], k_load_factor) + c.add(k.stock[2] / "y", "select", k.stock[1], "y0::coord", sums=True) + + if mode != "LDV": + return + + # Multiply by exogenous technology shares to obtain stock with (n, t) dimensions + c.add(k.stock, "mul", k.stock[2] / ("t", "y"), K.exo.t_share_ldv) + + # Fraction of sales in preceding years (annual, not MESSAGE 'year' referring to + # multi-year periods) + c.add(k.sales_nty[0], "sales_fraction_annual", K.exo.age_ldv) + # Absolute sales in preceding years + c.add(k.sales_nty[1], "mul", k.stock, k.sales_nty[0], 1.0 + margin) + # Aggregate to model periods; total sales across the period + c.add(k.sales_nty[2], "aggregate", k.sales_nty[1], K.y_.annual_agg, keep=False) + # Divide by duration_period for the equivalent of CAP_NEW/historical_new_capacity + c.add(k.sales_nty, "div", k.sales_nty[2], "duration_period:y") + + # Rename dimensions to match those expected in prepare_computer(), above + c.add(k.sales, "rename_dims", k.sales_nty, name_dict={"n": "nl", "y": "yv"}) + + # Convert units + c.add(k.sales[0], "convert_units", k.sales, units="million * vehicle / year") + + # historical_new_capacity: select only data prior to y₀ + kw: dict[str, Any] = dict( + common={}, + dims=dict(node_loc="nl", technology="t", year_vtg="yv"), + name="historical_new_capacity", + ) + c.add(k.sales[1], "select", k.sales[0], K.coord.yv_hist) + collect(f"{kw['name']}::{mode}", "as_message_df", k.sales[1], **kw) + + # CAP_NEW/bound_new_capacity_{lo,up} + # - Select only data from y₀ and later. + # - Discard values for ICE_conv. + # TODO Do not hard code this label; instead, identify the technology with the + # largest share and avoid setting constraints on it. + # - Add both upper and lower constraints to ensure the solution contains exactly + # the given value. + c.add(k.sales[2], "select", k.sales[0], indexers=dict(yv=info.Y)) + indexers = dict(t=["ICE_conv"]) + c.add(k.sales[3], "select", k.sales[2], indexers=indexers, inverse=True) + for kw["name"] in map("bound_new_capacity_{}".format, ("lo", "up")): + collect(f"{kw['name']}::{mode}", "as_message_df", k.sales[3], **kw) diff --git a/message_ix_models/model/transport/workflow.py b/message_ix_models/model/transport/workflow.py index 32fa5f81ea..7053c54e16 100644 --- a/message_ix_models/model/transport/workflow.py +++ b/message_ix_models/model/transport/workflow.py @@ -2,14 +2,12 @@ from copy import deepcopy from typing import TYPE_CHECKING, Literal -from genno import KeyExistsError - from message_ix_models.model.workflow import Config as WorkflowConfig from message_ix_models.util import minimum_version -from .util import short_hash - if TYPE_CHECKING: + from sdmx.model.common import Code + from message_ix_models.util.context import Context from message_ix_models.workflow import Workflow @@ -41,6 +39,108 @@ ) +def add_steps(wf: "Workflow", base: str, scenario_code: "Code") -> str: + """Add 0 or more MESSAGEix-Transport workflow steps to `wf`. + + If `scenario_code` does not contain annotations necessary to configure + MESSAGEix-Transport, `base` is returned and no changes are made to `wf`. + + Otherwise, the following steps are added: + + 1. :func:`.transport.build.main`. This step clones the Scenario from `base` to a + URL given by :meth:`.Config.get_target_url`. + 2. If :attr:`.Config.policy` is truth-y (that is, contains any :class:`.Policy` + instances), call :func:`.model.workflow.step_0` and remove values for the + "bound_emission" parameter. Otherwise, no action. + 3. :func:`message_ix.tools.migrate.initial_new_capacity_up_v311`. + + The name of (3) is returned. + + As well, the following additional steps are added: + + - "[…] debug build". This is the same as (1), except giving :py:`dry_run=True`, + so the scenario is not modified; only debug output is generated. See + :func:`.transport.build.main`. + - "T debug multi": Collects all "[…] debug build" steps. Repeated calls to + :func:`.add_steps` extend the list. + - "T report multi": :func:`.transport.report.multi`, called on all the target URLs + for (1). Repeated calls to :func:`.add_steps` extend the list. + """ + from message_ix.tools.migrate import initial_new_capacity_up_v311 + + from message_ix_models.model.workflow import step_0 + + from . import build + from .config import Config + from .report import callback, multi + + # Retrieve the Context used for the Workflow + context: "Context" = wf.graph["context"] + + try: + # Retrieve .transport.Config and make a copy for this particular workflow branch + config = deepcopy(context.transport) + except AttributeError: + # Not yet configured → use defaults + config = Config.from_context(context) + + try: + # Update the .transport.Config from the `scenario_code` + config.code = scenario_code + except KeyError: + # `scenario_code` does not contain annotations for .model.transport; do nothing + return base + + # Use transport reporting + if callback not in context.report.callback: + context.report.register(callback) + + # Short label for workflow step names + label = f"{config.code.id} T" + + # Identify the target of the build step + target_url = config.get_target_url(context) + + # Build MESSAGEix-Transport on the scenario + name = wf.add_step( + f"{label} built", base, build.main, target=target_url, clone=True, config=config + ) + + if config.policy: + # Prepare emissions accounting for carbon pricing + kw = dict(remove_emission_parameters=("bound_emission",)) + name = wf.add_step(f"{label} step_0", name, step_0, **kw) + + # Adjust initial_new_capacity_up values for message_ix#924 + name = wf.add_step( + f"{label} incu adjusted", + name, + lambda _, s: initial_new_capacity_up_v311(s, safety_factor=1.05), + ) + + # 'Simulate' build and produce debug outputs + debug = f"{label} debug build" + wf.add_step(debug, base, build.main, config=config, dry_run=True) + + # Compare debug outputs from multiple simulated builds + if "T debug build" not in wf: + # NB Here we use genno.Computer.add(), not .Workflow.add_step(). This is because + # because the operations are not WorkflowSteps that receive, modify, and + # return Scenario objects—only ordinary Python functions. + wf.add("T debug build", build.debug_multi, "context") + # Append the step ID for the debug step + wf.graph["T debug build"] += (debug,) + + # Report (including plot) using data from multiple, solved scenarios + if "T report multi" not in wf: + wf.add("T report multi", multi, "context", "T targets") + wf.add("T targets", []) + # Append this target URL to the list of target URLs + wf.graph["T targets"].append(target_url) + + return name + + def base_scenario_url( context: "Context", config: "Config", method: Literal["auto", "bare"] = "bare" ) -> str: @@ -100,64 +200,22 @@ def maybe_use_temporary_platform(context: "Context") -> None: log.info("No --platform/--url; using temporary, in-memory database") -def scenario_url(context: "Context", label: str | None = None) -> str: - """Construct a target URL for a built MESSAGEix-Transport scenario. - - If the :attr:`.dest` URL is set on `context` (for instance, provided via the - :program:`--dest` CLI option), this URL returned with `label` appended to the - scenario name. - - If not, a form is used like: - - - :py:`model = "MESSAGEix-GLOBIOM 1.1-T-{regions}"`. Any value of the "model" key - from :attr:`.core.Config.dest_scenario` is appended. - - :py:`scenario = "{label}"`. Any value of the "scenario" key from - :attr:`.core.Config.dest_scenario` is appended; if this is not set, then either - "policy" (if :attr:`.transport.Config.policy` is set) or "baseline". - """ - # Construct a URL template for MESSAGEix-Transport scenarios - if context.core.dest: - # Value from --dest CLI option - # TODO Check that this works if a version # is specified - return f"{context.dest} {label or ''}".strip() - else: - # Values from --model-extra, --scenario-extra CLI options - m_extra = context.core.dest_scenario.get("model", "") - s_extra = context.core.dest_scenario.get("scenario") or ( - "policy" if context.transport.policy else "baseline" - ) - - return "/".join( - ( - f"MESSAGEix-GLOBIOM 1.1-T-{context.model.regions} {m_extra}".rstrip(), - f"{label or ''} {s_extra}".strip(), - ) - ) - - @minimum_version("message_ix 3.11") def generate( - context: "Context", - *, - report_key: str = "transport all", - dry_run: bool = False, - **options, + context: "Context", *, report_key: str = "transport all", **options ) -> "Workflow": - from message_ix.tools.migrate import initial_new_capacity_up_v311 + """Generate the MESSAGEix-Transport :class:`.Workflow`.""" - from message_ix_models import Workflow - from message_ix_models.model.workflow import solve, step_0 - from message_ix_models.report import report + from message_ix_models.model.workflow import from_codelist - from . import build from .config import CL_SCENARIO, Config - from .report import multi # Handle CLI options # TODO respect quiet options.pop("target_model_name", None) # Stored on context.core.dest_scenario options.pop("target_scenario_name", None) # Stored on context.core.dest_scenario base_scenario_method = options.pop("base_scenario") + del base_scenario_method maybe_use_temporary_platform(context) @@ -166,90 +224,8 @@ def generate( # Set the default .report.Config key for ".* reported" steps context.report.key = report_key - context.report.register("model.transport") - - # Create the workflow - wf = Workflow(context) - - # Collections of step names - debug, reported, targets = [], [], [] - - # Iterate over all scenarios in IIASA_ECE:CL_TRANSPORT_SCENARIO - for scenario_code in CL_SCENARIO.get(): - # Make a copy of the base .transport.Config for this particular workflow branch - config = deepcopy(context.transport) - - # Update the .transport.Config from the `scenario_code` - config.code = scenario_code - - # Short and long labels for workflow step names and scenario names - label, label_full = config.code.id, config.label - - # Identify the base scenario - base_url = base_scenario_url(context, config, base_scenario_method) - # log.debug(f"Base scenario for scenario={label_full!r}: {base_url}") - # log.debug(f"{config.policy = }") - - # Name of the base step - base = f"base {short_hash(base_url)}" - - try: - # Load the base model scenario - wf.add_step(base, None, target=base_url) - except KeyExistsError: - # Base scenario URL is identical to another (ssp, policy) combination; use - # the scenario returned by that step - pass - - # Identify the target of the build step - target_url = scenario_url(context, label_full) - targets.append(target_url) - - # Build MESSAGEix-Transport on the scenario - name = wf.add_step( - f"{label} built", - base, - build.main, - target=target_url, - clone=True, - config=config, - ) - - if config.policy: - # Prepare emissions accounting for carbon pricing - kw = dict(remove_emission_parameters=("bound_emission",)) - name = wf.add_step(f"{label} step_0", name, step_0, **kw) - - # Adjust initial_new_capacity_up values for message_ix#924 - name = wf.add_step( - f"{label} incu adjusted", - name, - lambda _, s: initial_new_capacity_up_v311(s, safety_factor=1.05), - ) - - # 'Simulate' build and produce debug outputs - debug.append(f"{label} debug build") - wf.add_step(debug[-1], base, build.main, config=config, dry_run=True) - - # Solve - wf.add_step(f"{label} solved", name, solve, config=SOLVE_CONFIG) - - # Report - reported.append(f"{label} reported") - wf.add_step(reported[-1], f"{label} solved", report) - - # NB the following use genno.Computer.add(), not .Workflow.add_step(). This is - # because the operations are not WorkflowSteps that receive, modify, and return - # Scenario objects—only ordinary Python functions. - - # Compare debug outputs from multiple simulated builds - wf.add("debug build", build.debug_multi, "context", *debug) - - # Report (including plot) using data from multiple, solved scenarios - wf.add("report multi", multi, "context", targets=targets) - # Report all the scenarios - wf.add("all reported", reported) - wf.default_key = "all reported" + # Set options for solving + context.solve = SOLVE_CONFIG - return wf + return from_codelist(context, CL_SCENARIO) diff --git a/message_ix_models/model/workflow.py b/message_ix_models/model/workflow.py index c5d0b7939f..c2ea55d5b2 100644 --- a/message_ix_models/model/workflow.py +++ b/message_ix_models/model/workflow.py @@ -8,13 +8,15 @@ from message_ix import Scenario -from message_ix_models.util import identify_nodes +from message_ix_models import Workflow +from message_ix_models.util import identify_nodes, minimum_version, short_hash from message_ix_models.util.config import ConfigHelper if TYPE_CHECKING: from typing import TypedDict - from message_ix_models import Context + from message_ix_models import Context, Workflow + from message_ix_models.util.sdmx import StructureFactory class CommonArgs(TypedDict): relation_name: str @@ -62,6 +64,74 @@ class Config(ConfigHelper): ) +@minimum_version("message_ix 3.11") # Same as .transport.add_steps() +def from_codelist(context: "Context", cl: type["StructureFactory"]) -> "Workflow": + """Generate a workflow using a code list. + + - IDs of codes in `cl` are used to label steps. + - The following are invoked automatically: + + - :func:`.model.transport.workflow.add_steps` + + .. todo:: Add and also invoke functions like: + + - :py:`model.buildings.workflow.add_steps` + - :py:`model.material.workflow.add_steps` + + …in a standard or configurable order. + + See also + -------- + .project.circeular.workflow.generate + .model.transport.workflow.generate + """ + from genno import KeyExistsError + + from message_ix_models.model.transport import workflow as transport + from message_ix_models.report import report + + # Create the workflow + wf = Workflow(context) + + # Collection of step names + reported = [] + + # Iterate over all scenarios in IIASA_ECE:CL_CIRCEULAR_TRANSPORT_SCENARIO + for scenario_code in cl.get(force=True): + # Identify the URL of the base scenario + base_url = scenario_code.eval_annotation(id="base-scenario-URL") + + # Short label for subsequent steps + label = scenario_code.id + + # Name of the base step + name = f"base {short_hash(base_url)}" + try: + # Load the base model scenario + wf.add_step(name, None, target=base_url) + except KeyExistsError: + # Base scenario URL is identical to another (ssp, policy) combination; use + # the scenario returned by that step + pass + + name = transport.add_steps(wf, name, scenario_code) + + # Solve + wf.add_step(f"{label} solved", name, solve) + + # Report + reported.append(f"{label} reported") + wf.add_step( + reported[-1], f"{label} solved", report, transport={"code": scenario_code} + ) + + # Report all the scenarios + wf.add("all reported", reported) + wf.default_key = "all reported" + + return wf + + def solve( context: "Context", scenario: Scenario, @@ -71,8 +141,12 @@ def solve( ): """Common model solve step for ENGAGE, NAVIGATE, and other workflows. - The steps respond settings from an optional instance of :class:`Config` passed as a - keyword argument. + The steps respond to settings from a :class:`Config` instance. In order of + precedence: + + 1. The keyword argument `config`. + 2. The "solve" key on `context`. + 3. A default instance of :class:`Config` *Before* `scenario` is solved: @@ -95,10 +169,15 @@ def solve( :obj:`True`. """ - config = config or Config() + # Identify configuration + try: + config = config or context.solve + except AttributeError: + config = Config() # Set reserve margin values if config.reserve_margin: + # FIXME Use an analogous function in message-ix-models, with tests from message_data.scenario_generation.reserve_margin import res_marg res_marg.main(scenario) @@ -112,6 +191,7 @@ def solve( if config.demand_scenario: # Retrieve DEMAND variable data from a different scenario and set as values # for the demand parameter + # FIXME Use an analogous function in message-ix-models, with tests from message_data.tools.utilities import transfer_demands source = Scenario(scenario.platform, **config.demand_scenario) diff --git a/message_ix_models/project/circeular/cli.py b/message_ix_models/project/circeular/cli.py index 44d128f24f..889e345116 100644 --- a/message_ix_models/project/circeular/cli.py +++ b/message_ix_models/project/circeular/cli.py @@ -1,5 +1,7 @@ import click +from message_ix_models.workflow import make_click_command + @click.group("circeular") def cli(): @@ -7,3 +9,12 @@ def cli(): https://docs.messageix.org/projects/models/en/latest/project/circeular.html """ + + +cli.add_command( + make_click_command( + f"{__package__}.workflow.generate", + name="CircEUlar", + slug="circeular", + ) +) diff --git a/message_ix_models/project/circeular/structure.py b/message_ix_models/project/circeular/structure.py index 6548fdcde9..dfb1075467 100644 --- a/message_ix_models/project/circeular/structure.py +++ b/message_ix_models/project/circeular/structure.py @@ -1,3 +1,4 @@ +from copy import deepcopy from typing import TYPE_CHECKING from message_ix_models.util.sdmx import StructureFactory @@ -7,23 +8,28 @@ class CL_TRANSPORT_SCENARIO(StructureFactory["common.Codelist"]): - """SDMX code list ``IIASA_ECE:CL_CIRCEULAR_TRANSPORT_SCENARIO``. + """SDMX code list ``IIASA_ECE:CL_CIRCEULAR_SCENARIO``. This code lists contains unique IDs for CircEUlar transport scenarios. """ - urn = "IIASA_ECE:CL_CIRCEULAR_TRANSPORT_SCENARIO" - version = "1.0.0" + urn = "IIASA_ECE:CL_CIRCEULAR_SCENARIO" + version = "1.1.0" @classmethod def create(cls) -> "common.Codelist": from sdmx.model import common + from message_ix_models.model.transport.config import CL_SCENARIO from message_ix_models.util.sdmx import read # Other data structures IIASA_ECE = read("IIASA_ECE:AGENCIES")["IIASA_ECE"] + # Retrieve the code "M SSP2" from IIASA_ECE:CL_TRANSPORT_SCENARIO. + # The annotations on this code control .model.transport.build(). + transport_ssp2 = CL_SCENARIO.get()["M SSP2"] + cl: "common.Codelist" = common.Codelist( id=cls.urn.partition(":")[-1], maintainer=IIASA_ECE, @@ -32,21 +38,25 @@ def create(cls) -> "common.Codelist": is_final=True, ) - for id_, market, material in ( - ("_CC_C_D_D", "Compact car", "default"), - ("_CC_C_I_D", "Compact car", "improvement"), - ("_CT_C_D_D", "Continuing trends", "default"), - ("_CT_C_I_D", "Continuing trends", "improvement"), - ("_ES_C_D_D", "Extreme SUVs", "default"), - ("_ES_C_I_D", "Extreme SUVs", "improvement"), - ("_NoS_C_D_D", "No SUVs", "default"), - ("_NoS_C_I_D", "No SUVs", "improvement"), + for id_, market, fuel_economy in ( + # 'Narrow' is one of the following 2 + ("CC-C-D-D", "Compact car", "default"), + ("CC-C-I-D", "Compact car", "improvement"), + # 'Slow', 'Close', and 'SSP' are one of the following 2 + ("CT-C-D-D", "Continuing trends", "default"), + ("CT-C-I-D", "Continuing trends", "improvement"), + # Sensitivity cases + ("ES-C-D-D", "Extreme SUVs", "default"), + ("ES-C-I-D", "Extreme SUVs", "improvement"), + ("NoS-C-D-D", "No SUVs", "default"), + ("NoS-C-I-D", "No SUVs", "improvement"), ): cl.append( common.Code( id=id_, - name=f"{market}, {material}", + name=f"{market}, {fuel_economy}", description="regional=convergence, material=default", + annotations=deepcopy(transport_ssp2.annotations), ) ) diff --git a/message_ix_models/project/circeular/workflow.py b/message_ix_models/project/circeular/workflow.py new file mode 100644 index 0000000000..0643471b64 --- /dev/null +++ b/message_ix_models/project/circeular/workflow.py @@ -0,0 +1,23 @@ +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from message_ix_models.util.context import Context + from message_ix_models.workflow import Workflow + + +def generate( + context: "Context", *, report_key: str = "transport_all", **options +) -> "Workflow": + """Generate the CircEUlar scenario workflow.""" + from message_ix_models.model.transport.workflow import SOLVE_CONFIG + from message_ix_models.model.workflow import from_codelist + + from .structure import CL_TRANSPORT_SCENARIO + + # Set the default .report.Config key for ".* reported" steps + context.report.key = report_key + + # Set options for solving + context.solve = SOLVE_CONFIG + + return from_codelist(context, CL_TRANSPORT_SCENARIO) diff --git a/message_ix_models/project/ssp/transport.py b/message_ix_models/project/ssp/transport.py index a4398d4eab..eeed881084 100644 --- a/message_ix_models/project/ssp/transport.py +++ b/message_ix_models/project/ssp/transport.py @@ -363,7 +363,6 @@ def get_computer( """ from message_ix_models.model import Config as ModelConfig from message_ix_models.model.transport import Config as TransportConfig - from message_ix_models.model.transport import workflow # Create a Computer instance c = genno.Computer() @@ -394,9 +393,8 @@ def get_computer( # - Retrieve a 'label' used to construct a target scenario URL. cfg = TransportConfig.from_context(context) cfg.code = sc - label_full = cfg.label # Construct the target scenario URL - url = workflow.scenario_url(context, label_full) + url = cfg.get_target_url(context) # Optionally apply a regex substitution URL_SUB = { "LED-SSP1": ("$", "#162"), # Point to a specific version diff --git a/message_ix_models/report/__init__.py b/message_ix_models/report/__init__.py index ec57b001c3..b170f0dffb 100644 --- a/message_ix_models/report/__init__.py +++ b/message_ix_models/report/__init__.py @@ -271,6 +271,9 @@ def report(context: Context, *args, **kwargs): if context.report.legacy["use"]: return _invoke_legacy_reporting(context) + # Update `context` using any remaining `kwargs` + context.update(kwargs) + with ( nullcontext() if context.core.verbose diff --git a/message_ix_models/report/operator.py b/message_ix_models/report/operator.py index ee9015ec63..3e69ee749f 100644 --- a/message_ix_models/report/operator.py +++ b/message_ix_models/report/operator.py @@ -24,7 +24,12 @@ from iam_units.emissions import SPECIES from message_ix_models.model.structure import get_codelist -from message_ix_models.util import MappingAdapter, add_par_data, nodes_ex_world +from message_ix_models.util import ( + MappingAdapter, + WildcardAdapter, + add_par_data, + nodes_ex_world, +) from message_ix_models.util.sdmx import leaf_ids if TYPE_CHECKING: @@ -47,6 +52,7 @@ def __lt__(self, __other: Any) -> bool: ... __all__ = [ "add_par_data", "broadcast_wildcard", + "broadcast_wildcard2", "call", "codelist_to_groups", "compound_growth", @@ -118,6 +124,26 @@ def broadcast_wildcard( return MappingAdapter(mapping)(qty) +def broadcast_wildcard2( + qty: "TQuantity", *coords: Sequence[str], dim: Hashable | Sequence[Hashable] = "n" +) -> "TQuantity": + """Like :func:`broadcast_wildcard`, but using :class:`.WildcardAdapter`.""" + if isinstance(dim, Hashable) and not isinstance(dim, tuple): + dim = (dim,) + if len(dim) != len(coords): + raise ValueError( + f"Must provide same number of dim (got |{dim}| = {len(dim)}) as coords " + f"(got {len(coords)})" + ) + + # Iterate over dimensions `d` and respective coords `c` + result = qty + for d, c in zip(dim, coords): + result = WildcardAdapter(d, c)(result) + + return result + + def call(callable, *args, **kwargs): """Invoke a callable on other arguments.""" return callable(*args, **kwargs) @@ -410,7 +436,8 @@ def nodes_world_agg( """Mapping to aggregate e.g. nl="World" from values for child nodes of "World". This mapping should be used with :func:`.genno.operator.aggregate`, giving the - argument ``keep=False``. It includes 1:1 mapping from each region name to itself. + argument :py:`keep=False`, because it includes 1:1 mapping from each region name to + itself. """ from message_ix_models.model.structure import get_codelist diff --git a/message_ix_models/report/util.py b/message_ix_models/report/util.py index c91bc3b2cc..a887f728ea 100644 --- a/message_ix_models/report/util.py +++ b/message_ix_models/report/util.py @@ -2,18 +2,14 @@ from collections.abc import Iterable from dataclasses import dataclass, field from itertools import count -from typing import TYPE_CHECKING import pandas as pd from dask.core import quote -from genno import Key, Keys +from genno import Computer, Key, Keys from genno.compat.pyam.util import collapse as genno_collapse from genno.core.key import single_key from message_ix import Reporter -from sdmx.model.v21 import Code - -if TYPE_CHECKING: - from genno import Computer +from sdmx.model.common import Code log = logging.getLogger(__name__) @@ -334,13 +330,87 @@ def add_replacements(dim: str, codes: Iterable[Code]) -> None: qux: {} # No "report" annotation → no mapping - …results in entries :py:`{"foo": "fOO", "bar": "Baz"}` added to :data:`REPLACE_DIMS` + …results in entries :py:`{"Foo": "fOO", "Bar": "Baz"}` added to :data:`REPLACE_DIMS` and used by :func:`collapse`. """ for code in codes: + # List of candidates + candidates = [code.id, code.name] try: - label = str(code.get_annotation(id="report").text) + # Append the value of the "report" annotation, if any + candidates.append(code.get_annotation(id="report").text) except KeyError: pass - else: + + # Final entry in the list with a non-empty string representation + label = next(filter(None, map(str, reversed(candidates)))) + + if label != code.id: REPLACE_DIMS[dim][f"{code.id.title()}$"] = label + + +# FIXME Type as "Computer" str alias, when supported by genno.Computer.apply() +def store_write_ts(c: Computer, base_key: Key) -> Key: + """Add tasks to store and write files with time-series data from `base_key`. + + `base_key` **should** refer to a task that returns time-series data in the IAMC + structure; that is, the format used by :meth:`ixmp.TimeSeries.add_timeseries`. + + If `base_key` is for instance "foo::iamc", this function adds the following keys: + + "foo::iamc+all" + Both of: + + "foo::iamc+file" + Both of: + + "foo::iamc+csv" + Write data in `base_key` to a file named :file:`foo.csv` in CSV format, + wherein the file stem is the same as the :attr:`.Key.name` of `base_key`. + "foo::iamc+xlsx" + Write the data in `base_key` to a file named :file:`foo.xlsx` in Excel + format. + + The two files are created in a subdirectory created with + :func:`make_output_path`, including a path component constructed from the + scenario URL. + + "foo::iamc+store" + Store the data in `base_key` as time series data on the + :class:`.Scenario` identified by the key "scenario", using + :func:`ixmp.report.operator.store_ts`. + + Other code **may** then :meth:`~.Reporter.get` one of the 3 keys, as needed, to + perform some or all of these tasks. + + Returns + ------- + Key + the "+all" key described above. + + Example + ------- + >>> rep = Reporter(...) + >>> result = rep.apply(store_write_ts, "foo::iamc") + >>> result + + """ + k = Key(base_key) + + file_keys = [] + for suffix in ("csv", "xlsx"): + # Create the path + name = f"{k.name}.{suffix}" + path = c.add(k[f"{suffix} path"], "make_output_path", "config", name=name) + # Write `key` to the path + file_keys.append(c.add(k[suffix], "write_report", base_key, path)) + + # Write all files + c.add(k["file"], "summarize", *file_keys) + + # Store data on "scenario" + c.add(k["store"], "store_ts", "scenario", base_key) + + # Both write and store + c.add(k["all"], "summarize", k["store"], *file_keys) + return k["all"] diff --git a/message_ix_models/testing/__init__.py b/message_ix_models/testing/__init__.py index 18a779d4b8..3432950d6f 100644 --- a/message_ix_models/testing/__init__.py +++ b/message_ix_models/testing/__init__.py @@ -20,6 +20,7 @@ import pytest import sdmx.exceptions from ixmp import config as ixmp_config +from packaging.version import Version from message_ix_models import util from message_ix_models.model import snapshot @@ -78,6 +79,11 @@ # 11: pytest.mark.timeout( # 600, method="thread" if platform.system() == "Windows" else "thread" # ), + 12: pytest.mark.xfail( + Version(version("message_ix")) < Version("3.12"), + reason="Requires MESSAGE cap-comm parameters, only available in message-ix " + ">=3.12", + ), "#375": pytest.mark.flaky( reruns=3, rerun_delay=2, diff --git a/message_ix_models/testing/check.py b/message_ix_models/testing/check.py index 18cccb343d..0242a2d7ce 100644 --- a/message_ix_models/testing/check.py +++ b/message_ix_models/testing/check.py @@ -10,6 +10,7 @@ from typing import TYPE_CHECKING, ClassVar, TypeVar import genno +import numpy as np import pandas as pd if TYPE_CHECKING: @@ -240,6 +241,35 @@ def run(self, obj): return True, f"Units are {self.units!r}" +@dataclass +class InRange(Check): + """Values are in expected range.""" + + #: Minimum value, if any. + min: float = -np.inf + + #: Maximum value, if any. + max: float = np.inf + + #: Absolute tolerance. + atol: float = 1e-8 + + types = (genno.Quantity,) + + def run(self, obj): + data = obj.to_series().rename("value").reset_index() + + result = data["value"] < (self.min - self.atol) + if result.any(axis=None): + return False, f"Values <{self.min} for {result.sum()} observations" + + result = data["value"] > (self.max + self.atol) + if result.any(axis=None): + return False, f"Values >{self.max} for {result.sum()} observations" + + return True, self._description + + @dataclass class NoDuplicates(Check): """No duplicate indices in parameter data.""" diff --git a/message_ix_models/tests/model/test_workflow.py b/message_ix_models/tests/model/test_workflow.py index 9b1ea175b2..59624f8366 100644 --- a/message_ix_models/tests/model/test_workflow.py +++ b/message_ix_models/tests/model/test_workflow.py @@ -1,18 +1,77 @@ +import re from typing import TYPE_CHECKING -from message_ix_models.model.workflow import step_0 +from sdmx.model import common, v21 + +from message_ix_models.model.transport.workflow import SOLVE_CONFIG +from message_ix_models.model.workflow import from_codelist, step_0 from message_ix_models.testing import bare_res from message_ix_models.tools import ( add_AFOLU_CO2_accounting, add_alternative_TCE_accounting, ) +from message_ix_models.util.sdmx import StructureFactory if TYPE_CHECKING: - from pytest import FixtureRequest + from pytest import FixtureRequest, LogCaptureFixture from message_ix_models import Context +class CL_SCENARIO_TEST(StructureFactory): + """A scenario code list for testing.""" + + urn = "IIASA_ECE:CL_SCENARIO_TEST" + version = "1.0.0" + base_url = "" + + @classmethod + def create(cls) -> "common.Codelist": + from sdmx.model import common + + from message_ix_models.util.sdmx import read + + IIASA_ECE = read("IIASA_ECE:AGENCIES")["IIASA_ECE"] + cl: "common.Codelist" = common.Codelist( + id=cls.urn.partition(":")[-1], + maintainer=IIASA_ECE, + version="1.0.0", + is_external_reference=False, + is_final=True, + ) + + anno: list["common.BaseAnnotation"] = [ + v21.Annotation(id="base-scenario-URL", text=repr(cls.base_url)) + ] + + for id_ in "FOO BAR BAZ".split(): + cl.append(common.Code(id=id_, annotations=anno)) + + return cl + + +@from_codelist.minimum_version +def test_from_codelist( + caplog: "LogCaptureFixture", request: "FixtureRequest", test_context: "Context" +) -> None: + test_context.model.regions = "R12" + scenario = bare_res(request, test_context, solved=False) + + # Use the `scenario` as the base for a new Workflow + CL_SCENARIO_TEST.base_url = f"ixmp://{scenario.platform.name}/{scenario.url}" + + # Use specific, non-default solve config + test_context.solve = SOLVE_CONFIG + + # from_codelist() runs without error + wf = from_codelist(test_context, CL_SCENARIO_TEST) + + # Specific CPLEX options from SOLVE_CONFIG are used in the solve step + wf.get("FOO solved") + + assert any(re.match("^Use CPLEX options.*'iis': 1", msg) for msg in caplog.messages) + + def test_step_0(request: "FixtureRequest", test_context: "Context") -> None: """Test :func:`.model.workflow.step_0`.""" test_context.model.regions = "R12" diff --git a/message_ix_models/tests/model/transport/test_build.py b/message_ix_models/tests/model/transport/test_build.py index 216dee5f48..ffbb92d315 100644 --- a/message_ix_models/tests/model/transport/test_build.py +++ b/message_ix_models/tests/model/transport/test_build.py @@ -81,7 +81,7 @@ def scenario_code() -> Iterator["Code"]: False, "IKARUS", False, - marks=[mark.slow, make_mark[2](genno.ComputationError)], + marks=[mark.slow, make_mark[2](RuntimeError)], ), # Pending iiasa/message_data#190 param("ISR", "A", True, None, False, marks=MARK[3]), @@ -144,10 +144,7 @@ def test_bare_res( ("R12", "B", dict(code="EDITS-CA")), ("R12", "B", dict(code="DIGSY-BEST-C")), pytest.param( - "R12", - "B", - dict(code="SSP2", extra_modules=["material"]), - marks=pytest.mark.xfail(raises=NotImplementedError), + "R12", "B", dict(code="SSP2", extra_modules=["material"]), marks=MARK[12] ), # param("R14", "B", {}, marks=MARK[9]), # param("ISR", "A", {}, marks=MARK[3]), @@ -180,10 +177,9 @@ def test_debug( Passed to :func:`.verbose_check`. """ # Get a Computer prepared to build the model with the given options - c, _ = configure_build(test_context, regions, years, tmp_path, options=options) - - # Fixture: a scenario - c.add("scenario", bare_res(request, test_context)) + c, _ = configure_build( + test_context, regions, years, tmp_path, with_base=request, options=options + ) # Insert key-specific and common checks result = check.insert(c, N_node, verbosity, tmp_path) diff --git a/message_ix_models/tests/model/transport/test_config.py b/message_ix_models/tests/model/transport/test_config.py index b468fc42b1..06c3a6da58 100644 --- a/message_ix_models/tests/model/transport/test_config.py +++ b/message_ix_models/tests/model/transport/test_config.py @@ -1,3 +1,5 @@ +from collections.abc import Iterator + import pytest from message_ix_models import Context @@ -39,9 +41,13 @@ class TestConfig: @pytest.fixture - def c(self): + def c(self) -> Iterator[Config]: yield Config() + def test_fields(self, c: Config) -> None: + """Settable class property included in :meth:`.ConfigHelper._fields`.""" + assert {"code"} & c._fields() + @pytest.mark.parametrize("input, expected", SSP) def test_ssp0(self, input, expected): """Set SSP through the constructor.""" @@ -96,7 +102,7 @@ def test_get(self, test_context: Context) -> None: result = CL_SCENARIO.get(force=True) # Code list has the expected length - assert 296 == len(result) + assert 366 == len(result) # Code list contains codes with the expected IDs assert { @@ -138,11 +144,11 @@ def test_get(self, test_context: Context) -> None: @pytest.mark.parametrize( "ssp_or_led, N_exp", ( - ("SSP1", 7), - ("SSP2", 22), - ("SSP3", 1), - ("SSP4", 5), - ("SSP5", 7), + ("SSP1", 10), + ("SSP2", 27), + ("SSP3", 3), + ("SSP4", 7), + ("SSP5", 10), ), ) def test_iter_price_emission(ssp_or_led: str, N_exp: int, regions="R12") -> None: diff --git a/message_ix_models/tests/model/transport/test_demand.py b/message_ix_models/tests/model/transport/test_demand.py index 36faacf178..424441d1db 100644 --- a/message_ix_models/tests/model/transport/test_demand.py +++ b/message_ix_models/tests/model/transport/test_demand.py @@ -234,6 +234,7 @@ def test_urban_rural_shares(test_context, tmp_path, regions, years, pop_scen): assert set(["UR+SU", "RU"]) == set(result.coords["area_type"].values) +@make_mark["gh"](471) @MARK["#375"] @build.get_computer.minimum_version @workflow.generate.minimum_version @@ -252,7 +253,7 @@ def test_cli(tmp_path, mix_models_cli, test_context, nodes, target): """Transport CLI can be used to generate build-phase debug outputs.""" # NB test_context is necessary so that the temporary, in-memory platform established # by .transport.workflow.generate() does not carry to other tests - cmd = ["transport", "run", f"--nodes={nodes}", f"{target} debug build", "--go"] + cmd = ["transport", "run", f"--nodes={nodes}", f"{target} T debug build", "--go"] result = mix_models_cli.assert_exit_0(cmd) # Identify the path containing the outputs diff --git a/message_ix_models/tests/model/transport/test_ldv.py b/message_ix_models/tests/model/transport/test_ldv.py index 0656b2a1fe..fb75a7c047 100644 --- a/message_ix_models/tests/model/transport/test_ldv.py +++ b/message_ix_models/tests/model/transport/test_ldv.py @@ -54,16 +54,7 @@ def test_get_ldv_data(tmp_path, test_context, dummy_LDV, regions, years) -> None # TODO Merge the following with test_build.test_debug() using Check objects # Data are returned for the following parameters - exp_pars = { - "bound_new_capacity_lo", - "bound_new_capacity_up", - "capacity_factor", - "historical_new_capacity", - "input", - "output", - "technical_lifetime", - "var_cost", - } + exp_pars = {"capacity_factor", "input", "output", "var_cost"} if not dummy_LDV: exp_pars |= { "emission_factor", @@ -139,7 +130,7 @@ def include(arg): # No missing entries assert not df.isna().any(axis=None), df.tostring() - if "year_vtg" not in df.columns: + if "year_vtg" not in df.columns or par_name == "capacity_factor": continue # Data covers at least these periods diff --git a/message_ix_models/tests/model/transport/test_material.py b/message_ix_models/tests/model/transport/test_material.py new file mode 100644 index 0000000000..832f344e8f --- /dev/null +++ b/message_ix_models/tests/model/transport/test_material.py @@ -0,0 +1,15 @@ +from message_ix_models import Context +from message_ix_models.model.transport import Config +from message_ix_models.model.transport.material import get_groups + + +def test_get_groups(test_context: Context) -> None: + # Prepare a Config instance + cfg = Config.from_context(test_context) + + # Function runs without error + result = get_groups(cfg) + + # Does not contain mispellings of the technologies in technology.yaml + assert "ICAe_ptrp" not in result["t"] + assert "ICEm_ptrp" not in result["t"] diff --git a/message_ix_models/tests/model/transport/test_report.py b/message_ix_models/tests/model/transport/test_report.py index ba1930dd72..f62fe84ada 100644 --- a/message_ix_models/tests/model/transport/test_report.py +++ b/message_ix_models/tests/model/transport/test_report.py @@ -136,7 +136,7 @@ def test_debug( @pytest.mark.parametrize( "regions, years", ( - param("R11", "A", marks=make_mark[2](ValueError)), + param("R11", "A", marks=make_mark[2](RuntimeError)), ("R12", "B"), param("R14", "A", marks=MARK[9]), param("ISR", "A", marks=MARK[3]), @@ -180,6 +180,10 @@ def test_bare( rep, key1 = prepare_reporter(test_context, scenario) + # commented: Generate 'full' task graphs for presentation materials + # rep.visualize("transport-report.svg", "transport all", rankdir="LR") + # rep.visualize("transport-build.svg", "add transport data", rankdir="LR") + # Reporting `key` succeeds rep.get(key1) @@ -222,7 +226,7 @@ def test_simulated( rep.get(k) # A quantity for message_ix_models.model.transport can be computed - k = "transport stock::iamc" + k = "T stock::iamc" result = rep.get(k) assert 0 < len(result) @@ -283,14 +287,18 @@ def test_simulated_iamc( # Retrieve time series data stored on the scenario object ts = s.timeseries() - # print(ts, ts["variable"].unique(), sep="\n") # DEBUG + # print( # DEBUG + # ts.head().to_string(), + # ts.tail().to_string(), + # "\n".join(sorted(ts["variable"].unique())), + # sep="\n", + # ) # The reported data was stored on the scenario, and has expected variable names - # print("\n".join(sorted(ts["variable"].unique()))) # DEBUG assert { "Energy Service|Transportation|Domestic Aviation", "Final Energy|Transportation|Bus", - "Transport|Stock|Road|Passenger|LDV|BEV", + "Stocks|Transportation|Light-Duty Vehicle|Battery-Electric", } <= set(ts["variable"].unique()) del result diff --git a/message_ix_models/tests/model/transport/test_structure.py b/message_ix_models/tests/model/transport/test_structure.py new file mode 100644 index 0000000000..36c40dd529 --- /dev/null +++ b/message_ix_models/tests/model/transport/test_structure.py @@ -0,0 +1,45 @@ +from message_ix_models import Context +from message_ix_models.model.transport import Config +from message_ix_models.model.transport.structure import ( + get_commodity_groups, + get_technology_groups, +) + + +def test_get_commodity_groups(test_context: Context) -> None: + config = Config.from_context(test_context) + + # Function runs + c = get_commodity_groups(config.spec) + + # The "_T" groups is equal to the union of all others + assert set( + c["activity P"] + c["activity F"] + c["disutility"] + c["vehicle activity"] + ) == set(c["_T"]) + + +def test_get_technology_groups(test_context: Context) -> None: + config = Config.from_context(test_context) + + # Function runs + t = get_technology_groups(config.spec) + + # Vehicle technologies for each mode are present + assert {"2W", "AIR", "BUS", "F RAIL", "F ROAD", "LDV", "RAIL"} < set(t) + + # Vehicle technologies for each service are present + assert {"F", "P"} < set(t) + + # Service groups aggregate vehicle technologies for related modes + assert set(t["2W"] + t["AIR"] + t["BUS"] + t["LDV"] + t["RAIL"]) == set(t["P"]) + assert set(t["F RAIL"] + t["F ROAD"]) == set(t["F"]) + + # All vehicle technologies + assert not any(" usage" in tech for tech in t["vehicle"]), t["vehicle"] + assert set(t["F"] + t["P"] + t["OTHER"]) == set(t["vehicle"]) + + # # of LDV usage technologies: 27 consumer groups × # of LDV technologies + assert 27 * len(t["LDV"]) == len(t["usage LDV"]) + + # Vehicle and usage technologies + assert set(t["vehicle"] + t["usage"]) == set(t["_T"]) diff --git a/message_ix_models/tests/model/transport/test_workflow.py b/message_ix_models/tests/model/transport/test_workflow.py index 5e1bc573f7..ab0ec74cfb 100644 --- a/message_ix_models/tests/model/transport/test_workflow.py +++ b/message_ix_models/tests/model/transport/test_workflow.py @@ -1,6 +1,6 @@ import pytest -from message_ix_models.model.transport.workflow import generate +from message_ix_models.model.transport.workflow import SOLVE_CONFIG, generate from message_ix_models.project.digsy.structure import SCENARIO as DIGSY from message_ix_models.project.edits.structure import SCENARIO as EDITS @@ -22,6 +22,13 @@ def test_generate(test_context, base_scenario) -> None: # Workflow is generated wf = generate(test_context, base_scenario=base_scenario) + # SOLVE_CONFIG is stored to be used for "… solve" steps + ctx = wf.graph["context"] + assert ctx.solve == SOLVE_CONFIG + + # The default reporting key is set to "transport all" + assert "transport all" == ctx.report.key + # Workflow contains some expected steps assert "EDITS-HA reported" in wf assert "LED-SSP1 reported" in wf @@ -31,12 +38,9 @@ def test_generate(test_context, base_scenario) -> None: assert "SSP5 exo price 5cab reported" in wf # WorkflowStep objects store expected configuration for certain projects - assert ( - DIGSY["BEST-C"] - is wf.graph["DIGSY-BEST-C built"][0].kwargs["config"].project["DIGSY"] - ) - assert ( - EDITS["HA"] is wf.graph["EDITS-HA built"][0].kwargs["config"].project["EDITS"] - ) + step = wf.graph["DIGSY-BEST-C T built"][0] + assert DIGSY["BEST-C"] is step.kwargs["config"].project["DIGSY"] + step = wf.graph["EDITS-HA T built"][0] + assert EDITS["HA"] is step.kwargs["config"].project["EDITS"] # wf.run("LED-SSP1 reported") # NB Only works with base_scenario="bare" diff --git a/message_ix_models/tests/project/circeular/test_structure.py b/message_ix_models/tests/project/circeular/test_structure.py index cb8c9184fa..c28286afc0 100644 --- a/message_ix_models/tests/project/circeular/test_structure.py +++ b/message_ix_models/tests/project/circeular/test_structure.py @@ -10,6 +10,6 @@ def test_create(self) -> None: assert 8 == len(result) # An expected item is in the code list - item = result["_CC_C_D_D"] + item = result["CC-C-D-D"] # Description contains scenario information assert "regional=convergence, material=default" == str(item.description) diff --git a/message_ix_models/tests/project/circeular/test_workflow.py b/message_ix_models/tests/project/circeular/test_workflow.py new file mode 100644 index 0000000000..83916aa60e --- /dev/null +++ b/message_ix_models/tests/project/circeular/test_workflow.py @@ -0,0 +1,10 @@ +from message_ix_models import Context +from message_ix_models.model.workflow import from_codelist +from message_ix_models.project.circeular.workflow import generate + + +@from_codelist.minimum_version +def test_generate(test_context: Context) -> None: + wf = generate(test_context) + # TODO Expand with additional assertions + del wf diff --git a/message_ix_models/tests/project/test_navigate.py b/message_ix_models/tests/project/test_navigate.py index ae1939ab23..e077203246 100644 --- a/message_ix_models/tests/project/test_navigate.py +++ b/message_ix_models/tests/project/test_navigate.py @@ -48,7 +48,7 @@ def test_generate_workflow(test_context: "Context") -> None: # displays "MT solved" and its subtree may vary. _context = r"'context' \(above\)" BLOCKS = [ - "Truncate workflow at 'M T3.5 built'", + "Truncate workflow at 1 point matching 'M T3.5 built'", rf""" (\s+)- 'MT NPi-ref solved': \1- diff --git a/message_ix_models/tests/test_workflow.py b/message_ix_models/tests/test_workflow.py index 581c99d0b5..5cb39a6ac4 100644 --- a/message_ix_models/tests/test_workflow.py +++ b/message_ix_models/tests/test_workflow.py @@ -113,7 +113,7 @@ def test_make_click_command( # Invoke the command with various parameters for params, output in ( (["--go", "B"], "nothing returned, workflow will continue with"), - (["B"], "Workflow diagram written to"), + (["B"], "Write workflow diagram to"), ): # Command runs and exits with 0 result = mix_models_cli.assert_exit_0(["_test", "run"] + params) diff --git a/message_ix_models/tests/util/test_config.py b/message_ix_models/tests/util/test_config.py index 0d77cf21fb..f883652243 100644 --- a/message_ix_models/tests/util/test_config.py +++ b/message_ix_models/tests/util/test_config.py @@ -1,68 +1,70 @@ from dataclasses import dataclass, field +from pathlib import Path import pytest from message_ix_models.util.config import ConfigHelper -class TestConfigHelper: - @pytest.fixture - def cls(self) -> type: - """A class which inherits from ConfigHelper.""" +@dataclass +class C1(ConfigHelper): + """A class which inherits from ConfigHelper.""" - @dataclass - class Config(ConfigHelper): - foo_1: int = 1 - foo_2: str = "" - foo_3: bool = True + foo_1: int = 1 + foo_2: str = "" + foo_3: bool = True - return Config - @pytest.fixture - def cls2(self, cls) -> type: - """A class with an attribute.""" +@dataclass +class C2: + """NOT a ConfigHelper subclass.""" + + baz_1: int = 1 + baz_2: int = 2 - @dataclass - class Config3: - """NOT a ConfigHelper subclass.""" - baz_1: int = 1 - baz_2: int = 2 +@dataclass +class C3(ConfigHelper): + """A class with a plain attribute and 2 instances of classes.""" - @dataclass - class Config2(ConfigHelper): - bar_1: float = 0.01 - subconfig_a: cls = field(default_factory=cls) # type: ignore [valid-type] - subconfig_b: Config3 = field(default_factory=Config3) + bar_1: float = 0.01 + subconfig_a: C1 = field(default_factory=C1) + subconfig_b: C2 = field(default_factory=C2) - return Config2 +class TestConfigHelper: @pytest.fixture - def c(self, cls): - return cls(foo_1=99, foo_2="bar", foo_3=False) + def c(self) -> C1: + return C1(foo_1=99, foo_2="bar", foo_3=False) @pytest.fixture - def c2(self, cls, cls2): - result = cls2(bar_1=3.14, subconfig_a=cls(foo_1=99, foo_2="bar", foo_3=False)) + def c2(self) -> C3: + result = C3(bar_1=3.14, subconfig_a=C1(foo_1=99, foo_2="bar", foo_3=False)) result.subconfig_b.baz_1 = 2 result.subconfig_b.baz_2 = 1 return result - def test_canonical_name(self, cls): - assert "foo_1" == cls._canonical_name("foo 1") - assert "foo_2" == cls._canonical_name("foo-2") - assert "foo_3" == cls._canonical_name("foo_3") - assert None is cls._canonical_name("foo 4") + def test_canonical_name(self) -> None: + assert "foo_1" == C1._canonical_name("foo 1") + assert "foo_2" == C1._canonical_name("foo-2") + assert "foo_3" == C1._canonical_name("foo_3") + assert None is C1._canonical_name("foo 4") - def test_from_dict(self, cls, c): + def test_from_dict(self, c: C1) -> None: values = {"foo 1": 99, "foo-2": "bar", "foo_3": False} - assert c == cls.from_dict({"foo 1": 99, "foo-2": "bar", "foo_3": False}) + assert c == C1.from_dict({"foo 1": 99, "foo-2": "bar", "foo_3": False}) values.update(foo_4=3.14) with pytest.raises(ValueError): - cls.from_dict(values) - - def test_read_file(self, caplog, tmp_path, cls, cls2, c, c2): + C1.from_dict(values) + + def test_read_file( + self, + caplog: pytest.LogCaptureFixture, + tmp_path: Path, + c: C1, + c2: C3, + ) -> None: # Write a YAML snippet to file yaml_path = tmp_path.joinpath("config.yaml") yaml_path.write_text( @@ -77,16 +79,10 @@ def test_read_file(self, caplog, tmp_path, cls, cls2, c, c2): """ ) - obj1 = cls() + obj1 = C1() # Method runs - obj1.read_file(yaml_path, fail=False) - # Values are read - assert c == obj1, obj1 - # Messages are logged - assert [ - "Config has no attribute for file section 'foo_4'; ignored" - ] == caplog.messages - caplog.clear() + with pytest.raises(ValueError, match="no attribute for file section 'foo_4'"): + obj1.read_file(yaml_path) yaml_path.write_text( """ @@ -101,9 +97,9 @@ def test_read_file(self, caplog, tmp_path, cls, cls2, c, c2): """ ) - obj2 = cls2() + obj2 = C3() # Method runs - obj2.read_file(yaml_path, fail=False) + obj2.read_file(yaml_path) # Values are read assert c2 == obj2, obj2 @@ -116,22 +112,22 @@ def test_read_file(self, caplog, tmp_path, cls, cls2, c, c2): } """ ) - obj3 = cls() + obj3 = C1() # Method runs obj3.read_file(json_path) # Values are read assert c == obj3, obj3 - obj4 = cls() + obj4 = C1() with pytest.raises(NotImplementedError): obj4.read_file(yaml_path.with_suffix(".xlsx")) - def test_replace(self, c): + def test_replace(self, c: C1) -> None: result = c.replace(foo_2="baz") assert result is not c assert "baz" == result.foo_2 - def test_update(self, c): + def test_update(self, c: C1) -> None: """:meth:`.ConfigHelper.update` raises AttributeError.""" with pytest.raises(AttributeError): c.update(foo_4="") diff --git a/message_ix_models/tests/util/test_sdmx.py b/message_ix_models/tests/util/test_sdmx.py index 8ebd2cb7c9..9084ce3c79 100644 --- a/message_ix_models/tests/util/test_sdmx.py +++ b/message_ix_models/tests/util/test_sdmx.py @@ -185,6 +185,26 @@ def _get_item_scheme(self): assert _exp_max_value(E2) == max(member.value for member in E2) +class TestURNLookupEnum: + @pytest.fixture + def obj(self): + class Foo(URNLookupEnum, metaclass=ItemSchemeEnumType): + def _get_item_scheme(self): + return read("AGENCIES") + + return Foo["IIASA_ECE"] + + def test_urn(self, obj: URNLookupEnum) -> None: + """:attr:`.urn` retrieves the string URN for an enumeration member.""" + assert re.fullmatch( + rf"{_urn_prefix}.base.Agency=IIASA_ECE:AGENCIES.*\.IIASA_ECE", obj.urn + ) + + def test_str(self, obj: URNLookupEnum) -> None: + """:func:`str` on a member retrieves a partial URN.""" + assert re.fullmatch(r"IIASA_ECE:AGENCIES.*\.IIASA_ECE", str(obj)) + + def test_eval_anno(caplog, recwarn): c = Code() diff --git a/message_ix_models/util/__init__.py b/message_ix_models/util/__init__.py index dd21ec9784..2645e591a1 100644 --- a/message_ix_models/util/__init__.py +++ b/message_ix_models/util/__init__.py @@ -3,6 +3,7 @@ from collections.abc import Collection, Iterable, Mapping, MutableMapping, Sequence from datetime import datetime from functools import partial, singledispatch +from hashlib import blake2s from itertools import count from pathlib import Path from typing import TYPE_CHECKING, Any, Literal, Protocol @@ -781,6 +782,11 @@ def _(data: "MutableParameterData") -> "MutableParameterData": return data +def short_hash(value: str, len: int = 3) -> str: + """Return a short (length `len`) hash of `value`.""" + return blake2s(value.encode()).hexdigest()[:len] + + def show_versions() -> str: """Output of :func:`ixmp.show_versions`, as a :class:`str`.""" from io import StringIO diff --git a/message_ix_models/util/common.py b/message_ix_models/util/common.py index f19740c887..60b3f9f324 100644 --- a/message_ix_models/util/common.py +++ b/message_ix_models/util/common.py @@ -191,7 +191,10 @@ def adapt(self, qty: "TQuantity") -> "TQuantity": class WildcardAdapter(Adapter): """Adapt data using by broadcasting wildcard ("*") entries for 1 dimension.""" + #: Dimension on which to expand wildcard. dim: str + + #: Expected full list of coords along :attr:`dim`. coords: set[str] def __init__(self, dim: str, coords: Sequence[str]) -> None: diff --git a/message_ix_models/util/config.py b/message_ix_models/util/config.py index 6f01f313e7..446e255c8e 100644 --- a/message_ix_models/util/config.py +++ b/message_ix_models/util/config.py @@ -1,7 +1,7 @@ import logging import os import pickle -from collections.abc import Mapping, MutableMapping, Sequence +from collections.abc import Iterator, Mapping, MutableMapping, Sequence from dataclasses import dataclass, field, fields, is_dataclass, replace from hashlib import blake2s from pathlib import Path @@ -38,7 +38,7 @@ def _cache_path_factory() -> Path: ) -def _local_data_factory() -> Path: +def _local_data_factory(*parts: str) -> Path: """Default value for :attr:`.Config.local_data.""" from platformdirs import user_data_path @@ -50,6 +50,7 @@ def _local_data_factory() -> Path: ) .expanduser() .resolve() + .joinpath(*parts) ) @@ -66,13 +67,13 @@ class ConfigHelper: legible ways—e.g. "attribute name" or “attribute-name” instead of "attribute_name"— in configuration files and/or code. - It also add :meth:`hexdigest`. + It also adds :meth:`hexdigest`. """ @classmethod def _fields(cls) -> set[str]: """Names of fields in `cls`.""" - result = set(dir(cls)) + result = set(filter(lambda n: not n.startswith("_"), dir(cls))) if is_dataclass(cls): result |= set(map(lambda f: f.name, fields(cls))) return result @@ -84,20 +85,35 @@ def _canonical_name(cls, name: Hashable) -> str | None: return _name if _name in cls._fields() else None @classmethod - def _munge_dict(cls, data: Mapping[Hashable, Any], fail: str, kind: str): - for key, value in data.items(): - name = cls._canonical_name(key) + def _canonicalize( + cls, + data: Mapping[str, Any] | Mapping[Hashable, Any], + kind: str, + fail: type[Exception] | None = None, + ) -> Iterator[tuple[str, Any]]: + """Modify `data` by passing keys through :meth:`_canonical_name`. - if name: + Parameters + ---------- + kind + Used to format exception or log message. + """ + for key, value in data.items(): + if name := cls._canonical_name(key): yield name, value else: msg = f"{cls.__name__} has no attribute for {kind} {key!r}" - if fail == "raise": - raise ValueError(msg) + if fail is None: + log.info(msg) else: - log.info(f"{msg}; ignored") + raise fail(msg) + + def __iter__(self) -> Iterator[tuple[str, Any]]: + """Iterate over (field, value) pairs.""" + for f in self._fields(): + yield f, getattr(self, f) - def read_file(self, path: Path, fail="raise") -> None: + def read_file(self, path: Path) -> None: """Update configuration from file. Parameters @@ -109,11 +125,13 @@ def read_file(self, path: Path, fail="raise") -> None: of the dataclass raise a ValueError. Otherwise, a message is logged. """ if path.suffix == ".yaml": + # Read data from YAML import yaml with open(path, encoding="utf-8") as f: data = yaml.safe_load(f) elif path.suffix == ".json": + # Read data from JSON import json with open(path) as f: @@ -121,7 +139,7 @@ def read_file(self, path: Path, fail="raise") -> None: else: raise NotImplementedError(f"Read from {path.suffix}") - for key, value in self._munge_dict(data, fail, "file section"): + for key, value in self._canonicalize(data, "file section", ValueError): existing = getattr(self, key, None) if is_dataclass(existing) and not isinstance(existing, type): # Attribute value is also a dataclass; update it recursively @@ -137,11 +155,10 @@ def read_file(self, path: Path, fail="raise") -> None: def replace(self, **kwargs): """Like :func:`dataclasses.replace` with name manipulation.""" return replace( - self, - **{k: v for k, v in self._munge_dict(kwargs, "raise", "keyword argument")}, + self, **dict(self._canonicalize(kwargs, "keyword argument", ValueError)) ) - def update(self, **kwargs): + def update(self, arg: Mapping | None = None, **kwargs) -> None: """Update attributes in-place. Raises @@ -149,16 +166,15 @@ def update(self, **kwargs): AttributeError Any of the `kwargs` are not fields in the data class. """ - # TODO use _munge_dict(); allow a positional argument - for k, v in kwargs.items(): - if not hasattr(self, k): - raise AttributeError(k) + # Merge a positional argument and keyword arguments + data = dict(arg or {}) | kwargs + for k, v in self._canonicalize(data, "value", AttributeError): setattr(self, k, v) @classmethod def from_dict(cls, data: Mapping): """Construct an instance from `data` with name manipulation.""" - return cls(**{k: v for k, v in cls._munge_dict(data, "raise", "mapping key")}) + return cls(**dict(cls._canonicalize(data, "mapping key", ValueError))) def hexdigest(self, length: int = -1) -> str: """Return a hex digest that is unique for distinct settings on the instance. diff --git a/message_ix_models/util/context.py b/message_ix_models/util/context.py index 334999cc73..e460aedb8d 100644 --- a/message_ix_models/util/context.py +++ b/message_ix_models/util/context.py @@ -235,10 +235,18 @@ def pop(self, name, default=_Missing): def setdefault(self, name, value): return self._values.setdefault(name, value) - def update(self, arg=None, **kwargs): - # Force update() to use set(), above + def update(self, arg: Any = None, **kwargs) -> None: + """Update the Context. + + `arg` may be a :class:`dict` or nested :class:`dict`. + """ for k, v in dict(*filter(None, [arg]), **kwargs).items(): - self.set(k, v) + if k in self and hasattr(self[k], "update"): + # Use ConfigHelper.update(), e.g. .transport.Config.update() + self[k].update(v) + else: + # Force update() to use dealiasing via set(), above + self.set(k, v) def __deepcopy__(self, memo): result = Context() # Create a new instance; this also updates _CONTEXTS diff --git a/message_ix_models/util/sdmx.py b/message_ix_models/util/sdmx.py index 8807358bec..cc0360d167 100644 --- a/message_ix_models/util/sdmx.py +++ b/message_ix_models/util/sdmx.py @@ -444,17 +444,24 @@ def get(cls, *, force: bool = False) -> MaintainableT: and up-to-date version of the artefact as of :attr:`version`. This updated version is stored using :func:`write`. """ - existing = read(cls.urn) + try: + # Read the existing artefact from file + existing = read(cls.urn) + except FileNotFoundError: + # No existing file + existing = None - if existing.version != cls.version or force: + if existing is None or existing.version != cls.version or force: result = cls.create() # Touch up `existing` for a fair comparison - existing.maintainer = result.maintainer + if existing is not None: + existing.maintainer = result.maintainer # Compare `existing` and `result` - if not existing.compare(result, strict=True): + if existing is None or not existing.compare(result, strict=True): # `result` somehow differs from `existing`: + # - No existing artefact. # - `existing` is an older version; cls.version has been bumped. # - Some other change to cls.generate()` @@ -495,6 +502,11 @@ def urn(self) -> str: break return result + def __str__(self) -> str: + return self.urn.partition("=")[2] + + __repr__ = __str__ + class URNLookupEnum(URNLookupMixin, Enum): """Class constructed by ItemSchemeEnumType.""" diff --git a/message_ix_models/workflow.py b/message_ix_models/workflow.py index 641811ca5f..678cbfacce 100644 --- a/message_ix_models/workflow.py +++ b/message_ix_models/workflow.py @@ -206,7 +206,7 @@ def run(self, name_or_names: str | list[str]): """ return self.get(name_or_names) - def truncate(self, name: str): + def truncate(self, name: str) -> None: """Truncate the workflow at the step `name`. The step `name` is replaced with a new :class:`WorkflowStep` that simply loads @@ -306,8 +306,8 @@ def make_click_command(wf_callback: str, name: str, slug: str, **kwargs) -> "Com help_arg = f"""Run the {name} workflow up to step TARGET. - Unless --go is given, the workflow is only displayed. - --from is interpreted as a regular expression. + Unless --go is given, the workflow is only displayed, and a visualization written + to a file. --from is interpreted as a regular expression. """ @click.command(name="run", help=help_arg, **kwargs) @@ -317,7 +317,7 @@ def make_click_command(wf_callback: str, name: str, slug: str, **kwargs) -> "Com ) @click.argument("target_step", metavar="TARGET", required=False) @click.pass_obj - def _func(context, go, truncate_step, target_step, **kwargs): + def _func(context, go, truncate_step, target_step: str | None, **kwargs): from importlib import import_module from message_ix_models.util import show_versions @@ -336,9 +336,15 @@ def _func(context, go, truncate_step, target_step, **kwargs): except AttributeError: pass # truncate_step is None else: + N_truncate = 0 for step in filter(expr.fullmatch, wf.keys()): - log.info(f"Truncate workflow at {step!r}") wf.truncate(step) + N_truncate += 1 + log.info( + f"Truncate workflow at {N_truncate} point" + + ("s" if N_truncate != 1 else "") + + f" matching {truncate_step!r}" + ) # Identify the target step if target_step: @@ -368,12 +374,9 @@ def _func(context, go, truncate_step, target_step, **kwargs): if not go: path = context.get_local_path(f"{slug}-workflow.svg") - wf.visualize( - str(path), - # key=target_step, # DEBUG Uncomment to show only a subset of steps - rankdir="LR", - ) - log.info(f"Workflow diagram written to {path}") + log.info(f"Write workflow diagram to {path}") + # If target_step is given, show only this step + wf.visualize(path, key=target_step, rankdir="LR") return wf.run(target_step) diff --git a/pyproject.toml b/pyproject.toml index 932c271f4f..f911d76bd2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -87,6 +87,7 @@ tests = [ "gamsapi > 47.6.0", ] transport = [ + "genno[graphviz]", "message-ix-models[iea-web,report]", "requests-cache", "transport-energy",