示例#1
0
def get_bonds(mol: Molecule) -> np.ndarray:
    """Return an array with the atomic indices defining all bonds in **mol**.

    Parameters
    ----------
    mol : |plams.Molecule|_
        A PLAMS molecule.

    Returns
    -------
    :math:`n*2` |np.ndarray|_ [|np.int64|_]:
        A 2D array with atomic indices defining :math:`n` bonds.

    """
    mol.set_atoms_id()
    bonds = [(b.atom1.id, b.atom2.id) for b in mol.bonds]

    ret = np.array(bonds, dtype=int, ndmin=2)
    mol.unset_atoms_id()
    if not bonds:  # If no angles are found
        return ret

    # Sort horizontally
    mass = np.array([[mol[j].mass for j in i] for i in ret])
    idx1 = np.argsort(mass, axis=1)[:, ::-1]
    ret[:] = np.take_along_axis(ret, idx1, axis=1)

    # Sort and return vertically
    idx2 = np.argsort(ret, axis=0)[:, 0]
    return ret[idx2]
示例#2
0
def test_opt_gamess():
    """
    Test Optimization in Gamess using methanol in water.
    """
    methanol = Molecule('test/test_files/ion_methanol.xyz')
    methanol.properties['symmetry'] = 'Cs'

    s = Settings()
    s.specific.gamess.contrl.nzvar = 12
    s.specific.gamess.system.timlim = 2
    s.specific.gamess.system.mwords = 2
    s.specific.gamess.pcm.solvnt = 'water'
    s.specific.gamess.basis.gbasis = 'sto'
    s.specific.gamess.basis.ngauss = 3
    s.specific.gamess.guess.guess = 'huckel'
    s.specific.gamess.stapt.optol = '1d-5'
    s.specific.gamess.zmat["izmat(1)"] = "1,1,2,  1,2,3,  1,3,4,  1,3,5,  1,3,6, \n"\
                                         "2,1,2,3,  2,2,3,4,  2,2,3,5,  2,2,3,6, \n"\
                                         "3,1,2,3,4,  3,1,2,3,5,  3,1,2,3,6"

    inp = templates.geometry.overlay(s)
    methanol_geometry = gamess(inp, methanol, work_dir='/tmp')

    mol_opt = run(methanol_geometry.molecule)

    coords = concat([a.coords for a in mol_opt.atoms])

    expected_coords = [-0.9956983464, 0.9204754677, -0.0002616586, -0.72585581,
                       -0.0802380791, 2.18166e-05, 0.741292161, 0.0371204735,
                       -1.69738e-05, 1.1448441964, 0.5632291664, -0.9026112278,
                       1.1448447102, 0.562978981, 0.9027182521,
                       1.1454516521, -0.9993402516, 1.04943e-05]

    assert abs(sum(zipWith(operator.sub)(coords)(expected_coords))) < 1e-7
示例#3
0
def string_array_to_molecule(parser_fun, file_name, mol=None):
    """
    Convert a Numpy string array like:

    [['C', '-1.487460', '-0.028670', '-0.000060'],
    ['O', '0.376340', '0.028670', '-0.000060'],
    ['H', '-1.818910', '-1.067060', '-0.000060'],
    ['H', '-1.866470', '0.473700', '0.889930'],
    ['H', '-1.866470', '0.473700', '-0.890040'],
    ['H', '0.756720', '-0.950010', '-0.000060']]

    To a plams ``Molecule``.
    """
    string_array_to_float = np.vectorize(float)
    mols = parse_file(parser_fun, file_name).asList()
    last_mol = np.array(mols[-1])
    elems = last_mol[:, 0]
    coords = string_array_to_float(last_mol[:, 1:])
    if mol:
        if len(coords) == len(mol):
            plams_mol = mol
            for i in range(len(plams_mol)):
                plams_mol.atoms[i].coords = tuple(
                    [float(c) for c in coords[i]])
        else:
            raise RuntimeError('Output molecule does not match input molecule')
    else:
        plams_mol = Molecule()
        for e, c in zip(elems, coords):
            plams_mol.add_atom(Atom(symbol=e, coords=tuple(c)))
    return plams_mol
