Example #1
0
    def get_wigner_seitz_cell(self):
        """
        Returns the Wigner-Seitz cell for the given lattice.

        Returns:
            A list of list of coordinates.
            Each element in the list is a "facet" of the boundary of the
            Wigner Seitz cell. For instance, a list of four coordinates will
            represent a square facet.
        """
        from pyhull.voronoi import VoronoiTess
        vec1 = self.matrix[0]
        vec2 = self.matrix[1]
        vec3 = self.matrix[2]

        list_k_points = []
        for i, j, k in itertools.product([-1, 0, 1], [-1, 0, 1], [-1, 0, 1]):
            list_k_points.append(i * vec1 + j * vec2 + k * vec3)
        tess = VoronoiTess(list_k_points)
        to_return = []
        for r in tess.ridges:
            if r[0] == 13 or r[1] == 13:
                to_return.append([tess.vertices[i] for i in tess.ridges[r]])

        return to_return
Example #2
0
 def _set_voronoi_bond_orders(self):
     '''
     approximate bond order, from purely geometric voronoi solid angles'
     returns
     def bond_order(cd):
     '''
     p = self.positions
     bond_orders = []
     o_index = p.shape[1] / 2
     n_images = p.shape[1]
     for i in range(p.shape[2]):
         #[atomj * image, axis]
         vt = VoronoiTess(p[:, :, i].reshape((-1, 3)))
         bo = np.zeros([p.shape[0] * p.shape[1]] * 2)
         vts = np.array(vt.vertices)
         for (k1, k2), v in vt.ridges.items():
             if (k1 % n_images != o_index) and (k2 % n_images != o_index):
                 continue
             if -10.101 in vts[v]:
                 continue
             val = solid_angle(vt.points[k1], vts[v])
             bo[k1, k2] = val
             bo[k2, k1] = val
         nshape = (p.shape[0], p.shape[0], p.shape[1], 1)
         bond_orders.append(bo[o_index::n_images].reshape(nshape))
     self._voronoi_bond_orders = np.concatenate(bond_orders, -1)
Example #3
0
    def setup_voronoi_list(self, indices, voronoi_cutoff):
        """
        Set up of the voronoi list of neighbours by calling qhull
        :param indices: indices of the sites for which the Voronoi is needed
        :param voronoi_cutoff: Voronoi cutoff for the search of neighbours
        :raise RuntimeError: If an infinite vertex is found in the voronoi construction
        """
        self.voronoi_list = [None] * len(self.structure)
        logging.info('Getting all neighbors in structure')
        struct_neighbors = self.structure.get_all_neighbors(voronoi_cutoff,
                                                            include_index=True)
        t1 = time.clock()
        logging.info('Setting up Voronoi list :')

        for jj, isite in enumerate(indices):
            logging.info(
                '  - Voronoi analysis for site #{:d} ({:d}/{:d})'.format(
                    isite, jj + 1, len(indices)))
            site = self.structure[isite]
            neighbors1 = [(site, 0.0, isite)]
            neighbors1.extend(struct_neighbors[isite])
            distances = [i[1] for i in sorted(neighbors1, key=lambda s: s[1])]
            neighbors = [i[0] for i in sorted(neighbors1, key=lambda s: s[1])]
            qvoronoi_input = [s.coords for s in neighbors]
            voro = VoronoiTess(qvoronoi_input)
            all_vertices = voro.vertices

            results = []
            maxangle = 0.0
            mindist = 10000.0
            for nn, vind in list(voro.ridges.items()):
                if 0 in nn:
                    if 0 in vind:
                        raise RuntimeError("This structure is pathological,"
                                           " infinite vertex in the voronoi "
                                           "construction")

                    facets = [all_vertices[i] for i in vind]
                    try:
                        sa = solid_angle(site.coords, facets)
                    except ValueError:
                        sa = my_solid_angle(site.coords, facets)
                    maxangle = max([sa, maxangle])
                    mindist = min([mindist, distances[nn[1]]])
                    for iii, sss in enumerate(self.structure):
                        if neighbors[nn[1]].is_periodic_image(sss):
                            myindex = iii
                            break
                    results.append((neighbors[nn[1]], {
                        'angle': sa,
                        'distance': distances[nn[1]],
                        'index': myindex
                    }))
            for (nn, dd) in results:
                dd['weighted_angle'] = dd['angle'] / maxangle
                dd['weighted_distance'] = dd['distance'] / mindist
            self.voronoi_list[isite] = results
        t2 = time.clock()
        logging.info('Voronoi list set up in {:.2f} seconds'.format(t2 - t1))
