def show_hull(cname, ccol): ccoords = coords[names==cname] hull = ConvexHull(ccoords) xs = ccoords.ix[:,0] ys = ccoords.ix[:,1] zs = ccoords.ix[:,2] #ax.scatter(xs, ys, zs, c=ccol, marker='o') for simplex in hull.simplices: s = ccoords.irow(simplex) #print s sx = list(s.ix[:,0]) sy = list(s.ix[:,1]) sz = list(s.ix[:,2]) sx.append(sx[0]) sy.append(sy[0]) sz.append(sz[0]) ax.plot(sx, sy, sz, ccol, alpha=0.2) hulld = Delaunay(ccoords.irow(hull.vertices)) hulld.find_simplex(coords) hcol = ['grey' if x<0 else 'green' for x in hulld.find_simplex(coords)] hxs = coords.ix[:,0] hys = coords.ix[:,1] hzs = coords.ix[:,2] ax.scatter(hxs, hys, hzs, c=hcol, marker='o', alpha=0.2)
def zonotope_quadrature_rule(avmap, N, NX=10000): """ Description of zonotope_quadrature_rule Arguments: vert: W1: N: NX: (default=10000) Outputs: points: weights: """ vert = avmap.domain.vertY W1 = avmap.domain.subspaces.W1 # number of dimensions m, n = W1.shape # points y = np.vstack((vert, maximin_design(vert, N))) T = Delaunay(y) c = [] for t in T.simplices: c.append(np.mean(T.points[t], axis=0)) points = np.array(c) # approximate weights Y_samples = np.dot(np.random.uniform(-1.0, 1.0, size=(NX,m)), W1) I = T.find_simplex(Y_samples) weights = np.zeros((T.nsimplex, 1)) for i in range(T.nsimplex): weights[i] = np.sum(I==i) / float(NX) return points.reshape((T.nsimplex,n)), weights.reshape((T.nsimplex,1))
def compute(self): """ABC API""" Delaunay.__init__(self, self._points, self._furthest_site, self._incremental, self._qhull_options)
def __init__(self, target_image_dimensions, target_vertices=None): self.target_image_dimensions = target_image_dimensions # if target vertices are not set, assume we want to fill the entire targetImage if not target_vertices: rows, columns = target_image_dimensions[:2] self.target_vertices = np.array([[0, 0], [0, columns], [rows, 0], [rows, columns]]) else: self.target_vertices = target_vertices r0, c0 = np.round(np.mean(self.target_vertices, axis=0)).astype(np.int32) self.target_vertices = np.array(sorted(self.target_vertices, key=lambda (r, c): np.arctan2(r0 - r, c0 - c))) # get barycentric coordinates and corresponding points in target (new) image nys = np.arange(self.target_image_dimensions[0]) nxs = np.arange(self.target_image_dimensions[1]) image_pixels = np.transpose([np.repeat(nys, len(nxs)), np.tile(nxs, len(nys))]) triangles = Delaunay(self.target_vertices) memberships = triangles.find_simplex(image_pixels) # returns the triangle that each pixel is a member of Ts = triangles.transform[memberships, :2] # transformation matrices prs = image_pixels - triangles.transform[memberships, 2] # intermediate transformation barycentric_coordinates = np.array([Ts[i].dot(pr) for i, pr in enumerate(prs)]) barycentric_coordinates = np.hstack((barycentric_coordinates, 1 - np.sum(barycentric_coordinates, axis=1, keepdims=True))) target_vertices_indices = triangles.simplices[memberships] self.targetRow = image_pixels[:, 0] self.targetCol = image_pixels[:, 1] self.barycentric = barycentric_coordinates self.indices = target_vertices_indices
def draw_dimension(self, dimNumber): ''' Method to draw the points on the axes using the current dimension number ''' self.ax.cla() dim0 = self.combinations[self.dimNumber][0] dim1 = self.combinations[self.dimNumber][1] self.ax.plot(self.points[:,dim0][self.inCluster], self.points[:, dim1][self.inCluster], 'g.') self.ax.plot(self.points[:, dim0][self.outsideCluster], self.points[:,dim1][self.outsideCluster], marker='.', color='0.8', linestyle='None') self.ax.set_xlabel('Dimension {}'.format(dim0)) self.ax.set_ylabel('Dimension {}'.format(dim1)) plt.title('press c to cut, < or > to switch dimensions') self.fig.canvas.draw() ''' Method to take the current points from mouse input, convert them to a convex hull, and then update the inCluster and outsideCluster attributes based on the points that fall within the hull''' if not isinstance(hull, Delaunay): hull=Delaunay(hull) self.inCluster = hull.find_simplex(points)>=0 self.outsideCluster=np.logical_not(self.inCluster)
def _simplex_interp(self, teff, logg, fe, model_indecies): """ Perform barycentric interpolation on simplecies Args: teff (float): effective temperature logg (float): surface gravity fe (float): metalicity model_indecies (array): models to use in the interpolation Returns: array: spectrum at teff, logg, fe """ ndim = 3 model_table = np.array(self.model_table['teff logg fe'.split()]) points = model_table[model_indecies] tri = Delaunay(points) # Delaunay triangulation p = np.array([teff, logg, fe]) # cartesian coordinates simplex = tri.find_simplex(p) r = tri.transform[simplex,ndim,:] Tinv = tri.transform[simplex,:ndim,:ndim] c = Tinv.dot(p - r) c = np.hstack([c,1.0-c.sum()]) # barycentric coordinates # (3,many array) model_indecies_interp = model_indecies[tri.simplices[simplex]] model_spectra = self.model_spectra[model_indecies_interp,:] flux = np.dot(c,model_spectra) if simplex==-1: return np.ones_like(flux) return flux
def triangulate(self, size): shape = self.mImg.shape spacing = max(shape) / size sigma = spacing / 4 coords = self._get_distributed_points(spacing, sigma, include_corners = True) tri = Delaunay(coords) im_pts = self.get_xy_features() # pt_tri_membership becomes a map which is the same size as the # original image (first two dimensions only). each element contains # the triangle ID of that point in the source image pt_tri_membership = tri.find_simplex(im_pts.astype(dtype = np.double)) pt_tri_membership.resize(shape[0], shape[1]) num_tri = np.max(pt_tri_membership) tri_map = np.copy(self.mImg) # replace elements of each triangle with the mean value of the color # channels from the original image for tri in range(num_tri + 1): this_tri = pt_tri_membership == tri if not np.any(this_tri): continue for col in range(shape[2]): tri_map[this_tri, col] = np.mean(self.mImg[this_tri, col]) return tri_map
def compute(self): """ABC API""" self.id = "D({},{})".format(self._furthest_site, self._qhull_options) Delaunay.__init__(self, self._points, self._furthest_site, self._incremental, self._qhull_options)
def inside_convex_poly(pts): """Returns a function that checks if inputs are inside the convex hull of polyhedron defined by pts Alternative method to check is to get faces of the convex hull, then check if each normal is pointed away from each point. As it turns out, this is vastly slower than using qhull's find_simplex, even though the simplex is not needed. """ tri = Delaunay(pts) return lambda x: tri.find_simplex(x) != -1
def chromaticity_diagram_visual( samples=256, cmfs='CIE 1931 2 Degree Standard Observer', transformation='CIE 1931', parent=None): """ Creates a chromaticity diagram visual based on :class:`colour_analysis.visuals.Primitive` class. Parameters ---------- samples : int, optional Inner samples count used to construct the chromaticity diagram triangulation. cmfs : unicode, optional Standard observer colour matching functions used for the chromaticity diagram boundaries. transformation : unicode, optional {'CIE 1931', 'CIE 1960 UCS', 'CIE 1976 UCS'} Chromaticity diagram transformation. parent : Node, optional Parent of the chromaticity diagram in the `SceneGraph`. Returns ------- Primitive Chromaticity diagram visual. """ cmfs = get_cmfs(cmfs) illuminant = DEFAULT_PLOTTING_ILLUMINANT XYZ_to_ij = ( CHROMATICITY_DIAGRAM_TRANSFORMATIONS[transformation]['XYZ_to_ij']) ij_to_XYZ = ( CHROMATICITY_DIAGRAM_TRANSFORMATIONS[transformation]['ij_to_XYZ']) ij_c = XYZ_to_ij(cmfs.values, illuminant) triangulation = Delaunay(ij_c, qhull_options='QJ') samples = np.linspace(0, 1, samples) ii, jj = np.meshgrid(samples, samples) ij = tstack((ii, jj)) ij = np.vstack((ij_c, ij[triangulation.find_simplex(ij) > 0])) ij_p = np.hstack((ij, np.full((ij.shape[0], 1), 0))) triangulation = Delaunay(ij, qhull_options='QJ') RGB = normalise(XYZ_to_sRGB(ij_to_XYZ(ij, illuminant), illuminant), axis=-1) diagram = Primitive(vertices=ij_p, faces=triangulation.simplices, vertex_colours=RGB, parent=parent) return diagram
def interp_weights(xyz, uvw,d=3): tri = Delaunay(xyz) simplex = tri.find_simplex(uvw) vertices = np.take(tri.simplices, simplex, axis=0) temp = np.take(tri.transform, simplex, axis=0) delta = uvw - temp[:, d] bary = np.einsum('njk,nk->nj', temp[:, :d, :], delta) return vertices, np.hstack((bary, 1 - bary.sum(axis=1, keepdims=True)))
def hadrian_min(vectorized_f, xbnds, ybnds, xtol, ytol, swarm=8, mx_iters=5, inc=False): """ hadrian_min is a stochastic, hill climbing minimization algorithm. It uses a stratified sampling technique (Latin Hypercube) to get good coverage of potential new points. It also uses vectorized function evaluations to drive concurrent function evaluations. It is named after the Roman Emperor Hadrian, the most famous Latin hill mountain climber of ancient times. """ assert xbnds[1] > xbnds[0] assert ybnds[1] > ybnds[0] assert xtol > 0 assert ytol > 0 # simplexes are simplex indexes # vertexes are vertex indexes # points are spatial coordinates bnds = np.vstack((xbnds, ybnds)) points = latin_sample(np.vstack((xbnds, ybnds)), swarm) z = vectorized_f(points) # exclude corners from possibilities, but add them to the triangulation # this bounds the domain, but ensures they don't get picked points = np.append(points, list(product(xbnds, ybnds)), axis=0) z = np.append(z, 4*[z.max()]) tri = Delaunay(points, incremental=inc) del points for step in range(1, mx_iters+1): i, vertexes = get_minimum_neighbors(tri, z) disp = tri.points[i] - tri.points[np.unique(vertexes)] disp /= np.array([xtol, ytol]) err = err_mean(disp) if err < 1.: return tri.points[i], z[i], tri.points, z, 1 tri_points = tri.points[vertexes] bnds = np.cumsum(area(tri_points)) bnds /= bnds[-1] indx = np.searchsorted(bnds, np.random.rand(swarm)) new_pts = sample_triangle(tri_points[indx]) new_z = vectorized_f(new_pts) if inc: tri.add_points(new_pts) else: # make a new triangulation if I can't append points points = np.append(tri.points, new_pts, axis=0) tri = Delaunay(points) z = np.append(z, new_z) return None, None, tri.points, z, step
def inside_hull(self, labels): """This method checks whether a requested set of labels is inside the convex hull of the training data. Returns a bool. This method relies on Delauynay Triangulation and is thus exceedlingly slow for large dimensionality. """ L = flatten_struct(self.training_labels, use_labels=self.used_labels) l = flatten_struct(labels, use_labels=self.used_labels) hull = Delaunay(L.T) return hull.find_simplex(l.T) >= 0
def cut_cluster(self, points, hull): ''' Method to take the current points from mouse input, convert them to a convex hull, and then update the inCluster and outsideCluster attributes based on the points that fall within the hull''' if not isinstance(hull, Delaunay): hull=Delaunay(hull) self.inCluster = hull.find_simplex(points)>=0 self.outsideCluster=np.logical_not(self.inCluster)
def check_polygon_membership(cluster_boundary, points_to_check): cluster_boundary_points = [[x[0], x[1]] for x in cluster_boundary] hull = cluster_boundary_points if not isinstance(hull, Delaunay): hull = Delaunay(hull) gps_coords_to_check = [[x[0], x[1]] for x in points_to_check] point_in_cluster = [] for coord in gps_coords_to_check: point_in_cluster.append(1 if hull.find_simplex(coord) >= 0 else 0) return point_in_cluster
def in_hull(p, hull): """ Test if points in `p` are in `hull` `p` should be a `NxK` coordinates of `N` points in `K` dimensions `hull` is either a scipy.spatial.Delaunay object or the `MxK` array of the coordinates of `M` points in `K`dimensions for which Delaunay triangulation will be computed """ if not isinstance(hull, Delaunay): hull = Delaunay(hull) return hull.find_simplex(p) >= 0
def zonotope_quadrature_rule(avmap, N, NX=10000): """Quadrature rule on a zonotope. Quadrature when the dimension of the active subspace is greater than 1 and the simulation parameter space is bounded. Parameters ---------- avmap : ActiveVariableMap a domains.ActiveVariableMap N : int the number of quadrature nodes in the active variables NX : int, optional the number of samples to use to estimate the quadrature weights (default 10000) Returns ------- Yp : ndarray quadrature nodes on the active variables Yw : ndarray quadrature weights on the active variables See Also -------- integrals.quadrature_rule """ vert = avmap.domain.vertY W1 = avmap.domain.subspaces.W1 # number of dimensions m, n = W1.shape # points y = np.vstack((vert, maximin_design(vert, N))) T = Delaunay(y) c = [] for t in T.simplices: c.append(np.mean(T.points[t], axis=0)) points = np.array(c) # approximate weights Y_samples = np.dot(np.random.uniform(-1.0, 1.0, size=(NX,m)), W1) I = T.find_simplex(Y_samples) weights = np.zeros((T.nsimplex, 1)) for i in range(T.nsimplex): weights[i] = np.sum(I==i) / float(NX) Yp, Yw = points.reshape((T.nsimplex,n)), weights.reshape((T.nsimplex,1)) return Yp, Yw
def remove_c3k_inside(self): """Returns a boolean array of same length as secondary describing whether that element of secondary is outside the hull formed by primary """ c3k = self.training_labels['miles_id'] == 'c3k' miles = ~c3k L = flatten_struct(self.training_labels[miles], use_labels=self.used_labels) l = flatten_struct(self.training_labels[c3k], use_labels=self.used_labels) hull = Delaunay(L.T) inside = hull.find_simplex(l.T) >= 0 #inside = self.inside_hull(self.training_labels[c3k]) bad = self.training_indices[c3k][inside] self.leave_out(bad) return bad
def test_find_nn_triangles_point(): r"""Test find natural neighbors for a point function.""" x = list(range(10)) y = list(range(10)) gx, gy = np.meshgrid(x, y) pts = np.vstack([gx.ravel(), gy.ravel()]).T tri = Delaunay(pts) tri_match = tri.find_simplex([4.5, 4.5]) truth = [62, 63] nn = find_nn_triangles_point(tri, tri_match, [4.5, 4.5]) assert_array_almost_equal(truth, nn)
def inConvexHull(dictionary, mx, my): """ Check if (mx,my) point is in the data dictionary. """ import numpy from scipy.spatial import Delaunay pointlist = [] for k in dictionary.keys(): for ki in dictionary[k].keys(): pointlist.append([k, ki]) p = numpy.array(pointlist) dela = Delaunay(p) return dela.find_simplex((mx, my)) >= 0
def lle(self,ndim=2,nk=None, length_nsigma=2.0): """Embed the PSFs onto an ndim dimensional space Parameters ---------- ndim: int Number of LLE dimensions nk: int Number of nearest neighbors to check. """ self.ndim=ndim #The following if not nk: nk = int(1.5*np.sqrt(self.psf_fts_vect.shape[0])) self.nk = nk self.lle_proj = mdp.nodes.LLENode(nk,output_dim=ndim,verbose=True)(self.psf_fts_vect) lengths = np.empty(ndim) for d in range(ndim): one_sigmas = np.percentile(self.lle_proj[:,d],[16,84]) lengths[d] = length_nsigma*(one_sigmas[1]-one_sigmas[0]) print("Axis lengths: " + str(lengths) ) self.h_density = (np.prod(lengths)/self.lle_proj.shape[0])**(1.0/ndim) self.tri = Delaunay(self.lle_proj) self.point_lengths = np.sum(self.tri.points**2,1)
def triangle_weights(self, knearest, **params): """Triangulate the k-nearest models, then use the barycenter of the enclosing simplex to interpolate. """ inparams = np.array([params[p] for p in self.stellar_pars]) dtri = Delaunay(self.model_points[knearest, :]) triangle_ind = dtri.find_simplex(inparams) inds = dtri.simplices[triangle_ind, :] transform = dtri.transform[triangle_ind, :, :] Tinv = transform[:self.ndim, :] x_r = inparams - transform[self.ndim, :] bary = np.dot(Tinv, x_r) last = 1.0 - bary.sum() wghts = np.append(bary, last) oo = inds.argsort() return inds[oo], wghts[oo]
def feasible_illuminance(self, illuminance_transfer_matrix, num_points): from scipy.spatial import Delaunay max_illuminance = np.sum(illuminance_transfer_matrix, axis=1) illuminance_set = np.meshgrid(*[np.linspace(i, j, num_points) for i, j in zip(np.zeros((self.num_user, 1)), max_illuminance)]) for i in range(self.num_user): illuminance_set[i] = illuminance_set[i].reshape((illuminance_set[i].size, 1)) illuminance_set = np.hstack(illuminance_set) d = [] for num in range(2 ** self.num_LED): d.append(list(bin(num)[2:].zfill(self.num_LED))) d = np.array(d, dtype=float).T x = np.dot(illuminance_transfer_matrix, d).T hull = Delaunay(x) in_hull = hull.find_simplex(illuminance_set) >= 0 illuminance_set = illuminance_set[in_hull, :] return illuminance_set
def is_within_mesh_volume(points, mesh, tolerance=None): """ Returns if given points are within given mesh volume using Delaunay triangulation. Parameters ---------- points : array_like Points to check if they are within `mesh` volume. mesh : array_like Points of the volume used to generate the Delaunay triangulation. tolerance : numeric, optional Tolerance allowed in the inside-triangle check. Returns ------- bool Is within mesh volume. Notes ----- - This definition requires *scipy* to be installed. Examples -------- >>> mesh = np.array([[-1.0, -1.0, 1.0], ... [1.0, -1.0, 1.0], ... [1.0, -1.0, -1.0], ... [-1.0, -1.0, -1.0], ... [0.0, 1.0, 0.0]]) >>> is_within_mesh_volume(np.array([0.0005, 0.0031, 0.0010]), mesh) array(True, dtype=bool) >>> a = np.array([[0.0005, 0.0031, 0.0010], ... [0.3205, 0.4131, 0.5100]]) >>> is_within_mesh_volume(a, mesh) array([ True, False], dtype=bool) """ if is_scipy_installed(raise_exception=True): from scipy.spatial import Delaunay triangulation = Delaunay(mesh) simplex = triangulation.find_simplex(points, tol=tolerance) simplex = np.where(simplex >= 0, True, False) return simplex
def test_find_local_boundary(): r"""Test find edges of natural neighbor triangle group function.""" x = list(range(10)) y = list(range(10)) gx, gy = np.meshgrid(x, y) pts = np.vstack([gx.ravel(), gy.ravel()]).T tri = Delaunay(pts) tri_match = tri.find_simplex([4.5, 4.5]) nn = find_nn_triangles_point(tri, tri_match, [4.5, 4.5]) edges = find_local_boundary(tri, nn) truth = [(45, 55), (44, 45), (55, 54), (54, 44)] assert_array_almost_equal(truth, edges)
def Interpolate(paneldata, x, y): cord = np.array([x,y]) n = len(paneldata) tri = Delaunay(paneldata) triangleindex = tri.find_simplex(cord) intercords = tri.simplices[triangleindex] index1 = np.empty(2) index2 = np.empty(2) index3 = np.empty(2) if triangleindex >= 0: index1[0] = intercords[0] index2[0] = intercords[1] index3[0] = intercords[2] x1 = tri.points[intercords[0]][0] y1 = tri.points[intercords[0]][1] x2 = tri.points[intercords[1]][0] y2 = tri.points[intercords[1]][1] x3 = tri.points[intercords[2]][0] y3 = tri.points[intercords[2]][1] index1[1] = ((y2 - y3) * (x - x3) + (x3 - x2) * (y - y3)) / ((y2 - y3) * (x1 - x3) + (x3 - x2) * (y1 - y3)) index2[1] = ((y3 - y1) * (x - x3) + (x1 - x3) * (y - y3)) / ((y2 - y3) * (x1 - x3) + (x3 - x2) * (y1 - y3)) index3[1] = 1 - index1[1] - index2[1] else: index1[0] = -1 index1[1] = 10000000 index2[0] = -1 index2[1] = 10000000 index3[0] = 1 index3[1] = 0 distance = np.empty(n) for i in range(n): distance[i] = np.linalg.norm(np.subtract(cord, paneldata[i])) if distance[i] < index1[1]: index2[0] = index1[0] index2[1] = index1[1] index1[0] = i index1[1] = distance[i] elif distance[i] < index2[1]: index2[0] = i index2[1] = distance[i] base = index1[1] + index2[1] index1[1] /= base index2[1] /= base ans = np.array([index1, index2, index3]) return ans
def in_hull(self, p, hull): """ Test if point `p` is in `hull` `p` should be a `NxK` coordinates of `N` points in `K` dimensions `hull` is either a scipy.spatial.Delaunay object or the `MxK` array of the coordinates of `M` points in `K`dimensions for which Delaunay triangulation will be computed """ q = np.array([p]) if not isinstance(hull,Delaunay): try: hull = Delaunay(hull) except scipy.spatial.qhull.QhullError: return False return hull.find_simplex(q)>=0
def __init__(self, is_target, image_dimensions, vertices=None): self.image_dimensions = image_dimensions # if vertices are not set, assume we want to use the entire image if vertices is None: rows, columns = image_dimensions[:2] self.vertices = np.array([[0, 0], [0, columns - 1], [rows - 1, 0], [rows - 1, columns - 1]]) else: self.vertices = vertices.reshape((-1, 2)) r0, c0 = np.mean(self.vertices, axis=0).astype(np.int32) self.vertices = np.array(sorted(self.vertices, key=lambda (r, c): np.arctan2(r0 - r, c0 - c))) # get barycentric coordinates and corresponding points in target (new) image nys = np.arange(self.image_dimensions[0]) nxs = np.arange(self.image_dimensions[1]) image_pixels = np.transpose([np.repeat(nys, len(nxs)), np.tile(nxs, len(nys))]) image_pixels = np.array(image_pixels) triangles = Delaunay(self.vertices) # code below is abbout 0.01 s memberships = triangles.find_simplex(image_pixels) # returns the triangle that each pixel is a member of Ts = triangles.transform[memberships, :2] # transformation matrices prs = image_pixels - triangles.transform[memberships, 2] # intermediate transformation # code below is almost 1 s bl = Ts[:, 0, 0] * prs[:, 0] + Ts[:, 0, 1] * prs[:, 1] br = Ts[:, 1, 0] * prs[:, 0] + Ts[:, 1, 1] * prs[:, 1] barycentric_coordinates = np.hstack((bl.reshape((-1, 1)), br.reshape((-1, 1)))) barycentric_coordinates = np.hstack((barycentric_coordinates, 1 - np.sum(barycentric_coordinates, axis=1, keepdims=True))) target_vertices_indices = triangles.simplices[memberships] self.is_target = is_target self.rows = image_pixels[:, 0] self.cols = image_pixels[:, 1] self.barycentric = barycentric_coordinates self.indices = target_vertices_indices
def is_within_mesh_volume(points, mesh, tolerance=None): """ Returns if given points are within given mesh volume using Delaunay triangulation. Parameters ---------- points : array_like Points to check if they are within ``mesh`` volume. mesh : array_like Points of the volume used to generate the Delaunay triangulation. tolerance : numeric, optional Tolerance allowed in the inside-triangle check. Returns ------- bool Is within mesh volume. Examples -------- >>> mesh = np.array( ... [[-1.0, -1.0, 1.0], ... [1.0, -1.0, 1.0], ... [1.0, -1.0, -1.0], ... [-1.0, -1.0, -1.0], ... [0.0, 1.0, 0.0]] ... ) >>> is_within_mesh_volume(np.array([0.0005, 0.0031, 0.0010]), mesh) array(True, dtype=bool) >>> a = np.array([[0.0005, 0.0031, 0.0010], ... [0.3205, 0.4131, 0.5100]]) >>> is_within_mesh_volume(a, mesh) array([ True, False], dtype=bool) """ triangulation = Delaunay(mesh) simplex = triangulation.find_simplex(points, tol=tolerance) simplex = np.where(simplex >= 0, True, False) return simplex
def __init__(self,points,area,labels): Environment.__init__(self) self.area = area self.area_hull = Delaunay(area) self.points = points self.regions = labels self.get_voronoi() self.build_color_map() self.build_reachable_set()
newdata = [] zdata = [] cdata = [] for i in range(norminput.count_y): for j in range(norminput.count_x): zdata.append(norminput.data[j][i][0]) cdata.append(norminput.data[j][i][1]) newdata.append(j) newdata.append(i) print(norminput.count_x) print("Delaunay 処理中(多少時間がかかります)") pts = np.array(newdata).reshape(-1, 2) ztmp = np.array(zdata) tri = Delaunay(pts) newdata = pts.tolist() temp_len = len(newdata) for i in range(temp_len): newdata[i].append(zdata[i]) pts = np.array(newdata) fig = plt.figure() print("Delaunay 処理完了 (len(pts)=", len(pts), "), (len(pts[tri.simplices])=", len(pts[tri.simplices]), ")") #出力 filename_o = "output" outfile = open(filename_o + '.wrl', 'w') print(filename_o + ".wrl として出力中...") start = '#VRML V2.0 utf8\n'
def readgrid(grid_filename, proj, vert_filename=None, usespherical=True): """ readgrid(loc) Kristen Thyng, March 2013 This function should be read in at the beginnind of a run.py call. It reads in all necessary grid information that won't change in time and stores it in a dictionary called grid. All arrays are changed to Fortran ordering (from Python ordering) and to tracmass variables ordering from ROMS ordering i.e. from [t,k,j,i] to [i,j,k,t] right away after reading in. Args: grid_filename: File name (with extension) where grid information is stored vert_filename (optional): File name (with extension) where vertical grid information is stored, if not in grid_loc. Can also skip this if don't need vertical grid info. also optional prjection box parameters. Default is None. proj: Projection object. usespherical: Use spherical geometric coordinates (lat/lon) or not. Returns: * grid - Dictionary containing all necessary time-independent grid fields grid dictionary contains: (array sizing is for tracmass ordering) * imt,jmt,km: Grid index sizing constants in (x,y,z), are for horizontal rho grid [scalar] * dxv: Horizontal grid cell walls areas in x direction [imt,jmt-1] * dyu: Horizontal grid cell walls areas in y direction [imt-1,jmt] * dxdy: Horizontal area of cells defined at cell centers [imt,jmt] * mask: Land/sea mask [imt,jmt] * pm,pn: Difference in horizontal grid spacing in x and y [imt,jmt] * kmt: Number of vertical levels in horizontal space [imt,jmt] * dzt0: Thickness in meters of grid at each k-level with time-independent free surface. Surface is at km [imt,jmt,km]. * zrt0: Depth in meters of grid at each k-level on vertical rho grid with time-independent free surface. Surface is at km [imt,jmt,km] * zwt0: Depth in meters of grid at each k-level on vertical w grid with time-independent free surface. Surface is at km [imt,jmt,km] * xr, yr: Rho grid zonal (x) and meriodional (y) coordinates [imt,jmt] * xu, yu: U grid zonal (x) and meriodional (y) coordinates [imt,jmt] * xv, yv: V grid zonal (x) and meriodional (y) coordinates [imt,jmt] * xpsi, ypsi: Psi grid zonal (x) and meriodional (y) coordinates [imt, jmt] * X, Y: Grid index arrays * tri, trir: Delaunay triangulations * Cs_r, sc_r: Vertical grid streching paramters [km-1] * hc: Critical depth [scalar] * h: Depths [imt,jmt] * theta_s: Vertical stretching parameter [scalar]. A parameter (typically 0.0 <= theta_s < 5.0) that defines the amount of grid focusing. A higher value for theta_s will focus the grid more. * theta_b: Vertical stretching parameter [scalar]. A parameter (0.0 < theta_b < 1.0) that says whether the coordinate will be focused at the surface (theta_b -> 1.0) or split evenly between surface and bottom (theta_b -> 0) * basemap: Basemap object Note: all are in fortran ordering and tracmass ordering except for X, Y, tri, and tric To test: [array].flags['F_CONTIGUOUS'] will return true if it is fortran ordering """ # Read in grid parameters and find x and y in domain on different grids # use full dataset to get grid information gridfile = netCDF.Dataset(grid_filename) if usespherical: try: lon_vert = gridfile.variables['lon_vert'][:] lat_vert = gridfile.variables['lat_vert'][:] except: lon_rho = gridfile.variables['lon_rho'][:] lat_rho = gridfile.variables['lat_rho'][:] x_rho, y_rho = proj(lon_rho, lat_rho) # get vertex locations try: angle = gridfile.variables['angle'][:] except: angle = np.zeros(x_rho.shape) x_vert, y_vert = octant.grid.rho_to_vert( x_rho, y_rho, gridfile.variables['pm'][:], gridfile.variables['pn'][:], angle) lon_vert, lat_vert = proj(x_vert, y_vert, inverse=True) try: mask_rho = gridfile.variables['mask'][:] except: mask_rho = gridfile.variables['mask_rho'][:] grid = octant.grid.CGrid_geo(lon_vert, lat_vert, proj) grid.mask_rho = mask_rho else: # read cartesian data try: x_vert = gridfile.variables['x_vert'][:] y_vert = gridfile.variables['y_vert'][:] except: x_rho = gridfile.variables['x_rho'][:] y_rho = gridfile.variables['y_rho'][:] # get vertex locations try: angle = gridfile.variables['angle'][:] except: angle = np.zeros(x_rho.shape) x_vert, y_vert = octant.grid.rho_to_vert( x_rho, y_rho, gridfile.variables['pm'][:], gridfile.variables['pn'][:], angle) grid = octant.grid.CGrid(x_vert, y_vert) try: mask_rho = gridfile.variables['mask'][:] grid.mask_rho = mask_rho # except KeyError as 'mask': # mask_rho = gridfile.variables['mask_rho'][:] # grid.mask_rho = mask_rho except KeyError: print('No mask.') # Add into grid spherical coord variables so they are avaiable as # expected for the code but set them equal to the projected coords. # Make this better in the future. grid.lon_rho = grid.x_rho grid.lat_rho = grid.y_rho grid.lon_psi = grid.x_psi grid.lat_psi = grid.y_psi grid.lon_u = grid.x_u grid.lat_u = grid.y_u grid.lon_v = grid.x_v grid.lat_v = grid.y_v # vertical grid info if (vert_filename is not None) or ('s_w' in gridfile.variables): if 's_w' in gridfile.variables: # test for presence of vertical info nc = gridfile else: nc = netCDF.Dataset(vert_filename) if 's_w' in nc.variables: grid.sc_r = nc.variables['s_w'][:] # sigma coords, 31 layers else: grid.c_r = nc.variables['sc_w'][:] # sigma coords, 31 layers # stretching curve in sigma coords, 31 layers grid.Cs_r = nc.variables['Cs_w'][:] grid.hc = nc.variables['hc'][:] grid.theta_s = nc.variables['theta_s'][:] grid.theta_b = nc.variables['theta_b'][:] if 'Vtransform' in nc.variables: grid.Vtransform = nc.variables['Vtransform'][:] grid.Vstretching = nc.variables['Vstretching'][:] else: grid.Vtransform = 1 grid.Vstretching = 1 # Basing this on setupgrid.f95 for rutgersNWA example project from Bror grid.h = gridfile.variables['h'][:] # Grid sizes grid.imt = grid.h.shape[1] # 191 grid.jmt = grid.h.shape[0] # 671 if hasattr(grid, 'sc_r'): grid.km = grid.sc_r.shape[0] - 1 # 30 NOT SURE ON THIS ONE YET # Index grid, for interpolation between real and grid space # This is for rho # X goes from 0 to imt-1 and Y goes from 0 to jmt-1 # grid in index coordinates, without ghost cells grid.X, grid.Y = np.meshgrid(np.arange(grid.imt), np.arange(grid.jmt)) # Triangulation for grid space to curvilinear space pts = np.column_stack((grid.X.flatten(), grid.Y.flatten())) tess = Delaunay(pts) grid.tri = mtri.Triangulation(grid.X.flatten(), grid.Y.flatten(), tess.simplices.copy()) # Triangulation for curvilinear space to grid space # Have to use SciPy's Triangulation to be more robust. # http://matveichev.blogspot.com/2014/02/matplotlibs-tricontour-interesting.html if isinstance(grid.x_rho, np.ma.MaskedArray): pts = np.column_stack( (grid.x_rho.data.flatten(), grid.y_rho.data.flatten())) else: pts = np.column_stack((grid.x_rho.flatten(), grid.y_rho.flatten())) tess = Delaunay(pts) grid.trir = mtri.Triangulation(grid.x_rho.flatten(), grid.y_rho.flatten(), tess.simplices.copy()) # For the two triangulations that are not integer based, need to # preprocess the mask to get rid of potential flat triangles at the # boundaries # http://matplotlib.org/1.3.1/api/tri_api.html#matplotlib.tri.TriAnalyzer # Hopefully these will work for other cases too: for the xy spherical # unit test cases, I needed these both for the triangulation to be valid. mask = mtri.TriAnalyzer(grid.trir).get_flat_tri_mask(0.01, rescale=True) grid.trir.set_mask(mask) mask = mtri.TriAnalyzer(grid.trir).get_flat_tri_mask(0.01, rescale=False) grid.trir.set_mask(mask) if isinstance(grid.x_rho, np.ma.MaskedArray): pts = np.column_stack( (grid.lon_rho.data.flatten(), grid.lat_rho.data.flatten())) else: pts = np.column_stack((grid.lon_rho.flatten(), grid.lat_rho.flatten())) tess = Delaunay(pts) grid.trirllrho = mtri.Triangulation(grid.lon_rho.flatten(), grid.lat_rho.flatten(), tess.simplices.copy()) mask = mtri.TriAnalyzer(grid.trirllrho).get_flat_tri_mask(0.01, rescale=True) grid.trirllrho.set_mask(mask) mask = mtri.TriAnalyzer(grid.trirllrho).get_flat_tri_mask(0.01, rescale=False) grid.trirllrho.set_mask(mask) # tracmass ordering. # Not sure how to convert this to pm, pn with appropriate shift grid.dxv = 1 / grid.pm # pm is 1/\Delta x at cell centers grid.dyu = 1 / grid.pn # pn is 1/\Delta y at cell centers grid.dxdy = grid.dyu * grid.dxv # Change dxv,dyu to be correct u and v grid size after having # them be too big for dxdy calculation. This is not in the # rutgersNWA example and I am not sure why. [i,j] grid.dxv = 0.5 * (grid.dxv[:-1, :] + grid.dxv[1:, :]) grid.dyu = 0.5 * (grid.dyu[:, :-1] + grid.dyu[:, 1:]) # Adjust masking according to setupgrid.f95 for rutgersNWA example # project from Bror if hasattr(grid, 'sc_r'): mask2 = grid.mask.copy() grid.kmt = np.ones((grid.jmt, grid.imt)) * grid.km ind = (mask2 == 1) ind[0:grid.jmt - 1, :] = ind[1:grid.jmt, :] mask2[ind] = 1 ind = (mask2 == 1) ind[:, 0:grid.imt - 1] = ind[:, 1:grid.imt] mask2[ind] = 1 ind = (mask2 == 0) grid.kmt[ind] = 0 # Use octant to calculate depths/thicknesses for the appropriate # vertical grid parameters have to transform a few back to ROMS # coordinates and python ordering for this grid.zwt0 = octant.depths.get_zw(grid.Vtransform, grid.Vstretching, grid.km + 1, grid.theta_s, grid.theta_b, grid.h, grid.hc, zeta=0, Hscale=3) grid.zrt0 = octant.depths.get_zrho(grid.Vtransform, grid.Vstretching, grid.km, grid.theta_s, grid.theta_b, grid.h, grid.hc, zeta=0, Hscale=3) # this should be the base grid layer thickness that doesn't change in # time because it is for the reference vertical level grid.dzt0 = grid.zwt0[1:, :, :] - grid.zwt0[:-1, :, :] gridfile.close() return grid
other = set(simplex) other.remove(idx) neighbours[0] = neighbours[0].union(other) return sorted(list(neighbours[0])) def tetrahedron_volume(a, b, c, d): return np.abs(np.einsum('ij,ij->i', a - d, np.cross(b - d, c - d))) / 6 CLR_LINE = " \r" print("creating delaunay") points = np.array(grid.XYZ).T tri = Delaunay(points) tets = tri.points[tri.simplices] #vol = tetrahedron_volume(tets[:, 0], tets[:, 1], # tets[:, 2], tets[:, 3]) vor = Voronoi(points) print("finding all neighbours") neighbours = find_neighbours(tri) sys.stdout.write(CLR_LINE) print("creating convex hull") convex_hull = create_convex_hull_list(tri.convex_hull) sys.stdout.write(CLR_LINE) tri.close()
def distmesh(fd,fh,h0,xmin,ymin,xmax,ymax,pfix,ttol=0.1,dptol=0.001,Iflag=1,qmin=1.0): #Iflag = 0: do not print internal sim status and # do not plot intermediate meshes #Iflag = 1:(default) print internal simulation status only #Iflag = 2: plot intermediate meshes only #Iflag = 3: print internal sim status and plot intermediate meshes #Iflag = 4: prints the Delaunay iteration, minimum q and angle(deg) # Constants geps = 0.001*h0; deltat = 0.2; Fscale = 1.2 deps = h0 * np.sqrt(np.spacing(1)) random_seed = 17 # define the initial number of points in the grid in both directions h0x = h0; h0y = h0*np.sqrt(3)/2 # to obtain equilateral triangles Nx = int(np.floor((xmax - xmin)/h0x)) Ny = int(np.floor((ymax - ymin)/h0y)) x = np.linspace(xmin,xmax,Nx) y = np.linspace(ymin,ymax,Ny) # create the grid in the (x,y) plane xx,yy = np.meshgrid(x,y) # shift the even rows: it will reshape the rectangular grid of points # into a triangular-like grid (see Fig 1). As in many other areas of # optimization, providing a good initial guess helps convergence # into the desired final grid. xx[1::2] = xx[1::2] + h0x/2.0 # shifts even rows by h0x/2 # p: points of the grid p = np.zeros((np.size(xx),2)) p[:,0] = np.reshape(xx,np.size(xx)) p[:,1] = np.reshape(yy,np.size(yy)) # remove points outside the shape boundary with distance > geps p = np.delete(p,np.where(fd(p) > geps),axis=0) # redistribute remaining points according to the weighting function # and then add the fixed points np.random.seed(random_seed) # probability to keep a point: r0 = 1.0/fh(p)**2 p = np.concatenate((pfix,p[np.random.rand(len(p))<r0/max(r0),:])) pold = np.inf Num_of_Delaunay_triangulations = 0 Num_of_Node_movements = 0 # dp = F*dt while (1): Num_of_Node_movements += 1 if Iflag == 1 or Iflag == 3: # Newton flag print ('Num_of_Node_movements = %3d' % (Num_of_Node_movements)) if np.max(np.sqrt(np.sum((p - pold)**2,axis = 1))) > ttol: Num_of_Delaunay_triangulations += 1 if Iflag == 1 or Iflag == 3: # Delaunay flag print ('Num_of_Delaunay_triangulations = %3d' % \ (Num_of_Delaunay_triangulations)) pold = p tri = Delaunay(p) # instantiate a class t = tri.vertices pmid = (p[t[:,0]] + p[t[:,1]] + p[t[:,2]])/3.0 # keep the triangles whose geometrical center is inside the shape t = t[np.where(fd(pmid) < -geps)] bars = np.concatenate((t[:,[0,1]],t[:,[0,2]], t[:,[1,2]])) # delete repeated bars bars = unique_rows(np.sort(bars)) print (bars.shape) if Iflag == 4: min_q, min_angle_deg = triqual_flag(p,t) print ('Del iter: %3d, min q = %5.2f, min angle = %3.0f deg' \ % (Num_of_Delaunay_triangulations, min_q, min_angle_deg)) if min_q > qmin: break if Iflag == 2 or Iflag == 3: # graphical output of the current mesh ktrimesh(p,bars) # move mesh points based on bar lengths L and forces F print (p.shape) print (bars.shape) barvec = p[bars[:,0],:] - p[bars[:,1],:] L = np.sqrt(np.sum(barvec**2,axis=1)) hbars = 0.5*(fh(p[bars[:,0],:]) + fh(p[bars[:,1],:])) L0 = hbars*Fscale*np.sqrt(np.sum(L**2)/np.sum(hbars**2)) F = np.maximum(L0-L,0) Fvec = np.column_stack((F,F))*(barvec/np.column_stack((L,L))) # Fvec: bar forces, (x,y) components # Calculate now the total force on a given point p due to its # interaction with all the bars joining point p to neighboring points Ftot = np.zeros((len(p),2)) n = len(bars) for j in range(n): # sum of forces on the 1st point of a bar Ftot[bars[j,0],:] += Fvec[j,:] # the : for the (x,y) components # but the same point may be on the other side of a bar, so we # sum of forces on the 2nd point of a bar Ftot[bars[j,1],:] -= Fvec[j,:] # the minus sign is because by our convention, Fvec is the force # on the first node of a bar. Hence, the force on the 2nd node # of a bar is -Fvec (Netwon's action-reaction law) # force = 0 at fixed points, so they do not move: Ftot[0: len(pfix),:] = 0 # update the node positions p = p + deltat*Ftot # bring outside points back to the boundary d = fd(p); ix = d > 0 # find points outside (d > 0) dpx = np.column_stack((p[ix,0] + deps,p[ix,1])) dgradx = (fd(dpx) - d[ix])/deps dpy = np.column_stack((p[ix,0], p[ix,1] + deps)) dgrady = (fd(dpy) - d[ix])/deps p[ix,:] = p[ix,:] - np.column_stack((dgradx*d[ix], dgrady*d[ix])) # termination criterium: all interior nodes move less than dptol: if max(np.sqrt(np.sum(deltat*Ftot[d<-geps,:]**2,axis=1))/h0) < dptol: break final_tri = Delaunay(p) # another instantiation of the class t = final_tri.vertices pmid = (p[t[:,0]] + p[t[:,1]] + p[t[:,2]])/3.0 # keep the triangles whose geometrical center is inside the shape t = t[np.where(fd(pmid) < -geps)] bars = np.concatenate((t[:,[0,1]],t[:,[0,2]], t[:,[1,2]])) # delete repeated bars bars = unique_rows(np.sort(bars)) # orient all the triangles counterclockwise (ccw) t = ccw_tri(p,t) # graphical output of the current mesh ktrimesh(p,bars) triqual(p,t,fh) return p,t,bars
def voronoialgo(self): sx = self.points[2][0] lx = self.points[0][0] sy = self.points[0][1] ly = self.points[2][1] # a_degree = [[0 for _ in range(len(trilist[i].simplices))] for i in # range(len(find_touchingpoint_keepinzone_list))] # coord = [[0 for _ in range(len(trilist[i].simplices))] for i in range(len(find_touchingpoint_keepinzone_list))] # arealist = [[0 for _ in range(len(trilist[i].simplices))] for i in # range(len(find_touchingpoint_keepinzone_list))] # tri = Delaunay(self.points) vor = Voronoi(self.points[4:]) regions, vertices = self.voronoi_finite_polygons_2d(vor) # print(regions, vertices) ''' Visualization ''' # fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2) # ax1.set_xlim([self.points[2][0] - 0.05, self.points[1][0] + 0.05]) # ax1.set_ylim([self.points[0][1] - 0.05, self.points[1][1] + 0.05]) # ax2.set_xlim([self.points[2][0] - 0.05, self.points[1][0] + 0.05]) # ax2.set_ylim([self.points[0][1] - 0.05, self.points[1][1] + 0.05]) # ax3.set_xlim([self.points[2][0] - 0.05, self.points[1][0] + 0.05]) # ax3.set_ylim([self.points[0][1] - 0.05, self.points[1][1] + 0.05]) # ax4.set_ylim([self.points[2][0] - 0.05, self.points[1][0] + 0.05]) # ax4.set_xlim([self.points[0][1] - 0.05, self.points[1][1] + 0.05]) # ax1.set_xlim([self.points[2][0], self.points[1][0]]) # ax1.set_ylim([self.points[0][1], self.points[1][1]]) # ax2.set_xlim([self.points[2][0], self.points[1][0]]) # ax2.set_ylim([self.points[0][1], self.points[1][1]]) # ax3.set_xlim([self.points[2][0], self.points[1][0]]) # ax3.set_ylim([self.points[0][1], self.points[1][1]]) # ax4.set_xlim([self.points[2][0], self.points[1][0]]) # ax4.set_ylim([self.points[0][1], self.points[1][1]]) # print(self.points) # print(type(self.points[0])) # print(type(self.points)) #ax1.triplot(self.points[:, 0], self.points[:, 1], tri.simplices.copy()) # ax1.plot(self.points[:, 0], self.points[:, 1], 'o') # for i in range(len(self.points)): # ax1.text(self.points[i][0], self.points[i][1],'{}'.format(i), fontsize=6) polygon_count = 0 region_count = 0 ''' Each polygon ''' # nearpointslist = [] # farpointslist = [] # largepointslist = [] # smallpointslist = [] # # nearpointslist_idx = [] # farpointslist_idx = [] # largepointslist_idx = [] # smallpointslist_idx = [] # totalpoints = [] waypointlist = [] for region in regions: convextest = [] in_keepinzone_points_coord = [] in_keepinzone_points_list = [] polygon = vertices[region] # ax1.fill(*zip(*polygon), alpha=0.4) # print("-------------") # print(" ",str(polygon_count)," ") # print(vertices[region]) # print(region) ''' Points of Each polygon ''' for countvertices in range(len(vertices[region])): # print(countvertices, vertices[region]) if vertices[region][countvertices][0] > sx and vertices[ region][countvertices][0] < lx: if vertices[region][countvertices][1] > sy and vertices[ region][countvertices][1] < ly: # print(vertices[region][countvertices]) in_keepinzone_points_coord.append( vertices[region][countvertices].tolist()) # print(region[region_count]) in_keepinzone_points_list.append(region[region_count]) region_count += 1 # print("in_keepinzone_points_list\n",in_keepinzone_points_list) ''' keepinzone과 voronoi영역 만나는 점 추가 ''' in_keepinzone_points_coord = self.findtouchingpointkeepinzone( polygon, region, in_keepinzone_points_coord, in_keepinzone_points_list) ''' keepinzone의 꼭지점 추가 ''' in_keepinzone_points_coord = self.insertkeepinzonevertex( in_keepinzone_points_coord, polygon_count) #print(len(in_keepinzone_points_coord)) adjusted_polygon_points_coord = in_keepinzone_points_coord[:] ''' Visualization ''' # in_keepinzone_points_coord = np.array(in_keepinzone_points_coord) # print("in_keepinzone_points_coord",in_keepinzone_points_coord) # ax2.plot(in_keepinzone_points_coord[:,0], in_keepinzone_points_coord[:,1], 'o') # ax2.plot(self.points[polygon_count+4, 0], self.points[polygon_count+4, 1],'v') # ax2.text(self.points[polygon_count+4, 0], self.points[polygon_count+4, 1]+0.01,'{}'.format(polygon_count), fontsize=6) # for ttt in range(len(in_keepinzone_points_coord)): # ax2.text(in_keepinzone_points_coord[ttt][0],in_keepinzone_points_coord[ttt][1]+polygon_count*0.02,'{} point:{}'.format(polygon_count, ttt), fontsize=6) ''' voronoi로 나눈 지역 delaunay로 나눔 ''' # recovery point 추가 adjusted_polygon_points_coord.insert( 0, self.points[polygon_count + 4].tolist()) trilist = Delaunay(adjusted_polygon_points_coord) #coordlist, arealist, degreelist = self.infotriangles(adjusted_polygon_points_coord, trilist) coordlist, arealist, oneofarea = self.infotriangles( adjusted_polygon_points_coord, trilist, self.points[polygon_count + 4]) # print("adjust\n",adjusted_polygon_points_coord) # print("trilist.simplices.copy()\n",trilist.simplices) # print("arealist\n",arealist) # print("coordlist\n",coordlist) # totalpoints.append(coordlist) waypointlist.append(oneofarea) # ''' # NEAR POINTS # ''' # nearpoints_idx = self.calcdistancecenterandrecovery(coordlist, self.points[polygon_count+4]) # nearpoints = [0 for _ in range(len(coordlist))] # for i in range(len(nearpoints_idx)): # nearpoints[i] = coordlist[nearpoints_idx[i]] # nearpointslist.append(nearpoints) # nearpointslist_idx.append(nearpoints_idx) # # farpoints = nearpoints[::-1] # farpointslist.append(farpoints) # farpointslist_idx.append(nearpoints_idx[::-1]) # print("NEAR") # print(np.array(coordlist)) # print(np.array(nearpoints_idx)) # print(np.array(nearpoints)) ''' NEAR POINTS END ''' # ''' # SIZE POINTS # ''' # smallpoints_idx = self.sortaraesize(arealist) # smallpoints = [0 for _ in range(len(coordlist))] # for i in range(len(smallpoints_idx)): # smallpoints[i] = coordlist[smallpoints_idx[i]] # smallpointslist.append(smallpoints) # smallpointslist_idx.append(smallpoints_idx) # # largepoints = smallpoints[::-1] # largepointslist.append(largepoints) # largepointslist_idx.append(smallpoints_idx[::-1]) ''' SIZE POINTS END ''' #print(np.array(nearpointslist)) # for i in range(len(nearpoints)): # convextest.append(nearpoints[i]) # # for i in range(len(adjusted_polygon_points_coord)): # # convextest.append(adjusted_polygon_points_coord[i]) # # convextest = np.array(convextest) # print("convextest\n",convextest) # hull = ConvexHull(convextest) # print(hull.points) # for simplex in hull.simplices: # ax4.plot(convextest[simplex, 0], convextest[simplex, 1], 'k-') # #ax4.text(coordlist[simplex, 0], coordlist[simplex, 1],'{}'.format()) # print("convextest[hull.simplices]\n", convextest[hull.simplices, 1]) ''' Visualization ''' # coordlist = np.array(coordlist) # #coordlist = coordlist # adjusted_polygon_points_coord = np.array(adjusted_polygon_points_coord) # ax3.triplot(adjusted_polygon_points_coord[:, 0], adjusted_polygon_points_coord[:, 1],trilist.simplices.copy()) # ax3.plot(coordlist[:, 0], coordlist[:, 1], 'o') # # for ttt in range(len(trilist.simplices)): # ax3.text(coordlist[ttt][0],coordlist[ttt][1]+polygon_count*0.01,'{}\n{}'.format(ttt, round(arealist[ttt],3)), fontsize=6) # ax4.triplot(adjusted_polygon_points_coord[:, 1], adjusted_polygon_points_coord[:, 0],trilist.simplices.copy()) # ax4.plot(coordlist[:, 1], coordlist[:, 0], 'o') # # for ttt in range(len(trilist.simplices)): # ax4.text(coordlist[ttt][1], coordlist[ttt][0] + polygon_count * 0.01, # '{}\n{}'.format(ttt, round(arealist[ttt], 3)), fontsize=6) polygon_count += 1 region_count = 0 print("waypoints!!!\n", waypointlist) waypointlist = np.array(waypointlist) # print("waypoints!!!\n",waypointlist) # waypointlist = np.array(waypointlist) # for i in range(len(waypointlist)): # waypointlist[i] = np.array(waypointlist[i]) # for j in range(len(waypointlist[i])): # ax4.plot(waypointlist[i][j][:, 0], waypointlist[i][j][:, 1],'v') # for k in range(len(waypointlist[i][j])): # ax4.text(waypointlist[i][j][k][0],waypointlist[i][j][k][1],'{}'.format(k),fontsize=6) ''', set order of points ''' distancelist = [] shortestroute = [] for i in range(len(totalpoints)): #print("nearpointslist[i]\n",totalpoints[i]) if self.startway == 0: startidx = nearpointslist_idx[i][0] elif self.startway == 1: startidx = farpointslist_idx[i][0] elif self.startway == 2: startidx = smallpointslist_idx[i][0] else: startidx = largepointslist_idx[i][0] temp, route = self.findnearestlist(totalpoints[i], startidx) #print("route\n",route) distancelist.append(temp) shortestroute.append(route) ''' set order of points END ''' totalpoints = np.array(totalpoints) nearpointslist = np.array(nearpointslist) farpointslist = np.array(farpointslist) largepointslist = np.array(largepointslist) smallpointslist = np.array(smallpointslist) print("totalpoints\n", totalpoints) # ''' # set order of points # ''' # distancelist = [] # shortestroute = [] # # for i in range(len(totalpoints)): # #print("nearpointslist[i]\n",totalpoints[i]) # if self.startway == 0: # startidx = nearpointslist_idx[i][0] # elif self.startway == 1: # startidx = farpointslist_idx[i][0] # elif self.startway == 2: # startidx = smallpointslist_idx[i][0] # else: # startidx = largepointslist_idx[i][0] # temp, route = self.findnearestlist(totalpoints[i], startidx) # #print("route\n",route) # distancelist.append(temp) # shortestroute.append(route) # # ''' # set order of points END # ''' # totalpoints = np.array(totalpoints) # nearpointslist = np.array(nearpointslist) # farpointslist = np.array(farpointslist) # largepointslist = np.array(largepointslist) # smallpointslist = np.array(smallpointslist) # print("totalpoints\n",totalpoints) # print("near\n", nearpointslist) # print(nearpointslist_idx) # print("far\n", farpointslist) # print(farpointslist_idx) # print("large\n", largepointslist) # print(largepointslist_idx) # print("small\n", smallpointslist) # print(smallpointslist_idx) # # print("distancelist\n",np.array(distancelist)) # print("shortestroute\n",shortestroute) # self.searchcoord = totalpoints # self.searchroute = shortestroute return waypointlist # plt.show() # if __name__ == '__main__': # nkeepinzone = 4 # nrecoveryzone = 4 # numberofdroneeachrecoveryzone = 3 # pointlist = [[] for _ in range((nkeepinzone + nrecoveryzone))] # # # # LEFT DOWN # # pointlist[0] = [40.12915017 - 0.04, -121.4366 - 0.03] # # # LEFT UP # # pointlist[1] = [40.12915017 - 0.04, -120.6866 + 0.03] # # # RIGHT UP # # pointlist[2] = [39.5177 + 0.04, -120.6866 + 0.03] # # # RIHGT DOWN # # pointlist[3] = [39.5177 + 0.04, -121.4366 - 0.03] # # # # LEFT DOWN # pointlist[0] = [40.12915017, -121.4366] # # LEFT UP # pointlist[1] = [40.12915017, -120.6866] # # RIGHT UP # pointlist[2] = [39.5177, -120.6866] # # RIHGT DOWN # pointlist[3] = [39.5177, -121.4366] # # pointlist[4] = [39.9258, -121.2517] # pointlist[5] = [39.9919, -120.8328] # pointlist[6] = [39.5894, -121.0448] # pointlist[7] = [39.7181, -121.254] # # pointlist[8] = [39.8012, -121.1] # # pointlist[9] = [39.8094, -120.828] # # pointlist = np.array(pointlist) # ''' # startway # 0 = nearest # 1 = farthest # 2 = smallest # 3 = largest # ''' # voro = VoronoiSearch(pointlist, nkeepinzone, nrecoveryzone, numberofdroneeachrecoveryzone, 0) # voro.voronoialgo() # print("SEARCHCOORD\n",voro.searchcoord) # print("SEARCHROUTE\n",voro.searchroute) # try: # voro.delaunayalgo() # except: # print("voronoi doesn't work")
lef_wt=1.0-rig_wt new_width=int(lef_wt*src_width+rig_wt*dest_width) new_height=int(lef_wt*src_height+rig_wt*dest_height) interim_image=np.zeros([new_height,new_width,depth]) interim_points=[] total_feature_points=len(src_points) for ii in range(total_feature_points): interim_r=int(src_points[ii][0]*lef_wt+dest_points[ii][0]*rig_wt) interim_c=int(src_points[ii][1]*lef_wt+dest_points[ii][1]*rig_wt) interim_points.append((interim_r,interim_c)) triangulation=Delaunay(interim_points) triangulation_indices=triangulation.simplices all_points=[] for h in range(new_height): for w in range(new_width): all_points.append((h,w)) all_points=np.array(all_points) point_index=triangulation.find_simplex(all_points) X=triangulation.transform[point_index,:2] Y=all_points - triangulation.transform[point_index,2] baricentric_coord=np.einsum('ijk,ik->ij', X, Y) baricentric_coord=np.c_[baricentric_coord, 1 - baricentric_coord.sum(axis=1)] counter=0
def _make_delaunay_mesh(self, coords, connectivity): mesh = Delaunay(coords) mesh.simplices = connectivity.astype(np.int32) return mesh
def __getMean3D_CloughTocher(self, dx, dy, mask=None, clip=False, force=False): # Get the discretization if (dx is None): tmp = self.pointcloud.bounds[1] - self.pointcloud.bounds[0] dx = 0.01 * tmp assert dx > 0.0, "dx must be positive!" # Get the discretization if (dy is None): tmp = self.pointcloud.bounds[3] - self.pointcloud.bounds[2] dy = 0.01 * tmp assert dy > 0.0, "dy must be positive!" tmp = np.column_stack((self.pointcloud.x, self.points.y)) # Get the points to interpolate to x, y, intPoints = interpolation.getGridLocations2D( self.pointcloud.bounds, dx, dy) # Create a distance mask if mask: self.pointcloud.setKdTree( nDims=2) # Set the KdTree on the data points g = np.meshgrid(x, y) xi = _ndim_coords_from_arrays(tuple(g), ndim=tmp.shape[1]) dists, indexes = self.points.kdtree.query(xi) iMask = np.where(dists > mask) # Get the value bounds minV = np.nanmin(self.mean) maxV = np.nanmax(self.mean) # Initialize 3D volume mean3D = StatArray.StatArray(np.zeros( [self.zGrid.size, y.nCells, x.nCells], order='F'), name='Conductivity', units='$Sm^{-1}$') # Triangulate the data locations dTri = Delaunay(tmp) # Interpolate for each depth print('Interpolating using clough tocher') Bar = progressbar.ProgressBar() for i in Bar(range(self.zGrid.size)): # Get the model values for the current depth vals1D = self.mean[i, :] # Create the interpolant f = CloughTocher2DInterpolator(dTri, vals1D) # Interpolate to the grid vals = f(intPoints) # Reshape to a 2D array vals = vals.reshape(y.size, x.size) # clip values to the observed values if (clip): vals.clip(minV, maxV) # Mask based on distance if (mask): vals[iMask] = np.nan # Add values to the 3D array mean3D[i, :, :] = vals self.mean3D = mean3D #.reshape(self.zGrid.size*y.size*x.size)
def mesh(self): self.tri = Delaunay(self.points)
def in_hull(p, hull): from scipy.spatial import Delaunay if not isinstance(hull, Delaunay): hull = Delaunay(hull) return hull.find_simplex(p) >= 0
def doWork(self): if self.error is None: # In case we have only one class unnasigned = 0 classes = self.matrix.matrix_view.shape[2] layer = get_vector_layer_by_name(self.layer) idx = layer.fieldNameIndex(self.id_field) feature_count = layer.featureCount() self.emit(SIGNAL("desire_lines"), ('job_size_dl', feature_count)) all_centroids = {} P = 0 for feat in layer.getFeatures(): P += 1 self.emit(SIGNAL("desire_lines"), ('jobs_done_dl', P)) self.emit(SIGNAL("desire_lines"), ('text_dl',"Loading Layer Features: " + str(P) + "/" + str(feature_count))) geom = feat.geometry() if geom is not None: point = list(geom.centroid().asPoint()) centroid_id = feat.attributes()[idx] all_centroids[centroid_id] = point #Creating resulting layer EPSG_code = int(layer.crs().authid().split(":")[1]) desireline_layer = QgsVectorLayer("LineString?crs=epsg:" + str(EPSG_code), self.dl_type, "memory") dlpr = desireline_layer.dataProvider() fields = [QgsField("link_id", QVariant.Int), QgsField("A_Node", QVariant.Int), QgsField("B_Node", QVariant.Int), QgsField("direct", QVariant.Int), QgsField("distance", QVariant.Double)] for f in self.matrix.view_names: fields.extend([QgsField(f + '_ab', QVariant.Double), QgsField(f + '_ba', QVariant.Double), QgsField(f + '_tot', QVariant.Double)]) dlpr.addAttributes(fields) desireline_layer.updateFields() if self.dl_type == "DesireLines": self.emit(SIGNAL("desire_lines"), ('text_dl',"Creating Desire Lines")) self.emit(SIGNAL("desire_lines"), ('job_size_dl', self.matrix.zones ** 2 / 2)) desireline_link_id = 1 q = 0 all_features = [] for i in range(self.matrix.zones): a_node = self.matrix.index[i] if a_node in all_centroids.keys(): if np.sum(self.matrix.matrix_view[i, :, :]) + np.sum(self.matrix.matrix_view[:, i, :]) > 0: columns_with_filled_cells = np.nonzero(np.sum(self.matrix.matrix_view[i, :, :], axis=1)) for j in columns_with_filled_cells[0]: if np.sum(self.matrix.matrix_view[i, j, :]) + np.sum(self.matrix.matrix_view[j, i, :]) > 0: b_node = self.matrix.index[j] if a_node in all_centroids.keys() and b_node in all_centroids.keys(): a_point = all_centroids[a_node] a_point = QgsPoint(a_point[0], a_point[1]) b_point = all_centroids[b_node] b_point = QgsPoint(b_point[0], b_point[1]) dist = QgsGeometry().fromPoint(a_point).distance(QgsGeometry().fromPoint(b_point)) feature = QgsFeature() feature.setGeometry(QgsGeometry.fromPolyline([a_point, b_point])) attrs = [desireline_link_id, int(a_node), int(b_node), 0, dist] for c in range(classes): attrs.extend([float(self.matrix.matrix_view[i, j, c]), float(self.matrix.matrix_view[j, i, c]), float(self.matrix.matrix_view[i, j, c]) + float(self.matrix.matrix_view[j, i, c])]) feature.setAttributes(attrs) all_features.append(feature) desireline_link_id += 1 else: tu = (a_node, b_node, np.sum(self.matrix.matrix_view[i, j, :]), np.sum(self.matrix.matrix_view[j, i, :])) self.report.append('No centroids available to depict flow between node {0} and node' '{1}. Total AB flow was equal to {2} and total BA flow was ' 'equal to {3}'.format(*tu)) unnasigned += np.sum(self.matrix.matrix_view[i, j, :]) + \ np.sum(self.matrix.matrix_view[j, i, :]) else: tu = (a_node, np.sum(self.matrix.matrix_view[i, :, :])) self.report.append('No centroids available to depict flows from node {0} to all the others.' 'Total flow from this zone is equal to {1}'.format(*tu)) unnasigned += np.sum(self.matrix.matrix_view[i, :, :]) q += self.matrix.zones self.emit(SIGNAL("desire_lines"), ('jobs_done_dl', q)) if unnasigned > 0: self.report.append('Total non assigned flows (not counting intrazonals):' + str(unnasigned)) if desireline_link_id > 1: a = dlpr.addFeatures(all_features) self.result_layer = desireline_layer else: self.report.append('Nothing to show') elif self.dl_type == "DelaunayLines": self.emit(SIGNAL("desire_lines"), ('text_dl', "Building Delaunay dataset")) points = [] node_id_in_delaunay_results = {} i = 0 self.emit(SIGNAL("desire_lines"), ('job_size_dl', len(all_centroids))) for k, v in all_centroids.iteritems(): self.emit(SIGNAL("desire_lines"), ('jobs_done_dl', i)) points.append(v) node_id_in_delaunay_results[i] = k i += 1 self.emit(SIGNAL("desire_lines"), ('text_dl', "Computing Delaunay Triangles")) tri = Delaunay(np.array(points)) # We process all the triangles to only get each edge once self.emit(SIGNAL("desire_lines"), ('text_dl', "Building Delaunay Network: Collecting Edges")) edges = [] if self.python_version == 32: all_edges = tri.vertices else: all_edges = tri.simplices self.emit(SIGNAL("desire_lines"), ('job_size_dl', len(all_edges))) for j, triangle in enumerate(all_edges): self.emit(SIGNAL("desire_lines"), ('jobs_done_dl', j)) links = list(itertools.combinations(triangle, 2)) for i in links: edges.append([min(i[0],i[1]), max(i[0],i[1])]) self.emit(SIGNAL("desire_lines"), ('text_dl', "Building Delaunay Network: Getting unique edges")) edges = OrderedDict((str(x), x) for x in edges).values() # Writing Delaunay layer self.emit(SIGNAL("desire_lines"), ('text_dl', "Building Delaunay Network: Assembling Layer")) desireline_link_id = 1 data = [] dl_ids_on_links = {} self.emit(SIGNAL("desire_lines"), ('job_size_dl', len(edges))) for j, edge in enumerate(edges): self.emit(SIGNAL("desire_lines"), ('jobs_done_dl', j)) a_node = node_id_in_delaunay_results[edge[0]] a_point = all_centroids[a_node] a_point = QgsPoint(a_point[0], a_point[1]) b_node = node_id_in_delaunay_results[edge[1]] b_point = all_centroids[b_node] b_point = QgsPoint(b_point[0], b_point[1]) dist = QgsGeometry().fromPoint(a_point).distance(QgsGeometry().fromPoint(b_point)) line = [] line.append(desireline_link_id) line.append(a_node) line.append(b_node) line.append(dist) line.append(dist) line.append(0) data.append(line) dl_ids_on_links[desireline_link_id] = [a_node, b_node, 0, dist] desireline_link_id += 1 self.emit(SIGNAL("desire_lines"), ('text_dl', "Building graph")) network = np.asarray(data) del data #types for the network self.graph = Graph() itype = self.graph.default_types('int') ftype = self.graph.default_types('float') all_types = [itype, itype, itype, ftype, ftype, np.int8] all_titles = ['link_id', 'a_node', 'b_node', 'distance_ab', 'distance_ba', 'direction'] dt = [(t, d) for t, d in zip(all_titles, all_types)] self.graph.network = np.zeros(network.shape[0], dtype=dt) for k, t in enumerate(dt): self.graph.network[t[0]] = network[:, k].astype(t[1]) del network self.graph.type_loaded = 'NETWORK' self.graph.status = 'OK' self.graph.network_ok = True try: self.graph.prepare_graph(self.matrix.index.astype(np.int64)) self.graph.set_graph(cost_field='distance', skim_fields=False, block_centroid_flows=False) self.results = AssignmentResults() self.results.prepare(self.graph, self.matrix) self.emit(SIGNAL("desire_lines"), ('text_dl', "Assigning demand")) self.emit(SIGNAL("desire_lines"), ('job_size_dl', self.matrix.index.shape[0])) assigner = allOrNothing(self.matrix, self.graph, self.results) assigner.execute() self.report = assigner.report self.emit(SIGNAL("desire_lines"), ('text_dl', "Collecting results")) link_loads = self.results.save_to_disk() self.emit(SIGNAL("desire_lines"), ('text_dl', "Building resulting layer")) features = [] max_edges = len(edges) self.emit(SIGNAL("desire_lines"), ('job_size_dl', max_edges)) for i, link_id in enumerate(link_loads.index): self.emit(SIGNAL("desire_lines"), ('jobs_done_dl', i)) a_node, b_node, direct, dist = dl_ids_on_links[link_id] attr = [int(link_id), a_node, b_node, direct, dist] a_point = all_centroids[a_node] a_point = QgsPoint(a_point[0], a_point[1]) b_point = all_centroids[b_node] b_point = QgsPoint(b_point[0], b_point[1]) feature = QgsFeature() feature.setGeometry(QgsGeometry.fromPolyline([a_point, b_point])) for c in self.matrix.view_names: attr.extend([float(link_loads.data[c + '_ab'][i]), float(link_loads.data[c + '_ba'][i]), float(link_loads.data[c + '_tot'][i])]) feature.setAttributes(attr) features.append(feature) a = dlpr.addFeatures(features) self.result_layer = desireline_layer except ValueError as error: self.report = [error.message] self.emit(SIGNAL("desire_lines"), ('finished_desire_lines_procedure', 0))
def _make_pixel_cache(subject, xfmname, height=1024, thick=32, depth=0.5, sampler='nearest'): from scipy import sparse from scipy.spatial import Delaunay flat, polys = db.get_surf(subject, "flat", merge=True, nudge=True) valid = np.unique(polys) fmax, fmin = flat[valid].max(0), flat[valid].min(0) size = fmax - fmin aspect = size[0] / size[1] width = int(aspect * height) grid = np.mgrid[fmin[0]:fmax[0]:width * 1j, fmin[1]:fmax[1]:height * 1j].reshape(2, -1) mask, extents = get_flatmask(subject, height=height) assert mask.shape[0] == width and mask.shape[1] == height # Get barycentric coordinates dl = Delaunay(flat[valid, :2]) simps = dl.find_simplex(grid.T[mask.ravel()]) missing = simps == -1 tfms = dl.transform[simps] l1, l2 = (tfms[:, :2].transpose(1, 2, 0) * (grid.T[mask.ravel()] - tfms[:, 2]).T).sum(1) l3 = 1 - l1 - l2 ll = np.vstack([l1, l2, l3]) ll[:, missing] = 0 from ..mapper import samplers xfm = db.get_xfm(subject, xfmname, xfmtype='coord') sampclass = getattr(samplers, sampler) # Transform fiducial vertex locations to pixel locations using barycentric xfm try: pia, polys = db.get_surf(subject, "pia", merge=True, nudge=False) wm, polys = db.get_surf(subject, "wm", merge=True, nudge=False) piacoords = xfm( (pia[valid][dl.vertices][simps] * ll[np.newaxis].T).sum(1)) wmcoords = xfm( (wm[valid][dl.vertices][simps] * ll[np.newaxis].T).sum(1)) valid_p = np.array([ np.all((0 <= piacoords), axis=1), piacoords[:, 0] < xfm.shape[2], piacoords[:, 1] < xfm.shape[1], piacoords[:, 2] < xfm.shape[0] ]) valid_p = np.all(valid_p, axis=0) valid_w = np.array([ np.all((0 <= wmcoords), axis=1), wmcoords[:, 0] < xfm.shape[2], wmcoords[:, 1] < xfm.shape[1], wmcoords[:, 2] < xfm.shape[0] ]) valid_w = np.all(valid_w, axis=0) valid = np.logical_and(valid_p, valid_w) vidx = np.nonzero(valid)[0] mapper = sparse.csr_matrix((mask.sum(), np.prod(xfm.shape))) if thick == 1: i, j, data = sampclass( piacoords[valid] * depth + wmcoords[valid] * (1 - depth), xfm.shape) mapper = mapper + sparse.csr_matrix( (data / float(thick), (vidx[i], j)), shape=mapper.shape) return mapper for t in np.linspace(0, 1, thick + 2)[1:-1]: i, j, data = sampclass( piacoords[valid] * t + wmcoords[valid] * (1 - t), xfm.shape) mapper = mapper + sparse.csr_matrix( (data / float(thick), (vidx[i], j)), shape=mapper.shape) return mapper except IOError: fid, polys = db.get_surf(subject, "fiducial", merge=True) fidcoords = xfm( (fid[valid][dl.vertices][simps] * ll[np.newaxis].T).sum(1)) valid = reduce(np.logical_and, [ reduce(np.logical_and, (0 <= fidcoords).T), fidcoords[:, 0] < xfm.shape[2], fidcoords[:, 1] < xfm.shape[1], fidcoords[:, 2] < xfm.shape[0] ]) vidx = np.nonzero(valid)[0] i, j, data = sampclass(fidcoords[valid], xfm.shape) csrshape = mask.sum(), np.prod(xfm.shape) return sparse.csr_matrix((data, (vidx[i], j)), shape=csrshape)
def alpha_shape(points, alpha): """ Compute the alpha shape (concave hull) of a set of points. @param points: Iterable container of points. @param alpha: alpha value to influence the gooeyness of the border. Smaller numbers don't fall inward as much as larger numbers. Too large, and you lose everything! """ if len(points) < 4: # When you have a triangle, there is no sense # in computing an alpha shape. return geometry.MultiPoint(list(points)).convex_hull def add_edge(edges, edge_points, coords, i, j): """ Add a line between the i-th and j-th points, if not in the list already """ if (i, j) in edges or (j, i) in edges: # already added return edges.add((i, j)) edge_points.append(coords[[i, j]]) #coords = pylab.array([point.coords[0] for point in points]) coords = points tri = Delaunay(coords) edges = set() edge_points = [] # loop over triangles: # ia, ib, ic = indices of corner points of the # triangle for ia, ib, ic in tri.vertices: pa = coords[ia] pb = coords[ib] pc = coords[ic] # Lengths of sides of triangle a = pylab.sqrt((pa[0] - pb[0])**2 + (pa[1] - pb[1])**2) b = pylab.sqrt((pb[0] - pc[0])**2 + (pb[1] - pc[1])**2) c = pylab.sqrt((pc[0] - pa[0])**2 + (pc[1] - pa[1])**2) # Semiperimeter of triangle s = (a + b + c) / 2.0 # Area of triangle by Heron's formula area = pylab.sqrt(s * (s - a) * (s - b) * (s - c)) circum_r = a * b * c / (4.0 * area) # Here's the radius filter. #print circum_r if circum_r < 1.0 / alpha: add_edge(edges, edge_points, coords, ia, ib) add_edge(edges, edge_points, coords, ib, ic) add_edge(edges, edge_points, coords, ic, ia) m = geometry.MultiLineString(edge_points) triangles = list(polygonize(m)) return cascaded_union(triangles), edge_points
def main(_): # Initialize the game engine pygame.init() # Define the colors we will use in RGB format BLACK = ( 0, 0, 0) GRAY = (150, 150, 150) WHITE = (255, 255, 255) BLUE = ( 0, 0, 255) GREEN = ( 0, 255, 0) RED = (255, 0, 0) # Set the height and width of the screen size = [1024, 768] screen = pygame.display.set_mode(size) pygame.display.set_caption("Rectangle placement") #Loop until the user clicks the close button. done = False clock = pygame.time.Clock() center = [size[0] // 2, size[1] // 2] screenRect = pygame.Rect(0, 0, size[0], size[1]).inflate(-400, -300) myfont = pygame.font.SysFont("monospace", 15) rects = create_rects(center, FLAGS.num_rects) meanW = reduce((lambda s, r: s + r.width), [0] + rects) / len(rects) meanH = reduce((lambda s, r: s + r.height), [0] + rects) / len(rects) for rect in rects: pass if FLAGS.save: pickle.dump(rects, open('rectangles.pkl', 'wb'), protocol=pickle.HIGHEST_PROTOCOL) if FLAGS.load: rects = pickle.load(open('rectangles.pkl')) def sortClosestFirst(rect): v1 = rect.center v2 = center return math.sqrt(math.pow(v1[0] - v2[0], 2) + math.pow(v1[1] - v2[1], 2)) def sortBiggestFirst(rect): return -rect.size[0] * rect.size[1] def sortSmallestFirst(rect): return rect.size[0] * rect.size[1] class DefaultGravityCenterStrategy(object): def getCenter(self, finder): return self.getMiddle(finder.drawn) def getMiddle(self, rectangles): l = len(rectangles) if not l: return center xs = map(lambda r: r.center[0], rectangles) ys = map(lambda r: r.center[1], rectangles) return [sum(xs) // l, sum(ys) // l] class DrawnAndCurrentGravityCenterStrategy(DefaultGravityCenterStrategy): def getCenter(self, finder): if finder.current: rects = finder.drawn + [finder.current] else: rects = finder.drawn return self.getMiddle(rects) class PlaceFinder(object): def __init__(self, rectangles, sortCallback, gcStrategy, grow = 0): self.grow = grow self.gcStrategy = gcStrategy self.toDraw = sorted(rectangles, key = sortCallback) map(lambda r: r.inflate_ip(self.grow, self.grow), self.toDraw) self.drawn = [] self.current = self.next() @property def gravityCenter(self): return self.gcStrategy.getCenter(self) def next(self): return self.toDraw.pop(0) if self.toDraw else None def findNextPlace(self): if not self.current: return False self.collisions = self.current.collidelistall(self.drawn) if not self.collisions: self.drawn.append(self.current) self.current = self.next() return True G = self.gravityCenter v = [self.current.center[0] - G[0], self.current.center[1] - G[1]] if (np.zeros(2, dtype=int) == v).all(): # if v == [0, 0] v = np.ones(2) lv = math.sqrt(v[0] * v[0] + v[1] * v[1]) if lv == 0: lv = 1 v = [math.ceil(2 * v[0] / lv), math.ceil(2 * v[1] / lv)] self.current.center = [self.current.center[0] + v[0], self.current.center[1] + v[1]] if not screenRect.contains(self.current): self.current = self.next() return True if FLAGS.sort == 'biggest': sortCallback = sortBiggestFirst elif FLAGS.sort == 'smallest': sortCallback = sortSmallestFirst else: sortCallback = sortClosestFirst gcStrategy = DefaultGravityCenterStrategy() if not FLAGS.gc_current else DrawnAndCurrentGravityCenterStrategy() finder = PlaceFinder(rects, sortCallback, gcStrategy, grow = FLAGS.grow) if not FLAGS.anim: while finder.findNextPlace(): pass while not done: # This limits the while loop to a max of 10 times per second. # Leave this out and we will use all CPU we can. #clock.tick(100) for event in pygame.event.get(): # User did something if event.type == pygame.KEYDOWN and (event.key == 27 or event.key == 113): done=True # Flag that we are done so we exit this loop # Clear the screen and set the screen background screen.fill(WHITE) pygame.draw.rect(screen, hex_to_rgb('#ff0000'), screenRect, 2) if FLAGS.anim: finder.findNextPlace() for rect in finder.toDraw: if not rect: continue pygame.draw.rect(screen, GRAY, rect, 1) centers = [] # For Delaunay triangulation for i, rect in enumerate(finder.drawn + [finder.current]): if not rect: continue color = GRAY if rect.width > meanW and rect.height > meanH: color = hex_to_rgb('#ff0000') centers.append(rect.center) else: continue pygame.draw.rect(screen, color, rect.inflate(-finder.grow, -finder.grow), 1) if not FLAGS.no_numbers: label = myfont.render(str(i), 1, hex_to_rgb('#ff0000')) screen.blit(label, [rect.center[0] - 6, rect.center[1] -6]) if FLAGS.centers: drawCross(screen, finder.gravityCenter, BLUE, width = 2) drawCross(screen, center, hex_to_rgb('#ff0000'), width = 2) # Delaunay triangulation if len(centers) > 3: points = np.array(centers) tri = Delaunay(points) graph = np.zeros((len(points), len(points))) for simplex in tri.simplices: graph[simplex[0], simplex[1]] = scipy.spatial.distance.euclidean(points[simplex[0]], points[simplex[1]]) graph[simplex[1], simplex[2]] = scipy.spatial.distance.euclidean(points[simplex[1]], points[simplex[2]]) graph[simplex[2], simplex[0]] = scipy.spatial.distance.euclidean(points[simplex[2]], points[simplex[0]]) if not FLAGS.no_tri: pygame.draw.lines(screen, hex_to_rgb('#cdcdcd'), True, points[simplex], 1) # Spanning Tree tree = minimum_spanning_tree(graph) a = scipy.sparse.find(tree)[0] b = scipy.sparse.find(tree)[1] if not FLAGS.no_tree: for j in xrange(0, len(a)): pygame.draw.line(screen, hex_to_rgb('#333333'), points[a[j]], points[b[j]], 2) # Go ahead and update the screen with what we've drawn. # This MUST happen after all the other drawing commands. pygame.display.flip() # Be IDLE friendly pygame.quit()
#%% import numpy as np import matplotlib.pyplot as plt from scipy.spatial import Delaunay import sys sys.path.append('../') import useful_functions as uf import quality_measures as qa #%% N = 10 xlims, ylims = [0, 3], [0, 3] X = np.random.uniform(*xlims, N) Y = np.random.uniform(*ylims, N) points = np.array((X, Y)).T print(points.shape) T = Delaunay(points) fig, ax = plt.subplots() ax.triplot(X, Y, T.simplices) ax.scatter(X, Y, marker='o') #%%
u = [] v = [] w = [] for l in pc: if not l[0].isalpha(): u.append(float(l[0])) v.append(float(l[1])) w.append(float(l[2])) ua = np.array(u) va = np.array(v) #tri = mtri.Triangulation(u, v) tri = Delaunay(np.array([u, v]).T) points3d = [] points2d = [] vertex = [] for i in range(ua.shape[0]): points3d.append([ua[i], va[i], w[i]]) points2d.append([ua[i], va[i]]) for vert in tri.simplices: #for vert in tri.triangles: vertex.append(vert) fig = plt.figure() ax = fig.add_subplot(1, 1, 1, projection='3d')
def __init__(self, name): nc = Dataset(name) x_domain = (250, 400) # general-waddden sea (250, 380) y_domain = (450, 760) # (530,760) # x_domain = (300,390) # Texel-case # y_domain = (650,760) v = nc.variables["VELV"][:, :, :] u = nc.variables["VELU"][:, :, :] d = nc.variables["SEP"][:, :, :] x = nc.variables["x"][:, :] y = nc.variables["y"][:, :] t = nc.variables["time"][:] t = t * 60 x = x[x_domain[0]:x_domain[1], y_domain[0]:y_domain[1]] y = y[x_domain[0]:x_domain[1], y_domain[0]:y_domain[1]] u = u[:, x_domain[0]:x_domain[1], y_domain[0]:y_domain[1]] v = v[:, x_domain[0]:x_domain[1], y_domain[0]:y_domain[1]] d = d[:, x_domain[0]:x_domain[1], y_domain[0]:y_domain[1]] x_temp = ma.array(x.reshape(x.size)) y_temp = ma.array(y.reshape(x.size)) nodes = np.zeros((y_temp[y_temp.mask == False].size, 2)) nodes[:, 0] = y_temp[y_temp.mask == False] nodes[:, 1] = x_temp[y_temp.mask == False] print("1/3") bat, nodesb = self.bat() Db_new = griddata((nodesb[:, 1], nodesb[:, 0]), bat, (x, y), method="cubic") WD = d * 0 for i in range(d.shape[0]): WD[i, :, :] = d[i, :, :] - Db_new print("2/3") u_n = [] v_n = [] d_n = [] for node in nodes: xloc = np.argwhere(x == node[1])[0, 1] yloc = np.argwhere(y == node[0])[0, 0] u_n.append(u[:, yloc, xloc]) v_n.append(v[:, yloc, xloc]) d_n.append(WD[:, yloc, xloc]) d_n = np.array(d_n) d_n[d_n < -600] = 0 v_n = np.array(v_n) v_n[v_n < -600] = 0 u_n = np.array(u_n) u_n[u_n < -600] = 0 self.nodes = nodes self.u = np.transpose(u_n) self.v = np.transpose(v_n) self.WD = np.transpose(d_n) self.tria = Delaunay(nodes) self.t = t
def render_mesh(self): """ Perform a Delaunay triangulation to obtain the direct neighbours of each particle. Triangulation should be re-done when particle displacements exceed a certain threshold """ points = self.particles["coords"] # Particle baricentres r_max = self.particles["r_max"] x_max = self.sim_params["box"][0] IDs = self.particles["ID"] # Identify candidates for ghost particles ghosts_left = np.where(points[:, 0] < r_max)[0] ghosts_right = np.where(points[:, 0] > x_max - r_max)[0] ghosts = np.hstack([ghosts_left, ghosts_right]) # Count real/ghost particles N = self.sim_params["N"] N_left = len(ghosts_left) N_right = len(ghosts_right) # Calculate position offset of ghosts offsets = np.zeros((N + N_left + N_right, 2)) offsets[N:N+N_left, 0] = x_max offsets[N+N_left:, 0] = -x_max # Collect ghost praticle coordinates ghost_coords_left = points[ghosts_left] ghost_coords_right = points[ghosts_right] ghost_coords = np.vstack([ghost_coords_left, ghost_coords_right]) # Generate prime numbered IDs for particles prime_IDs = np.array(list(islice(self.primes(), N)), dtype=int) # Create lookup table for real/ghost particles all_IDs = np.hstack([IDs, ghosts]) # Particle centroids used in triangulation (including offsets) all_points = np.vstack([points, ghost_coords]) + offsets # Create mesh object tri = Delaunay(all_points) # Neighboring vertices of vertices. The indices of neighbouring # vertices of vertex k are obtained by ptrs[inds[k]:inds[k+1]] inds, ptrs = tri.vertex_neighbor_vertices # Create lookup table for particle contacts prime_lookup = {} # Loop over all particles (including ghosts) for n in range(len(all_IDs)): # Get the neighbours of this particle neighbours = ptrs[inds[n]:inds[n + 1]] i = all_IDs[n] # Loop over all particle neighbours for k in neighbours: j = all_IDs[k] # Generate a particle-pair ID from primes contact_id = prime_IDs[i] * prime_IDs[j] # Create dictionary entry prime_lookup[contact_id] = 0 # Number of particle-pair contacts N_contacts = inds[-1] // 2 # Contact IDs keys = sorted(prime_lookup.keys()) # Create new lookup table for contacts prime_lookup = dict(zip(keys, np.arange(N_contacts))) # Store vertices and neighbours as contact dict self.contacts = { "N": N_contacts, "inds": inds, "ptrs": ptrs, "points": tri.points.copy(), "lookup": all_IDs, "offsets": offsets, "prime_lookup": prime_lookup, "prime_IDs": prime_IDs, "shear": np.zeros((N_contacts, 3)), "forces": np.zeros((N_contacts, 2)), "tri": tri, } return True
def topography(zfunc, xlim, ylim, depth, n=10): ''' Returns a collection of simplices that form a box-like domain. The bottom and sides of the box are flat and to top of the box is shaped according to a user-specified topography function. This is only for three-dimensional domains. Parameters ---------- zfunc : callable Function that takes a (N,2) array of surface coordinates and returns an (N,) array of elevations at those coordinates. This function should taper to zero at the edges of the domain. xlim : (2,) array x bounds of the domain ylim : (2,) array y bounds of the domain depth : float Depth of the domain. This should be positive. n : int, optional Number of simplices along the x and y axis. Increasing this number results in a better resolved domain. Returns ------- vert : (P,3) float array Vertices of the domain. smp : (Q,3) int array Indices of the vertices that make up each simplex. Rows 0-2 make up the simplices for the bottom of the domain. Rows 2-10 make up the sides of the domain. The remaining rows make up the simplices for the surface. ''' base_vert = np.array([[0.0, 0.0, -1.0], [0.0, 0.0, 0.0], [0.0, 1.0, -1.0], [0.0, 1.0, 0.0], [1.0, 0.0, -1.0], [1.0, 0.0, 0.0], [1.0, 1.0, -1.0], [1.0, 1.0, 0.0]]) # scale vertices to user specs base_vert[:, 0] *= (xlim[1] - xlim[0]) base_vert[:, 0] += xlim[0] base_vert[:, 1] *= (ylim[1] - ylim[0]) base_vert[:, 1] += ylim[0] base_vert[:, 2] *= depth base_smp = np.array([[0, 2, 6], [0, 4, 6], [0, 1, 3], [0, 2, 3], [0, 1, 4], [1, 5, 4], [4, 5, 7], [4, 6, 7], [2, 3, 7], [2, 6, 7]]) # make grid of top vertices x = np.linspace(xlim[0], xlim[1], n) y = np.linspace(ylim[0], ylim[1], n) xg, yg = np.meshgrid(x, y) xf, yf, zf = xg.flatten(), yg.flatten(), np.zeros(n**2) # find the interior top vertices and change their z value according # to zfunc interior = ((xf != xlim[0]) & (xf != xlim[1]) & (yf != ylim[0]) & (yf != ylim[1])) interior_xy = np.array([xf[interior], yf[interior]]).T zf[interior] = zfunc(interior_xy) # make the top simplices top_vert = np.array([xf, yf, zf]).T top_smp = Delaunay(top_vert[:, :2]).simplices # combine the base with the top vert = np.vstack((base_vert, top_vert)) smp = np.vstack((base_smp, 8 + top_smp)) return vert, smp
import matplotlib.pyplot as plt from scipy.spatial import Delaunay import numpy as np import networkx as nx import math a = 1 b = 1 num_points = 20 radius = .2 points = np.random.rand(num_points, 2) points[:, 0] = a * points[:, 0] points[:, 1] = b * points[:, 1] tri = Delaunay(points) plt.triplot(points[:, 0], points[:, 1], tri.simplices.copy()) plt.triplot(points[:, 0], points[:, 1], 'o') plt.show() nlist = tri.vertex_neighbor_vertices g = nx.Graph() for n in range(num_points): g.add_edges_from([(n, x) for x in nlist[1][nlist[0][n]:nlist[0][n + 1]]]) pos = {n: points[n, :] for n in range(num_points)} plt.figure()
def __init__(self, src_grid_name, tgt_grid_name, level=1, verbose=False, window=3, period=1): # Put here info on grids to be obtained from __call__ # This currently works with mask files # 'masks_CMCC-CM2_VHR4_AGCM.nc' # and # 'ORCA025L50_mesh_mask.nc' # Path to auxiliary Ocean files homedir = os.path.expanduser("~") self.mdir = homedir + '/Dropbox (CMCC)/data_zapata' self.ingrid = src_grid_name self.outgrid = tgt_grid_name # Parameter for sea over land self.window = window self.period = period # Check levels if level > 0: self.level = level else: SystemError(f' Surface variable not available, Level {level}') #Resolve grids s_in = self._resolve_grid(src_grid_name, level) tk = s_in['tmask'] self.T_lon = s_in['lonT'] self.T_lat = s_in['latT'] mask = tk.assign_coords({ 'lat': self.T_lat, 'lon': self.T_lon }).drop_vars(['U_lon', 'U_lat', 'V_lon', 'V_lat', 'T_lon', 'T_lat']).rename({'z': 'deptht'}) tk = s_in['umask'] self.U_lon = s_in['lonU'] self.U_lat = s_in['latU'] masku = tk.assign_coords({ 'lat': self.U_lat, 'lon': self.U_lon }).drop_vars(['U_lon', 'U_lat', 'V_lon', 'V_lat', 'T_lon', 'T_lat']).rename({'z': 'deptht'}) tk = s_in['vmask'] self.V_lon = s_in['lonV'] self.V_lat = s_in['latV'] maskv = tk.assign_coords({ 'lat': self.V_lat, 'lon': self.V_lon }).drop_vars(['U_lon', 'U_lat', 'V_lon', 'V_lat', 'T_lon', 'T_lat']).rename({'z': 'deptht'}) self.name = 'UV Velocity' self.level = str(level) #Fix Polar Fold mask[-3:, :] = False #T angles self.tangle = s_in['tangle'] #Sea over land self.mask = xr.where(mask != 0, 1, np.nan) self.masktb, dum = self.mask_sea_over_land(mask) self.maskub, self.masku = self.mask_sea_over_land(masku) self.maskvb, self.maskv = self.mask_sea_over_land(maskv) print(f' Generating interpolator for {self.name}') if verbose: print(self.mask, self.masku, self.maskv) # Get triangulation for all grids self.latlon, self.sea_index, self.masT_vec = get_sea(self.mask) self.tri_sea_T = Delaunay( self.latlon) # Compute the triangulation for T print(f' computing the triangulation for T grid') latlon_U, self.sea_index_U, masU_vec = get_sea(self.masku) self.tri_sea_U = Delaunay(latlon_U) # Compute the triangulation for U print(f' computing the triangulation for U grid') latlon_V, self.sea_index_V, masT_vec = get_sea(self.maskv) self.tri_sea_V = Delaunay(latlon_V) # Compute the triangulation for V print(f' computing the triangulation for V grid') #Target Grid s_out = self._resolve_grid(tgt_grid_name, level, verbose=verbose) self.mask_reg = s_out['tmask'] self.cent_long = s_out['cent_long'] self.latlon_reg, self.sea_index_reg, self.regmask_vec = get_sea( self.mask_reg)
[1, 2, 3, 12, 13], [10, 11, 13, 14], [3, 9, 14, 13, 4], [9, 4, 16, 17], [16, 5, 18, 17], [5, 15, 7, 8, 18], [15, 6, 7], ] #p1=plt.plot(points[:,0],points[:,1],'o') #plt.hold(True) #ps = []*len(parts) allTris = [] nAllTris = [] for i in range(len(parts)): tri = Delaunay(points[np.array(vertList[i]) - 1]) tris = [0] * tri.vertices.shape[0] ntris = [0] * tri.vertices.shape[0] for j in range(tri.vertices.shape[0]): tris[j] = points[tri.vertices[j]].tolist() ntris[j] = points[tri.vertices[j]] plt.plot(ntris[j][:, 0], ntris[j][:, 1]) allTris.extend(tris) nAllTris.extend(ntris) parts[i] = tris plt.show() allTris = allTris[1:] #for tri in nAllTris: # plt.plot(tri[:,0],tri[:,1])
def test_plate_from_zero(): # Plate geometry and laminate data a = 0.406 b = 0.254 E1 = 1.295e11 E2 = 9.37e9 nu12 = 0.38 G12 = 5.24e9 G13 = 5.24e9 G23 = 5.24e9 plyt = 1.9e-4 laminaprop = (E1, E2, nu12, G12, G13, G23) angles = [0, 45, -45, 90, 90, -45, 45, 0] # Generating Mesh # --- import numpy as np from scipy.spatial import Delaunay xs = np.linspace(0, a, 8) ys = np.linspace(0, b, 8) points = np.array(np.meshgrid(xs, ys)).T.reshape(-1, 2) tri = Delaunay(points) # Using Meshless Package # --- from scipy.sparse import coo_matrix from composites.laminate import read_stack from structsolve import solve, lb from meshless.espim.read_mesh import read_delaunay from meshless.espim.plate2d_calc_k0 import calc_k0 from meshless.espim.plate2d_calc_kG import calc_kG from meshless.espim.plate2d_add_k0s import add_k0s mesh = read_delaunay(points, tri) nodes = np.array(list(mesh.nodes.values())) prop_from_nodes = True nodes_xyz = np.array([n.xyz for n in nodes]) # **Applying properties # applying heterogeneous properties for node in nodes: lam = read_stack(angles, plyt=plyt, laminaprop=laminaprop) node.prop = lam # **Defining Boundary Conditions** # DOF = 5 def bc(K, mesh): for node in nodes[nodes_xyz[:, 0] == xs.min()]: for dof in [1, 3]: j = dof - 1 K[node.index * DOF + j, :] = 0 K[:, node.index * DOF + j] = 0 for node in nodes[(nodes_xyz[:, 1] == ys.min()) | (nodes_xyz[:, 1] == ys.max())]: for dof in [2, 3]: j = dof - 1 K[node.index * DOF + j, :] = 0 K[:, node.index * DOF + j] = 0 for node in nodes[nodes_xyz[:, 0] == xs.max()]: for dof in [3]: j = dof - 1 K[node.index * DOF + j, :] = 0 K[:, node.index * DOF + j] = 0 # **Calculating Constitutive Stiffness Matrix** k0s_method = 'cell-based' k0 = calc_k0(mesh, prop_from_nodes) add_k0s(k0, mesh, prop_from_nodes, k0s_method, alpha=0.2) bc(k0, mesh) k0 = coo_matrix(k0) # **Defining Load and External Force Vector** def define_loads(mesh): loads = [] load_nodes = nodes[(nodes_xyz[:, 0] == xs.max()) & (nodes_xyz[:, 1] != ys.min()) & (nodes_xyz[:, 1] != ys.max())] fx = -1. / (nodes[nodes_xyz[:, 0] == xs.max()].shape[0] - 1) for node in load_nodes: loads.append([node, (fx, 0, 0)]) load_nodes = nodes[(nodes_xyz[:, 0] == xs.max()) & ( (nodes_xyz[:, 1] == ys.min()) | (nodes_xyz[:, 1] == ys.max()))] fx = -1. / (nodes[nodes_xyz[:, 0] == xs.max()].shape[0] - 1) / 2 for node in load_nodes: loads.append([node, (fx, 0, 0)]) return loads n = k0.shape[0] // DOF fext = np.zeros(n * DOF, dtype=np.float64) loads = define_loads(mesh) for node, force_xyz in loads: fext[node.index * DOF + 0] = force_xyz[0] print('Checking sum of forces: %s' % str(fext.reshape(-1, DOF).sum(axis=0))) # **Running Static Analysis** d = solve(k0, fext, silent=True) total_trans = (d[0::DOF]**2 + d[1::DOF]**2)**0.5 print('Max total translation', total_trans.max()) # **Calculating Geometric Stiffness Matrix** kG = calc_kG(d, mesh, prop_from_nodes) bc(kG, mesh) kG = coo_matrix(kG) # **Running Linear Buckling Analysis** eigvals, eigvecs = lb(k0, kG, silent=True) print('First 5 eigenvalues') print('\n'.join(map(str, eigvals[:5]))) assert np.allclose(eigvals[:5], [ 1004.29332981, 1822.11577078, 2898.3728806, 2947.17499169, 3297.54959342, ])
# plt.plot(points[:,0], points[:,1], 'o') plt.show() if __name__ == '__main__': import sys if len(sys.argv) > 1: img_fname = sys.argv[1] else: img_fname = '/n/lichtmangpfs01/Instrument_drop/U19_Zebrafish/EM/w019/w019_h02_20190325_14-10-55/001_S15R1/000021/001_000021_028_2019-03-25T1414044834028.bmp' #img_fname = '/n/lichtmangpfs01/Instrument_drop/U19_Zebrafish/EM/w019/w019_h02_20190326_00-43-52/002_S16R1/000021/002_000021_040_2019-03-26T0046443382649.bmp' img = cv2.imread(img_fname, 0) detector = WrinkleDetector(kernel_size=3, threshold=200, min_line_length=100) contours = detector.detect(img) #detector.visualize_contours(img, contours, "temp_wrinkle_detector4.png") hex_grid = utils.generate_hexagonal_grid( [0, img.shape[1], 0, img.shape[0]], 500) mesh_tri = Delaunay(hex_grid) edges_filter = MeshEdgesFilter(mesh_tri) filtered_edges_indices, filtered_simplices = edges_filter.filter_by_wrinkles( contours) visualize_filtered_mesh(mesh_tri, filtered_edges_indices, filtered_simplices, img)
# fileName = fileName+str(i)+".tif" # im_cube[:,:,i-1] = plt.imread(fileName) vert = build_vert_by_th(img, nx, ny) print('verts:', len(vert)) sys.stdout.flush() base_square_vert = np.asarray([vert[0], vert[1], vert[nx], vert[nx + 1]]) tri_vert_to_og_vert = {} tri_vert_to_og_vert[0] = 0 tri_vert_to_og_vert[1] = 1 tri_vert_to_og_vert[2] = nx tri_vert_to_og_vert[3] = nx + 1 # print(base_cube) tri = Delaunay(base_square_vert[:, :2]) tri.simplices.sort() # np.savetxt("simpliecs.txt",tri.simplices) print("Build tri from tetra.") sys.stdout.flush() base_square_tri = tri.simplices print("Build edge from tri.") sys.stdout.flush() base_square_edge = builEdgeFromTri(base_square_tri) print('base edges:', base_square_edge) print('base tris:', base_square_tri) # print(base_cube_edge) square_edge = [] for e in base_square_edge:
def __init__(self, name): name = "D:/DCSM-FM_100m/A06_pieter/DCSM-FM_100m_0008_map.nc" b = -35 nc = Dataset(name) x = nc.variables["mesh2d_face_x"][:b] y = nc.variables["mesh2d_face_y"][:b] WD1 = nc.variables["mesh2d_waterdepth"][:, :b] u1 = nc.variables["mesh2d_ucx"][:, :b] v1 = nc.variables["mesh2d_ucy"][:, :b] nodes1 = np.zeros((len(x), 2)) nodes1[:, 0] = y nodes1[:, 1] = x print("1/7") name = "D:/DCSM-FM_100m/A06_pieter/DCSM-FM_100m_0009_map.nc" a = 13 b = -101 nc = Dataset(name) x = nc.variables["mesh2d_face_x"][a:b] y = nc.variables["mesh2d_face_y"][a:b] WD2 = nc.variables["mesh2d_waterdepth"][:, a:b] u2 = nc.variables["mesh2d_ucx"][:, a:b] v2 = nc.variables["mesh2d_ucy"][:, a:b] nodes2 = np.zeros((len(x), 2)) nodes2[:, 0] = y nodes2[:, 1] = x nodes1 = np.concatenate((nodes1, nodes2), axis=0) WD1 = np.concatenate((WD1, WD2), axis=1) u1 = np.concatenate((u1, u2), axis=1) v1 = np.concatenate((v1, v2), axis=1) print("2/7") name = "D:/DCSM-FM_100m/A06_pieter/DCSM-FM_100m_0018_map.nc" b = -173 nc = Dataset(name) x = nc.variables["mesh2d_face_x"][:b] y = nc.variables["mesh2d_face_y"][:b] WD2 = nc.variables["mesh2d_waterdepth"][:, :b] u2 = nc.variables["mesh2d_ucx"][:, :b] v2 = nc.variables["mesh2d_ucy"][:, :b] nodes2 = np.zeros((len(x), 2)) nodes2[:, 0] = y nodes2[:, 1] = x nodes1 = np.concatenate((nodes1, nodes2), axis=0) WD1 = np.concatenate((WD1, WD2), axis=1) u1 = np.concatenate((u1, u2), axis=1) v1 = np.concatenate((v1, v2), axis=1) print("3/7") name = "D:/DCSM-FM_100m/A06_pieter/DCSM-FM_100m_0013_map.nc" a = -20000 b = -200 nc = Dataset(name) x = nc.variables["mesh2d_face_x"][a:b] y = nc.variables["mesh2d_face_y"][a:b] WD2 = nc.variables["mesh2d_waterdepth"][:, a:b] u2 = nc.variables["mesh2d_ucx"][:, a:b] v2 = nc.variables["mesh2d_ucy"][:, a:b] nodes2 = np.zeros((len(x), 2)) nodes2[:, 0] = y nodes2[:, 1] = x nodes1 = np.concatenate((nodes1, nodes2), axis=0) WD1 = np.concatenate((WD1, WD2), axis=1) u1 = np.concatenate((u1, u2), axis=1) v1 = np.concatenate((v1, v2), axis=1) print("4/7") name = "D:/DCSM-FM_100m/A06_pieter/DCSM-FM_100m_0007_map.nc" b = -300 nc = Dataset(name) x = nc.variables["mesh2d_face_x"][:b] y = nc.variables["mesh2d_face_y"][:b] WD2 = nc.variables["mesh2d_waterdepth"][:, :b] u2 = nc.variables["mesh2d_ucx"][:, :b] v2 = nc.variables["mesh2d_ucy"][:, :b] nodes2 = np.zeros((len(x), 2)) nodes2[:, 0] = y nodes2[:, 1] = x nodes1 = np.concatenate((nodes1, nodes2), axis=0) WD1 = np.concatenate((WD1, WD2), axis=1) u1 = np.concatenate((u1, u2), axis=1) v1 = np.concatenate((v1, v2), axis=1) print("5/7") name = "D:/DCSM-FM_100m/A06_pieter/DCSM-FM_100m_0019_map.nc" b = -12533 nc = Dataset(name) x = nc.variables["mesh2d_face_x"][:b] y = nc.variables["mesh2d_face_y"][:b] WD2 = nc.variables["mesh2d_waterdepth"][:, :b] u2 = nc.variables["mesh2d_ucx"][:, :b] v2 = nc.variables["mesh2d_ucy"][:, :b] nodes2 = np.zeros((len(x), 2)) nodes2[:, 0] = y nodes2[:, 1] = x nodes1 = np.concatenate((nodes1, nodes2), axis=0) WD1 = np.concatenate((WD1, WD2), axis=1) u1 = np.concatenate((u1, u2), axis=1) v1 = np.concatenate((v1, v2), axis=1) print("6/7") name = "D:/DCSM-FM_100m/A06_pieter/DCSM-FM_100m_0006_map.nc" a = -19000 + 149 b = -5649 nc = Dataset(name) x = nc.variables["mesh2d_face_x"][a:b] y = nc.variables["mesh2d_face_y"][a:b] WD2 = nc.variables["mesh2d_waterdepth"][:, a:b] u2 = nc.variables["mesh2d_ucx"][:, a:b] v2 = nc.variables["mesh2d_ucy"][:, 0:b] nodes2 = np.zeros((len(x), 2)) nodes2[:, 0] = y nodes2[:, 1] = x t = nc.variables["time"][:] t0 = "22/12/2012 00:00:00" d = datetime.strptime(t0, "%d/%m/%Y %H:%M:%S") t0 = d.timestamp() self.t = t + t0 nodes = np.concatenate((nodes1, nodes2), axis=0) WD = np.concatenate((WD1, WD2), axis=1) u = np.concatenate((u1, u2), axis=1) v = np.concatenate((v1, v2), axis=1) print("7/7") idx = np.unique(nodes, axis=0, return_index=True)[1] nodes = nodes[idx] WD = WD[:, idx] u = u[:, idx] v = v[:, idx] self.nodes = nodes self.WD = WD self.u = u self.v = v self.tria = Delaunay(self.nodes)
def alphashape(points, alpha=None): """ Compute the alpha shape (concave hull) of a set of points. If the number of points in the input is three or less, the convex hull is returned to the user. For two points, the convex hull collapses to a `LineString`; for one point, a `Point`. Args: points (list or ``shapely.geometry.MultiPoint`` or \ ``geopandas.GeoDataFrame``): an iterable container of points alpha (float): alpha value Returns: ``shapely.geometry.Polygon`` or ``shapely.geometry.LineString`` or ``shapely.geometry.Point`` or ``geopandas.GeoDataFrame``: \ the resulting geometry """ # If given a geodataframe, extract the geometry if USE_GP and isinstance(points, geopandas.GeoDataFrame): crs = points.crs points = points['geometry'] else: crs = None if not isinstance(points, MultiPoint): points = MultiPoint(list(points)) # If given a triangle for input, or an alpha value of zero or less, # return the convex hull. if len(points) < 4 or (alpha is not None and alpha <= 0): result = points.convex_hull if crs: gdf = geopandas.GeoDataFrame( geopandas.GeoSeries(result)).rename(columns={ 0: 'geometry' }).set_geometry('geometry') gdf.crs = crs return gdf else: return result # Determine alpha parameter if one is not given if alpha is None: try: from optimizealpha import optimizealpha except ImportError: from .optimizealpha import optimizealpha alpha = optimizealpha(points) coords = np.array([point.coords[0] for point in points]) tri = Delaunay(coords) edges = set() edge_points = [] # Loop over triangles for ia, ib, ic in tri.vertices: pa = coords[ia] pb = coords[ib] pc = coords[ic] # Lengths of sides of triangle a = math.sqrt((pa[0] - pb[0])**2 + (pa[1] - pb[1])**2) b = math.sqrt((pb[0] - pc[0])**2 + (pb[1] - pc[1])**2) c = math.sqrt((pc[0] - pa[0])**2 + (pc[1] - pa[1])**2) # Semiperimeter of triangle s = (a + b + c) * 0.5 # Area of triangle by Heron's formula # Precompute value inside square root to avoid unbound math error in # case of 0 area triangles. area = s * (s - a) * (s - b) * (s - c) if area > 0: area = math.sqrt(area) # Radius Filter if a * b * c / (4.0 * area) < 1.0 / alpha: for i, j in itertools.combinations([ia, ib, ic], r=2): if (i, j) not in edges and (j, i) not in edges: edges.add((i, j)) edge_points.append(coords[[i, j]]) # Create the resulting polygon from the edge points m = MultiLineString(edge_points) triangles = list(polygonize(m)) result = cascaded_union(triangles) # Convert to pandas geodataframe object if that is what was an input if crs: gdf = geopandas.GeoDataFrame( geopandas.GeoSeries(result)).rename(columns={ 0: 'geometry' }).set_geometry('geometry') gdf.crs = crs return gdf else: return result
def unstructured_network_periodic_y(nr_pores, domain_size=None, quasi_2d=False): r_min, r_max = 20e-6, 75e-6 pdf_pore_radius = beta(1.25, 1.5, loc=r_min, scale=(r_max - r_min)) r_min, r_max = 1e-6, 25e-6 pdf_tube_radius = beta(1.5, 2, loc=r_min, scale=(r_max - r_min)) if domain_size is None: if quasi_2d: r_max = 75e-6 domain_length = (4. / 3. * np.pi * r_max**3 * nr_pores)**(1. / 3.) domain_size = [ 2 * domain_length, 2 * domain_length, domain_length / 4. ] else: r_max = 75e-6 domain_length = (4. / 3. * np.pi * r_max**3 * nr_pores)**(1. / 3.) domain_size = [2 * domain_length, domain_length, domain_length] rad_generated = pdf_pore_radius.rvs(size=nr_pores) x_coord, y_coord, z_coord, rad = sphere_packing(rad=rad_generated, domain_size=domain_size) x_coord_dup = np.tile(x_coord, 3) y_coord_dup = np.hstack( [y_coord, y_coord + domain_size[1], y_coord - domain_size[1]]) z_coord_dup = np.tile(z_coord, 3) origin_id = np.hstack( [np.arange(nr_pores), np.arange(nr_pores), np.arange(nr_pores)]) marker = np.hstack( [np.ones(nr_pores), np.zeros(nr_pores), np.zeros(nr_pores)]).astype(np.int) points = zip(x_coord_dup, y_coord_dup, z_coord_dup) tri = Delaunay(points) indices, indptr = tri.vertex_neighbor_vertices csr_mat = csr_matrix( (np.ones(len(indptr)), np.asarray(indptr), np.asarray(indices)), shape=(nr_pores * 3, nr_pores * 3)) coo_mat = csr_mat.tocoo() edgelist_1 = coo_mat.row[coo_mat.row < coo_mat.col] edgelist_2 = coo_mat.col[coo_mat.row < coo_mat.col] length = np.sqrt((x_coord_dup[edgelist_1] - x_coord_dup[edgelist_2])**2 + (y_coord_dup[edgelist_1] - y_coord_dup[edgelist_2])**2 + (z_coord_dup[edgelist_1] - z_coord_dup[edgelist_2])**2) edge_ids_short = (length < np.max(rad) * 4).nonzero()[0] edgelist_1_short = edgelist_1[edge_ids_short] edgelist_2_short = edgelist_2[edge_ids_short] length = np.sqrt( (x_coord_dup[edgelist_1_short] - x_coord_dup[edgelist_2_short])**2 + (y_coord_dup[edgelist_1_short] - y_coord_dup[edgelist_2_short])**2 + (z_coord_dup[edgelist_1_short] - z_coord_dup[edgelist_2_short])**2) minlen_edge = min(length) edge_ids_truncated = (marker[edgelist_1_short] | marker[edgelist_2_short]).nonzero()[0] # Remove edges not leading in original domain row = edgelist_1_short[edge_ids_truncated] col = edgelist_2_short[edge_ids_truncated] # Convert ids of edges row = origin_id[row] col = origin_id[col] edgelist_1 = row[row < col] edgelist_2 = col[row < col] edgelist = np.vstack([edgelist_1, edgelist_2]).T y_diff = np.minimum( abs(x_coord[edgelist_1] - x_coord[edgelist_2]), domain_size[0] - y_coord[edgelist_1] + y_coord[edgelist_2]) y_diff = np.minimum( y_diff, domain_size[0] - y_coord[edgelist_2] + y_coord[edgelist_1]) length = np.sqrt((x_coord[edgelist_1] - x_coord[edgelist_2])**2 + (y_diff)**2 + (z_coord[edgelist_1] - z_coord[edgelist_2])**2) length = np.maximum(length, minlen_edge) rad_tubes = pdf_tube_radius.rvs(size=len(edgelist_1)) network = StructuredPoreNetwork([1, 1, 1], 1.0e-16) network.add_pores(x_coord, y_coord, z_coord, rad) network.add_throats(edgelist + 1, r=rad_tubes, l=length, G=np.ones(len(edgelist_1)) / 16.0) network._fix_tubes_larger_than_ngh_pores() network = prune_network(network, [0.1, 0.9, -0.1, 1.1, 0.1, 0.9]) network = reorder_network(network) return network
def _get_hull_volume(points): r""" Calculate the volume of a set of points by dividing the bounding surface into triangles and working out the volume of all the pyramid elements connected to the volume centroid """ # Remove any duplicate points - this messes up the triangulation points = _sp.asarray(misc.unique_list(np.around(points, 10))) try: tri = Delaunay(points, qhull_options='QJ Pp') except _sp.spatial.qhull.QhullError: logger.error("Volume suspect for points: " + str(points)) # We only want points included in the convex hull to calculate the centroid hull_centroid = _sp.array( [points[:, 0].mean(), points[:, 1].mean(), points[:, 2].mean()]) hull_volume = 0.0 pyramid_COMs = [] for ia, ib, ic in tri.convex_hull: # Points making each triangular face # Collection of co-ordinates of each point in this face face_x = points[[ia, ib, ic]][:, 0] face_y = points[[ia, ib, ic]][:, 1] face_z = points[[ia, ib, ic]][:, 2] # Average of each co-ordinate is the centroid of the face face_centroid = [face_x.mean(), face_y.mean(), face_z.mean()] face_centroid_vector = face_centroid - hull_centroid # Vectors of the sides of the face used to find normal vector and area vab = points[ib] - points[ia] vac = points[ic] - points[ia] vbc = points[ic] - points[ib] # As vectors are co-planar the cross-product will produce the normal # vector of the face face_normal = _sp.cross(vab, vac) try: face_unit_normal = face_normal / _sp.linalg.norm(face_normal) except RuntimeWarning: logger.error('Pore Volume Error:' + str(vab) + ' ' + str(vac)) """ As triangles are orientated randomly in 3D we could either transform co-ordinates to align with a plane and perform 2D operations to work out the area or we could work out the lengths of each side and use Heron's formula which is easier. Using Delaunay traingulation will always produce triangular faces but if dealing with other polygons co-ordinate transfer may be necessary """ a = _sp.linalg.norm(vab) b = _sp.linalg.norm(vbc) c = _sp.linalg.norm(vac) # Semiperimeter s = 0.5 * (a + b + c) face_area = _sp.sqrt(s * (s - a) * (s - b) * (s - c)) # Now the volume of the pyramid section defined by the 3 face points # and the hull centroid can be calculated " pyramid_volume = _sp.absolute( _sp.dot(face_centroid_vector, face_unit_normal) * face_area / 3) # Each pyramid is summed together to calculate the total volume hull_volume += pyramid_volume # The Centre of Mass will not be the same as the geometrical centroid. # Weighted adjustment is calculated from pyramid centroid and volume. vha = points[ia] - hull_centroid vhb = points[ib] - hull_centroid vhc = points[ic] - hull_centroid pCOM = ((vha + vhb + vhc) / 4) * pyramid_volume pyramid_COMs.append(pCOM) if _sp.isnan(hull_volume): hull_volume = 0.0 if hull_volume > 0: hull_COM = hull_centroid + _sp.mean(_sp.asarray(pyramid_COMs), axis=0) / hull_volume else: hull_COM = hull_centroid return hull_volume, hull_COM
def predict_hinge(atoms, outputfile, Alpha=float('Inf'),method='AlphaShape',GenerateKirchoff=False,filename='Output.pdb',MinimumHingeLength=5,nclusters=4): """This function is used to carry out hinge prediction given the parameters. Notes: * The packman.bin.PACKMAN uses this function * Ideally, the alpha values should be scanned from 0 to 10 to obtain conclusively repetative hinges (Use '' for this purpose) * Please refer to the following paper for the details on the algorithm and citation: Pranav M. Khade, Ambuj Kumar, Robert L. Jernigan, Characterizing and Predicting Protein Hinges for Mechanistic Insight, Journal of Molecular Biology, Volume 432, Issue 2, 2020, Pages 508-522, ISSN 0022-2836, https://doi.org/10.1016/j.jmb.2019.11.018. (http://www.sciencedirect.com/science/article/pii/S0022283619306837) * Tutorial Link: * The predicted hinges are stored in packman.molecule.Chain object as an packman.molecule.Hinge object. Todo: * Add reference to the function in the description which scans multiple alpha values for conclusive hinges. * Remove GenerateKirchoff parameter and sections Args: atoms ([packman.molecule.Atom]) : PACKMAN uses backbone atoms of the protein. However, any number and type of atoms can be used (Alpha value range will change) outputfile (file) : Output File. Alpha (float, optional) : Please refer to the paper for this parameter. Defaults to float('Inf'). method (str, optional) : Please refer to the paper for this parameter. Defaults to 'AlphaShape'. GenerateKirchoff (bool, optional) : Soon to be removed. Defaults to False. filename (str, optional) : Please refer to the paper for this parameter. Defaults to 'Output.pdb'. MinimumHingeLength (int, optional): Please refer to the paper for this parameter. Defaults to 5. nclusters (int, optional) : Please refer to the paper for this parameter. Defaults to 4. Returns: SelectedTesselations : The Alpha Shape (Subset of Delaunay Tesselations) """ if(method=='AlphaShape'): def GetCircumsphere(Tetrahydron): """Get the Circumsphere of the set of four points. Given any four three dimentional points, this function calculates the features of the circumsphere having the given four points on it's surface. Notes: * Function level: 1 (1 being top) * DistanceToSurface will be removed in future. * Possible to move this to geometrical package in future. Args: Tetrahydron ([type]): [description] Returns: [Centre, Radius, DistanceToSurface] (float): The 3D coordinates of the geometrical center of the given four points, Radius of the circumsphere made up of given four points, Distance to the center (in that order) """ alpha_mat,gamma_mat,Dx_mat,Dy_mat,Dz_mat=[],[],[],[],[] for i in Tetrahydron: temp_coords=i.get_location() alpha_mat.append([temp_coords[0],temp_coords[1],temp_coords[2],1]) gamma_mat.append([temp_coords[0]**2+temp_coords[1]**2+temp_coords[2]**2,temp_coords[0],temp_coords[1],temp_coords[2]]) Dx_mat.append([temp_coords[0]**2+temp_coords[1]**2+temp_coords[2]**2,temp_coords[1],temp_coords[2],1]) Dy_mat.append([temp_coords[0]**2+temp_coords[1]**2+temp_coords[2]**2,temp_coords[0],temp_coords[2],1]) Dz_mat.append([temp_coords[0]**2+temp_coords[1]**2+temp_coords[2]**2,temp_coords[0],temp_coords[1],1]) alpha=numpy.linalg.det(alpha_mat) gamma=numpy.linalg.det(gamma_mat) Dx=(+numpy.linalg.det(Dx_mat)) Dy=(-numpy.linalg.det(Dy_mat)) Dz=(+numpy.linalg.det(Dz_mat)) Centre=numpy.array([Dx/2*alpha,Dy/2*alpha,Dz/2*alpha]) Radius=numpy.sqrt(Dx**2 + Dy**2 + Dz**2 - 4*alpha*gamma)/(2*numpy.absolute(alpha)) DistanceToSurface=numpy.linalg.norm(Centre-AllAtoms[a].get_location()) return Centre,Radius,DistanceToSurface def AlphaTest(atoms,Alpha,Centre,CircumRadius,DistanceToSurface,Tree=None): """Alpha Test as per the paper. Notes: * Function level: 1 (1 being top) * Confirm is sphere hollowness should be checked or it is covered by tesselations. * For more information on the alpha shape, read the following paper: EdelsbrunnerandE. P. M ̈ucke.Three-dimensional alpha shapes. Manuscript UIUCDCS-R-92-1734, Dept.Comput.Sci. ,Univ.Illinois, Urbana-Champaign, IL, 1992. Todo: * Remove multiple unused parameters Args: atoms ([packman.molecule.Atom]): Set of atoms. (Read parent method description) Alpha (float) : Alpha. (Read parent method description) Centre ([float]) : Centre of the circumsphere. (Read parent method description) CircumRadius ([float]) : Circumradius of the circumsphere. (Read parent method description) DistanceToSurface ([float]) : Distance to the surface (Will be removed) Tree ([scipy.KDTree], optional): KDTree of the atoms. Defaults to None. (Will be removed) Returns: bool: True if alpha test is passed. False otherwise. """ if(CircumRadius<Alpha): return True else: return False def GetStats(atoms,SelectedHingeResidues,filename='Output'): """This sub-method is used to get the statistical data on the hinges and print it into a file. Notes: * * Function level: 1 (1 being top) * Do something about the output file Args: atoms ([packman.molecule.Atom]) : Set of atoms. (Read parent method description) SelectedHingeResidues ([packman.molecule.Residue]): Predicted hinge residues. filename (str, optional) : Output file name. Defaults to 'Output'. Returns: [p-value, stats] (float): p-value of the predicted hinge, statistics of the hinge (in that order) """ hinge_atoms=[i.get_backbone() for i in SelectedHingeResidues] hinge_atoms=[item for sublist in hinge_atoms for item in sublist] non_hinge_atoms=list(set([i for i in atoms])-set(hinge_atoms)) all_atoms_bfactor=[i.get_bfactor() for i in atoms] hinge_atoms_bfactor=[i.get_bfactor() for i in hinge_atoms] non_hinge_atoms_bfactor=[i.get_bfactor() for i in non_hinge_atoms] return_stats=[] outputfile.write('\nSTATISTICS\n\t\tN\tMin\tMax\tMean\tMode\tMedian\tSTDDev\n') return_stats.append(['','N','Min','Max','Mean','Mode','Median','STDDev']) outputfile.write('Total '+'\t'+str(len(all_atoms_bfactor))+'\t'+str(numpy.min(all_atoms_bfactor))+'\t'+str(numpy.max(all_atoms_bfactor))+'\t'+str(numpy.mean(all_atoms_bfactor))+'\t'+str(mode(all_atoms_bfactor)[0][0])+'\t'+str(numpy.median(all_atoms_bfactor))+'\t'+str(numpy.std(all_atoms_bfactor))+'\n') return_stats.append(['Total',len(all_atoms_bfactor),numpy.min(all_atoms_bfactor),numpy.max(all_atoms_bfactor),numpy.mean(all_atoms_bfactor),mode(all_atoms_bfactor)[0][0],numpy.median(all_atoms_bfactor),numpy.std(all_atoms_bfactor)]) outputfile.write('Hinge '+'\t'+str(len(hinge_atoms_bfactor))+'\t'+str(numpy.min(hinge_atoms_bfactor))+'\t'+str(numpy.max(hinge_atoms_bfactor))+'\t'+str(numpy.mean(hinge_atoms_bfactor))+'\t'+str(mode(hinge_atoms_bfactor)[0][0])+'\t'+str(numpy.median(hinge_atoms_bfactor))+'\t'+str(numpy.std(hinge_atoms_bfactor))+'\n') return_stats.append(['Hinge',len(hinge_atoms_bfactor),numpy.min(hinge_atoms_bfactor),numpy.max(hinge_atoms_bfactor),numpy.mean(hinge_atoms_bfactor),mode(hinge_atoms_bfactor)[0][0],numpy.median(hinge_atoms_bfactor),numpy.std(hinge_atoms_bfactor)]) outputfile.write('NonHinge'+'\t'+str(len(non_hinge_atoms_bfactor))+'\t'+str(numpy.min(non_hinge_atoms_bfactor))+'\t'+str(numpy.max(non_hinge_atoms_bfactor))+'\t'+str(numpy.mean(non_hinge_atoms_bfactor))+'\t'+str(mode(non_hinge_atoms_bfactor)[0][0])+'\t'+str(numpy.median(non_hinge_atoms_bfactor))+'\t'+str(numpy.std(non_hinge_atoms_bfactor))+'\n') return_stats.append(['NonHinge',len(non_hinge_atoms_bfactor),numpy.min(non_hinge_atoms_bfactor),numpy.max(non_hinge_atoms_bfactor),numpy.mean(non_hinge_atoms_bfactor),mode(non_hinge_atoms_bfactor)[0][0],numpy.median(non_hinge_atoms_bfactor),numpy.std(non_hinge_atoms_bfactor)]) p_value = permutation_test(hinge_atoms_bfactor, non_hinge_atoms_bfactor,method='approximate',num_rounds=10000,seed=0) outputfile.write('\np-value:\t'+str(p_value)+'\n') return p_value,return_stats def GetLeastSquarePlane(atoms,HingeResidues,HingePlane): """This sub-function gives the Least Square Plane equation of the given atoms. This plane is currently gives us an idea about the possible direction of the movement of the hinge residues (See figures in the publication) Todo: * Change the name of the parameter HingePlane (It is misleading) Notes: * Function level: 1 (1 being top) * Possibly will be moved to geometry module later. * Check the output file for this equation. The instructions to visualize this plane are given at the end of the file. Args: atoms ([packman.molecule.Atom]) : Set of atoms. (Read parent method description) HingeResidues ([packman.molecule.Residue]): Predicted hinge residues. HingePlane (int) : Index of the HingePlane Returns: [a,b,c,d]: Four coefficients essential to define the plane in 3D space. """ hinge_points=[item.get_location() for sublist in [i.get_backbone() for i in HingeResidues] for item in sublist] HingeAtoms=[item for sublist in [i.get_backbone() for i in HingeResidues] for item in sublist] NonHingeAtoms=[i.get_location() for i in atoms if i not in HingeAtoms] #Zipping the values hinge_xs,hinge_ys,hinge_zs = zip(*hinge_points) XS,YS,ZS=zip(*NonHingeAtoms) def project_points(x, y, z, a, b, c): """Project the points on a given plane Projects the points with coordinates x, y, z onto the plane defined by a*x + b*y + c*z = 1 Todo: * Explain the returning variables properly Notes: * Function level: 2 (1 being top) * Possibly will be moved to the geometry module Args: x (float): X-coordinate of the point to be projected on the plane. y (float): Y-coordinate of the point to be projected on the plane. z (float): Z-coordinate of the point to be projected on the plane. a (float): X-component of the plane. b (float): Y-component of the plane. c (float): Z-component of the plane. Returns: Neccesary information to project the points on the given plane. """ vector_norm = a*a + b*b + c*c normal_vector = numpy.array([a, b, c]) / numpy.sqrt(vector_norm) point_in_plane = numpy.array([a, b, c]) / vector_norm points = numpy.column_stack((x, y, z)) points_from_point_in_plane = points - point_in_plane proj_onto_normal_vector = numpy.dot(points_from_point_in_plane,normal_vector) proj_onto_plane = (points_from_point_in_plane - proj_onto_normal_vector[:, None]*normal_vector) return point_in_plane + proj_onto_plane def FitPlane(points): """Plane fitting algorithm given the points. Notes: * Function level: 2 (1 being top) Args: points ([float]): Two dimentional array of 3D points Returns: [a,b,c,d] (float) : Numbers essential to define the Least Square Plane equation """ xs,ys,zs = zip(*points) def plane(x, y, params): """Plane Object Args: x ([type]): [description] y ([type]): [description] params ([type]): [description] Returns: [float]: Equation of the plane """ a = params[0] b = params[1] c = params[2] z = a*x + b*y + c return z def error(params, points): """Get the error Args: params ([type]): [description] points ([type]): [description] Returns: [type]: [description] """ result = 0 for (x,y,z) in points: plane_z = plane(x, y, params) diff = abs(plane_z - z) result += diff**2 return result def cross(a, b): """Get cross Args: a ([type]): [description] b ([type]): [description] Returns: [type]: [description] """ return [a[1]*b[2] - a[2]*b[1], a[2]*b[0] - a[0]*b[2], a[0]*b[1] - a[1]*b[0]] fun = functools.partial(error, points=points) params0 = [0, 0, 0] res = minimize(fun, params0) a = res.x[0] b = res.x[1] c = res.x[2] point = numpy.array([0.0, 0.0, c]) normal = numpy.array(cross([1,0,a], [0,1,b])) d = -point.dot(normal) xx, yy = numpy.meshgrid([min(xs),max(xs)], [min(ys),max(ys)]) z = (-normal[0] * xx - normal[1] * yy - d) * 1. /normal[2] #Three points on the plane p1=numpy.array([numpy.mean(xx[0]),numpy.mean(yy[:,0]),numpy.mean(z)]) p2=numpy.array([xx[0][0], yy[0][1], z[0][0]]) p3=numpy.array([xx[0][1], yy[0][0], z[0][1]]) p4=numpy.array([xx[1][0], yy[1][1], z[1][0]]) #Two vectors in the plane v1=p3-p1 v2=p2-p1 #vector normal to the plane cp = numpy.cross(v1, v2) a, b, c = cp # This evaluates a * x3 + b * y3 + c * z3 which equals d d = numpy.dot(cp, p3) a,b,c,d=a/d,b/d,c/d,d/d #outputfile.write('The equation is {0}x + {1}y + {2}z = {3}'.format(a, b, c, d)) #Plane in PyMol outputfile.write('import plane\n') outputfile.write('plane.make_plane_points(name=\'HingePlane'+ str(HingePlane) +'\', l1='+str(list(p4))+', l2='+str(list(p2))+', l3='+str(list(p3))+', center=False, makepseudo=False)'+'\n') outputfile.write('set cgo_transparency, 0.35, HingePlane'+str(HingePlane)+'\n') return a,b,c,d a,b,c,d=FitPlane(hinge_points) projected=project_points(hinge_xs,hinge_ys,hinge_zs,a,b,c) return projected AllAtoms=[i for i in atoms] AlphaKirchoff=numpy.zeros((len(AllAtoms),len(AllAtoms))) DelaunayTesssellation=Delaunay([i.get_location() for i in AllAtoms]) SelectedTesselations=[] ProteinGraph=nx.Graph() if(GenerateKirchoff): Tree=KDTree([i.get_location() for i in AllAtoms]) for a,b,c,d in DelaunayTesssellation.vertices: Tetrahydron=[AllAtoms[a],AllAtoms[b],AllAtoms[c],AllAtoms[d]] Centre,Radius,DistanceToSurface=GetCircumsphere(Tetrahydron) #Alpha Test if(AlphaTest(AllAtoms,Alpha,Centre,Radius,DistanceToSurface,Tree=Tree)): ProteinGraph.add_nodes_from([a,b,c,d]) ProteinGraph.add_edges_from([(a,b),(a,c),(a,d),(b,c),(b,d),(c,d)]) SelectedTesselations.append([AllAtoms[a],AllAtoms[b],AllAtoms[c],AllAtoms[d]]) AlphaKirchoff[a][b]=1 AlphaKirchoff[a][c]=1 AlphaKirchoff[a][d]=1 AlphaKirchoff[b][a]=1 AlphaKirchoff[b][c]=1 AlphaKirchoff[b][d]=1 AlphaKirchoff[c][a]=1 AlphaKirchoff[c][b]=1 AlphaKirchoff[c][d]=1 AlphaKirchoff[d][a]=1 AlphaKirchoff[d][b]=1 AlphaKirchoff[d][c]=1 for numi,i in enumerate(AlphaKirchoff): AlphaKirchoff[numi][numi]=numpy.sum(i) else: for a,b,c,d in DelaunayTesssellation.vertices: Tetrahydron=[AllAtoms[a],AllAtoms[b],AllAtoms[c],AllAtoms[d]] Centre,Radius,DistanceToSurface=GetCircumsphere(Tetrahydron) #Alpha Test if(AlphaTest(AllAtoms,Alpha,Centre,Radius,DistanceToSurface)): ProteinGraph.add_nodes_from([a,b,c,d]) ProteinGraph.add_edges_from([(a,b),(a,c),(a,d),(b,c),(b,d),(c,d)]) SelectedTesselations.append([AllAtoms[a],AllAtoms[b],AllAtoms[c],AllAtoms[d]]) centrality=nx.eccentricity(ProteinGraph) centrality_sorted_with_keys=numpy.array([float(centrality[j]) for j in sorted([i for i in centrality.keys()])]).reshape(-1, 1) #Cluster (4 is like a resolution here) km=KMeans(n_clusters=nclusters) km.fit(centrality_sorted_with_keys) central_nodes=numpy.argwhere(km.labels_==numpy.argmin(km.cluster_centers_)).T[0] HingeResidues=list(set([atoms[i].get_parent() for i in central_nodes])) HingeResiduesID=[i.get_id() for i in HingeResidues] SortedHingeResidues=[x for _,x in sorted(zip(HingeResiduesID,HingeResidues))] HingeResiduesID=[i.get_id() for i in SortedHingeResidues] PredictedHinges=[] for i,j in groupby(HingeResiduesID,lambda n, c=count(): n-next(c)): Local_Hinge=[k for k in j] if(len(Local_Hinge)>MinimumHingeLength): PredictedHinges.append(SortedHingeResidues[HingeResiduesID.index(Local_Hinge[0]):HingeResiduesID.index(Local_Hinge[-1])+1]) #Print part Hinges=[] Chains=','.join(list(set([i.get_parent().get_id() for i in SortedHingeResidues]))) outputfile.write('Filename= '+str(filename)+'\t| Chain(s)= '+Chains+'\t| AlphaValue= '+str(Alpha)+'\t| MinimumHingeLength= '+str(MinimumHingeLength)+'\t| EccentricityClusters= '+str(nclusters)+ '\n') outputfile.write('Hindge Residues(Predicted):\n') for numi,i in enumerate(PredictedHinges): #Assigning domain IDs for _ in i:_.set_domain_id('FL'+str(numi)) #Molecule.Hinge(numi,elements,stats,p) outputfile.write('\nHinge #'+str(numi+1)+'\nResidues: '+i[0].get_name()+'-'+str(i[0].get_id()) +' to '+i[-1].get_name()+'-'+str(i[-1].get_id())+'\n') p_value,hstats=GetStats(atoms,i,filename=filename) outputfile.write('\nPymol Terminal Commands for Visualizing:\ncolor blue, resi '+str(i[0].get_id())+':'+str(i[-1].get_id())+'\n') GetLeastSquarePlane(atoms,i,numi+1) outputfile.write("#--------------------------------------------------#\n") #HingeObject Hinges.append( Hinge(numi,i,hstats,p_value)) #Assigning domain IDs AllChainResidues=[i for i in HingeResidues[0].get_parent().get_residues()] #If sorting is needed #AllChainResiduesID=[i.get_id() for i in AllChainResidues] #print([i.get_id() for i in AllChainResidues]) #AllChainResidues=[x for _,x in sorted(zip(AllChainResiduesID,AllChainResidues))] DomainNumber,flag=0,True for i in AllChainResidues: if(i.get_domain_id()==None): i.set_domain_id('DM'+str(DomainNumber)) flag=True elif(i.get_domain_id()[:2]=='FL' and flag): DomainNumber+=1 flag=False AllChainResidues[0].get_parent().set_hinges(Hinges) if(GenerateKirchoff): return AlphaKirchoff,SelectedTesselations else: return SelectedTesselations