Esempio n. 1
0
    def build_struct(self, name, params, position, mol=None, createPrinted=False):
        """
        Build a peptide from a sequence entered through the Property Manager dialog.
        """

        if len(self.peptide_cache) == 0:
            return None

        # Create a molecule
        mol = Chunk(self.win.assy,name)

        # Generate dummy atoms positions

        self.prev_coords[0][0] = position[0] - 1.499
        self.prev_coords[0][1] = position[1] + 1.539
        self.prev_coords[0][2] = position[2]

        self.prev_coords[1][0] = position[0] - 1.499
        self.prev_coords[1][1] = position[1]
        self.prev_coords[1][2] = position[2]

        self.prev_coords[2][0] = position[0]
        self.prev_coords[2][1] = position[1]
        self.prev_coords[2][2] = position[2]

        # Add a N-terminal hydrogen
        atom = Atom("H", position, mol)
        atom._is_aromatic = False
        atom._is_single = False
        self.nterm_hydrogen = atom

        # Generate the peptide chain.
        self.length = 1
        for index, phi, psi in self.peptide_cache:
            name, short_name, symbol, zmatrix, size = AMINO_ACIDS[index]
            self._buildResiduum(mol, zmatrix, size, phi, psi, None, symbol)

        # Add a C-terminal OH group
        self._buildResiduum(mol, CTERM_ZMATRIX, 5, 0.0, 0.0, None, symbol)        
        
        # Compute bonds (slow!)
        # This should be replaced by a proper bond assignment.
        inferBonds(mol)

        mol._protein_helix = []
        mol._protein_sheet = []
        
        # Assign proper bond orders.
        i = 1
        for atom in mol.atoms.itervalues():
            if self.ss_idx == 1:
                mol._protein_helix.append(i) 
            elif self.ss_idx == 2:
                mol._protein_sheet.append(i)  
            if atom.bonds:
                for bond in atom.bonds:
                    if bond.atom1.getAtomTypeName()=="sp2" and \
                       bond.atom2.getAtomTypeName()=="sp2":
                        if (bond.atom1._is_aromatic and
                            bond.atom2._is_aromatic):
                            bond.set_v6(V_AROMATIC)
                        elif ((bond.atom1._is_aromatic == False and
                               bond.atom1._is_aromatic == False) and
                               not (bond.atom1._is_single and
                                    bond.atom2._is_single)):
                            bond.set_v6(V_DOUBLE)
            i += 1
                            
        # Remove temporary attributes.
        for atom in mol.atoms.itervalues():
            del atom._is_aromatic
            del atom._is_single

        return mol
