def test_split2(self): graph = self.create_split_graph2() betweenness = array.array('f', [0])*6 # Fastest way of allocating arrays of array.array-type pstalgo.SegmentBetweenness( graph_handle = graph, distance_type = DistanceType.ANGULAR, radius = pstalgo.Radii(angular=45), out_betweenness = betweenness) pstalgo.FreeGraph(graph) self.assertEqual(betweenness, array.array('f', [0, 1, 1, 2, 2, 0]))
def test_five_chain(self): graph = self.create_chain_graph(5) betweenness = array.array('f', [0])*5 # Fastest way of allocating arrays of array.array-type pstalgo.SegmentBetweenness( graph_handle = graph, distance_type = DistanceType.STEPS, radius = pstalgo.Radii(steps=4), out_betweenness = betweenness) pstalgo.FreeGraph(graph) self.assertEqual(betweenness, array.array('f', [0, 3, 4, 3, 0]))
def run(self, delegate): import pstalgo # Do it here when it is needed instead of on plugin load Vector = pstalgo.Vector props = self._props radii_list = RadiiFromSettings(pstalgo, self._props).split() # Distance modes distance_modes = DistanceTypesFromSettings(pstalgo, props) # Weight modes class WeightMode(object): NONE = 0 LENGTH = 1 weight_modes = [] if props['weight_none']: weight_modes.append(WeightMode.NONE) if props['weight_length']: weight_modes.append(WeightMode.LENGTH) if props['weight_data']: for name in props['weight_data_cols']: weight_modes.append(name) def GenerateScoreColumnName(distance_mode, weight, radii, norm): if weight == WeightMode.NONE: weight = ColName.WEIGHT_NONE elif weight == WeightMode.LENGTH: weight = ColName.WEIGHT_LENGTH return GenColName(ColName.NETWORK_BETWEENNESS, pst_distance_type=distance_mode, weight=weight, radii=radii, normalization=norm) def GenerateStatColumnName(stat, distance_mode, radii): name = GenColName(ColName.NETWORK_BETWEENNESS, pst_distance_type=distance_mode, radii=radii, extra=stat) print(name) return name # Number of analyses analysis_count = len(radii_list) * len(distance_modes) * len( weight_modes) # Tasks class Tasks(object): BUILD_GRAPH = 1 ANALYSIS = 2 WRITE_RESULTS = 3 progress = MultiTaskProgressDelegate(delegate) progress.addTask(Tasks.BUILD_GRAPH, 1, None) progress.addTask(Tasks.ANALYSIS, 5 * analysis_count, None) initial_alloc_state = stack_allocator.state() graph = None try: # Graph progress.setCurrentTask(Tasks.BUILD_GRAPH) (graph, line_rows, _) = BuildAxialGraph( self._model, pstalgo, stack_allocator, self._props['in_network'], self._props['in_unlinks'] if self._props['in_unlinks_enabled'] else None, None, progress) line_count = line_rows.size() # Allocate output arrays weights = None scores = Vector(ctypes.c_float, line_count, stack_allocator, line_count) scores_std = Vector(ctypes.c_float, line_count, stack_allocator, line_count) if props['norm_standard'] else None total_counts = Vector(ctypes.c_uint, line_count, stack_allocator, line_count) total_depths = Vector(ctypes.c_float, line_count, stack_allocator, line_count) output_N = (False != props['output_N']) output_TD = (False != props['output_TD']) output_MD = (False != props['output_MD']) progress.setCurrentTask(Tasks.ANALYSIS) analysis_progress = TaskSplitProgressDelegate( analysis_count, "Performing analysis", progress) for weight_mode in weight_modes: # Get weights if weight_mode == WeightMode.NONE: pass elif weight_mode == WeightMode.LENGTH: if weights is None: weights = Vector(ctypes.c_float, line_count, stack_allocator) weights.resize(line_count) pstalgo.GetGraphLineLengths(graph, weights) else: if weights is None: weights = Vector(ctypes.c_float, line_count, stack_allocator) column_name = weight_mode analysis_progress.setStatus("Reading weight data '%s'" % column_name) weights.resize(0) self._model.readValues(self._props['in_network'], column_name, line_rows, weights) # These metrics are independent of weight mode, and should therefore only be outputted for first weight mode if weight_mode != weight_modes[0]: output_N = False output_TD = False output_MD = False for radii in radii_list: for distance_mode in distance_modes: # Analysis sub progress analysis_sub_progress = MultiTaskProgressDelegate( analysis_progress) analysis_sub_progress.addTask(Tasks.ANALYSIS, 3, "Calculating") analysis_sub_progress.addTask(Tasks.WRITE_RESULTS, 1, "Writing line results") # Analysis analysis_sub_progress.setCurrentTask(Tasks.ANALYSIS) pstalgo.SegmentBetweenness( graph_handle=graph, distance_type=distance_mode, radius=radii, weights=None if weight_mode == WeightMode.NONE else weights, attraction_points=None, progress_callback=pstalgo. CreateAnalysisDelegateCallbackWrapper( analysis_sub_progress), out_betweenness=scores, out_node_count=total_counts, out_total_depth=total_depths) # Output analysis_sub_progress.setCurrentTask( Tasks.WRITE_RESULTS) columns = [] # No normalization if props['norm_none']: columns.append((GenerateScoreColumnName( distance_mode, weight_mode, radii, ColName.NORM_NONE), 'float', scores.values())) # Standard normalization if scores_std is not None: pstalgo.StandardNormalize(scores, scores.size(), scores_std) columns.append((GenerateScoreColumnName( distance_mode, weight_mode, radii, ColName.NORM_STANDARD), 'float', scores_std.values())) # Node counts if output_N: columns.append((GenerateStatColumnName( ColName.EXTRA_NODE_COUNT, distance_mode, radii), 'integer', total_counts.values())) # Total depths if output_TD: columns.append((GenerateStatColumnName( ColName.EXTRA_TOTAL_DEPTH, distance_mode, radii), 'float', total_depths.values())) # Mean depths if output_MD: columns.append( (GenerateStatColumnName( ColName.EXTRA_MEAN_DEPTH, distance_mode, radii), 'float', MeanDepthGen(total_depths, total_counts))) # Write self._model.writeColumns(self._props['in_network'], line_rows, columns, analysis_sub_progress) analysis_progress.nextTask() finally: stack_allocator.restore(initial_alloc_state) if graph: pstalgo.FreeGraph(graph) delegate.setStatus("Network Betweenness done") delegate.setProgress(1)
def run(self, delegate): import pstalgo # Do it here when it is needed instead of on plugin load Vector = pstalgo.Vector props = self._props model = self._model radii_list = RadiiFromSettings(pstalgo, self._props).split() # Distance modes distance_modes = DistanceTypesFromSettings(pstalgo, props) def GenerateColumnName(attr_name, distance_mode, radii, norm): return GenColName(ColName.ATTRACTION_BETWEENNESS, weight=attr_name, pst_distance_type=distance_mode, radii=radii, normalization=norm) # Attraction columns (None = use value 1 for every attraction) attraction_columns = props['dest_data'] if props[ 'dest_data_enabled'] else [None] # Number of analyses analysis_count = len(attraction_columns) * len(radii_list) * len( distance_modes) # Tasks class Tasks(object): READ_ATTRACTIONS = 1 BUILD_GRAPH = 2 ANALYSIS = 3 WRITE_RESULTS = 4 progress = MultiTaskProgressDelegate(delegate) progress.addTask(Tasks.READ_ATTRACTIONS, 1, None) progress.addTask(Tasks.BUILD_GRAPH, 1, None) progress.addTask(Tasks.ANALYSIS, 10 * analysis_count, None) initial_alloc_state = stack_allocator.state() graph = None try: # Attraction points progress.setCurrentTask(Tasks.READ_ATTRACTIONS) (attr_table, attr_rows, attr_points, attr_points_per_polygon) = ReadAttractionPoints( model, pstalgo, stack_allocator, props, progress) # Graph progress.setCurrentTask(Tasks.BUILD_GRAPH) (graph, line_rows, _) = BuildAxialGraph( self._model, pstalgo, stack_allocator, self._props['in_network'], self._props['in_unlinks'] if self._props['in_unlinks_enabled'] else None, None, progress) line_count = line_rows.size() # Allocate output arrays scores = Vector(ctypes.c_float, line_count, stack_allocator, line_count) scores_std = Vector(ctypes.c_float, line_count, stack_allocator, line_count) if props['norm_standard'] else None # Analyses attr_values = None progress.setCurrentTask(Tasks.ANALYSIS) analysis_progress = TaskSplitProgressDelegate( analysis_count, "Performing analysis", progress) for attr_col in attraction_columns: # Attraction values if attr_col is not None: if attr_values is None: attr_values = Vector(ctypes.c_float, attr_rows.size(), stack_allocator) attr_values.clear() for value in AttractionValueGen(model, attr_table, attr_rows, [attr_col], progress): attr_values.append(value) attr_title = GenerateAttractionDataName( props['in_destinations'], attr_col, props['dest_name']) for radii in radii_list: for distance_mode in distance_modes: # Analysis sub progress analysis_sub_progress = MultiTaskProgressDelegate( analysis_progress) analysis_sub_progress.addTask(Tasks.ANALYSIS, 1, "Calculating") analysis_sub_progress.addTask(Tasks.WRITE_RESULTS, 0, "Writing line results") # Analysis analysis_sub_progress.setCurrentTask(Tasks.ANALYSIS) pstalgo.SegmentBetweenness( graph_handle=graph, distance_type=distance_mode, radius=radii, weights=None if attr_col is None else attr_values, attraction_points=attr_points, progress_callback=pstalgo. CreateAnalysisDelegateCallbackWrapper( analysis_sub_progress), out_betweenness=scores) # Write analysis_sub_progress.setCurrentTask( Tasks.WRITE_RESULTS) columns = [] if props['norm_none']: columns.append( (GenerateColumnName(attr_title, distance_mode, radii, ColName.NORM_NONE), 'float', scores.values())) if props['norm_standard']: pstalgo.StandardNormalize(scores, scores.size(), scores_std) columns.append( (GenerateColumnName(attr_title, distance_mode, radii, ColName.NORM_STANDARD), 'float', scores_std.values())) self._model.writeColumns(self._props['in_network'], line_rows, columns, analysis_sub_progress) # Progress analysis_progress.nextTask() finally: stack_allocator.restore(initial_alloc_state) if graph: pstalgo.FreeGraph(graph) delegate.setStatus("Attraction Betweenness done") delegate.setProgress(1)