示例#1
0
def calc_dihedral(chain, child_res_id):
    """
    calculates the dihedral angles (phi, psi) for residue of index
    child_res_id in chain
    
    returns a tuple of form (phi, psi), if it exists
    
    """
    from math import pi
    from Bio import PDB
    
    try:
        CP = chain.child_list[(child_res_id-1)]['C'].get_vector()
        N = chain.child_list[child_res_id]['N'].get_vector()
        CA = chain.child_list[child_res_id]['CA'].get_vector()
        C = chain.child_list[child_res_id]['C'].get_vector()
        NA = chain.child_list[(child_res_id+1)]['N'].get_vector()
    except KeyError:
        return () # no dihedral angles for corner residues or non-a.a.'residues'
    else:
        try:
            phi = PDB.calc_dihedral(CP, N, CA, C)*-180/pi
            psi = PDB.calc_dihedral(N, CA, C, NA)*-180/pi
            return (phi, psi)
        except ZeroDivisionError:
            return ()
示例#2
0
def calc_all_dihedrals(chain, child_res_id):
    """
    calculates the dihedral angles (phi, psi, chia, chib) for residue of
    index child_res_id in chain
    
    returns a tuple of form (phi, psi, chia, chib), if it exists
    
    where ambiguity in chi angle definition exists:
    chia is in reference to the longer side chain or the heavier atom
    chib to the shorter
    
    if no ambiguity, chia=chib
    
    if residue is a GLY or ALA return only (phi, psi)
    """

    from math import pi
    from Bio import PDB
    try:
        residue = chain.child_list[child_res_id]
        name = residue.get_resname()
        if name == 'GLY' or name == 'ALA':
            dih = calc_dihedral(chain, child_res_id)
            phi = dih[0]
            psi = dih[1]
            return (phi, psi, 0, 0)          
        
    except KeyError:
        print "key error line 103"
        return () # no dihedral angles for corner residues or non-a.a.'residues'
    except IndexError:
        print 'IndexError line 106, probable cause: irregular PDB file'
        return ()     
    try:
        CP = chain.child_list[(child_res_id-1)]['C'].get_vector()
        N = chain.child_list[child_res_id]['N'].get_vector()
        CA = chain.child_list[child_res_id]['CA'].get_vector()
        C = chain.child_list[child_res_id]['C'].get_vector()
        NA = chain.child_list[(child_res_id+1)]['N'].get_vector()
        CB = chain.child_list[child_res_id]['CB'].get_vector()
        fourth_chi_atom = chain.child_list[child_res_id].child_list[5].get_vector()
        if name == 'VAL' or name == 'ILE' or name == 'THR':
            alt_fourth_chi_atom = chain.child_list[child_res_id].child_list[6].get_vector()
        else:
            alt_fourth_chi_atom = fourth_chi_atom
    except KeyError:
        print 'KeyError line 119'
        return () # no dihedral angles for corner residues or non-a.a.'residues'
    except IndexError:
        print 'IndexError line 122, probable cause: irregular PDB file'
        return ()
    else:
        try:
            phi = PDB.calc_dihedral(CP, N, CA, C)*-180/pi
            psi = PDB.calc_dihedral(N, CA, C, NA)*-180/pi
            chia= PDB.calc_dihedral(C, CA, CB, fourth_chi_atom)*-180/pi
            chib= PDB.calc_dihedral(C, CA, CB, alt_fourth_chi_atom)*-180/pi
            return (phi, psi, chia, chib)
        except ZeroDivisionError:
            return ()
示例#3
0
def compute_chi4(structure_, model_, chain_, curr_residue_):
    chi4 = 999.00
    if curr_residue_.has_id('CG') and curr_residue_.has_id(
            'CD') and curr_residue_.has_id('NE'):
        curr_cg = structure_[model_.id][chain_.id][
            curr_residue_.id]['CG'].get_vector()
        curr_cd = structure_[model_.id][chain_.id][
            curr_residue_.id]['CD'].get_vector()
        curr_ne = structure_[model_.id][chain_.id][
            curr_residue_.id]['NE'].get_vector()

        if curr_residue_.has_id('CZ') and curr_residue_.resname == 'ARG':
            curr_cz = structure_[model_.id][chain_.id][
                curr_residue_.id]['CZ'].get_vector()
            chi4 = round(
                math.degrees(
                    PDB.calc_dihedral(curr_cg, curr_cd, curr_ne, curr_cz)), 2)

    if curr_residue_.has_id('CG') and curr_residue_.has_id(
            'CD') and curr_residue_.has_id('CE'):
        curr_cg = structure_[model_.id][chain_.id][
            curr_residue_.id]['CG'].get_vector()
        curr_cd = structure_[model_.id][chain_.id][
            curr_residue_.id]['CD'].get_vector()
        curr_ce = structure_[model_.id][chain_.id][
            curr_residue_.id]['CE'].get_vector()

        if curr_residue_.has_id('NZ') and curr_residue_.resname == 'LYS':
            curr_nz = structure_[model_.id][chain_.id][
                curr_residue_.id]['NZ'].get_vector()
            chi4 = round(
                math.degrees(
                    PDB.calc_dihedral(curr_cg, curr_cd, curr_ce, curr_nz)), 2)

    return chi4
示例#4
0
def calc_dihedral(chain, child_res_id):
    """
    calculates the dihedral angles (phi, psi) for residue of index
    child_res_id in chain
    
    returns a tuple of form (phi, psi), if it exists
    
    """
    from math import pi
    from Bio import PDB

    try:
        CP = chain.child_list[(child_res_id - 1)]['C'].get_vector()
        N = chain.child_list[child_res_id]['N'].get_vector()
        CA = chain.child_list[child_res_id]['CA'].get_vector()
        C = chain.child_list[child_res_id]['C'].get_vector()
        NA = chain.child_list[(child_res_id + 1)]['N'].get_vector()
    except KeyError:
        return (
        )  # no dihedral angles for corner residues or non-a.a.'residues'
    else:
        try:
            phi = PDB.calc_dihedral(CP, N, CA, C) * -180 / pi
            psi = PDB.calc_dihedral(N, CA, C, NA) * -180 / pi
            return (phi, psi)
        except ZeroDivisionError:
            return ()
示例#5
0
 def analyze_dihedral(self):
     """
     Deprecated. Please use class Dihedral_Analisys
     """
     angles = list()
     cov_atm_lig = self.ligand.child_dict[self.ligand_dict['cov_atm']]
     ##dihedral between CA < CB < SG < ligand
     angle_1 = math.degrees(
         bp.calc_dihedral(self.covalent_res.child_dict['CA'].get_vector(),
                          self.covalent_res.child_dict['CB'].get_vector(),
                          self.covalent_atm_res.get_vector(),
                          cov_atm_lig.get_vector()))
     angles.append(angle_1)
     ##all dihedral of CB < SG < ligand-covalent-atom < other ligand atoms
     ns = bp.NeighborSearch(list(self.ligand.get_atom()))
     neigh = ns.search(cov_atm_lig.get_coord(), 2)
     neigh = filter(lambda x: x.name != self.ligand_dict['cov_atm'],
                    neigh)  # removes the atom itself
     for i in neigh:
         ang = math.degrees(
             bp.calc_dihedral(
                 self.covalent_res.child_dict['CB'].get_vector(),
                 self.covalent_atm_res.get_vector(),
                 cov_atm_lig.get_vector(), i.get_vector()))
         angles.append(ang)
     open('/'.join([self.path, DIHEDRAL_OUTPUT]), 'w').write(
         reduce(lambda x, ang: ' '.join([x, str(ang)]), angles, ''))
