code: def is_cation_pi(
      cation_position,
      ring_center,
      ring_normal,
      dist_cutoff=6.5,
      angle_cutoff=30.0,
  ):
      """Check if a cation and an aromatic ring form contact.
  
      Parameters:
      -----------
      ring_center: np.ndarray
          Positions of ring center. Can be computed with the compute_ring_center
          function.
      ring_normal: np.ndarray
          Normal of ring. Can be computed with the compute_ring_normal function.
      dist_cutoff: float
          Distance cutoff. Max allowed distance between ring center
          and cation (in Angstroms).
      angle_cutoff: float
          Angle cutoff. Max allowed deviation from the ideal (0deg)
          angle between ring normal and vector pointing from ring
          center to cation (in degrees).
      """
      cation_to_ring_vec = cation_position - ring_center
      dist = np.linalg.norm(cation_to_ring_vec)
      angle = (
          angle_between(cation_to_ring_vec, ring_normal) * 180.0 / np.pi
      )
      if (angle < angle_cutoff or angle > 180.0 - angle_cutoff) and (
          dist < dist_cutoff
      ):
          return True
      return False
  
file_path: deepchem/deepchem/utils/noncovalent_utils.py
imports: import numpy
  from collections import Counter
  from deepchem.utils.fragment_utils import get_partial_charge
  from deepchem.utils.rdkit_utils import compute_ring_center
  from deepchem.utils.rdkit_utils import compute_ring_normal
  from deepchem.utils.geometry_utils import angle_between
  from deepchem.utils.geometry_utils import is_angle_within_cutoff
label_desc: Use image node_id 7 for calling a global function with example usage: is_cation_pi(cation_position, ring_center, ring_normal, dist_cutoff, angle_cutoff) and returns: False, True