def test_angle_between_three(self):
     """
 TestPoint: Test that the angle between three points is computed.
 """
     assert angle_between_three_points(
         Point(coords=np.array([1, 0, 0])),
         Point(coords=np.array([0, 0, 0])),
         Point(coords=np.array([0, 0, 1]))) == np.pi / 2
 def test_angle_between_three(self):
     """
 TestPoint: Test that the angle between three points is computed.
 """
     assert (
         angle_between_three_points(
             Point(coords=np.array([1, 0, 0])), Point(coords=np.array([0, 0, 0])), Point(coords=np.array([0, 0, 1]))
         )
         == np.pi / 2
     )
Exemple #3
0
def compute_hydrogen_bonds(ligand, receptor):
    """
  Computes hydrogen bonds between ligand and receptor.

  Returns a dictionary whose keys are of form
  HDONOR-${MOLTYPE}_${RESIDUETYPE}_${STRUCTURE} where MOLTYPE is either
  "RECEPTOR" or "LIGAND", RESIDUETYPE is "BACKBONE" or "SIDECHAIN" and
  where STRUCTURE is "ALPHA" or "BETA" or "OTHER". The values are counts
  of the numbers of hydrogen bonds associated with the given keys.

  Parameters
  ----------
  ligand: PDB
    A PDB Object describing the ligand molecule.
  receptor: PDB
    A PDB object describing the receptor protein.
  """
    hbonds = {
        'HDONOR-LIGAND_BACKBONE_ALPHA': 0,
        'HDONOR-LIGAND_BACKBONE_BETA': 0,
        'HDONOR-LIGAND_BACKBONE_OTHER': 0,
        'HDONOR-LIGAND_SIDECHAIN_ALPHA': 0,
        'HDONOR-LIGAND_SIDECHAIN_BETA': 0,
        'HDONOR-LIGAND_SIDECHAIN_OTHER': 0,
        'HDONOR-RECEPTOR_BACKBONE_ALPHA': 0,
        'HDONOR-RECEPTOR_BACKBONE_BETA': 0,
        'HDONOR-RECEPTOR_BACKBONE_OTHER': 0,
        'HDONOR-RECEPTOR_SIDECHAIN_ALPHA': 0,
        'HDONOR-RECEPTOR_SIDECHAIN_BETA': 0,
        'HDONOR-RECEPTOR_SIDECHAIN_OTHER': 0
    }
    for ligand_index in ligand.all_atoms:
        ligand_atom = ligand.all_atoms[ligand_index]
        for receptor_index in receptor.all_atoms:
            receptor_atom = receptor.all_atoms[receptor_index]
            # Now see if there's some sort of hydrogen bond between
            # these two atoms. distance cutoff = H_BOND_DIST, angle cutoff =
            # H_BOND_ANGLE.
            dist = ligand_atom.coordinates.dist_to(receptor_atom.coordinates)
            if dist < CONTACT_CUTOFF:
                electronegative_atoms = ["O", "N", "F"]
                if ((ligand_atom.element in electronegative_atoms)
                        and (receptor_atom.element in electronegative_atoms)):

                    hydrogens = []
                    # TODO(rbharath): This is a horrible inner-loop search. Can
                    # this be made more efficient?
                    for atm_index in ligand.all_atoms:
                        atom = ligand.all_atoms[atm_index]
                        if atom.element == "H":
                            # Make sure to set comment (used below)
                            atom.comment = "LIGAND"
                            if (atom.coordinates.dist_to(
                                    ligand_atom.coordinates) < H_BOND_DIST):
                                hydrogens.append(atom)

                    for atm_index in receptor.all_atoms:
                        atom = receptor.all_atoms[atm_index]
                        if atom.element == "H":
                            # Make sure to set comment (used below)
                            atom.comment = "RECEPTOR"
                            if (atom.coordinates.dist_to(
                                    receptor_atom.coordinates) < H_BOND_DIST):
                                hydrogens.append(atom)

                    #print "nearby hydrogens: " + str(hydrogens)
                    # now we need to check the angles
                    # TODO(rbharath): Rather than using this heuristic, it seems like
                    # it might be better to just report the angle in the feature
                    # vector...
                    for hydrogen in hydrogens:
                        angle = math.fabs(180 - angle_between_three_points(
                            ligand_atom.coordinates, hydrogen.coordinates,
                            receptor_atom.coordinates) * 180.0 / math.pi)
                        if (angle <= H_BOND_ANGLE):
                            hbonds_key = (
                                "HDONOR-" + hydrogen.comment + "_" +
                                receptor_atom.side_chain_or_backbone() + "_" +
                                receptor_atom.structure)
                            hashtable_entry_add_one(hbonds, hbonds_key)
    return hbonds
