def __call__(self, input, error=False):
     X = self.scale_input(input)
     if not error:
         Y = dot(self.w, X)
     else:
         Y = dot(self.w, X), zeros(self.num_outputs)
     return self.scale_output(Y)
    def _leftDown_preparation_for_dragging(self, objectUnderMouse, event):
        """
        Handle left down event. Preparation for rotation and/or selection
        This method is called inside of self.leftDown.
        @param event: The mouse left down event.
        @type  event: QMouseEvent instance
        @see: self.leftDown
        @see: self.leftDragRotation
        Overrides _superclass._leftDown_preparation_for_dragging
        """

        _superclass._leftDown_preparation_for_dragging(self, objectUnderMouse, event)
        self.o.SaveMouse(event)
        self.picking = True
        self.dragdist = 0.0
        # delta for constrained rotations.
        self.rotDelta = 0

        if self.rotateOption == "ROTATEDEFAULT":
            self.o.trackball.start(self.o.MousePos[0], self.o.MousePos[1])
        else:
            if self.rotateOption == "ROTATEX":
                ma = V(1, 0, 0)  # X Axis
                self.axis = "X"
            elif self.rotateOption == "ROTATEY":
                ma = V(0, 1, 0)  # Y Axis
                self.axis = "Y"
            elif self.rotateOption == "ROTATEZ":
                ma = V(0, 0, 1)  # Z Axis
                self.axis = "Z"
            elif self.rotateOption == "ROT_TRANS_ALONG_AXIS":
                # The method 'self._leftDown_preparation_for_dragging should
                # never be reached if self.rotateOption is 'ROT_TRANS_ALONG_AXIS'
                # If this code is reached, it indicates a bug. So fail gracefully
                # by calling self.leftADown()
                if debug_flags.atom_debug:
                    print_compact_stack(
                        "bug: _leftDown_preparation_for_dragging" " called for rotate option" "'ROT_TRANS_ALONG_AXIS'"
                    )

                self.leftADown(objectUnderMouse, event)
                return

            else:
                print "Move_Command: Error - unknown rotateOption value =", self.rotateOption
                return

            ma = norm(V(dot(ma, self.o.right), dot(ma, self.o.up)))
            # When in the front view, right = 1,0,0 and up = 0,1,0, so ma will
            # be computed as 0,0.This creates a special case problem when the
            # user wants to constrain rotation around the Z axis because Zmat
            # will be zero.  So we have to test for this case (ma = 0,0) and
            # fix ma to -1,0.  This was needed to fix bug 537.  Mark 050420
            if ma[0] == 0.0 and ma[1] == 0.0:
                ma = [-1.0, 0.0]
            self.Zmat = A([ma, [-ma[1], ma[0]]])

        self.leftDownType = "ROTATE"

        return
Exemplo n.º 3
0
 def __call__(self,input,error=False):
     X = self.scale_input(input)
     if not error:
         Y = dot(self.w,X)
     else:
         Y = dot(self.w,X), zeros(self.num_outputs)
     return self.scale_output(Y)
Exemplo n.º 4
0
 def __init__(self, point1=None, point2=None, slab=None):
     # Huaicai 4/23/05: added some comments below to help understand the code.
     if slab:
         # convert from 2d (x, y) coordinates into its 3d world (x, y, 0)
         #coordinates(the lower-left and upper-right corner).
         #In another word, the 3d coordinates minus the z offset of the plane
         x = dot(A(point1), A(point2))
         # Get the vector from upper-right point to the lower-left point
         dx = subtract.reduce(x)
         # Get the upper-left and lower right corner points
         oc = x[1] + V(point2[0] * dot(dx, point2[0]),
                       point2[1] * dot(dx, point2[1]))
         # Get the four 3d cooridinates on the bottom cookie-cutting plane
         sq1 = cat(x, oc) + slab.normal * dot(slab.point, slab.normal)
         # transfer the above 4 3d coordinates in parallel to get that on
         #the top plane, put them together
         sq1 = cat(sq1, sq1 + slab.thickness * slab.normal)
         self.data = V(maximum.reduce(sq1), minimum.reduce(sq1))
     elif point2:
         # just 2 3d points
         self.data = V(maximum(point1, point2), minimum(point1, point2))
     elif point1:
         # list of points: could be 2d or 3d?  +/- 1.8 to make the bounding
         #box enclose the vDw ball of an atom?
         self.data = V(
             maximum.reduce(point1) + BBOX_MARGIN,
             minimum.reduce(point1) - BBOX_MARGIN)
     else:
         # a null bbox
         self.data = None
Exemplo n.º 5
0
 def __init__(self, point1 = None, point2 = None, slab = None):
     # Huaicai 4/23/05: added some comments below to help understand the code.
     if slab:
         # convert from 2d (x, y) coordinates into its 3d world (x, y, 0) 
         #coordinates(the lower-left and upper-right corner). 
         #In another word, the 3d coordinates minus the z offset of the plane
         x = dot(A(point1), A(point2))
         # Get the vector from upper-right point to the lower-left point
         dx = subtract.reduce(x)
         # Get the upper-left and lower right corner points
         oc = x[1] + V(point2[0]*dot(dx,point2[0]), 
                       point2[1]*dot(dx,point2[1]))
         # Get the four 3d cooridinates on the bottom cookie-cutting plane
         sq1 = cat(x,oc) + slab.normal*dot(slab.point, slab.normal)
         # transfer the above 4 3d coordinates in parallel to get that on
         #the top plane, put them together
         sq1 = cat(sq1, sq1+slab.thickness*slab.normal)
         self.data = V(maximum.reduce(sq1), minimum.reduce(sq1))
     elif point2:
         # just 2 3d points
         self.data = V(maximum(point1, point2), minimum(point1, point2))
     elif point1:
         # list of points: could be 2d or 3d?  +/- 1.8 to make the bounding 
         #box enclose the vDw ball of an atom?
         self.data = V(maximum.reduce(point1) + BBOX_MARGIN, 
                       minimum.reduce(point1) - BBOX_MARGIN)
     else:
         # a null bbox
         self.data = None
Exemplo n.º 6
0
 def rtz(self, pt):
     d = pt - self.p0
     z = dot(d, self.zn)
     d = d - z * self.zn
     r = vlen(d)
     theta = Numeric.arctan2(dot(d, self.v), dot(d, self.u))
     return Numeric.array((r, theta, z), 'd')
Exemplo n.º 7
0
 def rtz(self, pt):
     d = pt - self.p0
     z = dot(d, self.zn)
     d = d - z * self.zn
     r = vlen(d)
     theta = Numeric.arctan2(dot(d, self.v), dot(d, self.u))
     return Numeric.array((r, theta, z), "d")