示例#6
0
def compute_chi1(structure_, model_, chain_, curr_residue_):
    chi1 = 999.00
    if curr_residue_.has_id('N') and curr_residue_.has_id(
            'CA') and curr_residue_.has_id('CB'):
        curr_n = structure_[model_.id][chain_.id][
            curr_residue_.id]['N'].get_vector()
        curr_ca = structure_[model_.id][chain_.id][
            curr_residue_.id]['CA'].get_vector()
        curr_cb = structure_[model_.id][chain_.id][
            curr_residue_.id]['CB'].get_vector()

        if curr_residue_.has_id('CG') and (curr_residue_.resname == 'ARG'
                                           or curr_residue_.resname == 'ASN'
                                           or curr_residue_.resname == 'ASP'
                                           or curr_residue_.resname == 'GLN'
                                           or curr_residue_.resname == 'GLU'
                                           or curr_residue_.resname == 'HIS'
                                           or curr_residue_.resname == 'LEU'
                                           or curr_residue_.resname == 'LYS'
                                           or curr_residue_.resname == 'MET'
                                           or curr_residue_.resname == 'PHE'
                                           or curr_residue_.resname == 'PRO'
                                           or curr_residue_.resname == 'TRP'
                                           or curr_residue_.resname == 'TYR'):
            curr_cg = structure_[model_.id][chain_.id][
                curr_residue_.id]['CG'].get_vector()
            chi1 = round(
                math.degrees(
                    PDB.calc_dihedral(curr_n, curr_ca, curr_cb, curr_cg)), 2)

        if curr_residue_.has_id('SG') and curr_residue_.resname == 'CYS':
            curr_sg = structure_[model_.id][chain_.id][
                curr_residue_.id]['SG'].get_vector()
            chi1 = round(
                math.degrees(
                    PDB.calc_dihedral(curr_n, curr_ca, curr_cb, curr_sg)), 2)

        if curr_residue_.has_id('CG1') and (curr_residue_.resname == 'VAL'
                                            or curr_residue_.resname == 'ILE'):
            curr_cg1 = structure_[model_.id][chain_.id][
                curr_residue_.id]['CG1'].get_vector()
            chi1 = round(
                math.degrees(
                    PDB.calc_dihedral(curr_n, curr_ca, curr_cb, curr_cg1)), 2)

        if curr_residue_.has_id('OG') and curr_residue_.resname == 'SER':
            curr_og = structure_[model_.id][chain_.id][
                curr_residue_.id]['OG'].get_vector()
            chi1 = round(
                math.degrees(
                    PDB.calc_dihedral(curr_n, curr_ca, curr_cb, curr_og)), 2)

        if curr_residue_.has_id('OG1') and curr_residue_.resname == 'THR':
            curr_og1 = structure_[model_.id][chain_.id][
                curr_residue_.id]['OG1'].get_vector()
            chi1 = round(
                math.degrees(
                    PDB.calc_dihedral(curr_n, curr_ca, curr_cb, curr_og1)), 2)
    return chi1
                def calc_phi_psi(structure):
                    '''Function makes 3 lists of proteins C-alpha, C and N atom vectors. These lists are then used to calculate
                     dihedral angles of proteins.'''

                    atom_vector_list_Ca = []
                    atom_vector_list_N = []
                    atom_vector_list_C = []

                    # For-loop for acquiring atom vectors, but only for those residues which have a C-alpha atom.
                    for chain in structure.get_chains():
                        for res in chain:
                            if res.has_id('CA'):
                                for atom in res:
                                    if atom.get_name() == 'N':
                                        atom_vector_list_N.append(atom.get_vector())
                                    elif atom.get_name() == 'CA':
                                        atom_vector_list_Ca.append(atom.get_vector())
                                    elif atom.get_name() == 'C':
                                        atom_vector_list_C.append(atom.get_vector())
                                    else:
                                        pass

                    len_vec = 0

                    ### The if statement compares vector list length between C-alpha vector list and two others, if one of them is
                    ### shorter than C-alpha, possibly due to an error in the PDB structure, then the length vector which is
                    ### required for calculating dihedral angles is set to be C-alpha which is the same length as other vector lists
                    if len(atom_vector_list_Ca) > len(atom_vector_list_C) or len(atom_vector_list_Ca) > len(
                            atom_vector_list_N):
                        c_ca = len(atom_vector_list_Ca) - len(atom_vector_list_C)
                        n_ca = len(atom_vector_list_Ca) - len(atom_vector_list_N)
                        if c_ca == n_ca:
                            len_vec = len(atom_vector_list_Ca) - c_ca
                    else:
                        len_vec = len(atom_vector_list_Ca)

                    dihedral_phi = []
                    dihedral_psi = []

                    # So we don't include first amino acid which has no phi angle and last amino acid which has no psi angle!
                    cut_off = range(1, len_vec - 1)

                    # Calculation of phi angles!
                    for i in cut_off:
                        dihedral_phi.append(PDB.calc_dihedral(atom_vector_list_C[i - 1],
                                                              atom_vector_list_N[i],
                                                              atom_vector_list_Ca[i],
                                                              atom_vector_list_C[i]))

                    # Calculation of psi angles!
                    for i in cut_off:
                        dihedral_psi.append(PDB.calc_dihedral(atom_vector_list_N[i],
                                                              atom_vector_list_Ca[i],
                                                              atom_vector_list_C[i],
                                                              atom_vector_list_N[i + 1]))
                    return (dihedral_phi, dihedral_psi)
示例#8
0
def calc_all_dihedrals(chain, res_id):
    """
    calculates the dihedral angles (phi, psi, chia, chib) for residue of
    index res_id in chain
    
    returns a tuple of form (phi, psi, chia, chib), if it exists
    
    where ambiguity in chi angle definition exists:
    chia is in reference to the longer side chain or the heavier atom
    chib to the shorter
    
    if no ambiguity, chia=chib
    
    if residue is a GLY or ALA return only (phi, psi)
    """

    from math import pi
    from Bio import PDB
    try:
        residue = chain.child_list[res_id]
        name = residue.get_resname()
        if name == 'GLY' or name == 'ALA':
            dih = calc_dihedral(chain, res_id)
            phi = dih[0]
            psi = dih[1]
            return (phi, psi, 0, 0)

    except KeyError:
        print "key error line 196"
        return (
        )  # no dihedral angles for corner residues or non-a.a.'residues'
    try:
        CP = chain.child_list[(res_id - 1)]['C'].get_vector()
        N = chain.child_list[res_id]['N'].get_vector()
        CA = chain.child_list[res_id]['CA'].get_vector()
        C = chain.child_list[res_id]['C'].get_vector()
        NA = chain.child_list[(res_id + 1)]['N'].get_vector()
        CB = chain.child_list[res_id]['CB'].get_vector()
        fourth_chi_atom = chain.child_list[res_id].child_list[5].get_vector()

        if name == 'VAL' or name == 'ILE' or name == 'THR':
            alt_fourth_chi_atom = chain.child_list[res_id].child_list[
                6].get_vector()
        else:
            alt_fourth_chi_atom = fourth_chi_atom
    except KeyError:
        print 'key error line 211'
        return (
        )  # no dihedral angles for corner residues or non-a.a.'residues'
    else:
        phi = PDB.calc_dihedral(CP, N, CA, C) * -180 / pi
        psi = PDB.calc_dihedral(N, CA, C, NA) * -180 / pi
        chia = PDB.calc_dihedral(C, CA, CB, fourth_chi_atom) * -180 / pi
        chib = PDB.calc_dihedral(C, CA, CB, alt_fourth_chi_atom) * -180 / pi
    return (phi, psi, chia, chib)
示例#9
0
def get_dihedral( residue_list ):

	'''
	returns phi and psi angles of a residue and the amino acid sidechain present

	residue_list - []Bio.PDB.Residue - list of 3 *hopefully* continuous residues

	'''

	for one, two in zip( residue_list[:-1], residue_list[1:] ):

		if ( two.get_id()[1] - one.get_id()[1] ) != 1:

			raise BackboneError( "Discontinuous residues", two.get_id()[1] )

	atoms = (
		{"C": False},
		{"N": False,
		"CA": False,
		"C": False},
		{"N": False}
	)

	for i, residue in enumerate( residue_list ):

		if i == 1:

			res_name = SeqUtils.seq1( residue.get_resname() )

			if not is_aa( res_name ):

				raise BackboneError( "Not a valid amino acid", residue.get_id()[1] )

		for atom in residue.get_unpacked_list():

			if atom.name in atoms[i].keys():
				
				atoms[i][ atom.name ] = atom.get_vector()

	if False in map( check_dict, atoms ):

		raise BackboneError( "Missing backbone atoms", residue.get_id()[1] )

	dihedrals = [
		PDB.calc_dihedral( atoms[0]["C"], atoms[1]["N"], atoms[1]["CA"], atoms[1]["C"] ), #phi
		PDB.calc_dihedral( atoms[1]["N"], atoms[1]["CA"], atoms[1]["C"], atoms[2]["N"] ) #psi
	]

	return ( dihedrals, res_name )