示例#4
0
def test_opt_gamess():
    """
    Test Optimization in Gamess using methanol in water.
    """
    methanol = Molecule('test/test_files/ion_methanol.xyz')
    methanol.properties['symmetry'] = 'Cs'

    s = Settings()
    s.specific.gamess.contrl.nzvar = 12
    s.specific.gamess.system.timlim = 2
    s.specific.gamess.system.mwords = 2
    s.specific.gamess.pcm.solvnt = 'water'
    s.specific.gamess.basis.gbasis = 'sto'
    s.specific.gamess.basis.ngauss = 3
    s.specific.gamess.guess.guess = 'huckel'
    s.specific.gamess.stapt.optol = '1d-5'
    s.specific.gamess.zmat["izmat(1)"] = "1,1,2,  1,2,3,  1,3,4,  1,3,5,  1,3,6, \n"\
                                         "2,1,2,3,  2,2,3,4,  2,2,3,5,  2,2,3,6, \n"\
                                         "3,1,2,3,4,  3,1,2,3,5,  3,1,2,3,6"

    inp = templates.geometry.overlay(s)
    methanol_geometry = gamess(inp, methanol, work_dir='/tmp')

    mol_opt = run(methanol_geometry.molecule)

    coords = concat([a.coords for a in mol_opt.atoms])

    expected_coords = [
        -0.9956983464, 0.9204754677, -0.0002616586, -0.72585581, -0.0802380791,
        2.18166e-05, 0.741292161, 0.0371204735, -1.69738e-05, 1.1448441964,
        0.5632291664, -0.9026112278, 1.1448447102, 0.562978981, 0.9027182521,
        1.1454516521, -0.9993402516, 1.04943e-05
    ]

    assert abs(sum(zipWith(operator.sub)(coords)(expected_coords))) < 1e-7
示例#5
0
    def repr_Molecule(self, obj: Molecule, level: int) -> str:  # noqa: N802
        """Create a :class:`str` representation of a |plams.Molecule| instance."""
        if level <= 0:
            return f'{obj.__class__.__name__}(...)'
        elif not obj:
            return f'{obj.__class__.__name__}()'

        obj.set_atoms_id()
        ret = 'Atoms: \n'
        i = self.maxMolecule

        # Print atoms
        kwargs = {'decimal': self.maxfloat, 'space': 14 - (6 - self.maxfloat)}
        for atom in obj.atoms[:i]:
            ret += f'  {atom.id:<5d}{atom.str(**kwargs).strip()}\n'
        if len(obj.atoms) > i:
            ret += '  ...\n'

        # Print bonds
        if len(obj.bonds):
            ret += 'Bonds: \n'
            for bond in obj.bonds[:i]:
                ret += f'  ({bond.atom1.id})--{bond.order:1.1f}--({bond.atom2.id})\n'
            if len(obj.bonds) > i:
                ret += '  ...\n'

        # Print lattice vectors
        if obj.lattice:
            ret += 'Lattice:\n'
            for vec in obj.lattice:
                ret += '  {:16.10f} {:16.10f} {:16.10f}\n'.format(*vec)

        obj.unset_atoms_id()
        indent = 4 * ' '
        return f'{obj.__class__.__name__}(\n{textwrap.indent(ret[:-1], indent)}\n)'
示例#6
0
文件: parser.py 项目: SCM-NV/qmworks
def string_array_to_molecule(parser_fun, file_name, mol=None):
    """
    Convert a Numpy string array like:

    [['C', '-1.487460', '-0.028670', '-0.000060'],
    ['O', '0.376340', '0.028670', '-0.000060'],
    ['H', '-1.818910', '-1.067060', '-0.000060'],
    ['H', '-1.866470', '0.473700', '0.889930'],
    ['H', '-1.866470', '0.473700', '-0.890040'],
    ['H', '0.756720', '-0.950010', '-0.000060']]

    To a plams ``Molecule``.
    """
    string_array_to_float = np.vectorize(float)
    mols = parse_file(parser_fun, file_name).asList()
    last_mol = np.array(mols[-1])
    elems = last_mol[:, 0]
    coords = string_array_to_float(last_mol[:, 1:])
    if mol:
        if len(coords) == len(mol):
            plams_mol = mol
            for i in range(len(plams_mol)):
                plams_mol.atoms[i].coords = tuple([float(c) for c in coords[i]])
        else:
            raise RuntimeError('Output molecule does not match input molecule')
    else:
        plams_mol = Molecule()
        for e, c in zip(elems, coords):
            plams_mol.add_atom(Atom(symbol=e, coords=tuple(c)))
    return plams_mol
