Skip to content

Commit

Permalink
Format entire code base based on new code guidelines
Browse files Browse the repository at this point in the history
Following #285.
  • Loading branch information
timtroendle committed Mar 15, 2024
1 parent c7e0300 commit e254b0c
Show file tree
Hide file tree
Showing 60 changed files with 1,731 additions and 1,149 deletions.
1 change: 0 additions & 1 deletion CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,3 @@ references:
- family-names: Pfenninger
given-names: Stefan
orcid: https://orcid.org/0000-0002-8420-9498

2 changes: 1 addition & 1 deletion config/energy-balances/energy-balance-carrier-names.csv
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,4 @@ E7000,Electricity,electricity,electricity,electricity,
H8000,Heat,heat,heat,heat,heat
BIOE,Bioenergy,,,,
O4000,,oil,,,
SFF_P1000_S2000,,solid_fossil,,,solid_fossil
SFF_P1000_S2000,,solid_fossil,,,solid_fossil
2 changes: 1 addition & 1 deletion config/energy-balances/energy-balance-category-names.csv
Original file line number Diff line number Diff line change
Expand Up @@ -294,4 +294,4 @@ CRF5F1,Waste management,,Long-term storage of carbon in waste disposal sites,,
CRF5F2,Waste management,,Annual change in total long-term carbon storage,,
CRF5F3,Waste management,,Annual change in total long-term carbon storage in harvested wood products HWP waste,,
CRF6,Other sectors,,,,
CRF_INDCO2,Indirect CO2,,,,
CRF_INDCO2,Indirect CO2,,,,
2 changes: 1 addition & 1 deletion config/nuclear-capacity-2050.csv
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ France,0,51000,https://www.rte-france.com/actualites/futurs-energetiques-neutral
United Kingdom,8900,8900,https://assets.publishing.service.gov.uk/government/uploads/system/uploads/attachment_data/file/789655/Nuclear_electricity_in_the_UK.pdf,
Hungary,2400,2400,https://ec.europa.eu/energy/sites/ener/files/documents/ec_courtesy_translation_hu_necp.pdf, assuming no new capacity 2030 -> 2050
Romania,650,2650,"http://www.enpg.ro/wp-content/uploads/2018/12/NECP-Romania-EPG-Analysis.pdf, 4 CANDU reactors, 650MW each, with 4th going online in 2031. Depends on when the other 3 go online (i.e. are they decommissioned by 2050?)",
Slovakia,940,3340,https://www.world-nuclear.org/information-library/country-profiles/countries-o-s/slovakia.aspx, Depends on if 2.4 GW of planned capacity is realised.
Slovakia,940,3340,https://www.world-nuclear.org/information-library/country-profiles/countries-o-s/slovakia.aspx, Depends on if 2.4 GW of planned capacity is realised.
2 changes: 1 addition & 1 deletion docs/css/extras.css
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,4 @@
.tabbed-content {
display: contents;
}
}
}
2 changes: 1 addition & 1 deletion lib/eurocalliopelib/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""Top-level package of eurocalliopelib."""

__version__ = "1.2.0.dev" # Additionally defined in setup.py.
__version__ = "1.2.0.dev" # Additionally defined in setup.py.
7 changes: 3 additions & 4 deletions lib/eurocalliopelib/docs/addfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,17 @@

class AddFilePlugin(BasePlugin):
config_scheme = (
('path_to_file', mkdocs.config.config_options.Type(str)),
('path_to_src_dir', mkdocs.config.config_options.Type(str)),
("path_to_file", mkdocs.config.config_options.Type(str)),
("path_to_src_dir", mkdocs.config.config_options.Type(str)),
)


def on_files(self, files, config, **kwargs):
"""Link top-level files to mkdocs files."""
linked_md_file = File(
path=self.config["path_to_file"],
src_dir=self.config["path_to_src_dir"],
dest_dir=config["site_dir"],
use_directory_urls=config["use_directory_urls"]
use_directory_urls=config["use_directory_urls"],
)
files.append(linked_md_file)
return files
18 changes: 11 additions & 7 deletions lib/eurocalliopelib/docs/dag.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,28 @@
from contextlib import redirect_stdout
from pathlib import Path

import snakemake
import mkdocs
import pydot
import snakemake
from mkdocs.plugins import BasePlugin
from mkdocs.structure.files import File
import pydot


class DAGPlugin(BasePlugin):
config_scheme = (
('path_to_snakefile', mkdocs.config.config_options.Type(str)),
('path_to_src_dir', mkdocs.config.config_options.Type(str)),
('path_to_png_relative_to_site', mkdocs.config.config_options.Type(str))
("path_to_snakefile", mkdocs.config.config_options.Type(str)),
("path_to_src_dir", mkdocs.config.config_options.Type(str)),
("path_to_png_relative_to_site", mkdocs.config.config_options.Type(str)),
)

def on_files(self, files, config, **kwargs):
"""Generate DAG as png and add it to mkdocs files."""
path_to_snakemake = Path.cwd() / self.config["path_to_snakefile"]
path_to_png = Path.cwd() / self.config["path_to_src_dir"] / self.config["path_to_png_relative_to_site"]
path_to_png = (
Path.cwd()
/ self.config["path_to_src_dir"]
/ self.config["path_to_png_relative_to_site"]
)
path_to_png.parent.mkdir(parents=True, exist_ok=True)
graph_string = io.StringIO()
with redirect_stdout(graph_string):
Expand All @@ -31,7 +35,7 @@ def on_files(self, files, config, **kwargs):
path=self.config["path_to_png_relative_to_site"],
src_dir=self.config["path_to_src_dir"],
dest_dir=config["site_dir"],
use_directory_urls=config["use_directory_urls"]
use_directory_urls=config["use_directory_urls"],
)
files.append(dag_file)
return files
20 changes: 12 additions & 8 deletions lib/eurocalliopelib/docs/schema.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import yaml
from pathlib import Path

import jsonschema2md
import mkdocs
import yaml
from mkdocs.plugins import BasePlugin
from mkdocs.structure.files import File


class SchemaPlugin(BasePlugin):
config_scheme = (
('path_to_schema', mkdocs.config.config_options.Type(str)),
('path_to_src_dir', mkdocs.config.config_options.Type(str)),
('path_to_md_relative_to_site', mkdocs.config.config_options.Type(str))
("path_to_schema", mkdocs.config.config_options.Type(str)),
("path_to_src_dir", mkdocs.config.config_options.Type(str)),
("path_to_md_relative_to_site", mkdocs.config.config_options.Type(str)),
)

def on_serve(self, server, config, builder):
Expand All @@ -22,7 +22,11 @@ def on_serve(self, server, config, builder):
def on_files(self, files, config, **kwargs):
"""Generate overview over configuration schema and add to mkdoc's files."""
path_to_schema = Path.cwd() / self.config["path_to_schema"]
path_to_md = Path.cwd() / self.config["path_to_src_dir"] / self.config["path_to_md_relative_to_site"]
path_to_md = (
Path.cwd()
/ self.config["path_to_src_dir"]
/ self.config["path_to_md_relative_to_site"]
)
path_to_md.parent.mkdir(parents=True, exist_ok=True)

