Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add_geo_set_generator #13

Merged
merged 10 commits into from
Sep 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ src/*
examples/files/DE.inc
__pycache__
output
config
config
build
11 changes: 9 additions & 2 deletions docs/get_started/examples.md → docs/examples.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@

## Examples
# Examples
The following notebooks provide examples on how to use pybalmorel for pre-processing, post-processing and for executing Balmorel scenarios:
- [Pre-Processing](https://github.com/Mathias157/pybalmorel/blob/master/examples/PreProcessing.ipynb)
- [Execution](https://github.com/Mathias157/pybalmorel/blob/master/examples/Execution.ipynb)
- [Post-Processing](https://github.com/Mathias157/pybalmorel/blob/master/examples/PostProcessing.ipynb)

The next pages also include some code snippets on how to use various functions.

```{toctree}
:maxdepth: 1

examples/geofilemaker.md
```
16 changes: 16 additions & 0 deletions docs/examples/geofilemaker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Defining Geography

pybalmorel includes a GUI to interactively define nodes in Balmorel's hierarchical geographic structure comprising countries, regions and areas.
```python
from pybalmorel import GUI
GUI.geofilemaker()
```

The video below illustrates how it works.
:::{figure} ../img/geoset_generator_example.gif
:name: geofilemaker
:alt: How to use the 'geofilemaker' GUI.
:width: 100%
:align: center
How to use the 'geofilemaker' GUI.
:::
3 changes: 2 additions & 1 deletion docs/get_started.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Get Started

An installation instruction.

```{toctree}
:maxdepth: 1

get_started/installation.md
get_started/examples.md
```
14 changes: 7 additions & 7 deletions docs/get_started/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ channels:
- conda-forge
dependencies:
- python >= 3.9
- pandas >= 2.1.4
- matplotlib >= 3.9.0
- geopandas >= 0.14.4
- ipywidgets >= 8.1.3
- ipykernel
- pandas>=2.1.4
- matplotlib>=3.9.0
- geopandas>=1.0.1
- ipywidgets>=8.1.3
- pip
- pip:
- gamsapi[transfer] >= 45.0.0
- pybalmorel
- gamsapi[transfer]>=45.0.0
- eel>=0.17.0
- pybalmorel==0.3.6
```
Binary file added docs/img/geoset_generator_example.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Get started [here](get_started.md).
:hidden:

get_started
examples
```

```{toctree}
Expand Down
14 changes: 14 additions & 0 deletions environment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: pybalmorel
channels:
- conda-forge
dependencies:
- python >= 3.9
- pandas>=2.1.4
- matplotlib>=3.9.0
- geopandas>=1.0.1
- ipywidgets>=8.1.3
- pip
- pip:
- gamsapi[transfer]>=45.0.0
- eel>=0.17.0
- pybalmorel==0.3.6
14 changes: 0 additions & 14 deletions environment.yml

This file was deleted.

32 changes: 28 additions & 4 deletions examples/PreProcessing.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@
"outputs": [],
"source": [
"### 0.1 Use development scripts or the package installed from pip\n",
"use_development = True\n",
"use_development = False\n",
"if use_development:\n",
" import sys\n",
" import os\n",
" # Adjust the sys.path to include the project root directory\n",
" project_root = os.path.abspath(os.path.join(os.path.dirname(\"__file__\"), '..'))\n",
" if project_root not in sys.path:\n",
" sys.path.insert(0, project_root)\n",
" from src.pybalmorel import IncFile\n",
" from src.pybalmorel import IncFile, GUI\n",
"else:\n",
" from pybalmorel import IncFile"
]
Expand All @@ -40,7 +40,7 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -65,6 +65,30 @@
"# Save .inc file to path (will save as ./Balmorel/sc1/data/DE.inc)\n",
"DE.save()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## GUI for Generating Geographic .inc Files\n",
"\n",
"Will generate the necessary geographic files:\n",
"- CCCRRRAAA.inc\n",
"- CCC.inc\n",
"- RRR.inc\n",
"- AAA.inc\n",
"- CCCRRR.inc\n",
"- RRRAAA.inc"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"GUI.geofilemaker()"
]
}
],
"metadata": {
Expand All @@ -83,7 +107,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.11"
"version": "3.12.6"
}
},
"nbformat": 4,
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "pybalmorel"
version = "0.3.5"
version = "0.3.6"
maintainers = [
{ name="Mathias Berg Rosendal", email="[email protected]"},
{ name="Théodore Le Nalinec"},
Expand All @@ -17,7 +17,7 @@ classifiers = [
"Operating System :: OS Independent",
]
dependencies = ['pandas>=2.1.4', 'matplotlib>=3.9.0', 'geopandas>=0.14.4',
'gamsapi[transfer]>=45.0.0', 'ipywidgets>=8.1.3']
'gamsapi[transfer]>=45.0.0', 'ipywidgets>=8.1.3', 'eel>=0.17.0']

[project.urls]
Repository = "https://github.com/Mathias157/pybalmorel"
Expand Down
4 changes: 2 additions & 2 deletions src/pybalmorel/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from . import formatting, utils
from .classes import IncFile, MainResults, Balmorel
from .classes import IncFile, MainResults, Balmorel, GUI

__all__ = [IncFile, MainResults, Balmorel]
__all__ = [IncFile, MainResults, Balmorel, GUI]
28 changes: 27 additions & 1 deletion src/pybalmorel/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from matplotlib.axes import Axes
from .utils import symbol_to_df
from .interactive.interactive_functions import interactive_bar_chart
from .interactive.dashboard.eel_dashboard import interactive_geofilemaker
from .plotting.production_profile import plot_profile
from .plotting.maps_balmorel import plot_map

Expand Down Expand Up @@ -391,4 +392,29 @@ def load_incfiles(self,
model_db.run()

# Store the database (will take some minutes)
self.input_data[scenario] = model_db.get_out_db()
self.input_data[scenario] = model_db.get_out_db()


class GUI:
def __init__(self) -> None:
pass

# Interactive bar chart plotting
def bar_chart(self, MainResults_instance):
"""Interactive GUI to plot bar charts from MainResults

Args:
MainResults_instance (class): Loaded MainResults

Returns:
None: An interactive GUI is opened to plot bar charts
"""
return interactive_bar_chart(MainResults_instance)

def geofilemaker():
"""Opens a GUI to interactively generate necessary .inc files for Balmorel geography

Returns:
None: An interactive GUI to generate geographic .inc files
"""
return interactive_geofilemaker()
87 changes: 87 additions & 0 deletions src/pybalmorel/interactive/dashboard/eel_dashboard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#%%
import eel
import ast
from pybalmorel import IncFile
import pkg_resources
import os

# 1.0 Other functions
def get_wkdir():
return os.path.abspath('.')

# 1.1 Create .inc Files
def create_incfile(unique_processing):
"""The general wrapper for creating and saving .inc files,
because the creating of the IncFile class and saving it is the same everytime.
The unique processing of the .body content differs, however.

Args:
unique_processing (func): The unique processing per case
**incfile_kwargs: Keyword arguments to pass to IncFile
"""
def wrapper(**kwargs):
inc_file = IncFile(name=kwargs['name'], prefix=kwargs['prefix'],
suffix=kwargs['suffix'], path=kwargs['path'])
unique_processing(inc_file, kwargs['geo_nodes'])
inc_file.save()
return wrapper

## 1.1.1 CCC, RRR or AAA
@create_incfile
def create_sets(inc_file: IncFile, geo_nodes_layer2: dict):
inc_file.body += '\n'.join(list(geo_nodes_layer2.keys()))

## 1.1.2 CCCRRRAAA
@create_incfile
def create_CCCRRRAAA(inc_file: IncFile, geo_nodes: dict):
for key in geo_nodes.keys():
inc_file.body += '\n* %s:\n' % key.capitalize()
inc_file.body += '\n'.join(geo_nodes[key].keys())

## 1.1.3 CCCRRR or RRRAAA
@create_incfile
def create_setconnection(inc_file: IncFile, geo_nodes_layer1: dict):
for node in geo_nodes_layer1.keys():
if len(geo_nodes_layer1[node]) != 0:
inc_file.body += f'\n{node} . '
inc_file.body += f'\n{node} . '.join(geo_nodes_layer1[node])


# 1.2 Create .inc Files
def create_incfiles(output: str, path: str):
geo_nodes = ast.literal_eval(output) # Convert output to dict
prefix = """SET CCC(CCCRRRAAA) 'All countries'
/\n"""
create_sets(geo_nodes=geo_nodes['countries'], name='CCC', prefix=prefix, suffix="\n/;", path=path)

prefix = """SET RRR(CCCRRRAAA) 'All regions'
/\n"""
create_sets(geo_nodes=geo_nodes['regions'], name='RRR', prefix=prefix, suffix="\n/;", path=path)

prefix = """SET AAA(CCCRRRAAA) 'All areas'
/\n"""
create_sets(geo_nodes=geo_nodes['areas'], name='AAA', prefix=prefix, suffix="\n/;", path=path)

prefix = """* All sets that are related to Geographical resolution
SET CCCRRRAAA 'All geographical entities (CCC + RRR + AAA)'
/"""
create_CCCRRRAAA(geo_nodes=geo_nodes, name='CCCRRRAAA', prefix=prefix, suffix="\n/;", path=path)

prefix="""SET CCCRRR(CCC,RRR) "Regions in countries"
/"""
create_setconnection(geo_nodes=geo_nodes['countries'], name='CCCRRR', prefix=prefix, suffix="\n/;", path=path)

prefix="""SET RRRAAA(RRR,AAA) "Areas in regions"
/"""
create_setconnection(geo_nodes=geo_nodes['regions'], name='RRRAAA', prefix=prefix, suffix="\n/;", path=path)

def interactive_geofilemaker():

# Get working directory and package directory
static_path = pkg_resources.resource_filename(__name__, 'static')
index_path = pkg_resources.resource_filename(__name__, 'static/index.html')

eel.init(static_path)
eel.expose(get_wkdir)
eel.expose(create_incfiles)
eel.start(index_path)
Loading