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

Added technology data download class #25

Merged
merged 7 commits into from
Nov 13, 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
17 changes: 16 additions & 1 deletion docs/examples/preprocessing.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,19 @@ The video below illustrates how it works.
:width: 100%
:align: center
How to use the 'geofilemaker' GUI.
:::
:::

## Downloading Technology Catalogues

The technology catalogues from the Danish Energy Agency are useful and streamlined data inputs for energy system modelling. The function below will check if the electricity and district heating technology catalogue exists in the specified path (the working directory in this case) and download it if it does not exist in the path:

```python
from pybalmorel import TechData

TD = TechData(path='.')
print('Available technology catalogues: ', list(TD.files.keys()))

TD.download_catalogue('el_and_dh')
```

Note that [TechData.download_all_catalogues](https://balmorelcommunity.github.io/pybalmorel/autoapi/pybalmorel/classes/index.html#pybalmorel.classes.TechData.download_all_catalogues) will look for or try to download all catalogues.
2 changes: 1 addition & 1 deletion docs/get_started/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ dependencies:
- ipykernel>=6.29.5
- pip
- pip:
- pybalmorel==0.4.3
- pybalmorel==0.4.4
```

2 changes: 1 addition & 1 deletion environment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ dependencies:
- pytest=8.3.3
- pip
- pip:
- pybalmorel==0.4.3
- pybalmorel==0.4.4
277 changes: 274 additions & 3 deletions examples/PreProcessing.ipynb

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "pybalmorel"
version = "0.4.3"
version = "0.4.4"
maintainers = [
{ name="Mathias Berg Rosendal", email="[email protected]"},
{ name="Théodore Le Nalinec"},
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, GUI
from .classes import IncFile, MainResults, Balmorel, GUI, TechData

__all__ = [IncFile, MainResults, Balmorel, GUI]
__all__ = [IncFile, MainResults, Balmorel, GUI, TechData]
87 changes: 87 additions & 0 deletions src/pybalmorel/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
import gams
import pandas as pd
import numpy as np
from dataclasses import dataclass, field
from urllib.parse import urljoin
import requests
from typing import Union, Tuple
from functools import partial
from matplotlib.figure import Figure
Expand Down Expand Up @@ -438,7 +441,91 @@ def load_incfiles(self,
# Store the database (will take some minutes)
self.input_data[scenario] = model_db.get_out_db()

@dataclass
class TechData:
files: dict = field(default_factory=lambda: {
"el_and_dh" : "technology_data_for_el_and_dh.xlsx",
"indi_heat" : "technology_data_heating_installations.xlsx",
"ren_fuels" : "data_sheets_for_renewable_fuels.xlsx",
"storage" : "technology_datasheet_for_energy_storage.xlsx",
"ccts" : "technology_data_for_carbon_capture_transport_storage.xlsx",
"indu_heat" : "technology_data_for_industrial_process_heat_0.xlsx",
"trans" : "energy_transport_datasheet.xlsx"
})
path: str = r"C:\Users\mathi\gitRepos\balmorel-preprocessing\RawDataProcessing\Data\Technology Data" # Change this later

def load(self, file: str):
f = pd.read_excel(os.path.join(self.path, self.files[file]),
sheet_name='alldata_flat')
return f

# Function to download a file from a URL and save it to a specified folder
def download_file(self, url, save_folder, filename=None):
"""
Downloads a file from a given URL and saves it to a specified folder.
Args:
url (str): The URL of the file to download.
save_folder (str): The folder where the file should be saved.
filename (str, optional): The name to save the file as. If not provided, the filename is extracted from the URL.
Returns:
str: The full path to the saved file.
Raises:
requests.exceptions.RequestException: If the download fails.
Notes:
- The function ensures that the save folder exists.
- The file is downloaded in chunks to handle large files efficiently.
chunk_size:
The size of each chunk of data to be written to the file. In this case, it is set to 8192 bytes (8 KB).
"""
# Make sure the save folder exists
os.makedirs(save_folder, exist_ok=True)

# If no filename is provided, extract the filename from the URL
if filename is None:
filename = url.split("/")[-1]

# Full path to save the file
save_path = os.path.join(save_folder, filename)

# Download the file with streaming to handle large files
with requests.get(url, stream=True) as response:
response.raise_for_status() # Raise an error if the download fails
with open(save_path, 'wb') as file:
for chunk in response.iter_content(chunk_size=8192):
file.write(chunk)

print(f"Downloaded file to: {save_path}")
return save_path

def download_catalogue(self,
file: str,
save_to_folder: str = '.',
domain: str = "https://ens.dk/sites/ens.dk/files/Analyser/"):
"""Downloads technology catalogue from DEA website

Args:
file (str): _description_
save_to_folder (str, optional): _description_. Defaults to '.'.
domain (_type_, optional): _description_. Defaults to "https://ens.dk/sites/ens.dk/files/Analyser/".
"""
try:
# You probably used the short name used in this class
filename = self.files[file]
except KeyError:
# ..in case you wrote the full name of the file
filename = file

if not(filename in os.listdir(save_to_folder)):
self.download_file(urljoin(domain, filename), save_to_folder)
else:
print('\nThe file:\t\t%s\nalready exists in:\t%s'%(self.files[file], save_to_folder))

def download_all_catalogues(self,
save_to_folder: str = '.'):
for file in self.files.keys():
self.download_catalogue(file, save_to_folder)


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