コード例 #1
0
    def score(self, segpos, *, verbosity=False, **kw):
        x_from = segpos[self.from_seg]
        x_to = segpos[self.to_seg]
        xhat = x_to @ inv(x_from)
        trans = xhat[..., :, 3]
        if self.nfold is 1:
            angle = hm.angle_of(xhat)
            carterrsq = np.sum(trans[..., :3]**2, axis=-1)
            roterrsq = angle**2
        else:
            if self.origin_seg is not None:
                tgtaxis = segpos[self.origin_seg] @ [0, 0, 1, 0]
                tgtcen = segpos[self.origin_seg] @ [0, 0, 0, 1]
                axis, angle, cen = hm.axis_ang_cen_of(xhat)
                carterrsq = hm.hnorm2(cen - tgtcen)
                roterrsq = (1 - np.abs(hm.hdot(axis, tgtaxis))) * np.pi
            else:  # much cheaper if cen not needed
                axis, angle = hm.axis_angle_of(xhat)
                carterrsq = roterrsq = 0
            carterrsq = carterrsq + hm.hdot(trans, axis)**2
            roterrsq = roterrsq + (angle - self.symangle)**2
            # if self.relweight is not None:
            #     # penalize 'relative' error
            #     distsq = np.sum(trans[..., :3]**2, axis=-1)
            #     relerrsq = carterrsq / distsq
            #     relerrsq[np.isnan(relerrsq)] = 9e9
            #     # too much of a hack??
            #     carterrsq += self.relweight * relerrsq
            if verbosity > 0:
                print('axis', axis[0])
                print('trans', trans[0])
                print('dot trans', hm.hdot(trans, axis)[0])
                print('angle', angle[0] * 180 / np.pi)

        return np.sqrt(carterrsq / self.tol**2 + roterrsq / self.rot_tol**2)
コード例 #2
0
ファイル: unbounded.py プロジェクト: willsheffler/worms
    def __init__(
        self,
        symname,
        tgtaxis1,
        tgtaxis2,
        from_seg,
        *,
        tolerance=1.0,
        lever=50,
        to_seg=-1,
        space_group_str=None,
        cell_dist_scale=1.0,
        tgtaxis2_isects=[0, 1, 0],
    ):
        """ Worms criteria for non-intersecting axes re: unbounded things

        assume tgtaxis1 goes through origin
        tgtaxis2 intersects tgtaxis2_isects

        Args:
            symname (str): Symmetry identifier, to label stuff and look up the symdef file.
            tgtaxis1: Target axis 1.
            tgtaxis2: Target axis 2.
            from_seg (int): The segment # to start at.
            tolerance (float): A geometry/alignment error threshold. Vaguely Angstroms.
            lever (float): Tradeoff with distances and angles for a lever-like object. To convert an angle error to a distance error for an oblong shape.
            to_seg (int): The segment # to end at.
            space_group_str: The target space group.

        """

        self.symname = symname
        self.cell_dist_scale = cell_dist_scale
        self.tgtaxis1 = np.asarray(
            tgtaxis1, dtype="f8"
        )  ## we are treating these as vectors for now, make it an array if it isn't yet, set array type to 8-type float
        self.tgtaxis2 = np.asarray(tgtaxis2, dtype="f8")
        # print(self.tgtaxis1.shape)
        # print(np.linalg.norm(tgtaxis1))
        self.tgtaxis1 /= np.linalg.norm(
            self.tgtaxis1)  # normalize target axes to 1,1,1
        self.tgtaxis2 /= np.linalg.norm(self.tgtaxis2)
        if hm.angle(self.tgtaxis1, self.tgtaxis2) > np.pi / 2:
            self.tgtaxis2 = -self.tgtaxis2
        self.from_seg = from_seg
        self.tolerance = tolerance
        self.lever = lever
        self.to_seg = to_seg
        self.space_group_str = space_group_str
        ## if you want to store arguments, you have to write these self.argument lines

        self.target_angle = np.arccos(
            np.abs(hm.hdot(self.tgtaxis1, self.tgtaxis2))
        )  ## already set to a non- self.argument in this function
        # print(self.target_angle * (180 / np.pi))
        self.is_cyclic = False
        self.origin_seg = None
        self.tgtaxis2_isects = tgtaxis2_isects
