示例#1
0
 def _get_other(self, central_xyz: ArrayLike, other: ArrayLike,
                box: Optional[ArrayLike]=None) -> Optional[ArrayLike]:
     pairs2 = capped_distance(central_xyz, other, self.cutoff_other,
                              box=box, return_distances=False)
     if len(pairs2):
         other_xyz = other[np.unique(pairs2[:, 1])]
     else:
         other_xyz = None
     
     return other_xyz
    def _single_frame(self):

        pairs = capped_distance(self.protein.positions, self.group.positions,
                                self.cutoff, box=self.universe.dimensions,
                                return_distances=False)

        prot = self.protein_rix[pairs[:, 0]]
        group = self.group_rix[pairs[:, 1]]

        tmp = np.zeros_like(self.percent_contact)
        tmp[(prot, group)] = 1

        self.percent_contact += tmp
示例#3
0
def get_distances_with_projection(coordinates: ArrayLike,
                                  orientations: ArrayLike,
                                  cutoff: float,
                                  box: Optional[ArrayLike] = None,
                                  angle_factor: float = 1) -> ArrayLike:
    n_coordinates = len(coordinates)
    # set up distance matrix
    filler = (angle_factor + 1) * cutoff
    dist_mat = np.ones((n_coordinates, n_coordinates)) * filler
    dist_mat[np.diag_indices(n_coordinates)] = 0
    pairs, dists = capped_distance(coordinates,
                                   coordinates,
                                   cutoff,
                                   box=box,
                                   return_distances=True)
    pi, pj = tuple(pairs.T)

    # split pairs and distances by residue
    splix = np.where(np.ediff1d(pairs[:, 0]))[0] + 1
    plist = np.split(pairs, splix)
    dlist = np.split(dists, splix)

    # project distances onto orientation vector
    for p, d in zip(plist, dlist):
        i = p[0, 0]
        js = p[1:, 1]  # first is self-to-self
        d = d[1:]
        i_coord = coordinates[i]

        # TODO: can I get around this? slow
        neigh_ = coordinates[js].copy()

        if box is not None:
            unwrap_around(neigh_, i_coord, box[:3])
        neigh_ -= i_coord

        vec = orientations[[i]]
        if np.any(np.isnan(vec)):
            continue

        ang_ = calc_cosine_similarity(vec, neigh_)
        proj = np.abs(d * ang_)
        # weight projected distance by angle_factor
        half = (proj * angle_factor)[0]
        dist_mat[i, js] = half + d

    dist_mat += dist_mat.T  # symmetrize
    dist_mat /= 2
    return dist_mat
示例#4
0
文件: base.py 项目: OMaraLab/lipyds
    def _update_leaflets(self):
        """Update the ``residue_leaflets`` attribute for the current frame."""
        self.leafletfinder.run()
        self.leaflet_atomgroups = {}

        # assign inner residues
        inside_rix = self.residues_inside.resindices
        for rix in inside_rix:
            i = self._resindex_to_analysis_order[rix]
            lf = self.leafletfinder.resindex_to_leaflet[rix]
            self.residue_leaflets[i] = lf

        if not self._first_atoms_outside:
            return

        # assign outside residues by neighbors
        box = self.get_box()
        pairs = capped_distance(self._first_atoms_outside.positions,
                                self.leafletfinder._first_atoms.positions,
                                max_cutoff=self.leafletfinder.cutoff,
                                box=box,
                                return_distances=False)
        splix = np.where(np.ediff1d(pairs[:, 0]))[0] + 1
        plist = np.split(pairs, splix)
        outside_rix = self.residues_outside.resindices
        for arr in plist:
            i = self._resindex_to_analysis_order[outside_rix[arr[0, 0]]]
            neighbor_rix = self.leafletfinder.residues.resindices[arr[:, 1]]
            # neighbor_ix = np.array([self._resindex_to_analysis_order[j]
            #                         for j in neighbor_rix])
            # get most common neighbors
            leaflet_is = [
                self.leafletfinder.resindex_to_leaflet[r] for r in neighbor_rix
            ]
            most_common = np.bincount(leaflet_is).argmax()
            self.residue_leaflets[i] = most_common

        self.leaflet_residues = {
            i: list()
            for i in np.unique(self.residue_leaflets)
        }
        for i, lf_i in enumerate(self.residue_leaflets):
            self.leaflet_residues[lf_i].append(i)
        for lf_i, res_i in self.leaflet_residues.items():
            ag = sum(self.sel_by_residue[i] for i in res_i)
            self.leaflet_atomgroups[lf_i] = ag
