Exemplo n.º 1
0
def get_qcinput_specification(
        spec_name: str,
        solvent: Optional[str] = None) -> Tuple[QCInputSpecification, str]:
    """Get the computational specification in a QCEngine-ready format

    Args:
        spec_name: Name of the quantum chemistry specification
        solvent: Name of the solvent to use
    Returns:
        - Input specification
        - Name of the program
    """

    # Make the specification
    spec = get_computation_specification(spec_name, solvent)

    # Reshape it to QCInputSpecification
    program = spec.pop("program")
    spec["model"] = {
        "method": spec.pop("method"),
    }
    if "basis" in spec:
        spec["model"]["basis"] = spec.pop("basis")
    if "keywords" in spec:
        spec["keywords"] = spec["keywords"]["values"]

    return QCInputSpecification(**spec), program
Exemplo n.º 2
0
def run_single_point(xyz: str,
                     driver: DriverEnum,
                     qc_config: QCInputSpecification,
                     charge: int = 0,
                     compute_config: Optional[Union[TaskConfig, Dict]] = None,
                     code: str = _code) -> AtomicResult:
    """Run a single point calculation

    Args:
        xyz: Structure in XYZ format
        driver: What type of property to compute: energy, gradient, hessian
        qc_config (dict): Quantum Chemistry configuration used for evaluating the energy
        charge (int): Charge of the molecule
        compute_config (TaskConfig): Configuration for the quantum chemistry code, such as parallelization settings
        code (str): Which QC code to use for the evaluation
    Returns:
        QCElemental-format result of the output
    """

    # Parse the molecule
    mol = Molecule.from_data(xyz, dtype="xyz", molecular_charge=charge)

    # Run the computation
    input_spec = AtomicInput(molecule=mol,
                             driver=driver,
                             **qc_config.dict(exclude={'driver'}))
    return compute(input_spec,
                   code,
                   local_options=compute_config,
                   raise_error=True)
Exemplo n.º 3
0
def compute_reference_energy(element: str,
                             qc_config: QCInputSpecification,
                             n_open: int,
                             code: str = _code) -> float:
    """Compute the energy of an isolated atom in vacuum

    Args:
        element (str): Symbol of the element
        qc_config (QCInputSpecification): Quantum Chemistry configuration used for evaluating he energy
        n_open (int): Number of open atomic orbitals
        code (str): Which QC code to use for the evaluation
    Returns:
        (float): Energy of the isolated atom
    """

    # Make the molecule
    xyz = f'1\n{element}\n{element} 0 0 0'
    mol = Molecule.from_data(xyz,
                             dtype='xyz',
                             molecular_multiplicity=n_open,
                             molecular_charge=0)

    # Run the atomization energy calculation
    input_spec = AtomicInput(molecule=mol,
                             driver='energy',
                             **qc_config.dict(exclude={'driver'}))
    result = compute(input_spec, code, raise_error=True)

    return result.return_result
Exemplo n.º 4
0
def test_torsiondrive_generic():

    input_data = TorsionDriveInput(
        keywords=TDKeywords(dihedrals=[(2, 0, 1, 5)], grid_spacing=[180]),
        input_specification=QCInputSpecification(driver=DriverEnum.gradient,
                                                 model=Model(method="UFF",
                                                             basis=None)),
        initial_molecule=[qcng.get_molecule("ethane")] * 2,
        optimization_spec=OptimizationSpecification(
            procedure="geomeTRIC",
            keywords={
                "coordsys": "dlc",
                "maxiter": 300,
                "program": "rdkit",
            },
        ),
    )

    ret = qcng.compute_procedure(input_data, "torsiondrive", raise_error=True)

    assert ret.error is None
    assert ret.success

    expected_grid_ids = {"180", "0"}

    assert {*ret.optimization_history} == expected_grid_ids

    assert {*ret.final_energies} == expected_grid_ids
    assert {*ret.final_molecules} == expected_grid_ids

    assert (pytest.approx(ret.final_molecules["180"].measure([2, 0, 1, 5]),
                          abs=1.0e-2) == 180.0
            or pytest.approx(ret.final_molecules["180"].measure([2, 0, 1, 5]),
                             abs=1.0e-2) == -180.0)
    assert pytest.approx(ret.final_molecules["0"].measure([2, 0, 1, 5]),
                         abs=1.0e-2) == 0.0

    assert ret.provenance.creator.lower() == "torsiondrive"
    assert ret.optimization_history["180"][0].provenance.creator.lower(
    ) == "geometric"
    assert ret.optimization_history["180"][0].trajectory[
        0].provenance.creator.lower() == "rdkit"

    assert ret.stdout == "All optimizations converged at lowest energy. Job Finished!\n"