Example #4
0
def voroArea(topAtoms, qry, maxX, maxY):
    topCRDs = topAtoms.coordinates()

    #convert 3D to 2D: extractig X and Y axis
    topCRDs = selCoord(topCRDs, [0, 1])
    topPoints = getNumPoints(topAtoms, qry)

    uq_resNames = topPoints[0]
    # Residues names in the given system
    uq_numAtoms = topPoints[1]
    # the number of selected atoms corresponding to residue names

    # calculating voronoi tessellation
    voro = VoronoiTess(topCRDs)
    voro_vtex = voro.vertices
    voro_regn = voro.regions

    # calculating area per lipids
    resIDs = topAtoms.resids()
    # obtaining residue ids
    resNames = topAtoms.resnames()

    # initializing array
    areaLipids = [0] * (len(resIDs) + 1)
    # each array will be used for individual lipid area and last one will be the average area

    res_cnt = 0
    # residue count
    num_atoms = 0
    # number of atoms corresponding to the current residue name
    crd_idx = 0
    # coordinate index
    for res_name in resNames:
        # find corresponding residue
        num_atoms = uq_numAtoms[uq_resNames.index(res_name)]
        #calculating the area corresponding to the point
        atom_cnt = 0
        myarea = 0.0
        for dummy in range(num_atoms):
            print crd_idx
            my_region = getPos(voro_regn[crd_idx])
            liparea = crdArea(my_region, voro_vtex, maxX, maxY)
            print liparea
            crd_idx = crd_idx + 1
            myarea = myarea + liparea
        areaLipids[res_cnt] = myarea
        res_cnt = res_cnt + 1
    areaLipids[len(areaLipids) - 1] = sum(areaLipids) / res_cnt
    print crd_idx
    print len(topCRDs)
    return areaLipids
Example #5
0
 def get_wigner_seitz(self):
     if HAS_PYHULL:
         from pyhull.voronoi import VoronoiTess
         points = []
         for i, j, k in itertools.product((-1, 0, 1), repeat=3):
             points.append(i * self.cell[0] + j * self.cell[1] + k * self.cell[2])
         tess = VoronoiTess(points)
         ret = []
         for r in tess.ridges:
             if r[0] == 13 or r[1] == 13:
                 ret.append([tess.vertices[i] for i in tess.ridges[r]])
         return ret
     else:
         raise NotImplementedError
Example #6
0
    def setUp(self):
        data = [[0, 0], [-0.5, -0.5], [-0.5, 0.5], [0.5, -0.5], [0.5, 0.5]]
        self.voro = VoronoiTess(data)
        sphere_data = [
            [0.3927286959385721, 0.3027233106882571, -0.0642087887467873],
            [-0.3040289937812381, 0.08411211324060132, -0.3879323695524365],
            [-0.4167147320140305, -0.1124203247935928, 0.252409395022804],
            [-0.09784613055257477, 0.3994051836806832, 0.2844321254445218],
            [0.0167085276338464, 0.4969839143091518, 0.05222847903455247],
            [-0.3010383814570601, 0.3973744439739354, 0.03833332970300512],
            [0.321916886905792, -0.3514017778986294, -0.1512822144687402],
            [-0.02357104947939958, 0.4654006301246191, -0.1812364728912125],
            [0.3199720537828011, -0.3299443654301472, -0.1968618818332127],
            [-0.4630278928730662, -0.1886147011806086, 0.005446551209538857]
        ]
        self.spvoro = VoronoiTess(sphere_data)

        #Make sure higher dim works.
        points = np.random.randn(10, 5)
        self.hdvoro = VoronoiTess(points)

        #Check that bad points raises an error.
        bad_points = [[0, 0], [0, 1, 0], [0, 0]]
        self.assertRaises(ValueError, VoronoiTess, bad_points)
