Пример #1
0
 def findPositions(self):
     # First atom at origin
     self.coordinates[self.data[0][0]] = Vector(0,0,0)
     # Second atom along x-axis
     self.coordinates[self.data[1][0]] = Vector(self.data[1][2],0,0)
     # Third atom in xy-plane
     try:
         pos1 = self.coordinates[self.data[2][1]]
     except KeyError:
         raise ValueError("atom %d has no defined position"
                           % self.data[2][1].number)
     try:
         pos2 = self.coordinates[self.data[2][3]]
     except KeyError:
         raise ValueError("atom %d has no defined position"
                           % self.data[2][3].number)
     sphere = Sphere(pos1, self.data[2][2])
     cone = Cone(pos1, pos2-pos1, self.data[2][4])
     plane = Plane(Vector(0,0,0), Vector(0,0,1))
     points = sphere.intersectWith(cone).intersectWith(plane)
     self.coordinates[self.data[2][0]] = points[0]
     # All following atoms defined by distance + angle + dihedral
     for entry in self.data[3:]:
         try:
             pos1 = self.coordinates[entry[1]]
         except KeyError:
             raise ValueError("atom %d has no defined position"
                               % entry[1].number)
         try:
             pos2 = self.coordinates[entry[3]]
         except KeyError:
             raise ValueError("atom %d has no defined position"
                               % entry[3].number)
         try:
             pos3 = self.coordinates[entry[5]]
         except KeyError:
             raise ValueError("atom %d has no defined position"
                               % entry[5].number)
         distance = entry[2]
         angle = entry[4]
         dihedral = entry[6]
         sphere = Sphere(pos1, distance)
         cone = Cone(pos1, pos2-pos1, angle)
         plane123 = Plane(pos3, pos2, pos1)
         points = sphere.intersectWith(cone).intersectWith(plane123)
         for p in points:
             if Plane(pos2, pos1, p).normal * plane123.normal > 0:
                 break
         p = rotatePoint(p, Line(pos1, pos2-pos1), dihedral)
         self.coordinates[entry[0]] = p
Пример #2
0
 def findPositions(self):
     # First atom at origin
     self.coordinates[self.data[0][0]] = Vector(0, 0, 0)
     # Second atom along x-axis
     self.coordinates[self.data[1][0]] = Vector(self.data[1][2], 0, 0)
     # Third atom in xy-plane
     try:
         pos1 = self.coordinates[self.data[2][1]]
     except KeyError:
         raise ValueError("atom %d has no defined position" %
                          self.data[2][1].number)
     try:
         pos2 = self.coordinates[self.data[2][3]]
     except KeyError:
         raise ValueError("atom %d has no defined position" %
                          self.data[2][3].number)
     sphere = Sphere(pos1, self.data[2][2])
     cone = Cone(pos1, pos2 - pos1, self.data[2][4])
     plane = Plane(Vector(0, 0, 0), Vector(0, 0, 1))
     points = sphere.intersectWith(cone).intersectWith(plane)
     self.coordinates[self.data[2][0]] = points[0]
     # All following atoms defined by distance + angle + dihedral
     for entry in self.data[3:]:
         try:
             pos1 = self.coordinates[entry[1]]
         except KeyError:
             raise ValueError("atom %d has no defined position" %
                              entry[1].number)
         try:
             pos2 = self.coordinates[entry[3]]
         except KeyError:
             raise ValueError("atom %d has no defined position" %
                              entry[3].number)
         try:
             pos3 = self.coordinates[entry[5]]
         except KeyError:
             raise ValueError("atom %d has no defined position" %
                              entry[5].number)
         distance = entry[2]
         angle = entry[4]
         dihedral = entry[6]
         sphere = Sphere(pos1, distance)
         cone = Cone(pos1, pos2 - pos1, angle)
         plane123 = Plane(pos3, pos2, pos1)
         points = sphere.intersectWith(cone).intersectWith(plane123)
         for p in points:
             if Plane(pos2, pos1, p).normal * plane123.normal > 0:
                 break
         p = rotatePoint(p, Line(pos1, pos2 - pos1), dihedral)
         self.coordinates[entry[0]] = p