def compute_hydrogen_bonds(ligand, receptor):
  """
  Computes hydrogen bonds between ligand and receptor.

  Returns a dictionary whose keys are of form
  HDONOR-${MOLTYPE}_${RESIDUETYPE}_${STRUCTURE} where MOLTYPE is either
  "RECEPTOR" or "LIGAND", RESIDUETYPE is "BACKBONE" or "SIDECHAIN" and
  where STRUCTURE is "ALPHA" or "BETA" or "OTHER". The values are counts
  of the numbers of hydrogen bonds associated with the given keys.

  Parameters
  ----------
  ligand: PDB
    A PDB Object describing the ligand molecule.
  receptor: PDB
    A PDB object describing the receptor protein.
  """
  hbonds = {
    'HDONOR-LIGAND_BACKBONE_ALPHA': 0,
    'HDONOR-LIGAND_BACKBONE_BETA': 0,
    'HDONOR-LIGAND_BACKBONE_OTHER': 0,
    'HDONOR-LIGAND_SIDECHAIN_ALPHA': 0,
    'HDONOR-LIGAND_SIDECHAIN_BETA': 0,
    'HDONOR-LIGAND_SIDECHAIN_OTHER': 0,
    'HDONOR-RECEPTOR_BACKBONE_ALPHA': 0,
    'HDONOR-RECEPTOR_BACKBONE_BETA': 0,
    'HDONOR-RECEPTOR_BACKBONE_OTHER': 0,
    'HDONOR-RECEPTOR_SIDECHAIN_ALPHA': 0,
    'HDONOR-RECEPTOR_SIDECHAIN_BETA': 0,
    'HDONOR-RECEPTOR_SIDECHAIN_OTHER': 0}
  for ligand_index in ligand.all_atoms:
    ligand_atom = ligand.all_atoms[ligand_index]
    for receptor_index in receptor.all_atoms:
      receptor_atom = receptor.all_atoms[receptor_index]
      # Now see if there's some sort of hydrogen bond between
      # these two atoms. distance cutoff = H_BOND_DIST, angle cutoff =
      # H_BOND_ANGLE.
      dist = ligand_atom.coordinates.dist_to(receptor_atom.coordinates)
      if dist < CONTACT_CUTOFF:
        electronegative_atoms = ["O", "N", "F"]
        if ((ligand_atom.element in electronegative_atoms)
          and (receptor_atom.element in electronegative_atoms)):

          hydrogens = []
          # TODO(rbharath): This is a horrible inner-loop search. Can
          # this be made more efficient?
          for atm_index in ligand.all_atoms:
            atom = ligand.all_atoms[atm_index]
            if atom.element == "H":
              # Make sure to set comment (used below) 
              atom.comment = "LIGAND"
              if (atom.coordinates.dist_to(ligand_atom.coordinates)
                    < H_BOND_DIST):
                hydrogens.append(atom)

          for atm_index in receptor.all_atoms:
            atom = receptor.all_atoms[atm_index]
            if atom.element == "H":
              # Make sure to set comment (used below) 
              atom.comment = "RECEPTOR"
              if (atom.coordinates.dist_to(receptor_atom.coordinates)
                  < H_BOND_DIST):
                hydrogens.append(atom)

          #print "nearby hydrogens: " + str(hydrogens)
          # now we need to check the angles
          # TODO(rbharath): Rather than using this heuristic, it seems like
          # it might be better to just report the angle in the feature
          # vector... 
          for hydrogen in hydrogens:
            angle = math.fabs(180 - angle_between_three_points(
              ligand_atom.coordinates, hydrogen.coordinates,
              receptor_atom.coordinates) * 180.0 / math.pi)
            if (angle <= H_BOND_ANGLE):
              hbonds_key = ("HDONOR-" + hydrogen.comment + "_" +
                  receptor_atom.side_chain_or_backbone() + "_" +
                  receptor_atom.structure)
              hashtable_entry_add_one(hbonds, hbonds_key)
  return hbonds