示例#7
0
def modified_minimum_scan_rdkit(ligand: Molecule, bond_tuple: Tuple[int, int],
                                anchor: Atom) -> None:
    """A modified version of the :func:`.global_minimum_scan_rdkit` function.

    * Uses the ligand vector as criteria rather than the energy.
    * Geometry optimizations are constrained during the conformation search.
    * Finish with a final unconstrained geometry optimization.

    See Also
    --------
    :func:`global_minimum_scan_rdkit<scm.plams.recipes.global_minimum.minimum_scan_rdkit>`:
        Optimize the molecule (RDKit UFF) with 3 different values for the given dihedral angle and
        find the lowest energy conformer.

        :param |Molecule| mol: The input molecule
        :param tuple bond_tuple: A 2-tuples containing the atomic indices of valid bonds
        :return |Molecule|: A copy of *mol* with a newly optimized geometry

    """
    # Define a number of variables and create 3 copies of the ligand
    angles = (-120, 0, 120)
    mol_list = [ligand.copy() for _ in range(3)]
    for angle, mol in zip(angles, mol_list):
        bond = mol[bond_tuple]
        atom = mol[bond_tuple[0]]
        mol.rotate_bond(bond, atom, angle, unit='degree')
    rdmol_list = [molkit.to_rdmol(mol, properties=False) for mol in mol_list]

    # Optimize the (constrained) geometry for all dihedral angles in angle_list
    # The geometry that yields the minimum energy is returned
    fixed = _find_idx(mol, bond)
    for rdmol in rdmol_list:
        ff = UFF(rdmol)
        for f in fixed:
            ff.AddFixedPoint(f)
        ff.Minimize()

    # Find the conformation with the optimal ligand vector
    cost_list = []
    try:
        i = ligand.atoms.index(anchor)
    except ValueError:
        i = -1  # Default to the origin as anchor

    for rdmol in rdmol_list:
        xyz = rdmol_as_array(rdmol)
        if i == -1:  # Default to the origin as anchor
            xyz = np.vstack([xyz, [0, 0, 0]])
        rotmat = optimize_rotmat(xyz, i)
        xyz[:] = xyz @ rotmat.T
        xyz -= xyz[i]
        cost = np.exp(xyz[:, 1:]).sum()
        cost_list.append(cost)

    # Perform an unconstrained optimization on the best geometry and update the geometry of ligand
    j = np.argmin(cost_list)
    rdmol_best = rdmol_list[j]
    UFF(rdmol).Minimize()
    ligand.from_rdmol(rdmol_best)
示例#8
0
def store_optimized_molecule(optimized_geometry: Molecule, name: str,
                             path_results: str):
    """Store the xyz molecular geometry."""
    path_geometry = f"{path_results}/{name}"
    if not os.path.exists(path_geometry):
        os.mkdir(path_geometry)
    with open(f"{path_geometry}/{name}_OPT.xyz", 'w') as f:
        optimized_geometry.writexyz(f)
示例#9
0
    def __init__(self, mol: Molecule) -> None:
        """Initialize the instance."""
        mol.set_atoms_id(start=0)

        self._mol = mol
        self._dist_mat = _get_dist_mat(mol)
        self._dist_mat.setflags(write=False)
        self.id_set = set()
        self.neighbor_dict = {}
示例#10
0
def tuplesXYZ_to_plams(xs):
    """ Transform a list of namedTuples to a Plams molecule """
    plams_mol = Molecule()
    for at in xs:
        symb = at.symbol
        cs = at.xyz
        plams_mol.add_atom(Atom(symbol=symb, coords=tuple(cs)))

    return plams_mol
示例#11
0
def tuplesXYZ_to_plams(xs):
    """ Transform a list of namedTuples to a Plams molecule """
    plams_mol = Molecule()
    for at in xs:
        symb = at.symbol
        cs = at.xyz
        plams_mol.add_atom(Atom(symbol=symb, coords=tuple(cs)))

    return plams_mol
示例#12
0
def _bond_id_generator(
        mol: Molecule) -> Generator[Tuple[int, int, int, int], None, None]:
    """Yield all permutations of the bond-defining atoms indices in **mol**."""
    mol.set_atoms_id(start=0)
    for b in mol.bonds:
        id1 = b.atom1.id
        id2 = b.atom2.id
        yield id1, id2, id2, id1

    mol.unset_atoms_id()
示例#13
0
def _protonate_mol(mol: Molecule) -> Molecule:
    mol_cp = mol.copy()

    i = mol.index(mol.properties.dummies)
    anchor = mol_cp[i]
    if anchor.properties.charge != -1:
        raise NotImplementedError("Non-anionic anchors are not supported")

    anchor.properties.charge = 0
    return add_Hs(mol_cp, forcefield="uff")
示例#14
0
def read_mol_xyz(mol_dict: Settings) -> Optional[Molecule]:
    """Read an .xyz file."""
    try:
        mol = Molecule(mol_dict.mol, inputformat='xyz')
        if mol_dict.guess_bonds and not mol_dict.is_qd:
            mol.guess_bonds()
        if not mol_dict.is_core:
            canonicalize_mol(mol)
        return mol
    except Exception as ex:
        print_exception('read_mol_xyz', mol_dict.name, ex)
