Example #1
0
def compute_pi_cation(ligand, receptor):
  """
  Computes number of pi-cation interactions.

  Returns a dictionary whose keys are of form
  ${MOLTYPE}-CHARGED_${STRUCTURE} where MOLTYPE is either "LIGAND" or
  "RECEPTOR" and STRUCTURE is "ALPHA" or "BETA" or "OTHER".

  Parameters
  ----------
  ligand: PDB Object
    small molecule to dock.
  receptor: PDB Object
    protein to dock agains.
  """
  pi_cation = {
    'PI-CATION_LIGAND-CHARGED_ALPHA': 0,
    'PI-CATION_LIGAND-CHARGED_BETA': 0,
    'PI-CATION_LIGAND-CHARGED_OTHER': 0,
    'PI-CATION_RECEPTOR-CHARGED_ALPHA': 0,
    'PI-CATION_RECEPTOR-CHARGED_BETA': 0,
    'PI-CATION_RECEPTOR-CHARGED_OTHER': 0}
  for aromatic in receptor.aromatic_rings:
    for charged in ligand.charges:
      if charged.positive == True: # so only consider positive charges
        if (charged.coordinates.dist_to(aromatic.center) < CATION_PI_CUTOFF):

          # project the charged onto the plane of the aromatic
          charge_projected = project_point_onto_plane(
              charged.coordinates,aromatic.plane_coeff)
          if (charge_projected.dist_to(aromatic.center)
            < aromatic.radius + PI_PADDING):
            structure = receptor.all_atoms[aromatic.indices[0]].structure
            if structure == "":
              # since it could be interacting with a cofactor or something
              structure = "OTHER"
            key = "PI-CATION_LIGAND-CHARGED_" + structure

            hashtable_entry_add_one(pi_cation, key)

  for aromatic in ligand.aromatic_rings:
    # now it's the ligand that has the aromatic group
    for charged in receptor.charges:
      if charged.positive == True: # so only consider positive charges
        if (charged.coordinates.dist_to(aromatic.center) < CATION_PI_CUTOFF):
          charge_projected = project_point_onto_plane(
              charged.coordinates,aromatic.plane_coeff)
          if (charge_projected.dist_to(aromatic.center)
              < aromatic.radius + PI_PADDING):
            structure = receptor.all_atoms[charged.indices[0]].structure
            if structure == "":
              # since it could be interacting with a cofactor or something
              structure = "OTHER"
            key = "PI-CATION_RECEPTOR-CHARGED_" + structure

            hashtable_entry_add_one(pi_cation, key)
  return pi_cation
