def test_compute_dataset(fractal_compute_server):

    client = portal.FractalClient(fractal_compute_server.get_address(""))
    ds_name = "He_PES"
    ds = portal.collections.Dataset(ds_name, client, ds_type="ie")

    # Adds options
    option = portal.data.get_options("psi_default")

    opt_ret = client.add_options([option])
    opt_key = option["name"]

    # Add two helium dimers to the DB at 4 and 8 bohr
    He1 = portal.Molecule([[2, 0, 0, -2], [2, 0, 0, 2]], dtype="numpy", units="bohr", frags=[1])
    ds.add_ie_rxn("He1", He1, attributes={"r": 4}, reaction_results={"default": {"Benchmark": 0.0009608501557}})

    # Save the DB and re-acquire via classmethod
    r = ds.save()
    ds = portal.collections.Dataset.from_server(client, ds_name)
    assert "Dataset(" in str(ds)

    # Test collection lists
    ret = client.list_collections()
    assert ret == {"dataset": [ds_name]}

    ret = client.list_collections("dataset")
    assert ret == [ds_name]

    He2 = portal.Molecule([[2, 0, 0, -4], [2, 0, 0, 4]], dtype="numpy", units="bohr", frags=[1])
    ds.add_ie_rxn("He2", He2, attributes={"r": 4}, reaction_results={"default": {"Benchmark": -0.00001098794749}})

    # Save the DB and overwrite the result, reacquire via client
    r = ds.save(overwrite=True)
    ds = client.get_collection("dataset", ds_name)

    # Compute SCF/sto-3g
    ret = ds.compute("SCF", "STO-3G")
    assert len(ret["submitted"]) == 3
    fractal_compute_server.objects["queue_nanny"].await_results()

    # Query computed results
    assert ds.query("SCF", "STO-3G")
    assert pytest.approx(0.6024530476071095, 1.e-5) == ds.df.loc["He1", "SCF/STO-3G"]
    assert pytest.approx(-0.006895035942673289, 1.e-5) == ds.df.loc["He2", "SCF/STO-3G"]

    # Check results
    assert ds.query("Benchmark", "", reaction_results=True)
    assert pytest.approx(0.00024477933196125805, 1.e-5) == ds.statistics("MUE", "SCF/STO-3G")
Example #2
0
def test_service_torsiondrive(dask_server_fixture):

    client = portal.FractalClient(dask_server_fixture.get_address())

    # Add a HOOH
    hooh = portal.data.get_molecule("hooh.json")
    mol_ret = client.add_molecules({"hooh": hooh})

    # Geometric options
    torsiondrive_options = {
        "torsiondrive_meta": {
            "dihedrals": [[0, 1, 2, 3]],
            "grid_spacing": [90]
        },
        "optimization_meta": {
            "program": "geometric",
            "coordsys": "tric",
        },
        "qc_meta": {
            "driver": "gradient",
            "method": "UFF",
            "basis": "",
            "options": "none",
            "program": "rdkit",
        },
    }

    ret = client.add_service("torsiondrive", [mol_ret["hooh"]],
                             torsiondrive_options)
    compute_key = ret[0]

    # Manually handle the compute
    nanny = dask_server_fixture.objects["queue_nanny"]
    nanny.await_services(max_iter=5)
    assert len(nanny.list_current_tasks()) == 0

    # Get a TorsionDriveORM result and check data
    result = client.get_procedures({"procedure": "torsiondrive"})[0]
    assert isinstance(str(result), str)  # Check that repr runs

    assert pytest.approx(0.002597541340221565,
                         1e-5) == result.final_energies(0)
    assert pytest.approx(0.000156553761859276,
                         1e-5) == result.final_energies(90)
    assert pytest.approx(0.000156553761859271,
                         1e-5) == result.final_energies(-90)
    assert pytest.approx(0.000753492556057886,
                         1e-5) == result.final_energies(180)
