class TestSymgroupCycles(unittest.TestCase):
    def setUp(self):
        self._geometry = Geometry(
            positions=[[0.506643354, -1.227657970, 0.000000000],
                       [1.303068499, 0.000000000, 0.000000000],
                       [0.506643354, 1.227657970, 0.000000000],
                       [-0.926250976, 0.939345948, 0.000000000],
                       [-0.926250976, -0.939345948, 0.000000000]],
            # name='test',
            symbols=['C', 'C', 'C', 'C', 'C'],
            connectivity_thresh=1.5,
        )

    def test_symmetry_measure(self):
        measure = self._geometry.get_symmetry_measure('C5')
        self.assertAlmostEqual(measure, 0.8247502, places=6)
        measure = self._geometry.get_symmetry_measure('C2')
        self.assertAlmostEqual(measure, 0.0, places=6)
        measure = self._geometry.get_symmetry_measure('C3')
        self.assertAlmostEqual(measure, 33.482451, places=6)

    #def test_symmetry_measure_permutation(self):
    #    measure = self._geometry.get_symmetry_measure('C5', fix_permutation=True)
    #    self.assertAlmostEqual(measure, 0.8247502, places=6)

    def test_symmetry_nearest(self):
        nearest = self._geometry.get_symmetry_nearest_structure(
            'C5').get_positions()
        # print(nearest)
        reference = [[4.05078542e-01, -1.24670356e+00, 0.00000000e+00],
                     [1.31086170e+00, -1.33226763e-16, 0.00000000e+00],
                     [4.05078542e-01, 1.24670356e+00, 0.00000000e+00],
                     [-1.06050939e+00, 7.70505174e-01, 0.00000000e+00],
                     [-1.06050939e+00, -7.70505174e-01, 0.00000000e+00]]
        testing.assert_array_almost_equal(nearest, reference, decimal=6)
Esempio n. 2
0
def get_reference_structure(label, central_atom=0):
    global ideal_structures
    from cosymlib.molecule.geometry import Geometry

    if ideal_structures is None:
        file_path = os.path.dirname(
            os.path.abspath(__file__)) + '/ideal_structures_center.yaml'
        with open(file_path, 'r') as stream:
            ideal_structures = yaml.load(stream, Loader=yaml.FullLoader)

    try:
        if central_atom == 0:
            coordinates = ideal_structures[label][:-1]
            # coordinates = resize_structure(ideal_structures[label][:-1])
            return Geometry(positions=coordinates,
                            name=label,
                            symbols=['L'] * len(coordinates),
                            connectivity=[])

        else:
            coordinates = ideal_structures[label]
            # coordinates = resize_structure(ideal_structures[label], center=ideal_structures[label][-1])
            return Geometry(positions=coordinates,
                            name=label,
                            symbols=['L'] * (len(coordinates) - 1) + ['M'],
                            connectivity=[])
    except KeyError as e:
        raise Exception('Shape reference label "{}" not found!'.format(
            e.args[0]))
 def setUp(self):
     self._geometry = Geometry(
         positions=[[0.506643354, -1.227657970, 0.000000000],
                    [1.303068499, 0.000000000, 0.000000000],
                    [0.506643354, 1.227657970, 0.000000000],
                    [-0.926250976, 0.939345948, 0.000000000],
                    [-0.926250976, -0.939345948, 0.000000000]],
         # name='test',
         symbols=['C', 'C', 'C', 'C', 'C'],
         connectivity_thresh=1.5,
     )
def get_geometry_from_file_cor(file_name, read_multiple=False):
    """
    Reads a Conquest formatted file and the geometry of all structures in it
    :param file_name: file name
    :param read_multiple: read multiple files if available
    :return: list of Geometry objects
    """
    input_molecule = [[], []]
    geometries = []
    with open(file_name, mode='r') as lines:

        for idl, line in enumerate(lines):
            if line.lstrip().startswith(comment_line):
                pass
            elif line.strip() == '':
                warnings.warn('Line {} is empty'.format(idl + 1),
                              errors.EmptyLineWarning)
            else:
                try:
                    float(line.split()[1])
                    if len(line.split()) == 4:
                        input_molecule[0].append(line.split()[0])
                        input_molecule[1].append(line.split()[1:])
                    elif len(line.split()) == 5:
                        input_molecule[0].append(line.split()[0])
                        input_molecule[1].append(line.split()[1:-1])
                    else:
                        float(line.split()[2])
                except (ValueError, IndexError):
                    if input_molecule[0]:
                        geometries.append(
                            Geometry(symbols=input_molecule[0],
                                     positions=input_molecule[1],
                                     name=name))
                    input_molecule = [[], []]
                    name = line.replace('**FRAG**', '')[:-1]
                    name = name.replace(' ', '')
        geometries.append(
            Geometry(symbols=input_molecule[0],
                     positions=input_molecule[1],
                     name=name))
        if not read_multiple:
            return geometries[0]

    # Check if all geometries are of the same vertices
    check_geometries_vertices(geometries, file_name)

    return geometries