Example #7
0
    def connectivity_array(self):
        """
        Provides connectivity array.

        Returns:
            connectivity: An array of shape [atomi, atomj, imagej]. atomi is
            the index of the atom in the input structure. Since the second
            atom can be outside of the unit cell, it must be described
            by both an atom index and an image index. Array data is the
            solid angle of polygon between atomi and imagej of atomj
        """
        #shape = [site, axis]
        cart_coords = np.array(self.s.cart_coords)
        #shape = [site, image, axis]
        all_sites = cart_coords[:, None, :] + self.cart_offsets[None, :, :]
        vt = VoronoiTess(all_sites.reshape((-1, 3)))
        n_images = all_sites.shape[1]
        cs = (len(self.s), len(self.s), len(self.cart_offsets))
        connectivity = np.zeros(cs)
        vts = np.array(vt.vertices)
        for (ki, kj), v in vt.ridges.items():
            atomi = ki // n_images
            atomj = kj // n_images

            imagei = ki % n_images
            imagej = kj % n_images

            if imagei != n_images // 2 and imagej != n_images // 2:
                continue

            if imagei == n_images // 2:
                #atomi is in original cell
                val = solid_angle(vt.points[ki], vts[v])
                connectivity[atomi, atomj, imagej] = val

            if imagej == n_images // 2:
                #atomj is in original cell
                val = solid_angle(vt.points[kj], vts[v])
                connectivity[atomj, atomi, imagei] = val

            if -10.101 in vts[v]:
                warn('Found connectivity with infinite vertex. '
                     'Cutoff is too low, and results may be '
                     'incorrect')
        return connectivity
    def generate_tesselation(self):
        """Generate and return the tesselation as prescribed by the arguments of the __init__() function
        
        Returns
        -------
        
        random_mesh : Mesh type
            a mesh object with based on random voronoi seeds of the requested size, 
            and where the requested number of Lloyd relaxation steps has been applied
        
        """

        # First, we generate an initial tesselation. This is where the random seeds are made and the internal
        # mesh variable are first written
        self.generate_initial_tesselation()

        # if the user does not request relaxation steps, just return this mesh
        if (self.number_of_relaxation_steps == 0):
            # we need to crop the mesh before we return it, i.e. cut of the regions and cells that we added
            # to hide boundary effects
            return self.crop_and_return_mesh()
        else:
            # if relaxation steps are required we perform them
            for iteration in range(self.number_of_relaxation_steps):

                # get the centroids of the existing mesh
                centroid_positions = []
                for element in self.mesh.elements:
                    centroid_positions.append(element.calculate_centroid())

                # add our padding centroids, i.e. two rows of regularly spaced centroids
                # on the outside of the entire region of interest (which includes extra space and cells)
                all_centroid_positions = np.vstack(
                    (np.array(centroid_positions),
                     self.padding_centroid_positions))

                # We generate a Voronoi tesselation of that
                self.voronoi_diagram = VoronoiTess(all_centroid_positions)

                # now we clean up that voronoi tesselation and set the mesh in the generator
                self.remove_padding_cells_from_voronoi_diagram_and_create_mesh(
                )

            # after we went through the iterations we can crop and return the mesh
            return self.crop_and_return_mesh()
Example #9
0
    def get_voronoi_polyhedra(self, n):
        """
        Gives a weighted polyhedra around a site. This uses the voronoi
        construction with solid angle weights.
        See ref: A Proposed Rigorous Definition of Coordination Number,
        M. O'Keeffe, Acta Cryst. (1979). A35, 772-775

        Args:
            n:
                site index

        Returns:
            A dictionary of sites sharing a common Voronoi facet with the site
            n and their solid angle weights
        """

        localtarget = self._target
        center = self._structure[n]
        neighbors = self._structure.get_sites_in_sphere(
            center.coords, VoronoiCoordFinder.default_cutoff)
        neighbors = [i[0] for i in sorted(neighbors, key=lambda s: s[1])]
        qvoronoi_input = [s.coords for s in neighbors]
        voro = VoronoiTess(qvoronoi_input)
        all_vertices = voro.vertices

        results = {}
        for nn, vind in voro.ridges.items():
            if 0 in nn:
                if 0 in vind:
                    raise RuntimeError("This structure is pathological,"
                                       " infinite vertex in the voronoi "
                                       "construction")

                facets = [all_vertices[i] for i in vind]
                results[neighbors[nn[1]]] = solid_angle(center.coords, facets)

        maxangle = max(results.values())

        resultweighted = {}
        for nn, angle in results.items():
            if nn.specie in localtarget:
                resultweighted[nn] = angle / maxangle

        return resultweighted
    def generate_initial_tesselation(self):
        """Generate the initial tesselation.
        
        In this method we distribute nx_with_dummies*ny_with_dummies points randomly in a box of 
        dimension [nx_with_dummies, ny_with_dummies]. We then add the padding centroids on the outside
        of the box to `cut of' infinity. Finally, we take the voronoi tesselation of all these centroids,
        and remove the voronoi cells originating from the padding centroids from this tesselation.
        This is designed such that the average area of the remaining cells should be one.
        """

        total_number_of_random_points_to_create = np.prod(
            self.nx_with_dummies * self.ny_with_dummies)

        # We make a mesh of cell centroids.
        # First we get an array with random entries between 0 and 1 in x and y directions of correct length
        centroid_positions = np.random.rand(
            total_number_of_random_points_to_create, 2)

        # Then we blow this array up to the correct dimensions in x and y

        centroid_positions[:, 0] *= self.nx_with_dummies
        centroid_positions[:, 1] *= self.ny_with_dummies

        # and we shift the mesh such that the bottom and left added space is negative
        centroid_positions[:, 0] -= 3.5
        centroid_positions[:, 1] -= 3.5
        # the region with the centroids now spreads from -3.5 to (self.[nx/ny] + 4.5) so that we can add padding
        # cells at integer coordinates, i.e -4 and self.[nx/ny] + 5

        # Now we add some padding cells on the outside.

        centroid_positions = np.vstack(
            (centroid_positions, self.padding_centroid_positions))

        # We generate a Voronoi tesselation of that
        self.voronoi_diagram = VoronoiTess(centroid_positions)

        # now we clean up this voronoi tesselation and set the mesh of the generator
        # cleaning up means we remove the voronoi cells originating from the padding seeds
        self.remove_padding_cells_from_voronoi_diagram_and_create_mesh()