示例#15
0
def geometry_to_molecule(geometry):
    """
    Convert a list of XYZ coordinates to a Molecule object
    """
    mol = Molecule()

    for i in range(0, len(geometry)):
        mol.add_atom(
            Atom(symbol=geometry[i][0],
                 coords=(geometry[i][1], geometry[i][2], geometry[i][3])))

    return mol
示例#16
0
def sanitize_dim_3(value: Any, padding: float = np.nan) -> np.ndarray:
    """Convert a Molecule or sequence of :math:`m` molecules into an :math:`m*n*3` array.

    If necessary, the to-be returned array is padded with **padding** .

    Parameters
    ----------
    arg : object
        The to be parsed object.
        Acceptable types are:

        * A PLAMS :class:`Atom`
        * A PLAMS :class:`Molecule`
        * A (nested) Sequences consisting of PLAMS :class:`Atom`
        * A (nested) Sequences consisting of PLAMS :class:`Molecule`
        * An array-like object with a dimensionality smaller than 3 and float-compatible elements.

    padding : float
        A value used for padding the to-be returned array.
        Only relevant if **arg** consists of multiple molecule with different numbers of atoms.

    Returns
    -------
    :math:`m*n*3` |np.ndarray|_ [|np.float64|_]
        A 3D array consisting of floats.

    Raises
    ------
    ValueError
        Raised if dimensionality of the to-be returned array is higher than 3
        or the content of **arg** cannot be converted into an array of floats.

    """
    if _is_atom(value):
        return np.array(value.coords)[None, None, :]

    elif _is_atom_sequence(value):
        return Molecule.as_array(None, atom_subset=value)[None, :]

    elif _is_mol_sequence(value):
        max_at = max(len(mol) for mol in value)
        ret = np.full((len(value), max_at, 3), padding, order='F')
        for i, mol in enumerate(value):
            j = len(mol)
            ret[i, :j] = Molecule.as_array(None, atom_subset=mol)
        return ret

    else:
        ret = np.array(value, ndmin=3, dtype=float, copy=False)
        if ret.ndim > 3:
            raise ValueError(f"Failed to create a 3D array; observed dimensionality: {ret.ndim}")
        return ret
示例#17
0
def allign_axis(mol: Molecule, anchor: Atom):
    """Allign a molecule with the Cartesian X-axis; setting **anchor** as the origin."""
    try:
        idx = mol.atoms.index(anchor)
    except ValueError as ex:
        raise MoleculeError("The passed anchor is not in mol") from ex

    xyz = mol.as_array()  # Allign the molecule with the X-axis
    rotmat = optimize_rotmat(xyz, idx)
    xyz[:] = xyz @ rotmat.T
    xyz -= xyz[idx]
    xyz[:] = xyz.round(decimals=3)
    mol.from_array(xyz)
示例#18
0
def parse_molecule_traj(file_traj: PathLike) -> Molecule:
    """Read Molecules from the job_name.traj file."""
    mols = manyXYZ(file_traj)
    # Last geometry corresponds to the optimized structure
    opt_mol = mols[-1]

    plams_mol = Molecule()
    for at in opt_mol:
        symb = at.symbol
        cs = at.xyz
        plams_mol.add_atom(Atom(symbol=symb, coords=tuple(cs)))

    return plams_mol
示例#19
0
def _get_ligand(mol: Molecule) -> Molecule:
    """Extract a single ligand from **mol** as a copy."""
    at_list = []
    res = mol.atoms[-1].properties.pdb_info.ResidueNumber
    for at in reversed(mol.atoms):
        if at.properties.pdb_info.ResidueNumber == res:
            at_list.append(at)
        else:
            ret = Molecule()
            ret.atoms = at_list
            ret.bonds = list(
                set(chain.from_iterable(at.bonds for at in at_list)))
            return ret.copy()
示例#20
0
def supstitution_symmetry(mol):
    """Returns atomic symbols of substituted atoms (or first conection of non diatomic ligand).

    Writes type of substitution symetry at the molecular properties

    Parameters
    ----------
    mol : |plams.Molecule|
        A PLAMS molecule

    Returns
    -------
    str
        Type of subsymmetry

    """
    dataframe, type_of_symetry = [], []
    ligand_identity = mol.properties.ligID

    # Defining C atoms conected to substituents and making Molecule object (cmol) out of them
    catoms = mol.properties.coords_other_arrays
    cmol = Molecule()
    for at in catoms:
        cmol.add_atom(mol.closest_atom(at))

    # If substitution is linear, simple combinations without repetition can be applied
    if len(ligand_identity) <= 2:
        if len(ligand_identity) == 1:
            logger.warning(
                "One does not simply ask for subsymmetry of one atom!")
            return
        elif len(ligand_identity) == 0:
            logger.warning(
                "One does not simply ask for subsymmetry of no atom")
            return
        else:
            subsymmetry = 'linear'
    else:
        # Getting non zero row indices from data frame - defines symmetry type

        dataframe = get_symmetry(cmol, decimals=2)
        type_of_symetry = np.unique(dataframe.to_numpy().nonzero()[0])

        # Assign type of symetry and atomic symbols
        if list(type_of_symetry) == [0, 1, 8, 9]:
            subsymmetry = 'D2h'
        else:
            logger.warning("Subsymmetry is not recognized")
            return

    return subsymmetry