Esempio n. 5
0
    def get_shape_structure(self,
                            shape_label,
                            central_atom=0,
                            fix_permutation=False):
        from cosymlib.molecule.geometry import Geometry
        structure_coordinates = self._shape.structure(
            shape_label,
            central_atom=central_atom,
            fix_permutation=fix_permutation)

        return Geometry(symbols=self.get_symbols(),
                        positions=structure_coordinates,
                        name=self.name + '_structure')
def get_geometry_from_file_ref(file_name, read_multiple=False):
    """
    Reads a Conquest formatted file and the geometry of all structures in it
    :param file_name: file name
    :param read_multiple: read all geometries inside the file
    :return: list of Geometry objects
    """
    input_molecule = []
    structures = []
    with open(file_name, mode='r') as lines:
        lines.readline()
        lines.readline()
        name = lines.readline().split()[0]
        for line in lines:
            if line.lstrip().startswith(comment_line):
                pass
            # elif line.strip() == '':
            #     warnings.warn('Line {} is empty'.format(idl + 1), custom_errors.EmptyLineWarning)
            else:
                try:
                    if len(line.split()) > 3:
                        float(line.split()[1])
                        input_molecule.append(line.split()[1:])
                    else:
                        float(line.split()[0])
                        input_molecule.append(line.split())
                except (ValueError, IndexError):
                    if input_molecule:
                        structures.append(
                            Geometry(positions=input_molecule, name=name))
                    input_molecule = []
                    name = line.split()[0]
        structures.append(Geometry(positions=input_molecule, name=name))
    if read_multiple is False:
        return structures[0]

    return structures
def get_geometry_from_file_pdb(file_name, read_multiple=False):
    """
    Reads a Conquest formatted file and the geometry of all structures in it
    :param file_name: file name
    :param read_multiple: read multiple files if available
    :return: list of Geometry objects
    """

    file_txt = open(file_name, mode='r').read()

    index_list = []
    for i in re.finditer('TITLE', file_txt):
        index_list.append(i.start())
    index_list.append(len(file_txt))

    geometries = []
    for i in range(len(index_list) - 1):
        mol_section = file_txt[index_list[i]:index_list[i + 1]]
        coordinates = []
        symbols = []
        connect = []
        name = ''
        for line in mol_section.split('\n'):
            if line.find('TITLE') > -1:
                name = ' '.join(line.split()[1:])
            if line.find('HETATM') > -1 or line.find('ATOM') > -1:
                coordinates.append([float(num) for num in line.split()[4:7]])
                symbols.append(line.split()[2])
            if line.find('CONECT') > -1:
                connect.append([int(num) for num in line.split()[1:]])
            if line.find('TER') > -1 or line.find('END') > -1:
                break

        connectivity = []
        for atom in connect:
            for j in atom[1:]:
                connectivity.append((atom[0], j))

        geometries.append(
            Geometry(symbols=symbols,
                     positions=coordinates,
                     name=name,
                     connectivity=connectivity))

    if read_multiple is False:
        return geometries[0]

    return geometries
Esempio n. 8
0
    def get_symmetry_nearest_structure(self,
                                       label,
                                       central_atom=0,
                                       center=None,
                                       multi=1):
        """
        Returns the nearest ideal structure

        :param label: symmetry point group
        :type label: str
        :param central_atom: central atom position (0 if no central atom)
        :type central_atom: int
        :param center: center of the measure in Cartesian coordinates
        :type center: list
        :return: The structure
        :rtype: Geometry
        """
        return Geometry(symbols=self.get_symbols(),
                        positions=self._symmetry.nearest_structure(label),
                        name=self.name + '_nearest')