Exemplo n.º 5
0
from qcelemental.models.procedures import QCInputSpecification, Model
from sklearn.linear_model import BayesianRidge
from sklearn.pipeline import Pipeline

from moldesign.config import theta_nwchem_config as config
from moldesign.sample.moldqn import generate_molecules, SklearnReward
from moldesign.score import compute_score
from moldesign.score.group_contrib import GroupFeaturizer
from moldesign.select import greedy_selection
from moldesign.simulate import compute_atomization_energy, compute_reference_energy
from moldesign.utils import get_platform_info
from colmena.method_server import ParslMethodServer
from colmena.redis.queue import ClientQueues, make_queue_pairs

# Define the QCMethod used for the
spec = QCInputSpecification(model=Model(method='hf', basis='sto-3g'))
compute_config = {'nnodes': 1, 'cores_per_rank': 2}

multiplicity = {'H': 2, 'He': 1, 'Li': 2, 'C': 3, 'N': 4, 'O': 3, 'F': 2}


class Thinker(Thread):
    """Simple ML-enhanced optimization loop for molecular design

    Performs one simulation at a time and generates molecules in batches.
    """
    def __init__(self,
                 queues: ClientQueues,
                 initial_molecules: List[str],
                 output_dir: str,
                 n_parallel: int = 1,
Exemplo n.º 6
0
    with open(os.path.join(args.mpnn_directory, 'atom_types.json')) as fp:
        atom_types = json.load(fp)
    with open(os.path.join(args.mpnn_directory, 'bond_types.json')) as fp:
        bond_types = json.load(fp)
    with open(args.initial_database) as fp:
        initial_database = json.load(fp)
    with open(args.reference_energies) as fp:
        ref_energies = json.load(fp)
    with open(args.initial_search_space) as fp:
        initial_search_space = json.load(fp)
    with open(args.initial_agent, 'rb') as fp:
        agent = pkl.load(fp)
    with open(args.qc_spec) as fp:
        qc_spec = json.load(fp)
    code = qc_spec.pop("program")
    qc_spec = QCInputSpecification(**qc_spec)

    # Make the reward function
    agent.env.reward_fn = MPNNReward(mpnn,
                                     atom_types,
                                     bond_types,
                                     maximize=False)

    # Create an output directory with the time and run parameters
    start_time = datetime.utcnow()
    params_hash = hashlib.sha256(
        json.dumps(run_params).encode()).hexdigest()[:6]
    out_dir = os.path.join(
        'runs', f'{start_time.strftime("%d%b%y-%H%M%S")}-{params_hash}')
    os.makedirs(out_dir, exist_ok=True)
Exemplo n.º 7
0
from moldesign.simulate import compute_atomization_energy, compute_reference_energy
from qcelemental.models.procedures import QCInputSpecification

qcspec = QCInputSpecification(driver='gradient',
                              model=dict(method='hf', basis='6-31g'))


def test_simple_mol():
    assert compute_atomization_energy('C', qcspec, {'C': -2, 'H': -3}) < 0


def test_ref_energy():
    assert compute_reference_energy('C', qcspec, 1) < 0