示例#21
0
def get_asa_fragments(qd: Molecule) -> Tuple[List[Molecule], Molecule]:
    """Construct the fragments for an activation strain analyses.

    Parameters
    ----------
    qd : |plams.Molecule|
        A Molecule whose atoms' properties should be marked with `pdb_info.ResidueName`.
        Atoms in the core should herein be marked with ``"COR"``.

    Returns
    -------
    :class:`list` [|plams.Molecule|] and |plams.Molecule|
        A list of ligands and the core.
        Fragments are defined based on connectivity patterns (or lack thereof).

    """
    # Delete all atoms within the core
    mol_complete = qd.copy()
    core = Molecule()
    core.properties = mol_complete.properties.copy()

    core_atoms = [at for at in mol_complete if at.properties.pdb_info.ResidueName == 'COR']
    for atom in core_atoms:
        mol_complete.delete_atom(atom)
        atom.mol = core

    core.atoms = core_atoms
    mol_complete.properties.name += '_frags'
    core.properties.name += '_core'

    # Fragment the molecule
    ligand_list = mol_complete.separate()

    # Set atomic properties
    for at1, at2 in zip(chain(*ligand_list), mol_complete):
        at1.properties.symbol = at2.properties.symbol
        at1.properties.charge_float = at2.properties.charge_float
    for at1, at2 in zip(core, qd):
        at1.properties.symbol = at2.properties.symbol
        at1.properties.charge_float = at2.properties.charge_float

    # Set the prm parameter which points to the created .prm file
    name = mol_complete.properties.name[:-1]
    path = mol_complete.properties.path
    prm = mol_complete.properties.prm
    for mol in ligand_list:
        mol.properties.name = name
        mol.properties.path = path
        mol.properties.prm = prm

    return ligand_list, core
示例#22
0
def set_qd(qd: Molecule, mol_dict: Settings) -> Molecule:
    """Update quantum dots imported by :func:`.read_mol`."""
    # Create ligand (and anchor) molecules
    ligand = molkit.from_smiles(mol_dict.ligand_smiles)
    ligand_rdmol = molkit.to_rdmol(ligand)
    anchor = molkit.from_smiles(mol_dict.ligand_anchor)
    anchor_rdmol = molkit.to_rdmol(anchor)
    qd_rdmol = molkit.to_rdmol(qd)

    # Create arrays of atomic indices of the core and ligands
    lig_idx = 1 + np.array(qd_rdmol.GetSubstructMatches(ligand_rdmol))
    core_idx = np.arange(1, len(qd))[~lig_idx]
    lig_idx = lig_idx.ravel().tolist()
    core_idx = core_idx.tolist()

    # Guess bonds
    if mol_dict.guess_bonds:
        qd.guess_bonds(atom_subset=[qd[i] for i in lig_idx])

    # Reorder all atoms: core atoms first followed by ligands
    qd.atoms = [qd[i] for i in core_idx] + [qd[j] for i in lig_idx for j in i]

    # Construct a list with the indices of all ligand anchor atoms
    core_idx_max = 1 + len(core_idx)
    _anchor_idx = ligand_rdmol.GetSubstructMatch(anchor_rdmol)[0]
    start = core_idx_max + _anchor_idx
    stop = core_idx_max + _anchor_idx + np.product(lig_idx.shape)
    step = len(ligand)
    anchor_idx = list(range(start, stop, step))

    # Update the properties of **qd**
    for i in anchor_idx:
        qd[i].properties.anchor = True
    qd.properties.indices = list(range(1, core_idx_max)) + anchor_idx
    qd.properties.job_path = []
    qd.properties.name = mol_dict.name
    qd.properties.path = mol_dict.path
    qd.properties.ligand_smiles = Chem.CanonSmiles(mol_dict.ligand_smiles)
    qd.properties.ligand_anchor = f'{ligand[_anchor_idx].symbol}{_anchor_idx}'

    # Update the pdb_info of all atoms
    for i, at in enumerate(qd, 1):
        at.properties.pdb_info.SerialNumber = i
        if i <= core_idx_max:  # A core atom
            at.properties.pdb_info.ResidueNumber = 1
        else:  # A ligand atom
            at.properties.pdb_info.ResidueNumber = 2 + int(
                (i - core_idx_max) / len(ligand))
