Пример #1
0
    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
Пример #2
0
    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]