API Reference¶
Submodules¶
openelec.clustering module¶
clusters module for openelec
Provides functions to read in a raster population dataset and convert to discrete vector polgons, each with a set population value. Additionally calculate each polygon’s distance from a provided grid infrastructure vector.
Functions:
 prepare_clusters
 clip_rasters
 create_clusters
 filter_merge_clusters
 add_raster_layer
 add_vector_layer
 fix_column
 save_clusters

openelec.clustering.
add_raster_layer
(clusters, raster, operation, col_name, affine=None, crs=None)[source]¶ The filter_merge_clusters() process loses the underlying raster values. So we need to use rasterstats.zonal_stats() to get it back.
Parameters:  clusters (geopandas.GeoDataFrame) – The processed clusters.
 raster (str, pathlib.Path or numpy.ndarray) – Either a path to the raster, or numpy.ndarray with the data.
 operation (str) – The operation to perform when extracting the raster data. Either ‘sum’, ‘max’, or ‘mean’
 col_name (str) – Name of the column to add.
 affine (affine.Affine(), optional) – If a numpy ndarray is passed above, the affine is also needed.
 crs (proj.crs, optional) – Override raster’s reported crs
Returns: clusters – The processed clusters with new column.
Return type: geopandas.GeoDataFrame

openelec.clustering.
add_vector_layer
(clusters, vector, operation, col_name, shape, affine, raster_crs)[source]¶ Use a vector containing grid infrastructure to determine each cluster’s distance from the grid.
Parameters:  clusters (geopandas.GeoDataFrame) – The processed clusters.
 vector (str, pathlib.Path or geopandas.GeoDataFrame) – Path to or already imported grid dataframe.
 operation (str) – Operation to perform in extracting vector data. Currently only ‘distance’ supported.
 shape (tuple) – Tuple of two integers representing the shape of the data for rasterizing grid. Sould match the clipped raster.
 affine (affine.Affine()) – As above, should match the clipped raster.
Returns: clusters – The processed clusters with new column.
Return type: geopandas.GeoDataFrame

openelec.clustering.
clip_raster
(raster, boundary, boundary_layer=None)[source]¶ Clip the raster to the given administrative boundary.
Parameters:  raster (string, pathlib.Path or rasterio.io.DataSetReader) – Location of or already opened raster.
 boundary (string, pathlib.Path or geopandas.GeoDataFrame) – The poylgon by which to clip the raster.
 boundary_layer (string, optional) – For multilayer files (like GeoPackage), specify the layer to be used.
Returns:  Three elements:
 clipped: numpy.ndarray
Contents of clipped raster.
 affine: affine.Affine()
Information for mapping pixel coordinates to a coordinate system.
 crs: dict
Dict of the form {‘init’: ‘epsg:4326’} defining the coordinate reference system of the raster.
Return type: tuple

openelec.clustering.
create_clusters
(raster, affine, crs)[source]¶ Create a polygon GeoDataFrame from the given raster
Parameters:  raster (numpy.ndarray) – The raster data to use.
 affine (affine.Affine()) – Raster pixel mapping information.
 crs (dict) – Dict of the form {‘init’: ‘epsg:4326’} defining the coordinate reference system to use.
Returns: clusters – A GeoDataFrame with integer index and two columns: geometry contains the Shapely polygon representations raster_val contains the values from the raster
Return type: geopandas.GeoDataFrame

openelec.clustering.
filter_merge_clusters
(clusters, max_block_size_multi=5, min_block_pop=50, buffer_amount=150)[source]¶ The vectors created by create_clusters() are a single square for each raster pixel. This function does the follows:  Remove overly large clusters, caused by defects in the input raster.  Remove clusters with population below a certain threshold.  Buffer the remaining clusters and merge those that overlap.
Parameters:  clusters (geopandas.GeoDataFrame) – The unprocessed clusters created by create_clusters()
 max_block_size_multi (int, optional (default 5.)) – Remove clusters that are more than this many times average size.
 min_block_pop (int, optional (default 50.)) – Remove clusters with below this population.
 buffer_amount (int, optional (default 150.)) – Distance in metres by which to buffer the clusters before merging.
Returns: clusters – The processed clusters.
Return type: geopandas.GeoDataFrame

openelec.clustering.
fix_column
(clusters, col_name, factor=1, minimum=0, maximum=None, no_value=None, per_capita=False)[source]¶ A number of operations to apply to a columns values to get desired output.
Parameters:  clusters (GeoDataFrame) – The clusters object.
 col_name (str) – The column to apply the operation to.
 factor (float, optional (default 1.)) – Factor by which to multiply the column vales.
 minimum (float, optional (default 0.)) – Apply a minimum threshold to the values.
 maximum (str, optional) – Currently only supported for ‘largest’. Limits the values to double the value of the cluster with the highest population.
 no_value (str, optional) – Currently only supported for ‘median’. Replaces NaN instances with the median value.
 per_capita (boolean, optional (default False.)) – Divide values by cluster population.
