def _fadn_par(vec, geom):
    """First non-zero Atomic Displacement that is Non-Parallel with Vec

    Utility function to identify the first atomic displacement in a geometry
    that is both (a) not the zero vector and (b) non-(anti-)parallel with a
    reference vector.

    Parameters
    ----------
    vec
        length-3 |npfloat_| --
        Reference vector. Does not need to be normalized.

    geom
        length-3N |npfloat_| --
        *CENTERED* molecular geometry.

    Returns
    -------
    out_vec
        length-3 |npfloat_| --
        Normalized non-zero atomic displacement not (anti-)parallel to vec.

    """

    # Imports
    import numpy as np
    from scipy import linalg as spla
    from ..const import PRM
    from ..error import InertiaError
    from .vector import parallel_check as parchk

    # Geom and vec must both be the right shape
    if not (len(geom.shape) == 1 and geom.shape[0] % 3 == 0):
        raise ValueError("Geometry is not length 3N")
    ## end if
    if not vec.shape == (3,):
        raise ValueError("Reference vector is not length 3")
    ## end if

    # vec must not be the zero vector
    if spla.norm(vec) < PRM.ZERO_VEC_TOL:
        raise ValueError("Reference vector norm is too small")
    ## end if

     # Normalize the ref vec
    vec = vec / spla.norm(vec)

    # Iterate over reshaped geometry
    for disp in geom.reshape((geom.shape[0]//3, 3)):
        # See if the displacement is nonzero and nonparallel to the ref vec
        if spla.norm(disp) >= PRM.ZERO_VEC_TOL and \
                not parchk(disp.reshape(3), vec):
            # This is the displacement you are looking for
            out_vec = disp / spla.norm(disp)
            break
            ## end if
        ## end if
    ## next disp
    else:
        # Nothing fit the bill - must be a linear molecule?
        raise InertiaError(InertiaError.BAD_GEOM,
                    "Linear molecule, no non-parallel displacement", "")
    ## end for disp

    # Return the resulting vector
    return out_vec
def _fadn_par ( vec , geom ) : import numpy as np from scipy import linalg as spla from . . const import PRM from . . error import InertiaError from . vector import parallel_check as parchk if not ( len ( geom . shape ) == 1 and geom . shape [ 0 ] % 3 == 0 ) : raise ValueError ( "Geometry is not length 3N" ) if not vec . shape == ( 3 , ) : raise ValueError ( "Reference vector is not length 3" ) if spla . norm ( vec ) < PRM . ZERO_VEC_TOL : raise ValueError ( "Reference vector norm is too small" ) vec = vec / spla . norm ( vec ) for disp in geom . reshape ( ( geom . shape [ 0 ] // 3 , 3 ) ) : if spla . norm ( disp ) >= PRM . ZERO_VEC_TOL and not parchk ( disp . reshape ( 3 ) , vec ) : out_vec = disp / spla . norm ( disp ) break else : raise InertiaError ( InertiaError . BAD_GEOM , "Linear molecule, no non-parallel displacement" , "" ) return out_vec
First non-zero Atomic Displacement that is Non-Parallel with Vec

    Utility function to identify the first atomic displacement in a geometry
    that is both (a) not the zero vector and (b) non-(anti-)parallel with a
    reference vector.

    Parameters
    ----------
    vec
        length-3 |npfloat_| --
        Reference vector. Does not need to be normalized.

    geom
        length-3N |npfloat_| --
        *CENTERED* molecular geometry.

    Returns
    -------
    out_vec
        length-3 |npfloat_| --
        Normalized non-zero atomic displacement not (anti-)parallel to vec.