Skip to content

Commit

Permalink
Merge branch 'dev' of github.com:openego/eDisGo into feature/#274-imp…
Browse files Browse the repository at this point in the history
…rove-rtd-doc
  • Loading branch information
maike93he committed Sep 9, 2022
2 parents f2e5f28 + 4735c19 commit eb78d1b
Show file tree
Hide file tree
Showing 32 changed files with 2,381 additions and 1,138 deletions.
16 changes: 8 additions & 8 deletions doc/api/edisgo.tools.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,6 @@ edisgo.tools.config module
:undoc-members:
:show-inheritance:

edisgo.tools.edisgo\_run module
--------------------------------

.. automodule:: edisgo.tools.edisgo_run
:members:
:undoc-members:
:show-inheritance:

edisgo.tools.geo module
------------------------

Expand All @@ -33,6 +25,14 @@ edisgo.tools.geopandas\_helper module
:undoc-members:
:show-inheritance:

edisgo.tools.logger module
----------------------------------------

.. automodule:: edisgo.tools.logger
:members:
:undoc-members:
:show-inheritance:

edisgo.tools.networkx\_helper module
----------------------------------------

Expand Down
2 changes: 1 addition & 1 deletion doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
"shapely": ("https://shapely.readthedocs.io/en/latest/manual.html#%s", "shapely."),
"ding0": ("https://dingo.readthedocs.io/en/dev/api/ding0.html#%s", "Ding0"),
"pypsa": ("https://pypsa.readthedocs.io/en/latest/components.html#%s", "pypsa"),
"plotly": ("https://plotly.com/python-api-reference/generated/#%s.html", "plotly"),
"plotly": ("https://plotly.com/python-api-reference/generated/%s.html", "plotly"),
}
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
Expand Down
2 changes: 2 additions & 0 deletions doc/whatsnew/v0-2-0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ Changes
* added pre-commit hooks (flake8, black, isort, pyupgrade) `#229 <https://github.com/openego/eDisGo/pull/229>`_
* added issue and pull request templates `#220 <https://github.com/openego/eDisGo/issues/220>`_
* added Windows installation yml and documentation
* added functionality to set up different loggers with individual logging levels and where to write output `#295 <https://github.com/openego/eDisGo/issues/295>`_
* added integrity checks of eDisGo object `#231 <https://github.com/openego/eDisGo/issues/231>`_
* added functionality to save to and load from zip archive `#216 <https://github.com/openego/eDisGo/pull/216>`_
* added option to not raise error in case power flow did not converge `#207 <https://github.com/openego/eDisGo/issues/207>`_
* added pyplot `#214 <https://github.com/openego/eDisGo/pull/214>`_
* added functionality to create geopandas dataframes `#224 <https://github.com/openego/eDisGo/issues/224>`_
* added functionality to resample time series `#269 <https://github.com/openego/eDisGo/pull/269>`_
* added tests
* major refactoring of loads and time series

Expand Down
3 changes: 2 additions & 1 deletion edisgo/config/config_grid_expansion_default.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
# Standard equipment for grid expansion measures. Source: Rehtanz et. al.: "Verteilnetzstudie für das Land Baden-Württemberg", 2017.
hv_mv_transformer = 40 MVA
mv_lv_transformer = 630 kVA
mv_line = NA2XS2Y 3x1x185 RM/25
mv_line_10kv = NA2XS2Y 3x1x185 RM/25
mv_line_20kv = NA2XS2Y 3x1x240
lv_line = NAYY 4x1x150

[grid_expansion_allowed_voltage_deviations]
Expand Down
48 changes: 47 additions & 1 deletion edisgo/edisgo.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ class EDisGo:
def __init__(self, **kwargs):

# load configuration
self._config = Config(config_path=kwargs.get("config_path", None))
self._config = Config(config_path=kwargs.get("config_path", "default"))

# instantiate topology object and load grid data
self.topology = Topology(config=self.config)
Expand Down Expand Up @@ -2037,6 +2037,52 @@ def check_integrity(self):

logging.info("Integrity check finished. Please pay attention to warnings.")

def resample_timeseries(self, method: str = "ffill", freq: str = "15min"):
"""
Resamples all generator, load and storage time series to a desired resolution.
The following time series are affected by this:
* :attr:`~.network.timeseries.TimeSeries.generators_active_power`
* :attr:`~.network.timeseries.TimeSeries.loads_active_power`
* :attr:`~.network.timeseries.TimeSeries.storage_units_active_power`
* :attr:`~.network.timeseries.TimeSeries.generators_reactive_power`
* :attr:`~.network.timeseries.TimeSeries.loads_reactive_power`
* :attr:`~.network.timeseries.TimeSeries.storage_units_reactive_power`
Both up- and down-sampling methods are possible.
Parameters
----------
method : str, optional
Method to choose from to fill missing values when resampling.
Possible options are:
* 'ffill'
Propagate last valid observation forward to next valid
observation. See :pandas:`pandas.DataFrame.ffill<DataFrame.ffill>`.
* 'bfill'
Use next valid observation to fill gap. See
:pandas:`pandas.DataFrame.bfill<DataFrame.bfill>`.
* 'interpolate'
Fill NaN values using an interpolation method. See
:pandas:`pandas.DataFrame.interpolate<DataFrame.interpolate>`.
Default: 'ffill'.
freq : str, optional
Frequency that time series is resampled to. Offset aliases can be found
here:
https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#offset-aliases.
Default: '15min'.
"""
self.timeseries.resample_timeseries(method=method, freq=freq)