Returns: clusters – The ‘fixed’ clusters.
Return type: GeoDataFrame
openelec.conv module¶
Module for loading and saving.
Functions:
 read_data
 merge_geometry
 spatialise
 geojsonify
 geometry
 properties
 overpass
 json2geojson
save_to_path

openelec.conv.
geojsonify
(gdf, property_cols=[])[source]¶ Convert GeoDataFrame to GeoJSON that can be supplied to JavaScript.
Parameters:  gdf (geopandas.GeoDataFrame) – GeoDataFrame to be converted.
 property_cols (list, optional) – List of column names from gdf to be included in ‘properties’ of each GeoJSON feature.
Returns: geoJson – A GeoJSON representatial List of column names from gdf to be included in ‘properties’ of each GeoJSON feature.
Return type: dict
Returns: geojson – A GeoJSON representation that can be parsed by standard JSON readers.
Return type: dict

openelec.conv.
geometry
(coordinates)[source]¶ Convert a GeoDataFrame geometry value into a GeoJSONfriendly form..
Parameters: coords (shapely.LineString, shapely.Polygon or shapely.MultiPolygon) – A single geometry entry from a GeoDataFrame. Returns: geom_dict – A GeoJSON geometry element of the form ‘geometry’: { ’type’: type, ‘coordinates’: coords}
Return type: dict

openelec.conv.
json2geojson
(items)[source]¶ Convert a json from OSM Overpass to a GeoJSON.
Parameters: items (json) – The JSON representation. Returns: geojson – As a GeoJSON. Return type: dict

openelec.conv.
merge_geometry
(results, geometry, columns=None)[source]¶ Merge results from modelling with an original input geometry, using the index as key for both.
Parameters:  results (list of dicts) – Output from modelling.
 geometry (GeoDataFrame) – Target geometry with amtching index.
 columns (list, optional) – List of columns to include in output. If not provided, keep all.
Returns: spatial – Results with geometry.
Return type: GeoDataFrame

openelec.conv.
overpass
(bounds)[source]¶ Get OSM Overpass results from specified bounds as GeoJSON.
Parameters: bounds (str) – String in this format: “S, W, N, E” Returns: geojson – GeoJSON results. Return type: dict

openelec.conv.
properties
(row, property_cols)[source]¶ Get the selected columns from the pandas row as a GeoJSONfriendly dict.
Parameters:  row (pandas.Series) – A single row from a GeoDataFrame.
 property_cols (list) – List of column names to be added.
Returns: prop_dict – A GeoJSON element of the form properties: {
’column1’: property1, ‘column2’: property2, …
}
Return type: dict

openelec.conv.
read_data
(data)[source]¶ Read targets (clusters, buildings) data from a file or other source.
Parameters: data (Path, str, dict) – Path to a Fionareadable file, or GeoJSONlike dict. Can also be a string representation of a GeoJSON. Returns: targets – The data filtered and processed. Return type: GeoDataFrame

openelec.conv.
save_to_path
(path, **features)[source]¶ Save the provided features in the directory specified. File names are taken from the keywords.

openelec.conv.
spatialise
(results, type='line')[source]¶ Convert results to a GeoDataFrame using values to create a geometry.
Parameters:  results (list of dicts) – An output from the modelling.
 type (str, optional (default 'line'.)) – What type of geometry it is. (Currently only implemented for ‘line’).
Returns: spatial – Results with geometry.
Return type: GeoDataFrame
openelec.local module¶
local module for openelec Tool designed to take a small village and estimate the optimum connections, based on a PV installation location and economic data.
Includes LocalModel class and calculate_profit function.

class
openelec.local.
LocalModel
(data)[source]¶ Bases:
openelec.model.Model
Inherits from Model. Goal is to fully merge NationalModel and LocalModel, as they share lots of functionality.
This class provides most of the functionality for using openelec at the local level.

baseline
(min_area=20)[source]¶ Filter on population and assign whether currently electrified.
Parameters:  targets (GeoDataFrame) – Loaded targets.
 min_area (int, optional (default 20.)) – Minimum target area in m2.

connect_targets
(origin=None)[source]¶ Create an MST connecting the target features.
Parameters: origin (tuple of two floats) – Tuple of format (latitude, longitude) of origin point (such as a generator) if desired. If not supplied, the largest target building is used instead,

