Iterator over selected dihedral angles.

        Angles are in degrees as with :meth:`dihed_single`.

        See `above <toc-generators_>`_ for more information on
        calling options.


        Parameters
        ----------
        g_nums
            |int| or iterable |int| or |None| --
            Indices of the desired geometry

        ats_1
            |int| or iterable |int| or |None| --
            Indices of the first atoms

        ats_2
            |int| or iterable |int| or |None| --
            Indices of the second atoms

        ats_3
            |int| or iterable |int| or |None| --
            Indices of the third atoms

        ats_4
            |int| or iterable |int| or |None| --
            Indices of the fourth atoms

        invalid_error
            |bool|, optional --
            If |False| (the default), |None| values are returned for
            results corresponding to invalid indices. If |True|,
            exceptions are raised per normal.

        Yields
        ------
        dihed
            |npfloat_| --
            Out-of-plane/dihedral angles in degrees for the indicated
            atom sets `ats_1`-`ats_2`-`ats_3`-`ats_4`, drawn from
            the respective `g_nums`.

        Raises
        ------
        ~exceptions.IndexError
            If an invalid (out-of-range) `g_num` or `at_#` is provided.

        ~exceptions.ValueError
            If all iterable objects are not the same length.

        ~exceptions.ValueError
            If any corresponding `ats_#` indices are equal.

        ~opan.error.XYZError
            (typecode :data:`~opan.error.XYZError.DIHED`) If either
            of the atom trios (1-2-3 or
            2-3-4) is too close to linearity for any group of `ats_#`

def dihed_iter(self, g_nums, ats_1, ats_2, ats_3, ats_4, \
                                                    invalid_error=False):
        """ Iterator over selected dihedral angles.

        Angles are in degrees as with :meth:`dihed_single`.

        See `above <toc-generators_>`_ for more information on
        calling options.


        Parameters
        ----------
        g_nums
            |int| or iterable |int| or |None| --
            Indices of the desired geometry

        ats_1
            |int| or iterable |int| or |None| --
            Indices of the first atoms

        ats_2
            |int| or iterable |int| or |None| --
            Indices of the second atoms

        ats_3
            |int| or iterable |int| or |None| --
            Indices of the third atoms

        ats_4
            |int| or iterable |int| or |None| --
            Indices of the fourth atoms

        invalid_error
            |bool|, optional --
            If |False| (the default), |None| values are returned for
            results corresponding to invalid indices. If |True|,
            exceptions are raised per normal.

        Yields
        ------
        dihed
            |npfloat_| --
            Out-of-plane/dihedral angles in degrees for the indicated
            atom sets `ats_1`-`ats_2`-`ats_3`-`ats_4`, drawn from
            the respective `g_nums`.

        Raises
        ------
        ~exceptions.IndexError
            If an invalid (out-of-range) `g_num` or `at_#` is provided.

        ~exceptions.ValueError
            If all iterable objects are not the same length.

        ~exceptions.ValueError
            If any corresponding `ats_#` indices are equal.

        ~opan.error.XYZError
            (typecode :data:`~opan.error.XYZError.DIHED`) If either
            of the atom trios (1-2-3 or
            2-3-4) is too close to linearity for any group of `ats_#`

        """
        # Suitability of ats_n indices will be checked within the
        #  self.dihed_single() calls and thus no check is needed here.

        # Import the tuple-generating function
        from .utils import pack_tups

        # Print the function inputs if debug mode is on
        if _DEBUG:   # pragma: no cover
            print("g_nums = {0}".format(g_nums))
            print("ats_1 = {0}".format(ats_1))
            print("ats_2 = {0}".format(ats_2))
            print("ats_3 = {0}".format(ats_3))
            print("ats_4 = {0}".format(ats_4))
        ## end if

        # Perform the None substitution
        arglist = self._none_subst(g_nums, ats_1, ats_2, ats_3, ats_4)

        # Expand/pack the tuples from the inputs
        tups = pack_tups(*arglist)

        # Dump the results if debug mode is on
        if _DEBUG:   # pragma: no cover
            print(tups)
        ## end if

        # Construct the generator using the packed tuples.
        for tup in tups:
            yield self._iter_return(tup, self.dihed_single, invalid_error)