diff --git a/arc/species/converter.py b/arc/species/converter.py index b8ec5e7d06..c2d488a963 100644 --- a/arc/species/converter.py +++ b/arc/species/converter.py @@ -44,6 +44,9 @@ ob.obErrorLog.SetOutputLevel(0) logger = get_logger() +DIST_PRECISION = 0.01 # Angstrom +ANGL_PRECISION = 0.1 # rad (for both bond angle and dihedral) + def str_to_xyz(xyz_str: str, project_directory: Optional[str] = None, @@ -2074,7 +2077,7 @@ def calculate_errors(result_coords): def meets_precision(result_coords): r_error, a_error, d_error = calculate_errors(result_coords) - return r_error < 0.01 and a_error < 0.1 and d_error < 0.1 + return r_error < DIST_PRECISION and a_error < ANGL_PRECISION and d_error < ANGL_PRECISION guess_functions = [ generate_initial_guess_r_a, @@ -2262,7 +2265,9 @@ def angle_eq(x, y, z): cross_product_length = np.linalg.norm(np.cross(BA, BX)) dot_product = np.dot(BA, BX) calc_angle = math.atan2(cross_product_length, dot_product) - return (calc_angle - target_angle) ** 2 + angle_diff = calc_angle - target_angle + wrapped_diff = np.arctan2(np.sin(angle_diff), np.cos(angle_diff)) # wrapped to the range (-pi, pi] + return wrapped_diff return angle_eq @@ -2310,7 +2315,7 @@ def dihedral_eq(x, y, z): BC_norm = np.linalg.norm(BC) cos_calc = np.dot(N1, N2) / (N1_norm * N2_norm) sin_calc = np.dot(BC, np.cross(N1, N2)) / (BC_norm * N1_norm * N2_norm) - return (cos_calc - cos_d) ** 2 + (sin_calc - sin_d) ** 2 + return np.sqrt((cos_calc - cos_d) ** 2 + (sin_calc - sin_d) ** 2) return dihedral_eq diff --git a/arc/species/converter_test.py b/arc/species/converter_test.py index 8203d2f56c..086b46c2ea 100644 --- a/arc/species/converter_test.py +++ b/arc/species/converter_test.py @@ -1082,7 +1082,6 @@ def test_zmat_from_xyz(self): 'A_9_0_1': 107.32624053955078, 'D_9_0_1_8': 243.79214484231346, 'R_6|7_4|4': 1.089653491973877}, 'map': {0: 1, 1: 0, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9}} - self.assertEqual(zmat_1, expected_zmat_1) self.assertTrue(_compare_zmats(zmat_1, expected_zmat_1)) zmat_2 = converter.zmat_from_xyz(xyz=self.xyz6['str'], @@ -4669,7 +4668,7 @@ def test_add_atom_to_xyz_using_internal_coords(self): (-3.17488405, 0.21042224, 1.24128129), (-3.53487445, 1.21797729, 1.25310144), (-3.56603419, -0.31800758, 2.08547528), (-1.63624745, 0.21425655, 1.30595531), (-1.24509731, 0.74268637, 0.46176133), (-1.3183353, 0.6960459, 2.20690531), - (-1.0413732051724125, -1.4526805980775839, 1.2873769860752802))} + (-1.0398666203453495, -1.4521333553792743, 1.2864271004043641))} self.assertTrue(almost_equal_coords_lists(new_xyz_1, expected_xyz_1)) self.assertAlmostEqual(calculate_param(coords=new_xyz_1['coords'], atoms=[7, 10]), 1.77, places=2) self.assertAlmostEqual(calculate_param(coords=new_xyz_1['coords'], atoms=[4, 7, 10]), 109.5, places=1) @@ -4685,9 +4684,9 @@ def test_add_atom_to_xyz_using_internal_coords(self): d_value=-60.0, opt_method='BFGS', ) - self.assertAlmostEqual(new_xyz_2['coords'][-1][0], -1.065095539786487, places=3) - self.assertAlmostEqual(new_xyz_2['coords'][-1][1], -1.4737067126385224, places=3) - self.assertAlmostEqual(new_xyz_2['coords'][-1][2], 1.2912758496528232, places=3) + self.assertAlmostEqual(new_xyz_2['coords'][-1][0], -1.0407054376010356, places=2) + self.assertAlmostEqual(new_xyz_2['coords'][-1][1], -1.4428236405325816, places=2) + self.assertAlmostEqual(new_xyz_2['coords'][-1][2], 1.2912758496528232, places=2) self.assertAlmostEqual(calculate_param(coords=new_xyz_1['coords'], atoms=[4, 10]), 2.70, places=1) self.assertAlmostEqual(calculate_param(coords=new_xyz_1['coords'], atoms=[4, 0, 10]), 61.46, places=0) self.assertAlmostEqual(calculate_param(coords=new_xyz_1['coords'], atoms=[0, 4, 7, 10]), 300, places=1) @@ -4715,7 +4714,7 @@ def test_add_atom_to_xyz_using_internal_coords(self): (0.35773087, -1.66017412, -0.9786309), (-0.45608483, -1.87500387, -1.86208833), (-1.82486467, -0.81522856, 0.14629516), (-1.06962462, 0.60119223, 0.90442455), (-1.14968688, 0.45844916, -0.88969505), (1.33643417, -2.15859899, -0.90083808), - (1.4820209463152687, -2.3772302636106577, 0.30367261748030894))} + (1.4828150949768655, -2.377060198658591, 0.30306573909787815))} self.assertTrue(almost_equal_coords(new_xyz_3, expected_xyz)) self.assertAlmostEqual(calculate_param(coords=new_xyz_3['coords'], atoms=[2, 8]), 1.85, places=2) self.assertAlmostEqual(calculate_param(coords=new_xyz_3['coords'], atoms=[1, 2, 8]), 77.4, places=1) @@ -4744,9 +4743,9 @@ def test_add_atom_to_xyz_using_internal_coords(self): a_value=77.4, d_value=140, ) - self.assertAlmostEqual(new_xyz_4['coords'][-1][0], 1.8986166253764283) - self.assertAlmostEqual(new_xyz_4['coords'][-1][1], 0.9987236974936107) - self.assertAlmostEqual(new_xyz_4['coords'][-1][2], 0.8154061174277444) + self.assertAlmostEqual(new_xyz_4['coords'][-1][0], 1.8986166253764283, places=2) + self.assertAlmostEqual(new_xyz_4['coords'][-1][1], 0.9987236974936107, places=2) + self.assertAlmostEqual(new_xyz_4['coords'][-1][2], 0.8154061174277444, places=2) self.assertAlmostEqual(calculate_param(coords=new_xyz_4['coords'], atoms=[1, 14]), 1.85, places=2) self.assertAlmostEqual(calculate_param(coords=new_xyz_4['coords'], atoms=[3, 1, 14]), 77.4, places=1) self.assertAlmostEqual(calculate_param(coords=new_xyz_4['coords'], atoms=[2, 0, 1, 14]), 140, places=1)