model
(target_coverage=None)[source]¶ Run the model with the given economic parameters and return the processed network and nodes.
cut arcs one by one, see which cut is the most profitable, and then take that network and repeat the process annual income should be specified by the nodes
Then we start with the complete network, and try ‘deleting’ each arc. Whichever deletion is the most profitable, we make it permanent and repeat the process with the new configuration. This continues until there are no more increases in profitability to be had.
Parameters: target_coverage (float, optional) – If provided, model will aim to achieve this level of population coverage, rather than optimising on NPV.

parameters
(demand, tariff, gen_cost, cost_wire, cost_connection, opex_ratio, years, discount_rate)[source]¶ Set up model parameters.
Parameters:  demand (int) – Demand in kWh/person/month.
 tariff (float) – Tariff to be charged in USD/kWh.
 gen_cost (int) – Generator cost in USD/kW.
 cost_wire (int) – Wire cost in USD/m.
 cost_connection (int) – Cost per household connection in USD.
 opex_ratio (float) – Annual OPEX as a percentage of CAPEX (range 0 1).
 years (int) – Project duration in years.
 discount_rate (float) – Discount rate to be used for NPV calculation (range 01).


openelec.local.
calculate_profit
(network, nodes, index, disabled_arc_index, cost, income_per_month, cost_wire, cost_connection, num_people_per_m2, demand, tariff)[source]¶ Here we recurse through the network and calculate profit, starting with all arcs that connect to the index node, and get the endnodes for those arcs calculate profit on those nodes, and then recurse! disabled_arc should be treated as if disabled
Parameters:  nodes (network,) – Current state of both.
 index (int) – Current index.
 disabled_arc_index (int) – Arc that is currently disabled.
 etc (cost) –
openelec.model module¶
model module for openelec.
Provides common functionality for LocalModel and NationalModel.

class
openelec.model.
Model
(data)[source]¶ Bases:
object
Base class for NationalModel and LocalModel.

results_as_geojson
(network_columns=None, targets_columns=None)[source]¶ Convert all model output to GeoJSON.

openelec.national module¶
national module for openelec
Includes NationalModel class and find_best function.

class
openelec.national.
NationalModel
(data)[source]¶ Bases:
openelec.model.Model
Inherits from Model. Goal is to fully merge NationalModel and LocalModel, as they share lots of functionality.
This class provides most of the functionality for using openelec at the national level.

demand_levels
()[source]¶ Calculate demand level in kWh/p/month, either from MTF or using a simple formula.
# TODO Add productive use, schools

dynamic
(steps=4, years_per_step=5)[source]¶ Run the model dynamically, splitting into a specified number of steps with a number of years between each one. Creates an iterator that yields results after each step.
Parameters:  steps (int, optional (default 4.)) – Number of steps to use.
 years_per_step (int, optional (default 5.)) – Number of years per step.
 demand_factor (int, optional (default None.)) – If provided, uses this factor in demand calculations. If None, uses the MTF levels instead.
Yields:  targets_out, networks_out (GeoDataFrames) – The next step of targets and network.
 results (dict) – The next step of results.

dynamic_combine
()[source]¶ Run the dyamic model and combine the results into a single set of GeoDataFrames and a results dict.
Returns:  targets, network (GeoDataFrames) – Combined targets and network.
 results (dict) – Dict of results keyed on step number.

initial_access
()[source]¶ Calibrate initial electricity access levels (per electrified cluster) to match national statistics.

model
()[source]¶ Run the national planning model with the provided parameters.
Then we’re ready to calculate the optimum grid extension. This is done by expanding out from each already connected node, finding the optimum connection of nearby nodes. This is then compared to the offgrid cost and if better, these nodes are marked as connected. Then the loop continues until no new connections are found.

parameters
(grid_mv_cost=50, grid_lv_cost=3, grid_trans_cost=3500, grid_conn_cost=200, grid_opex_ratio=0.02, mg_gen_cost=4000, mg_lv_cost=2, mg_conn_cost=100, mg_opex_ratio=0.02, actual_pop=10000000.0, pop_growth=0.01, access_tot=0.3, access_urban=0.66, grid_dist_connected=2, minimum_pop=100, gdp_growth=0.02, discount_rate=0.08, people_per_hh=5, target_access=1.0, demand_factor=5, use_mtf=False)[source]¶ Set up model parameters


openelec.national.
find_best
(network, nodes, index, prev_arc, b_demand=0, b_length=1e09, b_nodes=[], b_arcs=[], c_demand=0, c_length=1e09, c_nodes=[], c_arcs=[])[source]¶ This function recurses the network, bringing current c_ values with it. These aren’t returned, so are left untouched sidebranch explorations. The b_ values are returned, and updated when a better configuration found. Thus these will remember the best solution including all side meanders.
openelec.network module¶
network module of openelec. Provides functionality for creating MST and network from input points.
Functions:
 create_network
 spanning_tree
 add_origin
 remove_existing
 direct_network

