def convert_many(self, coords, molecule=None, origins=None, axes=None, ordering=None, reembed=False, axes_choice=None, return_derivs=None, strip_dummies=False, strip_embedding=True, planar_ref_tolerance=None, **kwargs):
    '\n        Converts from Cartesian to ZMatrix coords, attempting to preserve the embedding\n        '
    from .Molecule import Molecule
    n_sys = coords.shape[0]
    n_coords = coords.shape[1]
    n_atoms = len(molecule.atoms)
    if (n_coords != (n_atoms + 2)):
        if (n_coords != n_atoms):
            raise ValueError('Embedding unclear when num_coords ({}) < num_atoms ({})'.format(n_coords, n_atoms))
        x_ax = axes[..., 0, :]
        y_ax = axes[..., 1, :]
        extra_norms0 = nput.vec_norms(x_ax)
        extra_norms1 = nput.vec_norms(y_ax)
        (extra_angles, _) = nput.vec_angles(x_ax, y_ax)
        extra_coords = np.zeros((n_sys, 2, 3))
        extra_coords[(..., 0, 0)] = extra_norms0
        extra_coords[(..., 1, 0)] = extra_norms1
        extra_coords[(..., 1, 1)] = extra_angles
        coords = np.concatenate([extra_coords, coords], axis=(- 2))
        if (ordering is not None):
            ordering = np.array(ordering, dtype=int)
            ordering = (ordering + 3)
            ordering = np.concatenate([[[0, (- 1), (- 1), (- 1)], [1, 0, (- 1), (- 1)], [2, 0, 1, (- 1)]], ordering])
    refuse_derivs = (reembed and (coords.squeeze().ndim != 2))
    res = CoordinateSet(coords, ZMatrixCoordinates).convert(CartesianCoordinates3D, ordering=ordering, origins=origins, axes=axes, return_derivs=(return_derivs and (not refuse_derivs)), **kwargs)
    if isinstance(res, tuple):
        (carts, opts) = res
    else:
        carts = res
        opts = res.converter_options
    if reembed:
        if (molecule is None):
            raise ValueError("can't reembed without a reference structure")
        embed_carts = carts[..., 3:, :]
        reembed = (not ((carts.squeeze().ndim == 2) and np.allclose(molecule.coords, embed_carts, atol=1e-05)))
        if reembed:
            if (not return_derivs):
                embed_carts = molecule.embed_coords(embed_carts, planar_ref_tolerance=planar_ref_tolerance)
                carts = np.concatenate([carts[..., :3, :], embed_carts], axis=(- 2))
            else:
                (inert_coords, coord_coms, coord_axes) = Molecule(molecule.atoms, embed_carts).principle_axis_data
                if (axes_choice is None):
                    axes_choice = (0, 1)
                guh = self.convert_many(coords, origins=coord_coms, axes=coord_axes[:, axes_choice], molecule=molecule, reembed=False, ordering=ordering, return_derivs=return_derivs, axes_choice=axes_choice, **kwargs)
                return guh
    opts['origins'] = origins
    opts['axes'] = axes
    if (ordering is not None):
        opts['ordering'] = (ordering[3:] - 3)
    if strip_dummies:
        dummies = ([0, 1, 2] + [(x + 3) for x in molecule.dummy_positions])
    elif strip_embedding:
        dummies = [0, 1, 2]
    else:
        dummies = None
    if (dummies is not None):
        main_excludes = np.setdiff1d(np.arange((len(molecule.atoms) + 3)), dummies)
        sub_excludes = (main_excludes - 1)
        if ('derivs' in opts):
            derivs = opts['derivs']
            reshaped_derivs = ([None] * len(derivs))
            deriv_excludes = np.arange(3, (len(molecule.atoms) + 3))
            for (i, v) in enumerate(derivs):
                start_dim = (v.ndim - i)
                for j in range(start_dim, v.ndim, 2):
                    v = np.take(v, deriv_excludes, axis=j)
                v = np.take(v, sub_excludes, axis=(- 2))
                reshaped_derivs[i] = v
            opts['derivs'] = reshaped_derivs
        carts = carts[..., main_excludes, :]
    return (carts, opts)