Example #2
0
def compute_pi_cation(ligand, receptor):
  """
  Computes number of pi-cation interactions.

  Returns a dictionary whose keys are of form
  ${MOLTYPE}-CHARGED_${STRUCTURE} where MOLTYPE is either "LIGAND" or
  "RECEPTOR" and STRUCTURE is "ALPHA" or "BETA" or "OTHER".

  Parameters
  ----------
  ligand: PDB Object
    small molecule to dock.
  receptor: PDB Object
    protein to dock agains.
  """
  pi_cation = {
      'PI-CATION_LIGAND-CHARGED_ALPHA': 0,
      'PI-CATION_LIGAND-CHARGED_BETA': 0,
      'PI-CATION_LIGAND-CHARGED_OTHER': 0,
      'PI-CATION_RECEPTOR-CHARGED_ALPHA': 0,
      'PI-CATION_RECEPTOR-CHARGED_BETA': 0,
      'PI-CATION_RECEPTOR-CHARGED_OTHER': 0}
  for aromatic in receptor.aromatic_rings:
    for charged in ligand.charges:
      if charged.positive == True: # so only consider positive charges
        if charged.coordinates.dist_to(aromatic.center) < CATION_PI_CUTOFF:

          # project the charged onto the plane of the aromatic
          charge_projected = project_point_onto_plane(
              charged.coordinates, aromatic.plane_coeff)
          if (charge_projected.dist_to(aromatic.center)
              < aromatic.radius + PI_PADDING):
            structure = receptor.all_atoms[aromatic.indices[0]].structure
            if structure == "":
              # since it could be interacting with a cofactor or something
              structure = "OTHER"
            key = "PI-CATION_LIGAND-CHARGED_" + structure

            hashtable_entry_add_one(pi_cation, key)

  for aromatic in ligand.aromatic_rings:
    # now it's the ligand that has the aromatic group
    for charged in receptor.charges:
      if charged.positive: # so only consider positive charges
        if charged.coordinates.dist_to(aromatic.center) < CATION_PI_CUTOFF:
          charge_projected = project_point_onto_plane(
              charged.coordinates, aromatic.plane_coeff)
          if (charge_projected.dist_to(aromatic.center)
              < aromatic.radius + PI_PADDING):
            structure = receptor.all_atoms[charged.indices[0]].structure
            if structure == "":
              # since it could be interacting with a cofactor or something
              structure = "OTHER"
            key = "PI-CATION_RECEPTOR-CHARGED_" + structure

            hashtable_entry_add_one(pi_cation, key)
  return pi_cation
    def test_project_point(self):
        """
    TestPoint: Test that projection onto plane works.
    """
        # First test with projection onto xy-plane
        value = project_point_onto_plane(Point(coords=np.array([1, 2, 3])), [0, 0, 1, 0])
        assert np.array_equal(value.as_array(), np.array([1, 2, 0]))

        # Now test projection onto plane z = 4
        value = project_point_onto_plane(Point(coords=np.array([1, 2, 3])), [0, 0, 1, 4])
        assert np.array_equal(value.as_array(), np.array([1, 2, 4]))
    def test_project_point(self):
        """
    TestPoint: Test that projection onto plane works.
    """
        # First test with projection onto xy-plane
        value = project_point_onto_plane(Point(coords=np.array([1, 2, 3])),
                                         [0, 0, 1, 0])
        assert np.array_equal(value.as_array(), np.array([1, 2, 0]))

        # Now test projection onto plane z = 4
        value = project_point_onto_plane(Point(coords=np.array([1, 2, 3])),
                                         [0, 0, 1, 4])
        assert np.array_equal(value.as_array(), np.array([1, 2, 4]))
Example #5
0
def compute_pi_pi_stacking(ligand, receptor):
    """
  Computes pi-pi interactions.

  Returns a dictionary with keys of form STACKING_${STRUCTURE} where
  STRUCTURE is "ALPHA" or "BETA" or "OTHER". Values are counts of the
  number of such stacking interactions.

  Parameters
  ----------
  ligand: PDB Object.
    small molecule to dock.
  receptor: PDB Object
    protein to dock agains.
  """
    pi_stacking = {
        'STACKING_ALPHA': 0,
        'STACKING_BETA': 0,
        'STACKING_OTHER': 0
    }
    for lig_aromatic in ligand.aromatic_rings:
        for rec_aromatic in receptor.aromatic_rings:
            dist = lig_aromatic.center.dist_to(rec_aromatic.center)
            if dist < PI_PI_CUTOFF:
                # so there could be some pi-pi interactions.  Now, let's
                # check for stacking interactions. Are the two pi's roughly
                # parallel?
                lig_aromatic_norm_vector = Point(coords=np.array([
                    lig_aromatic.plane_coeff[0], lig_aromatic.plane_coeff[1],
                    lig_aromatic.plane_coeff[2]
                ]))
                rec_aromatic_norm_vector = Point(coords=np.array([
                    rec_aromatic.plane_coeff[0], rec_aromatic.plane_coeff[1],
                    rec_aromatic.plane_coeff[2]
                ]))
                angle_between_planes = (angle_between_points(
                    lig_aromatic_norm_vector, rec_aromatic_norm_vector) *
                                        180.0 / math.pi)

                if (math.fabs(angle_between_planes - 0) < 30.0
                        or math.fabs(angle_between_planes - 180) < 30.0):
                    # so they're more or less parallel, it's probably pi-pi
                    # stacking now, since pi-pi are not usually right on
                    # top of each other. They're often staggered. So I don't
                    # want to just look at the centers of the rings and
                    # compare. Let's look at each of the atoms.  do atom of
                    # the atoms of one ring, when projected onto the plane of
                    # the other, fall within that other ring?

                    # start by assuming it's not a pi-pi stacking interaction
                    pi_pi = False
                    for ligand_ring_index in lig_aromatic.indices:
                        # project the ligand atom onto the plane of the receptor ring
                        pt_on_receptor_plane = project_point_onto_plane(
                            ligand.all_atoms[ligand_ring_index].coordinates,
                            rec_aromatic.plane_coeff)
                        if (pt_on_receptor_plane.dist_to(rec_aromatic.center)
                                <= rec_aromatic.radius + PI_PADDING):
                            pi_pi = True
                            break

                    # TODO(rbharath): This if-else is confusing.
                    if pi_pi == False:
                        for receptor_ring_index in rec_aromatic.indices:
                            # project the ligand atom onto the plane of the receptor ring
                            pt_on_ligand_plane = project_point_onto_plane(
                                receptor.all_atoms[receptor_ring_index].
                                coordinates, lig_aromatic.plane_coeff)
                            if (pt_on_ligand_plane.dist_to(lig_aromatic.center)
                                    <= lig_aromatic.radius + PI_PADDING):
                                pi_pi = True
                                break

                    if pi_pi == True:
                        structure = receptor.all_atoms[
                            rec_aromatic.indices[0]].structure
                        if structure == "":
                            # since it could be interacting with a cofactor or something
                            structure = "OTHER"
                        key = "STACKING_" + structure
                        hashtable_entry_add_one(pi_stacking, key)
    return pi_stacking
