def pc_generate_pyKDTree(pc_xyz): try: from pykdtree.kdtree import KDTree as pyKDTree except ImportError: raise pc_generate_pyKDTree("pykdtree not installed.") pc_xyz_pyKDTree_tree = pyKDTree(pc_xyz) return pc_xyz_pyKDTree_tree
def knn_query(in_coords, out_coords, k: int): from pykdtree.kdtree import ( KDTree as pyKDTree, # pylint: disable=no-name-in-module,import-outside-toplevel ) tree = pyKDTree(in_coords) dists, indices = tree.query(out_coords, k) return dists, indices
def kdtree(coordinates, use_pykdtree=True, **kwargs): """ Create a KD-Tree object with the given coordinate arrays. Automatically transposes and flattens the coordinate arrays into a single matrix for use in the KD-Tree classes. All other keyword arguments are passed to the KD-Tree class. If installed, package ``pykdtree`` will be used instead of :class:`scipy.spatial.cKDTree` for better performance. Not all features are available in ``pykdtree`` so if you require the scipy version set ``use_pykdtee=False``. Parameters ---------- coordinates : tuple of arrays Arrays with the coordinates of each data point. Should be in the following order: (easting, northing, vertical, ...). All coordinate arrays are used. use_pykdtree : bool If True, will prefer ``pykdtree`` (if installed) over :class:`scipy.spatial.cKDTree`. Otherwise, always use the scipy version. Returns ------- tree : :class:`scipy.spatial.cKDTree` or ``pykdtree.kdtree.KDTree`` The tree instance initialized with the given coordinates and arguments. """ points = np.transpose(n_1d_arrays(coordinates, len(coordinates))) if pyKDTree is not None and use_pykdtree: tree = pyKDTree(points, **kwargs) else: tree = cKDTree(points, **kwargs) return tree
def skeletonize_mesh(mesh, soma_pt=None, soma_radius=7500, collapse_soma=True, invalidation_d=12000, smooth_vertices=False, compute_radius=True, compute_original_index=True, verbose=True): ''' Build skeleton object from mesh skeletonization Parameters ---------- mesh: meshparty.trimesh_io.Mesh the mesh to skeletonize, defaults assume vertices in nm soma_pt: np.array a length 3 array specifying to soma location to make the root default=None, in which case a heuristic root will be chosen in units of mesh vertices. soma_radius: float distance in mesh vertex units over which to consider mesh vertices close to soma_pt to belong to soma these vertices will automatically be invalidated and no skeleton branches will attempt to reach them. This distance will also be used to collapse all skeleton points within this distance to the soma_pt root if collpase_soma is true. (default=7500 (nm)) collapse_soma: bool whether to collapse the skeleton around the soma point (default True) invalidation_d: float the distance along the mesh to invalidate when applying TEASAR like algorithm. Controls how detailed a structure the skeleton algorithm reaches. default (12000 (nm)) smooth_vertices: bool whether to smooth the vertices of the skeleton compute_radius: bool whether to calculate the radius of the skeleton at each point on the skeleton (default True) compute_original_index: bool whether to calculate how each of the mesh nodes maps onto the skeleton (default True) verbose: bool whether to print verbose logging Returns ------- :obj:`meshparty.skeleton.Skeleton` a Skeleton object for this mesh ''' skel_verts, skel_edges, smooth_verts, orig_skel_index, skel_map = calculate_skeleton_paths_on_mesh( mesh, soma_pt=soma_pt, soma_thresh=soma_radius, invalidation_d=invalidation_d, return_map=True) if smooth_vertices is True: skel_verts = smooth_verts if collapse_soma is True and soma_pt is not None: soma_verts = mesh_filters.filter_spatial_distance_from_points( mesh, [soma_pt], soma_radius) new_v, new_e, new_skel_map, vert_filter, root_ind = collapse_soma_skeleton( soma_pt, skel_verts, skel_edges, soma_d_thresh=soma_radius, mesh_to_skeleton_map=skel_map, soma_mesh_indices=soma_verts, return_filter=True, return_soma_ind=True) else: new_v, new_e, new_skel_map = skel_verts, skel_edges, skel_map vert_filter = np.arange(len(orig_skel_index)) if soma_pt is None: sk_graph = utils.create_csgraph(new_v, new_e) root_ind = utils.find_far_points_graph(sk_graph)[0] else: _, qry_inds = pyKDTree(new_v).query( soma_pt[np.newaxis, :]) # Still try to root close to the soma root_ind = qry_inds[0] skel_map_full_mesh = np.full(mesh.node_mask.shape, -1, dtype=np.int64) skel_map_full_mesh[mesh.node_mask] = new_skel_map ind_to_fix = mesh.map_boolean_to_unmasked(np.isnan(new_skel_map)) skel_map_full_mesh[ind_to_fix] = -1 props = {} if compute_original_index is True: props['mesh_index'] = np.append( mesh.map_indices_to_unmasked(orig_skel_index[vert_filter]), -1) if compute_radius is True: rs = ray_trace_distance(orig_skel_index[vert_filter], mesh) rs = np.append(rs, soma_radius) props['rs'] = rs sk = Skeleton(new_v, new_e, mesh_to_skel_map=skel_map_full_mesh, vertex_properties=props, root=root_ind) return sk
def pykdtree(self): """ pykdtree.pyKDTree object : k-D tree from pykdtree (a bit faster but fewer functions) """ if self._pykdtree is None: self._pykdtree = pyKDTree(self.vertices) return self._pykdtree
def pykdtree(self): if self._pykdtree is None: self._pykdtree = pyKDTree(self.vertices) return self._pykdtree