Exemplo n.º 1
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))
Exemplo n.º 2
0
def test_SerMolecule():
    """Test molecule serialization."""
    mol = molkit.from_smiles("c1ccccc1CC")
    registry = packages.registry()
    encoded_molecule = registry.deep_encode(mol)
    decoded_molecule = registry.deep_decode(encoded_molecule)
    assert len(mol) == len(decoded_molecule)
Exemplo n.º 3
0
def test_freeze_with_adf():
    mol = molkit.from_smiles('CO')
    s = Settings()
    s.freeze = ["C", "O"]
    expected_settings = Settings({'freeze': ["C", "O"], 'specific': adf_const})
    assert str(adf.generic2specific(s, mol)) == str(expected_settings)
    s.freeze = [1, 2]
    expected_settings = Settings({'freeze': [1, 2], 'specific': adf_const})
    assert str(adf.generic2specific(s, mol)) == str(expected_settings)
Exemplo n.º 4
0
def test_selected_atoms_with_dftb():
    mol = molkit.from_smiles('CO')
    s = Settings()
    s.selected_atoms = ["H"]
    expected_settings = Settings(
        {'selected_atoms': ['H'], 'specific': dftb_const})
    assert dftb.generic2specific(s, mol) == expected_settings
    s.selected_atoms = indices
    expected_settings = Settings(
        {'selected_atoms': indices, 'specific': dftb_const})
    assert str(dftb.generic2specific(s, mol)) == str(expected_settings)
Exemplo n.º 5
0
def test_freeze_with_dftb():
    mol = molkit.from_smiles('CO')
    s = Settings()
    s.freeze = ["C", "O"]
    expected_settings = Settings(
        {'freeze': ['C', 'O'], 'specific': dftb_const})
    assert str(dftb.generic2specific(s, mol)) == str(expected_settings)
    s.freeze = [1, 2]
    expected_settings = Settings(
        {'freeze': [1, 2], 'specific': dftb_const})
    assert str(dftb.generic2specific(s, mol)) == str(expected_settings)
Exemplo n.º 6
0
def test_freeze_with_adf():
    mol = molkit.from_smiles('CO')
    s = Settings()
    s.freeze = ["C", "O"]
    expected_settings = Settings(
        {'freeze': ["C", "O"], 'specific': adf_const})
    assert str(adf.generic2specific(s, mol)) == str(expected_settings)
    s.freeze = [1, 2]
    expected_settings = Settings(
        {'freeze': [1, 2], 'specific': adf_const})
    assert str(adf.generic2specific(s, mol)) == str(expected_settings)
Exemplo n.º 7
0
def test_freeze_with_dftb():
    mol = molkit.from_smiles('CO')
    s = Settings()
    s.freeze = ["C", "O"]
    expected_settings = Settings({
        'freeze': ['C', 'O'],
        'specific': dftb_const
    })
    assert str(dftb.generic2specific(s, mol)) == str(expected_settings)
    s.freeze = [1, 2]
    expected_settings = Settings({'freeze': [1, 2], 'specific': dftb_const})
    assert str(dftb.generic2specific(s, mol)) == str(expected_settings)
Exemplo n.º 8
0
def test_freeze_with_adf():
    """Test the freeze keyword with ADF."""
    mol = molkit.from_smiles('CO')
    s = Settings()
    s.freeze = ["C", "O"]
    expected_settings = Settings(
        {'freeze': ["C", "O"], 'specific': adf_const})
    assertion.eq(str(adf.generic2specific(s, mol)), str(expected_settings))
    s.freeze = [1, 2]
    expected_settings = Settings(
        {'freeze': [1, 2], 'specific': adf_const})
    assertion.eq(str(adf.generic2specific(s, mol)), str(expected_settings))
Exemplo n.º 9
0
def test_selected_atoms_with_gamess():
    mol = molkit.from_smiles('CO')
    s = Settings()
    s.selected_atoms = ["H"]
    expected_settings = Settings(
        {'selected_atoms': ['H'], 'specific': gamess_sett})
    assert str(gamess.generic2specific(s, mol)) == str(expected_settings)
    s = Settings()
    s.selected_atoms = indices
    expected_settings = Settings(
        {'selected_atoms': indices, 'specific': gamess_sett})
    assert str(gamess.generic2specific(s, mol)) == str(expected_settings)