示例#23
0
def test_adf_mock(mocker: MockFixture):
    """Mock the ADF output."""
    mol = Molecule(PATH_MOLECULES / "acetonitrile.xyz")
    job = adf(templates.geometry, mol)

    run_mocked = mocker.patch("qmflows.run")
    jobname = "ADFjob"
    dill_path = WORKDIR / jobname / "ADFjob.dill"
    plams_dir = WORKDIR / jobname
    run_mocked.return_value = ADF_Result(templates.geometry,
                                         mol,
                                         jobname,
                                         dill_path=dill_path,
                                         work_dir=plams_dir,
                                         plams_dir=plams_dir)
    rs = run_mocked(job)
    assertion.isfinite(rs.energy)
    assertion.isfinite(rs.h**o)
    assertion.isfinite(rs.lumo)
    # Array of runtime for each optimization
    assertion.isfinite(rs.runtime[-1])
    # 3-dimensional vector
    assertion.len_eq(rs.dipole, 3)
    # number of steps until convergence
    assertion.eq(rs.optcycles, 8)

    # Test molecule
    # Molecule
    mol = rs.molecule
    assertion.isinstance(mol, Molecule)
    assertion.len_eq(mol, 6)  # there are 6 atoms
示例#24
0
def fun_ethylene(scratch_path):
    """
    Test Ethylene single
    """
    geometry = Molecule('test/test_files/ethylene.xyz')
    job_settings = prepare_cp2k_settings(geometry, scratch_path)

    cp2k_result = run(cp2k(job_settings, geometry, work_dir=scratch_path))

    # Path to the HDF5 file
    hdf5_file = 'quantum.hdf5'

    # Path to the molecular orbitals energies and  coefficients
    path_es = 'ethylene/cp2k_job/cp2k/mo/eigenvalues'
    path_css = 'ethylene/cp2k_job/cp2k/mo/coefficients'

    with h5py.File(hdf5_file) as f5:
        dump_to_hdf5(cp2k_result.orbitals,
                     'cp2k',
                     f5,
                     project_name='ethylene',
                     job_name=cp2k_result.job_name,
                     property_to_dump='orbitals')
        energies = f5[path_es].value
        coefficients = f5[path_css].value

    print("Energy array shape: ", energies.shape)
    print("Coefficients array shape: ", coefficients.shape)
    assert (energies.shape == (40, )) and (coefficients.shape == (46, 40))
示例#25
0
def test_opt_orca():
    """Test Orca input generation and run functions."""
    h2o = Molecule(PATH_MOLECULES / "h2o.xyz", 'xyz', charge=0, multiplicity=1)

    h2o_geometry = dftb(templates.geometry, h2o)

    s = Settings()
    # generic keyword "basis" must be present in the generic dictionary
    s.basis = "sto_dzp"
    # s.specific.adf.basis.core = "large"

    r = templates.singlepoint.overlay(s)
    h2o_singlepoint = orca(r, h2o_geometry.molecule)

    dipole = h2o_singlepoint.dipole

    final_result = run(dipole, n_processes=1)

    expected_dipole = [0.82409, 0.1933, -0.08316]
    diff = sqrt(sum((x - y)**2 for x, y in zip(final_result, expected_dipole)))
    logger.info(
        f"Expected dipole computed with Orca 3.0.3 is: {expected_dipole}")
    logger.info(f"Actual dipole is: {final_result}")

    assertion.lt(diff, 1e-2)
示例#26
0
def test_linear_ts():
    """
    compute a first approximation to the TS.
    """
    # Read the Molecule from file
    cnc = Molecule('test/test_files/C-N-C.mol', 'mol')

    # User define Settings
    settings = Settings()
    settings.functional = "pbe"
    settings.basis = "SZ"
    settings.specific.dftb.dftb.scc

    constraint1 = Distance(1, 5)
    constraint2 = Distance(3, 4)

    # scan input
    pes = PES(cnc, constraints=[constraint1, constraint2],
              offset=[2.3, 2.3], get_current_values=False,
              nsteps=2, stepsize=[0.1, 0.1])

    # returns a set of results object containing the output of
    # each point in the scan
    lt = pes.scan([dftb, adf], settings)

    # Gets the object presenting the molecule
    # with the maximum energy calculated from the scan
    apprTS = select_max(lt, "energy")

    # Run the TS optimization, using the default TS template
    ts = run(apprTS)

    expected_energy = -3.219708290363864

    assert abs(ts.energy - expected_energy) < 0.02