parser = jsonschema2md.Parser()
Expand All @@ -38,17 +42,17 @@ def on_files(self, files, config, **kwargs):
path=self.config["path_to_md_relative_to_site"],
src_dir=self.config["path_to_src_dir"],
dest_dir=config["site_dir"],
use_directory_urls=config["use_directory_urls"]
use_directory_urls=config["use_directory_urls"],
)
files.append(schema_md_file)
return files

@staticmethod
def customise_markdown(lines):
# 1. Change headline
assert lines[0] == '# JSON Schema\n\n'
assert lines[0] == "# JSON Schema\n\n"
lines[0] = "# Configuration parameters of Euro-Calliope's workflow\n\n"
# 2. Remove main description and subheadline
assert lines[2] == '## Properties\n\n'
assert lines[2] == "## Properties\n\n"
del lines[2]
return lines
5 changes: 4 additions & 1 deletion lib/eurocalliopelib/geo/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from .spatiotemporal import area_weighted_time_series, convert_old_style_capacity_factor_time_series # noqa: F401
from .spatiotemporal import ( # noqa: F401
area_weighted_time_series,
convert_old_style_capacity_factor_time_series,
)

WGS84 = "EPSG:4326"
EPSG3035 = "EPSG:3035"
72 changes: 40 additions & 32 deletions lib/eurocalliopelib/geo/spatiotemporal.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import geopandas as gpd
import numpy as np
import pandas as pd
import geopandas as gpd
import xarray as xr
from shapely.geometry import Point
from geopandas.tools import overlay
from shapely.geometry import Point