Exemplo n.º 10
0
def test_freeze_with_dftb():
    """Test freeze keyword for DFTB."""
    mol = molkit.from_smiles('CO')
    s = Settings()
    s.freeze = ["C", "O"]
    expected_settings = Settings(
        {'freeze': ['C', 'O'], 'specific': dftb_const})
    assertion.eq(str(dftb.generic2specific(s, mol)), str(expected_settings))
    s.freeze = [1, 2]
    expected_settings = Settings(
        {'freeze': [1, 2], 'specific': dftb_const})
    assertion.eq(str(dftb.generic2specific(s, mol)), str(expected_settings))
Exemplo n.º 11
0
def test_selected_atoms_with_dftb():
    """Test the DFTB selection atoms funcionality."""
    mol = molkit.from_smiles('CO')
    s = Settings()
    s.selected_atoms = ["H"]
    expected_settings = Settings(
        {'selected_atoms': ['H'], 'specific': dftb_const})
    assertion.eq(dftb.generic2specific(s, mol), expected_settings)
    s.selected_atoms = indices
    expected_settings = Settings(
        {'selected_atoms': indices, 'specific': dftb_const})
    assertion.eq(str(dftb.generic2specific(s, mol)), str(expected_settings))
Exemplo n.º 12
0
def test_selected_atoms_with_adf():
    """Test the ADF atoms selection features."""
    mol = molkit.from_smiles('CO')
    s = Settings()
    s.selected_atoms = ["H"]
    expected_settings = Settings(
        {'selected_atoms': ['H'], 'specific': adf_const})

    assertion.eq(str(adf.generic2specific(s, mol)), str(expected_settings))
    s.selected_atoms = indices
    expected_settings = Settings(
        {'selected_atoms': indices, 'specific': adf_const})
    assertion.eq(str(adf.generic2specific(s, mol)), str(expected_settings))
Exemplo n.º 13
0
def test_dftb_props():
    """
    Get properties from DFTB freq calc
    """

    mol = molkit.from_smiles('F[H]')
    result = run(dftb(templates.freq, mol, job_name='dftb_FH'))
    expected_energy = -4.76
    assert abs(result.energy - expected_energy) < 0.01
    assert len(result.dipole) == 3
    expected_frequency = 3460.92
    assert abs(result.frequencies - expected_frequency) < 0.1
    assert len(result.charges) == 2
    assert abs(result.charges[0] + result.charges[1]) < 1e-6
Exemplo n.º 14
0
def test_adf_props():
    """
    Get properties from ADF freq calc
    """

    mol = molkit.from_smiles('F[H]')
    result = run(adf(templates.freq, mol, job_name='adf_FH'))
    expected_energy = -0.30
    assert abs(result.energy - expected_energy) < 0.01
    assert len(result.dipole) == 3
    expected_frequency = 3480.90
    assert abs(result.frequencies[1] - expected_frequency) < 0.1
    assert len(result.charges) == 2
    assert abs(result.charges[0] + result.charges[1]) < 1e-6
Exemplo n.º 15
0
def test_selected_atoms_with_orca():
    """Test atom selection features for Orca."""
    mol = molkit.from_smiles('CO')
    s = Settings()
    s.selected_atoms = ["H"]
    expected_settings = Settings(
        {'selected_atoms': ['H'], 'specific': orca_const})
    assertion.eq(str(orca.generic2specific(s, mol)), str(expected_settings))

    s.selected_atoms = indices
    expected_settings = Settings(
        {'selected_atoms': indices, 'specific': orca_const})

    assertion.eq(str(orca.generic2specific(s, mol)), str(expected_settings))
Exemplo n.º 16
0
def test_selected_atoms_with_dftb():
    mol = molkit.from_smiles('CO')
    s = Settings()
    s.selected_atoms = ["H"]
    expected_settings = Settings({
        'selected_atoms': ['H'],
        'specific': dftb_const
    })
    assert dftb.generic2specific(s, mol) == expected_settings
    s.selected_atoms = indices
    expected_settings = Settings({
        'selected_atoms': indices,
        'specific': dftb_const
    })
    assert str(dftb.generic2specific(s, mol)) == str(expected_settings)
Exemplo n.º 17
0
def test_selected_atoms_with_gamess():
    mol = molkit.from_smiles('CO')
    s = Settings()
    s.selected_atoms = ["H"]
    expected_settings = Settings({
        'selected_atoms': ['H'],
        'specific': gamess_sett
    })
    assert str(gamess.generic2specific(s, mol)) == str(expected_settings)
    s = Settings()
    s.selected_atoms = indices
    expected_settings = Settings({
        'selected_atoms': indices,
        'specific': gamess_sett
    })
    assert str(gamess.generic2specific(s, mol)) == str(expected_settings)