示例#5
0
    def _single_frame(self):
        other = self.other.positions
        box = self.get_box()

        for lf_i in range(self.n_leaflets):
            ag = self.leaflet_atomgroups[lf_i]
            coords = get_centers_by_residue(ag)

            pairs, dists = capped_distance(coords, coords,
                                           self.cutoff,
                                           box=box,
                                           return_distances=True)
            
            if not len(pairs):
                continue
            
            # think this is faster than constructing massive voronoi diagram
            splix = np.where(np.ediff1d(pairs[:, 0]))[0] + 1
            plist = np.split(pairs, splix)
            dlist = np.split(dists, splix)
            d_order = [np.argsort(x) for x in dlist]
            plist = [p[x[:self.max_neighbors+1]] for p, x in zip(plist, d_order)]

            for pairs_ in plist:
                central_i = pairs_[0, 0]
                central_coord = coords[central_i]
                neighbor_coords = coords[pairs_[1:, 1]]

                other_coords = self._get_other_coordinates(central_coord, other, box)

                try:
                    area = lipid_area(central_coord, neighbor_coords,
                                      other_coordinates=other_coords,
                                      box=box)
                except ValueError:
                    area = np.nan

                resindex = ag.residues[central_i].resindex
                residue_index = self._resindex_to_analysis_order[resindex]
                residue_label = self.ids[residue_index]

                self.areas[self._frame_index][residue_index] = area
                self.areas_by_leaflet[self._frame_index][lf_i][residue_index] = area
                self.areas_by_attr[lf_i][residue_label].append(area)
示例#6
0
 def _get_capped_distances(self, atomgroup: AtomGroup) -> ArrayLike:
     return capped_distance(self._first_atoms.positions,
                            atomgroup.positions,
                            box=self.get_box(),
                            max_cutoff=self.cutoff,
                            return_distances=False)
示例#7
0
文件: dei.py 项目: OMaraLab/lipyds
    def _single_frame(self):
        # initial scoop for nearby groups
        coords_ = self.selection.positions
        pairs = distances.capped_distance(self.protein.positions,
                                          coords_,
                                          self.cutoff,
                                          box=self.protein.dimensions,
                                          return_distances=False)
        if pairs.size > 0:
            indices = np.unique(pairs[:, 1])
        else:
            indices = []

        # now look for groups in the buffer
        if len(indices) and self.buffer:
            pairs2, dist = distances.capped_distance(
                self.protein.positions,
                coords_,
                self.max_cutoff,
                min_cutoff=self.cutoff,
                box=self.protein.dimensions,
                return_distances=True)

            # don't count things in inner cutoff
            mask = [x not in indices for x in pairs2[:, 1]]
            pairs2 = pairs2[mask]
            dist = dist[mask]

            if pairs2.size > 0:
                _ix = np.argsort(pairs2[:, 1])
                indices2 = pairs2[_ix][:, 1]
                dist = dist[_ix] - self.cutoff

                init_resix2 = self.selection.resindices[indices2]
                # sort through for minimum distance
                ids2, splix = np.unique(init_resix2, return_index=True)
                resix2 = init_resix2[splix]
                split_dist = np.split(dist, splix[1:])
                min_dist = np.array([x.min() for x in split_dist])

                # logistic function
                for i, leaflet_residues in self._current_leaflet_residues.items(
                ):
                    ids = self._current_leaflet_ids[i]
                    match, rix, lix = np.intersect1d(
                        resix2,
                        leaflet_residues.resindices,
                        assume_unique=True,
                        return_indices=True)
                    subdist = min_dist[rix]
                    subids = ids[lix]
                    for j, x in enumerate(self.ids):
                        mask = (subids == x)
                        xdist = subdist[mask]
                        exp = -0.5 * ((xdist / self._buffer_sigma)**2)
                        n = self._buffer_coeff * np.exp(exp)
                        self.near_counts[i, j, self._frame_index] += n.sum()

        soft = self.near_counts[:, :, self._frame_index].sum()

        init_resix = self.selection.resindices[indices]
        resix = np.unique(init_resix)

        for i, leaflet_residues in self._current_leaflet_residues.items():
            ids = self._current_leaflet_ids[i]
            _, ix1, ix2 = np.intersect1d(resix,
                                         leaflet_residues.resindices,
                                         assume_unique=True,
                                         return_indices=True)
            self.total_counts[i, self._frame_index] = len(ix1)
            subids = ids[ix2]
            for j, x in enumerate(self.ids):
                self.residue_counts[i, j, self._frame_index] += sum(ids == x)
                self.near_counts[i, j, self._frame_index] += sum(subids == x)

        both = self.near_counts[:, :, self._frame_index].sum()