def _GetPlanes(self, pdipts): try: # sklearn's KDTree is faster: use it if available from sklearn.neighbors import KDTree as Tree except: from scipy.spatial import cKDTree as Tree if self.GetNumberOfSlices() == 0: return [] # Get the Points over the NumPy interface wpdi = dsa.WrapDataObject(pdipts) # NumPy wrapped points points = np.array( wpdi.Points) # New NumPy array of points so we dont destroy input numPoints = pdipts.GetNumberOfPoints() if self.__useNearestNbr: tree = Tree(points) ptsi = tree.query([points[0]], k=numPoints)[1].ravel() else: ptsi = [i for i in range(numPoints)] # Iterate of points in order (skips last point): planes = [] for i in range(0, numPoints - 1, numPoints // self.GetNumberOfSlices()): # get normal pts1 = points[ptsi[i]] pts2 = points[ptsi[i + 1]] x1, y1, z1 = pts1[0], pts1[1], pts1[2] x2, y2, z2 = pts2[0], pts2[1], pts2[2] normal = [x2 - x1, y2 - y1, z2 - z1] # create plane plane = self._GeneratePlane([x1, y1, z1], normal) planes.append(plane) return planes
def _fix_to_topography(topo_points, points_to_update, static=20.0): """Update the z component of points to force them to lie on a topo surface""" tree = Tree(topo_points) ind = tree.query(points_to_update, k=1)[1].ravel() # Now update the elevation to be on the topo surface # Also shift it so its always just above the surface and not in the surface points_to_update[:,2] = topo_points[:,2][ind] + static return points_to_update
def _query(topoPts, dataPts): try: # sklearn's KDTree is faster: use it if available from sklearn.neighbors import KDTree as Tree except: from scipy.spatial import cKDTree as Tree tree = Tree(topoPts) i = tree.query(dataPts)[1].ravel() return topoPts[i]
def _query(topo_points, data_points): """Querrys the data points for their closest point on the topography surface""" try: # sklearn's KDTree is faster: use it if available from sklearn.neighbors import KDTree as Tree except ImportError: from scipy.spatial import cKDTree as Tree tree = Tree(topo_points) i = tree.query(data_points)[1].ravel() return topo_points[i]
def _EstimateAngleAndSpacing(self, pts, sample=.5): """internal use only """ try: # sklearn's KDTree is faster: use it if available from sklearn.neighbors import KDTree as Tree except: from scipy.spatial import cKDTree as Tree # Creat the indexing range for searching the points: num = len(pts) rng = np.linspace(0, num - 1, num=num, dtype=int) N = int(num * sample) + 1 rng = np.random.choice(rng, N) angles = np.zeros(len(rng)) tree = Tree(pts) distances = [[], []] ####################################################################### ####################################################################### # Find nearest point distall, ptsiall = tree.query(pts, k=2) pt1all, pt2all = pts[ptsiall[:, 0]], pts[ptsiall[:, 1]] ####################################################################### idx = 0 for i in rng: # OPTIMIZE ax, angles[idx], dist = self._ConvergeAngle(pt1all[i], pt2all[i]) distances[ax].append(dist) idx += 1 ####################################################################### #TODO??? angles, distances = self._ConvergeAngle(pt1all, pt2all) ####################################################################### ####################################################################### dx, dy = distances[0], distances[1] if len(dx) == 0: dx = dy elif len(dy) == 0: dy = dx TOLERANCE = np.min(np.append(dx, dy)) / 2.0 angle = np.average(np.unique(angles)) dx = np.unique(np.around(dx / TOLERANCE)) * TOLERANCE dy = np.unique(np.around(dy / TOLERANCE)) * TOLERANCE # Now round to decimals dx = np.around(dx, self.DECIMALS) dy = np.around(dx, self.DECIMALS) # print('Recovered: ', dx, dy) return angle, dx[0], dy[0]
def _find_min_path(points): try: # sklearn's KDTree is faster: use it if available from sklearn.neighbors import KDTree as Tree except ImportError: from scipy.spatial import cKDTree as Tree _compute_dist = lambda pt0, pt1: np.linalg.norm(pt0-pt1) ind, min_dist = None, np.inf tree = Tree(points) for pt in points: cur_ind = tree.query([pt], k=len(points))[1].ravel() dist = 0. for i in range(len(cur_ind)-1): dist += _compute_dist(points[cur_ind[i]], points[cur_ind[i+1]]) if dist < min_dist: ind = cur_ind min_dist = dist return ind.ravel()
def compute_D_I(A, B, k=None, r=None, parallel=True, query_radius=False): """Compute the distances (D) and the IDs of the neighbors (I) between the set of vectors A and the set of vectors B, considering just k neighbors or the neighbors within radius r. This computation is based on the use of a Tree, e.g. KDTree, BallTree. """ global joblib_available global tree print("Computing the tree (size=%s)." % B.shape[0]) t0 = time() tree = Tree(B) print("%s sec" % (time()-t0)) print("Computing %s NN queries, each for %s neighbors." % (A.shape[0], k)) t0 = time() if joblib_available and parallel: D, I = tree_parallel_query(tree, A, k=k, r=r, query_radius=query_radius) else: if query_radius: D, I = tree.query_radius(A, r=r, return_distance=True) else: D, I = tree.query(A, k=k) print("%s sec" % (time()-t0)) return D, I
def _ConnectCells(self, pdi, pdo, logTime=False): """Internal helper to perfrom the connection """ # NOTE: Type map is specified in vtkCellType.h cellType = self.__cellType nrNbr = self.__usenbr if logTime: startTime = datetime.now() # Get the Points over the NumPy interface wpdi = dsa.WrapDataObject(pdi) # NumPy wrapped input points = np.array( wpdi.Points) # New NumPy array of poins so we dont destroy input if self.__unique: # Remove repeated points points = np.unique(points, axis=0) def _makePolyCell(ptsi): cell = vtk.vtkPolyLine() cell.GetPointIds().SetNumberOfIds(len(ptsi)) for i in ptsi: cell.GetPointIds().SetId(i, ptsi[i]) return cell def _makeLineCell(ptsi): if len(ptsi) != 2: raise _helpers.PVGeoError( '_makeLineCell() only handles two points') aLine = vtk.vtkLine() aLine.GetPointIds().SetId(0, ptsi[0]) aLine.GetPointIds().SetId(1, ptsi[1]) return aLine cells = vtk.vtkCellArray() numPoints = pdi.GetNumberOfPoints() if nrNbr: try: # sklearn's KDTree is faster: use it if available from sklearn.neighbors import KDTree as Tree except: from scipy.spatial import cKDTree as Tree # VTK_Line og = np.array([0.0, 0.0, 0.0]).reshape(1, -1) if cellType == vtk.VTK_LINE: tree = Tree(points) ind = tree.query(og, k=numPoints)[1].ravel() for i in range(len(ind) - 1): # Get indices of k nearest points ptsi = [ind[i], ind[i + 1]] cell = _makeLineCell(ptsi) cells.InsertNextCell(cell) points = np.delete(points, 0, 0) # Deletes first row # VTK_PolyLine elif cellType == vtk.VTK_POLY_LINE: tree = Tree(points) ptsi = tree.query(og, k=numPoints)[1].ravel() cell = _makePolyCell(ptsi.ravel()) cells.InsertNextCell(cell) else: raise _helpers.PVGeoError('Cell Type %d not ye implemented.' % cellType) else: # VTK_PolyLine if cellType == vtk.VTK_POLY_LINE: ptsi = [i for i in range(numPoints)] cell = _makePolyCell(ptsi) cells.InsertNextCell(cell) # VTK_Line elif cellType == vtk.VTK_LINE: for i in range(0, numPoints - 1): ptsi = [i, i + 1] cell = _makeLineCell(ptsi) cells.InsertNextCell(cell) else: raise _helpers.PVGeoError('Cell Type %d not ye implemented.' % cellType) if logTime: print((datetime.now() - startTime)) # Now add points and cells to output pdo.SetPoints(pdi.GetPoints()) pdo.SetLines(cells) # copy point data _helpers.copyArraysToPointData(pdi, pdo, 0) # 0 is point data # Copy cell data if type is LINE if cellType == vtk.VTK_LINE: # Be sure to rearange for Nearest neighbor approxiamtion for i in range(pdi.GetCellData().GetNumberOfArrays()): vtkarr = pdi.GetCellData().GetArray(i) name = vtkarr.GetName() if nrNbr: arr = interface.convertArray(vtkarr) arr = arr[ind] vtkarr = interface.convertArray(arr, name=name) pdo.GetCellData().AddArray(vtkarr) return pdo