Exemplo n.º 8
0
def drawLinearDimension(color,      # what color are we drawing this in
                        right, up,  # screen directions mapped to xyz coords
                        bpos,       # position of the handle for moving the text
                        p0, p1,     # positions of the ends of the dimension
                        text, highlighted=False):
    outOfScreen = cross(right, up)
    bdiff = bpos - 0.5 * (p0 + p1)
    csys = CylindricalCoordinates(p0, p1 - p0, bdiff, right)
    # This works OK until we want to keep the text right side up, then the
    # criterion for right-side-up-ness changes because we've changed 'up'.
    br, bt, bz = csys.rtz(bpos)
    e0 = csys.xyz((br + 0.5, 0, 0))
    e1 = csys.xyz((br + 0.5, 0, 1))
    drawline(color, p0, e0)
    drawline(color, p1, e1)
    v0 = csys.xyz((br, 0, 0))
    v1 = csys.xyz((br, 0, 1))
    if highlighted:
        drawline(color, v0, v1, width=THICKLINEWIDTH)
    else:
        drawline(color, v0, v1)
    # draw arrowheads at the ends
    a1, a2 = 0.25, 1.0 * csys.zinv
    arrow00 = csys.xyz((br + a1, 0, a2))
    arrow01 = csys.xyz((br - a1, 0, a2))
    drawline(color, v0, arrow00)
    drawline(color, v0, arrow01)
    arrow10 = csys.xyz((br + a1, 0, 1-a2))
    arrow11 = csys.xyz((br - a1, 0, 1-a2))
    drawline(color, v1, arrow10)
    drawline(color, v1, arrow11)
    # draw the text for the numerical measurement, make
    # sure it goes from left to right
    xflip = dot(csys.z, right) < 0
    # then make sure it's right side up
    theoreticalRight = (xflip and -csys.z) or csys.z
    theoreticalOutOfScreen = cross(theoreticalRight, bdiff)
    yflip = dot(theoreticalOutOfScreen, outOfScreen) < 0
    if debug_flags.atom_debug:
        print "DEBUG INFO FROM drawLinearDimension"
        print csys
        print theoreticalRight, theoreticalOutOfScreen
        print xflip, yflip
    if yflip:
        def fx(y):
            return br + 1.5 - y / (1. * HEIGHT)
    else:
        def fx(y):
            return br + 0.5 + y / (1. * HEIGHT)
    if xflip:
        def fz(x):
            return 0.9 - csys.zinv * x / (1. * WIDTH)
    else:
        def fz(x):
            return 0.1 + csys.zinv * x / (1. * WIDTH)
    def tfm(x, y, fx=fx, fz=fz):
        return csys.xyz((fx(y), 0, fz(x)))
    f3d = Font3D()
    f3d.drawString(text, tfm=tfm, color=color)
Exemplo n.º 9
0
 def Q(self,state,action=None):
     """
     Compute Q(s,a) from W*s.
     """
     if action is None:
         return dot(self.w, state)
     else:
         return dot(self.w[action],state)
Exemplo n.º 10
0
 def Q(self, state, action=None):
     """
     Compute Q(s,a) from W*s.
     """
     if action is None:
         return dot(self.w, state)
     else:
         return dot(self.w[action], state)
Exemplo n.º 11
0
Arquivo: filter.py Projeto: ctuna/ring
  def go(self, xn):
    if (self.x == None):
      self.x = ones(len(self.b)) * xn * 1.0
      self.y = ones(len(self.a)) * xn * 1.0 * sum(self.b) / (1+sum(self.a))

    self.x = concatenate([[xn], self.x[:-1]])
    yn = dot(self.b, self.x) - dot(self.a, self.y)
    self.y = concatenate([[yn], self.y[:-1]])
    return yn
Exemplo n.º 12
0
 def constrainedPosition(self):
     a = self.atoms
     p0, p1, p2, p3 = a[0].posn(), a[1].posn(), a[2].posn(), a[3].posn()
     axis = norm(p2 - p1)
     midpoint = 0.5 * (p1 + p2)
     return _constrainHandleToAngle(self.center() + self.handle_offset,
                                    p0 - dot(p0 - midpoint, axis) * axis,
                                    midpoint,
                                    p3 - dot(p3 - midpoint, axis) * axis)
Exemplo n.º 13
0
 def constrainedPosition(self):
     a = self.atoms
     p0, p1, p2, p3 = a[0].posn(), a[1].posn(), a[2].posn(), a[3].posn()
     axis = norm(p2 - p1)
     midpoint = 0.5 * (p1 + p2)
     return _constrainHandleToAngle(self.center() + self.handle_offset,
                                    p0 - dot(p0 - midpoint, axis) * axis,
                                    midpoint,
                                    p3 - dot(p3 - midpoint, axis) * axis)
    def rotateAboutPoint(self):
        """
        Rotates the selected entities along the specified vector, about the
        specified pivot point (pivot point it the starting point of the
        drawn vector.
        """

        if len(self.mouseClickPoints) != self.mouseClickLimit:
            print_compact_stack("Rotate about point bug: mouseclick points != mouseclicklimit: ")
            return


        pivotPoint = self.mouseClickPoints[0]
        ref_vec_endPoint = self.mouseClickPoints[1]
        rot_vec_endPoint = self.mouseClickPoints[2]

        reference_vec = norm(ref_vec_endPoint - pivotPoint)

        lineVector = norm(rot_vec_endPoint - pivotPoint)


        #lineVector = endPoint - startPoint

        quat1 = Q(lineVector, reference_vec)

        #DEBUG Disabled temporarily . will not be used
        if dot(lineVector, reference_vec) < 0:
            theta = math.pi - quat1.angle
        else:
            theta = quat1.angle

        #TEST_DEBUG-- Works fine
        theta = quat1.angle

        rot_axis = cross(lineVector, reference_vec)


        if dot(lineVector, reference_vec) < 0:
            rot_axis = - rot_axis

        cross_prod_1 = norm(cross(reference_vec, rot_axis))
        cross_prod_2 = norm(cross(lineVector, rot_axis))

        if dot(cross_prod_1, cross_prod_2) < 0:
            quat2 = Q(rot_axis, theta)
        else:
            quat2 = Q(rot_axis, - theta)

        movables = self.graphicsMode.getMovablesForLeftDragging()
        self.assy.rotateSpecifiedMovables(
            quat2,
            movables = movables,
            commonCenter = pivotPoint)

        self.glpane.gl_update()
        return
    def rotateAboutPoint(self):
        """
        Rotates the selected entities along the specified vector, about the
        specified pivot point (pivot point it the starting point of the
        drawn vector.
        """
        startPoint = self.mouseClickPoints[0]
        endPoint = self.mouseClickPoints[1]
        pivotAtom = self.graphicsMode.pivotAtom
        #initial assignment of reference_vec. The selected movables will be
        #rotated by the angle between this vector and the lineVector
        reference_vec = self.glpane.right
        if isinstance(pivotAtom, Atom) and not pivotAtom.molecule.isNullChunk():
            mol = pivotAtom.molecule
            reference_vec, node_junk = mol.getAxis_of_self_or_eligible_parent_node(
                atomAtVectorOrigin = pivotAtom)
            del node_junk
        else:
            reference_vec = self.glpane.right

        lineVector = endPoint - startPoint

        quat1 = Q(lineVector, reference_vec)

        #DEBUG Disabled temporarily . will not be used
        ##if dot(lineVector, reference_vec) < 0:
            ##theta = math.pi - quat1.angle
        ##else:
            ##theta = quat1.angle

        #TEST_DEBUG-- Works fine
        theta = quat1.angle

        rot_axis = cross(lineVector, reference_vec)

        if dot(lineVector, reference_vec) < 0:
            rot_axis = - rot_axis

        cross_prod_1 = norm(cross(reference_vec, rot_axis))
        cross_prod_2 = norm(cross(lineVector, rot_axis))

        if dot(cross_prod_1, cross_prod_2) < 0:
            quat2 = Q(rot_axis,  theta)
        else:
            quat2 = Q(rot_axis,  - theta)


        movables = self.graphicsMode.getMovablesForLeftDragging()
        self.assy.rotateSpecifiedMovables(
            quat2,
            movables = movables,
            commonCenter = startPoint)

        self.glpane.gl_update()
Exemplo n.º 16
0
 def project_2d_noeyeball(self, pt):
     """
     Bruce: Project a point into our plane (ignoring eyeball). Warning: arbitrary origin!
        
     Huaicai 4/20/05: This is just to project pt into a 2d coordinate 
     system (self.right, self.up) on a plane through pt and parallel to the screen 
     plane. For perspective projection, (x, y) on this plane is different than that on the plane 
     through pov.
     """
     x, y = self.right, self.up
     return V(dot(pt, x), dot(pt, y))