Example #3
0
def torsiondrive_fixture(dask_server_fixture):

    # Cannot use this fixture without these services. Also cannot use `mark` and `fixture` decorators
    pytest.importorskip("torsiondrive")
    pytest.importorskip("geometric")
    pytest.importorskip("rdkit")

    client = portal.FractalClient(dask_server_fixture.get_address())

    # Add a HOOH
    hooh = portal.data.get_molecule("hooh.json")
    mol_ret = client.add_molecules({"hooh": hooh})
    default_grid_spacing = 90

    # Geometric options
    torsiondrive_options = {
        "torsiondrive_meta": {
            "dihedrals": [[0, 1, 2, 3]],
            "grid_spacing": [default_grid_spacing]
        },
        "optimization_meta": {
            "program": "geometric",
            "coordsys": "tric",
        },
        "qc_meta": {
            "driver": "gradient",
            "method": "UFF",
            "basis": "",
            "options": "none",
            "program": "rdkit",
        },
    }

    def spin_up_test(grid_spacing=default_grid_spacing, **keyword_augments):
        instance_options = copy.deepcopy(torsiondrive_options)
        instance_options["torsiondrive_meta"]["grid_spacing"] = [grid_spacing]

        # instance_options = {**instance_options, **keyword_augments}
        recursive_dict_merge(instance_options, keyword_augments)
        ret = client.add_service("torsiondrive", [mol_ret["hooh"]],
                                 instance_options)
        nanny = dask_server_fixture.objects["queue_nanny"]
        nanny.await_services(max_iter=5)
        assert len(nanny.list_current_tasks()) == 0
        return ret

    yield spin_up_test, client
def test_compute_biofragment(fractal_compute_server):

    # Obtain a client and build a BioFragment
    client = portal.FractalClient(fractal_compute_server.get_address(""))

    butane = portal.data.get_molecule("butane.json")
    frag = portal.collections.BioFragment("CCCC", butane, client=client)

    # Options
    torsiondrive_options = {
        "torsiondrive_meta": {
            "internal_grid_spacing": [90],
            "terminal_grid_spacing": [90],
        },
        "optimization_meta": {
            "program": "geometric",
            "coordsys": "tric",
        },
        "qc_meta": {
            "driver": "gradient",
            "method": "UFF",
            "basis": "",
            "options": "none",
            "program": "rdkit",
        },
    }
    frag.add_options_set("torsiondrive", "v1", torsiondrive_options)

    # Required torsions
    needed_torsions = {
      "internal": [
        [[0, 2, 3, 1]],
      ],
      "terminal": [
        [[3, 2, 0, 4]],
        [[2, 3, 1, 7]],
      ]
    } # yapf: disable
def test_compute_openffworkflow(fractal_compute_server):

    # Obtain a client and build a BioFragment
    client = portal.FractalClient(fractal_compute_server.get_address(""))
    nanny = fractal_compute_server.objects["queue_nanny"]

    openff_workflow_options = {
        # Blank Fragmenter options
        "enumerate_states": {},
        "enumerate_fragments": {},
        "torsiondrive_input": {},

        # TorsionDrive, Geometric, and QC options
        "torsiondrive_meta": {},
        "optimization_meta": {
            "program": "geometric",
            "coordsys": "tric",
        },
        "qc_meta": {
            "driver": "gradient",
            "method": "UFF",
            "basis": "",
            "options": "none",
            "program": "rdkit",
        }
    }
    wf = portal.collections.OpenFFWorkflow("Workflow1", client=client, options=openff_workflow_options)

    # Add a fragment and wait for the compute
    hooh = portal.data.get_molecule("hooh.json")
    fragment_input = {
        "label1": {
            "initial_molecule": hooh.to_json(),
            "grid_spacing": [120],
            "dihedrals": [[0, 1, 2, 3]],
        },
    }
    wf.add_fragment("HOOH", fragment_input, provenance={})
    assert set(wf.list_fragments()) == {"HOOH"}
    nanny.await_services(max_iter=5)

    final_energies = wf.list_final_energies()
    assert final_energies.keys() == {"HOOH"}
    assert final_energies["HOOH"].keys() == {"label1"}

    final_molecules = wf.list_final_molecules()
    assert final_molecules.keys() == {"HOOH"}
    assert final_molecules["HOOH"].keys() == {"label1"}

    # Add a second fragment
    butane = portal.data.get_molecule("butane.json")
    butane_id = butane.identifiers["canonical_isomeric_explicit_hydrogen_mapped_smiles"]

    fragment_input = {
        "label1": {
            "initial_molecule": butane.to_json(),
            "grid_spacing": [90],
            "dihedrals": [[0, 2, 3, 1]],
        },
    }
    wf.add_fragment(butane_id, fragment_input, provenance={})
    assert set(wf.list_fragments()) == {butane_id, "HOOH"}

    final_energies = wf.list_final_energies()
    assert final_energies.keys() == {butane_id, "HOOH"}
    assert final_energies[butane_id].keys() == {"label1"}
    assert final_energies[butane_id]["label1"] is None