diff --git a/README.md b/README.md index f2f6633f..9372d63c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -[![Documentation Status](https://readthedocs.org/projects/ding0/badge/?version=dev)](http://ding0.readthedocs.io/en/dev/?badge=dev) +[![Documentation Status](https://readthedocs.org/projects/ding0/badge/?version=dev)](http://dingo.readthedocs.io/en/dev) [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.834751.svg)](https://doi.org/10.5281/zenodo.834751) DING0 @@ -8,11 +8,6 @@ DING0 DIstribution Network GeneratOr -- A tool to generate synthetic medium and low voltage power distribution grids based on open (or at least accessible) data. -WARNING: Note, currently the data source Ding0 relies on - the -[Open Energy Database](http://oep.iks.cs.ovgu.de/dataedit/) - has no public -accessible API, yet. Thus, currently you won't be able to run Ding0 without -modifications. - Installation and usage ---------------------- diff --git a/ding0/config/config_db_tables.cfg b/ding0/config/config_db_tables.cfg index b6a76c14..33ef9285 100644 --- a/ding0/config/config_db_tables.cfg +++ b/ding0/config/config_db_tables.cfg @@ -24,7 +24,7 @@ mv_stations = EgoDpHvmvSubstation lv_stations = EgoDpMvlvSubstation re_generators = t_ego_dp_res_powerplant_sq_mview conv_generators = t_ego_dp_conv_powerplant_sq_mview -version = v0.4.2 +version = v0.4.5 [input_data_source] input_data = versioned \ No newline at end of file diff --git a/ding0/core/__init__.py b/ding0/core/__init__.py index f3be2a6d..4c9d9817 100644 --- a/ding0/core/__init__.py +++ b/ding0/core/__init__.py @@ -24,6 +24,7 @@ from ding0.core.powerflow import * from ding0.tools import pypsa_io from ding0.tools.animation import AnimationDing0 +from ding0.tools.plots import plot_mv_topology from ding0.flexopt.reinforce_grid import * import os @@ -36,12 +37,15 @@ from sqlalchemy.orm import sessionmaker from sqlalchemy import func from geoalchemy2.shape import from_shape -from shapely.wkt import loads as wkt_loads -from shapely.geometry import Point, MultiPoint, MultiLineString, LineString -from shapely.geometry import shape, mapping import subprocess import oedialect +if not 'READTHEDOCS' in os.environ: + from shapely.wkt import loads as wkt_loads + from shapely.geometry import Point, MultiPoint, MultiLineString, LineString + from shapely.geometry import shape, mapping + from shapely.wkt import dumps as wkt_dumps + logger = logging.getLogger('ding0') package_path = ding0.__path__[0] @@ -99,7 +103,7 @@ def orm(self): """Returns ORM data""" return self._orm - def run_ding0(self, session, mv_grid_districts_no=None, debug=False): + def run_ding0(self, session, mv_grid_districts_no=None, debug=False, export_figures=False): """ Let DING0 run by shouting at this method (or just call it from NetworkDing0 instance). This method is a wrapper for the main functionality of DING0. @@ -113,6 +117,8 @@ def run_ding0(self, session, mv_grid_districts_no=None, debug=False): all grid_districts & stations are imported) debug : bool, defaults to False If True, information is printed during process + export_figures : bool, defaults to False + If True, figures are shown or exported (default path: ~/.ding0/) during run. Returns ------- @@ -210,22 +216,36 @@ def run_ding0(self, session, mv_grid_districts_no=None, debug=False): self.build_lv_grids() # STEP 6: Build MV grids - self.mv_routing(debug=False, animation=False) + self.mv_routing(debug=False) + if export_figures: + grid = self._mv_grid_districts[0].mv_grid + plot_mv_topology(grid, subtitle='Routing completed', filename='1_routing_completed.png') # STEP 7: Connect MV and LV generators self.connect_generators(debug=False) + if export_figures: + plot_mv_topology(grid, subtitle='Generators connected', filename='2_generators_connected.png') # STEP 8: Set IDs for all branches in MV and LV grids self.set_branch_ids() # STEP 9: Relocate switch disconnectors in MV grid self.set_circuit_breakers(debug=debug) + if export_figures: + plot_mv_topology(grid, subtitle='Circuit breakers relocated', filename='3_circuit_breakers_relocated.png') # STEP 10: Open all switch disconnectors in MV grid self.control_circuit_breakers(mode='open') # STEP 11: Do power flow analysis of MV grid self.run_powerflow(session, method='onthefly', export_pypsa=False, debug=debug) + if export_figures: + plot_mv_topology(grid, subtitle='PF result (load case)', + filename='4_PF_result_load.png', + line_color='loading', node_color='voltage', testcase='load') + plot_mv_topology(grid, subtitle='PF result (feedin case)', + filename='5_PF_result_feedin.png', + line_color='loading', node_color='voltage', testcase='feedin') # STEP 12: Reinforce MV grid self.reinforce_grid() @@ -233,6 +253,14 @@ def run_ding0(self, session, mv_grid_districts_no=None, debug=False): # STEP 13: Close all switch disconnectors in MV grid self.control_circuit_breakers(mode='close') + if export_figures: + plot_mv_topology(grid, subtitle='Final grid PF result (load case)', + filename='6_final_grid_PF_result_load.png', + line_color='loading', node_color='voltage', testcase='load') + plot_mv_topology(grid, subtitle='Final grid PF result (feedin case)', + filename='7_final_grid_PF_result_feedin.png', + line_color='loading', node_color='voltage', testcase='feedin') + if debug: logger.info('Elapsed time for {0} MV Grid Districts (seconds): {1}'.format( str(len(mv_grid_districts_no)), time.time() - start)) @@ -359,7 +387,6 @@ def build_lv_grid_district(self, # raise ValueError( # 'Load Area {} has no LVGD - please re-open #155'.format( # repr(lv_load_area))) - from shapely.wkt import dumps as wkt_dumps geom = wkt_dumps(lv_load_area.geo_area) lv_grid_districts = \ diff --git a/ding0/core/network/__init__.py b/ding0/core/network/__init__.py index be2d9d35..24bfc7b8 100644 --- a/ding0/core/network/__init__.py +++ b/ding0/core/network/__init__.py @@ -131,10 +131,13 @@ def graph_add_node(self, node_object): def graph_draw(self, mode): """ Draws grid graph using networkx + This method is for debugging purposes only. + Use ding0.tools.plots.plot_mv_topology() for advanced plotting. + Parameters ---------- mode : str - Mode selection 'MV' or 'LV'. #TODO: check + Mode selection 'MV' or 'LV'. Notes ----- diff --git a/ding0/core/network/grids.py b/ding0/core/network/grids.py index 0e435f53..04d66645 100644 --- a/ding0/core/network/grids.py +++ b/ding0/core/network/grids.py @@ -16,7 +16,7 @@ # from ding0.core.network import GridDing0 from . import GridDing0 from ding0.core.network.stations import * -from ding0.core.network import RingDing0, BranchDing0, CircuitBreakerDing0 +from ding0.core.network import RingDing0, CircuitBreakerDing0 from ding0.core.network.loads import * from ding0.core.network.cable_distributors import MVCableDistributorDing0, LVCableDistributorDing0 from ding0.grid.mv_grid import mv_routing, mv_connect @@ -27,13 +27,15 @@ from ding0.flexopt.reinforce_grid import * from ding0.core.structure.regions import LVLoadAreaCentreDing0 +import os import networkx as nx from datetime import datetime -from shapely.ops import transform import pyproj from functools import partial import logging +if not 'READTHEDOCS' in os.environ: + from shapely.ops import transform logger = logging.getLogger('ding0') diff --git a/ding0/core/structure/regions.py b/ding0/core/structure/regions.py index 64de080b..24254bfa 100644 --- a/ding0/core/structure/regions.py +++ b/ding0/core/structure/regions.py @@ -13,10 +13,12 @@ __author__ = "nesnoj, gplssm" +import os from . import RegionDing0 from ding0.tools import config as cfg_ding0 -from shapely.wkt import loads as wkt_loads +if not 'READTHEDOCS' in os.environ: + from shapely.wkt import loads as wkt_loads class MVGridDistrictDing0(RegionDing0): diff --git a/ding0/examples/example_analyze_multiple_grid_districts.py b/ding0/examples/example_analyze_multiple_grid_districts.py index 120d1479..72a27d8f 100644 --- a/ding0/examples/example_analyze_multiple_grid_districts.py +++ b/ding0/examples/example_analyze_multiple_grid_districts.py @@ -12,30 +12,31 @@ Notes ----- -This example file assumes you have already run the example file -`example_multiple_grid_districts.py` and use the option to save the `nd` object to -disc. If the example script was executed in PWD, do not change `base_path` -below. -""" +This example file creates some statistics of the specified ding0 grids that are +saved to `BASEPATH/results/` and some plots that are shown and saved to +`BASEPATH/plots/`. The example assumes you have already run the example file +`example_multiple_grid_districts.py` and use the option to save the `nd` object +to disc. Make sure to use the same BASEPATH here as in +`example_multiple_grid_districts.py`. -__copyright__ = "Reiner Lemoine Institut gGmbH" -__license__ = "GNU Affero General Public License Version 3 (AGPL-3.0)" -__url__ = "https://github.com/openego/ding0/blob/master/LICENSE" -__author__ = "nesnoj, gplssm" +""" +__copyright__ = "Reiner Lemoine Institut gGmbH" +__license__ = "GNU Affero General Public License Version 3 (AGPL-3.0)" +__url__ = "https://github.com/openego/ding0/blob/master/LICENSE" +__author__ = "nesnoj, gplssm" from ding0.tools import results from ding0.tools.logger import get_default_home_dir import os -import pandas as pd from matplotlib import pyplot as plt - BASEPATH = get_default_home_dir() + def ding0_exemplary_plots(stats, base_path=BASEPATH): """ - Analyze multiple grid district data generated with Ding0 + Analyze multiple grid district data generated with Ding0. Parameters ---------- @@ -44,13 +45,15 @@ def ding0_exemplary_plots(stats, base_path=BASEPATH): base_path : str Root directory of Ding0 data structure, i.e. '~/.ding0' (which is default). + """ # make some plot plotpath = os.path.join(base_path, 'plots') results.plot_cable_length(stats, plotpath) + plt.show() results.plot_generation_over_load(stats, plotpath) - results.plot_km_cable_vs_line(stats, plotpath) + plt.show() def nd_load_and_stats(filenames, base_path=BASEPATH): @@ -59,8 +62,8 @@ def nd_load_and_stats(filenames, base_path=BASEPATH): Passes the list of files assuming the ding0 data structure as default in :code:`~/.ding0`. - Data will concatenated and key indicators for each grid district are - returned in table and graphic format + Data will be concatenated and key indicators for each grid district are + returned in table and graphic format. Parameters ---------- @@ -69,10 +72,12 @@ def nd_load_and_stats(filenames, base_path=BASEPATH): base_path : str Root directory of Ding0 data structure, i.e. '~/.ding0' (which is default). + Returns ------- stats : pandas.DataFrame Statistics of each MV grid districts + """ # load Ding0 data @@ -80,9 +85,9 @@ def nd_load_and_stats(filenames, base_path=BASEPATH): for filename in filenames: try: nd_load = results.load_nd_from_pickle(filename= - os.path.join(base_path, - 'results', - filename)) + os.path.join(base_path, + 'grids', + filename)) nds.append(nd_load) except: @@ -94,18 +99,16 @@ def nd_load_and_stats(filenames, base_path=BASEPATH): for n in nds[1:]: nd.add_mv_grid_district(n._mv_grid_districts[0]) - nodes_df, edges_df = nd.to_dataframe() - # get statistical numbers about grid - stats = results.calculate_mvgd_stats(nodes_df, edges_df) + stats = results.calculate_mvgd_stats(nd) - # TODO: correct LV peak load/ generation capacity. Same in all LV GD return stats + if __name__ == '__main__': base_path = BASEPATH - mv_grid_districts = list(range(1, 20)) + mv_grid_districts = list(range(1729, 1732)) filenames = ["ding0_grids__{ext}.pkl".format(ext=_) for _ in mv_grid_districts] @@ -115,7 +118,7 @@ def nd_load_and_stats(filenames, base_path=BASEPATH): # save stats file to disc stats.to_csv(os.path.join(base_path, 'results', - 'ding0_grids_stats_{first}-{last}'.format( + 'ding0_grids_stats_{first}-{last}.csv'.format( first=mv_grid_districts[0], last=mv_grid_districts[-1]))) diff --git a/ding0/examples/example_analyze_single_grid_district.py b/ding0/examples/example_analyze_single_grid_district.py index ed66f6b3..2b8fedfb 100644 --- a/ding0/examples/example_analyze_single_grid_district.py +++ b/ding0/examples/example_analyze_single_grid_district.py @@ -14,23 +14,21 @@ This example file assumes you have already run the example file `example_single_grid_district.py` and use the option to save the `nd` object to -disk. If the example script was executed in PWD, do not change `base_path` -below. -""" +disk. -__copyright__ = "Reiner Lemoine Institut gGmbH" -__license__ = "GNU Affero General Public License Version 3 (AGPL-3.0)" -__url__ = "https://github.com/openego/ding0/blob/master/LICENSE" -__author__ = "nesnoj, gplssm" +""" +__copyright__ = "Reiner Lemoine Institut gGmbH" +__license__ = "GNU Affero General Public License Version 3 (AGPL-3.0)" +__url__ = "https://github.com/openego/ding0/blob/master/LICENSE" +__author__ = "nesnoj, gplssm" from ding0.tools import results +from pandas import option_context from matplotlib import pyplot as plt -base_path = '' - -def example_stats(filename, plotpath=''): +def example_stats(filename): """ Obtain statistics from create grid topology @@ -42,16 +40,16 @@ def example_stats(filename, plotpath=''): nodes_df, edges_df = nd.to_dataframe() # get statistical numbers about grid - stats = results.calculate_mvgd_stats(nodes_df, edges_df) + stats = results.calculate_mvgd_stats(nd) # plot distribution of load/generation of subjacent LV grids stations = nodes_df[nodes_df['type'] == 'LV Station'] f, axarr = plt.subplots(2, sharex=True) - f.suptitle("Peak load (top)/ peak generation capacity (bottom) at LV " - "substation in kW") - stations.hist(column=['peak_load'], bins=20, alpha=0.5, ax=axarr[0]) + f.suptitle("Peak load (top) / peak generation capacity (bottom) at LV " + "substations in kW") + stations['peak_load'].hist(bins=20, alpha=0.5, ax=axarr[0]) axarr[0].set_title("Peak load in kW") - stations.hist(column=['generation_capacity'], bins=20, alpha=0.5, ax=axarr[1]) + stations['generation_capacity'].hist(bins=20, alpha=0.5, ax=axarr[1]) axarr[1].set_title("Peak generation capacity in kW") plt.show() @@ -59,51 +57,15 @@ def example_stats(filename, plotpath=''): print("You are analyzing MV grid district {mvgd}\n".format( mvgd=int(stats.index.values))) - # Print peak load - print("Total peak load: {load:.0f} kW".format(load=float(stats['peak_load']))) - print("\t thereof MV: {load:.0f} kW".format(load=0)) - print("\t thereof LV: {load:.0f} kW".format(load=float(stats['LV peak load']))) - - # Print generation capacity - print("\nTotal generation capacity: {gen:.0f} kW".format( - gen=float(stats['generation_capacity']))) - print("\t thereof MV: {gen:.0f} kW".format( - gen=float(stats['MV generation capacity']))) - print("\t thereof LV: {gen:.0f} kW".format( - gen=float(stats['LV generation capacity']))) - - # print total length of cables/overhead lines - print("\nTotal cable length: {length:.1f} km".format(length=float(stats['km_cable']))) - print("Total line length: {length:.1f} km".format(length=float(stats['km_line']))) - - # Other predefined functions bring extra information for example the number - # of generators directly connected to the bus bar of LV station - stations_generators = results.lv_grid_generators_bus_bar(nd) - print('\nGenerators directly connected to the substation') - for k, v in stations_generators.items(): - if v: - print("{station}: {gens}".format(station=k, gens=len(v))) - - # Number of line/cable equipment type - print("\n") - for t, cnt in dict(edges_df.groupby('type_name').size()).items(): - print("Line/cable of type {type} occurs {cnt} times".format(type=t, - cnt=cnt)) - - # Access results directly from nd-object if they are not available in stats/ - # nodes_df or edges_df - # One example: print length of each half ring in this MVGD - print("\n") - root = nd._mv_grid_districts[0].mv_grid.station() - for circ_breaker in nd._mv_grid_districts[0].mv_grid.circuit_breakers(): - for half_ring in [0, 1]: - half_ring_length = nd._mv_grid_districts[ - 0].mv_grid.graph_path_length( - circ_breaker.branch_nodes[half_ring], root) / 1000 - print('Length to circuit breaker', repr(circ_breaker), - ', half-ring', str(half_ring), ':', str(half_ring_length), - 'km') + # print all the calculated stats + # this isn't a particularly beautiful format but it is + # information rich + with option_context('display.max_rows', None, + 'display.max_columns', None, + 'display.max_colwidth', -1): + print(stats.T) + if __name__ == '__main__': filename = 'ding0_grids_example.pkl' - example_stats(filename) \ No newline at end of file + example_stats(filename) diff --git a/ding0/examples/example_multiple_grid_districts.py b/ding0/examples/example_multiple_grid_districts.py index d9bf3ffb..30a751e2 100755 --- a/ding0/examples/example_multiple_grid_districts.py +++ b/ding0/examples/example_multiple_grid_districts.py @@ -9,11 +9,10 @@ DING0 lives at github: https://github.com/openego/ding0/ The documentation is available on RTD: http://ding0.readthedocs.io""" -__copyright__ = "Reiner Lemoine Institut gGmbH" -__license__ = "GNU Affero General Public License Version 3 (AGPL-3.0)" -__url__ = "https://github.com/openego/ding0/blob/master/LICENSE" -__author__ = "nesnoj, gplssm" - +__copyright__ = "Reiner Lemoine Institut gGmbH" +__license__ = "GNU Affero General Public License Version 3 (AGPL-3.0)" +__url__ = "https://github.com/openego/ding0/blob/master/LICENSE" +__author__ = "nesnoj, gplssm" import matplotlib.pyplot as plt import time @@ -45,7 +44,6 @@ def create_results_dirs(base_path): The base path has subdirectories for raw and processed results """ - if not os.path.exists(base_path): print("Creating directory {} for results data.".format(base_path)) os.mkdir(base_path) @@ -111,21 +109,21 @@ def run_multiple_grid_districts(mv_grid_districts, run_id, failsafe=False, # instantiate ding0 network object nd = NetworkDing0(name='network', run_id=run_id) - if not os.path.exists(os.path.join(base_path, run_id)): - os.mkdir(os.path.join(base_path, run_id)) + if not os.path.exists(os.path.join(base_path, "grids")): + os.mkdir(os.path.join(base_path, "grids")) if not failsafe: # run DING0 on selected MV Grid District msg = nd.run_ding0(session=session, - mv_grid_districts_no=[mvgd]) + mv_grid_districts_no=[mvgd]) # save results - results.save_nd_to_pickle(nd, os.path.join(base_path, run_id)) + results.save_nd_to_pickle(nd, os.path.join(base_path, "grids")) else: # try to perform ding0 run on grid district try: msg = nd.run_ding0(session=session, - mv_grid_districts_no=[mvgd]) + mv_grid_districts_no=[mvgd]) # if not successful, put grid district to report if msg: corrupt_grid_districts = corrupt_grid_districts.append( @@ -135,7 +133,7 @@ def run_multiple_grid_districts(mv_grid_districts, run_id, failsafe=False, # if successful, save results else: results.save_nd_to_pickle(nd, os.path.join(base_path, - run_id)) + "grids")) except Exception as e: corrupt_grid_districts = corrupt_grid_districts.append( pd.Series({'id': mvgd, @@ -154,9 +152,8 @@ def run_multiple_grid_districts(mv_grid_districts, run_id, failsafe=False, else: metadata['mv_grid_districts'].append(mvgd) - # Save metadata to disk - with open(os.path.join(base_path, run_id, 'Ding0_{}.meta'.format(run_id)), + with open(os.path.join(base_path, "grids", 'Ding0_{}.meta'.format(run_id)), 'w') as f: json.dump(metadata, f) @@ -164,7 +161,7 @@ def run_multiple_grid_districts(mv_grid_districts, run_id, failsafe=False, corrupt_grid_districts.to_csv( os.path.join( base_path, - run_id, + "grids", 'corrupt_mv_grid_districts.txt'), index=False, float_format='%.0f') @@ -172,7 +169,6 @@ def run_multiple_grid_districts(mv_grid_districts, run_id, failsafe=False, print('Elapsed time for', str(len(mv_grid_districts)), 'MV grid districts (seconds): {}'.format(time.time() - start)) - return msg diff --git a/ding0/examples/example_parallel_multiple_grid_districts.py b/ding0/examples/example_parallel_multiple_grid_districts.py index 86280322..b2a35fce 100644 --- a/ding0/examples/example_parallel_multiple_grid_districts.py +++ b/ding0/examples/example_parallel_multiple_grid_districts.py @@ -7,7 +7,14 @@ It is developed in the project open_eGo: https://openegoproject.wordpress.com DINGO lives at github: https://github.com/openego/ding0/ -The documentation is available on RTD: http://ding0.readthedocs.io""" +The documentation is available on RTD: http://ding0.readthedocs.io + +Notes +----- + +This example file creates ding0 grids for all 3608 grid districts. + +""" __copyright__ = "Reiner Lemoine Institut gGmbH" __license__ = "GNU Affero General Public License Version 3 (AGPL-3.0)" diff --git a/ding0/examples/example_single_grid_district.py b/ding0/examples/example_single_grid_district.py index f3907100..f7f13ea2 100644 --- a/ding0/examples/example_single_grid_district.py +++ b/ding0/examples/example_single_grid_district.py @@ -40,15 +40,11 @@ nd = NetworkDing0(name='network') # choose MV Grid Districts to import -mv_grid_districts = [3040] +mv_grid_districts = [460] # run DING0 on selected MV Grid District nd.run_ding0(session=session, mv_grid_districts_no=mv_grid_districts) -# export grids to database -# nd.export_mv_grid(conn, mv_grid_districts) -# nd.export_mv_grid_new(conn, mv_grid_districts) - # export grid to file (pickle) save_nd_to_pickle(nd, filename='ding0_grids_example.pkl') diff --git a/ding0/grid/mv_grid/mv_connect.py b/ding0/grid/mv_grid/mv_connect.py index b057a325..24d1374a 100644 --- a/ding0/grid/mv_grid/mv_connect.py +++ b/ding0/grid/mv_grid/mv_connect.py @@ -13,6 +13,11 @@ __author__ = "nesnoj, gplssm" +import os +import pyproj +from functools import partial +import time +import logging from ding0.core.network.stations import * from ding0.core.network import BranchDing0, GeneratorDing0 @@ -23,14 +28,9 @@ from ding0.tools.geo import calc_geo_branches_in_buffer,calc_geo_dist_vincenty,\ calc_geo_centre_point, calc_geo_branches_in_polygon -from shapely.geometry import LineString -from shapely.ops import transform -import pyproj -from functools import partial - -import time -import logging - +if not 'READTHEDOCS' in os.environ: + from shapely.geometry import LineString + from shapely.ops import transform logger = logging.getLogger('ding0') diff --git a/ding0/grid/mv_grid/solvers/base.py b/ding0/grid/mv_grid/solvers/base.py index 62ff9bcc..33d4231e 100644 --- a/ding0/grid/mv_grid/solvers/base.py +++ b/ding0/grid/mv_grid/solvers/base.py @@ -193,10 +193,18 @@ def draw_network(self, anim): g.add_edges_from(e) plt.figure() + ax = plt.gca() + ax.get_xaxis().set_visible(False) + ax.get_yaxis().set_visible(False) if anim is not None: nx.draw_networkx(g, nodes_pos, with_labels=False, node_size=50) - plt.savefig(anim.file_path + anim.file_prefix + (4 - len(str(anim.counter))) * '0' + str(anim.counter) + '.png') + plt.savefig(anim.file_path + + anim.file_prefix + + (4 - len(str(anim.counter))) * '0' + + str(anim.counter) + '.png', + dpi=150, + bbox_inches='tight') anim.counter += 1 plt.close() else: diff --git a/ding0/tools/animation.py b/ding0/tools/animation.py index 33373850..abb34dcd 100644 --- a/ding0/tools/animation.py +++ b/ding0/tools/animation.py @@ -13,21 +13,22 @@ __author__ = "nesnoj, gplssm" -import ding0 from ding0.tools import config as cfg_ding0 +from ding0.tools.logger import get_default_home_dir import os class AnimationDing0: - """ Class for visual animation of routing process. + """ Class for visual animation of the routing process (solving CVRP). (basically a central place to store information about output file and count of saved images). Use argument 'animation=True' of method 'NetworkDing0.mv_routing()' to enable image export. + The images are exported to ding0's home dir which is usually ~/.ding0/ . Subsequently, FFMPEG can be used to convert images to animation, e.g. - - ffmpeg -r 10 -i mv-routing_ani_%04d.png -c:v libx264 -vf fps=25 -pix_fmt yuv420p mv-routing_ani.mp4 + + ffmpeg -r 5 -i mv-routing_ani_%04d.png -vframes 200 -r 15 -vcodec libx264 -y -an mv-routing_ani.mp4 -s 640x480 See Also -------- @@ -36,8 +37,7 @@ class AnimationDing0: def __init__(self, **kwargs): output_animation_file_prefix = cfg_ding0.get('output', 'animation_file_prefix') - package_path = ding0.__path__[0] - self.file_path = os.path.join(package_path, 'output/animation/') + self.file_path = os.path.join(get_default_home_dir(), 'animation/') self.file_prefix = output_animation_file_prefix self.counter = 1 diff --git a/ding0/tools/geo.py b/ding0/tools/geo.py index 8f3ad91d..4b9046ce 100644 --- a/ding0/tools/geo.py +++ b/ding0/tools/geo.py @@ -13,16 +13,17 @@ __author__ = "nesnoj, gplssm" +import os from geopy.distance import vincenty -from shapely.geometry import LineString -from shapely.ops import transform - import pyproj from functools import partial from ding0.tools import config as cfg_ding0 import logging +if not 'READTHEDOCS' in os.environ: + from shapely.geometry import LineString + from shapely.ops import transform logger = logging.getLogger('ding0') diff --git a/ding0/tools/plots.py b/ding0/tools/plots.py new file mode 100644 index 00000000..03b4a4f5 --- /dev/null +++ b/ding0/tools/plots.py @@ -0,0 +1,348 @@ +import os +import math +import numpy as np +import matplotlib.pyplot as plt +import networkx as nx +from pyproj import Proj, transform +import logging + +logger = logging.getLogger('ding0') +from ding0.tools.logger import get_default_home_dir +from ding0.core.network.grids import MVGridDing0 + +use_gpd = False +use_ctx = False + +if 'READTHEDOCS' not in os.environ: + use_gpd = True + try: + import geopandas as gpd + except: + use_gpd = False + + use_ctx = True + try: + import contextily as ctx + except: + use_ctx = False + + +def plot_mv_topology(grid, subtitle='', filename=None, testcase='load', + line_color=None, node_color='type', + limits_cb_lines=None, limits_cb_nodes=None, + background_map=True): + """ Draws MV grid graph using networkx + + Parameters + ---------- + grid : :obj:`MVGridDing0` + MV grid to plot. + subtitle : str + Extend plot's title by this string. + filename : str + If provided, the figure will be saved and not displayed (default path: ~/.ding0/). + A prefix is added to the file name. + testcase : str + Defines which case is to be used. Refer to config_calc.cfg to see further + assumptions for the cases. Possible options are: + + * 'load' (default) + Heavy-load-flow case + * 'feedin' + Feedin-case + line_color : str + Defines whereby to choose line colors. Possible options are: + + * 'loading' + Line color is set according to loading of the line in heavy load case. + You can use parameter `limits_cb_lines` to adjust the color range. + * None (default) + Lines are plotted in black. Is also the fallback option in case of + wrong input. + node_color : str + Defines whereby to choose node colors. Possible options are: + + * 'type' (default) + Node color as well as size is set according to type of node + (generator, MV station, etc.). Is also the fallback option in case of + wrong input. + * 'voltage' + Node color is set according to voltage deviation from 1 p.u.. + You can use parameter `limits_cb_nodes` to adjust the color range. + limits_cb_lines : :obj:`tuple` + Tuple with limits for colorbar of line color. First entry is the + minimum and second entry the maximum value. E.g. pass (0, 1) to + adjust the colorbar to 0..100% loading. + Default: None (min and max loading are used). + limits_cb_nodes : :obj:`tuple` + Tuple with limits for colorbar of nodes. First entry is the + minimum and second entry the maximum value. E.g. pass (0.9, 1) to + adjust the colorbar to 90%..100% voltage. + Default: None (min and max loading are used). + background_map : bool, optional + If True, a background map is plotted (default: stamen toner light). + The additional package `contextily` is needed for this functionality. + Default: True + + Notes + ----- + WGS84 pseudo mercator (epsg:3857) is used as coordinate reference system (CRS). + Therefore, the drawn graph representation may be falsified! + """ + + def set_nodes_style_and_position(nodes): + + # TODO: MOVE settings to config + # node types (name of classes) + node_types = ['MVStationDing0', + 'LVStationDing0', + 'LVLoadAreaCentreDing0', + 'MVCableDistributorDing0', + 'GeneratorDing0', + 'GeneratorFluctuatingDing0', + 'CircuitBreakerDing0', + 'n/a'] + + # node styles + colors_dict = {'MVStationDing0': '#f2ae00', + 'LVStationDing0': 'grey', + 'LVLoadAreaCentreDing0': '#fffc3d', + 'MVCableDistributorDing0': '#000000', + 'GeneratorDing0': '#00b023', + 'GeneratorFluctuatingDing0': '#0078b0', + 'CircuitBreakerDing0': '#c20000', + 'n/a': 'orange'} + sizes_dict = {'MVStationDing0': 120, + 'LVStationDing0': 7, + 'LVLoadAreaCentreDing0': 30, + 'MVCableDistributorDing0': 5, + 'GeneratorDing0': 50, + 'GeneratorFluctuatingDing0': 50, + 'CircuitBreakerDing0': 50, + 'n/a': 5} + zindex_by_type = {'MVStationDing0': 16, + 'LVStationDing0': 12, + 'LVLoadAreaCentreDing0': 11, + 'MVCableDistributorDing0': 13, + 'GeneratorDing0': 14, + 'GeneratorFluctuatingDing0': 14, + 'CircuitBreakerDing0': 15, + 'n/a': 10} + + # dict of node class names: list of nodes + nodes_by_type = {_: [] for _ in node_types} + # dict of node class names: list of node-individual color + node_colors_by_type = {_: [] for _ in node_types} + # dict of node class names: list of node-individual size + node_sizes_by_type = {_: [] for _ in node_types} + node_sizes_by_type['all'] = [] + # dict of nodes:node-individual positions + nodes_pos = {} + + for n in nodes: + if type(n).__name__ in node_types: + nodes_by_type[type(n).__name__].append(n) + node_colors_by_type[type(n).__name__].append(colors_dict[type(n).__name__]) + node_sizes_by_type[type(n).__name__].append(sizes_dict[type(n).__name__]) + node_sizes_by_type['all'].append(sizes_dict[type(n).__name__]) + else: + nodes_by_type['n/a'].append(n) + node_colors_by_type['n/a'].append(colors_dict['n/a']) + node_sizes_by_type['n/a'].append(sizes_dict['n/a']) + node_sizes_by_type['all'].append(sizes_dict['n/a']) + nodes_pos[n] = (n.geo_data.x, n.geo_data.y) + + return node_types, nodes_by_type, node_colors_by_type,\ + node_sizes_by_type, zindex_by_type, nodes_pos + + def reproject_nodes(nodes_pos, model_proj='4326'): + inProj = Proj(init='epsg:{srid}'.format(srid=model_proj)) + outProj = Proj(init='epsg:3857') + nodes_pos2 = {} + for k, v in nodes_pos.items(): + x2, y2 = transform(inProj, outProj, + v[0], + v[1]) + nodes_pos2[k] = (x2, y2) + return nodes_pos2 + + def plot_background_map(ax): + url = ctx.sources.ST_TONER_LITE + xmin, xmax, ymin, ymax = ax.axis() + basemap, extent = ctx.bounds2img(xmin, ymin, xmax, ymax, + zoom=12, url=url) + ax.imshow(basemap, extent=extent, interpolation='bilinear', zorder=0) + ax.axis((xmin, xmax, ymin, ymax)) + + def plot_region_data(ax): + # get geoms of MV grid district, load areas and LV grid districts + mv_grid_district = gpd.GeoDataFrame({'geometry': grid.grid_district.geo_data}, + crs={'init': 'epsg:{srid}'.format(srid=model_proj)}) + load_areas = gpd.GeoDataFrame({'geometry': [la.geo_area for la in grid.grid_district.lv_load_areas()]}, + crs={'init': 'epsg:{srid}'.format(srid=model_proj)}) + lv_grid_districts = gpd.GeoDataFrame({'geometry': [lvgd.geo_data + for la in grid.grid_district.lv_load_areas() + for lvgd in la.lv_grid_districts()]}, + crs={'init': 'epsg:{srid}'.format(srid=model_proj)}) + + # reproject to WGS84 pseudo mercator + mv_grid_district = mv_grid_district.to_crs(epsg=3857) + load_areas = load_areas.to_crs(epsg=3857) + lv_grid_districts = lv_grid_districts.to_crs(epsg=3857) + + # plot + mv_grid_district.plot(ax=ax, color='#ffffff', alpha=0.2, edgecolor='k', linewidth=2, zorder=2) + load_areas.plot(ax=ax, color='#fffea3', alpha=0.1, edgecolor='k', linewidth=0.5, zorder=3) + lv_grid_districts.plot(ax=ax, color='#ffffff', alpha=0.05, edgecolor='k', linewidth=0.5, zorder=4) + + if not isinstance(grid, MVGridDing0): + logger.warning('Sorry, but plotting is currently only available for MV grids but you did not pass an' + 'instance of MVGridDing0. Plotting is skipped.') + return + + g = grid._graph + model_proj = grid.network.config['geo']['srid'] + + if testcase == 'feedin': + case_idx = 1 + else: + case_idx = 0 + + nodes_types, nodes_by_type, node_colors_by_type, node_sizes_by_type, zindex_by_type, nodes_pos =\ + set_nodes_style_and_position(g.nodes()) + + # reproject to WGS84 pseudo mercator + nodes_pos = reproject_nodes(nodes_pos, model_proj=model_proj) + + plt.figure(figsize=(9, 6)) + ax = plt.gca() + + if line_color == 'loading': + edges_color = [] + for n1, n2 in g.edges(): + edge = g.edge[n1][n2] + if hasattr(edge['branch'], 's_res'): + edges_color.append(edge['branch'].s_res[case_idx] * 1e3 / + (3 ** 0.5 * edge['branch'].type['U_n'] * edge['branch'].type['I_max_th'])) + else: + edges_color.append(0) + edges_cmap = plt.get_cmap('jet') + #edges_cmap.set_over('#952eff') + else: + edges_color = ['black'] * len(list(grid.graph_edges())) + edges_cmap = None + + # plot nodes by voltage + if node_color == 'voltage': + voltage_station = grid._station.voltage_res[case_idx] + nodes_color = [] + for n in g.nodes(): + if hasattr(n, 'voltage_res'): + nodes_color.append(n.voltage_res[case_idx]) + else: + nodes_color.append(voltage_station) + + if testcase == 'feedin': + nodes_cmap = plt.get_cmap('Reds') + nodes_vmax = voltage_station + float(grid.network.config + ['mv_routing_tech_constraints'] + ['mv_max_v_level_fc_diff_normal']) + nodes_vmin = voltage_station + else: + nodes_cmap = plt.get_cmap('Reds_r') + nodes_vmin = voltage_station - float(grid.network.config + ['mv_routing_tech_constraints'] + ['mv_max_v_level_lc_diff_normal']) + nodes_vmax = voltage_station + + nodes = nx.draw_networkx_nodes(g, + pos=nodes_pos, + node_color=nodes_color, + # node_shape='o', # TODO: Add additional symbols here + cmap=nodes_cmap, + vmin=nodes_vmin, + vmax=nodes_vmax, + node_size=node_sizes_by_type['all'], + linewidths=0.25, + ax=ax) + nodes.set_zorder(10) + nodes.set_edgecolor('k') + + # colorbar nodes + if limits_cb_nodes is None: + limits_cb_nodes = (math.floor(min(nodes_color)*100)/100, + math.ceil(max(nodes_color)*100)/100) + v_range = np.linspace(limits_cb_nodes[0], limits_cb_nodes[1], 101) + cb_voltage = plt.colorbar(nodes, boundaries=v_range, + ticks=v_range[0:101:10], + fraction=0.04, pad=0.1) + cb_voltage.set_clim(vmin=limits_cb_nodes[0], + vmax=limits_cb_nodes[1]) + cb_voltage.set_label('Node voltage deviation in %', size='smaller') + cb_voltage.ax.tick_params(labelsize='smaller') + + # plot nodes by type + else: + for node_type in nodes_types: + if len(nodes_by_type[node_type]) != 0: + nodes = nx.draw_networkx_nodes(g, + nodelist=nodes_by_type[node_type], + pos=nodes_pos, + # node_shape='o', # TODO: Add additional symbols here + node_color=node_colors_by_type[node_type], + cmap=None, + vmin=None, + vmax=None, + node_size=node_sizes_by_type[node_type], + linewidths=0.25, + label=node_type, + ax=ax) + nodes.set_zorder(zindex_by_type[node_type]) + nodes.set_edgecolor('k') + + edges = nx.draw_networkx_edges(g, + pos=nodes_pos, + edge_color=edges_color, + edge_cmap=edges_cmap, + edge_vmin=0, + edge_vmax=1, + #width=1, + ax=ax) + edges.set_zorder(5) + + if line_color == 'loading': + # colorbar edges + if limits_cb_lines is None: + limits_cb_lines = (math.floor(min(edges_color)*100)/100, + math.ceil(max(edges_color)*100)/100) + loading_range = np.linspace(limits_cb_lines[0], limits_cb_lines[1], 101) + cb_loading = plt.colorbar(edges, boundaries=loading_range, + ticks=loading_range[0:101:10], + fraction=0.04, pad=0.04) + cb_loading.set_clim(vmin=limits_cb_lines[0], + vmax=limits_cb_lines[1]) + cb_loading.set_label('Line loading in % of nominal capacity', size='smaller') + cb_loading.ax.tick_params(labelsize='smaller') + + if use_ctx and background_map: + plot_background_map(ax=ax) + if use_gpd: + plot_region_data(ax=ax) + + plt.legend(fontsize=7) + plt.title('MV Grid District {id} - {st}'.format(id=grid.id_db, + st=subtitle)) + + # hide axes labels (coords) + ax.get_xaxis().set_visible(False) + ax.get_yaxis().set_visible(False) + + if filename is None: + plt.tight_layout() + plt.show() + else: + path = os.path.join(get_default_home_dir(), 'ding0_grid_{id}_{filename}'.format(id=str(grid.id_db), + filename=filename)) + plt.savefig(path, dpi=300, bbox_inches='tight') + plt.close() + logger.info('==> Figure saved to {path}'.format(path=path)) diff --git a/ding0/tools/pypsa_io.py b/ding0/tools/pypsa_io.py index 02fa1707..b36575fa 100644 --- a/ding0/tools/pypsa_io.py +++ b/ding0/tools/pypsa_io.py @@ -23,7 +23,6 @@ from geoalchemy2.shape import from_shape from math import tan, acos, pi, sqrt -from shapely.geometry import LineString from pandas import Series, DataFrame, DatetimeIndex from pypsa.io import import_series_from_dataframe from pypsa import Network @@ -33,6 +32,8 @@ import os import logging +if not 'READTHEDOCS' in os.environ: + from shapely.geometry import LineString logger = logging.getLogger('ding0') diff --git a/ding0/tools/results.py b/ding0/tools/results.py index 5722e98f..6f482392 100644 --- a/ding0/tools/results.py +++ b/ding0/tools/results.py @@ -18,7 +18,6 @@ import pandas as pd import time import os -import json import re from matplotlib import pyplot as plt @@ -30,29 +29,29 @@ from ding0.core import LVCableDistributorDing0, MVCableDistributorDing0 from ding0.core import MVStationDing0, LVStationDing0 from ding0.core import CircuitBreakerDing0 -from ding0.core.network.loads import LVLoadDing0, MVLoadDing0 +from ding0.core.network.loads import LVLoadDing0 from ding0.core import LVLoadAreaCentreDing0 -from shapely.ops import transform import pyproj from functools import partial from geoalchemy2.shape import from_shape from sqlalchemy.orm import sessionmaker -from shapely.wkt import loads as wkt_loads -from shapely.geometry import Point, MultiPoint, MultiLineString, LineString -from shapely.geometry import shape, mapping - import multiprocessing as mp -from math import floor, ceil, pi +from math import floor, pi -from ding0.flexopt.check_tech_constraints import check_load, check_voltage, \ - get_critical_line_loading, get_critical_voltage_at_nodes +from ding0.flexopt.check_tech_constraints import get_critical_line_loading, \ + get_critical_voltage_at_nodes from ding0.tools import config as cfg_ding0 import networkx as nx +if not 'READTHEDOCS' in os.environ: + from shapely.ops import transform + from shapely.geometry import LineString + from shapely.wkt import dumps as wkt_dumps + ############################################# plt.close('all') cfg_ding0.load_config('config_db_tables.cfg') @@ -160,9 +159,11 @@ def plot_cable_length(stats, plotpath): """ # cable and line kilometer distribution - f, axarr = plt.subplots(2, sharex=True) - stats.hist(column=['km_cable'], bins=5, alpha=0.5, ax=axarr[0]) - stats.hist(column=['km_line'], bins=5, alpha=0.5, ax=axarr[1]) + f, axarr = plt.subplots(2, 2, sharex=True) + stats.hist(column=['Length of MV overhead lines'], bins=5, alpha=0.5, ax=axarr[0, 0]) + stats.hist(column=['Length of MV underground cables'], bins=5, alpha=0.5, ax=axarr[0, 1]) + stats.hist(column=['Length of LV overhead lines'], bins=5, alpha=0.5, ax=axarr[1, 0]) + stats.hist(column=['Length of LV underground cables'], bins=5, alpha=0.5, ax=axarr[1, 1]) plt.savefig(os.path.join(plotpath, 'Histogram_cable_line_length.pdf')) @@ -170,10 +171,7 @@ def plot_cable_length(stats, plotpath): def plot_generation_over_load(stats, plotpath): """ - - :param stats: - :param plotpath: - :return: + Plot of generation over load """ # Generation capacity vs. peak load @@ -181,18 +179,24 @@ def plot_generation_over_load(stats, plotpath): sns.set_style("ticks") # reformat to MW - stats[['generation_capacity', 'peak_load']] = stats[['generation_capacity', - 'peak_load']] / 1e3 + + gen_cap_indexes = ["Gen. Cap. of MV at v_level 4", + "Gen. Cap. of MV at v_level 5", + "Gen. Cap. of LV at v_level 6", + "Gen. Cap. of LV at v_level 7"] + peak_load_index = ["LA Total LV Peak Load total"] + stats['generation_capacity'] = stats[gen_cap_indexes].sum(axis=1) / 1e3 + stats['peak_load'] = stats[peak_load_index] / 1e3 sns.lmplot('generation_capacity', 'peak_load', data=stats, fit_reg=False, - hue='v_nom', + # hue='v_nom', # hue='Voltage level', scatter_kws={"marker": "D", "s": 100}, aspect=2) - plt.title('Peak load vs. generation capcity') + plt.title('Peak load vs. generation capacity') plt.xlabel('Generation capacity in MW') plt.ylabel('Peak load in MW') @@ -1719,7 +1723,7 @@ def aggregate_loads(la_center, aggr): return aggr for mv_district in nw.mv_grid_districts(): - from shapely.wkt import dumps as wkt_dumps + mv_grid_id = mv_district.mv_grid.id_db mv_grid_id_db = '_'.join( [str(mv_district.mv_grid.__class__.__name__), 'MV', str(mv_grid_id), str(mv_district.mv_grid.id_db)]) diff --git a/ding0/tools/tests.py b/ding0/tools/tests.py index f0468d3c..c100ae1d 100644 --- a/ding0/tools/tests.py +++ b/ding0/tools/tests.py @@ -8,17 +8,14 @@ from geoalchemy2.shape import to_shape from sqlalchemy.orm import sessionmaker -from geoalchemy2.shape import from_shape -from shapely.geometry import Point, MultiPoint, MultiLineString, LineString import logging -import pandas as pd - logger = setup_logger(loglevel=logging.CRITICAL) + class Ding0RunTest(unittest.TestCase): - ''' ''' + def setUp(self): print('\n') diff --git a/ding0_system_dependencies.sh b/ding0_system_dependencies.sh index 719ca7ff..16168b95 100755 --- a/ding0_system_dependencies.sh +++ b/ding0_system_dependencies.sh @@ -12,8 +12,8 @@ apt-get install -y gcc apt-get install -y g++ apt-get install -y python3-tk -# addionatly dependencies, maybe required on Solydxk 8 -# Only tested with debian stable with didn't required packages listed below +# additional dependencies, maybe required on Solydxk 8 +# Only tested with debian stable with required packages listed below # apt-get install -y libfreetype6-dev # apt-get install -y pkg-config diff --git a/doc/api/ding0.config.rst b/doc/api/ding0.config.rst index 5b3d6fdd..2dd0d7a0 100644 --- a/doc/api/ding0.config.rst +++ b/doc/api/ding0.config.rst @@ -1,11 +1,11 @@ -ding0\.config package -===================== +ding0.config package +==================== Submodules ---------- -ding0\.config\.config\_db\_interfaces module --------------------------------------------- +ding0.config.config\_db\_interfaces module +------------------------------------------ .. automodule:: ding0.config.config_db_interfaces :members: diff --git a/doc/api/ding0.core.network.rst b/doc/api/ding0.core.network.rst index 168444c5..179eb696 100644 --- a/doc/api/ding0.core.network.rst +++ b/doc/api/ding0.core.network.rst @@ -1,43 +1,43 @@ -ding0\.core\.network package -============================ +ding0.core.network package +========================== Submodules ---------- -ding0\.core\.network\.cable\_distributors module ------------------------------------------------- +ding0.core.network.cable\_distributors module +--------------------------------------------- .. automodule:: ding0.core.network.cable_distributors :members: :undoc-members: :show-inheritance: -ding0\.core\.network\.grids module ----------------------------------- +ding0.core.network.grids module +------------------------------- .. automodule:: ding0.core.network.grids :members: :undoc-members: :show-inheritance: -ding0\.core\.network\.loads module ----------------------------------- +ding0.core.network.loads module +------------------------------- .. automodule:: ding0.core.network.loads :members: :undoc-members: :show-inheritance: -ding0\.core\.network\.stations module -------------------------------------- +ding0.core.network.stations module +---------------------------------- .. automodule:: ding0.core.network.stations :members: :undoc-members: :show-inheritance: -ding0\.core\.network\.transformers module ------------------------------------------ +ding0.core.network.transformers module +-------------------------------------- .. automodule:: ding0.core.network.transformers :members: diff --git a/doc/api/ding0.core.powerflow.rst b/doc/api/ding0.core.powerflow.rst index bf2cd5c5..0f4ed3e0 100644 --- a/doc/api/ding0.core.powerflow.rst +++ b/doc/api/ding0.core.powerflow.rst @@ -1,5 +1,5 @@ -ding0\.core\.powerflow package -============================== +ding0.core.powerflow package +============================ Module contents --------------- diff --git a/doc/api/ding0.core.rst b/doc/api/ding0.core.rst index 7b0435ec..0f61ea90 100644 --- a/doc/api/ding0.core.rst +++ b/doc/api/ding0.core.rst @@ -1,5 +1,5 @@ -ding0\.core package -=================== +ding0.core package +================== Subpackages ----------- @@ -10,18 +10,6 @@ Subpackages ding0.core.powerflow ding0.core.structure -Submodules ----------- - -ding0\.core\.upload\_to\_zenodo module --------------------------------------- - -.. automodule:: ding0.core.upload_to_zenodo - :members: - :undoc-members: - :show-inheritance: - - Module contents --------------- diff --git a/doc/api/ding0.core.structure.rst b/doc/api/ding0.core.structure.rst index 8e6b3476..abf1150d 100644 --- a/doc/api/ding0.core.structure.rst +++ b/doc/api/ding0.core.structure.rst @@ -1,19 +1,19 @@ -ding0\.core\.structure package -============================== +ding0.core.structure package +============================ Submodules ---------- -ding0\.core\.structure\.groups module -------------------------------------- +ding0.core.structure.groups module +---------------------------------- .. automodule:: ding0.core.structure.groups :members: :undoc-members: :show-inheritance: -ding0\.core\.structure\.regions module --------------------------------------- +ding0.core.structure.regions module +----------------------------------- .. automodule:: ding0.core.structure.regions :members: diff --git a/doc/api/ding0.flexopt.rst b/doc/api/ding0.flexopt.rst index c4c91886..546576ab 100644 --- a/doc/api/ding0.flexopt.rst +++ b/doc/api/ding0.flexopt.rst @@ -1,35 +1,35 @@ -ding0\.flexopt package -====================== +ding0.flexopt package +===================== Submodules ---------- -ding0\.flexopt\.check\_tech\_constraints module ------------------------------------------------ +ding0.flexopt.check\_tech\_constraints module +--------------------------------------------- .. automodule:: ding0.flexopt.check_tech_constraints :members: :undoc-members: :show-inheritance: -ding0\.flexopt\.reinforce\_grid module --------------------------------------- +ding0.flexopt.reinforce\_grid module +------------------------------------ .. automodule:: ding0.flexopt.reinforce_grid :members: :undoc-members: :show-inheritance: -ding0\.flexopt\.reinforce\_measures module ------------------------------------------- +ding0.flexopt.reinforce\_measures module +---------------------------------------- .. automodule:: ding0.flexopt.reinforce_measures :members: :undoc-members: :show-inheritance: -ding0\.flexopt\.reinforce\_measures\_dena module ------------------------------------------------- +ding0.flexopt.reinforce\_measures\_dena module +---------------------------------------------- .. automodule:: ding0.flexopt.reinforce_measures_dena :members: diff --git a/doc/api/ding0.grid.lv_grid.rst b/doc/api/ding0.grid.lv_grid.rst index 4fdd00ca..e022be5c 100644 --- a/doc/api/ding0.grid.lv_grid.rst +++ b/doc/api/ding0.grid.lv_grid.rst @@ -1,27 +1,27 @@ -ding0\.grid\.lv\_grid package -============================= +ding0.grid.lv\_grid package +=========================== Submodules ---------- -ding0\.grid\.lv\_grid\.build\_grid module ------------------------------------------ +ding0.grid.lv\_grid.build\_grid module +-------------------------------------- .. automodule:: ding0.grid.lv_grid.build_grid :members: :undoc-members: :show-inheritance: -ding0\.grid\.lv\_grid\.check module ------------------------------------ +ding0.grid.lv\_grid.check module +-------------------------------- .. automodule:: ding0.grid.lv_grid.check :members: :undoc-members: :show-inheritance: -ding0\.grid\.lv\_grid\.lv\_connect module ------------------------------------------ +ding0.grid.lv\_grid.lv\_connect module +-------------------------------------- .. automodule:: ding0.grid.lv_grid.lv_connect :members: diff --git a/doc/api/ding0.grid.mv_grid.models.rst b/doc/api/ding0.grid.mv_grid.models.rst index cd6dbc70..0ebbe40c 100644 --- a/doc/api/ding0.grid.mv_grid.models.rst +++ b/doc/api/ding0.grid.mv_grid.models.rst @@ -1,11 +1,11 @@ -ding0\.grid\.mv\_grid\.models package -===================================== +ding0.grid.mv\_grid.models package +================================== Submodules ---------- -ding0\.grid\.mv\_grid\.models\.models module --------------------------------------------- +ding0.grid.mv\_grid.models.models module +---------------------------------------- .. automodule:: ding0.grid.mv_grid.models.models :members: diff --git a/doc/api/ding0.grid.mv_grid.rst b/doc/api/ding0.grid.mv_grid.rst index 465bbb86..4923f183 100644 --- a/doc/api/ding0.grid.mv_grid.rst +++ b/doc/api/ding0.grid.mv_grid.rst @@ -1,5 +1,5 @@ -ding0\.grid\.mv\_grid package -============================= +ding0.grid.mv\_grid package +=========================== Subpackages ----------- @@ -14,24 +14,24 @@ Subpackages Submodules ---------- -ding0\.grid\.mv\_grid\.mv\_connect module ------------------------------------------ +ding0.grid.mv\_grid.mv\_connect module +-------------------------------------- .. automodule:: ding0.grid.mv_grid.mv_connect :members: :undoc-members: :show-inheritance: -ding0\.grid\.mv\_grid\.mv\_routing module ------------------------------------------ +ding0.grid.mv\_grid.mv\_routing module +-------------------------------------- .. automodule:: ding0.grid.mv_grid.mv_routing :members: :undoc-members: :show-inheritance: -ding0\.grid\.mv\_grid\.tools module ------------------------------------ +ding0.grid.mv\_grid.tools module +-------------------------------- .. automodule:: ding0.grid.mv_grid.tools :members: diff --git a/doc/api/ding0.grid.mv_grid.solvers.rst b/doc/api/ding0.grid.mv_grid.solvers.rst index 2e4a66c3..53ffc52f 100644 --- a/doc/api/ding0.grid.mv_grid.solvers.rst +++ b/doc/api/ding0.grid.mv_grid.solvers.rst @@ -1,27 +1,27 @@ -ding0\.grid\.mv\_grid\.solvers package -====================================== +ding0.grid.mv\_grid.solvers package +=================================== Submodules ---------- -ding0\.grid\.mv\_grid\.solvers\.base module -------------------------------------------- +ding0.grid.mv\_grid.solvers.base module +--------------------------------------- .. automodule:: ding0.grid.mv_grid.solvers.base :members: :undoc-members: :show-inheritance: -ding0\.grid\.mv\_grid\.solvers\.local\_search module ----------------------------------------------------- +ding0.grid.mv\_grid.solvers.local\_search module +------------------------------------------------ .. automodule:: ding0.grid.mv_grid.solvers.local_search :members: :undoc-members: :show-inheritance: -ding0\.grid\.mv\_grid\.solvers\.savings module ----------------------------------------------- +ding0.grid.mv\_grid.solvers.savings module +------------------------------------------ .. automodule:: ding0.grid.mv_grid.solvers.savings :members: diff --git a/doc/api/ding0.grid.mv_grid.tests.rst b/doc/api/ding0.grid.mv_grid.tests.rst index 9d8764c3..5396dce5 100644 --- a/doc/api/ding0.grid.mv_grid.tests.rst +++ b/doc/api/ding0.grid.mv_grid.tests.rst @@ -1,11 +1,11 @@ -ding0\.grid\.mv\_grid\.tests package -==================================== +ding0.grid.mv\_grid.tests package +================================= Submodules ---------- -ding0\.grid\.mv\_grid\.tests\.run\_test\_case module ----------------------------------------------------- +ding0.grid.mv\_grid.tests.run\_test\_case module +------------------------------------------------ .. automodule:: ding0.grid.mv_grid.tests.run_test_case :members: diff --git a/doc/api/ding0.grid.mv_grid.util.rst b/doc/api/ding0.grid.mv_grid.util.rst index 0cc2de73..fa7f6c0c 100644 --- a/doc/api/ding0.grid.mv_grid.util.rst +++ b/doc/api/ding0.grid.mv_grid.util.rst @@ -1,19 +1,19 @@ -ding0\.grid\.mv\_grid\.util package -=================================== +ding0.grid.mv\_grid.util package +================================ Submodules ---------- -ding0\.grid\.mv\_grid\.util\.data\_input module ------------------------------------------------ +ding0.grid.mv\_grid.util.data\_input module +------------------------------------------- .. automodule:: ding0.grid.mv_grid.util.data_input :members: :undoc-members: :show-inheritance: -ding0\.grid\.mv\_grid\.util\.util module ----------------------------------------- +ding0.grid.mv\_grid.util.util module +------------------------------------ .. automodule:: ding0.grid.mv_grid.util.util :members: diff --git a/doc/api/ding0.grid.rst b/doc/api/ding0.grid.rst index b9e16a34..e6697262 100644 --- a/doc/api/ding0.grid.rst +++ b/doc/api/ding0.grid.rst @@ -1,5 +1,5 @@ -ding0\.grid package -=================== +ding0.grid package +================== Subpackages ----------- @@ -12,8 +12,8 @@ Subpackages Submodules ---------- -ding0\.grid\.tools module -------------------------- +ding0.grid.tools module +----------------------- .. automodule:: ding0.grid.tools :members: diff --git a/doc/api/ding0.tools.rst b/doc/api/ding0.tools.rst index f2c9b6c9..355430f2 100644 --- a/doc/api/ding0.tools.rst +++ b/doc/api/ding0.tools.rst @@ -1,91 +1,99 @@ -ding0\.tools package -==================== +ding0.tools package +=================== Submodules ---------- -ding0\.tools\.animation module ------------------------------- +ding0.tools.animation module +---------------------------- .. automodule:: ding0.tools.animation :members: :undoc-members: :show-inheritance: -ding0\.tools\.config module ---------------------------- +ding0.tools.config module +------------------------- .. automodule:: ding0.tools.config :members: :undoc-members: :show-inheritance: -ding0\.tools\.debug module --------------------------- +ding0.tools.debug module +------------------------ .. automodule:: ding0.tools.debug :members: :undoc-members: :show-inheritance: -ding0\.tools\.geo module ------------------------- +ding0.tools.geo module +---------------------- .. automodule:: ding0.tools.geo :members: :undoc-members: :show-inheritance: -ding0\.tools\.logger module ---------------------------- +ding0.tools.logger module +------------------------- .. automodule:: ding0.tools.logger :members: :undoc-members: :show-inheritance: -ding0\.tools\.pypsa\_io module ------------------------------- +ding0.tools.plots module +------------------------ -.. automodule:: ding0.tools.pypsa_io +.. automodule:: ding0.tools.plots :members: :undoc-members: :show-inheritance: -ding0\.tools\.results module +ding0.tools.pypsa\_io module ---------------------------- -.. automodule:: ding0.tools.results +.. automodule:: ding0.tools.pypsa_io :members: :undoc-members: :show-inheritance: -ding0\.tools\.tests module +ding0.tools.results module -------------------------- +.. automodule:: ding0.tools.results + :members: + :undoc-members: + :show-inheritance: + +ding0.tools.tests module +------------------------ + .. automodule:: ding0.tools.tests :members: :undoc-members: :show-inheritance: -ding0\.tools\.tools module --------------------------- +ding0.tools.tools module +------------------------ .. automodule:: ding0.tools.tools :members: :undoc-members: :show-inheritance: -ding0\.tools\.validation module -------------------------------- +ding0.tools.validation module +----------------------------- .. automodule:: ding0.tools.validation :members: :undoc-members: :show-inheritance: -ding0\.tools\.write\_openego\_header module -------------------------------------------- +ding0.tools.write\_openego\_header module +----------------------------------------- .. automodule:: ding0.tools.write_openego_header :members: diff --git a/doc/calculation.rst b/doc/calculation.rst index 74a7ed33..9acbe0a3 100644 --- a/doc/calculation.rst +++ b/doc/calculation.rst @@ -4,8 +4,8 @@ Calculation principles Reactance ######### -We assume all cables and overhead lines as to be short lines. Thus, the capacity -is neither considered to calculate reactance of overhead lines and cables. +We assume all cables and overhead lines to be short lines. Thus, the capacity +is not considered in calculation of reactance of overhead lines and cables. .. math:: x = \omega * L diff --git a/doc/conf.py b/doc/conf.py index d89f440f..c66e81da 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -37,6 +37,7 @@ # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('../')) +sys.path.insert(0, os.path.abspath('../')) # -- General configuration ------------------------------------------------ diff --git a/doc/development.rst b/doc/development.rst index 69aa337a..f8fe3710 100644 --- a/doc/development.rst +++ b/doc/development.rst @@ -1,7 +1,7 @@ Notes to developers ~~~~~~~~~~~~~~~~~~~ -If you're interested to contribute and join the project. Feel free to submit +If you're interested to contribute and join the project, feel free to submit PR, contact us, or just create an issue if something seems odd. diff --git a/doc/getting_started.rst b/doc/getting_started.rst index a174c195..515ade3d 100644 --- a/doc/getting_started.rst +++ b/doc/getting_started.rst @@ -1,13 +1,6 @@ Getting started ~~~~~~~~~~~~~~~ -.. warning:: - Note, Ding0 relies on data provided by the - `OEDB `_. Currently, only - members of the openego project team have access to this database. Public - access (SQL queries wrapped by HTML) to the `OEDB` will be provided soon - - .. _installation: Installation @@ -16,11 +9,9 @@ Installation .. note:: Installation is only tested on (debian like) linux OS. -Ding0 is provided though PyPi package management and, thus, installable from +Ding0 is provided through PyPi package management and, thus, installable from sources of pip3. -The package relies on a bunch of dependencies. These are defined by package -meta data of Ding0 and installed via during installation of Ding0. Nevertheless, -you may need to have some specific package system packages installed for a +You may need to additionally install some specific system packages for a successful installation of Ding0 and its dependencies. The script `ding0_system_dependencies.sh` installs required system package @@ -35,8 +26,8 @@ dependencies. sudo ./ding0_system_dependencies.sh -We recommend install Ding0 (and in general third-party) python packages in a -virtual enviroment, encapsulated from system python distribution. +We recommend installing Ding0 (and in general third-party) python packages in a +virtual environment, encapsulated from the system python distribution. This is optional. If you want to follow our suggestion, install the tool `virtualenv `_ by @@ -44,8 +35,8 @@ This is optional. If you want to follow our suggestion, install the tool sudo apt-get install virtualenv # since Ubuntu 16.04 -Afterwards `virtualenv` allows to create multiple parallel python distributions. -Since Ding0 relies on Python 3, we specify this to virtualenv creation. +Afterwards `virtualenv` allows you to create multiple parallel python distributions. +Since Ding0 relies on Python 3, we specify this in the virtualenv creation. Create a new one for Ding0 by .. code-block:: bash @@ -60,8 +51,6 @@ Jump into (aka. activate) this python distribution by # Adjust path to your specific needs source ~/.virtualenvs/ding0/bin/activate -Now, your shell executed python command by this specific python distribution. - From that, the latest release of Ding0 is installed by .. code-block:: python @@ -70,12 +59,39 @@ From that, the latest release of Ding0 is installed by Pip allows to install a developer version of a package that uses currently -checked code of the repository. A developer mode installation is achieved by +checked out code. A developer mode installation is achieved by .. code-block:: python - pip3 install -e ding0 + pip3 install -e path/to/cloned/ding0/repository +Setup database connection +========================== + +Ding0 relies on data provided in the `OpenEnergy DataBase (oedb) `_. +In order to use ding0 you therefore need an account on the +`OpenEnergy Platform (OEP) `_. You can create a new account +`here `_. + +The package `ego.io `_ gives you a python SQL-Alchemy representations of +the oedb and access to it by using the +`oedialect `_, an SQL-Alchemy dialect used by the +OEP. Your API +access / login data will be saved in the folder ``.egoio`` in the file +``config.ini``. The ``config.ini`` is automatically created from user input when it does not exist. It +holds the following information: + +.. code-block:: bash + + [oedb] + dialect = oedialect + username = + database = oedb + host = openenergy-platform.org + port = 80 + password = + + Use Ding0 ========= diff --git a/doc/images/mvgd_plot_example1.png b/doc/images/mvgd_plot_example1.png new file mode 100644 index 00000000..377724f2 Binary files /dev/null and b/doc/images/mvgd_plot_example1.png differ diff --git a/doc/index.rst b/doc/index.rst index 1fc3c392..13bb8b86 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -3,20 +3,14 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -Welcome to ding0's documentation! -================================= - - .. figure:: images/DING0_Logo_300px.png :align: right - :scale: 80% - -DIstribution Network GeneratOr -- A tool to generate synthetic medium and low voltage power distribution grids based on open (or at least accessible) data. - -.. warning:: Note, currently the data source Ding0 relies on - the Open Energy Database - has no public accessible API, yet. Thus, currently you won't be able to run Ding0 without modifications. - + :scale: 70% +Welcome to ding0's documentation! +================================= +DIstribution Network GeneratOr -- A tool to generate synthetic medium and low voltage power distribution grids based on open (or at least accessible) data. .. toctree:: :maxdepth: 7 diff --git a/doc/usage_details.rst b/doc/usage_details.rst index b8432462..7d7e697e 100644 --- a/doc/usage_details.rst +++ b/doc/usage_details.rst @@ -10,18 +10,20 @@ We provide two examples of how to use Ding0 along with two example for analysis of resulting data. The :download:`first example <../ding0/examples/example_single_grid_district.py>` shows how Ding0 is applied to a single medium-voltage grid district. Grid topology for the -medium- and low-voltage grid level is generated an export to the *OEDB* and -save to file (.pkl). +medium- and low-voltage grid level is generated and saved to a file (.pkl). The :download:`analysis script <../ding0/examples/example_analyze_single_grid_district.py>` -takes data generated the first example and produces exemplary output: key +takes data generated in the first example and produces exemplary key figures and plots. -The second example shows how to generate a larger number of grid topology data +The :download:`second example <../ding0/examples/example_multiple_grid_districts.py>` shows +how to generate a larger number of grid topology data sets. As the current data source sometimes produces unuseful data or leads to program -execution interruption, these are excluded from grid topology generation. This +execution interruptions, grids that cannot be created are excluded from grid topology +generation. This is enable by setting :code:`failsafe=` to `True`. -The according analysis script provides exemplary plots for data of multiple grid +The according :download:`analysis script <../ding0/examples/example_analyze_multiple_grid_districts.py>` +provides exemplary plots for data of multiple grid districts. @@ -31,35 +33,55 @@ High-level functions Run ding0 --------- -Check out :meth:`~core.Network.run_ding0()` as high-level function which is also used the +Check out :meth:`~core.Network.run_ding0()` as high-level function which is also used in the :download:`example <../ding0/examples/example_single_grid_district.py>`. For larger calculation (parallelization) ---------------------------------------- -To generate data for a larger area consider to parallelize execution of Ding0 -using :func:`~.examples.example_multiple_grid_districts.run_multiple_grid_districts`. +To generate data for a larger area consider to parallelize execution of Ding0 +as done in the :download:`parallelization example <../ding0/examples/example_parallel_multiple_grid_districts.py>`. Analysis of grid data ===================== +Plot results +------------ + +The :func:`~.tools.plots.plot_mv_topology` allows plots of the MV grid including grid topology +with line loadings and node voltages. You can simply fire it using an MVGrid instance or pass argument +:code:`export_figures=True` to :meth:`~core.Network.run_ding0()` to export some key plots. +The plotting allows to draw a background map. For this function, the package `contextily` is needed which +is not included in the standard ding0 installation. If you want to use this feature, you can simply install it by + +.. code-block:: python + + pip3 install contextily + +See plotting function for a detailed description of possible modes and parameters. + +Example plot: + +.. figure:: images/mvgd_plot_example1.png + Export key figures ------------------ We provide a set of functions to export key figures of the generated data. -The following assumes a Ding0 network is available generated like +The following assumes a Ding0 network is generated as follows: .. code-block:: python from egoio.tools import db from ding0.core import NetworkDing0 - conn = db.connection(section='oedb') + engine = db.connection(section='oedb') + session = sessionmaker(bind=engine)() network = NetworkDing0(name='network') network.run_ding0( - conn=conn, + session=session, mv_grid_districts_no=[3040]) @@ -160,7 +182,7 @@ Lines "run_id", "int", "time and date of table generation", "yyyyMMddhhmmss" LV-Branchtees ------------ +-------------- .. csv-table:: lv_branchtee.csv :header: "Field","type", "Description", "Unit" :widths: 15, 10, 10, 30 @@ -171,7 +193,7 @@ LV-Branchtees "run_id", "int", "time and date of table generation", "yyyyMMddhhmmss" LV-Generators ------------ +------------- .. csv-table:: lv_generator.csv :header: "Field","type", "Description", "Unit" :widths: 15, 10, 10, 30 @@ -222,7 +244,7 @@ LV-Stations "run_id", "int", "time and date of table generation", "yyyyMMddhhmmss" LV-Transformers ------------ +---------------- .. csv-table:: lv_transformer.csv :header: "Field","type", "Description", "Unit" :widths: 15, 10, 10, 30 @@ -249,7 +271,7 @@ LV-Grids "run_id", "int", "time and date of table generation", "yyyyMMddhhmmss" MV-Branchtees ------------ +-------------- .. csv-table:: mv_branchtee.csv :header: "Field","type", "Description", "Unit" :widths: 15, 10, 10, 30 @@ -260,7 +282,7 @@ MV-Branchtees "run_id", "int", "time and date of table generation", "yyyyMMddhhmmss" MV-Generators ------------ +-------------- .. csv-table:: mv_generator.csv :header: "Field","type", "Description", "Unit" :widths: 15, 10, 10, 30 @@ -312,7 +334,7 @@ MV-Stations "run_id", "int", "time and date of table generation", "yyyyMMddhhmmss" MV-Transformers ------------ +---------------- .. csv-table:: lv_transformer.csv :header: "Field","type", "Description", "Unit" :widths: 15, 10, 10, 30 diff --git a/doc/welcome.rst b/doc/welcome.rst index c8df85c9..7a1329a7 100644 --- a/doc/welcome.rst +++ b/doc/welcome.rst @@ -2,11 +2,6 @@ What is ding0 about? #################### -**WARNING** Note, currently the data source Ding0 relies on - the -[Open Energy Database](http://oep.iks.cs.ovgu.de/dataedit/) - has no public -accessible API, yet. Thus, currently you won't be able to run Ding0 without -modifications. - DIstribution Network GeneratOr (Ding0) is a tool to generate synthetic medium and low voltage power distribution grids based on open (or at least accessible) data. diff --git a/doc/whatsnew.rst b/doc/whatsnew.rst index 5b650495..3a1eb2c2 100644 --- a/doc/whatsnew.rst +++ b/doc/whatsnew.rst @@ -8,6 +8,9 @@ See what's new as per release! :local: :backlinks: top +.. include:: whatsnew/v0-1-11.rst +.. include:: whatsnew/v0-1-10.rst +.. include:: whatsnew/v0-1-9.rst .. include:: whatsnew/v0-1-8.rst .. include:: whatsnew/v0-1-7.rst .. include:: whatsnew/v0-1-6.rst diff --git a/doc/whatsnew/v0-1-10.rst b/doc/whatsnew/v0-1-10.rst new file mode 100644 index 00000000..8899a824 --- /dev/null +++ b/doc/whatsnew/v0-1-10.rst @@ -0,0 +1,14 @@ +Release v0.1.10 November 5, 2018 +++++++++++++++++++++++++++++++++ + +This release introduces new plotting functionalities. + +Changes +------- + +* New plotting function :func:`~.tools.plots.plot_mv_topology` allows plots of the MV grid including grid topology + with line loadings and node voltages. You can simply fire it using an MVGrid instance or pass argument + :code:`export_figures=True` to :meth:`~core.Network.run_ding0()` to export some key figures. +* Find a new Jupyter notebook example `here `_ (sorry, currently only in German). +* Fix animation feature in :meth:`~.core.NetworkDing0.mv_routing()` to allow image export of routing process. +* Minor bugfixes diff --git a/doc/whatsnew/v0-1-11.rst b/doc/whatsnew/v0-1-11.rst new file mode 100644 index 00000000..fdd5277b --- /dev/null +++ b/doc/whatsnew/v0-1-11.rst @@ -0,0 +1,2 @@ +Release v0.1.11 month day, year ++++++++++++++++++++++++++++++++ diff --git a/doc/whatsnew/v0-1-8.rst b/doc/whatsnew/v0-1-8.rst index ad860d55..0924640d 100644 --- a/doc/whatsnew/v0-1-8.rst +++ b/doc/whatsnew/v0-1-8.rst @@ -1,8 +1,7 @@ -Release v0.1.8 ??? ??, 2018 -++++++++++++++++++++++++++++ +Release v0.1.8 September 5, 2018 ++++++++++++++++++++++++++++++++++++ - +A release to update software dependencies. -Changes -------- +* Data processing and ego.io versions are updated to 0.4.5 diff --git a/doc/whatsnew/v0-1-9.rst b/doc/whatsnew/v0-1-9.rst new file mode 100644 index 00000000..dbf5ca7a --- /dev/null +++ b/doc/whatsnew/v0-1-9.rst @@ -0,0 +1,4 @@ +Release v0.1.9 October 22, 2018 +++++++++++++++++++++++++++++++++ + +This release fixes the API documentation at readthedocs and the examples. diff --git a/rtd_requirements.txt b/rtd_requirements.txt index 28d6929a..c528e74c 100644 --- a/rtd_requirements.txt +++ b/rtd_requirements.txt @@ -1,12 +1,19 @@ sphinx_rtd_theme -numpy -psycopg2 -matplotlib -networkx -geoalchemy2 -shapely -geopy -pyproj -egoio -pandas +networkx >= 1.11, <=1.11 +geopy >=1.11.0, <=1.11.0 +pandas >=0.20.3, <=0.20.3 +pyproj >=1.9.5.1, <=1.9.5.1 +sqlalchemy >= 1.0.11, <= 1.2.0 +geoalchemy2 >= 0.2.6, <= 0.4.1 +matplotlib >=1.5.3, <=1.5.3 +egoio >=0.4.5 +pypsa >=0.11.0, <=0.11.0 +seaborn +unittest2 +oedialect mock + + + + + diff --git a/setup.py b/setup.py index f59ec94a..b349e527 100644 --- a/setup.py +++ b/setup.py @@ -18,26 +18,28 @@ setup(name='ding0', - version='v0.1.8dev', + version='v0.1.11dev', author='Reiner Lemoine Institut, openego development group', author_email='jonathan.amme@rl-institut.de', description='DIstribution Network GeneratOr', url='https://github.com/openego/ding0', license='GNU GPLv3', packages=find_packages(), - install_requires=['networkx >= 1.11, <= 1.11', + install_requires=['networkx >= 1.11, < 2.0', 'geopy >= 1.11.0, <= 1.11.0', 'pandas >= 0.20.3, <= 0.20.3', 'pyproj >= 1.9.5.1, <= 1.9.5.1', 'sqlalchemy >= 1.0.11, <= 1.2.0', 'geoalchemy2 >= 0.2.6, <= 0.4.1', - 'matplotlib >= 1.5.3, <= 1.5.3', - 'egoio>=0.4.1', + 'matplotlib >= 1.5.3, <= 2.0.2', + 'egoio >= 0.4.5', 'shapely >= 1.5.12, <= 1.6.3', 'pypsa >= 0.11.0, <= 0.11.0', 'seaborn', 'unittest2', - 'oedialect' + 'oedialect', + 'geopandas', + 'descartes' ], package_data={ 'ding0': [