Exemplo n.º 17
0
def calc_torsion_angle(atom_list):
    """
    Calculates torsional angle defined by four atoms, A1-A2-A3-A4,
    Return torsional angle value between atoms A2 and A3.

    @param atom_list: list of four atoms describing the torsion bond
    @type atom_list: list

    @return: value of the torsional angle (float)
    """
    # Note: this appears to be very general and perhaps ought to be moved to a more
    # general place (someday), perhaps VQT.py or nearby. [bruce 080828 comment]

    from Numeric import dot
    from math import atan2, pi, sqrt
    from geometry.VQT import cross

    if len(atom_list) != 4:
        # The list has to have four members.
        return 0.0

    # Calculate pairwise distances
    v12 = atom_list[0].posn() - atom_list[1].posn()
    v43 = atom_list[3].posn() - atom_list[2].posn()
    v23 = atom_list[1].posn() - atom_list[2].posn()

    # p is a vector perpendicular to the plane defined by atoms 1,2,3
    # p is perpendicular to v23_v12 plane
    p = cross(v23, v12)

    # x is a vector perpendicular to the plane defined by atoms 2,3,4.
    # x is perpendicular to v23_v43 plane
    x = cross(v23, v43)

    # y is perpendicular to v23_x plane
    y = cross(v23, x)

    # Calculate lengths of the x, y vectors.
    u1 = dot(x, x)
    v1 = dot(y, y)

    if u1 < 0.0 or \
       v1 < 0.0:
        return 360.0

    u2 = dot(p, x) / sqrt(u1)
    v2 = dot(p, y) / sqrt(v1)

    if u2 != 0.0 and \
       v2 != 0.0:
        # calculate the angle
        return atan2(v2, u2) * (180.0 / pi)
    else:
        return 360.0
Exemplo n.º 18
0
def calc_torsion_angle(atom_list):
    """
    Calculates torsional angle defined by four atoms, A1-A2-A3-A4,
    Return torsional angle value between atoms A2 and A3.

    @param atom_list: list of four atoms describing the torsion bond
    @type atom_list: list

    @return: value of the torsional angle (float)
    """
    # Note: this appears to be very general and perhaps ought to be moved to a more
    # general place (someday), perhaps VQT.py or nearby. [bruce 080828 comment]

    from Numeric import dot
    from math import atan2, pi, sqrt
    from geometry.VQT import cross

    if len(atom_list) != 4:
        # The list has to have four members.
        return 0.0

    # Calculate pairwise distances
    v12 = atom_list[0].posn() - atom_list[1].posn()
    v43 = atom_list[3].posn() - atom_list[2].posn()
    v23 = atom_list[1].posn() - atom_list[2].posn()

    # p is a vector perpendicular to the plane defined by atoms 1,2,3
    # p is perpendicular to v23_v12 plane
    p = cross(v23, v12)

    # x is a vector perpendicular to the plane defined by atoms 2,3,4.
    # x is perpendicular to v23_v43 plane
    x = cross(v23, v43)

    # y is perpendicular to v23_x plane
    y = cross(v23, x)

    # Calculate lengths of the x, y vectors.
    u1 = dot(x, x)
    v1 = dot(y, y)

    if u1 < 0.0 or \
       v1 < 0.0:
        return 360.0

    u2 = dot(p, x) / sqrt(u1)
    v2 = dot(p, y) / sqrt(v1)

    if u2 != 0.0 and \
       v2 != 0.0:
        # calculate the angle
        return atan2(v2, u2) * (180.0 / pi)
    else:
        return 360.0
Exemplo n.º 19
0
    def rotateAboutPoint(self):
        """
        Rotates the selected entities along the specified vector, about the
        specified pivot point (pivot point it the starting point of the
        drawn vector.
        """

        if len(self.mouseClickPoints) != self.mouseClickLimit:
            print_compact_stack(
                "Rotate about point bug: mouseclick points != mouseclicklimit: "
            )
            return

        pivotPoint = self.mouseClickPoints[0]
        ref_vec_endPoint = self.mouseClickPoints[1]
        rot_vec_endPoint = self.mouseClickPoints[2]

        reference_vec = norm(ref_vec_endPoint - pivotPoint)

        lineVector = norm(rot_vec_endPoint - pivotPoint)

        #lineVector = endPoint - startPoint

        quat1 = Q(lineVector, reference_vec)

        #DEBUG Disabled temporarily . will not be used
        if dot(lineVector, reference_vec) < 0:
            theta = math.pi - quat1.angle
        else:
            theta = quat1.angle

        #TEST_DEBUG-- Works fine
        theta = quat1.angle

        rot_axis = cross(lineVector, reference_vec)

        if dot(lineVector, reference_vec) < 0:
            rot_axis = -rot_axis

        cross_prod_1 = norm(cross(reference_vec, rot_axis))
        cross_prod_2 = norm(cross(lineVector, rot_axis))

        if dot(cross_prod_1, cross_prod_2) < 0:
            quat2 = Q(rot_axis, theta)
        else:
            quat2 = Q(rot_axis, -theta)

        movables = self.graphicsMode.getMovablesForLeftDragging()
        self.assy.rotateSpecifiedMovables(quat2,
                                          movables=movables,
                                          commonCenter=pivotPoint)

        self.glpane.gl_update()
        return
Exemplo n.º 20
0
 def project_2d_noeyeball(self, pt):
     """
     Bruce: Project a point into our plane (ignoring eyeball). Warning: arbitrary origin!
        
     Huaicai 4/20/05: This is just to project pt into a 2d coordinate 
     system (self.right, self.up) on a plane through pt and parallel to the screen 
     plane. For perspective projection, (x, y) on this plane is different than that on the plane 
     through pov.
     """
     x, y = self.right, self.up
     return V(dot(pt, x), dot(pt, y))
Exemplo n.º 21
0
  def kfupdate(self, dt, rs):
    self.ab  = array((rs.ax, -rs.ay, -rs.az))

    ph = self.phi
    th = self.theta
    P  = self.pmat

    A  = array(((-rs.q*cos(ph)*tan(th)+rs.r*sin(ph)*tan(th), (-rs.q*sin(ph)+rs.r*cos(ph))/(cos(th)*cos(th))),
                (rs.q*sin(ph)-rs.r*cos(ph)                 , 0)))

    dph = rs.p - rs.q*sin(ph)*tan(th) - rs.r*cos(ph)*tan(th)
    dth =      - rs.q*cos(ph)         - rs.r*sin(ph)
    dP  = dot(A, P) + dot(P, transpose(A)) + self.Q

    ph = ph + dph * dt
    th = th + dth * dt
    P  = P  + dP  * dt

    Cx = array((0               , cos(th)))
    Cy = array((-cos(th)*cos(ph), sin(th)*sin(ph)))
    Cz = array((cos(th)*sin(ph) , sin(th)*cos(ph)))
    C  = array((Cx, Cy, Cz))

    L = dot(dot(P, transpose(C)), inverse(self.R + dot(dot(C, P), transpose(C))))
    h = array((sin(th), -cos(th)*sin(ph), -cos(th)*cos(ph)))

    P  = dot(identity(2) - dot(L, C), P)
    ph = ph + dot(L[0], self.ab - h)
    th = th + dot(L[1], self.ab - h) 

    ph = ((ph+pi) % (2*pi)) - pi;
    th = ((th+pi) % (2*pi)) - pi;

    self.pmat  = P
    self.phi   = ph 
    self.theta = th

    psidot = rs.q * sin(ph) / cos(th) + rs.r * cos(ph) / cos(th);
    self.psi += psidot * dt;

    self.quat = eul2quat(ph,th,self.psi)
    # self.dcmb2e = quat2dcm(quatinv(self.quat))

    # self.ae = dot(self.dcmb2e, self.ab)
    self.ae = quatrotate(quatinv(self.quat), self.ab)
    self.ae[2] = -self.ae[2]-1
    self.ae[1] = -self.ae[1]

    self.ve += self.ae * dt * 9.81
    self.xe += self.ve * dt
