diff --git a/arc/species/converter.py b/arc/species/converter.py index 101bd04be6..bd35a1a07d 100644 --- a/arc/species/converter.py +++ b/arc/species/converter.py @@ -2011,6 +2011,43 @@ def compare_zmats(z1, z2, r_tol=0.01, a_tol=2, d_tol=2, verbose=False, symmetric symmetric_torsions=symmetric_torsions) +def compare_confs_fl(xyz1: dict, + xyz2: dict, + rtol: float = 0.01, + dmat2: Optional[np.ndarray] = None, + fl_distance2: Optional[float] = None, + ) -> Tuple[Optional[float], Optional[float], Optional[np.ndarray], Optional[np.ndarray]]: + """ + Compare two Cartesian coordinates representing conformers using first and last atom distances. If the distances are the same, + the distance matrices are computed and returned. + + The relative difference (``rtol`` * fl_distance1) is compared against the absolute difference abs(fl_distance1 - fl_distance2). + + Args: + xyz1 (dict): Conformer 1. + xyz2 (dict): Conformer 2. + rtol (float): The relative tolerance parameter (see Notes). + dmat2 (np.ndarray, optional): The distance matrix of conformer 2. + fl_distance2 (float, optional): The first and last atom distance of conformer 2. + + Returns: + Tuple containing distances and matrices: + - (fl_distance1, fl_distance2, dmat1, dmat2): First-to-last distances and distance matrices for both conformers. + """ + xyz1, xyz2 = check_xyz_dict(xyz1), check_xyz_dict(xyz2) + dmat1 = None + fl_distance1 = np.linalg.norm(np.array(xyz1['coords'][0]) - np.array(xyz1['coords'][-1])) + if fl_distance2 is None: + fl_distance2 = np.linalg.norm(np.array(xyz2['coords'][0]) - np.array(xyz2['coords'][-1])) + if abs(fl_distance1-fl_distance2)/fl_distance1>rtol: + return fl_distance1, fl_distance2, dmat1, dmat2 + if dmat1 is None: + dmat1 = xyz_to_dmat(xyz1) + if dmat2 is None: + dmat2 = xyz_to_dmat(xyz2) + return fl_distance1, fl_distance2, dmat1, dmat2 + + def compare_confs(xyz1: dict, xyz2: dict, rtol: float = 0.01,