Source code for R2PD.nearestnodes

"""
This module provides classes for facilitating the transfer of data between
the external and internal store as well as processing the data using a queue.
"""
import numpy as np
import pandas as pds
from scipy.spatial import cKDTree
from .powerdata import NodeCollection


[docs]def nearest_power_nodes(node_collection, resource_meta): """ Fill requested power nodes in node_collection with resource sites in resource_meta Parameters ---------- node_collection : 'pandas.DataFrame'|'GeneratorNodeCollection' DataFrame of requested nodes: [node_id(index), latitude, longitude, capacity] or NodeCollection instance resource_meta : 'pandas.DataFrame' DataFrame with resource node meta-data: [site_id(index), latitude, longitude, capacity] Returns --------- nodes : 'pandas.DataFrame' Requested nodes with site_ids and fractions of resource for each node """ if isinstance(node_collection, NodeCollection): node_data = node_collection.node_data else: node_data = node_collection # Create and populate DataFrame from requested list of nodes nodes = pds.DataFrame(columns=['latitude', 'longitude', 'capacity', 'site_id', 'site_fracs', 'r_cap'], index=node_data.index) nodes.loc[:, ['latitude', 'longitude', 'capacity']] = node_data.values nodes.loc[:, 'r_cap'] = node_data['capacity (MW)'] r_nodes = resource_meta[['longitude', 'latitude', 'capacity']].copy() # Add placeholder for remaining capacity available at resource node r_nodes['r_cap'] = r_nodes['capacity'] while True: # Extract resource nodes w/ remaining capacity r_left = r_nodes[r_nodes['r_cap'] > 0] r_index = r_left.index lat_lon = r_left.as_matrix(['latitude', 'longitude']) # Create cKDTree of [lat, lon] for resource nodes # w/ available capacity tree = cKDTree(lat_lon) # Extract nodes that still have capacity to be filled nodes_left = nodes[nodes['r_cap'] > 0] n_index = nodes_left.index node_lat_lon = nodes_left.as_matrix(['latitude', 'longitude']) # Find first nearest resource node to each requested node dist, pos = tree.query(node_lat_lon, k=1) node_pairs = pds.DataFrame({'pos': pos, 'dist': dist}) # Find the nearest pair of resource nodes and requested nodes node_pairs = node_pairs.groupby('pos')['dist'].idxmin() # Apply resource node to nearest requested node for i, n in node_pairs.iteritems(): r_i = r_index[i] n_i = n_index[n] resource = r_nodes.loc[r_i].copy() file_id = resource.name cap = resource['r_cap'] node = nodes.loc[n_i].copy() # Determine fract of resource node to apply to requested node if node['r_cap'] > cap: frac = cap / resource['capacity'] resource['r_cap'] = 0 node['r_cap'] += -1 * cap else: frac = node['r_cap'] / resource['capacity'] resource['r_cap'] += -1 * node['r_cap'] node['r_cap'] = 0 if np.all(pds.isnull(node['site_id'])): node['site_id'] = [file_id] node['site_fracs'] = [frac] else: node['site_id'] += [file_id] node['site_fracs'] += [frac] r_nodes.loc[r_i] = resource nodes.loc[n_i] = node # Continue nearest neighbor search and resource distribution # until capacity is filled for all requested nodes if np.sum(nodes['r_cap'] > 0) == 0: break return nodes[['latitude', 'longitude', 'capacity', 'site_id', 'site_fracs']]
[docs]def nearest_met_nodes(node_collection, resource_meta): """ Fill requested weather nodes in node_collection with resource sites in resource_meta Parameters ---------- node_collection : 'pandas.DataFrame'|'WeatherNodeCollection' DataFrame of requested nodes: [node_id(index), latitude, longitude] or NodeCollection instance resource_meta : 'pandas.DataFrame' DataFrame with resource node meta-data: [site_id(index), latitude, longitude] Returns --------- nodes : 'pandas.DataFrame' Requested nodes with site_id of resource for each node """ if isinstance(node_collection, NodeCollection): node_data = node_collection.node_data else: node_data = node_collection # Create and populate DataFrame from requested list of nodes nodes = pds.DataFrame(columns=['latitude', 'longitude', 'site_id'], index=node_data.index) nodes.loc[:, ['latitude', 'longitude']] = node_data.values # Extract resource nodes lat, lon lat_lon = resource_meta.as_matrix(['latitude', 'longitude']) # Create cKDTree of [lat, lon] for resource nodes w/ available capacity tree = cKDTree(lat_lon) # Extract requested lat, lon node_lat_lon = nodes.as_matrix(['latitude', 'longitude']) # Find first nearest resource node to each requested node _, site_id = tree.query(node_lat_lon, k=1) nodes['site_id'] = site_id return nodes[['latitude', 'longitude', 'site_id']]