# Path: tamkin/geom.py
# def transrot_basis(coordinates, rot=True):
#     """Constructs 6 vectors which represent global translations/rotations.
# 
#        Argument:
#         | coordinates  --  The atom coordinates (float numpy array with shape
#                            Nx3)
# 
#        Optional argument:
#         | rot  --  When True the rotations are included [default=True]
# 
#        The return value is a numpy array with 3*N columns and 6 (``rot==True``)
#        or 3 (``rot==False``) rows. The rows are not mass weighted.
#     """
#     if not rot:
#         result = np.zeros((3, coordinates.size), float)
#     else:
#         result = np.zeros((6, coordinates.size), float)
#     # translation
#     result[0, 0::3] = 1
#     result[1, 1::3] = 1
#     result[2, 2::3] = 1
#     if rot:
#         # rotation
#         result[3, 1::3] =  coordinates[:,2]
#         result[3, 2::3] = -coordinates[:,1]
#         result[4, 2::3] =  coordinates[:,0]
#         result[4, 0::3] = -coordinates[:,2]
#         result[5, 0::3] =  coordinates[:,1]
#         result[5, 1::3] = -coordinates[:,0]
#     return result


from tamkin.geom import transrot_basis
from molmod import Molecule as BaseMolecule, MolecularGraph, ReadOnly, \
    UnitCell, ReadOnlyAttribute
from molmod.periodic import periodic
from molmod.graphs import cached
        from tamkin.io.internal import dump_chk
        from tamkin.io.internal import load_chk
import numpy as np
        # take the optional arguments if present
        opt_fields = ["multiplicity", "symmetry_number", "periodic", "title", "symbols"]
        for ofield in opt_fields:
            if ofield in data:
                constructor_args[ofield] = data[ofield]
        # take the special optional arguments that need conversion
        if "edges" in data:
            graph = MolecularGraph(data["edges"], data["numbers"])
            constructor_args["graph"] = graph
        if "cell_vectors" in data:
            unit_cell = UnitCell(data["cell_vectors"], data.get("cell_active"))
            constructor_args["unit_cell"] = unit_cell
        # construct the molecule object
        return Molecule(**constructor_args)

    def raise_ext(self, shift=1e0):
        """Raise the eigenvalues of the global translations and rotations
        to a high value, such that their coupling with the internal vibrations
        becomes negligible, and they can easily be isolated from the vibrations."""

        # Construct basis for global translations and rotations
        D = self.external_basis.transpose() # mass-weighted
        # make it orthonormal
        svd_threshold = 1e-5
        U, W, Vt = np.linalg.svd(D, full_matrices=False)
        rank = (abs(W) > abs(W[0])*svd_threshold).sum()
        D = U[:,:rank]
        proj = np.dot(D,D.transpose())

        proj1 = proj * (self.masses3.reshape((1,-1)))**(0.5)

# Path: tamkin/geom.py
# def transrot_basis(coordinates, rot=True):
#     """Constructs 6 vectors which represent global translations/rotations.
# 
#        Argument:
#         | coordinates  --  The atom coordinates (float numpy array with shape
#                            Nx3)
# 
#        Optional argument:
#         | rot  --  When True the rotations are included [default=True]
# 
#        The return value is a numpy array with 3*N columns and 6 (``rot==True``)
#        or 3 (``rot==False``) rows. The rows are not mass weighted.
#     """
#     if not rot:
#         result = np.zeros((3, coordinates.size), float)
#     else:
#         result = np.zeros((6, coordinates.size), float)
#     # translation
#     result[0, 0::3] = 1
#     result[1, 1::3] = 1
#     result[2, 2::3] = 1
#     if rot:
#         # rotation
#         result[3, 1::3] =  coordinates[:,2]
#         result[3, 2::3] = -coordinates[:,1]
#         result[4, 2::3] =  coordinates[:,0]
#         result[4, 0::3] = -coordinates[:,2]
#         result[5, 0::3] =  coordinates[:,1]
#         result[5, 1::3] = -coordinates[:,0]
#     return result


# Path: tamkin/data.py
from tamkin.geom import transrot_basis
from molmod import Molecule as BaseMolecule, MolecularGraph, ReadOnly, \
    UnitCell, ReadOnlyAttribute
from molmod.periodic import periodic
from molmod.graphs import cached
        from tamkin.io.internal import dump_chk
        from tamkin.io.internal import load_chk
import numpy as np

        # take the optional arguments if present
        opt_fields = ["multiplicity", "symmetry_number", "periodic", "title", "symbols"]
        for ofield in opt_fields:
            if ofield in data:
                constructor_args[ofield] = data[ofield]
        # take the special optional arguments that need conversion
        if "edges" in data:
            graph = MolecularGraph(data["edges"], data["numbers"])
            constructor_args["graph"] = graph
        if "cell_vectors" in data:
            unit_cell = UnitCell(data["cell_vectors"], data.get("cell_active"))
            constructor_args["unit_cell"] = unit_cell
        # construct the molecule object
        return Molecule(**constructor_args)

    def raise_ext(self, shift=1e0):
        """Raise the eigenvalues of the global translations and rotations
        to a high value, such that their coupling with the internal vibrations
        becomes negligible, and they can easily be isolated from the vibrations."""

        # Construct basis for global translations and rotations
        D = self.external_basis.transpose() # mass-weighted
        # make it orthonormal
        svd_threshold = 1e-5
        U, W, Vt = np.linalg.svd(D, full_matrices=False)
        rank = (abs(W) > abs(W[0])*svd_threshold).sum()
        D = U[:,:rank]
        proj = np.dot(D,D.transpose())

        proj1 = proj * (self.masses3.reshape((1,-1)))**(0.5)

        proj2 = proj1* (self.masses3.reshape((-1,1)))**(0.5)