Beispiel #1
0
def get_pka(mol: Molecule, coskf_mol: Optional[str],
            coskf_mol_conj: Optional[str], water: str, hydronium: str,
            job: Type[Job], s: Settings) -> List[float]:
    if coskf_mol is None:
        return 5 * [np.nan]
    elif coskf_mol_conj is None:
        return 5 * [np.nan]

    s = Settings(s)
    s.input.compound[1]._h = water
    s.ignore_molecule = True

    s_dict = {}
    for name, coskf in _iter_coskf(coskf_mol_conj, coskf_mol, water,
                                   hydronium):
        _s = s.copy()
        _s.name = name
        _s.input.compound[0]._h = coskf
        s_dict[name] = _s

    # Run the job
    mol_name = mol.properties.name
    job_list = [CRSJob(settings=s, name=name) for name, s in s_dict.items()]
    results_list = [_crs_run(job, mol_name) for job in job_list]

    # Extract solvation energies and activity coefficients
    E_solv = {}
    for name, results in zip(("acid", "base", "solvent", "solvent_conj"),
                             results_list):
        results.wait()
        try:
            E_solv[name] = _E = results.get_energy()
            assert _E is not None
            logger.info(f'{results.job.__class__.__name__}: {mol_name} pKa '
                        f'calculation ({results.job.name}) is successful')
        except Exception:
            logger.error(f'{results.job.__class__.__name__}: {mol_name} pKa '
                         f'calculation ({results.job.name}) has failed')
            E_solv[name] = np.nan

    try:
        mol.properties.job_path += [
            join(job.path, job.name + '.in') for job in job_list
        ]
    except IndexError:  # The 'job_path' key is not available
        mol.properties.job_path = [
            join(job.path, job.name + '.in') for job in job_list
        ]

    ret = [E_solv[k] for k in ("acid", "base", "solvent", "solvent_conj")]
    ret.append(_get_pka(**E_solv))
    return ret
Beispiel #2
0
def get_solv(mol: Molecule, solvent_list: Iterable[str], coskf: Optional[str],
             job: Type[Job], s: Settings) -> List[float]:
    """Calculate the solvation energy of *mol* in various *solvents*.

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

    solvent_list : |List|_ [|str|_]
        A list of solvent molecules (*i.e.* .coskf files).

    coskf : str, optional
        The path+filename of the .coskf file of **mol**.

    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
    -------
    |list|_ [|float|_] & |list|_ [|float|_]
        A list of solvation energies and gammas.

    """
    # Return 3x np.nan if no coskf is None (i.e. the COSMO-surface construction failed)
    if coskf is None:
        i = 1 + 2 * len(solvent_list)
        return i * [np.nan]

    # Prepare a list of job settings
    s = Settings(s)
    s.input.compound[0]._h = coskf
    s.ignore_molecule = True
    s_list = []
    for solv in solvent_list:
        _s = s.copy()
        _s.name = solv.rsplit('.', 1)[0].rsplit(os.sep, 1)[-1]
        _s.input.compound[1]._h = solv
        s_list.append(_s)

    # Run the job
    mol_name = mol.properties.name
    job_list = [CRSJob(settings=s, name=s.name) for s in s_list]
    results_list = [
        _crs_run(job, mol_name, calc_type="pKa") for job in job_list
    ]

    # Extract solvation energies and activity coefficients
    E_solv = []
    Gamma = []
    for results in results_list:
        results.wait()
        try:
            E_solv.append(results.get_energy())
            Gamma.append(results.get_activity_coefficient())
            logger.info(
                f'{results.job.__class__.__name__}: {mol_name} activity coefficient '
                f'calculation ({results.job.name}) is successful')
        except Exception:
            logger.error(
                f'{results.job.__class__.__name__}: {mol_name} activity coefficient '
                f'calculation ({results.job.name}) has failed')
            E_solv.append(np.nan)
            Gamma.append(np.nan)

    try:
        mol.properties.job_path += [
            join(job.path, job.name + '.in') for job in job_list
        ]
    except IndexError:  # The 'job_path' key is not available
        mol.properties.job_path = [
            join(job.path, job.name + '.in') for job in job_list
        ]

    logp = _get_logp(s_list[0], name=mol_name, logger=logger)
    return E_solv + Gamma + [logp]