def get_geometry_from_file_xyz(file_name, read_multiple=False):
    """
    Reads a XYZ file and returns the geometry of all structures in it
    :param file_name: file name
    :param read_multiple: read multiple files if available
    :return: list of Geometry objects
    """
    input_molecule = [[], []]
    geometries = []
    n_atoms = None
    n_atoms_line = 1
    no_title_structures = 1
    with open(file_name, mode='r') as lines:
        for idl, line in enumerate(lines):
            if line.lstrip().startswith(comment_line):
                pass
            elif line.strip() == '':
                warnings.warn('Line {} is empty'.format(idl + 1),
                              errors.EmptyLineWarning)
            else:
                try:
                    float(line.split()[1])
                    input_molecule[0].append(line.split()[0])
                    input_molecule[1].append(line.split()[1:])
                except (IndexError, ValueError):
                    if input_molecule[0]:
                        if len(input_molecule[0]) != n_atoms:
                            warnings.warn(
                                'Number of atoms in line {} and number '
                                'of atoms provided are not equal'.format(
                                    n_atoms_line), errors.MissingAtomWarning)
                        if name == '':
                            name = no_name(file_name, no_title_structures)
                            no_title_structures += 1

                        geometries.append(
                            Geometry(symbols=input_molecule[0],
                                     positions=input_molecule[1],
                                     name=name))
                        n_atoms = None

                    name = ''
                    input_molecule = [[], []]
                    if n_atoms is None:
                        n_atoms = int(line.split()[0])
                        n_atoms_line = idl + 1
                    else:
                        name = line.split()[0]

        if len(input_molecule[0]) != n_atoms:
            warnings.warn(
                'Number of atoms in line {} and number '
                'of atoms provided are not equal'.format(n_atoms_line),
                errors.MissingAtomWarning)
        if name == '':
            name = no_name(file_name, no_title_structures)

        geometries.append(
            Geometry(symbols=input_molecule[0],
                     positions=input_molecule[1],
                     name=name))
        if not read_multiple:
            return geometries[0]

    # Check if all geometries are of the same vertices
    check_geometries_vertices(geometries, file_name)

    return geometries
