def test_queue_error(fractal_compute_server): client = portal.FractalClient(fractal_compute_server.get_address()) hooh = portal.data.get_molecule("hooh.json").to_json() del hooh["connectivity"] mol_ret = client.add_molecules({"hooh": hooh}) ret = client.add_compute("rdkit", "UFF", "", "energy", None, mol_ret["hooh"]) queue_id = ret["submitted"][0] # Pull out a special iteration on the queue manager fractal_compute_server.update_tasks() assert len(fractal_compute_server.list_current_tasks()) == 1 fractal_compute_server.await_results() assert len(fractal_compute_server.list_current_tasks()) == 0 db = fractal_compute_server.objects["storage_socket"] ret = db.get_queue({"status": "ERROR"})["data"] assert len(ret) == 1 assert "connectivity graph" in ret[0]["error"] fractal_compute_server.objects["storage_socket"].queue_mark_complete( [queue_id])
def test_queue_error(fractal_compute_server): reset_server_database(fractal_compute_server) client = ptl.FractalClient(fractal_compute_server) hooh = ptl.data.get_molecule("hooh.json").copy( update={"connectivity": None}) compute_ret = client.add_compute("rdkit", "UFF", "", "energy", None, hooh) # Pull out a special iteration on the queue manager fractal_compute_server.update_tasks() assert len(fractal_compute_server.list_current_tasks()) == 1 fractal_compute_server.await_results() assert len(fractal_compute_server.list_current_tasks()) == 0 # Pull from database, raw JSON db = fractal_compute_server.objects["storage_socket"] queue_ret = db.get_queue(status="ERROR")["data"] result = db.get_results(id=compute_ret.ids)['data'][0] assert len(queue_ret) == 1 # TODO: task.error is not used anymore # assert "connectivity graph" in queue_ret[0].error.error_message assert result['status'] == 'ERROR' # Force a complete mark and test fractal_compute_server.objects["storage_socket"].queue_mark_complete( [queue_ret[0].id]) result = db.get_results(id=compute_ret.ids)['data'][0] assert result['status'] == 'COMPLETE'
def test_compute_wavefunction(fractal_compute_server): psiver = qcng.get_program("psi4").get_version() if parse_version(psiver) < parse_version("1.4a2.dev160"): pytest.skip("Must be used a modern version of Psi4 to execute") # Build a client client = ptl.FractalClient(fractal_compute_server) # Add a hydrogen and helium molecule hydrogen = ptl.Molecule.from_data([[1, 0, 0, -0.5], [1, 0, 0, 0.5]], dtype="numpy", units="bohr") # Ask the server to compute a new computation r = client.add_compute( program="psi4", driver="energy", method="HF", basis="sto-3g", molecule=hydrogen, protocols={"wavefunction": "orbitals_and_eigenvalues"}, ) fractal_compute_server.await_results() assert len(fractal_compute_server.list_current_tasks()) == 0 result = client.query_results(id=r.ids)[0] assert result.wavefunction r = result.get_wavefunction("orbitals_a") assert isinstance(r, np.ndarray) assert r.shape == (2, 2) r = result.get_wavefunction(["orbitals_a", "basis"]) assert r.keys() == {"orbitals_a", "basis"}
def test_procedure_optimization_protocols(fractal_compute_server): # Add a hydrogen molecule hydrogen = ptl.Molecule.from_data([[1, 0, 0, -0.673], [1, 0, 0, 0.673]], dtype="numpy", units="bohr") client = fractal_compute_server.client() # Add compute options = { "keywords": None, "qc_spec": {"driver": "gradient", "method": "HF", "basis": "sto-3g", "program": "psi4"}, "protocols": {"trajectory": "final"}, } # Ask the server to compute a new computation r = client.add_procedure("optimization", "geometric", options, [hydrogen]) assert len(r.ids) == 1 compute_key = r.ids[0] # Manually handle the compute fractal_compute_server.await_results() assert len(fractal_compute_server.list_current_tasks()) == 0 # # Query result and check against out manual pul proc = client.query_procedures(id=r.ids)[0] assert proc.status == "COMPLETE" assert len(proc.trajectory) == 1 assert len(proc.energies) > 1
def test_service_gridoptimization_single_noopt(fractal_compute_server): client = ptl.FractalClient(fractal_compute_server) # Add a HOOH hooh = ptl.data.get_molecule("hooh.json") initial_distance = hooh.measure([1, 2]) # Options service = GridOptimizationInput(**{ "keywords": { "preoptimization": False, "scans": [{ "type": "distance", "indices": [1, 2], "steps": [-0.1, 0.0], "step_type": "relative" }] }, "optimization_spec": { "program": "geometric", "keywords": { "coordsys": "tric", } }, "qc_spec": { "driver": "gradient", "method": "UFF", "basis": "", "keywords": None, "program": "rdkit", }, "initial_molecule": hooh, }) # yapf: disable ret = client.add_service([service]) fractal_compute_server.await_services() assert len(fractal_compute_server.list_current_tasks()) == 0 result = client.query_procedures(id=ret.ids)[0] assert result.status == "COMPLETE" assert result.starting_grid == (1, ) assert pytest.approx(result.get_final_energies((0, )), abs=1.e-4) == 0.00032145876568280524 assert result.starting_molecule == result.initial_molecule # Check initial vs startin molecule assert result.initial_molecule == result.starting_molecule mol = client.query_molecules(id=result.starting_molecule)[0] assert pytest.approx(mol.measure([1, 2])) == initial_distance
def test_compute_queue_stack(fractal_compute_server): # Build a client client = ptl.FractalClient(fractal_compute_server) # Add a hydrogen and helium molecule hydrogen = ptl.Molecule.from_data([[1, 0, 0, -0.5], [1, 0, 0, 0.5]], dtype="numpy", units="bohr") helium = ptl.Molecule.from_data([[2, 0, 0, 0.0]], dtype="numpy", units="bohr") hydrogen_mol_id, helium_mol_id = client.add_molecules([hydrogen, helium]) kw = ptl.models.KeywordSet(**{"values": {"e_convergence": 1.0e-8}}) kw_id = client.add_keywords([kw])[0] # Add compute compute_args = {"driver": "energy", "method": "HF", "basis": "sto-3g", "keywords": kw_id, "program": "psi4"} # Ask the server to compute a new computation r = client.add_compute("psi4", "HF", "sto-3g", "energy", kw_id, [hydrogen_mol_id, helium]) assert len(r.ids) == 2 r2 = client.add_compute(**compute_args, molecule=[hydrogen_mol_id, helium]) assert len(r2.ids) == 2 assert len(r2.submitted) == 0 assert set(r2.ids) == set(r.ids) # Manually handle the compute fractal_compute_server.await_results() assert len(fractal_compute_server.list_current_tasks()) == 0 # Query result and check against out manual pul results_query = { "program": "psi4", "molecule": [hydrogen_mol_id, helium_mol_id], "method": compute_args["method"], "basis": compute_args["basis"], } results = client.query_results(**results_query, status=None) assert len(results) == 2 for r in results: assert r.provenance.creator.lower() == "psi4" if r.molecule == hydrogen_mol_id: assert pytest.approx(-1.0660263371078127, 1e-5) == r.properties.scf_total_energy elif r.molecule == helium_mol_id: assert pytest.approx(-2.807913354492941, 1e-5) == r.properties.scf_total_energy else: raise KeyError("Returned unexpected Molecule ID.") assert "RHF Reference" in results[0].get_stdout()
def spin_up_test(**keyword_augments): instance_options = copy.deepcopy(torsiondrive_options) recursive_dict_merge(instance_options, keyword_augments) inp = TorsionDriveInput(**instance_options) ret = client.add_service([inp], full_return=True) if ret.meta.n_inserted: # In case test already submitted compute_key = ret.data.ids[0] service = client.query_services(procedure_id=compute_key)[0] assert 'WAITING' in service['status'] fractal_compute_server.await_services() assert len(fractal_compute_server.list_current_tasks()) == 0 return ret.data
def test_torsiondrive_run(fractal_compute_server): # 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(fractal_compute_server) # Add a HOOH hooh = { 'symbols': ['H', 'O', 'O', 'H'], 'geometry': [ 1.84719633, 1.47046223, 0.80987166, 1.3126021, -0.13023157, -0.0513322, -1.31320906, 0.13130216, -0.05020593, -1.83756335, -1.48745318, 0.80161212 ], 'name': 'HOOH', 'connectivity': [[0, 1, 1], [1, 2, 1], [2, 3, 1]], } mol_ret = client.add_molecules({"hooh": hooh}) # Geometric options instance_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"]], instance_options) fractal_compute_server.await_results() assert len(fractal_compute_server.list_current_tasks()) == 0
def test_procedure_optimization(fractal_compute_server): # Add a hydrogen molecule hydrogen = ptl.Molecule.from_data([[1, 0, 0, -0.672], [1, 0, 0, 0.672]], dtype="numpy", units="bohr") client = ptl.FractalClient(fractal_compute_server.get_address("")) mol_ret = client.add_molecules([hydrogen]) kw = ptl.models.KeywordSet( values={"scf_properties": ["quadrupole", "wiberg_lowdin_indices"]}) kw_id = client.add_keywords([kw])[0] # Add compute options = { "keywords": None, "qc_spec": { "driver": "gradient", "method": "HF", "basis": "sto-3g", "keywords": kw_id, "program": "psi4" }, } # Ask the server to compute a new computation r = client.add_procedure("optimization", "geometric", options, mol_ret) assert len(r.ids) == 1 compute_key = r.ids[0] # Manually handle the compute fractal_compute_server.await_results() assert len(fractal_compute_server.list_current_tasks()) == 0 # # Query result and check against out manual pul query1 = client.query_procedures(procedure="optimization", program="geometric") query2 = client.query_procedures(id=compute_key) for query in [query1, query2]: assert len(query) == 1 opt_result = query[0] assert isinstance(opt_result.provenance.creator, str) assert isinstance(str(opt_result), str) # Check that repr runs assert pytest.approx(-1.117530188962681, 1e-5) == opt_result.get_final_energy() # Check pulls traj = opt_result.get_trajectory() assert len(traj) == len(opt_result.energies) assert np.array_equal(opt_result.get_final_molecule().symbols, ["H", "H"]) # Check individual elements for ind in range(len(opt_result.trajectory)): # Check keywords went through assert traj[ind].provenance.creator.lower() == "psi4" assert "SCF QUADRUPOLE XY" in traj[ind].extras["qcvars"] assert "WIBERG_LOWDIN_INDICES" in traj[ind].extras["qcvars"] # Make sure extra was popped assert "_qcfractal_tags" not in traj[ind].extras raw_energy = traj[ind].properties.return_energy assert pytest.approx(raw_energy, 1.e-5) == opt_result.energies[ind] # Check result stdout assert "RHF Reference" in traj[0].get_stdout() assert opt_result.get_molecular_trajectory( )[0].id == opt_result.initial_molecule assert opt_result.get_molecular_trajectory( )[-1].id == opt_result.final_molecule # Check stdout assert "internal coordinates" in opt_result.get_stdout() # Check that duplicates are caught r = client.add_procedure("optimization", "geometric", options, [mol_ret[0]]) assert len(r.ids) == 1 assert len(r.existing) == 1
def test_service_gridoptimization_single_opt(fractal_compute_server): client = ptl.FractalClient(fractal_compute_server) # Add a HOOH hooh = ptl.data.get_molecule("hooh.json") initial_distance = hooh.measure([1, 2]) mol_ret = client.add_molecules([hooh]) # Options service = GridOptimizationInput(**{ "keywords": { "preoptimization": True, "scans": [{ "type": "distance", "indices": [1, 2], "steps": [-0.1, 0.0], "step_type": "relative" }, { "type": "dihedral", "indices": [0, 1, 2, 3], "steps": [-90, 0], "step_type": "absolute" }] }, "optimization_spec": { "program": "geometric", "keywords": { "coordsys": "tric", } }, "qc_spec": { "driver": "gradient", "method": "UFF", "basis": "", "keywords": None, "program": "rdkit", }, "initial_molecule": mol_ret[0], }) # yapf: disable ret = client.add_service([service], tag="gridopt", priority="low") fractal_compute_server.await_services() assert len(fractal_compute_server.list_current_tasks()) == 0 result = client.query_procedures(id=ret.ids)[0] assert result.status == "COMPLETE" assert result.starting_grid == (1, 0) assert pytest.approx(result.get_final_energies((0, 0)), abs=1.e-4) == 0.0010044105443485617 assert pytest.approx(result.get_final_energies((1, 1)), abs=1.e-4) == 0.0026440964897817623 assert result.starting_molecule != result.initial_molecule # Check initial vs startin molecule assert result.initial_molecule == mol_ret[0] starting_mol = client.query_molecules(id=result.starting_molecule)[0] assert pytest.approx(starting_mol.measure([1, 2])) != initial_distance assert pytest.approx(starting_mol.measure([1, 2])) == 2.488686479260597 # Check tags on individual procedures proc_id = list(result.grid_optimizations.values())[0] opt = client.query_procedures(id=proc_id)[0] task = client.query_tasks(id=opt.task_id)[0] assert task.priority == 0 assert task.tag == "gridopt"
def test_procedure_optimization(fractal_compute_server): # Add a hydrogen molecule hydrogen = portal.Molecule([[1, 0, 0, -0.672], [1, 0, 0, 0.672]], dtype="numpy", units="bohr") client = portal.FractalClient(fractal_compute_server.get_address("")) mol_ret = client.add_molecules({"hydrogen": hydrogen.to_json()}) # Add compute compute = { "meta": { "procedure": "optimization", "program": "geometric", "options": None, "qc_meta": { "driver": "gradient", "method": "HF", "basis": "sto-3g", "options": None, "program": "psi4" }, }, "data": [mol_ret["hydrogen"]], } # Ask the server to compute a new computation r = requests.post(fractal_compute_server.get_address("task_queue"), json=compute) assert r.status_code == 200 # Get the first submitted task, the second index will be a hash_index submitted = r.json()["data"]["submitted"] compute_key = submitted[0] # Manually handle the compute fractal_compute_server.await_results() # print(fractal_compute_server.storage.get_procedures({})) assert len(fractal_compute_server.list_current_tasks()) == 0 # # Query result and check against out manual pul results1 = client.get_procedures({"program": "geometric"}) results2 = client.get_procedures({"queue_id": compute_key}) for results in [results1, results2]: assert len(results) == 1 assert isinstance(str(results[0]), str) # Check that repr runs assert pytest.approx(-1.117530188962681, 1e-5) == results[0].final_energy() # Check pulls traj = results[0].get_trajectory(projection={"properties": True}) energies = results[0].energies() assert len(traj) == len(energies) assert results[0].final_molecule()["symbols"] == ["H", "H"] # Check individual elements for ind in range(len(results[0]._trajectory)): raw_energy = traj[ind]["properties"]["return_energy"] assert pytest.approx(raw_energy, 1.e-5) == energies[ind] # Check that duplicates are caught r = requests.post(fractal_compute_server.get_address("task_queue"), json=compute) assert r.status_code == 200 assert len(r.json()["data"]["completed"]) == 1
def test_compute_queue_stack(fractal_compute_server): # Add a hydrogen and helium molecule hydrogen = portal.Molecule([[1, 0, 0, -0.5], [1, 0, 0, 0.5]], dtype="numpy", units="bohr") helium = portal.Molecule([[2, 0, 0, 0.0]], dtype="numpy", units="bohr") storage = fractal_compute_server.objects["storage_socket"] mol_ret = storage.add_molecules({ "hydrogen": hydrogen.to_json(), "helium": helium.to_json() }) hydrogen_mol_id = mol_ret["data"]["hydrogen"] helium_mol_id = mol_ret["data"]["helium"] option = portal.data.get_options("psi_default") opt_ret = storage.add_options([option]) opt_key = option["name"] # Add compute compute = { "meta": { "procedure": "single", "driver": "energy", "method": "HF", "basis": "sto-3g", "options": opt_key, "program": "psi4", }, "data": [hydrogen_mol_id, helium.to_json()], } # Ask the server to compute a new computation r = requests.post(fractal_compute_server.get_address("task_queue"), json=compute) assert r.status_code == 200 # Manually handle the compute fractal_compute_server.await_results() assert len(fractal_compute_server.list_current_tasks()) == 0 # Query result and check against out manual pul results_query = { "program": "psi4", "molecule": [hydrogen_mol_id, helium_mol_id], "method": compute["meta"]["method"], "basis": compute["meta"]["basis"] } results = storage.get_results(**results_query)["data"] assert len(results) == 2 for r in results: if r["molecule"] == hydrogen_mol_id: assert pytest.approx(-1.0660263371078127, 1e-5) == r["properties"]["scf_total_energy"] elif r["molecule"] == helium_mol_id: assert pytest.approx(-2.807913354492941, 1e-5) == r["properties"]["scf_total_energy"] else: raise KeyError("Returned unexpected Molecule ID.")