Skip to content

Commit bd6b002

Browse files
committed
Return deviations if closest results are returned instead of exact ones
in add_atom_to_xyz_using_internal_coords function
1 parent 52ef03b commit bd6b002

File tree

1 file changed

+39
-9
lines changed

1 file changed

+39
-9
lines changed

arc/species/converter.py

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2181,7 +2181,7 @@ def add_atom_to_xyz_using_internal_coords(xyz: Union[dict, str],
21812181
a_value: float,
21822182
d_value: float,
21832183
opt_method: str = 'Nelder-Mead',
2184-
) -> Optional[dict]:
2184+
) -> Tuple[Optional[dict], Optional[dict]]:
21852185
"""
21862186
Add an atom to XYZ. The new atom may have random r, a, and d index parameters
21872187
(not necessarily defined for the same respective atoms).
@@ -2200,11 +2200,19 @@ def add_atom_to_xyz_using_internal_coords(xyz: Union[dict, str],
22002200
opt_method (str, optional): The optimization method to use for finding the new atom's coordinates.
22012201
Additional options include 'trust-constr' and 'BFGS'.
22022202
2203-
Returns:
2204-
Optional[dict]: The updated xyz coordinates.
2203+
Returns:
2204+
xyz_guess: Optional[dict]
2205+
The updated xyz coordinates dictionary if successful, None if no solution found
2206+
deviations: Optional[dict]
2207+
A dictionary of precision deviations if criteria weren't met:
2208+
{
2209+
'distance': {'index': tuple, 'desired': float, 'error': float}, # distance error in Angstroms
2210+
'angle': {'indices': tuple, 'desired': float, 'error': float}, # angle error in degrees
2211+
'dihedral': {'indices': tuple, 'desired': float, 'error': float} # dihedral error in degrees
2212+
}
2213+
Returns None if precision criteria were met or no solution found.
22052214
"""
22062215
xyz = check_xyz_dict(xyz)
2207-
22082216
def calculate_errors(result_coords):
22092217
r_error = np.abs(np.sqrt(np.sum((np.array(result_coords) - np.array(xyz['coords'][r_index]))**2)) - r_value)
22102218
a_error = np.sqrt(angle_constraint(xyz['coords'][a_indices[0]], xyz['coords'][a_indices[1]], a_value)(*result_coords))
@@ -2213,7 +2221,7 @@ def calculate_errors(result_coords):
22132221

22142222
def meets_precision(result_coords):
22152223
r_error, a_error, d_error = calculate_errors(result_coords)
2216-
return r_error < 0.01 and a_error < 0.1 and d_error < 0.1
2224+
return r_error < 0.1 and a_error < 0.05236 and d_error < 0.05236
22172225

22182226
guess_functions = [
22192227
generate_initial_guess_r_a,
@@ -2249,22 +2257,44 @@ def meets_precision(result_coords):
22492257

22502258
if meets_precision(new_coord):
22512259
print("Precision criteria met. Returning result.")
2252-
return updated_xyz
2260+
return updated_xyz, None
22532261

22542262
if total_error < closest_error:
22552263
print(f"Updating closest result. Previous closest_error={closest_error}, new total_error={total_error}")
22562264
closest_result = updated_xyz
2265+
closest_errors = (r_error, a_error, d_error)
22572266
closest_error = total_error
22582267

22592268
except Exception as e:
22602269
print(f"Attempt {attempt} with {guess_func.__name__} failed due to exception: {e}")
22612270

22622271
if closest_result is not None:
2263-
print("Returning closest result as no guess met precision criteria.")
2264-
return closest_result
2272+
r_error, a_error, d_error = closest_errors
2273+
print(d_indices)
2274+
deviations = {}
2275+
last_index= len(updated_xyz['coords']) - 1
2276+
if r_error >= 0.1:
2277+
deviations['distance'] = {
2278+
'index': (r_index, last_index),
2279+
'desired': r_value,
2280+
'error': r_error
2281+
}
2282+
if a_error >= 0.05236:
2283+
deviations['angle'] = {
2284+
'indices': (a_indices[0], a_indices[1], last_index),
2285+
'desired': a_value,
2286+
'error': np.degrees(a_error)
2287+
}
2288+
if d_error >= 0.05236:
2289+
deviations['dihedral'] = {
2290+
'indices': (d_indices[0], d_indices[1], d_indices[2], last_index),
2291+
'desired': np.degrees(d_value),
2292+
'error': np.degrees(d_error)
2293+
}
2294+
return closest_result, deviations
22652295

22662296
print("No valid solution was found.")
2267-
return None
2297+
return None, None
22682298

22692299

22702300
def _add_atom_to_xyz_using_internal_coords(xyz: dict,

0 commit comments

Comments
 (0)