def selection_polyhedron(basepos, borderwidth=1.8):
    """
    Given basepos (a Numeric array of 3d positions), compute and return (as a list of vertices, each pair being an edge to draw)
    a simple bounding polyhedron, convenient for designating the approximate extent of this set of points.
    (This is used on the array of atom and open bond positions in a chunk to designate a selected chunk.)
       Make every face farther out than it needs to be to enclose all points in basepos, by borderwidth (default 1.8).
    Negative values of borderwidth might sometimes work, but are likely to fail drastically if the polyhedron is too small.
       The orientation of the faces matches the coordinate axes used in basepos (in typical calls, these are chunk-relative).
    [#e Someday we might permit caller-specified orientation axes. The axes of inertia would be interesting to try.]
    """
    #bruce 060226/060605 made borderwidth an argument (non-default values untested); documented retval format
    #bruce 060119 split this out of shakedown_poly_evals_evecs_axis() in chunk.py.
    # Note, it has always had some bad bugs for certain cases, like long diagonal rods.

    if not len(basepos):
        return []  # a guess

    # find extrema in many directions
    xtab = dot(basepos, polyXmat)
    mins = minimum.reduce(xtab) - borderwidth
    maxs = maximum.reduce(xtab) + borderwidth

    polyhedron = makePolyList(cat(maxs, mins))
    # apparently polyhedron is just a long list of vertices [v0,v1,v2,v3,...] to be passed to GL_LINES
    # (via drawlinelist), which will divide them into pairs and draw lines v0-v1, v2-v3, etc.
    # Maybe we should generalize the format, so some callers could also draw faces.
    # [bruce 060226/060605 comment]
    return polyhedron
def inertia_eigenvectors(basepos, already_centered=False):
    """
    Given basepos (an array of positions),
    compute and return (as a 2-tuple) the lists of eigenvalues and
    eigenvectors of the inertia tensor (computed as if all points had the same
    mass). These lists are always length 3, even for len(basepos) of 0,1, or 2,
    overlapping or colinear points, etc, though some evals will be 0 in these cases.
       Optional small speedup: if caller knows basepos is centered at the origin, it can say so.
    """
    #bruce 060119 split this out of shakedown_poly_evals_evecs_axis() in chunk.py
    basepos = A(basepos)  # make sure it's a Numeric array
    if not already_centered and len(basepos):
        center = add.reduce(basepos) / len(basepos)
        basepos = basepos - center
    # compute inertia tensor
    tensor = zeros((3, 3), Float)
    for p in basepos:
        rsq = dot(p, p)
        m = -multiply.outer(p, p)
        m[0, 0] += rsq
        m[1, 1] += rsq
        m[2, 2] += rsq
        tensor += m
    evals, evecs = eigenvectors(tensor)
    assert len(evals) == len(evecs) == 3
    return evals, evecs
Exemplo n.º 24
0
    def recompute_geom_both_ends_constrained(self):
        """
        Using self.b0L_pvec and self.chain_quat_cum and self.bm1R_pvec,
        figure out self.twist...
        [used for rings, and for linear chains with both ends constrained]
        """
        bonds = self.listb
        # what pvec would we have on the right end of the chain, if there were no per-bond twist?
        bm1R_pvec_no_twist = self.chain_quat_cum.rot( self.b0L_pvec ) # note, this is a vector perp to bond[-1]
        axism1 = self.axes[-1]
        # what twist is needed to put that vector over the actual one (or its neg), perhaps with 90-deg offset?
        i = len(bonds) - 1
##        if self.twist90 and i % 2 == 1:
##            bm1R_pvec_no_twist = norm(cross(axism1, bm1R_pvec_no_twist))
        # use negative if that fits better
        if dot(bm1R_pvec_no_twist, self.bm1R_pvec) < 0:
            bm1R_pvec_no_twist = - bm1R_pvec_no_twist
        # total twist is shared over every bond
        # note: we care which direction we rotate around axism1
        total_twist = twistor_angle( axism1, bm1R_pvec_no_twist, self.bm1R_pvec)
            # in radians; angular range is undefined, for now
            # [it's actually +- 2pi, twice what it would need to be in general],
            # so we need to coerce it into the range we want, +- pi/2 (90 degrees); here too we use the fact
            # that in this case, a twist of pi (180 degrees) is the same as 0 twist.
        while total_twist > math.pi/2:
            total_twist -= math.pi
        while total_twist <= - math.pi/2:
            total_twist += math.pi
        self.twist = total_twist / len(bonds)
        return
Exemplo n.º 25
0
    def setup_quat_center(self, atomList = None):
        """
        Setup the plane's quat using a list of atoms.

        If no atom list is supplied, the plane is centered in the glpane
        and parallel to the screen.

        @param atomList: A list of atoms.
        @type  atomList: list

        """
        if atomList:    
            self.atomPos = []
            for a in atomList:
                self.atomPos += [a.posn()]    
            planeNorm = self._getPlaneOrientation(self.atomPos)
            if dot(planeNorm, self.glpane.lineOfSight) < 0:
                planeNorm = -planeNorm                
            self.center = add.reduce(self.atomPos) / len(self.atomPos)
            self.quat   = Q(V(0.0, 0.0, 1.0), planeNorm) 
        else:       
            self.center = V(0.0, 0.0, 0.0)
            # Following makes sure that Plane edges are parallel to
            # the 3D workspace borders. Fixes bug 2448
            x, y ,z = self.glpane.right, self.glpane.up, self.glpane.out
            self.quat  = Q(x, y, z) 
            self.quat += Q(self.glpane.right, pi)
Exemplo n.º 26
0
 def InnerProduct(self, vector, other):
     """Innerproduct for vectors"""
     if vector.GetSpace() == other.GetSpace():
         return dot(vector.GetCartesianCoordinates(),
                    other.GetCartesianCoordinates())
     else:
         raise ValueError, 'Innerproduct of two vectors in different vector space not implemented'
Exemplo n.º 27
0
 def project_2d(self, pt):
     """
     like project_2d_noeyeball, but take into account self.eyeball;
     return None for a point that is too close to eyeball to be projected
     [in the future this might include anything too close to be drawn #e]
     """
     p = self.project_2d_noeyeball(pt)
     if self.eyeball:
         # bruce 041214: use "pfix" to fix bug 30 comment #3
         pfix = self.project_2d_noeyeball(self.org)
         p -= pfix
         try:
             ###e we recompute this a lot; should cache it in self or self.shp--Bruce
             ## Huaicai 04/23/05: made the change as suggested by Bruce above.
             p = p / (dot(pt - self.eyeball, self.normal) / self.eye2Pov)
         except:
             # bruce 041214 fix of unreported bug:
             # point is too close to eyeball for in-ness to be determined!
             # [More generally, do we want to include points which are
             #  projectable without error, but too close to the eyeball
             #  to be drawn? I think not, but I did not fix this yet
             #  (or report the bug). ###e]
             if debug_flags.atom_debug:
                 print_compact_traceback("atom_debug: ignoring math error for point near eyeball: ")
             return None
         p += pfix
     return p
Exemplo n.º 28
0
def selection_polyhedron(basepos, borderwidth = 1.8):
    """
    Given basepos (a Numeric array of 3d positions), compute and return (as a list of vertices, each pair being an edge to draw)
    a simple bounding polyhedron, convenient for designating the approximate extent of this set of points.
    (This is used on the array of atom and open bond positions in a chunk to designate a selected chunk.)
       Make every face farther out than it needs to be to enclose all points in basepos, by borderwidth (default 1.8).
    Negative values of borderwidth might sometimes work, but are likely to fail drastically if the polyhedron is too small.
       The orientation of the faces matches the coordinate axes used in basepos (in typical calls, these are chunk-relative).
    [#e Someday we might permit caller-specified orientation axes. The axes of inertia would be interesting to try.]
    """
    #bruce 060226/060605 made borderwidth an argument (non-default values untested); documented retval format
    #bruce 060119 split this out of shakedown_poly_evals_evecs_axis() in chunk.py.
    # Note, it has always had some bad bugs for certain cases, like long diagonal rods.

    if not len(basepos):
        return [] # a guess
    
    # find extrema in many directions
    xtab = dot(basepos, polyXmat)
    mins = minimum.reduce(xtab) - borderwidth
    maxs = maximum.reduce(xtab) + borderwidth

    polyhedron = makePolyList(cat(maxs,mins))
        # apparently polyhedron is just a long list of vertices [v0,v1,v2,v3,...] to be passed to GL_LINES
        # (via drawlinelist), which will divide them into pairs and draw lines v0-v1, v2-v3, etc.
        # Maybe we should generalize the format, so some callers could also draw faces.
        # [bruce 060226/060605 comment]
    return polyhedron