Example #11
0
from pyhull.convex_hull import ConvexHull
from pyhull.voronoi import VoronoiTess
#pts = [[-0.5, -0.5], [-0.5, 0.5], [0.5, -0.5], [0.5, 0.5], [0,0]]
pts = [[44.968046,-94.420307],[44.33328,-89.132008],[33.755787,-116.359998],[33.844843,-116.54911],[44.92057,-93.44786],
[44.240309,-91.493619],
[44.968041,-94.419696],
[44.333304,-89.132027],
[33.755783,-116.360066],
[33.844847,-116.549069],
[44.920474,-93.447851],
[44.240304,-91.493768]]
pts_reversed = []
for pt in pts:
    pts_reversed.append([pt[1], pt[0]])



print pts_reversed
hull = VoronoiTess (pts)
print hull.vertices




Example #12
0
from mpl_toolkits.mplot3d import axes3d, Axes3D
import numpy as np
import scipy as sp
import scipy.misc
import math
import matplotlib.pyplot as plt
from pyhull.voronoi import VoronoiTess

V = np.array([[0, 0, 0], [0, 1, 0], [1, 1, 1], [2, 1, 2], [3, 2, 1]])
plt.gca(projection='3d')
plt.plot(V[:, 0], V[:, 1], V[:, 2], 'o')

vor = VoronoiTess(V)
vorVer = np.array(vor.vertices)
print vorVer

plt.plot(vorVer[:, 0], vorVer[:, 1], vorVer[:, 2])

plt.show()
def check_road_segment(r_id, road, building_data, bld_geoms, bld_ids, method,
                       idx):
    """
    This function runs for every road segment the main logic.
    It creates a buffer, finds the buildings in the buffer,
    constructs abounding box, creates the voronoi, finds relationshipds
    between road segments and buildings, and the calls the classification.
    """

    road_to_building = {}
    classification = {}
    points_classified = {}

    # Create equidistant points along the road segment.
    road_coords = list(road.coords)
    eq_pts_road = discretise_road(road_coords)

    # Create buffer around the road (60m) and return all of its coordinates.
    # Discretise the buffer based on these coordinates for bounding the Voronoi.
    road_simple = road.simplify(5, preserve_topology=True)

    # Get the buffers for the roads and road sub-segments in the case the
    # road is too complex.
    sub_buffers = get_buffer_parts(r_id, road_simple)

    for new_id in sub_buffers:

        points_classified[new_id] = {}
        points_classified[new_id]['geom'] = {}
        points_classified[new_id]['class'] = {}

        road_part = sub_buffers[new_id]['new_road']
        classification[new_id] = {'geom': road_part}
        road_to_building[new_id] = {}

        # Find the buildings in the 60m buffer.
        blds_left_buffer = get_buildings_in_buffer(sub_buffers[new_id]['left'],
                                                   bld_geoms, bld_ids, idx)
        blds_right_buffer = get_buildings_in_buffer(
            sub_buffers[new_id]['right'], bld_geoms, bld_ids, idx)

        # No buildings on either side of the road, go to the next road segment.
        if not blds_left_buffer and not blds_right_buffer:
            classification[new_id]['class'] = 4
            continue

        # Discretise the buildings for the voronoi.
        eq_pts_blds_left, eq_pts_blds_left_flat = discretise_buildings(
            blds_left_buffer)
        eq_pts_blds_right, eq_pts_blds_right_flat = discretise_buildings(
            blds_right_buffer)

        # Create voronoi diagram out of the building, road and bounding box points.
        bbox = construct_bbox(eq_pts_road + eq_pts_blds_left_flat +
                              eq_pts_blds_right_flat)
        eq_pts_bbox = discretise_bbox(bbox)

        # Create the list with points for the voronoi diagram.
        vor_pts = eq_pts_road + eq_pts_blds_left_flat + eq_pts_blds_right_flat + eq_pts_bbox

        # Sometimes the library errors without a clear reason. In these cases
        # we set the class of the road segment to None.
        try:
            vor = VoronoiTess(vor_pts, add_bounding_box=False)
        except:
            print("Could not create Voronoi for this segment, id:", new_id)
            classification[new_id]['class'] = 'None'
            continue

        # Find the buildings facing the road for the left and right side.
        blds_left, blds_right, weights_left, weights_right = \
          find_road_building_relations(vor, eq_pts_road, eq_pts_blds_left,
                                       eq_pts_blds_right, road_coords)

        road_to_building[new_id]['left'] = blds_left
        road_to_building[new_id]['right'] = blds_right

        # general: 21283, 27058, 27267, 28822
        # voronoi column plots: 4269, 4270, 5811, 6283, 22841
        if new_id in ('19662'):
            vor = Voronoi(vor_pts)
            sub_left = {
                k: blds_left_buffer[k]
                for k in road_to_building[new_id]['left']
            }
            sub_right = {
                k: blds_right_buffer[k]
                for k in road_to_building[new_id]['right']
            }

        # Get the classification for the given road segment and the points
        # beloning to that road segment if the ray-tracing option is used.
        if method in ('raytracing', 'raytracing_both'):
            classification[new_id]['class'], points_classified[new_id] = \
              classify(method, building_data, blds_left, blds_right, weights_left,
                       weights_right, road_part, points_classified[new_id])

        else:
            classification[new_id]['class'] = classify(
                method, building_data, blds_left, blds_right, weights_left,
                weights_right, road_part, points_classified[new_id])

    return classification, points_classified