DEPRECATED_GRID_SIZE_IN_M = 50000 # old style capacity factors are on a grid of 50km size
DEPRECATED_GRID_SIZE_IN_M = (
50000 # old style capacity factors are on a grid of 50km size
)

WGS84_EPSG = 4326
WGS84 = f"EPSG:{WGS84_EPSG}"
Expand All @@ -25,7 +26,7 @@ def area_weighted_time_series(shapes, spatiotemporal, gridcell_overlap_threshold
stacked_spatiotemporal = spatiotemporal.stack(xy=["x", "y"])
weights_and_values = xr.Dataset({
"value": stacked_spatiotemporal,
"weight": weights_between_shape_and_xy(shapes, stacked_spatiotemporal)
"weight": weights_between_shape_and_xy(shapes, stacked_spatiotemporal),
})
return pd.DataFrame(
index=spatiotemporal.timestep.to_index(),
Expand All @@ -34,13 +35,13 @@ def area_weighted_time_series(shapes, spatiotemporal, gridcell_overlap_threshold
weights_and_values.sel(shape_id=shape_id), gridcell_overlap_threshold
)
for shape_id in shapes.shape_id
}
},
)


def assert_correct_form(shapes, spatiotemporal):
assert shapes.crs
assert "crs" in spatiotemporal.attrs.keys()
assert "crs" in spatiotemporal.attrs
assert shapes.crs == gpd.tools.crs.CRS(spatiotemporal.attrs["crs"])
assert "y" in spatiotemporal.dims, "Expect dimension 'y'"
assert "x" in spatiotemporal.dims, "Expect dimension 'x'"
Expand All @@ -50,38 +51,35 @@ def assert_correct_form(shapes, spatiotemporal):
def weights_between_shape_and_xy(shapes, stacked_spatiotemporal):
x, y = zip(*stacked_spatiotemporal.xy.values)
grid_gdf = (
gpd
.GeoSeries(
gpd.points_from_xy(x=x, y=y, crs=stacked_spatiotemporal.crs),
crs=shapes.crs
gpd.GeoSeries(
gpd.points_from_xy(x=x, y=y, crs=stacked_spatiotemporal.crs), crs=shapes.crs
)
.buffer(infer_resolution(stacked_spatiotemporal.unstack("xy")) / 2)
.envelope
)
index_gdf = gpd.GeoDataFrame(
geometry=grid_gdf,
data={"xy": stacked_spatiotemporal.xy},
crs=shapes.crs
geometry=grid_gdf, data={"xy": stacked_spatiotemporal.xy}, crs=shapes.crs
)
overlaid = overlay(index_gdf, shapes, how="intersection")
overlaid["area"] = overlaid.area
overlaid["weight"] = overlaid.groupby("shape_id").area.transform(lambda area: area / area.sum())
overlaid["weight"] = overlaid.groupby("shape_id").area.transform(
lambda area: area / area.sum()
)
weights = (
overlaid
.set_index(["xy", "shape_id"])
overlaid.set_index(["xy", "shape_id"])
.loc[:, "weight"]
.to_xarray()
.reindex_like(stacked_spatiotemporal) # add all xy's even without overlay
.fillna(0) # xy's without overlay have 0 weight
.reindex_like(stacked_spatiotemporal) # add all xy's even without overlay
.fillna(0) # xy's without overlay have 0 weight
)
return weights


def weighted_time_series(weights_and_values, gridcell_overlap_threshold):
ds = ( # drop all locations with weight == 0 or value == np.nan
weights_and_values
.where(weights_and_values.weight > 0)
.dropna(subset=["weight", "value"], dim="xy", how="any")
weights_and_values.where(weights_and_values.weight > 0).dropna(
subset=["weight", "value"], dim="xy", how="any"
)
)
assert ds.weight.sum() >= gridcell_overlap_threshold, ds.weight.sum()
if ds.weight.sum().round(5) != 1:
Expand Down Expand Up @@ -126,21 +124,27 @@ def convert_old_style_capacity_factor_time_series(ts):
deprecated and should be removed as soon as the published data is updated with the new format.
"""
site_id_map = {
site_id.item(): (ts["lon"].sel(site_id=site_id).item(), ts["lat"].sel(site_id=site_id).item())
site_id.item(): (
ts["lon"].sel(site_id=site_id).item(),
ts["lat"].sel(site_id=site_id).item(),
)
for site_id in ts.site_id
}
gdf = (
gpd
.GeoDataFrame(
data={"site_id": [site_id for site_id in site_id_map.keys()]},
gpd.GeoDataFrame(
data={"site_id": [site_id for site_id in site_id_map]},
geometry=[Point(lon, lat) for lon, lat in site_id_map.values()],
crs=WGS84
crs=WGS84,
)
.set_index("site_id")
.to_crs(EPSG3035)
)
gdf["x"] = [round(point.coords[0][0], ndigits=0) for point in gdf.geometry] # round to meter
gdf["y"] = [round(point.coords[0][1], ndigits=0) for point in gdf.geometry] # round to meter
gdf["x"] = [
round(point.coords[0][0], ndigits=0) for point in gdf.geometry
] # round to meter
gdf["y"] = [
round(point.coords[0][1], ndigits=0) for point in gdf.geometry
] # round to meter
ts["x"] = gdf["x"]
ts["y"] = gdf["y"]
ts = ts.set_index(site_id=["x", "y"]).unstack("site_id")
Expand All @@ -149,11 +153,15 @@ def convert_old_style_capacity_factor_time_series(ts):
# make sure the resolution is uniform
x = ts.x
y = ts.y
assert ((x.diff("x") == DEPRECATED_GRID_SIZE_IN_M).sum() / x.count()).item() > 0.9 # most are fine
assert ((y.diff("y") == DEPRECATED_GRID_SIZE_IN_M).sum() / x.count()).item() > 0.9 # most are fine
assert (
(x.diff("x") == DEPRECATED_GRID_SIZE_IN_M).sum() / x.count()
).item() > 0.9 # most are fine
assert (
(y.diff("y") == DEPRECATED_GRID_SIZE_IN_M).sum() / x.count()
).item() > 0.9 # most are fine
ts = ts.reindex(
x=np.arange(x[0], x[-1] + 1, step=DEPRECATED_GRID_SIZE_IN_M),
y=np.arange(y[0], y[-1] + 1, step=DEPRECATED_GRID_SIZE_IN_M)
y=np.arange(y[0], y[-1] + 1, step=DEPRECATED_GRID_SIZE_IN_M),
)
ts.attrs["crs"] = EPSG3035
return ts
17 changes: 11 additions & 6 deletions lib/eurocalliopelib/template.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Applies config parameters to template files."""

from pathlib import Path

import jinja2
Expand All @@ -13,23 +14,27 @@ def parametrise_template(path_to_template, path_to_output_yaml, **kwargs):
path_to_template = Path(path_to_template)
env = jinja2.Environment(
loader=jinja2.FileSystemLoader(path_to_template.parent),
lstrip_blocks=True, trim_blocks=True, keep_trailing_newline=True,
undefined=jinja2.StrictUndefined # This ensures that missing pandas index elements raise an exception instead of silently returning None
lstrip_blocks=True,
trim_blocks=True,
keep_trailing_newline=True,
undefined=jinja2.StrictUndefined, # This ensures that missing pandas index elements raise an exception instead of silently returning None
)
env.filters['unit'] = filters.unit
env.filters["unit"] = filters.unit
rendered = env.get_template(path_to_template.name).render(**kwargs)

with open(path_to_output_yaml, "w") as result_file:
result_file.write(rendered)


def _update_kwargs(**kwargs):
if "scaling_factors" in kwargs.keys():
if "scaling_factors" in kwargs:
kwargs["scaling_factors"]["specific_costs"] = (
kwargs["scaling_factors"]["monetary"] / kwargs["scaling_factors"]["power"]
)
for config_key in ["locations", "links"]: # we cannot allow keys with "." in them
if config_key in kwargs.keys():
kwargs[config_key] = kwargs[config_key].rename(index=lambda x: x.replace(".", "-"))
if config_key in kwargs:
kwargs[config_key] = kwargs[config_key].rename(
index=lambda x: x.replace(".", "-")
)

return kwargs
5 changes: 4 additions & 1 deletion lib/eurocalliopelib/utils.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
"""Utility functions."""

import pycountry


def eu_country_code_to_iso3(eu_country_code):
"""Converts EU country code to ISO 3166 alpha 3.
The European Union uses its own country codes, which often but not always match ISO 3166.
"""
assert len(eu_country_code) == 2, "EU country codes are of length 2, yours is '{}'.".format(eu_country_code)
assert (
len(eu_country_code) == 2
), f"EU country codes are of length 2, yours is '{eu_country_code}'."

return convert_country_code(eu_country_code, output="alpha3")

Expand Down
Loading

0 comments on commit e254b0c

Please sign in to comment.