@@ -552,6 +552,10 @@ def get_residue_custom_axes(self, edges, center):
552552 rot_center: (3,) rotation centre,
553553 lies on the E1-E2 vector
554554 rot_axes: (3,3) rotation axes of residue
555+
556+ Raises:
557+ ValueError: If axes cannot be normalized due to degeneracy.
558+
555559 """
556560 first_edge_centre_of_geometry_vector = center - edges [0 ]
557561 # look for projection of E1-O onto E1-E2 (E1-C)
@@ -567,10 +571,11 @@ def get_residue_custom_axes(self, edges, center):
567571 )
568572 y_axis = origin_centre_of_geometry_vector
569573 z_axis = np .cross (x_axis , y_axis )
570- x_axis /= np .linalg .norm (x_axis )
571- y_axis /= np .linalg .norm (y_axis )
572- z_axis /= np .linalg .norm (z_axis )
573- rot_axes = np .array ([x_axis , y_axis , z_axis ])
574+ unscaled_rot_axes = np .array ((x_axis , y_axis , z_axis ), dtype = float )
575+ mod = np .sqrt (np .sum (unscaled_rot_axes ** 2 , axis = 1 ))
576+ if np .any (np .isclose (mod , 0.0 )):
577+ raise ValueError ("Degenerate custom axes: cannot normalize (zero norm)." )
578+ rot_axes = unscaled_rot_axes / mod [:, np .newaxis ]
574579 rot_center = first_edge_origin_vector + edges [0 ]
575580 return rot_center , rot_axes
576581
@@ -677,7 +682,8 @@ def get_non_terminal_axes(self, residue, edges, dimensions):
677682 return rot_center , rot_axes
678683
679684 def get_bonded_axes (self , system , atom , dimensions : np .ndarray ):
680- r"""Compute UA rotational axes from bonded topology around a heavy atom.
685+ """
686+ Compute UA rotational axes from bonded topology around a heavy atom.
681687
682688 For a given heavy atom, use its bonded atoms to get the axes for rotating
683689 forces around. Few cases for choosing united atom axes, which are dependent
0 commit comments