示例#10
0
def compute_chi3(structure_, model_, chain_, curr_residue_):
    chi3 = 999.00
    if curr_residue_.has_id('CB') and curr_residue_.has_id(
            'CG') and curr_residue_.has_id('CD'):
        curr_cb = structure_[model_.id][chain_.id][
            curr_residue_.id]['CB'].get_vector()
        curr_cg = structure_[model_.id][chain_.id][
            curr_residue_.id]['CG'].get_vector()
        curr_cd = structure_[model_.id][chain_.id][
            curr_residue_.id]['CD'].get_vector()

        if curr_residue_.has_id('NE') and curr_residue_.resname == 'ARG':
            curr_ne = structure_[model_.id][chain_.id][
                curr_residue_.id]['NE'].get_vector()
            chi3 = round(
                math.degrees(
                    PDB.calc_dihedral(curr_cb, curr_cg, curr_cd, curr_ne)), 2)

        if curr_residue_.has_id('OE1') and (curr_residue_.resname == 'GLN'
                                            or curr_residue_.resname == 'GLU'):
            curr_oe1 = structure_[model_.id][chain_.id][
                curr_residue_.id]['OE1'].get_vector()
            chi3 = round(
                math.degrees(
                    PDB.calc_dihedral(curr_cb, curr_cg, curr_cd, curr_oe1)), 2)

        if curr_residue_.has_id('CE') and curr_residue_.resname == 'LYS':
            curr_ce = structure_[model_.id][chain_.id][
                curr_residue_.id]['CE'].get_vector()
            chi3 = round(
                math.degrees(
                    PDB.calc_dihedral(curr_cb, curr_cg, curr_cd, curr_ce)), 2)

    if curr_residue_.has_id('CB') and curr_residue_.has_id(
            'CG') and curr_residue_.has_id('SD') and curr_residue_.has_id(
                'CE') and curr_residue_.resname == 'MET':
        curr_cb = structure_[model_.id][chain_.id][
            curr_residue_.id]['CB'].get_vector()
        curr_cg = structure_[model_.id][chain_.id][
            curr_residue_.id]['CG'].get_vector()
        curr_sd = structure_[model_.id][chain_.id][
            curr_residue_.id]['SD'].get_vector()
        curr_ce = structure_[model_.id][chain_.id][
            curr_residue_.id]['CE'].get_vector()
        chi3 = round(
            math.degrees(PDB.calc_dihedral(curr_cb, curr_cg, curr_sd,
                                           curr_ce)), 2)
    return chi3
示例#11
0
def _sidechain_torsions(filename, model_id):

    parser = PDB.PDBParser(QUIET=True)
    structure_id = os.path.splitext(os.path.basename(filename))[0][-4:]
    structure = parser.get_structure(structure_id, filename)
    model = structure.get_list()[model_id]

    torsion_list = []

    for chain in model:
        for res in chain:
            # Skip heteroatoms
            if res.id[0] != " ":
                continue
            res_name = res.resname
            chis = [float('nan')] * CHI_COUNT
            for i, chi_res in enumerate(CHI_ATOMS):
                if res_name in chi_res:
                    try:
                        atom_list = chi_res[res_name]
                        vec_atoms = [res[a] for a in atom_list]
                        vectors = [a.get_vector() for a in vec_atoms]
                        angle = PDB.calc_dihedral(*vectors)
                        chis[i] = round(math.degrees(angle), 3)
                    except KeyError as error:
                        logging.info("Residue doesn't have required atoms.",
                                     res_name, res.get_list(), error)

            resi = "{0}{1}".format(res.id[1], res.id[2].strip())
            torsion_list.append([resi, res_name, chis])
    return torsion_list
 def calc_dihedral(self):
     cb = self.cov_receptor.parent['CB']
     ca = self.cov_receptor.parent['CA']
     lig_cov_neoghbors = self.get_atom_neighbors(self.cov_ligand, list(self.ligand.get_atoms()))
     self.angles = list()
     ang1 = math.degrees( bp.calc_dihedral(ca.get_vector(), 
                                           cb.get_vector(), 
                                           self.cov_receptor.get_vector(),
                                           self.cov_ligand.get_vector()))
     self.angles.append(ang1)
     for i in lig_cov_neoghbors:
         ang = math.degrees( bp.calc_dihedral(cb.get_vector(),
                                              self.cov_receptor.get_vector(),
                                              self.cov_ligand.get_vector(),
                                              i.get_vector()))
         self.angles.append(ang)
示例#13
0
 def calc_dihedral(self):
     cb = self.cov_receptor.parent['CB']
     ca = self.cov_receptor.parent['CA']
     lig_cov_neoghbors = self.get_atom_neighbors(
         self.cov_ligand, list(self.ligand.get_atoms()))
     self.angles = list()
     ang1 = math.degrees(
         bp.calc_dihedral(ca.get_vector(), cb.get_vector(),
                          self.cov_receptor.get_vector(),
                          self.cov_ligand.get_vector()))
     self.angles.append(ang1)
     for i in lig_cov_neoghbors:
         ang = math.degrees(
             bp.calc_dihedral(cb.get_vector(),
                              self.cov_receptor.get_vector(),
                              self.cov_ligand.get_vector(), i.get_vector()))
         self.angles.append(ang)
示例#14
0
def compute_torsion_angles(previous_residue, residue, next_residue):
    """
    Little helper function, calculates the backbone phi and psi torsion
    angles from the given residues and returns them
    :param residue: The amino acid residue the torsion angles shall be computed
    :return: Phi and psi backbone torsion angles
    """
    # print previous_residue.get_id()[1], residue.get_id()[1], next_residue.get_id()[1]
    # extract the atoms for the torsion calculation
    # 1.) for the phi
    atom_CO_0 = previous_residue['C'].get_vector()
    atom_N_1 = residue['N'].get_vector()
    atom_CA_1 = residue['CA'].get_vector()
    atom_CO_1 = residue['C'].get_vector()
    atom_N_2 = next_residue['N'].get_vector()

    phi_angle = PDB.calc_dihedral(atom_CO_0, atom_N_1, atom_CA_1, atom_CO_1)
    psi_angle = PDB.calc_dihedral(atom_N_1, atom_CA_1, atom_CO_1, atom_N_2)

    # convert into degrees
    return math.degrees(phi_angle), math.degrees(psi_angle)
 def analyze_dihedral(self):  
     """
     Deprecated. Please use class Dihedral_Analisys
     """
     angles = list()
     cov_atm_lig = self.ligand.child_dict[self.ligand_dict['cov_atm']]
     ##dihedral between CA < CB < SG < ligand
     angle_1 = math.degrees( bp.calc_dihedral(self.covalent_res.child_dict['CA'].get_vector(),
                                              self.covalent_res.child_dict['CB'].get_vector(),
                                              self.covalent_atm_res.get_vector(),
                                              cov_atm_lig.get_vector()))
     angles.append(angle_1)
     ##all dihedral of CB < SG < ligand-covalent-atom < other ligand atoms
     ns  = bp.NeighborSearch(list(self.ligand.get_atom()))        
     neigh = ns.search(cov_atm_lig.get_coord(), 2) 
     neigh = filter(lambda x: x.name != self.ligand_dict['cov_atm'], neigh)# removes the atom itself
     for i in neigh:
         ang = math.degrees( bp.calc_dihedral(self.covalent_res.child_dict['CB'].get_vector(),
                                              self.covalent_atm_res.get_vector(),
                                              cov_atm_lig.get_vector(),
                                              i.get_vector()))
         angles.append(ang)
     open('/'.join([self.path, DIHEDRAL_OUTPUT]), 'w').write(reduce(lambda x, ang: ' '.join([x, str(ang)]), angles, ''))
示例#16
0
    def __calc_chi(self, residue, group):
        #Define all possible chi angles for each residue
        chi_atoms = self.__gen_chi_list()

        #Convert Needed data to appropriate formats
        res_atoms = PDB.Selection.unfold_entities(residue, 'A')
        res_name = residue.get_resname()
        atom_names = []
        for atom in res_atoms:
            atom_names.append(atom.get_name())
        
        #Gather all four atoms to calculate the angle for
        atom1 = res_atoms[atom_names.index(chi_atoms[group][res_name][0])].get_vector()
        atom2 = res_atoms[atom_names.index(chi_atoms[group][res_name][1])].get_vector()
        atom3 = res_atoms[atom_names.index(chi_atoms[group][res_name][2])].get_vector()
        atom4 = res_atoms[atom_names.index(chi_atoms[group][res_name][3])].get_vector()
        #Return the dihedral angle between the atoms
        return PDB.calc_dihedral(atom1, atom2, atom3, atom4)*(180/const.pi)
示例#17
0
def compute_psi(structure_, model_, chain_, curr_residue_, next_residue_):
    psi = 999.00
    if curr_residue_.has_id('N') and curr_residue_.has_id(
            'CA'
    ) and curr_residue_.has_id('C') and next_residue_.has_id('N') and (
            next_residue_.id[1] == (curr_residue_.id[1] + 1)
    ):  #The last condition is required to make sure that the residues are consecutive
        curr_n = structure_[model_.id][chain_.id][
            curr_residue_.id]['N'].get_vector()
        curr_ca = structure_[model_.id][chain_.id][
            curr_residue_.id]['CA'].get_vector()
        curr_c = structure_[model_.id][chain_.id][
            curr_residue_.id]['C'].get_vector()
        next_n = structure_[model_.id][chain_.id][
            next_residue_.id]['N'].get_vector()
        psi = round(
            math.degrees(PDB.calc_dihedral(curr_n, curr_ca, curr_c, next_n)),
            2)
    return psi