Example #14
0
def get_voronoi_dicts(structure,
                      cutoff_radius=VORONOI_CUTOFF_RADIUS,
                      cutoff_weight_fraction=VORONOI_CUTOFF_WEIGHT_FRACTION):
    voronoi_finder = VoronoiCoordFinder(structure)

    voronoi_finder.cutoff = cutoff_radius

    voronoi_finder_2 = VoronoiNN()
    voronoi_finder_2.cutoff = cutoff_radius

    all_neighbor_sites = {}
    all_neighbor_pairs = {}

    for center_site_index in range(0, len(structure.sites)):
        neighbor_sites_dict = {}
        neighbor_pairs_list = []
        # print "center_site_index: ", center_site_index

        # Construct initial voronoi polyhedra using cutoff_radius
        neighborhood_sites = [structure[center_site_index]
                              ]  # begin list with center site

        polyhedra_sites = voronoi_finder.get_voronoi_polyhedra(
            center_site_index)

        polyhedra_sites_2 = voronoi_finder_2.get_voronoi_polyhedra(
            structure, center_site_index)

        cutoff_weight = cutoff_weight_fraction * sum(polyhedra_sites.values())
        for neighbor_site, neighbor_weight in polyhedra_sites.items():
            if neighbor_weight > cutoff_weight:
                neighborhood_sites.append(neighbor_site)

        # Re-tesselate only with sites that also meet cutoff_weight_fraction criteria
        voronoi_input_coords = [site.coords for site in neighborhood_sites]
        try:
            voronoi_tess = VoronoiTess(voronoi_input_coords)
        except IndexError:
            raise RuntimeError('VoronoiTess: details unknown')

        local_solid_angles = []
        center_coords = structure[center_site_index].coords
        n_neighborhood_sites = len(neighborhood_sites)
        n_voronoi_vertices = len(voronoi_tess.vertices)
        neighbor_lookup = np.zeros(shape=(n_voronoi_vertices,
                                          n_voronoi_vertices, 2),
                                   dtype=np.int8)

        # Loop over neighbor sites (which surrond center_site) to:
        # - calculate solid angles
        # - construct neighbor_lookup array (which maps each voronoi edge to two adjacent neighbors)
        for neighbor_index in range(1, n_neighborhood_sites):
            facet_vertex_list = voronoi_tess.ridges[(
                0, neighbor_index)]  # 0 = center site
            if 0 in facet_vertex_list:
                raise RuntimeError(
                    "Pathological structure: voronoi facet includes vertex at infinity"
                )

            # Calculate solid angle of facet between center site and this neighbor site
            facet_coords = [
                voronoi_tess.vertices[i] for i in facet_vertex_list
            ]
            local_solid_angles.append(solid_angle(center_coords, facet_coords))

            # Add this voronoi ridge to neighbor_lookup array, to identify adjacent voronoi facets
            n_vertices = len(facet_vertex_list)
            for vertex1_index in range(0, n_vertices):
                vertex2_index = vertex1_index + 1
                if vertex2_index == n_vertices:
                    vertex2_index = 0  # wrap vertex2_index

                # Properly order vertex indicies to only use upper triangle of neighbor_lookup array
                (low_vert_index,
                 high_vert_index) = (facet_vertex_list[vertex1_index],
                                     facet_vertex_list[vertex2_index])
                if low_vert_index > high_vert_index:
                    (low_vert_index, high_vert_index) = (high_vert_index,
                                                         low_vert_index)

                # Store adjacent voronoi neighbors on different levels of neighbor_lookup, at location defined
                # by common voronoi edge running between low_vert_index (row) and high_vert_index (column).
                if neighbor_lookup[low_vert_index, high_vert_index, 0] == 0:
                    neighbor_lookup[low_vert_index, high_vert_index,
                                    0] = neighbor_index  # first neighbor
                else:
                    neighbor_lookup[low_vert_index, high_vert_index,
                                    1] = neighbor_index  # second neighbor

        # Loop over neighbor sites again to construct neighbor_sites_dict with solid angle weights
        max_local_solid_angle = max(local_solid_angles)
        for neighbor_index in range(1, n_neighborhood_sites):
            # Note: neighborhood_sites (which starts with center) is one longer than local_solid_angles
            neighbor_sites_dict[neighborhood_sites[neighbor_index]] = \
                local_solid_angles[neighbor_index - 1] / max_local_solid_angle

        # Loop through upper triangle of neighbor_lookup and build a list of tuples of neighbor pair sites
        for low_vert_index in range(1, n_voronoi_vertices):
            for high_vert_index in range(low_vert_index + 1,
                                         n_voronoi_vertices):
                neighbor1_index = neighbor_lookup[low_vert_index,
                                                  high_vert_index, 0]
                neighbor2_index = neighbor_lookup[low_vert_index,
                                                  high_vert_index, 1]
                if neighbor1_index > 0 and neighbor2_index > 0:  # Both are non-zero
                    neighbor_pairs_list.append(
                        (neighborhood_sites[neighbor1_index],
                         neighborhood_sites[neighbor2_index]))
                elif neighbor1_index != 0 or neighbor2_index != 0:  # Only one is non-zero
                    raise RuntimeError(
                        "Unexpected neighbor_lookup matrix: non-paired edge")

        # Append per site values
        all_neighbor_sites[
            structure.sites[center_site_index]] = neighbor_sites_dict
        all_neighbor_pairs[
            structure.sites[center_site_index]] = neighbor_pairs_list

    return (all_neighbor_sites, all_neighbor_pairs)