Exemplo n.º 29
0
def inertia_eigenvectors(basepos, already_centered = False):
    """
    Given basepos (an array of positions),
    compute and return (as a 2-tuple) the lists of eigenvalues and
    eigenvectors of the inertia tensor (computed as if all points had the same
    mass). These lists are always length 3, even for len(basepos) of 0,1, or 2,
    overlapping or colinear points, etc, though some evals will be 0 in these cases.
       Optional small speedup: if caller knows basepos is centered at the origin, it can say so.
    """
    #bruce 060119 split this out of shakedown_poly_evals_evecs_axis() in chunk.py
    basepos = A(basepos) # make sure it's a Numeric array
    if not already_centered and len(basepos):
        center = add.reduce(basepos)/len(basepos)
        basepos = basepos - center
    # compute inertia tensor
    tensor = zeros((3,3),Float)
    for p in basepos:
        rsq = dot(p, p)
        m= - multiply.outer(p, p)
        m[0,0] += rsq
        m[1,1] += rsq
        m[2,2] += rsq
        tensor += m
    evals, evecs = eigenvectors(tensor)
    assert len(evals) == len(evecs) == 3
    return evals, evecs
Exemplo n.º 30
0
def makePolyList(v):
    xlines = [[],[],[],[],[],[],[],[],[],[],[],[]]
    segs = []
    for corner, edges, planes in polyTab:
        linx = []
        for i in range(3):
            l,s,r = planes[2*i:2*i+3]
            e = remainder(i+1,3)
            p1 = planepoint(v,corner,l,r)
            if abs(dot(p1,polyMat[s])) <= abs(v[s]):
                p2 = planepoint(v,l,s,r)
                linx += [p1]
                xlines[edges[i]] += [p2]
                xlines[edges[e]] += [p2]
                segs += [p1,p2]
            else:
                p1 = planepoint(v,corner,l,s)
                p2 = planepoint(v,corner,r,s)
                linx += [p1,p2]
                xlines[edges[i]] += [p1]
                xlines[edges[e]] += [p2]
        e=edges[0]
        xlines[e] = xlines[e][:-2] + [xlines[e][-1],xlines[e][-2]]
        for p1,p2 in zip(linx, linx[1:]+[linx[0]]):
            segs += [p1,p2]
    
    ctl = 12
    for lis in xlines[:ctl]:
        segs += [lis[0],lis[3],lis[1],lis[2]]

    assert type(segs) == type([]) #bruce 041119
    return segs
Exemplo n.º 31
0
 def closest_pt_params_to_ray(self, ray):
     ""
     p2, v2 = ray.params # note: at first I wrote self.params() (using method not attr)
     p1, v1 = self.params
     # do some math, solve for k in p1 + k * v1 = that point (remember that the vecs can be of any length):
     # way 1: express p2-p1 as a weighted sum of v1, v2, cross(v1,v2), then take the v1 term in that sum and add it to p1.
     # way 2: There must be a NumPy function that would just do this in about one step...
     # way 3: or maybe we can mess around with dot(v1,v2) sort of like in corner_analyzer in demo_polygon...
     # way 4: or we could google for "closest points on two lines" or so...
     # way 5: or we could call it the intersection of self with the plane containing p2, and directions v2 and the cross prod,
     # and use a formula in VQT. Yes, that may not be self-contained but it's fastest to code!
     v1n = norm(v1)
     v2n = norm(v2)
     perp0 = cross(v1n, v2n)
     if vlen(perp0) < 0.01:
         ##k btw what if the lines are parallel, in what way should we fail?
         # and for that matter what if they are *almost* parallel so that we're too sensitive -- do we use an env param
         # to decide whether to fail in that case too? If we're an Instance we could do that from self.env... #e
         print "closest_pt_params_to_ray: too sensitive, returning None" ###### teach caller to handle this; let 0.01 be option
         return None
     perpn = norm(perp0)
     perpperp = cross(perpn,v2n)
     inter = planeXline(p2, perpperp, p1, v1n) # intersect plane (as plane point and normal) with line (as point and vector)
     if inter is None:
         print "inter is None (unexpected); data:",p1,v1,p2,v2,perp0
         return None
     # inter is the retval for a variant which just wants the closest point itself, i.e. closest_pt_to_ray
     return dot(inter - p1, v1n) / vlen(v1)
Exemplo n.º 32
0
 def recompute_geom_both_ends_constrained(self):
     """
     Using self.b0L_pvec and self.chain_quat_cum and self.bm1R_pvec,
     figure out self.twist...
     [used for rings, and for linear chains with both ends constrained]
     """
     bonds = self.listb
     # what pvec would we have on the right end of the chain, if there were no per-bond twist?
     bm1R_pvec_no_twist = self.chain_quat_cum.rot(
         self.b0L_pvec)  # note, this is a vector perp to bond[-1]
     axism1 = self.axes[-1]
     # what twist is needed to put that vector over the actual one (or its neg), perhaps with 90-deg offset?
     i = len(bonds) - 1
     ##        if self.twist90 and i % 2 == 1:
     ##            bm1R_pvec_no_twist = norm(cross(axism1, bm1R_pvec_no_twist))
     # use negative if that fits better
     if dot(bm1R_pvec_no_twist, self.bm1R_pvec) < 0:
         bm1R_pvec_no_twist = -bm1R_pvec_no_twist
     # total twist is shared over every bond
     # note: we care which direction we rotate around axism1
     total_twist = twistor_angle(axism1, bm1R_pvec_no_twist, self.bm1R_pvec)
     # in radians; angular range is undefined, for now
     # [it's actually +- 2pi, twice what it would need to be in general],
     # so we need to coerce it into the range we want, +- pi/2 (90 degrees); here too we use the fact
     # that in this case, a twist of pi (180 degrees) is the same as 0 twist.
     while total_twist > math.pi / 2:
         total_twist -= math.pi
     while total_twist <= -math.pi / 2:
         total_twist += math.pi
     self.twist = total_twist / len(bonds)
     return
Exemplo n.º 33
0
    def update_numberOfBases(self):
        """
        Updates the numberOfBases in the PM while a resize handle is being 
        dragged. 
        @see: self.getCursorText() where it is called. 
        """
        #@Note: originally (before 2008-04-05, it was called in 
        #DnaStrand_ResizeHandle.on_drag() but that 'may' have some bugs 
        #(not verified) also see self.getCursorText() to know why it is
        #called there (basically a workaround for bug 2729
        if self.grabbedHandle is None:
            return

        currentPosition = self.grabbedHandle.currentPosition
        resize_end = self.grabbedHandle.origin

        new_duplexLength = vlen( currentPosition - resize_end )

        numberOfBasePairs_to_change = getNumberOfBasePairsFromDuplexLength('B-DNA', 
                                                                           new_duplexLength)

        original_numberOfBases = self.struct.getNumberOfBases()
        #If the dot product of handle direction and the direction in which it 
        #is dragged is negative, this means we need to subtract bases
        direction_of_drag = norm(currentPosition - resize_end)
        if dot(self.grabbedHandle.direction, direction_of_drag ) < 0:
            total_number_of_bases = original_numberOfBases - numberOfBasePairs_to_change
            self.propMgr.numberOfBasesSpinBox.setValue(total_number_of_bases)
        else:
            total_number_of_bases = original_numberOfBases + numberOfBasePairs_to_change
            self.propMgr.numberOfBasesSpinBox.setValue(total_number_of_bases - 1)