Example #6
0
def compute_pi_t(ligand, receptor):
    """
  Computes T-shaped pi-pi interactions.

  Returns a dictionary with keys of form T-SHAPED_${STRUCTURE} where
  STRUCTURE is "ALPHA" or "BETA" or "OTHER". Values are counts of the
  number of such stacking interactions.

  Parameters
  ----------
  ligand: PDB Object.
    small molecule to dock.
  receptor: PDB Object
    protein to dock agains.
  """
    pi_t = {'T-SHAPED_ALPHA': 0, 'T-SHAPED_BETA': 0, 'T-SHAPED_OTHER': 0}
    for lig_aromatic in ligand.aromatic_rings:
        for rec_aromatic in receptor.aromatic_rings:
            lig_aromatic_norm_vector = Point(coords=np.array([
                lig_aromatic.plane_coeff[0], lig_aromatic.plane_coeff[1],
                lig_aromatic.plane_coeff[2]
            ]))
            rec_aromatic_norm_vector = Point(coords=np.array([
                rec_aromatic.plane_coeff[0], rec_aromatic.plane_coeff[1],
                rec_aromatic.plane_coeff[2]
            ]))
            angle_between_planes = (angle_between_points(
                lig_aromatic_norm_vector, rec_aromatic_norm_vector) * 180.0 /
                                    math.pi)
            if (math.fabs(angle_between_planes - 90) < 30.0
                    or math.fabs(angle_between_planes - 270) < 30.0):
                # so they're more or less perpendicular, it's probably a
                # pi-edge interaction having looked at many structures, I
                # noticed the algorithm was identifying T-pi reactions
                # when the two rings were in fact quite distant, often
                # with other atoms in between. Eye-balling it, requiring
                # that at their closest they be at least 5 A apart seems
                # to separate the good T's from the bad
                min_dist = 100.0
                for ligand_ind in lig_aromatic.indices:
                    ligand_at = ligand.all_atoms[ligand_ind]
                    for receptor_ind in rec_aromatic.indices:
                        receptor_at = receptor.all_atoms[receptor_ind]
                        dist = ligand_at.coordinates.dist_to(
                            receptor_at.coordinates)
                        if dist < min_dist:
                            min_dist = dist

                if min_dist <= 5.0:
                    # so at their closest points, the two rings come within
                    # 5 A of each other.

                    # okay, is the ligand pi pointing into the receptor
                    # pi, or the other way around?  first, project the
                    # center of the ligand pi onto the plane of the
                    # receptor pi, and vs. versa

                    # This could be directional somehow, like a hydrogen
                    # bond.

                    pt_on_receptor_plane = project_point_onto_plane(
                        lig_aromatic.center, rec_aromatic.plane_coeff)
                    pt_on_ligand_plane = project_point_onto_plane(
                        rec_aromatic.center, lig_aromatic.plane_coeff)

                    # now, if it's a true pi-T interaction, this projected
                    # point should fall within the ring whose plane it's
                    # been projected into.
                    if ((pt_on_receptor_plane.dist_to(rec_aromatic.center) <=
                         rec_aromatic.radius + PI_PADDING)
                            or (pt_on_ligand_plane.dist_to(lig_aromatic.center)
                                <= lig_aromatic.radius + PI_PADDING)):

                        # so it is in the ring on the projected plane.
                        structure = receptor.all_atoms[
                            rec_aromatic.indices[0]].structure
                        if structure == "":
                            # since it could be interacting with a cofactor or something
                            structure = "OTHER"
                        key = "T-SHAPED_" + structure

                        hashtable_entry_add_one(pi_t, key)
    return pi_t