Example #15
0
def get_voronoi_dicts_2(structure,
                        cutoff_radius=VORONOI_CUTOFF_RADIUS,
                        cutoff_weight_fraction=VORONOI_CUTOFF_WEIGHT_FRACTION):
    voronoi_finder_2 = VoronoiNN()
    voronoi_finder_2.cutoff = cutoff_radius

    all_neighbor_sites = {}
    all_neighbor_pairs = {}

    for center_site_index in range(0, len(structure.sites)):
        neighbor_sites_dict = {}
        neighbor_pairs_list = []

        neighborhood_sites = [structure[center_site_index]]

        sites_property = voronoi_finder_2.get_nn_info(structure,
                                                      center_site_index)

        cutoff_weight = cutoff_weight_fraction * sum(
            voronoi_finder_2.get_weights_of_nn_sites(structure,
                                                     center_site_index))

        for neighbor_index in range(0, len(sites_property)):
            neighbor_weight = voronoi_finder_2.get_nn_info(
                structure, center_site_index)[neighbor_index]['weight']
            neighbor_site = voronoi_finder_2.get_nn_info(
                structure, center_site_index)[neighbor_index]['site']
            if neighbor_weight > cutoff_weight:
                neighborhood_sites.append(neighbor_site)
                neighbor_sites_dict[neighbor_site] = neighbor_weight

        # Re-tesselate only with sites that also meet cutoff_weight_fraction criteria
        voronoi_input_coords = [site.coords for site in neighborhood_sites]
        try:
            voronoi_tess = VoronoiTess(voronoi_input_coords)
        except IndexError:
            raise RuntimeError('VoronoiTess: details unknown')

        n_neighborhood_sites = len(neighborhood_sites)
        n_voronoi_vertices = len(voronoi_tess.vertices)
        neighbor_lookup = np.zeros(shape=(n_voronoi_vertices,
                                          n_voronoi_vertices, 2),
                                   dtype=np.int8)

        # Loop over neighbor sites (which surrond center_site) to:
        # - calculate solid angles
        # - construct neighbor_lookup array (which maps each voronoi edge to two adjacent neighbors)
        for neighbor_index in range(1, n_neighborhood_sites):
            facet_vertex_list = voronoi_tess.ridges[(
                0, neighbor_index)]  # 0 = center site
            if 0 in facet_vertex_list:
                raise RuntimeError(
                    "Pathological structure: voronoi facet includes vertex at infinity"
                )

            # Add this voronoi ridge to neighbor_lookup array, to identify adjacent voronoi facets
            n_vertices = len(facet_vertex_list)
            for vertex1_index in range(0, n_vertices):
                vertex2_index = vertex1_index + 1
                if vertex2_index == n_vertices:
                    vertex2_index = 0  # wrap vertex2_index

                # Properly order vertex indicies to only use upper triangle of neighbor_lookup array
                (low_vert_index,
                 high_vert_index) = (facet_vertex_list[vertex1_index],
                                     facet_vertex_list[vertex2_index])
                if low_vert_index > high_vert_index:
                    (low_vert_index, high_vert_index) = (high_vert_index,
                                                         low_vert_index)

                # Store adjacent voronoi neighbors on different levels of neighbor_lookup, at location defined
                # by common voronoi edge running between low_vert_index (row) and high_vert_index (column).
                if neighbor_lookup[low_vert_index, high_vert_index, 0] == 0:
                    neighbor_lookup[low_vert_index, high_vert_index,
                                    0] = neighbor_index  # first neighbor
                else:
                    neighbor_lookup[low_vert_index, high_vert_index,
                                    1] = neighbor_index  # second neighbor

        # Loop through upper triangle of neighbor_lookup and build a list of tuples of neighbor pair sites
        for low_vert_index in range(1, n_voronoi_vertices):
            for high_vert_index in range(low_vert_index + 1,
                                         n_voronoi_vertices):
                neighbor1_index = neighbor_lookup[low_vert_index,
                                                  high_vert_index, 0]
                neighbor2_index = neighbor_lookup[low_vert_index,
                                                  high_vert_index, 1]
                if neighbor1_index > 0 and neighbor2_index > 0:  # Both are non-zero
                    neighbor_pairs_list.append(
                        (neighborhood_sites[neighbor1_index],
                         neighborhood_sites[neighbor2_index]))
                elif neighbor1_index != 0 or neighbor2_index != 0:  # Only one is non-zero
                    raise RuntimeError(
                        "Unexpected neighbor_lookup matrix: non-paired edge")

        # Append per site values
        all_neighbor_sites[
            structure.sites[center_site_index]] = neighbor_sites_dict
        all_neighbor_pairs[
            structure.sites[center_site_index]] = neighbor_pairs_list

    return (all_neighbor_sites, all_neighbor_pairs)