Converts from Cartesian to ZMatrix coords, attempting to preserve the embedding
def convert_many(self, coords, molecule=None, origins=None, axes=None, ordering=None, reembed=False, axes_choice=None, return_derivs=None, strip_dummies=False, strip_embedding=True, planar_ref_tolerance=None, **kwargs):
    '\n        \n        '
    from .Molecule import Molecule
    n_sys = coords.shape[0]
    n_coords = coords.shape[1]
    n_atoms = len(molecule.atoms)
    if (n_coords != (n_atoms + 2)):
        if (n_coords != n_atoms):
            raise ValueError('Embedding unclear when num_coords ({}) < num_atoms ({})'.format(n_coords, n_atoms))
        x_ax = axes[..., 0, :]
        y_ax = axes[..., 1, :]
        extra_norms0 = nput.vec_norms(x_ax)
        extra_norms1 = nput.vec_norms(y_ax)
        (extra_angles, _) = nput.vec_angles(x_ax, y_ax)
        extra_coords = np.zeros((n_sys, 2, 3))
        extra_coords[(..., 0, 0)] = extra_norms0
        extra_coords[(..., 1, 0)] = extra_norms1
        extra_coords[(..., 1, 1)] = extra_angles
        coords = np.concatenate([extra_coords, coords], axis=(- 2))
        if (ordering is not None):
            ordering = np.array(ordering, dtype=int)
            ordering = (ordering + 3)
            ordering = np.concatenate([[[0, (- 1), (- 1), (- 1)], [1, 0, (- 1), (- 1)], [2, 0, 1, (- 1)]], ordering])
    refuse_derivs = (reembed and (coords.squeeze().ndim != 2))
    res = CoordinateSet(coords, ZMatrixCoordinates).convert(CartesianCoordinates3D, ordering=ordering, origins=origins, axes=axes, return_derivs=(return_derivs and (not refuse_derivs)), **kwargs)
    if isinstance(res, tuple):
        (carts, opts) = res
    else:
        carts = res
        opts = res.converter_options
    if reembed:
        if (molecule is None):
            raise ValueError("can't reembed without a reference structure")
        embed_carts = carts[..., 3:, :]
        reembed = (not ((carts.squeeze().ndim == 2) and np.allclose(molecule.coords, embed_carts, atol=1e-05)))
        if reembed:
            if (not return_derivs):
                embed_carts = molecule.embed_coords(embed_carts, planar_ref_tolerance=planar_ref_tolerance)
                carts = np.concatenate([carts[..., :3, :], embed_carts], axis=(- 2))
            else:
                (inert_coords, coord_coms, coord_axes) = Molecule(molecule.atoms, embed_carts).principle_axis_data
                if (axes_choice is None):
                    axes_choice = (0, 1)
                guh = self.convert_many(coords, origins=coord_coms, axes=coord_axes[:, axes_choice], molecule=molecule, reembed=False, ordering=ordering, return_derivs=return_derivs, axes_choice=axes_choice, **kwargs)
                return guh
    opts['origins'] = origins
    opts['axes'] = axes
    if (ordering is not None):
        opts['ordering'] = (ordering[3:] - 3)
    if strip_dummies:
        dummies = ([0, 1, 2] + [(x + 3) for x in molecule.dummy_positions])
    elif strip_embedding:
        dummies = [0, 1, 2]
    else:
        dummies = None
    if (dummies is not None):
        main_excludes = np.setdiff1d(np.arange((len(molecule.atoms) + 3)), dummies)
        sub_excludes = (main_excludes - 1)
        if ('derivs' in opts):
            derivs = opts['derivs']
            reshaped_derivs = ([None] * len(derivs))
            deriv_excludes = np.arange(3, (len(molecule.atoms) + 3))
            for (i, v) in enumerate(derivs):
                start_dim = (v.ndim - i)
                for j in range(start_dim, v.ndim, 2):
                    v = np.take(v, deriv_excludes, axis=j)
                v = np.take(v, sub_excludes, axis=(- 2))
                reshaped_derivs[i] = v
            opts['derivs'] = reshaped_derivs
        carts = carts[..., main_excludes, :]
    return (carts, opts)