Example #7
0
def compute_pi_pi_stacking(ligand, receptor):
  """
  Computes pi-pi interactions.

  Returns a dictionary with keys of form STACKING_${STRUCTURE} where
  STRUCTURE is "ALPHA" or "BETA" or "OTHER". Values are counts of the
  number of such stacking interactions.

  Parameters
  ----------
  ligand: PDB Object.
    small molecule to dock.
  receptor: PDB Object
    protein to dock agains.
  """
  pi_stacking = {'STACKING_ALPHA': 0, 'STACKING_BETA': 0, 'STACKING_OTHER': 0}
  for lig_aromatic in ligand.aromatic_rings:
    for rec_aromatic in receptor.aromatic_rings:
      dist = lig_aromatic.center.dist_to(rec_aromatic.center)
      if dist < PI_PI_CUTOFF:
        # so there could be some pi-pi interactions.  Now, let's
        # check for stacking interactions. Are the two pi's roughly
        # parallel?
        lig_aromatic_norm_vector = Point(
            coords=np.array([lig_aromatic.plane_coeff[0],
                             lig_aromatic.plane_coeff[1],
                             lig_aromatic.plane_coeff[2]]))
        rec_aromatic_norm_vector = Point(
            coords=np.array([rec_aromatic.plane_coeff[0],
                             rec_aromatic.plane_coeff[1],
                             rec_aromatic.plane_coeff[2]]))
        angle_between_planes = (angle_between_points(
            lig_aromatic_norm_vector, rec_aromatic_norm_vector)
            * 180.0/math.pi)

        if (math.fabs(angle_between_planes-0) < 30.0
            or math.fabs(angle_between_planes-180) < 30.0):
          # so they're more or less parallel, it's probably pi-pi
          # stacking now, since pi-pi are not usually right on
          # top of each other. They're often staggered. So I don't
          # want to just look at the centers of the rings and
          # compare. Let's look at each of the atoms.  do atom of
          # the atoms of one ring, when projected onto the plane of
          # the other, fall within that other ring?

          # start by assuming it's not a pi-pi stacking interaction
          pi_pi = False
          for ligand_ring_index in lig_aromatic.indices:
            # project the ligand atom onto the plane of the receptor ring
            pt_on_receptor_plane = project_point_onto_plane(
                ligand.all_atoms[ligand_ring_index].coordinates,
                rec_aromatic.plane_coeff)
            if (pt_on_receptor_plane.dist_to(rec_aromatic.center)
               <= rec_aromatic.radius + PI_PADDING):
              pi_pi = True
              break

          # TODO(rbharath): This if-else is confusing.
          if pi_pi == False:
            for receptor_ring_index in rec_aromatic.indices:
              # project the ligand atom onto the plane of the receptor ring
              pt_on_ligand_plane = project_point_onto_plane(
                  receptor.all_atoms[receptor_ring_index].coordinates,
                  lig_aromatic.plane_coeff)
              if (pt_on_ligand_plane.dist_to(lig_aromatic.center)
                  <= lig_aromatic.radius + PI_PADDING):
                pi_pi = True
                break

          if pi_pi == True:
            structure = receptor.all_atoms[rec_aromatic.indices[0]].structure
            if structure == "":
              # since it could be interacting with a cofactor or something
              structure = "OTHER"
            key = "STACKING_" + structure
            hashtable_entry_add_one(pi_stacking, key)
  return pi_stacking