def voroArea(Atoms, qry, size_x, size_y):
    orgCRDs = Atoms.coordinates()

    #convert 3D to 2D: extractig X and Y axis
    orgCRDs = selCoord(orgCRDs, [0, 1])
    orgPoints = getNumPoints(Atoms, qry)

    uq_resNames = orgPoints[0]
    # Residues names in the given system
    uq_numAtoms = orgPoints[1]
    # the number of selected atoms corresponding to residue names

    #-------------------------------
    # calculating image boxes
    # 5 |    3      | 7
    # 1 | primary 0 | 2
    # 6 |     4     | 8
    #-------------------------------
    sysCRDs = mkimagebox(orgCRDs, size_x, size_y)

    # calculating voronoi tessellation
    voro = VoronoiTess(sysCRDs)
    voro_vtex = voro.vertices
    voro_regn = voro.regions

    # calculating area per lipids
    resIDs = Atoms.resids()
    # obtaining residue ids
    resNames = Atoms.resnames()

    # initializing array
    areaLipids = [0.0] * (len(resIDs) + 1)
    # each array will be used for individual lipid area and last one will be the average area

    res_cnt = 0
    # residue count
    num_atoms = 0
    # number of atoms corresponding to the current residue name
    crd_idx = 0
    # coordinate index
    M = numpy.array(sysCRDs)

    max_x = M.max(axis=0)[0] / 2.0
    max_y = M.max(axis=0)[1] / 2.0
    min_x = M.min(axis=0)[0] / 2.0
    min_y = M.min(axis=0)[1] / 2.0

    for res_name in resNames:
        # find corresponding residue
        num_atoms = uq_numAtoms[uq_resNames.index(res_name)]
        #print resNames;
        #calculating the area corresponding to the point
        atom_cnt = 0
        myarea = 0.0
        for dummy in range(num_atoms):
            #print "max_x={}, max_y={}, min_x={}, min_y={}".format(max_x, max_y, min_x, min_y);
            #print "crdIdx:{0}, lenRegio:{1}, len(CRDs):{2}, residue:{3}, num_atoms:{4}, num_residue:{5}".format(crd_idx, len(voro_regn), len(orgCRDs), res_name, num_atoms, len(resNames));
            if crd_idx >= len(orgCRDs):
                break
            else:
                my_region = getPos(voro_regn[crd_idx])
                liparea = crdArea(my_region, voro_vtex, max_x, max_y, min_x,
                                  min_y)
                #print "crd_idx={}, res_name ={}, res_ID={}, X={}, Y={}".format(crd_idx, res_name, resIDs[res_cnt], sysCRDs[crd_idx][0], sysCRDs[crd_idx][1]);
                crd_idx = crd_idx + 1
                myarea = myarea + liparea
        areaLipids[res_cnt] = myarea
        res_cnt = res_cnt + 1
    areaLipids[len(areaLipids) - 1] = sum(areaLipids) / res_cnt
    #print "len(areaLipids): {}, len(orgCRDs): {}".format(len(areaLipids), len(orgCRDs));
    return areaLipids
