def test_sgrp_90plus(self): line_coords = array.array('d', [0, 0, -1, 0, -1, 0.01]) line_indices = array.array('I', [0, 1, 2, 0]) g = pstalgo.CreateSegmentGraph(line_coords, line_indices, None) self.doTest(g, 2, 100, False, [0, 1], [0, 1]) self.doTest(g, 2, 180, False, [0, 0], [0, 0]) self.doTest(g, 2, 100, True, [0, 1], [0, 1]) self.doTest(g, 2, 180, True, [0, 0], [0, 0]) pstalgo.FreeSegmentGraph(g) line_coords = array.array('d', [0, 0, -1, 0, -1, 0.01, 1, 1]) line_indices = array.array('I', [0, 1, 2, 0, 0, 3]) g = pstalgo.CreateSegmentGraph(line_coords, line_indices, None) self.doTest(g, 3, 90, False, [0, 1, 0], [0, 1, 0]) pstalgo.FreeSegmentGraph(g)
def test_aint_five_chain(self): count = 5 length = 3 g = CreateSegmentChainGraph(count, length) self.doTest(g, count, False, Radii(), [count] * count, [0] * count, None, [4] * count, [math.pow(count, 1.2)] * count, [count * count] * count) self.doTest(g, count, True, Radii(), [count] * count, [0] * count, None, None, None, None) self.doTest(g, count, False, Radii(straight=0), [1] * count, None, None, None, None, None) self.doTest(g, count, False, Radii(straight=1), [1] * count, None, None, None, None, None) self.doTest(g, count, False, Radii(straight=length), [2, 3, 3, 3, 2], None, None, None, None, None) self.doTest(g, count, False, Radii(walking=0), [1] * count, None, None, None, None, None) self.doTest(g, count, False, Radii(walking=1), [1] * count, None, None, None, None, None) self.doTest(g, count, False, Radii(walking=3), [2, 3, 3, 3, 2], None, None, None, None, None) self.doTest(g, count, False, Radii(steps=0), [1] * count, None, None, None, None, None) self.doTest(g, count, False, Radii(steps=1), [2, 3, 3, 3, 2], None, None, None, None, None) self.doTest(g, count, False, Radii(steps=2), [3, 4, 5, 4, 3], None, None, None, None, None) self.doTest(g, count, False, Radii(angular=1), [count] * count, None, None, None, None, None) pstalgo.FreeSegmentGraph(g)
def test_five_chain(self): line_length = 3 line_length_sqr = line_length * line_length graph = self.create_chain_graph(line_count=5, line_length=line_length) betweenness = array.array( 'f', [0]) * 5 # Fastest way of allocating arrays of array.array-type node_counts = array.array('I', [0]) * 5 total_depths = array.array('f', [0]) * 5 pstalgo.FastSegmentBetweenness(graph_handle=graph, distance_type=DistanceType.STEPS, weigh_by_length=True, radius=pstalgo.Radii(steps=4), out_betweenness=betweenness, out_node_count=node_counts, out_total_depth=total_depths) pstalgo.FreeSegmentGraph(graph) self.assertEqual( betweenness, array.array('f', [ 0, 3 * line_length_sqr, 4 * line_length_sqr, 3 * line_length_sqr, 0 ])) self.assertEqual(node_counts, array.array('I', [5, 5, 5, 5, 5])) self.assertEqual(total_depths, array.array('f', [0, 0, 0, 0, 0]))
def test_createsegmentgraph(self): line_coords = array.array('d', [0, 0, 1, 0]) line_indices = array.array('I', [0, 1]) segment_graph_handle = pstalgo.CreateSegmentGraph( line_coords, line_indices, None) self.assertIsNotNone(segment_graph_handle) pstalgo.FreeSegmentGraph(segment_graph_handle)
def test_sgrp_chain(self): count = 5 length = 3 g = CreateSegmentChainGraph(count, length) self.doTest(g, count, 1, False, [0] * count, [0] * count) self.doTest(g, count, 1, True, [0] * count, [0] * count) pstalgo.FreeSegmentGraph(g)
def test_ach_square(self): line_count = 4 line_length = 3 graph = CreateSegmentSquareGraph(line_length) self.doTest(graph, line_count, Radii(), False, [1,1,1,1], [line_count]*line_count, [4]*line_count, None) self.doTest(graph, line_count, Radii(angular=80), False, None, [1]*line_count, [0]*line_count, None) self.doTest(graph, line_count, Radii(angular=100), False, None, [3]*line_count, [2]*line_count, None) self.doTest(graph, line_count, Radii(), True, [36,36,36,36], [line_count]*line_count, [4,4,4,4], [12,12,12,12]) pstalgo.FreeSegmentGraph(graph)
def test_sgrp_square(self): count = 4 length = 3 g = CreateSegmentSquareGraph(length) self.doTest(g, count, 89, False, [0, 1, 2, 3], [0, 1, 0, 1]) self.doTest(g, count, 89, True, [0, 1, 2, 3], [0, 1, 0, 1]) self.doTest(g, count, 90, False, [0] * count, [0] * count) self.doTest(g, count, 90, True, [0] * count, [0] * count) pstalgo.FreeSegmentGraph(g)
def test_sgrp_crshr(self): count = 12 g = CreateCrosshairSegmentGraph() self.doTest(g, count, 89, False, [0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5], [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1]) self.doTest(g, count, 89, True, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], [0, 1, 2, 1, 0, 1, 0, 2, 0, 1, 2, 3]) self.doTest(g, count, 90, False, [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2], [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2]) pstalgo.FreeSegmentGraph(g)
def test_ach_line_weight(self): line_count = 5 line_length = 3 graph = CreateSegmentChainGraph(line_count, line_length) choice = array.array('f', [0])*line_count pstalgo.AngularChoice( graph_handle = graph, radius = Radii(), weigh_by_length = True, angle_threshold = 0, angle_precision = 1, out_choice = choice) self.assertEqual(choice, array.array('f', [36, 90, 108, 90, 36])) pstalgo.FreeSegmentGraph(graph)
def test_aint_square(self): count = 4 length = 3 g = CreateSegmentSquareGraph(length) self.doTest(g, count, False, Radii(), [count] * count, [4] * count, None, [float(count - 1) / 5] * count, [math.pow(count, 1.2) / 5] * count, None) self.doTest(g, count, True, Radii(), [count] * count, [4] * count, None, [9.0 / 13.0] * count, [math.pow(9, 1.2) / 13.0] * count, None) self.doTest(g, count, False, Radii(angular=80), [1] * count, [0] * count, None, None, None, None) self.doTest(g, count, False, Radii(angular=100), [3] * count, [2] * count, None, None, None, None) pstalgo.FreeSegmentGraph(g)
def test_sgint_crshr(self): count = 12 gcount = 8 seg_graph = CreateCrosshairSegmentGraph() group_arr = array.array('I', [0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7]) group_graph = pstalgo.CreateSegmentGroupGraph(seg_graph, group_arr, gcount) self.doTest(group_graph, gcount, Radii(), None, [gcount] * gcount, [11, 11, 11, 11, 10, 10, 10, 10]) self.doTest(group_graph, gcount, Radii(steps=1), None, [4, 4, 4, 4, 5, 5, 5, 5], [3, 3, 3, 3, 4, 4, 4, 4]) self.doTest(group_graph, gcount, Radii(walking=1), None, [7, 7, 7, 7, 8, 8, 8, 8], [9, 9, 9, 9, 10, 10, 10, 10]) pstalgo.FreeSegmentGroupGraph(group_graph) pstalgo.FreeSegmentGraph(seg_graph)
def test_ach_five_chain(self): line_count = 5 line_length = 3 graph = CreateSegmentChainGraph(line_count, line_length) self.doTest(graph, line_count, Radii(), False, [0, 6, 8, 6, 0], [line_count]*line_count, [0, 0, 0, 0, 0], None) self.doTest(graph, line_count, Radii(straight=0), False, None, [1]*line_count, None, None) self.doTest(graph, line_count, Radii(straight=1), False, None, [1]*line_count, None, None) self.doTest(graph, line_count, Radii(straight=line_length), False, None, [2, 3, 3, 3, 2], None, None) self.doTest(graph, line_count, Radii(walking=0), False, None, [1]*line_count, None, None) self.doTest(graph, line_count, Radii(walking=1), False, None, [1]*line_count, None, None) self.doTest(graph, line_count, Radii(walking=3), False, None, [2, 3, 3, 3, 2], None, None) self.doTest(graph, line_count, Radii(steps=0), False, None, [1]*line_count, None, None) self.doTest(graph, line_count, Radii(steps=1), False, None, [2, 3, 3, 3, 2], None, None) self.doTest(graph, line_count, Radii(steps=2), False, None, [3, 4, 5, 4, 3], None, None) self.doTest(graph, line_count, Radii(angular=1), False, None, [line_count]*line_count, None, None) self.doTest(graph, line_count, Radii(), True, [36.0, 90.0, 108.0, 90.0, 36.0], [line_count]*line_count, [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]) pstalgo.FreeSegmentGraph(graph)
def test_sgint_chain(self): count = 5 length = 3 seg_graph = CreateSegmentChainGraph(count, length) group_arr = array.array('I', [i for i in range(count)]) group_graph = pstalgo.CreateSegmentGroupGraph(seg_graph, group_arr, count) self.doTest(group_graph, count, Radii(), [0.352, 0.704, 1.056, 0.704, 0.352], [count] * count, [10, 7, 6, 7, 10]) self.doTest(group_graph, count, Radii(walking=0), None, [2, 3, 3, 3, 2], None) self.doTest(group_graph, count, Radii(walking=1), None, [2, 3, 3, 3, 2], None) self.doTest(group_graph, count, Radii(walking=3), None, [3, 4, 5, 4, 3], None) self.doTest(group_graph, count, Radii(steps=0), None, [1, 1, 1, 1, 1], None) self.doTest(group_graph, count, Radii(steps=1), None, [2, 3, 3, 3, 2], None) self.doTest(group_graph, count, Radii(steps=2), None, [3, 4, 5, 4, 3], None) self.doTest(group_graph, count, Radii(walking=3, steps=0), None, [1] * count, None) self.doTest(group_graph, count, Radii(walking=0, steps=2), None, [2, 3, 3, 3, 2], None) pstalgo.FreeSegmentGroupGraph(group_graph) group_arr = array.array('I', [0, 1, 1, 1, 2]) group_graph = pstalgo.CreateSegmentGroupGraph(seg_graph, group_arr, 3) self.doTest(group_graph, 3, Radii(), None, [3, 3, 3], [3, 2, 3]) self.doTest(group_graph, 3, Radii(steps=0), None, [1, 1, 1], [0, 0, 0]) self.doTest(group_graph, 3, Radii(steps=1), None, [2, 3, 2], [1, 2, 1]) self.doTest(group_graph, 3, Radii(walking=0), None, [2, 3, 2], [1, 2, 1]) self.doTest(group_graph, 3, Radii(walking=5), None, [2, 3, 2], [1, 2, 1]) self.doTest(group_graph, 3, Radii(walking=9), None, [3, 3, 3], [3, 2, 3]) pstalgo.FreeSegmentGroupGraph(group_graph) pstalgo.FreeSegmentGraph(seg_graph)
def test_split2(self): graph = self.create_split_graph2() betweenness = array.array( 'f', [0]) * 6 # Fastest way of allocating arrays of array.array-type node_counts = array.array('I', [0]) * 6 total_depths = array.array('f', [0]) * 6 pstalgo.FastSegmentBetweenness(graph_handle=graph, distance_type=DistanceType.ANGULAR, weigh_by_length=False, radius=pstalgo.Radii(angular=45), out_betweenness=betweenness, out_node_count=node_counts, out_total_depth=total_depths) pstalgo.FreeSegmentGraph(graph) self.assertEqual(betweenness, array.array('f', [0, 1, 1, 3, 3, 0])) self.assertEqual(node_counts, array.array('I', [6, 6, 6, 6, 6, 6])) self.assertTrue( IsArrayRoughlyEqual(total_depths, [0.26, 4.24, 4.24, 3.87, 3.87, 0.26], 0.02))
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 run(self, delegate): import pstalgo # Do it here when it is needed instead of on plugin load props = self._props Vector = pstalgo.Vector radii_list = RadiiFromSettings(pstalgo, self._props).split() # Tasks class Tasks(object): BUILD_SEGMENT_GRAPH = 1 ANALYSIS = 2 WRITE_RESULTS = 3 progress = MultiTaskProgressDelegate(delegate) progress.addTask(Tasks.BUILD_SEGMENT_GRAPH, 1, None) progress.addTask(Tasks.ANALYSIS, 10 * len(radii_list), None) initial_alloc_state = stack_allocator.state() segment_graph = None group_graph = None try: # Segment Graph progress.setCurrentTask(Tasks.BUILD_SEGMENT_GRAPH) (segment_graph, segment_rows) = BuildSegmentGraph( self._model, pstalgo, stack_allocator, self._props['in_network'], progress) segment_count = segment_rows.size() # Generate groups progress.setStatus("Generating groups") group_per_segment = Vector(ctypes.c_uint, segment_count, stack_allocator, segment_count) group_count = pstalgo.SegmentGrouping( segment_graph=segment_graph, angle_threshold=props['angle_threshold'], split_at_junctions=props['split_at_junctions'], out_group_id_per_line=group_per_segment)[0] # Create group graph progress.setStatus("Creating segment group graph") group_graph = pstalgo.CreateSegmentGroupGraph( segment_graph, group_per_segment, group_count) # Allocate output arrays scores_grp = Vector(ctypes.c_float, group_count, stack_allocator, group_count) total_counts_grp = Vector( ctypes.c_uint, group_count, stack_allocator, group_count ) if self._props['output_N'] or self._props['output_MD'] else None total_depths_grp = Vector( ctypes.c_float, group_count, stack_allocator, group_count ) if self._props['output_TD'] or self._props['output_MD'] else None scores_seg = Vector(ctypes.c_float, segment_count, stack_allocator, segment_count) total_counts_seg = Vector( ctypes.c_uint, segment_count, stack_allocator, segment_count ) if self._props['output_N'] or self._props['output_MD'] else None total_depths_seg = Vector( ctypes.c_float, segment_count, stack_allocator, segment_count ) if self._props['output_TD'] or self._props['output_MD'] else None progress.setCurrentTask(Tasks.ANALYSIS) radii_progress = TaskSplitProgressDelegate(len(radii_list), "Performing analysis", progress) for radii in radii_list: radii_sub_progress = MultiTaskProgressDelegate(radii_progress) radii_sub_progress.addTask(Tasks.ANALYSIS, 5, "Calculating") radii_sub_progress.addTask(Tasks.WRITE_RESULTS, 1, "Writing results") # Analysis radii_sub_progress.setCurrentTask(Tasks.ANALYSIS) pstalgo.SegmentGroupIntegration( group_graph=group_graph, radii=radii, progress_callback=pstalgo. CreateAnalysisDelegateCallbackWrapper(radii_sub_progress), out_integration=scores_grp, out_node_counts=total_counts_grp, out_total_depths=total_depths_grp) # Map outputs from group to segments if scores_grp is not None: MapGroupValues(scores_grp, group_per_segment, scores_seg) if total_counts_grp is not None: MapGroupValues(total_counts_grp, group_per_segment, total_counts_seg) if total_depths_grp is not None: MapGroupValues(total_depths_grp, group_per_segment, total_depths_seg) # Line outputs radii_sub_progress.setCurrentTask(Tasks.WRITE_RESULTS) base_name = '%s_%d%s' % (ColName.SEGMENT_GROUP_INTEGRATION, int(round(props['angle_threshold'])), '_sp' if props['split_at_junctions'] else '') columns = [] if scores_seg is not None: columns.append((GenColName(base_name, radii=radii), 'float', scores_seg.values())) if total_counts_seg is not None: columns.append( (GenColName(base_name, radii=radii, extra=ColName.EXTRA_NODE_COUNT), 'integer', total_counts_seg.values())) if total_depths_seg is not None: columns.append( (GenColName(base_name, radii=radii, extra=ColName.EXTRA_TOTAL_DEPTH), 'float', total_depths_seg.values())) if self._props['output_MD']: columns.append( (GenColName(base_name, radii=radii, extra=ColName.EXTRA_MEAN_DEPTH), 'float', MeanDepthGen(total_depths_seg, total_counts_seg))) self._model.writeColumns(self._props['in_network'], segment_rows, columns, radii_sub_progress) radii_progress.nextTask() finally: stack_allocator.restore(initial_alloc_state) if group_graph: pstalgo.FreeSegmentGroupGraph(group_graph) group_graph = None if segment_graph: pstalgo.FreeSegmentGraph(segment_graph) segment_graph = None delegate.setStatus("Segment Group Integration 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 need_no_weight_analysis = props['calc_no_weight'] need_length_weight_analysis = props['calc_length_weight'] def ScoreColName(radii, weight, norm): return GenColName(ColName.ANGULAR_INTEGRATION, radii=radii, weight=weight, normalization=norm) def ExtraColName(radii, extra): return GenColName(ColName.ANGULAR_INTEGRATION, radii=radii, extra=extra) # Tasks class Tasks(object): BUILD_GRAPH = 1 LENGTH_WEIGHT_ANALYSIS = 2 NO_WEIGHT_ANALYSIS = 3 WRITE_RESULTS = 4 progress = MultiTaskProgressDelegate(delegate) progress.addTask(Tasks.BUILD_GRAPH, 1, None) if need_length_weight_analysis: progress.addTask( Tasks.LENGTH_WEIGHT_ANALYSIS, 5, "Calculating length-weighted angular integration") if need_no_weight_analysis: progress.addTask(Tasks.NO_WEIGHT_ANALYSIS, 5, "Calculating angular integration") progress.addTask(Tasks.WRITE_RESULTS, 1, "Writing results") 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 total_counts = Vector(ctypes.c_uint, line_count, stack_allocator, line_count) total_depths = Vector(ctypes.c_float, line_count, stack_allocator, line_count) # Radius radii = RadiiFromSettings(pstalgo, self._props) columns = [] N_TD_MD_outputted = False # Length-weighted analysis if need_length_weight_analysis: progress.setCurrentTask(Tasks.LENGTH_WEIGHT_ANALYSIS) total_weights = Vector(ctypes.c_float, line_count, stack_allocator, line_count) total_depth_weights = Vector(ctypes.c_float, line_count, stack_allocator, line_count) pstalgo.AngularIntegration( graph_handle=graph, radius=radii, weigh_by_length=True, angle_threshold=props['angle_threshold'], angle_precision=props['angle_precision'], progress_callback=pstalgo. CreateAnalysisDelegateCallbackWrapper(progress), out_node_counts=total_counts, out_total_depths=total_depths, out_total_weights=total_weights, out_total_depth_weights=total_depth_weights) if props['norm_normalization']: scores_weighted = Vector(ctypes.c_float, line_count, stack_allocator, line_count) pstalgo.AngularIntegrationNormalizeLengthWeight( total_weights, total_depth_weights, line_count, scores_weighted) columns.append((ScoreColName(radii, ColName.WEIGHT_LENGTH, ColName.NORM_NONE), 'float', scores_weighted.values())) if props['norm_syntax']: scores_weighted = Vector(ctypes.c_float, line_count, stack_allocator, line_count) pstalgo.AngularIntegrationSyntaxNormalizeLengthWeight( total_weights, total_depth_weights, line_count, scores_weighted) columns.append( (ScoreColName(radii, ColName.WEIGHT_LENGTH, ColName.NORM_SYNTAX_NAIN), 'float', scores_weighted.values())) if props['norm_hillier']: scores_weighted = Vector(ctypes.c_float, line_count, stack_allocator, line_count) pstalgo.AngularIntegrationHillierNormalizeLengthWeight( total_weights, total_depth_weights, line_count, scores_weighted) columns.append( (ScoreColName(radii, ColName.WEIGHT_LENGTH, ColName.NORM_HILLIER), 'float', scores_weighted.values())) if not N_TD_MD_outputted: if props['output_N']: columns.append( (ExtraColName(radii, ColName.EXTRA_NODE_COUNT), 'integer', total_counts.values())) if props['output_TD']: columns.append( (ExtraColName(radii, ColName.EXTRA_TOTAL_DEPTH), 'float', total_depths.values())) if props['output_MD']: columns.append( (ExtraColName(radii, ColName.EXTRA_MEAN_DEPTH), 'float', MeanDepthGen(total_depths, total_counts))) N_TD_MD_outputted = True # Non-weighted analysis if need_no_weight_analysis: progress.setCurrentTask(Tasks.NO_WEIGHT_ANALYSIS) pstalgo.AngularIntegration( graph_handle=graph, radius=radii, weigh_by_length=False, angle_threshold=props['angle_threshold'], angle_precision=props['angle_precision'], progress_callback=pstalgo. CreateAnalysisDelegateCallbackWrapper(progress), out_node_counts=total_counts, out_total_depths=total_depths, out_total_weights=None, out_total_depth_weights=None) if props['norm_normalization']: scores = Vector(ctypes.c_float, line_count, stack_allocator, line_count) pstalgo.AngularIntegrationNormalize( total_counts, total_depths, line_count, scores) columns.append((ScoreColName(radii, ColName.WEIGHT_NONE, ColName.NORM_NONE), 'float', scores.values())) if props['norm_syntax']: scores = Vector(ctypes.c_float, line_count, stack_allocator, line_count) pstalgo.AngularIntegrationSyntaxNormalize( total_counts, total_depths, line_count, scores) columns.append( (ScoreColName(radii, ColName.WEIGHT_NONE, ColName.NORM_SYNTAX_NAIN), 'float', scores.values())) if props['norm_hillier']: scores = Vector(ctypes.c_float, line_count, stack_allocator, line_count) pstalgo.AngularIntegrationHillierNormalize( total_counts, total_depths, line_count, scores) columns.append( (ScoreColName(radii, ColName.WEIGHT_NONE, ColName.NORM_HILLIER), 'float', scores.values())) if not N_TD_MD_outputted: if props['output_N']: columns.append( (ExtraColName(radii, ColName.EXTRA_NODE_COUNT), 'integer', total_counts.values())) if props['output_TD']: columns.append( (ExtraColName(radii, ColName.EXTRA_TOTAL_DEPTH), 'float', total_depths.values())) if props['output_MD']: columns.append( (ExtraColName(radii, ColName.EXTRA_MEAN_DEPTH), 'float', MeanDepthGen(total_depths, total_counts))) N_TD_MD_outputted = True # Free graph pstalgo.FreeSegmentGraph(graph) graph = None # --- WRITE_RESULTS --- progress.setCurrentTask(Tasks.WRITE_RESULTS) self._model.writeColumns(self._props['in_network'], line_rows, columns, progress) finally: stack_allocator.restore(initial_alloc_state) if graph: pstalgo.FreeSegmentGraph(graph) graph = None delegate.setStatus("Reach 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 def GenerateName(what, angle_threshold, split): title = 'seggrp_' + what + '_' + str(int(angle_threshold)) if split: title += "_split" return title # Tasks class Tasks(object): GRAPH = 1 ANALYSIS = 2 WRITE = 3 progress = MultiTaskProgressDelegate(delegate) progress.addTask(Tasks.GRAPH, 5, None) progress.addTask(Tasks.ANALYSIS, 1, "Creating segment groups") progress.addTask(Tasks.WRITE, 5, "Writing results") initial_alloc_state = stack_allocator.state() graph = None try: # Graph progress.setCurrentTask(Tasks.GRAPH) (graph, line_rows) = BuildSegmentGraph(self._model, pstalgo, stack_allocator, props['in_network'], progress) line_count = line_rows.size() # Allocate output arrays group_ids = Vector(ctypes.c_uint, line_count, stack_allocator, line_count) colors = Vector(ctypes.c_uint, line_count, stack_allocator, line_count) if props['generate_colors'] else None # --- ANALYSIS --- progress.setCurrentTask(Tasks.ANALYSIS) (group_count, color_count) = pstalgo.SegmentGrouping( segment_graph=graph, angle_threshold=props['angle_threshold'], split_at_junctions=props['split_at_junctions'], out_group_id_per_line=group_ids, out_color_per_line=colors, progress_callback=pstalgo. CreateAnalysisDelegateCallbackWrapper(progress)) columns = [] if group_ids is not None: columns.append( (GenerateName("id", props['angle_threshold'], props['split_at_junctions']), 'integer', group_ids.values())) if colors is not None: color_column_name = GenerateName("color", props['angle_threshold'], props['split_at_junctions']) columns.append((color_column_name, 'integer', colors.values())) # --- WRITE_RESULTS --- progress.setCurrentTask(Tasks.WRITE) self._model.writeColumns(props['in_network'], line_rows, columns, progress) # Color layer if props['apply_colors']: assert (colors is not None) progress.setStatus('Coloring') ranges = [] for color_index in range(color_count): ranges.append( (str(color_index), PALETTE[color_index % len(PALETTE)], color_index)) model.makeThematic(props['in_network'], color_column_name, ranges) finally: stack_allocator.restore(initial_alloc_state) if graph: pstalgo.FreeSegmentGraph(graph) graph = None delegate.setStatus("Segment grouping done") delegate.setProgress(1)