コード例 #3
0
 def score(self, segpos, verbosity=False, **kw):
    cen1 = segpos[self.from_seg][..., :, 3]
    cen2 = segpos[self.to_seg][..., :, 3]
    ax1 = segpos[self.from_seg][..., :, 2]
    ax2 = segpos[self.to_seg][..., :, 2]
    if self.nondistinct_axes:
       p, q = hm.line_line_closest_points_pa(cen1, ax1, cen2, ax2)
       dist = hm.hnorm(p - q)
       cen = (p + q) / 2
       ax1c = hm.hnormalized(cen1 - cen)
       ax2c = hm.hnormalized(cen2 - cen)
       ax1 = np.where(hm.hdot(ax1, ax1c)[..., None] > 0, ax1, -ax1)
       ax2 = np.where(hm.hdot(ax2, ax2c)[..., None] > 0, ax2, -ax2)
       ang = np.arccos(hm.hdot(ax1, ax2))
    else:
       dist = hm.line_line_distance_pa(cen1, ax1, cen2, ax2)
       ang = np.arccos(np.abs(hm.hdot(ax1, ax2)))
    roterr2 = (ang - self.tgtangle)**2
    return np.sqrt(roterr2 / self.rot_tol**2 + (dist / self.tolerance)**2)
コード例 #4
0
def primary_xform_commutator(units, state=1, **kw):
    print('stub 0:')
    print(units[0].stub)
    closest = None
    for j in range(1, 20):
        x = hm.hinv(units[0].stub) @ units[j].stub
        # print(f'stub {j}:')
        # print(units[j].stub)
        # print(x)
        axis, ang, cen = hm.axis_ang_cen_of(x)
        helical = hm.hdot(axis, x[:, 3])
        print(j, helical, x[2, 3])
        if abs(helical) > 0.01:
            return x
    return None
コード例 #5
0
 def alignment(self, segpos, **kwargs):
     if self.origin_seg is not None:
         return inv(segpos[self.origin_seg])
     x_from = segpos[self.from_seg]
     x_to = segpos[self.to_seg]
     xhat = x_to @ inv(x_from)
     axis, ang, cen = hm.axis_ang_cen_of(xhat)
     # print('aln', axis)
     # print('aln', ang * 180 / np.pi)
     # print('aln', cen)
     # print('aln', xhat[..., :, 3])
     dotz = hm.hdot(axis, Uz)[..., None]
     tgtaxis = np.where(dotz > 0, [0, 0, 1, 0], [0, 0, -1, 0])
     align = hm.hrot((axis + tgtaxis) / 2, np.pi, cen)
     align[..., :3, 3] -= cen[..., :3]
     return align
コード例 #6
0
ファイル: criteria_unbounded.py プロジェクト: natteruw/worms
    def score(self, segpos, **kw):
        """ Score

        Args:
            segpos (lst): List of segment positions / coordinates.
            **kw I'll accept any "non-positional" argument as name = value, and store in a dictionary

        """
        ## numpy arrays of how many things you are scoring, and a 4x4 translation/rotation matrix
        ax1 = segpos[self.from_seg][
            ..., :,
            2]  ## from the first however many dimensions except the last two, give me the 2nd column, which for us is the Z-axis
        ax2 = segpos[self.to_seg][..., :, 2]
        #angle = hm.angle(ax1, ax2) ## homog angle function will compute the angle between two vectors, and give back an angle in radians
        angle = np.arccos(
            np.abs(hm.hdot(ax1, ax2))
        )  ## this is better because it contains absolutel value, which ensures that you always get the smaller of the angles resulting from intersecting two lines
        return np.abs(
            (angle - self.target_angle)
        ) / self.tol * self.lever  ## as tolerance goes up, you care about the angle error less. as lever goes up, you care about the angle error more.
コード例 #7
0
ファイル: unbounded.py プロジェクト: clrichar/worms
 def score(self, segpos, **kw):
     ax1 = segpos[self.from_seg][..., :, 2]
     ax2 = segpos[self.to_seg][..., :, 2]
     angle = np.arccos(np.abs(hm.hdot(ax1, ax2)))
     return np.abs(
         (angle - self.target_angle)) / self.tolerance * self.lever