Exemplo n.º 18
0
def test_hessian_transfer():
    """Test DFTB -> Orca hessian transfer."""
    h2o = molkit.from_smiles('O')
    h2o.properties.symmetry = 'C1'

    h2o_freq = dftb(templates.freq, h2o, job_name="freq").hessian

    s = Settings()
    s.inithess = h2o_freq

    h2o_opt = orca(templates.geometry.overlay(s), h2o, job_name="opt")

    energy = h2o_opt.energy
    dipole = h2o_opt.dipole

    wf = gather(energy, dipole)

    logger.info(run(wf))
Exemplo n.º 19
0
def test_orca_init_hessian():
    """Test the translation from settings to CP2K specific keywords."""
    # Read Hessian from DFTB
    PATH_RKF = PATH / "output_dftb" / "dftb_freq" / "dftb.rkf"
    assertion.truth(PATH_RKF.exists())
    hess = kfreader(PATH_RKF, section="AMSResults", prop="Hessian")
    water = molkit.from_smiles('[OH2]', forcefield='mmff')

    # Tess Hessian initialization
    s = Settings()
    hess = np.array(hess).reshape(9, 9)
    s.inithess = hess
    ORCA.handle_special_keywords(s, "inithess", hess, water)

    # Test that the hessian is readable
    new_hess = parse_hessian(s.specific.orca.geom.InHessName)
    new_hess = np.array(new_hess, dtype=np.float64)
    assertion.truth(np.allclose(hess, new_hess, atol=1e-5))
Exemplo n.º 20
0
def example_partial_geometry_opt():
    """
    Performa partial optimization freezing the Hydrogen atoms
    """
    methanol = molkit.from_smiles('CO')

    # optimize only H atoms
    s = Settings()
    s.freeze = [1, 2]
    geom_job1 = adf(templates.geometry.overlay(s), methanol, job_name='geom_job1').molecule

    # optimize only H atoms
    s = Settings()
    s.selected_atoms = ['H']
    geom_job2 = adf(templates.geometry.overlay(s), methanol, job_name='geom_job2').molecule

    geom1, geom2 = run(gather(geom_job1, geom_job2), n_processes=1)

    return geom1, geom2
Exemplo n.º 21
0
def example_generic_constraints():
    """Run different job with geometric constrains.

    This examples illustrates that, by using generic keywords, it is possible
    to call different packages interchangeably with the same Settings.
    """
    # build hydrogen fluoride molecule
    hydrogen_fluoride = molkit.from_smiles('F[H]')

    # loop over distances
    jobs = []
    for distance in [1.0, 1.1, 1.2]:
        s = Settings()
        s.constraint['dist 1 2'] = distance
        # loop over packages
        for package in [dftb, adf, orca]:
            job_name = package.pkg_name + '_' + str(distance)
            constraint_opt = package(templates.geometry.overlay(s),
                                     hydrogen_fluoride, job_name)
            jobs.append(constraint_opt)

    # run the jobs
    results = run(gather(*jobs))
    energies = [r.energy for r in results]
    names = [r.job_name for r in results]

    # put resulting energies into a dictionary
    table = {'dftb': {}, 'adf': {}, 'orca': {}}
    for r in results:
        package, distance = r.job_name.split('_')
        table[package][distance] = round(r.energy, 6)

    # print table
    hartree_to_kcalpermol = 627.094
    for package in ['dftb', 'adf', 'orca']:
        row = [package]
        for distance in ['1.0', '1.1', '1.2']:
            val = table[package][distance] - table[package]['1.0']
            row.append(round(val * hartree_to_kcalpermol, 2))
        logger.info('{:10s} {:10.2f} {:10.2f} {:10.2f}'.format(*row))

    return names, energies
Exemplo n.º 22
0
def test_hessian_transfer():
    """
    Test DFTB -> Orca hessian transfer
    """
    h2o = molkit.from_smiles('O')
    h2o.properties.symmetry = 'C1'

    h2o_freq = dftb(templates.freq, h2o, job_name="freq").hessian

    s = Settings()
    s.inithess = h2o_freq

    h2o_opt = orca(templates.geometry.overlay(s), h2o, job_name="opt")

    energy = h2o_opt.energy
    dipole = h2o_opt.dipole

    wf = gather(energy, dipole)

    print(run(wf))