Пример #3
0
  def Cartesian(self, BAT):
    """
    Conversion from (internal or extended) Bond-Angle-Torsion 
    to Cartesian coordinates
    """
    # Arrange BAT coordinates in convenient arrays
    offset = 6 if len(BAT)==(3*self.molecule.numberOfAtoms()) else 0
    bonds = BAT[offset+3:self.ntorsions+offset+3]
    angles = BAT[self.ntorsions+offset+3:2*self.ntorsions+offset+3]
    phase_torsions = BAT[2*self.ntorsions+offset+3:]
    torsions = [(phase_torsions[n] + phase_torsions[self._firstTorsionInd[n]]) \
      if self._firstTorsionInd[n]!=n else phase_torsions[n] \
      for n in range(self.ntorsions)]
    
    # Determine the positions of the first three atoms
    p1 = Vector(0,0,0) # First atom at origin
    p2 = Vector(0,0,BAT[offset]) # Second atom along z-axis
    # Third atom in xz-plane
    sphere = Sphere(p2, BAT[offset+1])
    cone = Cone(p2, -p2, BAT[offset+2])
    plane = Plane(p1, Vector(0,1,0))
    p3 = sphere.intersectWith(cone).intersectWith(plane)[0]

    # If appropriate, rotate and translate the first three atoms
    if offset==6:
      p1 = np.array(p1)
      p2 = np.array(p2)
      p3 = np.array(p3)
      # Rotate the third atom by the appropriate value
      (phi,theta,omega) = BAT[3:6]
      co = np.cos(omega)
      so = np.sin(omega)
      Romega = np.array([[co, -so, 0],[so, co, 0], [0, 0, 1]])
      p3 = Romega.dot(p3)
      # Rotate the second two atoms to point in the right direction
      cp = np.cos(phi)
      sp = np.sin(phi)
      ct = np.cos(theta)
      st = np.sin(theta)
      Re = np.array([[cp*ct,-sp,cp*st],[ct*sp,cp,sp*st],[-st,0,ct]])
      p2 = Re.dot(p2)
      p3 = Re.dot(p3)
      # Translate the first three atoms by the origin
      origin = np.array(BAT[:3])
      p1 += origin
      p2 += origin
      p3 += origin
    
    self.root[0].setPosition(Vector(p1))
    self.root[1].setPosition(Vector(p2))
    self.root[2].setPosition(Vector(p3))

    # Add fourth and remaining atoms
    for ((a1,a2,a3,a4), bond, angle, torsion) in zip(self._torsionL,bonds,angles,torsions):
      sphere = Sphere(a2.position(), bond)
      cone = Cone(a2.position(), a3.position()-a2.position(), angle)
      plane123 = Plane(a4.position(), a3.position(), a2.position())
      points = sphere.intersectWith(cone).intersectWith(plane123)
      for p in points:
        if Plane(a3.position(), a2.position(), p).normal * plane123.normal > 0:
          break
      # The line points in the opposite direction to the ZMatrix constructor from
      # MMTK, but it seems to be correct
      p = rotatePoint(p, Line(a2.position(), a2.position()-a3.position()), torsion)
      a1.setPosition(p)
    
    return self.universe.configuration().array