示例#27
0
文件: parser.py 项目: SCM-NV/qmflows
def string_array_to_molecule(parser_fun: ParserElement,
                             file_name: PathLike,
                             mol: Optional_[Molecule] = None) -> Molecule:
    """Convert a Numpy string array.

    It takes an array like:
    [['C', '-1.487460', '-0.028670', '-0.000060'],
    ['O', '0.376340', '0.028670', '-0.000060'],
    ['H', '-1.818910', '-1.067060', '-0.000060'],
    ['H', '-1.866470', '0.473700', '0.889930'],
    ['H', '-1.866470', '0.473700', '-0.890040'],
    ['H', '0.756720', '-0.950010', '-0.000060']]

    and covert it to a plams ``Molecule``.
    """
    mols = parse_file(parser_fun, file_name).asList()
    last_mol = np.array(mols[-1])
    elems = last_mol[:, 0]
    coords = np.array(last_mol[:, 1:], dtype=float)

    if mol:
        if len(coords) == len(mol):
            mol.from_array(coords)
        else:
            raise RuntimeError('Output molecule does not match input molecule')

    else:
        mol = Molecule()
        for e, c in zip(elems, coords):
            mol.add_atom(Atom(symbol=e, coords=tuple(c)))
    return mol
示例#28
0
def test_c2pk_cell_opt() -> None:
    """Test CP2K cell optimization calculations with the :class:`CP2K_MM` class."""
    mol = Molecule(PATH / 'cspbbr3_3d.xyz')

    s = Settings()
    s.specific.cp2k += cell_opt.specific.cp2k_mm.copy()
    s.specific.cp2k.motion.cell_opt.max_iter = 10
    s.specific.cp2k.motion.print['forces low'].filename = ''

    s.gmax = [22, 22, 22]
    s.cell_parameters = [25.452, 35.995, 24.452]
    s.charge = {
        'param': 'charge',
        'Cs': 0.2,
        'Pb': 0.4,
        'Br': -0.2,
    }
    s.lennard_jones = {
        'param': ('sigma', 'epsilon'),
        'unit': ('nm', 'kjmol'),
        'Cs Cs': (0.585, 1),
        'Cs Pb': (0.510, 1),
        'Br Se': (0.385, 1),
        'Pb Pb': (0.598, 1),
        'Br Pb': (0.290, 1),
        'Br Br': (0.426, 1),
    }

    job = cp2k_mm(settings=s, mol=mol, job_name='cp2k_mm_cell_opt')
    result = run(job, path=PATH)
    assertion.eq(result.status, 'successful')
示例#29
0
def read_unique_atomic_labels(path_traj_xyz: str) -> set:
    """
    Return the unique atomic labels
    """
    mol = Molecule(path_traj_xyz, 'xyz')

    return set(at.symbol for at in mol.atoms)
示例#30
0
def get_surface_charge_adf(mol: Molecule, job: Type[Job],
                           s: Settings) -> Settings:
    """Perform a gas-phase ADF single point and return settings for a COSMO-ADF single point.

    The previous gas-phase calculation as moleculair fragment.

    Parameters
    ----------
    mol : |plams.Molecule|_
        A PLAMS Molecule.

    job : |Callable|_
        A type Callable of a class derived from :class:`Job`, e.g. :class:`AMSJob`
        or :class:`Cp2kJob`.

    s : |plams.Settings|_
        The settings for **job**.

    Returns
    -------
    |plams.Settings|_
        A new Settings intance, constructed from **s**, suitable for DFT COSMO-RS calculations.

    """
    s.input.allpoints = ''
    results = mol.job_single_point(job, s, ret_results=True)
    coskf = get_coskf(results)

    for at in mol:
        at.properties.adf.fragment = 'gas'
    s.update(get_template('qd.yaml')['COSMO-ADF'])
    s.input.fragments.gas = coskf

    return s
示例#31
0
def get_surface_charge(mol: Molecule, job: Type[Job],
                       s: Settings) -> Optional[str]:
    """Construct the COSMO surface of the **mol**.

    Parameters
    ----------
    mol : |plams.Molecule|_
        A PLAMS Molecule.

    job : |Callable|_
        A type Callable of a class derived from :class:`Job`, e.g. :class:`AMSJob`
        or :class:`Cp2kJob`.

    s : |plams.Settings|_
        The settings for **job**.

    Returns
    -------
    |plams.Settings|_
        Optional: The path+filename of a file containing COSMO surface charges.

    """
    s = Settings(s)
    # Special procedure for ADF jobs
    # Use the gas-phase electronic structure as a fragment for the COSMO single point
    if job is ADFJob:
        s = get_surface_charge_adf(mol, job, s)

    s.runscript.post = '$ADFBIN/cosmo2kf "mopac.cos" "mopac.coskf"'
    results = mol.job_single_point(job, s, ret_results=True)
    return get_coskf(results)