Example #8
0
def compute_pi_t(ligand, receptor):
  """
  Computes T-shaped pi-pi interactions.

  Returns a dictionary with keys of form T-SHAPED_${STRUCTURE} where
  STRUCTURE is "ALPHA" or "BETA" or "OTHER". Values are counts of the
  number of such stacking interactions.

  Parameters
  ----------
  ligand: PDB Object.
    small molecule to dock.
  receptor: PDB Object
    protein to dock agains.
  """
  pi_t = {'T-SHAPED_ALPHA': 0, 'T-SHAPED_BETA': 0, 'T-SHAPED_OTHER': 0}
  for lig_aromatic in ligand.aromatic_rings:
    for rec_aromatic in receptor.aromatic_rings:
      lig_aromatic_norm_vector = Point(
          coords=np.array([lig_aromatic.plane_coeff[0],
                           lig_aromatic.plane_coeff[1],
                           lig_aromatic.plane_coeff[2]]))
      rec_aromatic_norm_vector = Point(
          coords=np.array([rec_aromatic.plane_coeff[0],
                           rec_aromatic.plane_coeff[1],
                           rec_aromatic.plane_coeff[2]]))
      angle_between_planes = (angle_between_points(
          lig_aromatic_norm_vector, rec_aromatic_norm_vector)
          * 180.0/math.pi)
      if (math.fabs(angle_between_planes-90) < 30.0
          or math.fabs(angle_between_planes-270) < 30.0):
        # so they're more or less perpendicular, it's probably a
        # pi-edge interaction having looked at many structures, I
        # noticed the algorithm was identifying T-pi reactions
        # when the two rings were in fact quite distant, often
        # with other atoms in between. Eye-balling it, requiring
        # that at their closest they be at least 5 A apart seems
        # to separate the good T's from the bad
        min_dist = 100.0
        for ligand_ind in lig_aromatic.indices:
          ligand_at = ligand.all_atoms[ligand_ind]
          for receptor_ind in rec_aromatic.indices:
            receptor_at = receptor.all_atoms[receptor_ind]
            dist = ligand_at.coordinates.dist_to(receptor_at.coordinates)
            if dist < min_dist:
              min_dist = dist

        if min_dist <= 5.0:
          # so at their closest points, the two rings come within
          # 5 A of each other.

          # okay, is the ligand pi pointing into the receptor
          # pi, or the other way around?  first, project the
          # center of the ligand pi onto the plane of the
          # receptor pi, and vs. versa

          # This could be directional somehow, like a hydrogen
          # bond.

          pt_on_receptor_plane = project_point_onto_plane(
              lig_aromatic.center, rec_aromatic.plane_coeff)
          pt_on_ligand_plane = project_point_onto_plane(
              rec_aromatic.center, lig_aromatic.plane_coeff)

          # now, if it's a true pi-T interaction, this projected
          # point should fall within the ring whose plane it's
          # been projected into.
          if ((pt_on_receptor_plane.dist_to(rec_aromatic.center)
            <= rec_aromatic.radius + PI_PADDING)
            or (pt_on_ligand_plane.dist_to(lig_aromatic.center)
            <= lig_aromatic.radius + PI_PADDING)):

            # so it is in the ring on the projected plane.
            structure = receptor.all_atoms[rec_aromatic.indices[0]].structure
            if structure == "":
              # since it could be interacting with a cofactor or something
              structure = "OTHER"
            key = "T-SHAPED_" + structure

            hashtable_entry_add_one(pi_t, key)
  return pi_t