def import_edisgo_from_pickle(filename, path=""):
abs_path = os.path.abspath(path)
Expand Down
20 changes: 10 additions & 10 deletions edisgo/equipment/equipment-parameters_LV_cables.csv
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
name,U_n,I_max_th,R_per_km,L_per_km
#-,kV,kA,ohm/km,mH/km
NAYY 4x1x300,0.4,0.419,0.1,0.279
NAYY 4x1x240,0.4,0.364,0.125,0.254
NAYY 4x1x185,0.4,0.313,0.164,0.256
NAYY 4x1x150,0.4,0.275,0.206,0.256
NAYY 4x1x120,0.4,0.245,0.253,0.256
NAYY 4x1x95,0.4,0.215,0.320,0.261
NAYY 4x1x50,0.4,0.144,0.449,0.270
NAYY 4x1x35,0.4,0.123,0.868,0.271
name,U_n,I_max_th,R_per_km,L_per_km,C_per_km
#-,kV,kA,ohm/km,mH/km,uF/km
NAYY 4x1x300,0.4,0.419,0.1,0.279,0
NAYY 4x1x240,0.4,0.364,0.125,0.254,0
NAYY 4x1x185,0.4,0.313,0.164,0.256,0
NAYY 4x1x150,0.4,0.275,0.206,0.256,0
NAYY 4x1x120,0.4,0.245,0.253,0.256,0
NAYY 4x1x95,0.4,0.215,0.320,0.261,0
NAYY 4x1x50,0.4,0.144,0.449,0.270,0
NAYY 4x1x35,0.4,0.123,0.868,0.271,0
2 changes: 1 addition & 1 deletion edisgo/flex_opt/charging_strategies.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
],
}

logger = logging.getLogger("edisgo")
logger = logging.getLogger(__name__)


# TODO: the dummy timeseries should be as long as the simulated days and not
Expand Down
66 changes: 39 additions & 27 deletions edisgo/flex_opt/reinforce_measures.py
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ def reinforce_lines_voltage_issues(edisgo_obj, grid, crit_nodes):
]
elif isinstance(grid, MVGrid):
standard_line = edisgo_obj.config["grid_expansion_standard_equipment"][
"mv_line"
f"mv_line_{int(grid.nominal_voltage)}kv"
]
else:
raise ValueError("Inserted grid is invalid.")
Expand Down Expand Up @@ -693,40 +693,52 @@ def _replace_by_parallel_standard_lines(lines):

lines_changes.update(number_parallel_lines.to_dict())

standard_line_type = edisgo_obj.config["grid_expansion_standard_equipment"][
"{}_line".format(voltage_level)
]

lines_changes = {}

# chose lines of right grid level
relevant_lines = edisgo_obj.topology.lines_df.loc[
crit_lines[crit_lines.voltage_level == voltage_level].index
]
if not relevant_lines.empty:
nominal_voltage = edisgo_obj.topology.buses_df.loc[
edisgo_obj.topology.lines_df.loc[relevant_lines.index[0], "bus0"], "v_nom"
]
if nominal_voltage == 0.4:
standard_line_type = edisgo_obj.config["grid_expansion_standard_equipment"][
"lv_line"
]
else:
standard_line_type = edisgo_obj.config["grid_expansion_standard_equipment"][
f"mv_line_{int(nominal_voltage)}kv"
]

# handling of standard lines
lines_standard = relevant_lines.loc[relevant_lines.type_info == standard_line_type]
if not lines_standard.empty:
_add_parallel_standard_lines(lines_standard.index)
# handling of standard lines
lines_standard = relevant_lines.loc[
relevant_lines.type_info == standard_line_type
]
if not lines_standard.empty:
_add_parallel_standard_lines(lines_standard.index)