def get_molecule_from_file_molden(file_name, read_multiple=False):
    key_list = [
        'Charge', 'Multiplicity', 'Atomic numbers',
        'Current cartesian coordinates', 'Shell type',
        'Number of primitives per shell', 'Shell to atom map',
        'Primitive exponents', 'Contraction coefficients',
        'P(S=P) Contraction coefficients', 'Alpha MO coefficients',
        'Beta MO coefficients', 'MO Energies'
    ]

    type_list = {'s': '0', 'p': '1', 'd': '2', 'f': '3', 'sp': '-1'}

    input_molecule = {key: [] for key in key_list}
    read_molden = False
    read_coordinates = False
    read_basis = False
    read_coefficients = False
    occupation = {'Alpha': [], 'Beta': []}
    with open(file_name, mode='r') as lines:
        lines.readline()
        lines.readline()
        name = file_name.split('.')[0]
        for line in _non_blank_lines(lines):

            if '[' in line:
                pass
            elif read_molden:
                if '======= END OF MOLDEN-FORMAT MOLECULAR ORBITALS =======' in line:
                    break
                if read_coordinates:
                    input_molecule['Atomic numbers'].append(line.split()[2])
                    input_molecule['Current cartesian coordinates'].append(
                        line.split()[3:])
                if read_basis:
                    try:
                        number = float(line.split()[0].replace('D', 'E'))
                        if number - int(number) != 0.:
                            input_molecule['Primitive exponents'].append(
                                line.split()[0].replace('D', 'E'))
                            input_molecule['Contraction coefficients'].append(
                                line.split()[1].replace('D', 'E'))
                            if len(line.split()) > 2:
                                input_molecule[
                                    'P(S=P) Contraction coefficients'].append(
                                        line.split()[2].replace('D', 'E'))
                            else:
                                input_molecule[
                                    'P(S=P) Contraction coefficients'].append(
                                        0.)
                        else:
                            atom = line.split()[0]
                    except ValueError:
                        input_molecule['Shell to atom map'].append(atom)
                        input_molecule['Shell type'].append(
                            type_list[line.split()[0].lower()])
                        input_molecule[
                            'Number of primitives per shell'].append(
                                line.split()[1])
                if read_coefficients:
                    if 'Sym' in line:
                        pass
                    else:
                        if 'Ene' in line:
                            input_molecule['MO Energies'].append(
                                float(re.split('[= ]', line)[-1]))
                        elif 'Spin' in line:
                            spin = re.split('[= ]', line)[-1]
                            input_molecule[spin + ' MO coefficients'].append(
                                [])
                        elif 'Occup' in line:
                            occupation[spin].append(
                                int(float(line.split('=')[-1])))
                        else:
                            input_molecule[spin +
                                           ' MO coefficients'][-1].append(
                                               line.split()[1])

            if '[Atoms]' in line:
                read_molden = True
                read_coordinates = True
                if 'AU' in line:
                    bohr_to_angstrom = 0.529177249
                else:
                    bohr_to_angstrom = 1
            elif '[GTO]' in line:
                read_coordinates = False
                read_basis = True
            elif '[MO]' in line:
                read_basis = False
                read_coefficients = True
            elif '[5D]' in line:
                input_molecule['Shell type'] = [
                    x.replace('2', '-2') for x in input_molecule['Shell type']
                ]
            elif '[7F]' in line:
                input_molecule['Shell type'] = [
                    x.replace('3', '-3') for x in input_molecule['Shell type']
                ]

        coordinates = np.array(input_molecule['Current cartesian coordinates'],
                               dtype=float).reshape(-1, 3) * bohr_to_angstrom

        total_n_electrons = 0
        symbols = []
        for atom_number in input_molecule['Atomic numbers']:
            total_n_electrons += int(atom_number)
            symbols.append(atomic_number_to_element(atom_number))

        new_occupation = []
        if len(occupation['Beta']) == 0:
            if 2 not in occupation['Alpha']:
                occupation['Beta'] = occupation['Alpha']
            else:
                for occup in occupation['Alpha']:
                    new_occupation.append(occup // 2)
                    if occup == 2:
                        occupation['Beta'].append(1)
                    else:
                        occupation['Beta'].append(0)
                occupation['Alpha'] = new_occupation
        n_electrons = sum(occupation['Alpha'] + occupation['Beta'])
        input_molecule['Multiplicity'].append(
            sum(occupation['Alpha']) - sum(occupation['Beta']) + 1)
        input_molecule['Charge'].append(int(total_n_electrons - n_electrons))

        basis = basis_format(
            basis_set_name='UNKNOWN',
            atomic_numbers=input_molecule['Atomic numbers'],
            atomic_symbols=symbols,
            shell_type=input_molecule['Shell type'],
            n_primitives=input_molecule['Number of primitives per shell'],
            atom_map=input_molecule['Shell to atom map'],
            p_exponents=input_molecule['Primitive exponents'],
            c_coefficients=input_molecule['Contraction coefficients'],
            p_c_coefficients=input_molecule['P(S=P) Contraction coefficients'])

        geometry = Geometry(symbols=symbols, positions=coordinates, name=name)

        Ca = np.array(input_molecule['Alpha MO coefficients'], dtype=float)
        if input_molecule['Beta MO coefficients']:
            Cb = np.array(input_molecule['Beta MO coefficients'], dtype=float)
        else:
            Cb = []

        warnings.warn('Beta energies not implemented yet')
        ee = ElectronicStructure(
            basis=basis,
            orbital_coefficients=[Ca, Cb],
            # charge=input_molecule['Charge'][0],
            multiplicity=input_molecule['Multiplicity'][0],
            alpha_energies=input_molecule['MO Energies'],
            beta_energies=[],
            alpha_occupancy=occupation['Alpha'],
            beta_occupancy=occupation['Beta'])

        if read_multiple:
            return [Molecule(geometry, ee)]

        return Molecule(geometry, ee)
def get_molecule_from_file_fchk(file_name, read_multiple=False):
    key_list = [
        'Charge', 'Multiplicity', 'Number of alpha electrons',
        'Number of beta electrons', 'Atomic numbers',
        'Current cartesian coordinates', 'Shell type',
        'Number of primitives per shell', 'Shell to atom map',
        'Primitive exponents', 'Contraction coefficients',
        'P(S=P) Contraction coefficients', 'Alpha Orbital Energies',
        'Beta Orbital Energies', 'Alpha MO coefficients',
        'Beta MO coefficients'
    ]
    input_molecule = [[] for _ in range(len(key_list))]
    read = False
    with open(file_name, mode='r') as lines:
        name = lines.readline().split()[0]  #.strip('\n')
        line = lines.readline().split()
        basis_set = line[-1]
        if 'R' in line[1]:
            del key_list[-1]

        n = 1
        options = True
        for line in lines:
            if read:
                try:
                    float(line.split()[0])
                    input_molecule[n].append(line.split())
                except ValueError:
                    read = False

            for idn, key in enumerate(key_list):
                if key in line:
                    if n == len(key_list) - 1:
                        break
                    if options and idn != 4:
                        input_molecule[idn].append(int(line.split()[-1]))
                        n = idn
                        break
                    else:
                        options = False
                    if n == idn:
                        n += 1
                    else:
                        n = idn
                    read = True
                    break

        for n in range(4, len(input_molecule)):
            input_molecule[n] = reformat_input(input_molecule[n])
        bohr_to_angstrom = 0.529177249
        coordinates = np.array(input_molecule[5], dtype=float).reshape(
            -1, 3) * bohr_to_angstrom

        atomic_number = [int(num) for num in input_molecule[4]]
        symbols = []
        for number in atomic_number:
            symbols.append(atomic_number_to_element(number))

        basis = basis_format(basis_set_name=basis_set,
                             atomic_numbers=atomic_number,
                             atomic_symbols=symbols,
                             shell_type=input_molecule[6],
                             n_primitives=input_molecule[7],
                             atom_map=input_molecule[8],
                             p_exponents=input_molecule[9],
                             c_coefficients=input_molecule[10],
                             p_c_coefficients=input_molecule[11])

        geometry = Geometry(symbols=symbols, positions=coordinates, name=name)

        alpha_energies = np.array(input_molecule[12], dtype=float).tolist()
        if input_molecule[13]:
            beta_energies = np.array(input_molecule[13], dtype=float).tolist()
        else:
            beta_energies = []

        Ca = np.array(input_molecule[14], dtype=float).reshape(
            -1, int(np.sqrt(len(input_molecule[14]))))
        if input_molecule[15]:
            Cb = np.array(input_molecule[15], dtype=float).reshape(
                -1, int(np.sqrt(len(input_molecule[15]))))
        else:
            Cb = []

        electronic_structure = ElectronicStructure(
            basis=basis,
            orbital_coefficients=[Ca, Cb],
            # charge=input_molecule[0][0],
            multiplicity=input_molecule[1][0],
            alpha_energies=alpha_energies,
            beta_energies=beta_energies,
            alpha_occupancy=[1] * int(input_molecule[2][0]),
            beta_occupancy=[1] * int(input_molecule[3][0]))

        if read_multiple:
            return [Molecule(geometry, electronic_structure)]

        return Molecule(geometry, electronic_structure)
    def print_minimum_distortion_path_shape(self, shape_label1, shape_label2, central_atom=0,
                                            min_dev=None, max_dev=None, min_gco=None, max_gco=None,
                                            num_points=20, output=None):
        """
        Print the minimum distortion path

        :param shape_label1: First reference shape label
        :type shape_label1: str
        :param shape_label2: Second reference shape label
        :type shape_label2: str
        :param central_atom: Position of the central atom
        :type central_atom: int
        :param min_dev:
        :type min_dev: float
        :param max_dev:
        :type max_dev: float
        :param min_gco:
        :type min_gco: float
        :param max_gco:
        :type max_gco: float
        :param num_points: Number of points
        :type num_points: int
        :param output1: Display hook
        :type output1: hook
        """

        if output is not None:
            output_name, file_extension = os.path.splitext(output.name)
            output1 = open(output_name + '_pth.csv', 'w')
            output2 = open(output_name + '_pth.xyz', 'w')
            output3 = output
        else:
            output1 = sys.stdout
            output2 = sys.stdout
            output3 = sys.stdout

        csm, devpath, gen_coord = self.get_path_parameters(shape_label1, shape_label2, central_atom=central_atom)

        txt_params = ''
        if min_dev is not None:
            txt_params = 'Deviation threshold to calculate Path deviation function: ' \
                         '{:2.1f}% - {:2.1f}%\n'.format(min_dev, max_dev)
        if min_gco is not None:
            txt_params += 'Deviation threshold to calculate Generalized Coordinate: ' \
                          '{:2.1f}% - {:2.1f}%\n'.format(min_gco, max_gco)
        txt_params += '\n'
        txt_params += '{:9} '.format('structure'.upper())
        for csm_label in list(csm.keys()):
            txt_params += '{:^8} '.format(csm_label)
        txt_params += '{:^8} {:^8}'.format('DevPath', 'GenCoord')
        txt_params += '\n'

        if min_gco is not None and min_dev is not None:
            filter_mask = [min_dev <= dv <= max_dev and min_gco <= gc <= max_gco for dv, gc in zip(devpath, gen_coord)]
        elif min_gco is not None:
            filter_mask = [min_gco <= gc <= max_gco for gc in  gen_coord]
        elif min_dev is not None:
            filter_mask = [min_dev <= dv <= max_dev for dv in devpath]
        else:
            filter_mask = [True for _ in range(len(self._molecules))]

        for idx, molecule in enumerate(self._molecules):
            if not filter_mask[idx]:
                continue

            txt_params += '{:9} '.format(molecule.name.strip())
            for label in list(csm.keys()):
                txt_params += '{:^8.3f} '.format(csm[label][idx])
            txt_params += '{:^8.1f} {:^8.1f}'.format(devpath[idx], gen_coord[idx])
            txt_params += '\n'

        # self.print_shape_measure()
        txt_params += 'skipped {} structure/s\n\n'.format(filter_mask.count(False))
        output3.write(txt_params)

        if isinstance(shape_label1, Geometry):
            label1_name = shape_label1.name
        else:
            label1_name = shape_label1
        if isinstance(shape_label2, Geometry):
            label2_name = shape_label2.name
        else:
            label2_name = shape_label2

        path = get_shape_path(shape_label1, shape_label2, num_points)
        txt_path = 'Minimum distortion path\n'
        txt_path += ' {:^6}  {:^6}\n'.format(label1_name, label2_name)
        for idx, value in enumerate(path[0]):
            txt_path += '{:6.3f}  {:6.3f}'.format(path[0][idx], path[1][idx])
            txt_path += '\n'
        txt_path += '\n'
        output1.write(txt_path)

        test_structures = []
        for ids, structure in enumerate(path[2]):
            test_structures.append(Geometry(symbols=['' for _ in range(len(structure))],
                                            positions=structure, name='map_structure{}'.format(ids)))
        output2.write(file_io.get_file_xyz_txt(test_structures))

        if output1 is sys.stdout:
            plt.plot(path[0], path[1], 'k', linewidth=2.0)
            plt.scatter(np.array(csm[label1_name])[filter_mask],
                        np.array(csm[label2_name])[filter_mask], linewidths=0.01)
            plt.xlabel(label1_name)
            plt.ylabel(label2_name)
            plt.show()
Esempio n. 13
0
def get_nm_vibration_path(geometry, normal_mode, points=10, backward=False, k=1.5):

    nm_np_matrix = np.array(normal_mode)
    geom_np = np.array(geometry)
    if backward:
        x = np.linspace(-k, k, points)
    else:
        x = np.linspace(k/points, k, points)

    structures_path = []
    for dx in x:
        structures_path.append(geom_np + dx*nm_np_matrix)

    return structures_path


molecule = read_generic_structure_file('sf6.fchk')
freq, nm_martices = read_normal_modes_gaussian('../old_examples/sf6_freq.out')
k_points = 1.5
points = 10
n_freq = 1
path = get_nm_vibration_path(molecule.geometry.get_positions(), nm_martices[n_freq - 1], k=k_points)

x = np.linspace(k_points/points, k_points, points)
output = open('sf6_freq{}.xyz'.format(n_freq), 'w')
for ids, structure in enumerate(path):
    xi = '{:.2f}'.format(x[ids]).replace('.', '')
    txt = get_file_xyz_txt(Geometry(structure, symbols=molecule.geometry.get_symbols(), name='freq : ' + str(freq[0]) +
                                                                                             ' ' + str(xi)))
    output.write(txt)