Example #17
0
legkeys.append(p)
legitems.append("Delaunay tri")

d = ConvexHull(points)

for s in d.simplices:
    for data in itertools.combinations(s.coords, dim):
        data = np.array(data)
        p, = plt.plot(data[:,0], data[:,1], 'b-') if dim == 2 else\
            ax.plot(data[:,0], data[:,1], data[:,2], 'b-')

legkeys.append(p)
legitems.append("Convex hull")

if dim == 2:
    d = VoronoiTess(points)
    points = d.points
    avg = np.average(points, 0)
    vertices = d.vertices
    for nn, vind in d.ridges.items():
        (i1, i2) = sorted(vind)
        if i1 == 0:
            c1 = np.array(vertices[i2])
            midpt = 0.5 * (np.array(points[nn[0]]) + np.array(points[nn[1]]))
            if np.dot(avg - midpt, c1 - midpt) > 0:
                c2 = c1 + 10 * (midpt - c1)
            else:
                c2 = c1 - 10 * (midpt - c1)
            p1, = plt.plot([c1[0], c2[0]], [c1[1], c2[1]], 'k--')
        else:
            c1 = vertices[i1]
Example #18
0
def generate_hexagonal(nx, ny):
    """Create a hexagonal mesh of dimension nx x ny.
        
    Parameters
    ----------
    nx : int
        Number of cells in x direction
    ny : int
        Number of cells in y direction
        
    Returns
    -------
    mesh : Mesh type
        hexagonal mesh of dimension nx, ny
    """
    # We specifiy the dimension of the grid in x and y direction
    number_of_cells = np.array((nx, ny))
    number_of_cells_and_dummies = number_of_cells + 2

    # We make a mesh of cell centroids
    centroid_positions = np.zeros((number_of_cells_and_dummies.prod(), 2),
                                  'double')
    origin = -number_of_cells_and_dummies / 2.0 + 0.5
    counter = 0
    for x_index in range(number_of_cells_and_dummies[0]):
        for y_index in range(number_of_cells_and_dummies[1]):
            if y_index % 2 == 0:
                centroid_positions[counter, 0] = origin[0] + x_index * 1.0
            else:
                centroid_positions[counter,
                                   0] = origin[0] + 0.5 + x_index * 1.0
            centroid_positions[counter, 1] = origin[1] + y_index * 1.0
            counter += 1

    # We generate a Voronoi tesselation of that
    voronoi_diagram = VoronoiTess(centroid_positions)

    # Now, let's get all vertices
    all_vertices = np.array(voronoi_diagram.vertices)

    # and all regions

    all_regions = voronoi_diagram.regions

    # now, let's make a new array of vertices and a new array of regions

    new_vertices = []
    new_elements = []
    index_map = [-1] * all_vertices.shape[0]
    current_number_of_new_vertices = 0
    # Loop over all regions
    for region in all_regions:
        # If this region is not a boundary region
        if (0 not in region) and (len(region) == 6):
            # then we want to keep it
            new_region = []
            for index in region:
                # if the index is not in the new vertices, add it
                if (index_map[index] == -1):
                    this_node = Node(all_vertices[index])
                    new_vertices.append(this_node)
                    index_map[index] = current_number_of_new_vertices
                    # and add it to the new region
                    new_region.append(this_node)
                    current_number_of_new_vertices += 1
                else:
                    # if it is in the new vertices though then add
                    # the right vertex to the new region
                    new_region.append(new_vertices[index_map[index]])
            # lets make an element from that region and add it to the list of elements
            new_elements.append(Element(new_region))

    # ensure that all the vertices in each element are ordered counterclockwise
    for element in new_elements:
        area = element.calculate_area()
        if area < 0:
            element.nodes.reverse()
        area = element.calculate_area()
        assert (abs(area - 1.0) < 1e-10)

    # now we can create a mesh and return it
    return Mesh(new_vertices, new_elements)