def parameters(self) -> Dict[str, float]: """ Get numerical geometric and topological parameters. """ # Cannot do simple cached_property because None might have been # returned previously. if self._parameters is None: self._parameters = determine_topology_parameters( trace_length_array=self.trace_length_array_non_weighted, node_counts=self.node_counts, area=self.total_area, branches_defined=self.topology_determined, correct_mauldon=self.circular_target_area, ) return self._parameters
def test_determine_topology_parameters( trace_length_array, node_counts, area, ): """ Test determining parameters. """ topology_parameters = parameters.determine_topology_parameters( trace_length_array, node_counts, area, ) assert all(param >= 0 for param in topology_parameters.values()) assert all( isinstance(param, (float, int)) for param in topology_parameters.values())
def test_determine_topology_parameters( trace_length_array, node_counts, area, branches_defined, correct_mauldon, branch_length_array, ): """ Test determining parameters. """ assert isinstance(area, float) topology_parameters = parameters.determine_topology_parameters( trace_length_array=trace_length_array, node_counts=node_counts, area=area, branches_defined=branches_defined, correct_mauldon=correct_mauldon, branch_length_array=branch_length_array, ) assert all(param >= 0 for param in topology_parameters.values()) assert all( isinstance(param, (float, int)) for param in topology_parameters.values())
def populate_sample_cell( sample_cell: Polygon, sample_cell_area: float, traces_sindex: PyGEOSSTRTreeIndex, traces: gpd.GeoDataFrame, nodes: gpd.GeoDataFrame, snap_threshold: float, resolve_branches_and_nodes: bool, ) -> Dict[str, float]: """ Take a single grid polygon and populate it with parameters. Mauldon determination requires that E-nodes are defined for every single sample circle. If correct Mauldon values are wanted `resolve_branches_and_nodes` must be passed as True. This will result in much longer analysis time. """ _centroid = sample_cell.centroid if not isinstance(_centroid, Point): raise TypeError("Expected Point centroid.") centroid = _centroid sample_circle = safe_buffer(centroid, np.sqrt(sample_cell_area) * 1.5) sample_circle_area = sample_circle.area assert sample_circle_area > 0 # Choose geometries that are either within the sample_circle or # intersect it # Use spatial indexing to filter to only spatially relevant traces, # traces and nodes trace_candidates_idx = spatial_index_intersection( traces_sindex, geom_bounds(sample_circle)) trace_candidates = traces.iloc[trace_candidates_idx] assert isinstance(trace_candidates, gpd.GeoDataFrame) if len(trace_candidates) == 0: return determine_topology_parameters( trace_length_array=np.array([]), node_counts=determine_node_type_counts(np.array([]), branches_defined=True), area=sample_circle_area, ) if resolve_branches_and_nodes: # Solve branches and nodes for each cell if wanted # Only way to make sure Mauldon parameters are correct _, nodes = branches_and_nodes( traces=trace_candidates, areas=gpd.GeoSeries([sample_circle], crs=traces.crs), snap_threshold=snap_threshold, ) # node_candidates_idx = list(nodes_sindex.intersection(sample_circle.bounds)) node_candidates_idx = spatial_index_intersection( spatial_index=pygeos_spatial_index(nodes), coordinates=geom_bounds(sample_circle), ) node_candidates = nodes.iloc[node_candidates_idx] # Crop traces to sample circle # First check if any geometries intersect # If not: sample_features is an empty GeoDataFrame if any( trace_candidate.intersects(sample_circle) for trace_candidate in trace_candidates.geometry.values): sample_traces = crop_to_target_areas( traces=trace_candidates, areas=gpd.GeoSeries([sample_circle]), is_filtered=True, keep_column_data=False, ) else: sample_traces = traces.iloc[0:0] if any(node.intersects(sample_circle) for node in nodes.geometry.values): # if any(nodes.intersects(sample_circle)): # TODO: Is node clipping stable? sample_nodes = gpd.clip(node_candidates, sample_circle) assert sample_nodes is not None assert all( isinstance(val, Point) for val in sample_nodes.geometry.values) else: sample_nodes = nodes.iloc[0:0] assert isinstance(sample_nodes, gpd.GeoDataFrame) assert isinstance(sample_traces, gpd.GeoDataFrame) sample_node_type_values = sample_nodes[CLASS_COLUMN].values assert isinstance(sample_node_type_values, np.ndarray) node_counts = determine_node_type_counts(sample_node_type_values, branches_defined=True) topology_parameters = determine_topology_parameters( trace_length_array=sample_traces.geometry.length.values, node_counts=node_counts, area=sample_circle_area, correct_mauldon=resolve_branches_and_nodes, ) return topology_parameters