# get lines that have not been updated yet (i.e. that are not standard
# lines)
relevant_lines = relevant_lines.loc[
~relevant_lines.index.isin(lines_standard.index)
]
# handling of cables where adding one cable is sufficient
lines_single = (
relevant_lines.loc[relevant_lines.num_parallel == 1]
.loc[relevant_lines.kind == "cable"]
.loc[crit_lines.max_rel_overload < 2]
)
if not lines_single.empty:
_add_one_parallel_line_of_same_type(lines_single.index)
# get lines that have not been updated yet (i.e. that are not standard
# lines)
relevant_lines = relevant_lines.loc[
~relevant_lines.index.isin(lines_standard.index)
]
# handling of cables where adding one cable is sufficient
lines_single = (
relevant_lines.loc[relevant_lines.num_parallel == 1]
.loc[relevant_lines.kind == "cable"]
.loc[crit_lines.max_rel_overload < 2]
)
if not lines_single.empty:
_add_one_parallel_line_of_same_type(lines_single.index)

# handle rest of lines (replace by as many parallel standard lines as
# needed)
relevant_lines = relevant_lines.loc[~relevant_lines.index.isin(lines_single.index)]
if not relevant_lines.empty:
_replace_by_parallel_standard_lines(relevant_lines.index)
# handle rest of lines (replace by as many parallel standard lines as
# needed)
relevant_lines = relevant_lines.loc[
~relevant_lines.index.isin(lines_single.index)
]
if not relevant_lines.empty:
_replace_by_parallel_standard_lines(relevant_lines.index)

return lines_changes
2 changes: 1 addition & 1 deletion edisgo/io/pypsa_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def _set_slack(grid):
],
"Line": edisgo_object.topology.lines_df.loc[
:,
["bus0", "bus1", "x", "r", "s_nom", "num_parallel", "length"],
["bus0", "bus1", "x", "r", "b", "s_nom", "num_parallel", "length"],
],
"Transformer": edisgo_object.topology.transformers_df.loc[
:, ["bus0", "bus1", "x_pu", "r_pu", "type_info", "s_nom"]
Expand Down
2 changes: 1 addition & 1 deletion edisgo/network/electromobility.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
if "READTHEDOCS" not in os.environ:
import geopandas as gpd

logger = logging.getLogger("edisgo")
logger = logging.getLogger(__name__)

COLUMNS = {
"charging_processes_df": [
Expand Down
86 changes: 85 additions & 1 deletion edisgo/network/timeseries.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,9 +307,11 @@ def reset(self):
Resets all time series.
Active and reactive power time series of all loads, generators and storage units
are deleted, as well as everything stored in :py:attr:`~time_series_raw`.
are deleted, as well as timeindex everything stored in
:py:attr:`~time_series_raw`.
"""
self.timeindex = pd.DatetimeIndex([])
self.generators_active_power = None
self.loads_active_power = None
self.storage_units_active_power = None
Expand Down Expand Up @@ -2145,6 +2147,88 @@ def _check_if_components_exist(
return set(component_names) - set(comps_not_in_network)
return component_names

def resample_timeseries(self, method: str = "ffill", freq: str = "15min"):
"""
Resamples all generator, load and storage time series to a desired resolution.
See :attr:`~.EDisGo.resample_timeseries` for more information.
Parameters
----------
method : str, optional
See :attr:`~.EDisGo.resample_timeseries` for more information.
freq : str, optional
See :attr:`~.EDisGo.resample_timeseries` for more information.
"""

# add time step at the end of the time series in case of up-sampling so that
# last time interval in the original time series is still included
attrs = self._attributes
freq_orig = self.timeindex[1] - self.timeindex[0]
df_dict = {}
for attr in attrs:
df_dict[attr] = getattr(self, attr)
if pd.Timedelta(freq) < freq_orig: # up-sampling
new_dates = pd.DatetimeIndex([df_dict[attr].index[-1] + freq_orig])
else: # down-sampling
new_dates = pd.DatetimeIndex([df_dict[attr].index[-1]])
df_dict[attr] = (
df_dict[attr]
.reindex(df_dict[attr].index.union(new_dates).unique().sort_values())
.ffill()
)

# create new index
if pd.Timedelta(freq) < freq_orig: # up-sampling
index = pd.date_range(
self.timeindex[0],
self.timeindex[-1] + freq_orig,
freq=freq,
closed="left",
)
else: # down-sampling
index = pd.date_range(
self.timeindex[0],
self.timeindex[-1],
freq=freq,
)

# set new timeindex
self._timeindex = index

# resample time series
if pd.Timedelta(freq) < freq_orig: # up-sampling
if method == "interpolate":
for attr in attrs:
setattr(
self,
attr,
df_dict[attr].resample(freq, closed="left").interpolate(),
)
elif method == "ffill":
for attr in attrs:
setattr(
self, attr, df_dict[attr].resample(freq, closed="left").ffill()
)
elif method == "bfill":
for attr in attrs:
setattr(
self, attr, df_dict[attr].resample(freq, closed="left").bfill()
)
else:
raise NotImplementedError(
f"Resampling method {method} is not implemented."
)
else: # down-sampling
for attr in attrs:
setattr(
self,
attr,
df_dict[attr].resample(freq).mean(),
)


class TimeSeriesRaw:
"""
Expand Down
Loading

0 comments on commit eb78d1b

Please sign in to comment.