示例#18
0
def compute_omega(structure_, model_, chain_, prev_residue_, curr_residue_):
    omega = 999.00
    if prev_residue_.has_id('CA') and prev_residue_.has_id(
            'C'
    ) and curr_residue_.has_id('N') and curr_residue_.has_id('CA') and (
            curr_residue_.id[1] == (prev_residue_.id[1] + 1)
    ):  #The last condition is required to make sure that the residues are consecutive
        prev_ca = structure_[model_.id][chain_.id][
            prev_residue_.id]['CA'].get_vector()
        prev_c = structure_[model_.id][chain_.id][
            prev_residue_.id]['C'].get_vector()
        curr_n = structure_[model_.id][chain_.id][
            curr_residue_.id]['N'].get_vector()
        curr_ca = structure_[model_.id][chain_.id][
            curr_residue_.id]['CA'].get_vector()
        omega = round(
            math.degrees(PDB.calc_dihedral(prev_ca, prev_c, curr_n, curr_ca)),
            2)
    return omega
def get_psi(chain, residue):
  '''Calculate the psi torsion of a residue.'''
  
  # Get the next residue

  res_id = residue.get_id()
  next_res = chain[res_id[1] + 1]
  
  next_flag = next_res.get_id()[0]
  if next_flag == 'W' or next_flag.startswith('H_'):
    raise Exception('Hetero residue type!')
  
  # Calculate the torsion

  n = residue['N'].get_vector()
  ca = residue['CA'].get_vector()
  c = residue['C'].get_vector()
  n_next = next_res['N'].get_vector()

  return PDB.calc_dihedral(n, ca, c, n_next)
def get_phi(chain, residue):
  '''Calculate the phi torsion of a residue.'''
  
  # Get the previous residue

  res_id = residue.get_id()
  prev_res = chain[res_id[1] - 1]
  
  prev_flag = prev_res.get_id()[0]
  if prev_flag == 'W' or prev_flag.startswith('H_'):
    raise Exception('Hetero residue type!')
 
  # Calculate the torsion

  c_prev = prev_res['C'].get_vector()
  n = residue['N'].get_vector()
  ca = residue['CA'].get_vector()
  c = residue['C'].get_vector()

  return PDB.calc_dihedral(c_prev, n, ca, c) 
示例#21
0
def compute_phi(
    structure_, model_, chain_, prev_residue_, curr_residue_
):  #The original variable names can not be assigned again, therefore copies of variables are created here
    phi = 999.00
    if prev_residue_.has_id('C') and curr_residue_.has_id(
            'N'
    ) and curr_residue_.has_id('CA') and curr_residue_.has_id('C') and (
            curr_residue_.id[1] == (prev_residue_.id[1] + 1)
    ):  #The last condition is required to make sure that the residues are consecutive
        prev_c = structure_[model_.id][chain_.id][
            prev_residue_.id]['C'].get_vector()
        curr_n = structure_[model_.id][chain_.id][
            curr_residue_.id]['N'].get_vector()
        curr_ca = structure_[model_.id][chain_.id][
            curr_residue_.id]['CA'].get_vector()
        curr_c = structure_[model_.id][chain_.id][
            curr_residue_.id]['C'].get_vector()
        phi = round(
            math.degrees(PDB.calc_dihedral(prev_c, curr_n, curr_ca, curr_c)),
            2)
    return phi
示例#22
0
    def calculate_torsion(self, fn):
        """Calculate side-chain torsion angles for given file"""
        id = os.path.splitext(os.path.basename(fn))[0]

        torsion_list = list()

        structure = self.parser.get_structure(id, fn)
        for model in structure:
            model_name = model.id
            for chain in model:
                chain_name = chain.id
                for res in chain:
                    # Skip heteroatoms
                    if res.id[0] != " ": continue
                    res_name = res.resname
                    if res_name in ("ALA", "GLY"): continue
                    chi_list = [""] * len(self.chi_names)
                    for x, chi in enumerate(self.chi_names):
                        chi_res = self.chi_atoms[chi]
                        try:
                            atom_list = chi_res[res_name]
                        except KeyError:
                            continue
                        try:
                            vec_atoms = [res[a] for a in atom_list]
                        except KeyError:
                            chi_list[x] = float("nan")
                            continue
                        vectors = [a.get_vector() for a in vec_atoms]
                        angle = PDB.calc_dihedral(*vectors)
                        if self.degrees:
                            angle = math.degrees(angle)
                        chi_list[x] = angle

                    resi = "{0}{1}".format(res.id[1], res.id[2].strip())
                    row = [id, model_name, chain_name, res_name, resi
                           ] + chi_list
                    torsion_list.append(dict(zip(self.fieldnames, row)))

        return torsion_list
psi = []
for i in range(0, numAngles - 2):
    #	nIndex  = 4*i;
    precaIndex = 4 * i + 1
    cpIndex = 4 * i + 2
    #	oIndex  = 4*i+3
    nIndex = 4 * i + 4
    caIndex = 4 * i + 5
    cp2Index = 4 * i + 6
    #       o2Index =4*i+7;
    n2Index = 4 * i + 8

    vcp = pdb.Vector(coordinates[cpIndex, 0:3])
    vn = pdb.Vector(coordinates[nIndex, 0:3])
    vca = pdb.Vector(coordinates[caIndex, 0:3])
    vcp2 = pdb.Vector(coordinates[cp2Index, 0:3])
    vn2 = pdb.Vector(coordinates[n2Index, 0:3])

    alpha1 = coordinates[precaIndex, 0:3]
    alpha2 = coordinates[caIndex, 0:3]

    currentDistance = np.linalg.norm(alpha1 - alpha2)

    currentPhi = pdb.calc_dihedral(vcp, vn, vca, vcp2)
    currentPsi = pdb.calc_dihedral(vn, vca, vcp2, vn2)
    phi.append(currentPhi)
    psi.append(currentPsi)
    caDistance.append(currentDistance)
print(len(phi))
print(caDistance)
示例#24
0
def compute_chi2(structure_, model_, chain_, curr_residue_):
    chi2 = 999.00
    if curr_residue_.has_id('CA') and curr_residue_.has_id(
            'CB') and curr_residue_.has_id('CG'):
        curr_ca = structure_[model_.id][chain_.id][
            curr_residue_.id]['CA'].get_vector()
        curr_cb = structure_[model_.id][chain_.id][
            curr_residue_.id]['CB'].get_vector()
        curr_cg = structure_[model_.id][chain_.id][
            curr_residue_.id]['CG'].get_vector()

        if curr_residue_.has_id('CD') and (curr_residue_.resname == 'ARG'
                                           or curr_residue_.resname == 'GLN'
                                           or curr_residue_.resname == 'GLU'
                                           or curr_residue_.resname == 'LYS'
                                           or curr_residue_.resname == 'PRO'):
            curr_cd = structure_[model_.id][chain_.id][
                curr_residue_.id]['CD'].get_vector()
            chi2 = round(
                math.degrees(
                    PDB.calc_dihedral(curr_ca, curr_cb, curr_cg, curr_cd)), 2)

        if curr_residue_.has_id('OD1') and (curr_residue_.resname == 'ASN'
                                            or curr_residue_.resname == 'ASP'):
            curr_od1 = structure_[model_.id][chain_.id][
                curr_residue_.id]['OD1'].get_vector()
            chi2 = round(
                math.degrees(
                    PDB.calc_dihedral(curr_ca, curr_cb, curr_cg, curr_od1)), 2)

        if curr_residue_.has_id('ND1') and curr_residue_.resname == 'HIS':
            curr_nd1 = structure_[model_.id][chain_.id][
                curr_residue_.id]['ND1'].get_vector()
            chi2 = round(
                math.degrees(
                    PDB.calc_dihedral(curr_ca, curr_cb, curr_cg, curr_nd1)), 2)

        if curr_residue_.has_id('CD1') and (curr_residue_.resname == 'LEU'
                                            or curr_residue_.resname == 'PHE'
                                            or curr_residue_.resname == 'TRP'
                                            or curr_residue_.resname == 'TYR'):
            curr_cd1 = structure_[model_.id][chain_.id][
                curr_residue_.id]['CD1'].get_vector()
            chi2 = round(
                math.degrees(
                    PDB.calc_dihedral(curr_ca, curr_cb, curr_cg, curr_cd1)), 2)

        if curr_residue_.has_id('SD') and curr_residue_.resname == 'MET':
            curr_sd = structure_[model_.id][chain_.id][
                curr_residue_.id]['SD'].get_vector()
            chi2 = round(
                math.degrees(
                    PDB.calc_dihedral(curr_ca, curr_cb, curr_cg, curr_sd)), 2)

    if curr_residue_.has_id('CA') and curr_residue_.has_id(
            'CB') and curr_residue_.has_id('CG1') and curr_residue_.has_id(
                'CD1') and curr_residue_.resname == 'ILE':
        curr_ca = structure_[model_.id][chain_.id][
            curr_residue_.id]['CA'].get_vector()
        curr_cb = structure_[model_.id][chain_.id][
            curr_residue_.id]['CB'].get_vector()
        curr_cg1 = structure_[model_.id][chain_.id][
            curr_residue_.id]['CG1'].get_vector()
        curr_cd1 = structure_[model_.id][chain_.id][
            curr_residue_.id]['CD1'].get_vector()
        chi2 = round(
            math.degrees(
                PDB.calc_dihedral(curr_ca, curr_cb, curr_cg1, curr_cd1)), 2)
    return chi2