示例#32
0
文件: rkffile.py 项目: BvB93/PLAMS
 def get_plamsmol(self):
     """
             Creates a PLAMS molecule object from the xyz-trajectory file
             """
     section_dict = self.file_object.read_section('Molecule')
     plamsmol = Molecule._mol_from_rkf_section(section_dict)
     return plamsmol
示例#33
0
def main(file_xyz, cell, restart, basis, basis_folder):
    """Define which systems need to be calculated."""
    system = Molecule(file_xyz)

    # Set path for basis set
    basisCP2K = join(basis_folder, "BASIS_MOLOPT")
    potCP2K = join(basis_folder, "GTH_POTENTIALS")

    # Settings specifics
    s = templates.geometry
    s.basis = basis
    s.potential = "GTH-PBE"
    s.cell_parameters = cell
    s.specific.cp2k.force_eval.dft.basis_set_file_name = basisCP2K
    s.specific.cp2k.force_eval.dft.potential_file_name = potCP2K
    s.specific.cp2k.force_eval.dft.uks = ''
    s.specific.cp2k.force_eval.dft.charge = '-1'
    s.specific.cp2k.force_eval.dft.multiplicity = '2'
    s.specific.cp2k.force_eval.dft.wfn_restart_file_name = f'{restart}'

    # =======================
    # Compute OPT files with CP2k
    # =======================

    result = run(cp2k(s, system))

    # ======================
    # Output the results
    # ======================

    print(result.energy)
示例#34
0
def example_FDE_fragments():
    # For the purpose of the example, define xyz files here:
    xyz1 = io.StringIO('''3

    O         0.00000000000000     -2.29819386240000      1.63037963360000
    H        -0.76925379540000     -2.28223123190000      2.22684542850000
    H         0.76925379540000     -2.28223123190000      2.22684542850000''')

    xyz2 = io.StringIO('''3

    O         0.00000000000000      2.29819386240000      1.63037963360000
    H        -0.76925379540000      2.28223123190000      2.22684542850000
    H         0.76925379540000      2.28223123190000      2.22684542850000''')

    xyz3 = io.StringIO('''3

    O         0.00000000000000      0.00000000000000     -0.26192472620000
    H         0.00000000000000      0.77162768440000      0.34261631290000
    H         0.00000000000000     -0.77162768440000      0.34261631290000''')

    # Read the Molecule from file
    m_h2o_1 = Molecule()
    m_h2o_1.readxyz(xyz1, 1)
    m_h2o_2 = Molecule()
    m_h2o_2.readxyz(xyz2, 1)
    m_mol = Molecule()
    m_mol.readxyz(xyz3, 1)

    settings = Settings()
    settings.basis = 'SZ'
    settings.specific.adf.nosymfit = ''

    # Prepare first water fragment
    r_h2o_1 = adf(templates.singlepoint.overlay(settings), m_h2o_1, job_name="h2o_1")

    # Prepare second water fragment
    r_h2o_2 = adf(templates.singlepoint.overlay(settings), m_h2o_2, job_name="h2o_2")

    frags = gather(schedule(Fragment)(r_h2o_1, m_h2o_1, isfrozen=True),
                   schedule(Fragment)(r_h2o_2, m_h2o_2, isfrozen=True),
                   Fragment(None, m_mol))

    job_fde = adf_fragmentsjob(templates.singlepoint. overlay(settings), frags,
                               job_name="test_fde_fragments")

    # Perform FDE job and get dipole
    # This gets the dipole moment of the active subsystem only
    dipole_fde = run(job_fde.dipole)

    print('FDE dipole:', dipole_fde)

    return dipole_fde
示例#35
0
def test_fail_gamess():
    """
    Gamess should return ``None`` if a calculation fails.
    """
    folder = tempfile.mkdtemp(prefix="qmflows_")
    symmetry = "Cpi"  # Erroneous Keyowrkd
    methanol = Molecule('test/test_files/ion_methanol.xyz')
    methanol.properties['symmetry'] = symmetry

    s = Settings()
    s.specific.gamess.contrl.nzvar = 12
    s.specific.gamess.pcm.solvnt = 'water'
    s.specific.gamess.basis.gbasis = 'sto'
    s.specific.gamess.basis.ngauss = 3

    inp = templates.geometry.overlay(s)
    methanol_geometry = gamess(inp, methanol, job_name="fail_gamess",
                               work_dir='/tmp')

    try:
        result = run(methanol_geometry.molecule, path=folder)
        assert isNone(result)
    finally:
        remove(folder)
示例#36
0
def create_molecule(name, r=2.25):
    mol = Molecule()
    mol.add_atom(Atom(symbol='Ba', coords=(0, 0, 0)))
    mol.add_atom(Atom(symbol='F', coords=(0, 0, r)))

    return mol