Exemplo n.º 34
0
 def project_2d(self, pt):
     """
     like project_2d_noeyeball, but take into account self.eyeball;
     return None for a point that is too close to eyeball to be projected
     [in the future this might include anything too close to be drawn #e]
     """
     p = self.project_2d_noeyeball(pt)
     if self.eyeball:
         # bruce 041214: use "pfix" to fix bug 30 comment #3
         pfix = self.project_2d_noeyeball(self.org)
         p -= pfix
         try:
             ###e we recompute this a lot; should cache it in self or self.shp--Bruce
             ## Huaicai 04/23/05: made the change as suggested by Bruce above.
             p = p / (dot(pt - self.eyeball, self.normal) / self.eye2Pov)
         except:
             # bruce 041214 fix of unreported bug:
             # point is too close to eyeball for in-ness to be determined!
             # [More generally, do we want to include points which are
             #  projectable without error, but too close to the eyeball
             #  to be drawn? I think not, but I did not fix this yet
             #  (or report the bug). ###e]
             if debug_flags.atom_debug:
                 print_compact_traceback("atom_debug: ignoring math error for point near eyeball: ")
             return None
         p += pfix
     return p
Exemplo n.º 35
0
 def closest_pt_params_to_ray(self, ray):
     ""
     p2, v2 = ray.params  # note: at first I wrote self.params() (using method not attr)
     p1, v1 = self.params
     # do some math, solve for k in p1 + k * v1 = that point (remember that the vecs can be of any length):
     # way 1: express p2-p1 as a weighted sum of v1, v2, cross(v1,v2), then take the v1 term in that sum and add it to p1.
     # way 2: There must be a NumPy function that would just do this in about one step...
     # way 3: or maybe we can mess around with dot(v1,v2) sort of like in corner_analyzer in demo_polygon...
     # way 4: or we could google for "closest points on two lines" or so...
     # way 5: or we could call it the intersection of self with the plane containing p2, and directions v2 and the cross prod,
     # and use a formula in VQT. Yes, that may not be self-contained but it's fastest to code!
     v1n = norm(v1)
     v2n = norm(v2)
     perp0 = cross(v1n, v2n)
     if vlen(perp0) < 0.01:
         ##k btw what if the lines are parallel, in what way should we fail?
         # and for that matter what if they are *almost* parallel so that we're too sensitive -- do we use an env param
         # to decide whether to fail in that case too? If we're an Instance we could do that from self.env... #e
         print "closest_pt_params_to_ray: too sensitive, returning None"  ###### teach caller to handle this; let 0.01 be option
         return None
     perpn = norm(perp0)
     perpperp = cross(perpn, v2n)
     inter = planeXline(
         p2, perpperp, p1, v1n
     )  # intersect plane (as plane point and normal) with line (as point and vector)
     if inter is None:
         print "inter is None (unexpected); data:", p1, v1, p2, v2, perp0
         return None
     # inter is the retval for a variant which just wants the closest point itself, i.e. closest_pt_to_ray
     return dot(inter - p1, v1n) / vlen(v1)
Exemplo n.º 36
0
    def __CM_Align_to_chunk(self):
        """
        Rotary or Linear Motor context menu command: "Align to chunk"
        This uses the chunk connected to the first atom of the motor.
        """
        # I needed this when attempting to simulate the rotation of a long, skinny
        # chunk.  The axis computed from the attached atoms was not close to the axis
        # of the chunk.  I figured this would be a common feature that was easy to add.
        # 
        ##e it might be nice to dim this menu item if the chunk's axis hasn't moved since this motor was made or recentered;
        # first we'd need to extend the __CM_ API to make that possible. [mark 050717]

        cmd = greenmsg("Align to Chunk: ")

        chunk = self.atoms[0].molecule # Get the chunk attached to the motor's first atom.
        # wware 060116 bug 1330
        # The chunk's axis could have its direction exactly reversed and be equally valid.
        # We should choose between those two options for which one has the positive dot
        # product with the old axis, to avoid reversals of motor direction when going
        # between "align to chunk" and "recenter on atoms".
        #bruce 060116 modified this fix to avoid setting axis to V(0,0,0) if it's perpendicular to old axis.
        newAxis = chunk.getaxis()
        if dot(self.axis,newAxis) < 0:
            newAxis = - newAxis
        self.axis = newAxis
        self.assy.changed()   # wware 060116 bug 1331 - assembly changed when axis changed

        info = "Aligned motor [%s] on chunk [%s]" % (self.name, chunk.name) 
        env.history.message( cmd + info ) 
        self.assy.w.win_update()

        return
Exemplo n.º 37
0
    def viewParallelTo(self):
        """
        Set view parallel to the vector defined by 2 selected atoms.
        """
        cmd = greenmsg("Set View Parallel To: ")

        atoms = self.assy.selatoms_list()

        if len(atoms) != 2:
            msg = redmsg("You must select 2 atoms.")
            env.history.message(cmd + msg)
            return

        v = norm(atoms[0].posn()-atoms[1].posn())

        if vlen(v) < 0.0001: # Atoms are on top of each other.
            info = 'The selected atoms are on top of each other.  No change in view.'
            env.history.message(cmd + info)
            return

        # If vec is pointing into the screen, negate (reverse) vec.
        if dot(v, self.glpane.lineOfSight) > 0:
            v = -v

        # Compute the destination quat (q2).
        q2 = Q(V(0,0,1), v)
        q2 = q2.conj()

        self.glpane.rotateView(q2)

        info = 'View set parallel to the vector defined by the 2 selected atoms.'
        env.history.message(cmd + info)
def makePolyList(v):
    xlines = [[], [], [], [], [], [], [], [], [], [], [], []]
    segs = []
    for corner, edges, planes in polyTab:
        linx = []
        for i in range(3):
            l, s, r = planes[2 * i:2 * i + 3]
            e = remainder(i + 1, 3)
            p1 = planepoint(v, corner, l, r)
            if abs(dot(p1, polyMat[s])) <= abs(v[s]):
                p2 = planepoint(v, l, s, r)
                linx += [p1]
                xlines[edges[i]] += [p2]
                xlines[edges[e]] += [p2]
                segs += [p1, p2]
            else:
                p1 = planepoint(v, corner, l, s)
                p2 = planepoint(v, corner, r, s)
                linx += [p1, p2]
                xlines[edges[i]] += [p1]
                xlines[edges[e]] += [p2]
        e = edges[0]
        xlines[e] = xlines[e][:-2] + [xlines[e][-1], xlines[e][-2]]
        for p1, p2 in zip(linx, linx[1:] + [linx[0]]):
            segs += [p1, p2]

    ctl = 12
    for lis in xlines[:ctl]:
        segs += [lis[0], lis[3], lis[1], lis[2]]

    assert type(segs) == type([])  #bruce 041119
    return segs
