From c43f54e3ee9ced98e637c4855cb1d9923afcbb29 Mon Sep 17 00:00:00 2001 From: Philip Hackstock <20710924+phackstock@users.noreply.github.com> Date: Mon, 18 Dec 2023 10:00:46 +0100 Subject: [PATCH] Initial commit --- .github/workflows/black.yml | 12 ++ .github/workflows/validation.yml | 29 ++++ .gitignore | 264 +++++++++++++++++++++++++++++ README.md | 47 +++++ definitions/.gitkeep | 0 definitions/region/common.yaml | 2 + definitions/variable/variable.yaml | 3 + mappings/.gitkeep | 0 requirements.txt | 2 + workflow.py | 15 ++ 10 files changed, 374 insertions(+) create mode 100644 .github/workflows/black.yml create mode 100644 .github/workflows/validation.yml create mode 100644 .gitignore create mode 100644 README.md create mode 100644 definitions/.gitkeep create mode 100644 definitions/region/common.yaml create mode 100644 definitions/variable/variable.yaml create mode 100644 mappings/.gitkeep create mode 100644 requirements.txt create mode 100644 workflow.py diff --git a/.github/workflows/black.yml b/.github/workflows/black.yml new file mode 100644 index 0000000..64fa1b8 --- /dev/null +++ b/.github/workflows/black.yml @@ -0,0 +1,12 @@ +# Based on https://black.readthedocs.io/en/stable/integrations/github_actions.html + +name: Lint + +on: [ push, pull_request ] + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: psf/black@stable diff --git a/.github/workflows/validation.yml b/.github/workflows/validation.yml new file mode 100644 index 0000000..4570b42 --- /dev/null +++ b/.github/workflows/validation.yml @@ -0,0 +1,29 @@ +# This workflow validates that the project is consistent with the nomenclature +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions + +name: Validate the project + +on: + push: + branches: [ main ] + pull_request: + branches: [ '**' ] + +jobs: + project-validation: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python 3.11 + uses: actions/setup-python@v4 + with: + python-version: 3.11 + + - name: Install requirements + run: pip install -r requirements.txt + + - name: Run the nomenclature project validation + run: nomenclature validate-project . diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6d93874 --- /dev/null +++ b/.gitignore @@ -0,0 +1,264 @@ +### IntelliJ PyCharm ### +.idea/ + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### macOS Patch ### +# iCloud generated files +*.icloud + +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history +.ionide + +# Support for Project snippet scope +.vscode/*.code-snippets + +# Ignore code-workspaces +*.code-workspace + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# End of https://www.toptal.com/developers/gitignore/api/python,visualstudiocode,windows,macos,linux diff --git a/README.md b/README.md new file mode 100644 index 0000000..c911678 --- /dev/null +++ b/README.md @@ -0,0 +1,47 @@ +# Scenario Explorer Workflow Template + +Copyright 2022-2023 IIASA + +[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) + +## Overview + +This is a template for project-specific scenario processing workflows. + +To use this template for a project, do the following: +- Create a new repository from this template +- Update the title and overview section of this Readme +- Start adding definitions and mappings + +### Project nomenclature + +The folder `definitions` can contain the project nomenclature, i.e., list of allowed +variables and regions, for use in the validation workflow. See the **nomenclature** +package for more information ([link](https://github.com/iamconsortium/nomenclature)). + +The folder `mappings` can contain model mappings that are used to register models and +define how results should be processed upon upload to a Scenario Explorer. + +### Model registration + +This is the step-by-step guide to registering your model: + +1. Fork this repository +2. Follow the instructions from the nomenclature documentation here: . +Please make sure to follow the instructions completely, both the _Model mapping_ and the _Region definitions_ part. You'll have to end up with two files. +3. Open a pull request into this repository. Make sure that the tests run through and correct any potential issues. If the tests are failing you can view the details by clicking on the failed test run. + +4. Set [@danielhuppmann](https://github.com/danielhuppmann) and [@phackstock](https://github.com/phackstock) as reviewers. +5. Once everything is in order we will merge your pull request and your model will be registered. + +### Workflow + +The module `workflow.py` has a function `main(df: pyam.IamDataFrame) -> pyam.IamDataFrame:`. + +Per default, this function takes an **IamDataFrame** and returns it without +modifications. [Read the docs](https://pyam-iamc.readthedocs.io) for more information +about the **pyam** package for scenario analysis and data visualization. + +**Important**: Do not change the name of the module `workflow.py` or the function `main` +as they are called like this by the Job Execution Service. Details can be found +[here](https://wiki.ece.iiasa.ac.at/wiki/index.php/Scenario_Explorer/Setup#Job_Execution_Service). diff --git a/definitions/.gitkeep b/definitions/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/definitions/region/common.yaml b/definitions/region/common.yaml new file mode 100644 index 0000000..aef9c53 --- /dev/null +++ b/definitions/region/common.yaml @@ -0,0 +1,2 @@ +- common: + - World diff --git a/definitions/variable/variable.yaml b/definitions/variable/variable.yaml new file mode 100644 index 0000000..e5a870e --- /dev/null +++ b/definitions/variable/variable.yaml @@ -0,0 +1,3 @@ +- Primary Energy: + description: Total primary energy consumption (direct equivalent) + unit: EJ/yr diff --git a/mappings/.gitkeep b/mappings/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..70a15e3 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +pyam-iamc >= 1.0 # the `pyam` package is released on pypi under this name +nomenclature-iamc >= 0.11 diff --git a/workflow.py b/workflow.py new file mode 100644 index 0000000..c85f21b --- /dev/null +++ b/workflow.py @@ -0,0 +1,15 @@ +from pathlib import Path +import pyam +from nomenclature import DataStructureDefinition, RegionProcessor, process + + +here = Path(__file__).absolute().parent + + +def main(df: pyam.IamDataFrame) -> pyam.IamDataFrame: + """Project/instance-specific workflow for scenario processing""" + + # Run the validation and region-processing + dsd = DataStructureDefinition(here / "definitions") + processor = RegionProcessor.from_directory(path=here / "mappings", dsd=dsd) + return process(df, dsd, processor=processor)