Пример #4
0
  def Cartesian(self, BAT):
    """
    Conversion from (internal or extended) Bond-Angle-Torsion 
    to Cartesian coordinates
    """
    # Arrange BAT coordinates in convenient arrays
    offset = 6 if len(BAT)==(3*self.natoms) else 0
    bonds = BAT[offset+3::3]
    angles = BAT[offset+4::3]
    phase_torsions = BAT[offset+5::3]
    torsions = [(phase_torsions[n] + phase_torsions[self._firstTorsionTInd[n]]) \
      if self._firstTorsionTInd[n]!=n else phase_torsions[n] \
      for n in range(self.ntorsions)]
    
    p1 = np.array([0.,0.,0.])
    p2 = np.array([0.,0.,BAT[offset]])
    p3 = np.array([BAT[offset+1]*np.sin(BAT[offset+2]), 0., \
      BAT[offset]-BAT[offset+1]*np.cos(BAT[offset+2])])

    # If appropriate, rotate and translate the first three atoms
    if offset==6:
      # Rotate the third atom by the appropriate value
      (phi,theta,omega) = BAT[3:6]
      co = np.cos(omega)
      so = np.sin(omega)
      Romega = np.array([[co, -so, 0],[so, co, 0], [0, 0, 1]])
      p3 = Romega.dot(p3)
      # Rotate the second two atoms to point in the right direction
      cp = np.cos(phi)
      sp = np.sin(phi)
      ct = np.cos(theta)
      st = np.sin(theta)
      Re = np.array([[cp*ct,-sp,cp*st],[ct*sp,cp,sp*st],[-st,0,ct]])
      p2 = Re.dot(p2)
      p3 = Re.dot(p3)
      # Translate the first three atoms by the origin
      origin = np.array(BAT[:3])
      p1 += origin
      p2 += origin
      p3 += origin

    XYZ = np.zeros((self.natoms,3))
    
    XYZ[self.rootInd[0]] = p1
    XYZ[self.rootInd[1]] = p2
    XYZ[self.rootInd[2]] = p3

    for ((a1,a2,a3,a4), bond, angle, torsion) in \
        zip(self._torsionIndL,bonds,angles,torsions):
      sphere = Sphere(Vector(XYZ[a2]), bond)
      cone = Cone(Vector(XYZ[a2]), Vector(XYZ[a3]-XYZ[a2]), angle)
      plane123 = Plane(Vector(XYZ[a4]), Vector(XYZ[a3]), Vector(XYZ[a2]))
      points = sphere.intersectWith(cone).intersectWith(plane123)
      p = points[0] if (Plane(Vector(XYZ[a3]), Vector(XYZ[a2]), points[0]).normal*plane123.normal)>0 else points[1]
      p = rotatePoint(Vector(p), Line(Vector(XYZ[a2]), Vector(XYZ[a2]-XYZ[a3])), torsion)
      XYZ[a1] = p.array

    return XYZ

    for ((a1,a2,a3,a4), bond, angle, torsion) in \
        zip(self._torsionIndL,bonds,angles,torsions):

      p2 = XYZ[a2]
      p3 = XYZ[a3]
      p4 = XYZ[a4]

      # circle = sphere.intersectWith(cone)
      n23 = normalize(p3-p2)

      # points = circle.intersectWith(plane123)
      # plane.intersectWith(Plane(circle.center, circle.normal)) is a line
      # line_direction = cross(normalize(cross(p4-p3,n23)),n23)

      # Rotate the point about the p2-p3 axis by the torsion angle
      v21 = (bond*np.cos(angle))*n23 - (bond*np.sin(angle))*cross(normalize(cross(p4-p3,n23)),n23)
      s = np.sin(torsion)
      c = np.cos(torsion)
      XYZ[a1] = p2 - cross(n23,v21)*s + np.sum(n23*v21)*n23*(1.0-c) + v21*c
Пример #5
0
  def Cartesian(self, BAT):
    """
    Conversion from (internal or extended) Bond-Angle-Torsion 
    to Cartesian coordinates
    """
    # Arrange BAT coordinates in convenient arrays
    offset = 6 if len(BAT) == (3 * self.natoms) else 0
    bonds = BAT[offset + 3::3]
    angles = BAT[offset + 4::3]
    phase_torsions = BAT[offset + 5::3]
    torsions = [(phase_torsions[n] + phase_torsions[self._firstTorsionTInd[n]]) \
      if self._firstTorsionTInd[n]!=n else phase_torsions[n] \
      for n in range(self.ntorsions)]

    p1 = np.array([0., 0., 0.])
    p2 = np.array([0., 0., BAT[offset]])
    p3 = np.array([BAT[offset+1]*np.sin(BAT[offset+2]), 0., \
      BAT[offset]-BAT[offset+1]*np.cos(BAT[offset+2])])

    # If appropriate, rotate and translate the first three atoms
    if offset == 6:
      # Rotate the third atom by the appropriate value
      (phi, theta, omega) = BAT[3:6]
      co = np.cos(omega)
      so = np.sin(omega)
      Romega = np.array([[co, -so, 0], [so, co, 0], [0, 0, 1]])
      p3 = Romega.dot(p3)
      # Rotate the second two atoms to point in the right direction
      cp = np.cos(phi)
      sp = np.sin(phi)
      ct = np.cos(theta)
      st = np.sin(theta)
      Re = np.array([[cp * ct, -sp, cp * st], [ct * sp, cp, sp * st],
                     [-st, 0, ct]])
      p2 = Re.dot(p2)
      p3 = Re.dot(p3)
      # Translate the first three atoms by the origin
      origin = np.array(BAT[:3])
      p1 += origin
      p2 += origin
      p3 += origin

    XYZ = np.zeros((self.natoms, 3))

    XYZ[self.rootInd[0]] = p1
    XYZ[self.rootInd[1]] = p2
    XYZ[self.rootInd[2]] = p3

    for ((a1,a2,a3,a4), bond, angle, torsion) in \
        zip(self._torsionIndL,bonds,angles,torsions):
      sphere = Sphere(Vector(XYZ[a2]), bond)
      cone = Cone(Vector(XYZ[a2]), Vector(XYZ[a3] - XYZ[a2]), angle)
      plane123 = Plane(Vector(XYZ[a4]), Vector(XYZ[a3]), Vector(XYZ[a2]))
      points = sphere.intersectWith(cone).intersectWith(plane123)
      p = points[0] if (Plane(Vector(XYZ[a3]), Vector(
        XYZ[a2]), points[0]).normal * plane123.normal) > 0 else points[1]
      p = rotatePoint(Vector(p),
                      Line(Vector(XYZ[a2]), Vector(XYZ[a2] - XYZ[a3])),
                      torsion)
      XYZ[a1] = p.array

    return XYZ

    for ((a1,a2,a3,a4), bond, angle, torsion) in \
        zip(self._torsionIndL,bonds,angles,torsions):

      p2 = XYZ[a2]
      p3 = XYZ[a3]
      p4 = XYZ[a4]

      # circle = sphere.intersectWith(cone)
      n23 = normalize(p3 - p2)

      # points = circle.intersectWith(plane123)
      # plane.intersectWith(Plane(circle.center, circle.normal)) is a line
      # line_direction = cross(normalize(cross(p4-p3,n23)),n23)

      # Rotate the point about the p2-p3 axis by the torsion angle
      v21 = (bond * np.cos(angle)) * n23 - (bond * np.sin(angle)) * cross(
        normalize(cross(p4 - p3, n23)), n23)
      s = np.sin(torsion)
      c = np.cos(torsion)
      XYZ[a1] = p2 - cross(n23, v21) * s + np.sum(
        n23 * v21) * n23 * (1.0 - c) + v21 * c