Esempio n. 2
0
    def _buildResiduum(self, mol, zmatrix, n_atoms, phi, psi, init_pos, symbol):
        """
        Builds cartesian coordinates for an amino acid from the internal
        coordinates table.

        mol is a chunk to which the amino acid will be added.

        zmatrix is an internal coordinates array corresponding to a given amino acid.
        n_atoms is a number of atoms to be build + 3 dummy atoms.

        phi is a peptide bond PHI angle.
        psi is a peptide bond PSI angle.

        init_pos are optional postions of previous CA, C and O atoms.

        symbol is a current amino acid symbol (used for proline case)

        Note: currently, it doesn't rebuild bonds, so inferBonds has to be called after.
        Unfortunately, the proper bond order can not be correctly recognized this way.
        """

        if mol == None:
            return

        if not init_pos: # assign three previous atom positions
            for i in range (0,3):
                self.coords[i][0] = self.prev_coords[i][0]
                self.coords[i][1] = self.prev_coords[i][1]
                self.coords[i][2] = self.prev_coords[i][2]
        else: # if no prev_coords are given, compute the first three atom positions
            num, name, atom_name, atom_type, \
               atom_c, atom_b, atom_a, r, a, t = zmatrix[1]
            self.coords[0][0] = 0.0;
            self.coords[0][1] = 0.0;
            self.coords[0][2] = 0.0;
            self.coords[1][0] = r;
            self.coords[1][1] = 0.0;
            self.coords[1][2] = 0.0;
            ccos = cos(DEG2RAD*a)
            num, name, atom_name, atom_type, \
               atom_c, atom_b, atom_a, r, a, t = zmatrix[2]
            if atom_c == 1:
                self.coords[2][0] = self.coords[0][0] + r*ccos
            else:
                self.coords[2][0] = self.coords[0][0] - r*ccos
            self.coords[2][1] = r * sin(DEG2RAD*a)
            self.coords[2][2] = 0.0
            for i in range (0, 3):
                self.prev_coords[i][0] = self.coords[i][0] + init_pos[0]
                self.prev_coords[i][1] = self.coords[i][1] + init_pos[1]
                self.prev_coords[i][2] = self.coords[i][2] + init_pos[2]

        for n in range (3, n_atoms):
            # Generate all coordinates using three previous atoms
            # as a frame of reference,
            num, name, atom_name, atom_type, \
               atom_c, atom_b, atom_a, r, a, t = zmatrix[n]

            cosa = cos(DEG2RAD * a)
            xb = self.coords[atom_b][0] - self.coords[atom_c][0]
            yb = self.coords[atom_b][1] - self.coords[atom_c][1]
            zb = self.coords[atom_b][2] - self.coords[atom_c][2]
            rbc = 1.0 / sqrt(xb*xb + yb*yb + zb*zb)

            if abs(cosa) >= 0.999:
                # Linear bond case
                # Skip angles, just extend along the bond.
                rbc = r * rbc * cosa
                self.coords[n][0] = self.coords[atom_c][0] + xb*rbc
                self.coords[n][1] = self.coords[atom_c][1] + yb*rbc
                self.coords[n][2] = self.coords[atom_c][2] + zb*rbc
            else:
                xa = self.coords[atom_a][0] - self.coords[atom_c][0]
                ya = self.coords[atom_a][1] - self.coords[atom_c][1]
                za = self.coords[atom_a][2] - self.coords[atom_c][2]

                xyb = sqrt(xb*xb + yb*yb)

                inv = False
                if xyb < 0.001:
                    xpa = za
                    za = -xa
                    xa = xpa
                    xpb = zb
                    zb = -xb
                    xb = xpb
                    xyb = sqrt(xb*xb + yb*yb)
                    inv = True

                costh = xb / xyb
                sinth = yb / xyb
                xpa = xa * costh + ya * sinth
                ypa = ya * costh - xa * sinth
                sinph = zb * rbc
                cosph = sqrt(abs(1.0- sinph * sinph))
                xqa = xpa * cosph + za * sinph
                zqa = za * cosph - xpa * sinph
                yza = sqrt(ypa * ypa + zqa * zqa)
                if yza < 1e-8:
                    coskh = 1.0
                    sinkh = 0.0
                else:
                    coskh = ypa / yza
                    sinkh = zqa / yza

                # Apply the peptide bond conformation
                if symbol != "P":
                    if name == "N  " and not init_pos:
                        t = self.prev_psi + 0.0
                    if name == "O  ":
                        t = psi + 180.0
                    if name == "HA " or name == "HA2":
                        t = 120.0 + phi
                    if name == "CB " or name == "HA3":
                        t = 240.0 + phi
                    if name == "C  ":
                        t = phi
                else:
                    # proline
                    if name == "N  " and not init_pos:
                        t = self.prev_psi + 0.0
                    if name == "O  ":
                        t = psi + 180.0
                    if name == "CA ":
                        t = phi - 120.0
                    if name == "CD ":
                        t = phi + 60.0

                sina = sin(DEG2RAD * a)
                sind = -sin(DEG2RAD * t)
                cosd = cos(DEG2RAD * t)

                # Apply the bond length.
                xd = r * cosa
                yd = r * sina * cosd
                zd = r * sina * sind

                # Compute the atom position using bond and torsional angles.
                ypd = yd * coskh - zd * sinkh
                zpd = zd * coskh + yd * sinkh
                xpd = xd * cosph - zpd * sinph
                zqd = zpd * cosph + xd * sinph
                xqd = xpd * costh - ypd * sinth
                yqd = ypd * costh + xpd * sinth

                if inv:
                    tmp = -zqd
                    zqd = xqd
                    xqd = tmp

                self.coords[n][0] = xqd + self.coords[atom_c][0]
                self.coords[n][1] = yqd + self.coords[atom_c][1]
                self.coords[n][2] = zqd + self.coords[atom_c][2]

                if self.nterm_hydrogen:
                    # It is a hack for the first hydrogen atom
                    # to make sure the bond length is correct.
                    self.nterm_hydrogen.setposn(
                        self.nterm_hydrogen.posn() + 0.325 * norm(V(xqd, yqd, zqd)))
                    self.nterm_hydrogen = None

                ax = self.coords[n][0]
                ay = self.coords[n][1]
                az = self.coords[n][2]

                # Store previous coordinates for the next building step
                if not init_pos:
                    if name=="N  ":
                        self.prev_coords[0][0] = self.coords[n][0]
                        self.prev_coords[0][1] = self.coords[n][1]
                        self.prev_coords[0][2] = self.coords[n][2]
                    if name=="CA ":
                        self.prev_coords[1][0] = self.coords[n][0]
                        self.prev_coords[1][1] = self.coords[n][1]
                        self.prev_coords[1][2] = self.coords[n][2]
                    if name=="C  ":
                        self.prev_coords[2][0] = self.coords[n][0]
                        self.prev_coords[2][1] = self.coords[n][1]
                        self.prev_coords[2][2] = self.coords[n][2]

                # Add a new atom to the molecule
                atom = Atom(
                    atom_name,
                    V(self.coords[n][0], self.coords[n][1], self.coords[n][2]),
                    mol)

                # Create temporary attributes for proper bond assignment.
                atom._is_aromatic = False
                atom._is_single = False

                if atom_type == "sp2a":
                    atom_type = "sp2"
                    atom._is_aromatic = True

                if atom_type == "sp2s":
                    atom_type = "sp2"
                    atom._is_single = True

                atom.set_atomtype_but_dont_revise_singlets(atom_type)

                if name == "CA ":
                    # Set c-alpha flag for protein main chain visualization.
                    atom._protein_ca = True
                else:
                    atom._protein_ca = False

                if name == "CB ":
                    # Set c-alpha flag for protein main chain visualization.
                    atom._protein_cb = True
                else:
                    atom._protein_cb = False

                if name == "N  ": 
                    # Set c-alpha flag for protein main chain visualization.
                    atom._protein_n = True
                else:
                    atom._protein_n = False

                if name == "C  ": 
                    # Set c-alpha flag for protein main chain visualization.
                    atom._protein_c = True
                else:
                    atom._protein_c = False

                if name == "O  ": 
                    # Set c-alpha flag for protein main chain visualization.
                    atom._protein_o = True
                else:
                    atom._protein_o = False

                # debug - output in PDB format	
                # print "ATOM  %5d  %-3s %3s %c%4d    %8.3f%8.3f%8.3f" % ( n, name, "ALA", ' ', res_num, coords[n][0], coords[n][1], coords[n][2])	

        self.prev_psi = psi # Remember previous psi angle.

        self.length += 1 # Increase the amino acid counter.

        return
    def _buildResidue(self, mol, zmatrix, n_atoms, idx, phi, psi, secondary, init_pos, residue_name, fake_chain=False):
        """
        Builds cartesian coordinates for an amino acid from the internal
        coordinates table.

        @param mol: a chunk to which the amino acid will be added.
        @type mol: Chunk

        @param zmatrix: is an internal coordinates array corresponding to a
        given amino acid.
        @type zmatrix: list

        @param n_atoms: size of z-matrix (a number of atoms to be build + 3
        dummy atoms)
        @type n_atoms: int

        @param idx: is a residue index (1..length).
        @type idx: integer

        @param phi, psi: peptide bond phi and psi angles
        @type phi, psi: float

        @param init_pos: optional postions of previous CA, C and O atoms.
        @type init_pos: V

        @param symbol: current amino acid symbol (used to derermine proline case)
        @type symbol: string

        """

        # note: currently, it doesn't rebuild bonds, so inferBonds has to be
        # called after this method. Unfortunately, the proper bond order can
        # not be correctly recognized this way. Therefore, temporary atom flags
        # _is_aromatic and _is_single are used.

        #this code was re-factored by EricM and internal-to-cartesian
        # conversion method was moved to geometry.InternalCoordinatesToCartesian

        if mol is None:
            return

        if not init_pos: # assign three previous atom positions
            coords = self.prev_coords
        else:
            # if no prev_coords are given, compute the first three atom positions
            coords = zeros([3,3], Float)
            num, name, atom_name, atom_type, \
               atom_c, atom_b, atom_a, r, a, t = zmatrix[1]
            coords[0][0] = 0.0;
            coords[0][1] = 0.0;
            coords[0][2] = 0.0;
            coords[1][0] = r;
            coords[1][1] = 0.0;
            coords[1][2] = 0.0;
            ccos = cos(DEG2RAD*a)
            num, name, atom_name, atom_type, \
               atom_c, atom_b, atom_a, r, a, t = zmatrix[2]
            if atom_c == 1:
                coords[2][0] = coords[0][0] + r*ccos
            else:
                coords[2][0] = coords[0][0] - r*ccos
            coords[2][1] = r * sin(DEG2RAD*a)
            coords[2][2] = 0.0
            for i in range (0, 3):
                self.prev_coords[i][0] = coords[i][0] + init_pos[0]
                self.prev_coords[i][1] = coords[i][1] + init_pos[1]
                self.prev_coords[i][2] = coords[i][2] + init_pos[2]

        translator = InternalCoordinatesToCartesian(n_atoms, coords)

        for n in range (3, n_atoms):
            # Generate all coordinates using three previous atoms
            # as a frame of reference,
            num, name, atom_name, atom_type, \
               atom_c, atom_b, atom_a, r, a, t = zmatrix[n]

            # Apply the peptide bond conformation
            if residue_name != "PRO":
                if name == "N  " and not init_pos:
                    t = self.prev_psi + 0.0
                if name == "O  ":
                    t = psi + 180.0
                if name == "HA " or name == "HA2":
                    t = 120.0 + phi
                if name == "CB " or name == "HA3":
                    t = 240.0 + phi
                if name == "C  ":
                    t = phi
            else:
                # proline
                if name == "N  " and not init_pos:
                    t = self.prev_psi + 0.0
                if name == "O  ":
                    t = psi + 180.0
                if name == "CA ":
                    t = phi - 120.0
                if name == "CD ":
                    t = phi + 60.0

            translator.addInternal(n+1, atom_c+1, atom_b+1, atom_a+1, r, a, t)
            xyz = translator.getCartesian(n+1)

            if self.nterm_hydrogen:
                # This is a hack for the first hydrogen atom
                # to make sure the bond length is correct.
                self.nterm_hydrogen.setposn(
                    self.nterm_hydrogen.posn() + \
                    0.325 * norm(xyz))
                self.nterm_hydrogen = None

            # Store previous coordinates for the next building step
            if not init_pos:
                if name=="N  ":
                    self.prev_coords[0][0] = xyz[0]
                    self.prev_coords[0][1] = xyz[1]
                    self.prev_coords[0][2] = xyz[2]
                if name=="CA ":
                    self.prev_coords[1][0] = xyz[0]
                    self.prev_coords[1][1] = xyz[1]
                    self.prev_coords[1][2] = xyz[2]
                if name=="C  ":
                    self.prev_coords[2][0] = xyz[0]
                    self.prev_coords[2][1] = xyz[1]
                    self.prev_coords[2][2] = xyz[2]

            # Add a new atom to the molecule
            if not fake_chain or \
               name == "CA ":
                atom = Atom(
                    atom_name,
                    xyz,
                    mol)

                if not self.init_ca and \
                   name == "CA ":
                    self.init_ca = atom

                if mol.protein:
                    aa = mol.protein.add_pdb_atom(atom,
                                             name.replace(' ',''),
                                             idx,
                                             AA_3_TO_1[residue_name])
                    atom.pdb_info = {}
                    atom.pdb_info['atom_name'] = name.replace(' ','')
                    atom.pdb_info['residue_name'] = residue_name
                    residue_id = "%3d " % idx
                    atom.pdb_info['residue_id'] = residue_id
                    atom.pdb_info['standard_atom'] = True
                    atom.pdb_info['chain_id'] = True
                    if aa:
                        aa.set_secondary_structure(secondary)

                # Create temporary attributes for proper bond assignment.
                atom._is_aromatic = False
                atom._is_single = False

                if atom_type == "sp2a":
                    atom_type = "sp2"
                    atom._is_aromatic = True

                if atom_type == "sp2s":
                    atom_type = "sp2"
                    atom._is_single = True

                atom.set_atomtype_but_dont_revise_singlets(atom_type)

                ### debug - output in PDB format
                ### print "ATOM  %5d  %-3s %3s %c%4d    %8.3f%8.3f%8.3f" % ( n, name, "ALA", ' ', res_num, xyz[0], xyz[1], xyz[2])

        self.prev_psi = psi # Remember previous psi angle.

        return
    def build_struct(self,
                     name,
                     params,
                     position,
                     mol=None,
                     createPrinted=False):
        """
        Build a peptide from a sequence entered through the Property Manager dialog.
        """

        if len(self.peptide_cache) == 0:
            return None

        # Create a molecule
        mol = Chunk(self.win.assy, name)

        # Generate dummy atoms positions

        self.prev_coords[0][0] = position[0] - 1.499
        self.prev_coords[0][1] = position[1] + 1.539
        self.prev_coords[0][2] = position[2]

        self.prev_coords[1][0] = position[0] - 1.499
        self.prev_coords[1][1] = position[1]
        self.prev_coords[1][2] = position[2]

        self.prev_coords[2][0] = position[0]
        self.prev_coords[2][1] = position[1]
        self.prev_coords[2][2] = position[2]

        # Add a N-terminal hydrogen
        atom = Atom("H", position, mol)
        atom._is_aromatic = False
        atom._is_single = False
        self.nterm_hydrogen = atom

        # Generate the peptide chain.
        self.length = 1
        for index, phi, psi in self.peptide_cache:
            name, short_name, symbol, zmatrix, size = AMINO_ACIDS[index]
            self._buildResiduum(mol, zmatrix, size, phi, psi, None, symbol)

        # Add a C-terminal OH group
        self._buildResiduum(mol, CTERM_ZMATRIX, 5, 0.0, 0.0, None, symbol)

        # Compute bonds (slow!)
        # This should be replaced by a proper bond assignment.
        inferBonds(mol)

        mol._protein_helix = []
        mol._protein_sheet = []

        # Assign proper bond orders.
        i = 1
        for atom in mol.atoms.itervalues():
            if self.ss_idx == 1:
                mol._protein_helix.append(i)
            elif self.ss_idx == 2:
                mol._protein_sheet.append(i)
            if atom.bonds:
                for bond in atom.bonds:
                    if bond.atom1.getAtomTypeName()=="sp2" and \
                       bond.atom2.getAtomTypeName()=="sp2":
                        if (bond.atom1._is_aromatic
                                and bond.atom2._is_aromatic):
                            bond.set_v6(V_AROMATIC)
                        elif ((bond.atom1._is_aromatic == False
                               and bond.atom1._is_aromatic == False)
                              and not (bond.atom1._is_single
                                       and bond.atom2._is_single)):
                            bond.set_v6(V_DOUBLE)
            i += 1

        # Remove temporary attributes.
        for atom in mol.atoms.itervalues():
            del atom._is_aromatic
            del atom._is_single

        return mol
    def _buildResiduum(self, mol, zmatrix, n_atoms, phi, psi, init_pos,
                       symbol):
        """
        Builds cartesian coordinates for an amino acid from the internal
        coordinates table.

        mol is a chunk to which the amino acid will be added.

        zmatrix is an internal coordinates array corresponding to a given amino acid.
        n_atoms is a number of atoms to be build + 3 dummy atoms.

        phi is a peptide bond PHI angle.
        psi is a peptide bond PSI angle.

        init_pos are optional postions of previous CA, C and O atoms.

        symbol is a current amino acid symbol (used for proline case)

        Note: currently, it doesn't rebuild bonds, so inferBonds has to be called after.
        Unfortunately, the proper bond order can not be correctly recognized this way.
        """

        if mol == None:
            return

        if not init_pos:  # assign three previous atom positions
            for i in range(0, 3):
                self.coords[i][0] = self.prev_coords[i][0]
                self.coords[i][1] = self.prev_coords[i][1]
                self.coords[i][2] = self.prev_coords[i][2]
        else:  # if no prev_coords are given, compute the first three atom positions
            num, name, atom_name, atom_type, \
               atom_c, atom_b, atom_a, r, a, t = zmatrix[1]
            self.coords[0][0] = 0.0
            self.coords[0][1] = 0.0
            self.coords[0][2] = 0.0
            self.coords[1][0] = r
            self.coords[1][1] = 0.0
            self.coords[1][2] = 0.0
            ccos = cos(DEG2RAD * a)
            num, name, atom_name, atom_type, \
               atom_c, atom_b, atom_a, r, a, t = zmatrix[2]
            if atom_c == 1:
                self.coords[2][0] = self.coords[0][0] + r * ccos
            else:
                self.coords[2][0] = self.coords[0][0] - r * ccos
            self.coords[2][1] = r * sin(DEG2RAD * a)
            self.coords[2][2] = 0.0
            for i in range(0, 3):
                self.prev_coords[i][0] = self.coords[i][0] + init_pos[0]
                self.prev_coords[i][1] = self.coords[i][1] + init_pos[1]
                self.prev_coords[i][2] = self.coords[i][2] + init_pos[2]

        for n in range(3, n_atoms):
            # Generate all coordinates using three previous atoms
            # as a frame of reference,
            num, name, atom_name, atom_type, \
               atom_c, atom_b, atom_a, r, a, t = zmatrix[n]

            cosa = cos(DEG2RAD * a)
            xb = self.coords[atom_b][0] - self.coords[atom_c][0]
            yb = self.coords[atom_b][1] - self.coords[atom_c][1]
            zb = self.coords[atom_b][2] - self.coords[atom_c][2]
            rbc = 1.0 / sqrt(xb * xb + yb * yb + zb * zb)

            if abs(cosa) >= 0.999:
                # Linear bond case
                # Skip angles, just extend along the bond.
                rbc = r * rbc * cosa
                self.coords[n][0] = self.coords[atom_c][0] + xb * rbc
                self.coords[n][1] = self.coords[atom_c][1] + yb * rbc
                self.coords[n][2] = self.coords[atom_c][2] + zb * rbc
            else:
                xa = self.coords[atom_a][0] - self.coords[atom_c][0]
                ya = self.coords[atom_a][1] - self.coords[atom_c][1]
                za = self.coords[atom_a][2] - self.coords[atom_c][2]

                xyb = sqrt(xb * xb + yb * yb)

                inv = False
                if xyb < 0.001:
                    xpa = za
                    za = -xa
                    xa = xpa
                    xpb = zb
                    zb = -xb
                    xb = xpb
                    xyb = sqrt(xb * xb + yb * yb)
                    inv = True

                costh = xb / xyb
                sinth = yb / xyb
                xpa = xa * costh + ya * sinth
                ypa = ya * costh - xa * sinth
                sinph = zb * rbc
                cosph = sqrt(abs(1.0 - sinph * sinph))
                xqa = xpa * cosph + za * sinph
                zqa = za * cosph - xpa * sinph
                yza = sqrt(ypa * ypa + zqa * zqa)
                if yza < 1e-8:
                    coskh = 1.0
                    sinkh = 0.0
                else:
                    coskh = ypa / yza
                    sinkh = zqa / yza

                # Apply the peptide bond conformation
                if symbol != "P":
                    if name == "N  " and not init_pos:
                        t = self.prev_psi + 0.0
                    if name == "O  ":
                        t = psi + 180.0
                    if name == "HA " or name == "HA2":
                        t = 120.0 + phi
                    if name == "CB " or name == "HA3":
                        t = 240.0 + phi
                    if name == "C  ":
                        t = phi
                else:
                    # proline
                    if name == "N  " and not init_pos:
                        t = self.prev_psi + 0.0
                    if name == "O  ":
                        t = psi + 180.0
                    if name == "CA ":
                        t = phi - 120.0
                    if name == "CD ":
                        t = phi + 60.0

                sina = sin(DEG2RAD * a)
                sind = -sin(DEG2RAD * t)
                cosd = cos(DEG2RAD * t)

                # Apply the bond length.
                xd = r * cosa
                yd = r * sina * cosd
                zd = r * sina * sind

                # Compute the atom position using bond and torsional angles.
                ypd = yd * coskh - zd * sinkh
                zpd = zd * coskh + yd * sinkh
                xpd = xd * cosph - zpd * sinph
                zqd = zpd * cosph + xd * sinph
                xqd = xpd * costh - ypd * sinth
                yqd = ypd * costh + xpd * sinth

                if inv:
                    tmp = -zqd
                    zqd = xqd
                    xqd = tmp

                self.coords[n][0] = xqd + self.coords[atom_c][0]
                self.coords[n][1] = yqd + self.coords[atom_c][1]
                self.coords[n][2] = zqd + self.coords[atom_c][2]

                if self.nterm_hydrogen:
                    # It is a hack for the first hydrogen atom
                    # to make sure the bond length is correct.
                    self.nterm_hydrogen.setposn(self.nterm_hydrogen.posn() +
                                                0.325 * norm(V(xqd, yqd, zqd)))
                    self.nterm_hydrogen = None

                ax = self.coords[n][0]
                ay = self.coords[n][1]
                az = self.coords[n][2]

                # Store previous coordinates for the next building step
                if not init_pos:
                    if name == "N  ":
                        self.prev_coords[0][0] = self.coords[n][0]
                        self.prev_coords[0][1] = self.coords[n][1]
                        self.prev_coords[0][2] = self.coords[n][2]
                    if name == "CA ":
                        self.prev_coords[1][0] = self.coords[n][0]
                        self.prev_coords[1][1] = self.coords[n][1]
                        self.prev_coords[1][2] = self.coords[n][2]
                    if name == "C  ":
                        self.prev_coords[2][0] = self.coords[n][0]
                        self.prev_coords[2][1] = self.coords[n][1]
                        self.prev_coords[2][2] = self.coords[n][2]

                # Add a new atom to the molecule
                atom = Atom(
                    atom_name,
                    V(self.coords[n][0], self.coords[n][1], self.coords[n][2]),
                    mol)

                # Create temporary attributes for proper bond assignment.
                atom._is_aromatic = False
                atom._is_single = False

                if atom_type == "sp2a":
                    atom_type = "sp2"
                    atom._is_aromatic = True

                if atom_type == "sp2s":
                    atom_type = "sp2"
                    atom._is_single = True

                atom.set_atomtype_but_dont_revise_singlets(atom_type)

                if name == "CA ":
                    # Set c-alpha flag for protein main chain visualization.
                    atom._protein_ca = True
                else:
                    atom._protein_ca = False

                if name == "CB ":
                    # Set c-alpha flag for protein main chain visualization.
                    atom._protein_cb = True
                else:
                    atom._protein_cb = False

                if name == "N  ":
                    # Set c-alpha flag for protein main chain visualization.
                    atom._protein_n = True
                else:
                    atom._protein_n = False

                if name == "C  ":
                    # Set c-alpha flag for protein main chain visualization.
                    atom._protein_c = True
                else:
                    atom._protein_c = False

                if name == "O  ":
                    # Set c-alpha flag for protein main chain visualization.
                    atom._protein_o = True
                else:
                    atom._protein_o = False

                # debug - output in PDB format
                # print "ATOM  %5d  %-3s %3s %c%4d    %8.3f%8.3f%8.3f" % ( n, name, "ALA", ' ', res_num, coords[n][0], coords[n][1], coords[n][2])

        self.prev_psi = psi  # Remember previous psi angle.

        self.length += 1  # Increase the amino acid counter.

        return