Exemplo n.º 39
0
    def getDnaRibbonParams(self):
        """
        Returns parameters for drawing the dna ribbon. 

        If the dna rubberband line should NOT be drawn (example when you are 
        removing bases from the strand or  if its unable to get dnaSegment) , 
        it retuns None. So the caller should check if the method return value
        is not None. 
        @see: DnaStrand_GraphicsMode._draw_handles()
        """

        if self.grabbedHandle is None:
            return None

        if self.grabbedHandle.origin is None:
            return None

        direction_of_drag = norm(self.grabbedHandle.currentPosition - \
                                 self.grabbedHandle.origin)

        #If the strand bases are being removed (determined by checking the 
        #direction of drag) , no need to draw the rubberband line. 
        if dot(self.grabbedHandle.direction, direction_of_drag) < 0:
            return None

        strandEndAtom, axisEndAtom = self.get_strand_and_axis_endAtoms_at_resize_end()

        #DnaStrand.get_DnaSegment_with_content_atom saely handles the case where
        #strandEndAtom is None. 
        dnaSegment = self.struct.get_DnaSegment_with_content_atom(strandEndAtom)

        ribbon1_direction = None

        if dnaSegment:     
            basesPerTurn = dnaSegment.getBasesPerTurn()
            duplexRise = dnaSegment.getDuplexRise()        
            ribbon1_start_point = strandEndAtom.posn()

            if strandEndAtom:
                ribbon1_start_point = strandEndAtom.posn()
                for bond_direction, neighbor in strandEndAtom.bond_directions_to_neighbors():
                    if neighbor and neighbor.is_singlet():
                        ribbon1_direction = bond_direction
                        break

            ribbon1Color = strandEndAtom.molecule.color
            if not ribbon1Color:
                ribbon1Color = strandEndAtom.element.color

            return (self.grabbedHandle.origin,
                    self.grabbedHandle.currentPosition,
                    basesPerTurn, 
                    duplexRise, 
                    ribbon1_start_point,
                    ribbon1_direction,
                    ribbon1Color
                )

        return None
Exemplo n.º 40
0
 def __init__(self, point0, z, uhint, uhint2):
     # u and v and zn are unit vectors
     # z is NOT a unit vector
     self.p0 = point0
     self.p1 = point1 = point0 + z
     self.z = z
     zlen = vlen(z)
     if zlen < 1.0e-6:
         raise ZeroLengthCylinder()
     self.zinv = 1.0 / zlen
     self.zn = zn = norm(z)
     u = norm(uhint - (dot(uhint, z) / zlen**2) * z)
     if vlen(u) < 1.0e-4:
         u = norm(uhint2 - (dot(uhint2, z) / zlen**2) * z)
     v = cross(zn, u)
     self.u = u
     self.v = v
Exemplo n.º 41
0
 def __init__(self, point0, z, uhint, uhint2):
     # u and v and zn are unit vectors
     # z is NOT a unit vector
     self.p0 = point0
     self.p1 = point1 = point0 + z
     self.z = z
     zlen = vlen(z)
     if zlen < 1.0e-6:
         raise ZeroLengthCylinder()
     self.zinv = 1.0 / zlen
     self.zn = zn = norm(z)
     u = norm(uhint - (dot(uhint, z) / zlen ** 2) * z)
     if vlen(u) < 1.0e-4:
         u = norm(uhint2 - (dot(uhint2, z) / zlen ** 2) * z)
     v = cross(zn, u)
     self.u = u
     self.v = v
Exemplo n.º 42
0
def mymousepoints(glpane, x, y): #bruce 071017 moved this here from testdraw.py
    ### TODO: rename, docstring

    # modified from GLPane.mousepoints; x and y are window coords (except y is 0 at bottom, positive as you go up [guess 070124])
    self = glpane
    just_beyond = 0.0
    p1 = A(gluUnProject(x, y, just_beyond))
    p2 = A(gluUnProject(x, y, 1.0))

    los = self.lineOfSight # isn't this just norm(p2 - p1)?? Probably not, if we're in perspective mode! [bruce Q 061206]
        # note: this might be in abs coords (not sure!) even though p1 and p2 would be in local coords.
        # I need to review that in GLPane.__getattr__. ###k

    k = dot(los, -self.pov - p1) / dot(los, p2 - p1)

    p2 = p1 + k*(p2-p1)
    return (p1, p2)
Exemplo n.º 43
0
def mvmul(A, x):
  """Multiply matrix A onto vector x
  """

  from Numeric import dot, reshape

  x = reshape(x, (A.shape[1], 1)) #Make x a column vector             
  return dot(A, x)
Exemplo n.º 44
0
    def computeEndPointsFromChunk(self, chunk, update = True):
        """
        Derives and returns the endpoints and radius of a Peptide chunk.
        @param chunk: a Peptide chunk
        @type  chunk: Chunk
        @return: endPoint1, endPoint2 and radius
        @rtype: Point, Point and float

        @note: computing the endpoints works fine when n=m or m=0. Otherwise,
               the endpoints can be slightly off the central axis, especially
               if the Peptide is short.
        @attention: endPoint1 and endPoint2 may not be the original endpoints,
                    and they may be flipped (opposites of) the original
                    endpoints.
        """
        # Since chunk.axis is not always one of the vectors chunk.evecs
        # (actually chunk.poly_evals_evecs_axis[2]), it's best to just use
        # the axis and center, then recompute a bounding cylinder.
        if not chunk.atoms:
            return None

        axis = chunk.axis
        axis = norm(axis) # needed
        center = chunk._get_center()
        points = chunk.atpos - center # not sure if basepos points are already centered
        # compare following Numeric Python code to findAtomUnderMouse and its caller
        matrix = matrix_putting_axis_at_z(axis)
        v = dot( points, matrix)
        # compute xy distances-squared between axis line and atom centers
        r_xy_2 = v[:,0]**2 + v[:,1]**2

        # to get radius, take maximum -- not sure if max(r_xy_2) would use Numeric code, but this will for sure:
        i = argmax(r_xy_2)
        max_xy_2 = r_xy_2[i]
        radius = sqrt(max_xy_2)
        # to get limits along axis (since we won't assume center is centered between them), use min/max z:
        z = v[:,2]
        min_z = z[argmin(z)]
        max_z = z[argmax(z)]

        # Adjust the endpoints such that the ladder rungs (rings) will fall
        # on the ring segments.
        # TO DO: Fix drawPeptideLadder() to offset the first ring, then I can
        # remove this adjustment. --Mark 2008-04-12
        z_adjust = self.getEndPointZOffset()
        min_z += z_adjust
        max_z -= z_adjust

        endpoint1 = center + min_z * axis
        endpoint2 = center + max_z * axis

        if update:
            #print "Original endpoints:", self.getEndPoints()
            self.setEndPoints(endpoint1, endpoint2)
            #print "New endpoints:", self.getEndPoints()

        return (endpoint1, endpoint2, radius)
Exemplo n.º 45
0
def projectPointOntoPlane(point, planeNormal, planePoint):
    planeNormal = normalise(planeNormal)
    relVector = vectorDifference(planePoint, point)
    dist = dot(relVector,planeNormal)
    oldpoint =point

    point = vectorAdd(point, (scalarMultiply(dist, planeNormal)))

    return point
Exemplo n.º 46
0
    def InnerProduct(self,vector,other):
	"""Innerproduct for vectors"""
	if vector.GetSpace()==other.GetSpace():
	    from Numeric import matrixmultiply,transpose
	    # (v,o)=(v_coor^T*basis^T*basis*o_coor)
	    metric=matrixmultiply(self.GetBasis(),transpose(self.GetBasis()))
	    return dot(vector.GetCoordinates(),matrixmultiply(metric,other.GetCoordinates()))
	else:
	    raise ValueError, 'Innerproduct of two vectors in different vector space not implemented'
Exemplo n.º 47
0
def best_vector_in_plane( axes, goodvecs, numeric_threshhold ):
    """
    axes is a list of two orthonormal vectors defining a plane,
    and goodvecs is a list of unit vectors or (ignored) zero vectors or Nones;
    return whichever unit vector in the plane defined by axes is closest in direction
    to the first goodvec which helps determine this (i.e. which is not zero or None,
    and is not perpendicular to the plane, using numeric_threshhold to determine what's too
    close to call). If none of the goodvecs help, return None.
    """
    x,y = axes
    for good in goodvecs:
        if good is not None:
            dx = dot(x,good) # will be 0 for good = V(0,0,0); not sensible for vlen(good) other than 0 or 1
            dy = dot(y,good)
            if abs(dx) < numeric_threshhold and abs(dy) < numeric_threshhold:
                continue # good is perpendicular to the plane (or is zero)
            return norm(dx * x + dy * y)
    return None