Exemplo n.º 23
0
def example_freqs():
    """
    This examples illustrates the possibility to use different packages interchangeably.
    Analytical frequencies are not available for B3LYP in ADF
    This workflow captures the resulting error and submits the same job to ORCA.
    """
    # Generate water molecule
    water = molkit.from_smiles('[OH2]', forcefield='mmff')

    # Pre-optimize the water molecule
    opt_water = dftb(templates.geometry, water, job_name="dftb_geometry")

    jobs = []

    # Generate freq jobs for 3 functionals
    for functional in ['pbe', 'b3lyp', 'blyp']:
        s = Settings()
        s.basis = 'DZ'
        s.functional = functional
        # Try to perform the jobs with adf or orca, take result from  first successful calculation
        freqjob = find_first_job(is_successful, [adf, orca],
                                 templates.freq.overlay(s),
                                 opt_water.molecule,
                                 job_name=functional)
        jobs.append(freqjob)

    # Run workflow
    results = run(gather(*jobs), n_processes=1)

    # extrac results
    freqs = [r.frequencies[-3:] for r in results]
    functionals = ['pbe', 'b3lyp', 'blyp']

    # Print the result
    table = [
        "{:10s}{:10.3f}{:10.3f}{:10.3f}\n".format(fun, *fs)
        for fun, fs in zip(functionals, freqs)
    ]
    print(table)

    return freqs
Exemplo n.º 24
0
def example_partial_geometry_opt():
    """Performa partial optimization freezing the Hydrogen atoms."""
    methanol = molkit.from_smiles('CO')

    # optimize only H atoms
    s = Settings()
    s.freeze = [1, 2]
    geom_job1 = adf(templates.geometry.overlay(s),
                    methanol,
                    job_name='geom_job1').molecule

    # optimize only H atoms
    s = Settings()
    s.selected_atoms = ['H']
    geom_job2 = adf(templates.geometry.overlay(s),
                    methanol,
                    job_name='geom_job2').molecule

    geom1, geom2 = run(gather(geom_job1, geom_job2), n_processes=1)

    return geom1, geom2
Exemplo n.º 25
0
def example_freqs():
    """
    This examples illustrates the possibility to use different packages interchangeably.
    Analytical frequencies are not available for B3LYP in ADF
    This workflow captures the resulting error and submits the same job to ORCA.
    """
    # Generate water molecule
    water = molkit.from_smiles('[OH2]', forcefield='mmff')

    # Pre-optimize the water molecule
    opt_water = dftb(templates.geometry, water, job_name="dftb_geometry")

    jobs = []

    # Generate freq jobs for 3 functionals
    for functional in ['pbe', 'b3lyp', 'blyp']:
        s = Settings()
        s.basis = 'DZ'
        s.functional = functional
        # Try to perform the jobs with adf or orca, take result from  first successful calculation
        freqjob = find_first_job(is_successful, [adf, orca], templates.freq.overlay(s),
                                 opt_water.molecule, job_name=functional)
        jobs.append(freqjob)

    # Run workflow
    results = run(gather(*jobs), n_processes=1)

    # extrac results
    freqs = [r.frequencies[-3:] for r in results]
    functionals = ['pbe', 'b3lyp', 'blyp']

    # Print the result
    table = ["{:10s}{:10.3f}{:10.3f}{:10.3f}\n".format(fun, *fs)
             for fun, fs in zip(functionals, freqs)]
    print(table)

    return freqs
Exemplo n.º 26
0
"""Mock the DFTB output."""
import numpy as np
import scm.plams.interfaces.molecule.rdkit as molkit
from assertionlib import assertion
from pytest_mock import MockFixture
from scm.plams import Molecule

from qmflows import dftb, templates
from qmflows.packages.SCM import DFTB_Result
from qmflows.test_utils import PATH

WORKDIR = PATH / "output_dftb"
WATER = molkit.from_smiles('[OH2]', forcefield='mmff')


def mock_runner(mocker_instance, jobname: str) -> DFTB_Result:
    """Create a Result instance using a mocked runner."""
    run_mocked = mocker_instance.patch("qmflows.run")
    dill_path = WORKDIR / jobname / f"{jobname}.dill"
    plams_dir = WORKDIR / jobname
    run_mocked.return_value = DFTB_Result(templates.geometry, WATER, jobname, dill_path=dill_path,
                                          plams_dir=plams_dir)
    return run_mocked


def test_dftb_opt_mock(mocker: MockFixture):
    """Mock a geometry optimization using DFTB."""
    jobname = "dftb_geometry"
    job = dftb(templates.geometry, WATER, job_name=jobname)

    run_mocked = mock_runner(mocker, jobname)