diff --git a/mosdef_dihedral_fit/tests/files/with_errors/dihedral_coords_position_with_errors_1.txt b/mosdef_dihedral_fit/tests/files/with_errors/dihedral_coords_position_with_errors_1.txt new file mode 100755 index 0000000..20e75b1 --- /dev/null +++ b/mosdef_dihedral_fit/tests/files/with_errors/dihedral_coords_position_with_errors_1.txt @@ -0,0 +1,13 @@ +ERROR INVOKED +Row Highlight Display Tag Symbol X Y Z +1 No Show 1 C 0.038875 0.044324 -0.011413 +2 No Show 2 C -1.465769 -0.032622 0.013366 +3 No Show 3 C -2.132975 1.336603 0.000182 +4 No Show 4 O 0.594959 -1.165924 0.000767 +5 No Show 5 O 0.687419 1.039064 -0.038656 +6 No Show 6 H -1.834701 1.923374 0.860427 +7 No Show 7 H -1.861486 1.893480 -0.888336 +8 No Show 8 H -1.773326 -0.632226 -0.838286 +9 No Show 9 H -1.746313 -0.602379 0.894330 +10 No Show 10 H -3.211788 1.226165 0.018599 +11 No Show 11 H 1.541303 -1.055849 -0.015879 diff --git a/mosdef_dihedral_fit/tests/test_file_read_write.py b/mosdef_dihedral_fit/tests/test_file_read_write.py index 8b8ca45..21aec02 100644 --- a/mosdef_dihedral_fit/tests/test_file_read_write.py +++ b/mosdef_dihedral_fit/tests/test_file_read_write.py @@ -136,10 +136,22 @@ def test_write_xyz_file_from_gaussian(self): assert "dihedral_coords_position_1.xyz" in os.listdir() assert "dihedral_coords_position_2.xyz" in os.listdir() + error_msg = "ERROR: The 'qm_coordinate_file_extension' variable extension is not listed or a an empty string." + with pytest.raises(ValueError, match=error_msg): + write_xyz_file_from_gaussian_coordinates( + atom_namesList, full_fn, "", "./", 2 + ) write_restart_coor_from_xyz_file("./", 2) assert "dihedral_coords_position_1.coor" in os.listdir() assert "dihedral_coords_position_2.coor" in os.listdir() + error_fn = "with_errors/dihedral_coords_position_with_errors_" + full_error_fn = self.get_fn(error_fn) + with pytest.raises(TypeError): + write_xyz_file_from_gaussian_coordinates( + atom_namesList, full_error_fn, extension, "./", 1 + ) + def test_check_gaussian_angle_energy_file_correct(self): full_path = self.get_fn( "gaussian_style_output_files/CT_CT_C_OH/output/dihedral.txt" @@ -185,6 +197,41 @@ def test_get_final_gaussian_output_file_data(self): assert elements == ["C", "C", "H", "H", "H", "H", "H", "H"] assert n_atoms == 8 + # Wrong input types + with pytest.raises(TypeError): + get_final_gaussian_output_file_data(None, [3, 1, 2, 8]) + + # Dict value must be list of integers + with pytest.raises(TypeError): + get_final_gaussian_output_file_data( + {full_path: [0.1, 0.2, 0.3, -0.4]}, [3, 1, 2, 8] + ) + + # Dict key must be a string + with pytest.raises(TypeError): + get_final_gaussian_output_file_data( + {1: [0.1, 0.2, 0.3, 0.4]}, [3, 1, 2, 8] + ) + + # Dict value must be a list + with pytest.raises(TypeError): + get_final_gaussian_output_file_data( + {full_path: "ERROR"}, [3, 1, 2, 8] + ) + + # manual_dihedral_atom_numbers_list must be a list of len 4 + with pytest.raises(TypeError): + get_final_gaussian_output_file_data( + {full_path: list(np.arange(32, dtype=int))}, None + ) + + # manual_dihedral_atom_numbers_list must be a list of integers + with pytest.raises(TypeError): + get_final_gaussian_output_file_data( + {full_path: list(np.arange(32, dtype=int))}, + [0.1, 0.2, 0.3, 0.4], + ) + def test_get_gaussian_log_file_data(self): full_path = self.get_fn( "gaussian/CT_CT_C_OH/output/CT_CT_C_OH_multiplicity_1.log" @@ -265,6 +312,22 @@ def test_get_gaussian_log_file_data(self): dihedral_atoms = out[5] assert dihedral_atoms == [5, 1, 2, 3] + # Input must be a dict + with pytest.raises(TypeError): + get_gaussian_log_file_data(None) + + # Dict key must be a string + with pytest.raises(TypeError): + get_gaussian_log_file_data({1: out_indices}) + + # Dict value must be a list of integers + with pytest.raises(TypeError): + get_gaussian_log_file_data({full_path: [0.1, 0.2, 0.3, -0.4]}) + + # Dict value must be a list + with pytest.raises(TypeError): + get_gaussian_log_file_data({full_path: "ERROR"}) + def test_write_qm_data_files(self): full_path = self.get_fn( "gaussian/CT_CT_C_OH/output/CT_CT_C_OH_multiplicity_1.log" @@ -273,6 +336,19 @@ def test_write_qm_data_files(self): write_qm_data_files({full_path: out_indices}) assert os.path.exists("extracted_gaussian_data/dihedral.txt") + # qm_engine not in list + with pytest.raises(ValueError): + write_qm_data_files(None, qm_engine="None") + + # when qm_engine="gaussian_style_final_files" + # manual_dihedral_atom_numbers_list must be a list of len 4 + with pytest.raises(TypeError): + write_qm_data_files( + {full_path: out_indices}, + None, + qm_engine="gaussian_style_final_files", + ) + def test_get_matching_dihedral_info_and_opls_fitting_data(self): out = get_matching_dihedral_info_and_opls_fitting_data( fit_dihedral_atom_types=["HC", "CT", "CT", "HC"], @@ -351,6 +427,102 @@ def test_get_matching_dihedral_info_and_opls_fitting_data(self): ] assert np.allclose(opls_paramsList[0], expected_opls_params) + # fit_dihedral_atom_types must be a list of length 4 + with pytest.raises(TypeError): + out = get_matching_dihedral_info_and_opls_fitting_data( + fit_dihedral_atom_types=["HC", "CT", "CT"], + psf_path_and_filename=self.get_fn( + "gaussian/HC_CT_CT_HC/output/GOMC_pdb_psf_ff_files.psf" + ), + qm_log_file_dict={ + self.get_fn( + "gaussian/HC_CT_CT_HC/output/HC_CT_CT_HC_multiplicity_1.log" + ): [] + }, + mol2_file=self.get_fn( + "gaussian/HC_CT_CT_HC/input/starting_coords/ethane_aa.mol2" + ), + qm_engine="gaussian", + manual_dihedral_atom_numbers_list=None, + ) + + # Each element of fit_dihedral_atom_types must be a string + with pytest.raises(TypeError): + out = get_matching_dihedral_info_and_opls_fitting_data( + fit_dihedral_atom_types=[1, 2, 3, 4], + psf_path_and_filename=self.get_fn( + "gaussian/HC_CT_CT_HC/output/GOMC_pdb_psf_ff_files.psf" + ), + qm_log_file_dict={ + self.get_fn( + "gaussian/HC_CT_CT_HC/output/HC_CT_CT_HC_multiplicity_1.log" + ): [] + }, + mol2_file=self.get_fn( + "gaussian/HC_CT_CT_HC/input/starting_coords/ethane_aa.mol2" + ), + qm_engine="gaussian", + manual_dihedral_atom_numbers_list=None, + ) + + # fit_dihedral_atom_types must be a list + with pytest.raises(TypeError): + out = get_matching_dihedral_info_and_opls_fitting_data( + fit_dihedral_atom_types=None, + psf_path_and_filename=self.get_fn( + "gaussian/HC_CT_CT_HC/output/GOMC_pdb_psf_ff_files.psf" + ), + qm_log_file_dict={ + self.get_fn( + "gaussian/HC_CT_CT_HC/output/HC_CT_CT_HC_multiplicity_1.log" + ): [] + }, + mol2_file=self.get_fn( + "gaussian/HC_CT_CT_HC/input/starting_coords/ethane_aa.mol2" + ), + qm_engine="gaussian", + manual_dihedral_atom_numbers_list=None, + ) + + # When qm_engine="gaussian_style_final_files" + # manual_dihedral_atom_numbers_list must be a list of len 4 + with pytest.raises(TypeError): + out = get_matching_dihedral_info_and_opls_fitting_data( + fit_dihedral_atom_types=["HC", "CT", "CT", "HC"], + psf_path_and_filename=self.get_fn( + "gaussian/HC_CT_CT_HC/output/GOMC_pdb_psf_ff_files.psf" + ), + qm_log_file_dict={ + self.get_fn( + "gaussian/HC_CT_CT_HC/output/HC_CT_CT_HC_multiplicity_1.log" + ): [] + }, + mol2_file=self.get_fn( + "gaussian/HC_CT_CT_HC/input/starting_coords/ethane_aa.mol2" + ), + qm_engine="gaussian_style_final_files", + manual_dihedral_atom_numbers_list=None, + ) + + # qm_engine must be "gaussian" or "gaussian_style_final_files" + with pytest.raises(ValueError): + out = get_matching_dihedral_info_and_opls_fitting_data( + fit_dihedral_atom_types=["HC", "CT", "CT", "HC"], + psf_path_and_filename=self.get_fn( + "gaussian/HC_CT_CT_HC/output/GOMC_pdb_psf_ff_files.psf" + ), + qm_log_file_dict={ + self.get_fn( + "gaussian/HC_CT_CT_HC/output/HC_CT_CT_HC_multiplicity_1.log" + ): [] + }, + mol2_file=self.get_fn( + "gaussian/HC_CT_CT_HC/input/starting_coords/ethane_aa.mol2" + ), + qm_engine="None", + manual_dihedral_atom_numbers_list=None, + ) + def test_change_gomc_ff_file_dihedral_values(self): new_file = self.get_fn( "gaussian/HC_CT_CT_HC/output/GOMC_pdb_psf_ff_files_dihedrals_zeroed.inp" @@ -375,3 +547,58 @@ def test_change_gomc_ff_file_dihedral_values(self): break assert checkFile + + with pytest.raises(TypeError): + change_gomc_ff_file_dihedral_values( + read_gomc_ff_filename=self.get_fn( + "gaussian/HC_CT_CT_HC/output/GOMC_pdb_psf_ff_files_dihedrals_per_xml.inp" + ), + new_gomc_ff_filename=new_file, + fit_dihedral_atom_types=[], + fit_dihedral_opls_k_0_1_2_3_4_values=[1, 0, 0, 0], + ) + + # zero_dihedral_atom_types must be a list or None + with pytest.raises(TypeError): + change_gomc_ff_file_dihedral_values( + read_gomc_ff_filename=self.get_fn( + "gaussian/HC_CT_CT_HC/output/GOMC_pdb_psf_ff_files_dihedrals_per_xml.inp" + ), + new_gomc_ff_filename=new_file, + fit_dihedral_atom_types=["HC", "CT", "CT", "HC"], + fit_dihedral_opls_k_0_1_2_3_4_values=[1, 0, 0, 0, 0], + zero_dihedral_atom_types="INVALID", + ) + + with pytest.raises(TypeError): + change_gomc_ff_file_dihedral_values( + read_gomc_ff_filename=self.get_fn( + "gaussian/HC_CT_CT_HC/output/GOMC_pdb_psf_ff_files_dihedrals_per_xml.inp" + ), + new_gomc_ff_filename=new_file, + fit_dihedral_atom_types=["HC", "CT", "CT", "HC"], + fit_dihedral_opls_k_0_1_2_3_4_values=[1, 0, 0, 0, 0], + zero_dihedral_atom_types=["CT"], + ) + + with pytest.raises(TypeError): + change_gomc_ff_file_dihedral_values( + read_gomc_ff_filename=self.get_fn( + "gaussian/HC_CT_CT_HC/output/GOMC_pdb_psf_ff_files_dihedrals_per_xml.inp" + ), + new_gomc_ff_filename=new_file, + fit_dihedral_atom_types=["HC", "CT", "CT", "HC"], + fit_dihedral_opls_k_0_1_2_3_4_values=[1, 0, 0, 0, 0], + zero_dihedral_atom_types=[1, 2, 3, 4], + ) + + with pytest.raises(ValueError): + change_gomc_ff_file_dihedral_values( + read_gomc_ff_filename=self.get_fn( + "gaussian/HC_CT_CT_HC/output/GOMC_pdb_psf_ff_files_dihedrals_per_xml.inp" + ), + new_gomc_ff_filename=new_file, + fit_dihedral_atom_types=["HC", "CT", "CT", "HC"], + fit_dihedral_opls_k_0_1_2_3_4_values=[1, 0, 0, 0, 0], + zero_dihedral_atom_types=["HC", "CT", "CT", "HC"], + ) diff --git a/mosdef_dihedral_fit/utils/file_read_and_write.py b/mosdef_dihedral_fit/utils/file_read_and_write.py index a5a21bf..16165f7 100755 --- a/mosdef_dihedral_fit/utils/file_read_and_write.py +++ b/mosdef_dihedral_fit/utils/file_read_and_write.py @@ -171,10 +171,8 @@ def write_xyz_file_from_gaussian_coordinates( and qm_coordinate_file_extension[0] == "." ): qm_coordinate_file_extension = qm_coordinate_file_extension[1:] - elif len(qm_coordinate_file_extension) > 0: qm_coordinate_file_extension = qm_coordinate_file_extension - else: raise ValueError( "ERROR: The 'qm_coordinate_file_extension' variable extension is not listed or a an empty string." @@ -519,7 +517,7 @@ def get_final_gaussian_output_file_data( else: for key_j, value_j in qm_log_file_dict.items(): if not isinstance(key_j, str): - raise ValueError( + raise TypeError( f"ERROR: In the 'get_final_gaussian_output_file_data' function, " f"the 'qm_log_file_dict' key " f"'{key_j}' is a {type(key_j)} not a string." @@ -804,7 +802,7 @@ def get_gaussian_log_file_data( else: for key_j, value_j in qm_log_file_dict.items(): if not isinstance(key_j, str): - raise ValueError( + raise TypeError( f"ERROR: In the 'get_gaussian_log_file_data' function, " f"the 'qm_log_file_dict' key " f"'{key_j}' is a {type(key_j)} not a string." @@ -1948,15 +1946,6 @@ def change_gomc_ff_file_dihedral_values( for list_i in zero_dihedral_atom_types: if not len(list_i) == 4: raise TypeError(zero_dihedral_atom_types_error) - - if ( - isinstance(list_i[0], str) - and isinstance(list_i[1], str) - and isinstance(list_i[2], str) - and isinstance(list_i[3], str) - ): - raise TypeError(zero_dihedral_atom_types_error) - elif not isinstance(zero_dihedral_atom_types, type(None)): raise TypeError(zero_dihedral_atom_types_error)