def test_ach_normalize(self): values = array.array('f', [1, 2, 3, 4, 5]) normalized = array.array('f', [0])*5 pstalgo.StandardNormalize(values, len(values), normalized) self.assertEqual(normalized, array.array('f', [0, 0.25, 0.5, 0.75, 1]), "Standard Normalization") pstalgo.AngularChoiceNormalize(values, array.array('I', [1, 2, 3, 4, 5]), len(values), normalized) self.assertTrue(IsArrayRoughlyEqual(normalized, [1, 2, 1.5, 4.0/6, 5.0/12]), "Normalization " + str(normalized)) TD = array.array('f', [5, 4, 3, 2, 1]) pstalgo.AngularChoiceSyntaxNormalize(values, TD, len(values), normalized) check = [(math.log10(values[i] + 1)/math.log10(TD[i] + 2)) for i in range(len(values))] self.assertTrue(IsArrayRoughlyEqual(normalized, check), "Syntax Normalization " + str(normalized) + " != " + str(check))
def run(self, delegate): import pstalgo # Do it here when it is needed instead of on plugin load Vector = pstalgo.Vector props = self._props def GenerateScoreColumnName(length_weight_enabled, radii, norm): return GenColName(ColName.ANGULAR_CHOICE, radii=radii, weight=ColName.WEIGHT_LENGTH if length_weight_enabled else ColName.WEIGHT_NONE, normalization=norm) def GenerateStatColumnName(stat, radii): return GenColName(ColName.ANGULAR_CHOICE, radii=radii, extra=stat) # Number of analyses analysis_count = 0 if props['weight_none']: analysis_count += 1 if props['weight_length']: analysis_count += 1 assert (analysis_count > 0) # 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) radii = RadiiFromSettings(pstalgo, self._props) initial_alloc_state = stack_allocator.state() graph = None try: # Graph progress.setCurrentTask(Tasks.BUILD_GRAPH) (graph, line_rows) = BuildSegmentGraph(self._model, pstalgo, stack_allocator, self._props['in_network'], progress) line_count = line_rows.size() # Allocate output arrays scores = Vector(ctypes.c_float, line_count, stack_allocator, line_count) scores_norm = Vector( ctypes.c_float, line_count, stack_allocator, line_count) if props['norm_normalization'] else None scores_std = Vector(ctypes.c_float, line_count, stack_allocator, line_count) if props['norm_standard'] else None scores_syntax = Vector( ctypes.c_float, line_count, stack_allocator, line_count) if props['norm_syntax'] 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) total_depth_weights = Vector( ctypes.c_float, line_count, stack_allocator, line_count) if props['weight_length'] else None progress.setCurrentTask(Tasks.ANALYSIS) analysis_progress = TaskSplitProgressDelegate( analysis_count, "Performing analysis", progress) N_TD_MD_outputted = False if props['weight_length']: # 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.AngularChoice( graph_handle=graph, radius=radii, weigh_by_length=True, angle_threshold=props['angle_threshold'], angle_precision=props['angle_precision'], progress_callback=pstalgo. CreateAnalysisDelegateCallbackWrapper( analysis_sub_progress), out_choice=scores, out_node_count=total_counts, out_total_depth=total_depths, out_total_depth_weight=total_depth_weights) # Output columns = [] if props['norm_none']: columns.append( (GenerateScoreColumnName(True, radii, ColName.NORM_NONE), 'float', scores.values())) # Normalization if scores_norm is not None: pstalgo.AngularChoiceNormalize(scores, total_counts, scores.size(), scores_norm) columns.append( (GenerateScoreColumnName(True, radii, ColName.NORM_TURNER), 'float', scores_norm.values())) # Standard normalization if scores_std is not None: pstalgo.StandardNormalize(scores, scores.size(), scores_std) columns.append( (GenerateScoreColumnName(True, radii, ColName.NORM_STANDARD), 'float', scores_std.values())) # Syntax normalization if scores_syntax is not None: pstalgo.AngularChoiceSyntaxNormalize( scores, total_depth_weights, scores.size(), scores_syntax) columns.append( (GenerateScoreColumnName(True, radii, ColName.NORM_SYNTAX_NACH), 'float', scores_syntax.values())) if not N_TD_MD_outputted: # N if props['output_N']: columns.append( (GenerateStatColumnName(ColName.EXTRA_NODE_COUNT, radii), 'integer', total_counts.values())) # TD if props['output_TD']: columns.append( (GenerateStatColumnName(ColName.EXTRA_TOTAL_DEPTH, radii), 'float', total_depths.values())) # MD if props['output_MD']: columns.append( (GenerateStatColumnName(ColName.EXTRA_MEAN_DEPTH, radii), 'float', MeanDepthGen(total_depths, total_counts))) N_TD_MD_outputted = True # Write analysis_sub_progress.setCurrentTask(Tasks.WRITE_RESULTS) self._model.writeColumns(self._props['in_network'], line_rows, columns, analysis_sub_progress) # Next task progress analysis_progress.nextTask() if props['weight_none']: # 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.AngularChoice(graph_handle=graph, radius=RadiiFromSettings( pstalgo, self._props), weigh_by_length=False, progress_callback=pstalgo. CreateAnalysisDelegateCallbackWrapper( analysis_sub_progress), out_choice=scores, out_node_count=total_counts, out_total_depth=total_depths) # Output columns = [] if props['weight_none']: if props['norm_none']: columns.append( (GenerateScoreColumnName(False, radii, ColName.NORM_NONE), 'float', scores.values())) # Normalization if scores_norm is not None: pstalgo.AngularChoiceNormalize(scores, total_counts, scores.size(), scores_norm) columns.append( (GenerateScoreColumnName(False, radii, ColName.NORM_TURNER), 'float', scores_norm.values())) # Standard normalization if scores_std is not None: pstalgo.StandardNormalize(scores, scores.size(), scores_std) columns.append( (GenerateScoreColumnName(False, radii, ColName.NORM_STANDARD), 'float', scores_std.values())) # Syntax normalization if scores_syntax is not None: pstalgo.AngularChoiceSyntaxNormalize( scores, total_depths, scores.size(), scores_syntax) columns.append( (GenerateScoreColumnName(False, radii, ColName.NORM_SYNTAX_NACH), 'float', scores_syntax.values())) if not N_TD_MD_outputted: # N if props['output_N']: columns.append( (GenerateStatColumnName(ColName.EXTRA_NODE_COUNT, radii), 'integer', total_counts.values())) # TD if props['output_TD']: columns.append( (GenerateStatColumnName(ColName.EXTRA_TOTAL_DEPTH, radii), 'float', total_depths.values())) # MD if props['output_MD']: columns.append( (GenerateStatColumnName(ColName.EXTRA_MEAN_DEPTH, radii), 'float', MeanDepthGen(total_depths, total_counts))) N_TD_MD_outputted = True # Write analysis_sub_progress.setCurrentTask(Tasks.WRITE_RESULTS) self._model.writeColumns(self._props['in_network'], line_rows, columns, analysis_sub_progress) # Next task progress analysis_progress.nextTask() finally: stack_allocator.restore(initial_alloc_state) if graph: pstalgo.FreeSegmentGraph(graph) delegate.setStatus("Angular Choice done") delegate.setProgress(1)
def DoAnalysis(weigh_by_length, output_counters): # 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.FastSegmentBetweenness( graph_handle=graph, distance_type=pstalgo.DistanceType.ANGULAR, weigh_by_length=weigh_by_length, radius=radii, progress_callback=pstalgo. CreateAnalysisDelegateCallbackWrapper( analysis_sub_progress), out_betweenness=scores, out_node_count=total_counts, out_total_depth=total_depths) # Output columns = [] if props['norm_none']: columns.append( (GenerateScoreColumnName(weigh_by_length, radii, ColName.NORM_NONE), 'float', scores.values())) # Normalization if scores_norm is not None: pstalgo.AngularChoiceNormalize(scores, total_counts, scores.size(), scores_norm) columns.append( (GenerateScoreColumnName(weigh_by_length, radii, ColName.NORM_TURNER), 'float', scores_norm.values())) # Standard normalization if scores_std is not None: pstalgo.StandardNormalize(scores, scores.size(), scores_std) columns.append( (GenerateScoreColumnName(weigh_by_length, radii, ColName.NORM_STANDARD), 'float', scores_std.values())) # Syntax normalization if scores_syntax is not None: pstalgo.AngularChoiceSyntaxNormalize( scores, total_depth_weights, scores.size(), scores_syntax) columns.append( (GenerateScoreColumnName(weigh_by_length, radii, ColName.NORM_SYNTAX_NACH), 'float', scores_syntax.values())) if output_counters: # N if props['output_N']: columns.append( (GenerateStatColumnName(ColName.EXTRA_NODE_COUNT, radii), 'integer', total_counts.values())) # TD if props['output_TD']: columns.append( (GenerateStatColumnName(ColName.EXTRA_TOTAL_DEPTH, radii), 'float', total_depths.values())) # MD if props['output_MD']: columns.append( (GenerateStatColumnName(ColName.EXTRA_MEAN_DEPTH, radii), 'float', MeanDepthGen(total_depths, total_counts))) # Write analysis_sub_progress.setCurrentTask(Tasks.WRITE_RESULTS) self._model.writeColumns(self._props['in_network'], line_rows, columns, analysis_sub_progress) # Next task progress analysis_progress.nextTask()
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)