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_scheduler"), json=compute) assert r.status_code == 200 # Get the first submitted job, the second index will be a hash_index submitted = r.json()["data"]["submitted"] compute_key = submitted[0][1] # Manually handle the compute nanny = fractal_compute_server.objects["queue_nanny"] nanny.await_results() assert len(nanny.list_current_tasks()) == 0 # # Query result and check against out manual pul results1 = client.get_procedures({"program": "geometric"}) results2 = client.get_procedures({"hash_index": 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()
def test_queue_duplicate_procedure(fractal_compute_server): client = portal.FractalClient(fractal_compute_server.get_address()) hooh = portal.data.get_molecule("hooh.json").to_json() mol_ret = client.add_molecules({"hooh": hooh}) geometric_options = { "options": None, "qc_meta": { "driver": "gradient", "method": "UFF", "basis": "", "options": None, "program": "rdkit" }, } ret = client.add_procedure("optimization", "geometric", geometric_options, mol_ret["hooh"]) assert len(ret["submitted"]) == 1 assert len(ret["completed"]) == 0 # Pull out fireworks launchpad and queue nanny fractal_compute_server.await_results() db = fractal_compute_server.objects["storage_socket"] ret = client.add_procedure("optimization", "geometric", geometric_options, mol_ret["hooh"]) assert len(ret["submitted"]) == 0 assert len(ret["completed"]) == 1
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_duplicate_submissions(fractal_compute_server): client = portal.FractalClient(fractal_compute_server.get_address()) he2 = portal.data.get_molecule("helium_dimer.json").to_json() mol_ret = client.add_molecules({"he2": he2}) ret = client.add_compute("rdkit", "UFF", "", "energy", None, mol_ret["he2"]) assert len(ret["submitted"]) == 1 assert len(ret["completed"]) == 0 assert len(ret["queue"]) == 0 queue_id = ret["submitted"][0] # Do not compute, add duplicate ret = client.add_compute("rdkit", "UFF", "", "energy", None, mol_ret["he2"]) assert len(ret["submitted"]) == 0 assert len(ret["completed"]) == 1 # assert ret["queue"][0] == queue_id # assert len(ret["queue"]) == 1 # assert ret["queue"][0] == queue_id # Cleanup fractal_compute_server.objects["storage_socket"].queue_mark_complete( [queue_id])
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][0] # Pull out fireworks launchpad and queue nanny nanny = fractal_compute_server.objects["queue_nanny"] assert len(nanny.list_current_tasks()) == 1 nanny.await_results() assert len(nanny.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_procedure_task_error(fractal_compute_server): client = portal.FractalClient(fractal_compute_server.get_address()) ret = client.add_compute("rdkit", "cookiemonster", "", "energy", None, [{ "geometry": [0, 0, 0], "symbols": ["He"] }]) # Manually handle the compute fractal_compute_server.await_results() # Check for error ret = client.check_tasks({"id": ret["submitted"][0]}) assert len(ret) == 1 assert ret[0]["status"] == "ERROR" assert "run_rdkit" in ret[0]["error"]
def test_queue_duplicate_compute(fractal_compute_server): client = portal.FractalClient(fractal_compute_server.get_address()) hooh = portal.data.get_molecule("hooh.json").to_json() mol_ret = client.add_molecules({"hooh": hooh}) ret = client.add_compute("rdkit", "UFF", "", "energy", "none", mol_ret["hooh"]) assert len(ret["submitted"]) == 1 assert len(ret["completed"]) == 0 # Pull out fireworks launchpad and queue nanny nanny = fractal_compute_server.objects["queue_nanny"] nanny.await_results() db = fractal_compute_server.objects["storage_socket"] ret = client.add_compute("rdkit", "UFF", "", "energy", "none", mol_ret["hooh"]) assert len(ret["submitted"]) == 0 assert len(ret["completed"]) == 1
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 frag.submit_torsion_drives("v1", needed_torsions)
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_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_scheduler"), json=compute) assert r.status_code == 200 # Get the first submitted job, the second index will be a hash_index submitted = r.json()["data"]["submitted"] compute_key = submitted[0] # Manually handle the compute nanny = fractal_compute_server.objects["queue_nanny"] nanny.await_results() assert len(nanny.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_scheduler"), 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_scheduler"), json=compute) assert r.status_code == 200 # Manually handle the compute nanny = fractal_compute_server.objects["queue_nanny"] nanny.await_results() assert len(nanny.list_current_tasks()) == 0 # Query result and check against out manual pul results_query = { "program": "psi4", "molecule_id": [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_id"] == hydrogen_mol_id: assert pytest.approx(-1.0660263371078127, 1e-5) == r["properties"]["scf_total_energy"] elif r["molecule_id"] == helium_mol_id: assert pytest.approx(-2.807913354492941, 1e-5) == r["properties"]["scf_total_energy"] else: raise KeyError("Returned unexpected Molecule ID.")
def test_compute_database(fractal_compute_server): client = portal.FractalClient(fractal_compute_server.get_address("")) db_name = "He_PES" db = portal.collections.Database(db_name, client, db_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]) db.add_ie_rxn("He1", He1, attributes={"r": 4}, reaction_results={"default": { "Benchmark": 0.0009608501557 }}) # Save the DB and re-acquire r = db.save() db = portal.collections.Database.from_server(client, db_name) He2 = portal.Molecule([[2, 0, 0, -4], [2, 0, 0, 4]], dtype="numpy", units="bohr", frags=[1]) db.add_ie_rxn( "He2", He2, attributes={"r": 4}, reaction_results={"default": { "Benchmark": -0.00001098794749 }}) # Save the DB and overwrite the result r = db.save(overwrite=True) # Open a new database db = portal.collections.Database.from_server(client, db_name) # Compute SCF/sto-3g ret = db.compute("SCF", "STO-3G") fractal_compute_server.objects["queue_nanny"].await_results() # Query computed results assert db.query("SCF", "STO-3G") assert pytest.approx(0.6024530476071095, 1.e-5) == db.df.loc["He1", "SCF/STO-3G"] assert pytest.approx(-0.006895035942673289, 1.e-5) == db.df.loc["He2", "SCF/STO-3G"] # Check results assert db.query("Benchmark", "", reaction_results=True) assert pytest.approx(0.00024477933196125805, 1.e-5) == db.statistics("MUE", "SCF/STO-3G")