tz-osemosys


Nametz-osemosys JSON
Version 0.0.16 PyPI version JSON
download
home_pageNone
SummaryAn OSeMOSYS implementation for the Future Energy Outlook by TransitionZero
upload_time2024-10-29 15:25:57
maintainerNone
docs_urlNone
authorNone
requires_python>=3.11
licenseNone
keywords energy milp climate
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            <picture>
  <source media="(prefers-color-scheme: dark)" srcset="https://github.com/transition-zero/.github/raw/main/profile/img/logo-dark.png">
  <img alt="TransitionZero Logo" width="1000px" src="https://github.com/transition-zero/.github/raw/main/profile/img/logo-light.png">
  <a href="https://www.transitionzero.org/">
</picture>

# TZ-OSEMOSYS - a modern long-run systems modelling framework

<!-- badges-begin -->

[![License][license badge]][license]
[![Contributor Covenant][contributor covenant badge]][code of conduct]
![Tests][tests badge]
![Coverage][coverage badge]
![Python][python badge]
![Status][status badge]

[license badge]: https://img.shields.io/github/license/ad-aures/castopod?color=blue
[license]: https://opensource.org/license/agpl-v3

[contributor covenant badge]: https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg
[code of conduct]: https://github.com/transition-zero/tz-osemosys/blob/main/CODE-OF-CONDUCT.md

[tests badge]: https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/Lkruitwagen/feffb38d46c750cad5402dca5dd54bf9/raw/tests_passing.json

[coverage badge]: https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/Lkruitwagen/6afead97828812b3c9ad498c94dd45f8/raw/coverage_badge.json

[python badge]: https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/Lkruitwagen/bd1e357c1bce5fc2c0808bcdb569157c/raw/python_version_badge.json

[status badge]: https://img.shields.io/badge/under%20construction-ffae00

<!-- badges-end -->


**OSeMOSYS** is an open source modelling system for long-run systems analysis and planning.
It has been employed to develop energy systems models from the scale of the globe, continents, countries, regions, and villages.
OSeMOSYS is extremely flexible - it can be used for high-fidelity representations of power systems, rich with technological detail;
medium-fidelity representations of all-energy systems including upstream energy supply, final energy demand, and climate policities;
or low-fidelity nexus problems including commodities like materials, energy, and financing, and a range of environomental and social impacts.

OSeMOSYS is entirely open-source and can be used with a variety of programming languages and solvers.

## OSeMOSYS with the Future Energy Outlook

TransitionZero has rebuilt OSeMOSYS as a pip-installable Python package (tz-osemosys).
This implementation of OSeMOSYS underlies our Future Energy Outlook capacity expansion model builder.
We have added the following features:

* [Pydantic](https://docs.pydantic.dev/latest/)-based model construction and validation
* [Linopy](https://linopy.readthedocs.io/en/latest/)-based numerical optimsation and solving
* Reverse-compatability with [OSeMOSYS-otoole](https://github.com/OSeMOSYS/otoole)

## Documentation

[TZ-OSeMOSYS](https://docs.feo.transitionzero.org/)

[Examples](examples)

[TransitionZero Platform Docs](https://docs.feo.transitionzero.org/)

[OSeMOSYS Docs](https://osemosys.readthedocs.io/en/latest/)

## Installation

TZ-OSeMOSYS can be installed with a simple `pip install tz-osemosys`. To solve a model, however, you'll need a solver. Any solver compatible with [Linopy](https://linopy.readthedocs.io/en/latest/) will work: [Coin-OR CBC](https://github.com/coin-or/Cbc), [GLPK](https://www.gnu.org/software/glpk/), [HiGHS](https://highs.dev/), [Gurobi](https://www.gurobi.com/solutions/gurobi-optimizer/), [CPLEX](https://dev.ampl.com/solvers/cplex/index.html), and more. We recommend HiGHS, the leading open-source solver.

### Solver Installation - HiGHS

HiGHS can be installed from source using `cmake` following the instructions [here](https://github.com/ERGO-Code/HiGHS?tab=readme-ov-file#installation). You'll need to install a cmake distribution for your relevant operating system.

*common issue: make sure you have write-privileges to default directory for `cmake --install build`, or either run this command with administrator privileges (`sudo cmake --install build` on mac and linux) or specify a different build directory*

### Docker installation

A docker container is provided that contains Python 3.11 and an installed version of HiGHS. You'll need to [install a docker distribution](https://docs.docker.com/engine/install/) relevant for your operating system.

The docker container is used in testing, but can also be used for local development work. The following docker command will run and enter the docker container, mount the current working directory at the `/home` directory, and change directory within the container to this directory.

```console
docker run -v $(pwd):/home -it  ghcr.io/transition-zero/tz-highs/highs-python:latest /bin/bash -c 'cd /home && /bin/bash'
```

*note! Any files changed within this mounted directory will persist, but any changes to environments, installed packes, etc. will not!*

## Quickstart

TZ-OSeMOSYS provides several entrypoints to get started quickly, however your model is specified.

### From Pydantic objects

Models can be specified directly with Pydantic objects. Pydantic gives useful tooling for class inheritance and field validation. The Model class and subclasses provide obvious semantic linking between the object types. The set of objects comprising the model is mutually exclusive - no information is repeated - and collectively exhaustive - no information needs to be extracted from csvs or other data sources.

```python
from tz.osemosys import (
    Model,
    Technology,
    TimeDefinition,
    Commodity,
    Region,
    Impact,
    OperatingMode,
)

time_definition = TimeDefinition(id="years-only", years=range(2020, 2051))
regions = [Region(id="single-region")]
commodities = [Commodity(id="electricity", demand_annual=25 * 8760)]  # 25GW * 8760hr/yr
impacts = [Impact(id="CO2", penalty=60)]  # 60 $mn/Mtonne
technologies = [
    Technology(
        id="coal-gen",
        operating_life=40,  # years
        capex=800,  # mn$/GW
        # straight-line reduction to 2040
        residual_capacity={
            yr: 25 * max((1 - (yr - 2020) / (2040 - 2020), 0))
            for yr in range(2020, 2051)
        },
        operating_modes=[
            OperatingMode(
                id="generation",
                # $mn20/Mt.coal / 8.14 TWh/Mt coal * 8760 GWh/GW / 0.3 /1000 GWh/TWh (therm eff)
                opex_variable=20 / 8.14 * 8760 / 0.3 / 1000,  # $71/GW/yr
                output_activity_ratio={"electricity": 1.0 * 8760},  # GWh/yr/GW
                emission_activity_ratio={
                    "CO2": 0.354 * 8760 / 1000
                },  # Mtco2/TWh * 8760GWh/Gw/yr /1000 GWh/TWh
            )
        ],
    ),
    Technology(
        id="solar-pv",
        operating_life=25,
        capex=1200,
        capacity_factor=0.3,
        operating_modes=[
            OperatingMode(
                id="generation",
                opex_variable=0,
                output_activity_ratio={"electricity": 1.0 * 8760},  # GWh/yr/GW
            )
        ],
    ),
]

model = Model(
    id="simple-carbon-price",
    time_definition=time_definition,
    regions=regions,
    commodities=commodities,
    impacts=impacts,
    technologies=technologies,
)

model.solve()
```


### From Yaml

YAML is a human-readable data serialisation language. We've build a custom YAML parser that allows the creation of model configurations that are _exhaustive_ while also being _expressive_.

- model fields can be cross-referenced in the yaml blob, e.g. `my_field: ${commodities[0].COAL.demand}`.
- model fields can also be populated from environment variables: `my_field: $ENV{MYVAR}`.
- simple Python expressions are automatically evaluated, including list comprehensions, dictionary comprehensions, `min`, `max`, `sum`, and `range` functions.
- for data keyed by an osemosys `set` (e.g. `YEARS`, `TIMESLICES`, `TECHNOLOGIES`), wildcards `"*"` can be used in place of explicitly listing all set members.
- data field `set` dimensions and membership are also automatically inferred - a single value can be given which will be broadcast to all set member combinations.
- single or multiple `.yaml` files can be composed together, allowing you to separate, e.g. `technologies.yaml`, from the rest of your model.
- with `cloudpathlib` and a cloud storage provider SDK installed the path to yaml files can be a cloud storage object URI. See <https://cloudpathlib.drivendata.org/stable/> for more details.
- `pip install "tz-osemosys[cloudpath]"` will install `cloudpathlib` and python client libraries for cloud storage provider SDKs.

```python
from tz.osemosys import Model

my_model = Model.from_yaml("path/to/yaml/directory")
```

### From Otoole outputs (legacy)

TZ-OSeMOSYS is provided with backwards compatability with the [otoole](https://github.com/OSeMOSYS/otoole) osemosys tooling. Any legacy models can be loaded from the directory of otoole-formatted csvs.

```python
from tz.osemosys import Model

my_model = Model.from_otoole_csv("path/to/otoole/csv/directory")
```

Read more in the [documentation](https://docs.feo.transitionzero.org/)

### Example models
There are several [example models](https://github.com/transition-zero/tz-osemosys/tree/main/examples) in TZ-OSeMOSYS that serve as learning tools and starting points for users. We recommend exploring the [two-region example model](https://github.com/transition-zero/tz-osemosys/tree/main/examples/two-region-model), which illustrates a simple system with two regions and includes primary, secondary, and final energy vectors. The model is built using yaml files and is fully documented within this repository.

### Development and Contributing

We welcome contributions! To get started as a contributor or as a developer, please read our [contributor guidelines](./CONTRIBUTING.md).

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "tz-osemosys",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.11",
    "maintainer_email": null,
    "keywords": "energy, milp, climate",
    "author": null,
    "author_email": "Lucas Kruitwagen <lucas.kruitwagen@gmail.com>, Ed Gill <edwardxtg@gmail.com>, Abhishek Shivakumar <abhishek0208@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/5e/61/ad15fa590e5a2e33a4176a6ceb191c244623635992132eac661ad0930ea9/tz_osemosys-0.0.16.tar.gz",
    "platform": null,
    "description": "<picture>\n  <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://github.com/transition-zero/.github/raw/main/profile/img/logo-dark.png\">\n  <img alt=\"TransitionZero Logo\" width=\"1000px\" src=\"https://github.com/transition-zero/.github/raw/main/profile/img/logo-light.png\">\n  <a href=\"https://www.transitionzero.org/\">\n</picture>\n\n# TZ-OSEMOSYS - a modern long-run systems modelling framework\n\n<!-- badges-begin -->\n\n[![License][license badge]][license]\n[![Contributor Covenant][contributor covenant badge]][code of conduct]\n![Tests][tests badge]\n![Coverage][coverage badge]\n![Python][python badge]\n![Status][status badge]\n\n[license badge]: https://img.shields.io/github/license/ad-aures/castopod?color=blue\n[license]: https://opensource.org/license/agpl-v3\n\n[contributor covenant badge]: https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg\n[code of conduct]: https://github.com/transition-zero/tz-osemosys/blob/main/CODE-OF-CONDUCT.md\n\n[tests badge]: https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/Lkruitwagen/feffb38d46c750cad5402dca5dd54bf9/raw/tests_passing.json\n\n[coverage badge]: https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/Lkruitwagen/6afead97828812b3c9ad498c94dd45f8/raw/coverage_badge.json\n\n[python badge]: https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/Lkruitwagen/bd1e357c1bce5fc2c0808bcdb569157c/raw/python_version_badge.json\n\n[status badge]: https://img.shields.io/badge/under%20construction-ffae00\n\n<!-- badges-end -->\n\n\n**OSeMOSYS** is an open source modelling system for long-run systems analysis and planning.\nIt has been employed to develop energy systems models from the scale of the globe, continents, countries, regions, and villages.\nOSeMOSYS is extremely flexible - it can be used for high-fidelity representations of power systems, rich with technological detail;\nmedium-fidelity representations of all-energy systems including upstream energy supply, final energy demand, and climate policities;\nor low-fidelity nexus problems including commodities like materials, energy, and financing, and a range of environomental and social impacts.\n\nOSeMOSYS is entirely open-source and can be used with a variety of programming languages and solvers.\n\n## OSeMOSYS with the Future Energy Outlook\n\nTransitionZero has rebuilt OSeMOSYS as a pip-installable Python package (tz-osemosys).\nThis implementation of OSeMOSYS underlies our Future Energy Outlook capacity expansion model builder.\nWe have added the following features:\n\n* [Pydantic](https://docs.pydantic.dev/latest/)-based model construction and validation\n* [Linopy](https://linopy.readthedocs.io/en/latest/)-based numerical optimsation and solving\n* Reverse-compatability with [OSeMOSYS-otoole](https://github.com/OSeMOSYS/otoole)\n\n## Documentation\n\n[TZ-OSeMOSYS](https://docs.feo.transitionzero.org/)\n\n[Examples](examples)\n\n[TransitionZero Platform Docs](https://docs.feo.transitionzero.org/)\n\n[OSeMOSYS Docs](https://osemosys.readthedocs.io/en/latest/)\n\n## Installation\n\nTZ-OSeMOSYS can be installed with a simple `pip install tz-osemosys`. To solve a model, however, you'll need a solver. Any solver compatible with [Linopy](https://linopy.readthedocs.io/en/latest/) will work: [Coin-OR CBC](https://github.com/coin-or/Cbc), [GLPK](https://www.gnu.org/software/glpk/), [HiGHS](https://highs.dev/), [Gurobi](https://www.gurobi.com/solutions/gurobi-optimizer/), [CPLEX](https://dev.ampl.com/solvers/cplex/index.html), and more. We recommend HiGHS, the leading open-source solver.\n\n### Solver Installation - HiGHS\n\nHiGHS can be installed from source using `cmake` following the instructions [here](https://github.com/ERGO-Code/HiGHS?tab=readme-ov-file#installation). You'll need to install a cmake distribution for your relevant operating system.\n\n*common issue: make sure you have write-privileges to default directory for `cmake --install build`, or either run this command with administrator privileges (`sudo cmake --install build` on mac and linux) or specify a different build directory*\n\n### Docker installation\n\nA docker container is provided that contains Python 3.11 and an installed version of HiGHS. You'll need to [install a docker distribution](https://docs.docker.com/engine/install/) relevant for your operating system.\n\nThe docker container is used in testing, but can also be used for local development work. The following docker command will run and enter the docker container, mount the current working directory at the `/home` directory, and change directory within the container to this directory.\n\n```console\ndocker run -v $(pwd):/home -it  ghcr.io/transition-zero/tz-highs/highs-python:latest /bin/bash -c 'cd /home && /bin/bash'\n```\n\n*note! Any files changed within this mounted directory will persist, but any changes to environments, installed packes, etc. will not!*\n\n## Quickstart\n\nTZ-OSeMOSYS provides several entrypoints to get started quickly, however your model is specified.\n\n### From Pydantic objects\n\nModels can be specified directly with Pydantic objects. Pydantic gives useful tooling for class inheritance and field validation. The Model class and subclasses provide obvious semantic linking between the object types. The set of objects comprising the model is mutually exclusive - no information is repeated - and collectively exhaustive - no information needs to be extracted from csvs or other data sources.\n\n```python\nfrom tz.osemosys import (\n    Model,\n    Technology,\n    TimeDefinition,\n    Commodity,\n    Region,\n    Impact,\n    OperatingMode,\n)\n\ntime_definition = TimeDefinition(id=\"years-only\", years=range(2020, 2051))\nregions = [Region(id=\"single-region\")]\ncommodities = [Commodity(id=\"electricity\", demand_annual=25 * 8760)]  # 25GW * 8760hr/yr\nimpacts = [Impact(id=\"CO2\", penalty=60)]  # 60 $mn/Mtonne\ntechnologies = [\n    Technology(\n        id=\"coal-gen\",\n        operating_life=40,  # years\n        capex=800,  # mn$/GW\n        # straight-line reduction to 2040\n        residual_capacity={\n            yr: 25 * max((1 - (yr - 2020) / (2040 - 2020), 0))\n            for yr in range(2020, 2051)\n        },\n        operating_modes=[\n            OperatingMode(\n                id=\"generation\",\n                # $mn20/Mt.coal / 8.14 TWh/Mt coal * 8760 GWh/GW / 0.3 /1000 GWh/TWh (therm eff)\n                opex_variable=20 / 8.14 * 8760 / 0.3 / 1000,  # $71/GW/yr\n                output_activity_ratio={\"electricity\": 1.0 * 8760},  # GWh/yr/GW\n                emission_activity_ratio={\n                    \"CO2\": 0.354 * 8760 / 1000\n                },  # Mtco2/TWh * 8760GWh/Gw/yr /1000 GWh/TWh\n            )\n        ],\n    ),\n    Technology(\n        id=\"solar-pv\",\n        operating_life=25,\n        capex=1200,\n        capacity_factor=0.3,\n        operating_modes=[\n            OperatingMode(\n                id=\"generation\",\n                opex_variable=0,\n                output_activity_ratio={\"electricity\": 1.0 * 8760},  # GWh/yr/GW\n            )\n        ],\n    ),\n]\n\nmodel = Model(\n    id=\"simple-carbon-price\",\n    time_definition=time_definition,\n    regions=regions,\n    commodities=commodities,\n    impacts=impacts,\n    technologies=technologies,\n)\n\nmodel.solve()\n```\n\n\n### From Yaml\n\nYAML is a human-readable data serialisation language. We've build a custom YAML parser that allows the creation of model configurations that are _exhaustive_ while also being _expressive_.\n\n- model fields can be cross-referenced in the yaml blob, e.g. `my_field: ${commodities[0].COAL.demand}`.\n- model fields can also be populated from environment variables: `my_field: $ENV{MYVAR}`.\n- simple Python expressions are automatically evaluated, including list comprehensions, dictionary comprehensions, `min`, `max`, `sum`, and `range` functions.\n- for data keyed by an osemosys `set` (e.g. `YEARS`, `TIMESLICES`, `TECHNOLOGIES`), wildcards `\"*\"` can be used in place of explicitly listing all set members.\n- data field `set` dimensions and membership are also automatically inferred - a single value can be given which will be broadcast to all set member combinations.\n- single or multiple `.yaml` files can be composed together, allowing you to separate, e.g. `technologies.yaml`, from the rest of your model.\n- with `cloudpathlib` and a cloud storage provider SDK installed the path to yaml files can be a cloud storage object URI. See <https://cloudpathlib.drivendata.org/stable/> for more details.\n- `pip install \"tz-osemosys[cloudpath]\"` will install `cloudpathlib` and python client libraries for cloud storage provider SDKs.\n\n```python\nfrom tz.osemosys import Model\n\nmy_model = Model.from_yaml(\"path/to/yaml/directory\")\n```\n\n### From Otoole outputs (legacy)\n\nTZ-OSeMOSYS is provided with backwards compatability with the [otoole](https://github.com/OSeMOSYS/otoole) osemosys tooling. Any legacy models can be loaded from the directory of otoole-formatted csvs.\n\n```python\nfrom tz.osemosys import Model\n\nmy_model = Model.from_otoole_csv(\"path/to/otoole/csv/directory\")\n```\n\nRead more in the [documentation](https://docs.feo.transitionzero.org/)\n\n### Example models\nThere are several [example models](https://github.com/transition-zero/tz-osemosys/tree/main/examples) in TZ-OSeMOSYS that serve as learning tools and starting points for users. We recommend exploring the [two-region example model](https://github.com/transition-zero/tz-osemosys/tree/main/examples/two-region-model), which illustrates a simple system with two regions and includes primary, secondary, and final energy vectors. The model is built using yaml files and is fully documented within this repository.\n\n### Development and Contributing\n\nWe welcome contributions! To get started as a contributor or as a developer, please read our [contributor guidelines](./CONTRIBUTING.md).\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "An OSeMOSYS implementation for the Future Energy Outlook by TransitionZero",
    "version": "0.0.16",
    "project_urls": {
        "Bug Reports": "https://github.com/transition-zero/tz-osemosys/issues",
        "Funding": "https://transitionzero.org",
        "Homepage": "https://github.com/transition-zero/tz-osemosys",
        "Source": "https://github.com/transition-zero/tz-osemosys"
    },
    "split_keywords": [
        "energy",
        " milp",
        " climate"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "1516c593bfc0670c9f95bdd3a614518716570b5ae62fcfc46bbf3c2cc002a6df",
                "md5": "fe50a001d3db5a4e23de2ed6de53ac9c",
                "sha256": "d267a07d4206562d112a2e520722145b82fb8f02cb7abfd1a6de488bfbff8258"
            },
            "downloads": -1,
            "filename": "tz_osemosys-0.0.16-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "fe50a001d3db5a4e23de2ed6de53ac9c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.11",
            "size": 918293,
            "upload_time": "2024-10-29T15:25:55",
            "upload_time_iso_8601": "2024-10-29T15:25:55.649623Z",
            "url": "https://files.pythonhosted.org/packages/15/16/c593bfc0670c9f95bdd3a614518716570b5ae62fcfc46bbf3c2cc002a6df/tz_osemosys-0.0.16-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5e61ad15fa590e5a2e33a4176a6ceb191c244623635992132eac661ad0930ea9",
                "md5": "812f971e62a02f5fab624a4f7dd54cf3",
                "sha256": "43c18d8ae889fa7d929972df15d926bef173510a41717d94dcaefc8f65be4263"
            },
            "downloads": -1,
            "filename": "tz_osemosys-0.0.16.tar.gz",
            "has_sig": false,
            "md5_digest": "812f971e62a02f5fab624a4f7dd54cf3",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.11",
            "size": 772881,
            "upload_time": "2024-10-29T15:25:57",
            "upload_time_iso_8601": "2024-10-29T15:25:57.287265Z",
            "url": "https://files.pythonhosted.org/packages/5e/61/ad15fa590e5a2e33a4176a6ceb191c244623635992132eac661ad0930ea9/tz_osemosys-0.0.16.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-10-29 15:25:57",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "transition-zero",
    "github_project": "tz-osemosys",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "tz-osemosys"
}
        
Elapsed time: 1.00408s