示例#25
0
 def calculate_torsion_psi(current_residue, next_residue):
     atom1 = current_residue['N'].get_vector()
     atom2 = current_residue['CA'].get_vector()
     atom3 = current_residue['C'].get_vector()
     atom4 = next_residue['N'].get_vector()
     return PDB.calc_dihedral(atom1, atom2, atom3, atom4)
示例#26
0
def get_pose_constraints(Pose, MaxDist, MinPositionSeperation, SasaRadius, SasaScale, UpstreamGrep, DownstreamGrep, NeedHydrogen=True):
    '''  '''
    # AlexsSasaCalculator is from Alex's interface_fragment_matching 
    # thanks Alex!
    #
    # This is used to give buried polar contacts more weight. Thanks Alex Ford!
    try:
      from interface_fragment_matching.utility.analysis import AtomicSasaCalculator
      # make instace of Alex's sasa calculator
      AlexsSasaCalculator = AtomicSasaCalculator(probe_radius=SasaRadius)
      ResidueAtomSasa = AlexsSasaCalculator.calculate_per_atom_sasa(Pose)    
    except ImportError:
      ' Error: SASA weighting of contacts requires interface_fragment_matching from Alex Ford '

    # for making full atom kd tree
    ResAtmCoordLists = []
    # for translating from kd tree index to ( residue, atom ) coord
    ResAtmRecordLists = []

    # loop through all residue numbers
    for Res in range(1, Pose.n_residue() + 1):
      # remade for each residue
      AtmRecordList = []
      AtmCoordList = []
      # loop through residue's atom numbers
      for Atm in range(1, Pose.residue(Res).natoms() + 1):
        # add (residue, atom) coord to residue's list
        AtmRecordList.append((Res, Atm))
        # add atom xyz coord to residue's list
        AtmCoordList.append( np.array(list(Pose.residue(Res).atom(Atm).xyz())) )
      
      # add residue's lists to respective global lists
      ResAtmCoordLists.extend(AtmCoordList)
      ResAtmRecordLists.extend(AtmRecordList)

    ResidueAtomArray = np.array( ResAtmCoordLists )
    ResidueAtomKDTree = spatial.KDTree( ResidueAtomArray )

    ResidueAtomNeighbors = ResidueAtomKDTree.query_ball_point( ResidueAtomArray, MaxDist )
    # ResidueAtomNearNeighbors = ResidueAtomKDTree.query_ball_point( ResidueAtomArray, 2.0 )
    ResidueAtomHydrogens = ResidueAtomKDTree.query_ball_point( ResidueAtomArray, 1.1 )

    # holds constraints before printing
    AllConstraints = [] 
    # holds sorted cst
    AllBackboneBackboneCst = []
    AllBackboneSidechainCst = []
    AllSidechainSidechainCst = []

    # All contacts are from upstream to downstream residues to avoid double counting
    Upstream = []
    for UpIndex, UpXyzCoords in enumerate(ResAtmCoordLists):
      UpRes, UpAtm = ResAtmRecordLists[UpIndex]

      # # loop through residues storing info on oxygens
      # for UpRes in range( 1, Pose.n_residue() + 1 ):
      #   # loop through atoms
      #   for UpAtm in range( 1, Pose.residue(UpRes).natoms() + 1 ):
      UpName = Pose.residue(UpRes).atom_name(UpAtm).replace(' ', '')

      # skip virtual residues
      if Pose.residue(UpRes).is_virtual(UpAtm):
        continue

      #                                this guy 
      #                                 /
      # checks upstream name           V
      if re.match(UpstreamGrep, UpName ): 
        # print '\n'*2
        # print 'UpRes, UpName', UpRes, UpName

        # get neighbors of upstream residues
        NeighborsOfUpstream = ResidueAtomNeighbors[UpIndex]
        
        # prep for loop
        Downstreams = []

        Constraints = []
        BackboneBackboneCst = []
        BackboneSidechainCst = []
        SidechainSidechainCst = []

        # ArbitrayOrderOfAtomNames = {}
        for DownIndex in NeighborsOfUpstream:
          # name presumes downstream, checks with if imediately below
          DownRes, DownAtm = ResAtmRecordLists[DownIndex]

          # checks that downstream residue is dowstream of upstream and passes min primary sequence spacing
          if DownRes - UpRes >= MinPositionSeperation:
            DownName = Pose.residue(DownRes).atom_name(DownAtm).replace(' ', '')
            
            # skip if same atom
            if UpRes == DownRes:
              if UpName == DownName:
                continue

            # skip virtual residues
            if Pose.residue(DownRes).is_virtual(DownAtm):
              continue

            # checks downstream name
            if re.match( DownstreamGrep, DownName ):
              # print 'DownRes, DownName', DownRes, DownName

              PotentialUpstreamHydrogens = ResidueAtomHydrogens[UpIndex]
              UpstreamHydrogens = []
              # print 'PotentialUpstreamHydrogens', PotentialUpstreamHydrogens
              for UpH_I in PotentialUpstreamHydrogens:
                UpH_Res, UpH_Atm = ResAtmRecordLists[UpH_I]
                UpH_Name  = Pose.residue(UpH_Res).atom_name(UpH_Atm).replace(' ', '')
                # print 'UpH_Name', UpH_Name
                if 'H' in UpH_Name:
                  UpstreamHydrogens.append((UpH_Res, UpH_Atm, UpH_Name))
                # print 'UpstreamHydrogens', UpstreamHydrogens

              PotentialDownstreamHydrogens = ResidueAtomHydrogens[DownIndex]
              DownstreamHydrogens = []
              # print 'PotentialDownstreamHydrogens', PotentialDownstreamHydrogens
              for DownH_I in PotentialDownstreamHydrogens:
                DownH_Res, DownH_Atm = ResAtmRecordLists[DownH_I]
                DownH_Name = Pose.residue(DownH_Res).atom_name(DownH_Atm).replace(' ', '')
                # print 'DownH_Name', DownH_Name
                if 'H' in DownH_Name:
                  DownstreamHydrogens.append((DownH_Res, DownH_Atm, DownH_Name))
                # print 'DownstreamHydrogens', DownstreamHydrogens

              # check their is at least one hydrogen in system before adding constraint
              if len(UpstreamHydrogens) or len(DownstreamHydrogens) or NeedHydrogen == False:

                # these trys / excepts seperate 
                # backbone-backbone from 
                # backbone-sidechain from
                # sidechain-sidechain interactions
                # 
                # in future maybe sort into seperate lists, shouldn't rely on ResidueAtomSasa to know what is in backbone
                try:
                  UpstreamSasa = ResidueAtomSasa[UpRes][UpName]
                  DownstreamSasa = ResidueAtomSasa[DownRes][DownName]
                  AverageSasa = np.mean([UpstreamSasa, DownstreamSasa])        
                  BBBB = 1
                  BBSC = SCSC = 0
                except KeyError:                
                  # These lines handle backbone to sidechain interactions
                  # set weight equal to the most buried 
                  try:
                    UpstreamSasa = ResidueAtomSasa[UpRes][UpName]
                    AverageSasa = SasaScale.FloorSasa
                    BBSC = 1
                    BBBB = SCSC = 0
                  except KeyError:
                    try:
                      DownstreamSasa = ResidueAtomSasa[DownRes][DownName]
                      AverageSasa = SasaScale.FloorSasa 
                      BBSC = 1
                      BBBB = SCSC = 0            
                    
                    # set weight of side chain side chain equal to the most buried             
                    except KeyError:
                      AverageSasa = SasaScale.CeilingSasa 
                      SCSC = 1
                      BBSC = BBBB = 0

                # use instance of sasa_scale to calculate weight based on avg sasa of N and O
                SasaBasedWeight = SasaScale.weigh(AverageSasa)
                # print 
                # print 'AverageSasa', AverageSasa
                # print 'SasaBasedWeight', SasaBasedWeight

                # print 'found downstream neighbor %s'%DownName
                DownXyzCoords = np.array( list(Pose.residue(DownRes).atom(DownAtm).xyz()) )
                # print 'DownRes, DownName', DownRes, DownName
                # print 'DownXyzCoords', DownXyzCoords

                # ## Get neighbors for angles and torsions to use with AtomPairs

                SelectUpNeighbors = []
                # iterates through upstream atom neighbors for references for angle
                for UpNeighborIndex in NeighborsOfUpstream:
                  UpNeighborRes, UpNeighborAtm = ResAtmRecordLists[UpNeighborIndex]
                  UpNeighborName = Pose.residue(UpNeighborRes).atom_name(UpNeighborAtm).replace(' ', '')

                  # keep looking if neighbor is hyrdogen
                  if 'H' in UpNeighborName:
                    continue                

                  # skip virtual residues
                  if Pose.residue(UpNeighborRes).is_virtual(UpNeighborAtm):
                    continue

                  # keep looking if neighbor is self
                  if UpNeighborName == UpName and UpNeighborRes == UpRes:
                    continue
                  # keep looking if neighbor is downstream residue again
                  if UpNeighborName == DownName and UpNeighborRes == DownRes:
                    continue
                  UpNeighborCoords = ResAtmCoordLists[UpNeighborIndex]
                  DistanceToNeighbor = solenoid_tools.vector_magnitude( UpXyzCoords - UpNeighborCoords )
                  SelectUpNeighbors.append( (DistanceToNeighbor, UpNeighborName, UpNeighborRes, UpNeighborCoords) )

                # sort by distance to atom, nearest first
                SelectUpNeighbors.sort()                
                UpNeighbor1Tuple = SelectUpNeighbors[0]
                UpNeighbor2Tuple = SelectUpNeighbors[1]
                # print '\n'*2
                # print 'UpRes, UpName', UpRes, UpName
                # print 'UpstreamHydrogens', UpstreamHydrogens
                # print 'SelectUpNeighbors', SelectUpNeighbors

                 # get neighbors of upstream residues
                NeighborsOfDownstream = ResidueAtomNeighbors[DownIndex]
                SelectDownNeighbors = []
                # iterates through upstream atom neighbors for references for angle
                for DownNeighborIndex in NeighborsOfDownstream:
                  DownNeighborRes, DownNeighborAtm = ResAtmRecordLists[DownNeighborIndex]
                  DownNeighborName = Pose.residue(DownNeighborRes).atom_name(DownNeighborAtm).replace(' ', '')

                  # keep looking if neighbor is hyrdogen
                  if 'H' in DownNeighborName:
                    continue                

                  # skip virtual residues
                  if Pose.residue(DownNeighborRes).is_virtual(DownNeighborAtm):
                    continue

                  # keep looking if neighbor is self
                  if DownNeighborName == DownName and DownNeighborRes == DownRes:
                    continue
                  # keep looking if neighbor is upstream residue
                  if DownNeighborName == UpName and DownNeighborRes == UpRes:
                    continue

                  DownNeighborCoords = ResAtmCoordLists[DownNeighborIndex]
                  DistanceToNeighbor = solenoid_tools.vector_magnitude( DownXyzCoords - DownNeighborCoords )
                  SelectDownNeighbors.append( (DistanceToNeighbor, DownNeighborName, DownNeighborRes, DownNeighborCoords) )

                # sort by distance to atom, nearest first
                SelectDownNeighbors.sort()
                DownNeighbor1Tuple = SelectDownNeighbors[0]
                DownNeighbor2Tuple = SelectDownNeighbors[1]
                # print 'DownRes, DownName', DownRes, DownName
                # print 'DownstreamHydrogens', DownstreamHydrogens
                # print 'SelectDownNeighbors', SelectDownNeighbors

                Distance = solenoid_tools.vector_magnitude(DownXyzCoords - UpXyzCoords)
                
                DistanceCst = 'AtomPair %s %d %s %d SCALARWEIGHTEDFUNC %f HARMONIC %.2f 1.0' %( UpName, UpRes, DownName, DownRes, SasaBasedWeight, Distance )

                # Use Biopython for angle and dihedral calculations
                # here 'Vec' means PDB.Vector of atom's xyz coord
                UpstreamVec = PDB.Vector(UpXyzCoords)
                DownstreamVec = PDB.Vector(DownXyzCoords)
                
                UpNeighbor1Vec = PDB.Vector(UpNeighbor1Tuple[3])
                UpNeighbor2Vec = PDB.Vector(UpNeighbor2Tuple[3])
                DownNeighbor1Vec = PDB.Vector(DownNeighbor1Tuple[3])
                DownNeighbor2Vec = PDB.Vector(DownNeighbor2Tuple[3])

                Angle1 = PDB.calc_angle(UpNeighbor1Vec, UpstreamVec, DownstreamVec)
                AngleCst1 = 'Angle %s %d %s %d %s %d SCALARWEIGHTEDFUNC %f CIRCULARHARMONIC %.2f 0.5' %( UpNeighbor1Tuple[1], UpNeighbor1Tuple[2], UpName, UpRes, DownName, DownRes, SasaBasedWeight, Angle1 )
                Angle2 = PDB.calc_angle(UpstreamVec, DownstreamVec, DownNeighbor1Vec)
                AngleCst2 = 'Angle %s %d %s %d %s %d SCALARWEIGHTEDFUNC %f CIRCULARHARMONIC %.2f 0.5' %( UpName, UpRes, DownName, DownRes, DownNeighbor1Tuple[1], DownNeighbor1Tuple[2], SasaBasedWeight, Angle2 )

                Torsion1 = PDB.calc_dihedral(UpNeighbor2Vec, UpNeighbor1Vec, UpstreamVec, DownstreamVec)
                TorsionCst1 = 'Dihedral %s %d %s %d %s %d %s %d SCALARWEIGHTEDFUNC %f CIRCULARHARMONIC %.2f 0.5' %( UpNeighbor2Tuple[1], UpNeighbor2Tuple[2], UpNeighbor1Tuple[1], UpNeighbor1Tuple[2], UpName, UpRes, DownName, DownRes, SasaBasedWeight, Torsion1 )
                Torsion2 = PDB.calc_dihedral(UpNeighbor1Vec, UpstreamVec, DownstreamVec, DownNeighbor1Vec)
                TorsionCst2 = 'Dihedral %s %d %s %d %s %d %s %d SCALARWEIGHTEDFUNC %f CIRCULARHARMONIC %.2f 0.5' %( UpNeighbor1Tuple[1], UpNeighbor1Tuple[2], UpName, UpRes, DownName, DownRes, DownNeighbor1Tuple[1], DownNeighbor1Tuple[2], SasaBasedWeight, Torsion2 )
                Torsion3 = PDB.calc_dihedral(UpstreamVec, DownstreamVec, DownNeighbor1Vec, DownNeighbor2Vec)
                TorsionCst3 = 'Dihedral %s %d %s %d %s %d %s %d SCALARWEIGHTEDFUNC %f CIRCULARHARMONIC %.2f 0.5' %( UpName, UpRes, DownName, DownRes, DownNeighbor1Tuple[1], DownNeighbor1Tuple[2], DownNeighbor2Tuple[1], DownNeighbor2Tuple[2], SasaBasedWeight, Torsion3 )

                # adds constraint to running lists of constraints
                Constraints.extend( [DistanceCst, AngleCst1, AngleCst2, TorsionCst1, TorsionCst2, TorsionCst3] )
                if BBBB: BackboneBackboneCst.extend( [DistanceCst, AngleCst1, AngleCst2, TorsionCst1, TorsionCst2, TorsionCst3] )
                if BBSC: BackboneSidechainCst.extend( [DistanceCst, AngleCst1, AngleCst2, TorsionCst1, TorsionCst2, TorsionCst3] )
                if SCSC: SidechainSidechainCst.extend( [DistanceCst, AngleCst1, AngleCst2, TorsionCst1, TorsionCst2, TorsionCst3] )

              # else:
              #   print 'No hydrogen!'
              #   sys.exit()

        AllConstraints.extend(Constraints)
        AllBackboneBackboneCst.extend(BackboneBackboneCst)
        AllBackboneSidechainCst.extend(BackboneSidechainCst)
        AllSidechainSidechainCst.extend(SidechainSidechainCst)

    SortedConstraints = (AllBackboneBackboneCst, AllBackboneSidechainCst, AllSidechainSidechainCst)

    return AllConstraints, SortedConstraints
