code: def is_pi_parallel(
      ring1_center: np.ndarray,
      ring1_normal: np.ndarray,
      ring2_center: np.ndarray,
      ring2_normal: np.ndarray,
      dist_cutoff: float = 8.0,
      angle_cutoff: float = 30.0,
  ) -> bool:
      """Check if two aromatic rings form a parallel pi-pi contact.
  
      Parameters
      ----------
      ring1_center, ring2_center: np.ndarray
          Positions of centers of the two rings. Can be computed with the
          compute_ring_center function.
      ring1_normal, ring2_normal: np.ndarray
          Normals of the two rings. Can be computed with the compute_ring_normal
          function.
      dist_cutoff: float
          Distance cutoff. Max allowed distance between the ring center (Angstroms).
      angle_cutoff: float
          Angle cutoff. Max allowed deviation from the ideal (0deg) angle between
          the rings (in degrees).
  
      Returns
      -------
      bool
          True if two aromatic rings form a parallel pi-pi.
      """
  
      dist = np.linalg.norm(ring1_center - ring2_center)
      angle = angle_between(ring1_normal, ring2_normal) * 180 / 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 10 for calling a global function with example usage: is_pi_parallel(ring1_center, ring1_normal, ring2_center, ring2_normal, dist_cutoff, angle_cutoff) and returns: False, True