openelec.network.
add_origin
(points, origin)[source]¶ If origin not specified, the model defaults to using index 0 as the ‘main’ point. Thus targets should already have been sorted by population/area with largest first.

openelec.network.
create_network
(targets, columns, existing_network=False, directed=False, origin=None)[source]¶ We then take all the clusters and calculate the optimum network that connects them all together. We use this to create a graph network of and nodes and arcs representing the clusters and connections.
Parameters:  clusters (GeoDataFrame) – The prepared clusters.
 columns (list) – List of columns to include.
 existing_network (boolean, optional (default False.)) – Whether there is an existing network. In this case, redundant lines in new network are removed.
 directed (boolean, optional (default False.)) – Whether the output network should be directed.
 origin (tuple, optional) – Location of an origin (e.g. generator) for the network. Should be of the form (latitude, longitude) in WGS84 coordinates. If not provided, the first element is set as origin.
Returns:  network (list of dicts) – The network arcs.
 nodes (list of dicts) – The network nodes.

openelec.network.
direct_network
(network, nodes, index, prev)[source]¶ Recursive function to direct the network from the PV point outwards We need to calculate the directionality of the network, starting from the PV location and reaching outwards to the furthest branches.
We use this to calculate, for each node, it’s marginal and total distance from the PV location. At the same time, we tell each arc which node is ‘upstream’ of it, and which is ‘downstream’. We also tell each node which arcs (at least one, up to three or four?) it is connected to.
Parameters:  network (list of dicts) – Containing the arc representations.
 nodes (list of dicts) – Containing the building node representations.
 index (int) – Current node index that we’re looking at.
Returns:  network (list of lists) – Nearby network directed for current node.
 nodes (list of list) – The nodes object.

openelec.network.
remove_existing
(network, nodes)[source]¶ Set which arcs don’t already exist (and the remainder do!)

openelec.network.
spanning_tree
(X, approximate=False)[source]¶ Function to calculate the Minimum spanning tree connecting the provided points X. Modified from astroML code in mst_clustering.py
Parameters: X (array_like) – 2D array of shape (n_sample, 2) containing the x and ycoordinates of the points. Returns: x_coords, y_coords – the x and y coordinates for plotting the graph. They are of size [2, n_links], and can be visualized using plt.plot(x_coords, y_coords, 'k')
Return type: ndarrays
openelec.prioritise module¶
prioritising module for openelec
Functions:
 priority

openelec.prioritise.
priority
(clusters, pop_range=None, grid_range=None, ntl_range=None, gdp_range=None, travel_range=None)[source]¶ Calculate the priority clusters that meet the criteria, and calculate a score from 15 for each.
Parameters:  clusters (GeoDataFrame) – Village clusters object.
 min_grid_dist (int) – Minimum distance from grid in metres to consider for clusters.
 max_ntl (int) – Maximum value of NTL (night time lights) to consider. Range 0255.
Returns:  clusters (GeoDatFrame) – Processed clusters.
 summary (dict) – Summary results.
openelec.util module¶
Helper functions for models.
Functions:
 connect_houses
 stranded_arcs
 calc_coverage
 assign_coverage
 calc_lv

openelec.util.
assign_coverage
(targets, access_rate)[source]¶ Estimate level of electricity access for each target.

openelec.util.
calc_coverage
(weight, pop, conn, pop_tot, target_access, accuracy=0.01, increment=0.1, max_coverage=0.8)[source]¶ Estimate coverage levels for the given parameters.
Parameters:  pop, conn (weight,) – Each a column from targets.
 pop_tot (int) – Total population.
 target_access (float) – Target access rate.
 accuracy (float, optional (default 0.01.)) – Acceptable accuracy level.
 increment (float, optional (default 0.1.)) – How much to increment each target’s coverage level on each loop.
 max_coverage (float, optional (default 0.8.)) – Max coverage level for any target.
Returns: coverage – Array of coverage levels of same shape as weight.
Return type: numpy array

openelec.util.
calc_lv
(people, demand, people_per_hh, area)[source]¶ Calculate LV cost parameters for the given parameters. Everything is in m and m2.

openelec.util.
connect_houses
(network, nodes, index)[source]¶ Then we disconnect all the houses that are no longer served by active arcs, and prune any stranded arcs that remained on unconnected paths. now we need to tell the houses that aren’t connected, that they aren’t connected (or viceversa)
Start from base, follow connection (similar to calculate_profit) and swith node[6] to 1 wherever connected and only follow the paths of connected houses.
Module contents¶
openelec package contains the following modules:
 clustering
 model
 local
 national
 io
 network
 prioritise
 util
GPL3.0 (c) Chris arderne