示例#27
0
def get_pose_constraints(Pose,
                         MaxDist,
                         MinPositionSeperation,
                         SasaRadius,
                         SasaScale,
                         UpstreamGrep,
                         DownstreamGrep,
                         NeedHydrogen=True):
    '''  '''
    # AlexsSasaCalculator is from Alex's interface_fragment_matching
    # thanks Alex!
    #
    # This is used to give buried polar contacts more weight. Thanks Alex Ford!
    try:
        from interface_fragment_matching.utility.analysis import AtomicSasaCalculator
        # make instace of Alex's sasa calculator
        AlexsSasaCalculator = AtomicSasaCalculator(probe_radius=SasaRadius)
        ResidueAtomSasa = AlexsSasaCalculator.calculate_per_atom_sasa(Pose)
    except ImportError:
        ' Error: SASA weighting of contacts requires interface_fragment_matching from Alex Ford '

    # for making full atom kd tree
    ResAtmCoordLists = []
    # for translating from kd tree index to ( residue, atom ) coord
    ResAtmRecordLists = []

    # loop through all residue numbers
    for Res in range(1, Pose.n_residue() + 1):
        # remade for each residue
        AtmRecordList = []
        AtmCoordList = []
        # loop through residue's atom numbers
        for Atm in range(1, Pose.residue(Res).natoms() + 1):
            # add (residue, atom) coord to residue's list
            AtmRecordList.append((Res, Atm))
            # add atom xyz coord to residue's list
            AtmCoordList.append(
                np.array(list(Pose.residue(Res).atom(Atm).xyz())))

        # add residue's lists to respective global lists
        ResAtmCoordLists.extend(AtmCoordList)
        ResAtmRecordLists.extend(AtmRecordList)

    ResidueAtomArray = np.array(ResAtmCoordLists)
    ResidueAtomKDTree = spatial.KDTree(ResidueAtomArray)

    ResidueAtomNeighbors = ResidueAtomKDTree.query_ball_point(
        ResidueAtomArray, MaxDist)
    # ResidueAtomNearNeighbors = ResidueAtomKDTree.query_ball_point( ResidueAtomArray, 2.0 )
    ResidueAtomHydrogens = ResidueAtomKDTree.query_ball_point(
        ResidueAtomArray, 1.1)

    # holds constraints before printing
    AllConstraints = []
    # holds sorted cst
    AllBackboneBackboneCst = []
    AllBackboneSidechainCst = []
    AllSidechainSidechainCst = []

    # All contacts are from upstream to downstream residues to avoid double counting
    Upstream = []
    for UpIndex, UpXyzCoords in enumerate(ResAtmCoordLists):
        UpRes, UpAtm = ResAtmRecordLists[UpIndex]

        # # loop through residues storing info on oxygens
        # for UpRes in range( 1, Pose.n_residue() + 1 ):
        #   # loop through atoms
        #   for UpAtm in range( 1, Pose.residue(UpRes).natoms() + 1 ):
        UpName = Pose.residue(UpRes).atom_name(UpAtm).replace(' ', '')

        # skip virtual residues
        if Pose.residue(UpRes).is_virtual(UpAtm):
            continue

        #                                this guy
        #                                 /
        # checks upstream name           V
        if re.match(UpstreamGrep, UpName):
            # print '\n'*2
            # print 'UpRes, UpName', UpRes, UpName

            # get neighbors of upstream residues
            NeighborsOfUpstream = ResidueAtomNeighbors[UpIndex]

            # prep for loop
            Downstreams = []

            Constraints = []
            BackboneBackboneCst = []
            BackboneSidechainCst = []
            SidechainSidechainCst = []

            # ArbitrayOrderOfAtomNames = {}
            for DownIndex in NeighborsOfUpstream:
                # name presumes downstream, checks with if imediately below
                DownRes, DownAtm = ResAtmRecordLists[DownIndex]

                # checks that downstream residue is dowstream of upstream and passes min primary sequence spacing
                if DownRes - UpRes >= MinPositionSeperation:
                    DownName = Pose.residue(DownRes).atom_name(
                        DownAtm).replace(' ', '')

                    # skip if same atom
                    if UpRes == DownRes:
                        if UpName == DownName:
                            continue

                    # skip virtual residues
                    if Pose.residue(DownRes).is_virtual(DownAtm):
                        continue

                    # checks downstream name
                    if re.match(DownstreamGrep, DownName):
                        # print 'DownRes, DownName', DownRes, DownName

                        PotentialUpstreamHydrogens = ResidueAtomHydrogens[
                            UpIndex]
                        UpstreamHydrogens = []
                        # print 'PotentialUpstreamHydrogens', PotentialUpstreamHydrogens
                        for UpH_I in PotentialUpstreamHydrogens:
                            UpH_Res, UpH_Atm = ResAtmRecordLists[UpH_I]
                            UpH_Name = Pose.residue(UpH_Res).atom_name(
                                UpH_Atm).replace(' ', '')
                            # print 'UpH_Name', UpH_Name
                            if 'H' in UpH_Name:
                                UpstreamHydrogens.append(
                                    (UpH_Res, UpH_Atm, UpH_Name))
                            # print 'UpstreamHydrogens', UpstreamHydrogens

                        PotentialDownstreamHydrogens = ResidueAtomHydrogens[
                            DownIndex]
                        DownstreamHydrogens = []
                        # print 'PotentialDownstreamHydrogens', PotentialDownstreamHydrogens
                        for DownH_I in PotentialDownstreamHydrogens:
                            DownH_Res, DownH_Atm = ResAtmRecordLists[DownH_I]
                            DownH_Name = Pose.residue(DownH_Res).atom_name(
                                DownH_Atm).replace(' ', '')
                            # print 'DownH_Name', DownH_Name
                            if 'H' in DownH_Name:
                                DownstreamHydrogens.append(
                                    (DownH_Res, DownH_Atm, DownH_Name))
                            # print 'DownstreamHydrogens', DownstreamHydrogens

                        # check their is at least one hydrogen in system before adding constraint
                        if len(UpstreamHydrogens) or len(
                                DownstreamHydrogens) or NeedHydrogen == False:

                            # these trys / excepts seperate
                            # backbone-backbone from
                            # backbone-sidechain from
                            # sidechain-sidechain interactions
                            #
                            # in future maybe sort into seperate lists, shouldn't rely on ResidueAtomSasa to know what is in backbone
                            try:
                                UpstreamSasa = ResidueAtomSasa[UpRes][UpName]
                                DownstreamSasa = ResidueAtomSasa[DownRes][
                                    DownName]
                                AverageSasa = np.mean(
                                    [UpstreamSasa, DownstreamSasa])
                                BBBB = 1
                                BBSC = SCSC = 0
                            except KeyError:
                                # These lines handle backbone to sidechain interactions
                                # set weight equal to the most buried
                                try:
                                    UpstreamSasa = ResidueAtomSasa[UpRes][
                                        UpName]
                                    AverageSasa = SasaScale.FloorSasa
                                    BBSC = 1
                                    BBBB = SCSC = 0
                                except KeyError:
                                    try:
                                        DownstreamSasa = ResidueAtomSasa[
                                            DownRes][DownName]
                                        AverageSasa = SasaScale.FloorSasa
                                        BBSC = 1
                                        BBBB = SCSC = 0

                                    # set weight of side chain side chain equal to the most buried
                                    except KeyError:
                                        AverageSasa = SasaScale.CeilingSasa
                                        SCSC = 1
                                        BBSC = BBBB = 0

                            # use instance of sasa_scale to calculate weight based on avg sasa of N and O
                            SasaBasedWeight = SasaScale.weigh(AverageSasa)
                            # print
                            # print 'AverageSasa', AverageSasa
                            # print 'SasaBasedWeight', SasaBasedWeight

                            # print 'found downstream neighbor %s'%DownName
                            DownXyzCoords = np.array(
                                list(
                                    Pose.residue(DownRes).atom(DownAtm).xyz()))
                            # print 'DownRes, DownName', DownRes, DownName
                            # print 'DownXyzCoords', DownXyzCoords

                            # ## Get neighbors for angles and torsions to use with AtomPairs

                            SelectUpNeighbors = []
                            # iterates through upstream atom neighbors for references for angle
                            for UpNeighborIndex in NeighborsOfUpstream:
                                UpNeighborRes, UpNeighborAtm = ResAtmRecordLists[
                                    UpNeighborIndex]
                                UpNeighborName = Pose.residue(
                                    UpNeighborRes).atom_name(
                                        UpNeighborAtm).replace(' ', '')

                                # keep looking if neighbor is hyrdogen
                                if 'H' in UpNeighborName:
                                    continue

                                # skip virtual residues
                                if Pose.residue(UpNeighborRes).is_virtual(
                                        UpNeighborAtm):
                                    continue

                                # keep looking if neighbor is self
                                if UpNeighborName == UpName and UpNeighborRes == UpRes:
                                    continue
                                # keep looking if neighbor is downstream residue again
                                if UpNeighborName == DownName and UpNeighborRes == DownRes:
                                    continue
                                UpNeighborCoords = ResAtmCoordLists[
                                    UpNeighborIndex]
                                DistanceToNeighbor = solenoid_tools.vector_magnitude(
                                    UpXyzCoords - UpNeighborCoords)
                                SelectUpNeighbors.append(
                                    (DistanceToNeighbor, UpNeighborName,
                                     UpNeighborRes, UpNeighborCoords))

                            # sort by distance to atom, nearest first
                            SelectUpNeighbors.sort()
                            UpNeighbor1Tuple = SelectUpNeighbors[0]
                            UpNeighbor2Tuple = SelectUpNeighbors[1]
                            # print '\n'*2
                            # print 'UpRes, UpName', UpRes, UpName
                            # print 'UpstreamHydrogens', UpstreamHydrogens
                            # print 'SelectUpNeighbors', SelectUpNeighbors

                            # get neighbors of upstream residues
                            NeighborsOfDownstream = ResidueAtomNeighbors[
                                DownIndex]
                            SelectDownNeighbors = []
                            # iterates through upstream atom neighbors for references for angle
                            for DownNeighborIndex in NeighborsOfDownstream:
                                DownNeighborRes, DownNeighborAtm = ResAtmRecordLists[
                                    DownNeighborIndex]
                                DownNeighborName = Pose.residue(
                                    DownNeighborRes).atom_name(
                                        DownNeighborAtm).replace(' ', '')

                                # keep looking if neighbor is hyrdogen
                                if 'H' in DownNeighborName:
                                    continue

                                # skip virtual residues
                                if Pose.residue(DownNeighborRes).is_virtual(
                                        DownNeighborAtm):
                                    continue

                                # keep looking if neighbor is self
                                if DownNeighborName == DownName and DownNeighborRes == DownRes:
                                    continue
                                # keep looking if neighbor is upstream residue
                                if DownNeighborName == UpName and DownNeighborRes == UpRes:
                                    continue

                                DownNeighborCoords = ResAtmCoordLists[
                                    DownNeighborIndex]
                                DistanceToNeighbor = solenoid_tools.vector_magnitude(
                                    DownXyzCoords - DownNeighborCoords)
                                SelectDownNeighbors.append(
                                    (DistanceToNeighbor, DownNeighborName,
                                     DownNeighborRes, DownNeighborCoords))

                            # sort by distance to atom, nearest first
                            SelectDownNeighbors.sort()
                            DownNeighbor1Tuple = SelectDownNeighbors[0]
                            DownNeighbor2Tuple = SelectDownNeighbors[1]
                            # print 'DownRes, DownName', DownRes, DownName
                            # print 'DownstreamHydrogens', DownstreamHydrogens
                            # print 'SelectDownNeighbors', SelectDownNeighbors

                            Distance = solenoid_tools.vector_magnitude(
                                DownXyzCoords - UpXyzCoords)

                            DistanceCst = 'AtomPair %s %d %s %d SCALARWEIGHTEDFUNC %f HARMONIC %.2f 1.0' % (
                                UpName, UpRes, DownName, DownRes,
                                SasaBasedWeight, Distance)

                            # Use Biopython for angle and dihedral calculations
                            # here 'Vec' means PDB.Vector of atom's xyz coord
                            UpstreamVec = PDB.Vector(UpXyzCoords)
                            DownstreamVec = PDB.Vector(DownXyzCoords)

                            UpNeighbor1Vec = PDB.Vector(UpNeighbor1Tuple[3])
                            UpNeighbor2Vec = PDB.Vector(UpNeighbor2Tuple[3])
                            DownNeighbor1Vec = PDB.Vector(
                                DownNeighbor1Tuple[3])
                            DownNeighbor2Vec = PDB.Vector(
                                DownNeighbor2Tuple[3])

                            Angle1 = PDB.calc_angle(UpNeighbor1Vec,
                                                    UpstreamVec, DownstreamVec)
                            AngleCst1 = 'Angle %s %d %s %d %s %d SCALARWEIGHTEDFUNC %f CIRCULARHARMONIC %.2f 0.5' % (
                                UpNeighbor1Tuple[1], UpNeighbor1Tuple[2],
                                UpName, UpRes, DownName, DownRes,
                                SasaBasedWeight, Angle1)
                            Angle2 = PDB.calc_angle(UpstreamVec, DownstreamVec,
                                                    DownNeighbor1Vec)
                            AngleCst2 = 'Angle %s %d %s %d %s %d SCALARWEIGHTEDFUNC %f CIRCULARHARMONIC %.2f 0.5' % (
                                UpName, UpRes, DownName, DownRes,
                                DownNeighbor1Tuple[1], DownNeighbor1Tuple[2],
                                SasaBasedWeight, Angle2)

                            Torsion1 = PDB.calc_dihedral(
                                UpNeighbor2Vec, UpNeighbor1Vec, UpstreamVec,
                                DownstreamVec)
                            TorsionCst1 = 'Dihedral %s %d %s %d %s %d %s %d SCALARWEIGHTEDFUNC %f CIRCULARHARMONIC %.2f 0.5' % (
                                UpNeighbor2Tuple[1], UpNeighbor2Tuple[2],
                                UpNeighbor1Tuple[1], UpNeighbor1Tuple[2],
                                UpName, UpRes, DownName, DownRes,
                                SasaBasedWeight, Torsion1)
                            Torsion2 = PDB.calc_dihedral(
                                UpNeighbor1Vec, UpstreamVec, DownstreamVec,
                                DownNeighbor1Vec)
                            TorsionCst2 = 'Dihedral %s %d %s %d %s %d %s %d SCALARWEIGHTEDFUNC %f CIRCULARHARMONIC %.2f 0.5' % (
                                UpNeighbor1Tuple[1], UpNeighbor1Tuple[2],
                                UpName, UpRes, DownName, DownRes,
                                DownNeighbor1Tuple[1], DownNeighbor1Tuple[2],
                                SasaBasedWeight, Torsion2)
                            Torsion3 = PDB.calc_dihedral(
                                UpstreamVec, DownstreamVec, DownNeighbor1Vec,
                                DownNeighbor2Vec)
                            TorsionCst3 = 'Dihedral %s %d %s %d %s %d %s %d SCALARWEIGHTEDFUNC %f CIRCULARHARMONIC %.2f 0.5' % (
                                UpName, UpRes, DownName, DownRes,
                                DownNeighbor1Tuple[1], DownNeighbor1Tuple[2],
                                DownNeighbor2Tuple[1], DownNeighbor2Tuple[2],
                                SasaBasedWeight, Torsion3)

                            # adds constraint to running lists of constraints
                            Constraints.extend([
                                DistanceCst, AngleCst1, AngleCst2, TorsionCst1,
                                TorsionCst2, TorsionCst3
                            ])
                            if BBBB:
                                BackboneBackboneCst.extend([
                                    DistanceCst, AngleCst1, AngleCst2,
                                    TorsionCst1, TorsionCst2, TorsionCst3
                                ])
                            if BBSC:
                                BackboneSidechainCst.extend([
                                    DistanceCst, AngleCst1, AngleCst2,
                                    TorsionCst1, TorsionCst2, TorsionCst3
                                ])
                            if SCSC:
                                SidechainSidechainCst.extend([
                                    DistanceCst, AngleCst1, AngleCst2,
                                    TorsionCst1, TorsionCst2, TorsionCst3
                                ])

                        # else:
                        #   print 'No hydrogen!'
                        #   sys.exit()

            AllConstraints.extend(Constraints)
            AllBackboneBackboneCst.extend(BackboneBackboneCst)
            AllBackboneSidechainCst.extend(BackboneSidechainCst)
            AllSidechainSidechainCst.extend(SidechainSidechainCst)

    SortedConstraints = (AllBackboneBackboneCst, AllBackboneSidechainCst,
                         AllSidechainSidechainCst)

    return AllConstraints, SortedConstraints
示例#28
0
 def calculate_torsion_phi(previous_residue, current_residue):
     atom1 = previous_residue['C'].get_vector()
     atom2 = current_residue['N'].get_vector()
     atom3 = current_residue['CA'].get_vector()
     atom4 = current_residue['C'].get_vector()
     return PDB.calc_dihedral(atom1, atom2, atom3, atom4)