Exemplo n.º 48
0
def _constrainHandleToAngle(pos, p0, p1, p2):
    """
    This works in two steps.
    (1) Project pos onto the plane defined by (p0, p1, p2).
    (2) Confine the projected point to lie within the angular arc.
    """
    u = pos - p1
    z0 = norm(p0 - p1)
    z2 = norm(p2 - p1)
    oop = norm(cross(z0, z2))
    u = u - dot(oop, u) * oop
    # clip the point so it lies within the angle
    if dot(cross(z0, u), oop) < 0:
        # Clip on the z0 side of the angle.
        u = vlen(u) * z0
    elif dot(cross(u, z2), oop) < 0:
        # Clip on the z2 side of the angle.
        u = vlen(u) * z2
    return p1 + u
Exemplo n.º 49
0
def pca(M):
    "Perform PCA on M, return eigenvectors and eigenvalues, sorted."
    T, N = shape(M)
    # if there are fewer rows T than columns N, use snapshot method
    if T < N:
        C = dot(M, t(M))
        evals, evecsC = eigenvectors(C)
        # HACK: make sure evals are all positive
        evals = where(evals < 0, 0, evals)
        evecs = 1. / sqrt(evals) * dot(t(M), t(evecsC))
    else:
        # calculate covariance matrix
        K = 1. / T * dot(t(M), M)
        evals, evecs = eigenvectors(K)
    # sort the eigenvalues and eigenvectors, descending order
    order = (argsort(evals)[::-1])
    evecs = take(evecs, order, 1)
    evals = take(evals, order)
    return evals, t(evecs)
Exemplo n.º 50
0
def pi_vectors(
        bond,
        out=DFLT_OUT,
        up=DFLT_UP,
        abs_coords=False):  # rename -- pi_info for pi bond in degen sp chain
    # see also PiBondSpChain.get_pi_info
    """
    Given a bond involving some pi orbitals, return the 4-tuple ((a1py, a1pz), (a2py, a2pz), ord_pi_y, ord_pi_z),
    where a1py and a1pz are orthogonal vectors from atom1 giving the direction of its p orbitals for use in drawing
    this bond (for twisted bonds, the details of these might be determined more by graphic design issues than by the
    shapes of the real pi orbitals of the bond, though the goal is to approximate those);
    where a2py and a2pz are the same for atom2 (note that a2py might not be parallel to a1py for twisted bonds);
    and where ord_pi_y and ord_pi_z are order estimates (between 0.0 and 1.0 inclusive) for use in drawing the bond,
    for the pi_y and pi_z orbitals respectively. Note that the choice of how to name the two pi orbitals (pi_y, pi_z)
    is arbitrary and up to this function.
       All returned vectors are in the coordinate system of bond, unless abs_coords is true.
       This should not be called for pi bonds which are part of an "sp chain",
    but it should be equivalent to the code that would be used for a 1-bond sp-chain
    (i.e. it's an optimization of that code, PiBondSpChain.get_pi_info, for that case).
    """
    atom1 = bond.atom1
    atom2 = bond.atom2
    bond_axis = atom2.posn() - atom1.posn()  #k not always needed i think
    # following subrs should be renamed, since we routinely call them for sp atoms,
    # e.g. in -C#C- where outer bonds are not potential pi bonds
    pvec1 = p_vector_from_sp2_atom(atom1, bond, out=out,
                                   up=up)  # might be None
    pvec2 = p_vector_from_sp2_atom(
        atom2, bond, out=out,
        up=up)  # ideally, close to negative or positive of pvec1
    # handle one being None (use other one in place of it) or both being None (use arb vectors)
    if pvec1 is None:
        if pvec2 is None:
            # use arbitrary vectors perp to the bond; compute differently if bond_axis ~= out [###@@@ make this a subr? dup code?]
            pvec = cross(out, bond_axis)
            lenpvec = vlen(pvec)
            if lenpvec < 0.01:
                pvec = up
            else:
                pvec /= lenpvec
            pvec1 = pvec2 = pvec
        else:
            pvec1 = pvec2
    else:
        if pvec2 is None:
            pvec2 = pvec1
        else:
            # both vectors not None -- use them, but negate pvec2 if this makes them more aligned
            if dot(pvec1, pvec2) < 0:
                pvec2 = -pvec2
    return pi_info_from_abs_pvecs(bond,
                                  bond_axis,
                                  pvec1,
                                  pvec2,
                                  abs_coords=abs_coords)
Exemplo n.º 51
0
    def viewNormalTo(self): # 
        """
        Set view to the normal vector of the plane defined by 3 or more
        selected atoms or a jig's (Motor or RectGadget) axis.
        """
        cmd = greenmsg("Set View Normal To: ")

        chunks = self.assy.selmols
        jigs = self.assy.getSelectedJigs()
        atoms = self.assy.selatoms_list()

        #following fixes bug 1748 ninad 061003. 
        if len(chunks) > 0 and len(atoms) == 0:
            # Even though chunks have an axis, it is not necessarily the same
            # axis attr stored in the chunk.  Get the chunks atoms and let
            # compute_heuristic_axis() recompute them.
            for c in range(len(chunks)):
                atoms += chunks[c].atoms.values()
        elif len(jigs) == 1 and len(atoms) == 0:
            # Warning: RectGadgets have no atoms.  We handle this special case below.
            atoms = jigs[0].atoms 
        elif len(atoms) < 3:
            # There is a problem when allowing only 2 selected atoms. 
            # Changing requirement to 3 atoms fixes bug 1418. mark 060322
            msg = redmsg("Please select some atoms, jigs, and/or chunks, covering at least 3 atoms")
            print "ops_view.py len(atoms) = ", len(atoms)
            env.history.message(cmd + msg)
            return

        # This check is needed for jigs that have no atoms.  Currently, this 
        # is the case for RectGadgets (ESP Image and Grid Plane) only.
        if len(atoms):
            pos = A( map( lambda a: a.posn(), atoms ) )
            nears = [ self.glpane.out, self.glpane.up ]
            axis = compute_heuristic_axis( pos, 'normal', already_centered = False, nears = nears, dflt = None )
        else: # We have a jig with no atoms.
            axis = jigs[0].getaxis() # Get the jig's axis.
            # If axis is pointing into the screen, negate (reverse) axis.
            if dot(axis, self.glpane.lineOfSight) > 0:
                axis = -axis

        if not axis:
            msg = orangemsg( "Warning: Normal axis could not be determined. No change in view." )
            env.history.message(cmd + msg)
            return

        # Compute the destination quat (q2).
        q2 = Q(V(0,0,1), axis)
        q2 = q2.conj()

        self.glpane.rotateView(q2)

        info = 'View set to normal vector of the plane defined by the selected atoms.'
        env.history.message(cmd + info)
def best_vector_in_plane(axes, goodvecs, numeric_threshhold):
    """
    axes is a list of two orthonormal vectors defining a plane,
    and goodvecs is a list of unit vectors or (ignored) zero vectors or Nones;
    return whichever unit vector in the plane defined by axes is closest in direction
    to the first goodvec which helps determine this (i.e. which is not zero or None,
    and is not perpendicular to the plane, using numeric_threshhold to determine what's too
    close to call). If none of the goodvecs help, return None.
    """
    x, y = axes
    for good in goodvecs:
        if good is not None:
            dx = dot(
                x, good
            )  # will be 0 for good = V(0,0,0); not sensible for vlen(good) other than 0 or 1
            dy = dot(y, good)
            if abs(dx) < numeric_threshhold and abs(dy) < numeric_threshhold:
                continue  # good is perpendicular to the plane (or is zero)
            return norm(dx * x + dy * y)
    return None