def test_given_esps(self, nme2ala2, methylammonium, methylammonium_nme2ala2_charge_constraints, stage_2, restraint_height, red_charges, job_esps, job_grids): resp_options = RespOptions(stage_2=stage_2, restraint_height_stage_1=restraint_height) job = Job( molecules=[methylammonium, nme2ala2], charge_constraints=methylammonium_nme2ala2_charge_constraints, resp_options=resp_options) for mol in job.molecules: for conf in mol.conformers: for orient in conf.orientations: fname = orient.qcmol.get_hash() orient.esp = job_esps[fname] orient.grid = job_grids[fname] job.charge_constraints.split_conformers = False job.compute_charges() charges = np.concatenate(job.charges) assert_allclose(charges[[0, 1, 2, 3, 8, 9, 10, 11, 12, 13, 14, 15]].sum(), 0, atol=1e-7) assert_allclose(charges[[27, 28, 29, 30, 31, 32]].sum(), 0, atol=1e-7) assert_allclose(charges[25], 0.6163) assert_allclose(charges[26], -0.5722) assert_allclose(charges[18], charges[22]) for calculated, reference in zip(job.charges[::-1], red_charges[::-1]): assert_allclose(calculated, reference, atol=1e-3)
def test_add_constraints_from_charges(self): pytest.importorskip("psi4") job = Job.parse_file(DMSO_JOB_WITH_ORIENTATION_ENERGIES) charge_options = job.charge_constraints assert len(charge_options.charge_sum_constraints) == 0 assert len(charge_options.charge_equivalence_constraints) == 0 constraints = job.generate_molecule_charge_constraints() assert len(constraints.charge_sum_constraints) == 0 assert len(constraints.charge_equivalence_constraints) == 2 constraints.add_constraints_from_charges([ -0.43877469, 0.14814998, 0.17996033, 0.18716814, 0.35743529, -0.5085439, -0.46067469, 0.19091725, 0.15500465, 0.18935764 ]) assert len(constraints.charge_sum_constraints) == 2 assert len(constraints.charge_equivalence_constraints) == 2 surface_constraints = job.construct_surface_constraint_matrix() assert surface_constraints.matrix.shape == (12, 11) matrix = SparseGlobalConstraintMatrix.from_constraints( surface_constraints, constraints) ref_a = np.loadtxt(DMSO_STAGE_2_A) ref_b = np.loadtxt(DMSO_STAGE_2_B) assert_allclose(matrix.coefficient_matrix.toarray(), ref_a) assert_allclose(matrix.constant_vector, ref_b)
def test_load_job_from_json(): job = Job.parse_file(TRIFLUOROETHANOL_JOB) assert len(job.molecules) == 1 orientation = job.molecules[0].conformers[0].orientations[0] assert_allclose(orientation.esp[0], 0.0054845008310878) assert_allclose(orientation.esp[-1], 0.0290851723179761) assert job.charges is None
def test_restrained(self, dmso, fractal_client): options = RespOptions(stage_2=True, restrained_fit=True) job = Job(molecules=[dmso], resp_options=options) job.run(client=fractal_client) resp_1 = [[ -0.31436216, 0.11376836, 0.14389443, 0.15583112, 0.30951582, -0.50568553, -0.33670393, 0.15982115, 0.12029174, 0.153629 ]] resp_2 = [[ -0.25158642, 0.11778735, 0.11778735, 0.11778735, 0.30951582, -0.50568553, -0.29298059, 0.12912489, 0.12912489, 0.12912489 ]] assert_allclose(job.stage_1_charges.restrained_charges, resp_1, atol=1e-5) assert_allclose(job.stage_2_charges.restrained_charges, resp_2, atol=1e-5)
def test_symmetric_constraints(tmpdir): pytest.importorskip("rdkit") # formic smiles: "[H:4][C:2](=[O:1])[O-:3]" mol = psiresp.Molecule.parse_file(FORMIC_ACID_JSON) with tmpdir.as_cwd(): shutil.copytree(FORMIC_ACID_WKDIR, "psiresp_working_directory") not_equiv = Job(molecules=[mol], charge_constraints=dict( symmetric_atoms_are_equivalent=False)).run()[0] # 0 and 2 are the oxygens assert not np.allclose(not_equiv[0], not_equiv[2]) equiv = Job(molecules=[mol], charge_constraints=dict( symmetric_atoms_are_equivalent=True)).run()[0] assert_allclose(equiv[0], equiv[2])
def test_conformer_splitting_one_conf(self, jobfile, n_mol, n_confs, nosplit, split): job = Job.parse_file(jobfile) charge_options = job.charge_constraints assert len(job.molecules) == n_mol assert [mol.n_conformers for mol in job.molecules] == n_confs charge_options.split_conformers = False surface_constraints = job.construct_surface_constraint_matrix() assert surface_constraints.matrix.shape == nosplit charge_options.split_conformers = True surface_constraints = job.construct_surface_constraint_matrix() assert surface_constraints.matrix.shape == split
def test_unrestrained(self, dmso, fractal_client): options = RespOptions(stage_2=True, restrained_fit=False) job = Job(molecules=[dmso], resp_options=options) job.run(client=fractal_client) esp_1 = [[ -0.43877469, 0.14814998, 0.17996033, 0.18716814, 0.35743529, -0.5085439, -0.46067469, 0.19091725, 0.15500465, 0.18935764 ]] esp_2 = [[ -0.39199538, 0.15716631, 0.15716631, 0.15716631, 0.35743529, -0.5085439, -0.43701446, 0.16953984, 0.16953984, 0.16953984 ]] assert_allclose(job.stage_1_charges.unrestrained_charges, esp_1, atol=1e-7) assert_allclose(job.stage_2_charges.unrestrained_charges, esp_2, atol=1e-7) chgrepr = """<RespCharges(restraint_height=0.0005, restraint_slope=0.1, restrained_fit=False, exclude_hydrogens=True) with 0 charge constraints; unrestrained_charges=[array([-0.43877, 0.14815, 0.17996, 0.18717, 0.35744, -0.50854, -0.46067, 0.19092, 0.155 , 0.18936])], restrained_charges=None>""" assert repr(job.stage_1_charges) == chgrepr
def test_run_manual(self, nme2ala2_empty, methylammonium_empty, tmpdir): pytest.importorskip("rdkit") nme2ala2_empty.optimize_geometry = True methylammonium_empty.optimize_geometry = True assert len(nme2ala2_empty.conformers) == 2 assert len(methylammonium_empty.conformers) == 1 job = Job(molecules=[methylammonium_empty, nme2ala2_empty]) data_wkdir = pathlib.Path(MANUAL_JOBS_WKDIR) with tmpdir.as_cwd(): # OPTIMIZATION assert not job.working_directory.exists() with pytest.raises(SystemExit, match="Exiting to allow running"): job.run() assert job.working_directory.exists() # check run file contents runfile = job.qm_optimization_options.get_run_file( job.working_directory) assert str( runfile ) == "psiresp_working_directory/optimization/run_optimization.sh" with runfile.open() as f: optlines = [x.strip() for x in f.readlines()] assert len(optlines) == 4 # check existence and copy completed files in opt_filenames = glob.glob(str(data_wkdir / "optimization/*")) assert len(opt_filenames) == 4 for file in opt_filenames: path = pathlib.Path(file.split("manual_jobs/")[1]) assert path.exists() if file.endswith("msgpack"): assert f"psi4 --qcschema {path.name}" in optlines shutil.copyfile(file, path) assert all(not conf.is_optimized for conf in job.iter_conformers()) # SINGLE POINT assert not job.qm_esp_options.get_working_directory( job.working_directory).exists() with pytest.raises(SystemExit, match="Exiting to allow running"): job.run() assert all(conf.is_optimized for conf in job.iter_conformers()) # check run file contents runfile = job.qm_esp_options.get_run_file(job.working_directory) assert str( runfile ) == "psiresp_working_directory/single_point/run_single_point.sh" with runfile.open() as f: splines = [x.strip() for x in f.readlines()] assert len(splines) == 11 # check existence and copy completed files in opt_filenames = glob.glob(str(data_wkdir / "single_point/*")) assert len(opt_filenames) == 11 for file in opt_filenames: path = pathlib.Path(file.split("manual_jobs/")[1]) assert path.exists() if file.endswith("msgpack"): assert f"psi4 --qcschema {path.name}" in splines shutil.copyfile(file, path) job.run() methylammonium_charges = [ -0.281849, 0.174016, 0.174016, 0.174016, -0.528287, 0.215501, 0.857086, 0.215501 ] nme2ala2_charges = [ 4.653798, -1.174226, -1.1742263, -1.1742263, -1.2224316, 0.1732717, -3.9707787, 0.8309516, 8.291471, 4.749616, -1.870866, -1.870866, -1.870866, 2.275405, -1.3199896, -1.3199896, -1.3199896, 1.6195477, -1.5787892, -14.898019, 2.9755072, 30.303230, -7.035844, -7.035844, -7.035844 ] assert_allclose(job.charges[0], methylammonium_charges, atol=1e-6) assert_allclose(job.charges[1], nme2ala2_charges, atol=1e-6)