def advanced_module(self, g_habitat, out, source_map, ground_map, source_id=None, component_with_points=None): solver_called = False solver_failed = False node_map = None if component_with_points != None: G = g_habitat.get_graph() G = ComputeBase.laplacian(G) node_map = g_habitat.node_map vc_map_id = '' if source_id==None else str(source_id) out.alloc_v_map(vc_map_id) if self.options.write_cur_maps: out.alloc_c_map(vc_map_id) for comp in range(1, g_habitat.num_components+1): if (component_with_points != None) and (comp != component_with_points): continue if self.options.data_type == 'raster': c_map = np.where(g_habitat.component_map == comp, 1, 0) local_source_map = np.multiply(c_map, source_map) local_ground_map = np.where(c_map, ground_map, 0) del c_map have_sources = (np.where(local_source_map, 1, 0)).sum() > 0 have_grounds = (np.where(local_ground_map, 1, 0)).sum() > 0 else: c_map = np.where(g_habitat.components == comp, 1, 0) sources = np.zeros(g_habitat.num_nodes) for idx in range(0, source_map.shape[0]): sources = np.where(g_habitat.node_map == source_map[idx,0], source_map[idx,1], sources) grounds = -9999 * np.ones(g_habitat.num_nodes) for idx in range(0, ground_map.shape[0]): grounds = np.where(g_habitat.node_map == ground_map[idx,0], ground_map[idx,1], grounds) if self.options.ground_file_is_resistances: _grounds = 1 / grounds grounds = np.where(grounds == -9999, 0, _grounds) else: grounds = np.where(grounds == -9999, 0, grounds) have_sources = (np.where(sources, 1, 0)).sum() > 0 have_grounds = (np.where(grounds, 1, 0)).sum() > 0 if not (have_sources and have_grounds): continue if component_with_points == None: (G, node_map) = g_habitat.prune_nodes_for_component(comp) G = ComputeBase.laplacian(G) if self.options.data_type == 'raster': (rows, cols) = np.where(local_source_map) values = local_source_map[rows,cols] local_sources_rc = np.c_[values,rows,cols] (rows, cols) = np.where(local_ground_map) values = local_ground_map[rows,cols] local_grounds_rc = np.c_[values,rows,cols] del rows, cols, values, local_source_map, local_ground_map numnodes = node_map.max() sources = np.zeros(numnodes) grounds = np.zeros(numnodes) num_local_sources = local_sources_rc.shape[0] num_local_grounds = local_grounds_rc.shape[0] for source in range(0, num_local_sources): src = self.grid_to_graph(local_sources_rc[source,1], local_sources_rc[source,2], node_map) # Possible to have more than one source at a node when there are polygons sources[src] += local_sources_rc[source,0] for ground in range(0, num_local_grounds): gnd = self.grid_to_graph (local_grounds_rc[ground,1], local_grounds_rc[ground,2], node_map) # Possible to have more than one ground at a node when there are polygons grounds[gnd] += local_grounds_rc[ground,0] (sources, grounds, finitegrounds) = self.resolve_conflicts(sources, grounds) solver_called = True try: voltages = self.multiple_solver(G, sources, grounds, finitegrounds) del sources, grounds except MemoryError: raise MemoryError except: voltages = -777 solver_failed = True if solver_failed==False: ##Voltage and current mapping are cumulative, since there may be independent components. if self.options.write_volt_maps or (self.options.scenario=='one-to-all'): out.accumulate_v_map(vc_map_id, voltages, node_map) if self.options.write_cur_maps: out.accumulate_c_map(vc_map_id, voltages, G, node_map, finitegrounds, None, None) if solver_failed==False and self.options.write_volt_maps: out.write_v_map(vc_map_id) if (self.options.write_cur_maps) and ((source_id == None) or ((source_id != None) and (self.options.write_cum_cur_map_only==False))): out.write_c_map(vc_map_id, node_map=node_map) if self.options.scenario=='one-to-all': if solver_failed==False: (row, col) = np.where(source_map>0) vmap = out.get_v_map(vc_map_id) voltages = vmap[row,col]/source_map[row,col] #allows for variable source strength elif self.options.scenario=='all-to-one': if solver_failed==False: voltages = 0 #return 0 voltage/resistance for all-to-one mode out.rm_v_map(vc_map_id) # Advanced mode will return voltages of the last component solved only for verification purposes. if solver_called==False: voltages = -1 return voltages, out.get_c_map(vc_map_id, True), solver_failed
def single_ground_all_pair_resistances(self, g_habitat, fp, cs, report_status): """Handles pairwise resistance/current/voltage calculations. Called once when focal points are used, called multiple times when focal regions are used. """ options = self.options last_write_time = time.time() numpoints = fp.num_points() parallelize = options.parallelize # TODO: revisit to see if restriction can be removed if options.low_memory_mode==True or self.state.point_file_contains_polygons==True: parallelize = False if (self.state.point_file_contains_polygons == True) or (options.write_cur_maps == True) or (options.write_volt_maps == True) or (options.use_included_pairs==True) or (options.data_type=='network'): use_resistance_calc_shortcut = False else: use_resistance_calc_shortcut = True # We use this when there are no focal regions. It saves time when we are also not creating maps shortcut_resistances = -1 * np.ones((numpoints, numpoints), dtype='float64') solver_failed_somewhere = [False] Compute.logger.info('Graph has ' + str(g_habitat.num_nodes) + ' nodes, ' + str(numpoints) + ' focal nodes and '+ str(g_habitat.num_components)+ ' components.') resistances = -1 * np.ones((numpoints, numpoints), dtype = 'float64') #Inf creates trouble in python 2.5 on Windows. Use -1 instead. # if use_resistance_calc_shortcut==True: # num_points_to_solve = numpoints # else: # num_points_to_solve = numpoints*(numpoints-1)/2 num_points_to_solve = 0 max_parallel = 0 for c in range(1, int(g_habitat.num_components+1)): if not fp.exists_points_in_component(c, g_habitat): continue num_parallel = 0 for (pt1_idx, pt2_idx) in fp.point_pair_idxs_in_component(c, g_habitat): if pt2_idx == -1: if (use_resistance_calc_shortcut==True): max_parallel = max(max_parallel, num_parallel) num_parallel = 0 break else: max_parallel = max(max_parallel, num_parallel) num_parallel = 0 continue num_parallel += 1 num_points_to_solve += 1 Compute.logger.debug('max parallel possible = ' + str(max_parallel) + ', will parallelize = ' + str(parallelize)) num_points_solved = 0 for c in range(1, int(g_habitat.num_components+1)): if not fp.exists_points_in_component(c, g_habitat): continue G_pruned, local_node_map = g_habitat.prune_nodes_for_component(c) G = ComputeBase.laplacian(G_pruned) del G_pruned if use_resistance_calc_shortcut: voltmatrix = np.zeros((numpoints,numpoints), dtype='float64') #For resistance calc shortcut G_dst_dst = local_dst = None for (pt1_idx, pt2_idx) in fp.point_pair_idxs_in_component(c, g_habitat): if pt2_idx == -1: if parallelize: self.state.worker_pool_wait() self.state.del_amg_hierarchy() if (local_dst != None) and (G_dst_dst != None): G[local_dst, local_dst] = G_dst_dst local_dst = G_dst_dst = None if (use_resistance_calc_shortcut==True): Compute.get_shortcut_resistances(pt1_idx, voltmatrix, numpoints, resistances, shortcut_resistances) break #No need to continue, we've got what we need to calculate resistances else: continue if parallelize: self.state.worker_pool_create(options.max_parallel, True) if report_status==True: num_points_solved += 1 if use_resistance_calc_shortcut==True: Compute.logger.info('solving focal node ' + str(num_points_solved) + ' of '+ str(num_points_to_solve)) else: Compute.logger.info('solving focal pair ' + str(num_points_solved) + ' of '+ str(num_points_to_solve)) local_src = fp.get_graph_node_idx(pt2_idx, local_node_map) if None == local_dst: local_dst = fp.get_graph_node_idx(pt1_idx, local_node_map) G_dst_dst = G[local_dst, local_dst] G[local_dst, local_dst] = 0 if self.state.amg_hierarchy == None: self.state.create_amg_hierarchy(G, self.options.solver) if use_resistance_calc_shortcut: post_solve = self._post_single_ground_solve(G, fp, cs, resistances, numpoints, pt1_idx, pt2_idx, local_src, local_dst, local_node_map, solver_failed_somewhere, use_resistance_calc_shortcut, voltmatrix) else: post_solve = self._post_single_ground_solve(G, fp, cs, resistances, numpoints, pt1_idx, pt2_idx, local_src, local_dst, local_node_map, solver_failed_somewhere) if parallelize: self.state.worker_pool.apply_async(Compute.parallel_single_ground_solver, args=(G, local_src, local_dst, options.solver, self.state.amg_hierarchy), callback=post_solve) #post_solve(self.state.worker_pool.apply(Compute.parallel_single_ground_solver, args=(G, local_src, local_dst, options.solver, self.state.amg_hierarchy))) else: try: voltages = Compute.single_ground_solver(G, local_src, local_dst, options.solver, self.state.amg_hierarchy) except: voltages = None post_solve(voltages) if options.low_memory_mode==True or self.state.point_file_contains_polygons==True: self.state.del_amg_hierarchy() (hours,mins,_secs) = ComputeBase.elapsed_time(last_write_time) if mins > 2 or hours > 0: last_write_time = time.time() CSIO.write_resistances(options.output_file, resistances, incomplete=True)# Save incomplete resistances self.state.del_amg_hierarchy() # Finally, resistance to self is 0. if use_resistance_calc_shortcut==True: resistances = shortcut_resistances for i in range(0, numpoints): resistances[i, i] = 0 return resistances, solver_failed_somewhere[0]