Пример #6
0
    def Cartesian(self, BAT):
        """
    Conversion from (internal or extended) Bond-Angle-Torsion 
    to Cartesian coordinates
    """
        # Arrange BAT coordinates in convenient arrays
        offset = 6 if len(BAT) == (3 * self.molecule.numberOfAtoms()) else 0
        bonds = BAT[offset + 3:self.ntorsions + offset + 3]
        angles = BAT[self.ntorsions + offset + 3:2 * self.ntorsions + offset +
                     3]
        phase_torsions = BAT[2 * self.ntorsions + offset + 3:]
        torsions = [(phase_torsions[n] + phase_torsions[self._firstTorsionInd[n]]) \
          if self._firstTorsionInd[n]!=n else phase_torsions[n] \
          for n in range(self.ntorsions)]

        # Determine the positions of the first three atoms
        p1 = Vector(0, 0, 0)  # First atom at origin
        p2 = Vector(0, 0, BAT[offset])  # Second atom along z-axis
        # Third atom in xz-plane
        sphere = Sphere(p2, BAT[offset + 1])
        cone = Cone(p2, -p2, BAT[offset + 2])
        plane = Plane(p1, Vector(0, 1, 0))
        p3 = sphere.intersectWith(cone).intersectWith(plane)[0]

        # If appropriate, rotate and translate the first three atoms
        if offset == 6:
            p1 = np.array(p1)
            p2 = np.array(p2)
            p3 = np.array(p3)
            # Rotate the third atom by the appropriate value
            (phi, theta, omega) = BAT[3:6]
            co = np.cos(omega)
            so = np.sin(omega)
            Romega = np.array([[co, -so, 0], [so, co, 0], [0, 0, 1]])
            p3 = Romega.dot(p3)
            # Rotate the second two atoms to point in the right direction
            cp = np.cos(phi)
            sp = np.sin(phi)
            ct = np.cos(theta)
            st = np.sin(theta)
            Re = np.array([[cp * ct, -sp, cp * st], [ct * sp, cp, sp * st],
                           [-st, 0, ct]])
            p2 = Re.dot(p2)
            p3 = Re.dot(p3)
            # Translate the first three atoms by the origin
            origin = np.array(BAT[:3])
            p1 += origin
            p2 += origin
            p3 += origin

        self.root[0].setPosition(Vector(p1))
        self.root[1].setPosition(Vector(p2))
        self.root[2].setPosition(Vector(p3))

        # Add fourth and remaining atoms
        for ((a1, a2, a3, a4), bond, angle,
             torsion) in zip(self._torsionL, bonds, angles, torsions):
            sphere = Sphere(a2.position(), bond)
            cone = Cone(a2.position(), a3.position() - a2.position(), angle)
            plane123 = Plane(a4.position(), a3.position(), a2.position())
            points = sphere.intersectWith(cone).intersectWith(plane123)
            for p in points:
                if Plane(a3.position(), a2.position(),
                         p).normal * plane123.normal > 0:
                    break
            # The line points in the opposite direction to the ZMatrix constructor from
            # MMTK, but it seems to be correct
            p = rotatePoint(p,
                            Line(a2.position(),
                                 a2.position() - a3.position()), torsion)
            a1.setPosition(p)