Esempio n. 6
0
    def _buildResidue(self,
                      mol,
                      zmatrix,
                      n_atoms,
                      idx,
                      phi,
                      psi,
                      secondary,
                      init_pos,
                      residue_name,
                      fake_chain=False):
        """
        Builds cartesian coordinates for an amino acid from the internal
        coordinates table.

        @param mol: a chunk to which the amino acid will be added.
        @type mol: Chunk

        @param zmatrix: is an internal coordinates array corresponding to a
        given amino acid.
        @type zmatrix: list

        @param n_atoms: size of z-matrix (a number of atoms to be build + 3
        dummy atoms)
        @type n_atoms: int

        @param idx: is a residue index (1..length).
        @type idx: integer

        @param phi, psi: peptide bond phi and psi angles
        @type phi, psi: float

        @param init_pos: optional postions of previous CA, C and O atoms.
        @type init_pos: V

        @param symbol: current amino acid symbol (used to derermine proline case)
        @type symbol: string

        """

        # note: currently, it doesn't rebuild bonds, so inferBonds has to be
        # called after this method. Unfortunately, the proper bond order can
        # not be correctly recognized this way. Therefore, temporary atom flags
        # _is_aromatic and _is_single are used.

        #this code was re-factored by EricM and internal-to-cartesian
        # conversion method was moved to geometry.InternalCoordinatesToCartesian

        if mol is None:
            return

        if not init_pos:  # assign three previous atom positions
            coords = self.prev_coords
        else:
            # if no prev_coords are given, compute the first three atom positions
            coords = zeros([3, 3], Float)
            num, name, atom_name, atom_type, \
               atom_c, atom_b, atom_a, r, a, t = zmatrix[1]
            coords[0][0] = 0.0
            coords[0][1] = 0.0
            coords[0][2] = 0.0
            coords[1][0] = r
            coords[1][1] = 0.0
            coords[1][2] = 0.0
            ccos = cos(DEG2RAD * a)
            num, name, atom_name, atom_type, \
               atom_c, atom_b, atom_a, r, a, t = zmatrix[2]
            if atom_c == 1:
                coords[2][0] = coords[0][0] + r * ccos
            else:
                coords[2][0] = coords[0][0] - r * ccos
            coords[2][1] = r * sin(DEG2RAD * a)
            coords[2][2] = 0.0
            for i in range(0, 3):
                self.prev_coords[i][0] = coords[i][0] + init_pos[0]
                self.prev_coords[i][1] = coords[i][1] + init_pos[1]
                self.prev_coords[i][2] = coords[i][2] + init_pos[2]

        translator = InternalCoordinatesToCartesian(n_atoms, coords)

        for n in range(3, n_atoms):
            # Generate all coordinates using three previous atoms
            # as a frame of reference,
            num, name, atom_name, atom_type, \
               atom_c, atom_b, atom_a, r, a, t = zmatrix[n]

            # Apply the peptide bond conformation
            if residue_name != "PRO":
                if name == "N  " and not init_pos:
                    t = self.prev_psi + 0.0
                if name == "O  ":
                    t = psi + 180.0
                if name == "HA " or name == "HA2":
                    t = 120.0 + phi
                if name == "CB " or name == "HA3":
                    t = 240.0 + phi
                if name == "C  ":
                    t = phi
            else:
                # proline
                if name == "N  " and not init_pos:
                    t = self.prev_psi + 0.0
                if name == "O  ":
                    t = psi + 180.0
                if name == "CA ":
                    t = phi - 120.0
                if name == "CD ":
                    t = phi + 60.0

            translator.addInternal(n + 1, atom_c + 1, atom_b + 1, atom_a + 1,
                                   r, a, t)
            xyz = translator.getCartesian(n + 1)

            if self.nterm_hydrogen:
                # This is a hack for the first hydrogen atom
                # to make sure the bond length is correct.
                self.nterm_hydrogen.setposn(
                    self.nterm_hydrogen.posn() + \
                    0.325 * norm(xyz))
                self.nterm_hydrogen = None

            # Store previous coordinates for the next building step
            if not init_pos:
                if name == "N  ":
                    self.prev_coords[0][0] = xyz[0]
                    self.prev_coords[0][1] = xyz[1]
                    self.prev_coords[0][2] = xyz[2]
                if name == "CA ":
                    self.prev_coords[1][0] = xyz[0]
                    self.prev_coords[1][1] = xyz[1]
                    self.prev_coords[1][2] = xyz[2]
                if name == "C  ":
                    self.prev_coords[2][0] = xyz[0]
                    self.prev_coords[2][1] = xyz[1]
                    self.prev_coords[2][2] = xyz[2]

            # Add a new atom to the molecule
            if not fake_chain or \
               name == "CA ":
                atom = Atom(atom_name, xyz, mol)

                if not self.init_ca and \
                   name == "CA ":
                    self.init_ca = atom

                if mol.protein:
                    aa = mol.protein.add_pdb_atom(atom, name.replace(' ', ''),
                                                  idx, AA_3_TO_1[residue_name])
                    atom.pdb_info = {}
                    atom.pdb_info['atom_name'] = name.replace(' ', '')
                    atom.pdb_info['residue_name'] = residue_name
                    residue_id = "%3d " % idx
                    atom.pdb_info['residue_id'] = residue_id
                    atom.pdb_info['standard_atom'] = True
                    atom.pdb_info['chain_id'] = True
                    if aa:
                        aa.set_secondary_structure(secondary)

                # Create temporary attributes for proper bond assignment.
                atom._is_aromatic = False
                atom._is_single = False

                if atom_type == "sp2a":
                    atom_type = "sp2"
                    atom._is_aromatic = True

                if atom_type == "sp2s":
                    atom_type = "sp2"
                    atom._is_single = True

                atom.set_atomtype_but_dont_revise_singlets(atom_type)

                ### debug - output in PDB format
                ### print "ATOM  %5d  %-3s %3s %c%4d    %8.3f%8.3f%8.3f" % ( n, name, "ALA", ' ', res_num, xyz[0], xyz[1], xyz[2])

        self.prev_psi = psi  # Remember previous psi angle.

        return