Loading docs/api/imars3d.backend.corrections.rst +2 −2 Original line number Diff line number Diff line Loading @@ -34,7 +34,7 @@ imars3d.backend.corrections.intensity\_fluctuation\_correction module :members: :undoc-members: :show-inheritance: :exclude-members: ct, air_pixels, max_workers, name, sigma, tqdm_class :exclude-members: ct, air_pixels, max_workers, name, sigma, tqdm_class, roi imars3d.backend.corrections.ring\_removal module ------------------------------------------------ Loading @@ -43,4 +43,4 @@ imars3d.backend.corrections.ring\_removal module :members: :undoc-members: :show-inheritance: :exclude-members: arrays, correction_range, kernel_size, max_workers, name, sub_division, tqdm_class, sinogram :exclude-members: arrays, correction_range, kernel_size, max_workers, name, sub_division, tqdm_class, sinogram, extreme_streak_iterations, extreme_detect_lambda, extreme_detect_size, extreme_replace_size, max_bin_iter_horizontal, bin_vertical, filter_strength, use_slices, slice_sizes, slice_step_sizes, denoise_indices src/imars3d/backend/diagnostics/rotation.py +7 −7 Original line number Diff line number Diff line Loading @@ -26,8 +26,8 @@ class find_rotation_center(param.ParameterizedFunction): array of angles in degrees or radians, which must match the order of arrays in_degrees: bool = True whether angles are in degrees or radians, default is True (degrees) atol_deg: float = 1e-3 tolerance for the search of 180 deg paris, default is 0.1 degrees atol_deg: Optional[float] = None tolerance for the search of 180 deg paris, default is None ("auto") num_pairs: int = 1 Number of pairs to look for. Specifying -1 means as many pairs as possible. max_workers: int = 0 Loading @@ -46,8 +46,8 @@ class find_rotation_center(param.ParameterizedFunction): ) in_degrees = param.Boolean(default=True, doc="whether angles are in degrees or radians, default is True (degrees)") atol_deg = param.Number( default=1e-3, doc="tolerance for the search of 180 deg paris, default is 0.1 degrees", default=None, doc="tolerance for the search of 180 deg paris, default is None (auto)", ) num_pairs = param.Integer( default=1, bounds=(-1, None), doc="Number of pairs to look for. Specifying -1 means as many pairs as possible." Loading @@ -72,7 +72,7 @@ class find_rotation_center(param.ParameterizedFunction): arrays=params.arrays, angles=params.angles, in_degrees=params.in_degrees, atol_deg=params.atol_deg, atol=params.atol_deg, num_pairs=params.num_pairs, max_workers=self.max_workers, tqdm_class=params.tqdm_class, Loading @@ -85,7 +85,7 @@ class find_rotation_center(param.ParameterizedFunction): arrays: np.ndarray, angles: np.ndarray, in_degrees: bool = True, atol_deg: float = 1e-3, atol: float = None, num_pairs: int = 1, max_workers: int = -1, tqdm_class=None, Loading @@ -96,8 +96,8 @@ class find_rotation_center(param.ParameterizedFunction): logger.error(msg) raise ValueError(msg) # locate 180 degree pairs atol = atol_deg if in_degrees else np.radians(atol_deg) idx_low, idx_hgh = find_180_deg_pairs_idx(angles, atol=atol, in_degrees=in_degrees) # decide how many pairs to use if num_pairs <= 0 or num_pairs >= idx_low.size: logger.info("Using all pairs of angles") elif num_pairs == 1: Loading src/imars3d/backend/diagnostics/tilt.py +10 −2 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ logger = logging.getLogger(__name__) def find_180_deg_pairs_idx( angles: np.ndarray, atol: float = 1e-3, atol: float = None, in_degrees: bool = True, ) -> Tuple[np.ndarray, np.ndarray]: """ Loading @@ -31,7 +31,7 @@ def find_180_deg_pairs_idx( angles: The list of angles as a 1d array. atol: The absolute tolerance in degree for the 180 degree pairs. The absolute tolerance for the 180 degree pairs. in_degrees: Whether the angles are in degrees or radians, default is in degrees. Loading @@ -45,6 +45,14 @@ def find_180_deg_pairs_idx( raise ValueError("angles must be a 1d array") # ensure angles are in degrees angles = angles if in_degrees else np.degrees(angles) # compute atol if not specified if atol is None: sorted_indices = np.argsort(angles) atol = np.min(np.diff(angles[sorted_indices])) / 2.0 del sorted_indices logger.debug(f"use computed atol = {atol}") else: atol = atol if in_degrees else np.degrees(atol) # compute the self difference matrix angles = angles[..., np.newaxis] diff_matrix = angles.T - angles Loading tests/unit/backend/diagnostics/test_rotation.py +3 −0 Original line number Diff line number Diff line Loading @@ -72,10 +72,13 @@ def test_differrent_centers(center_ref): projs = get_synthetic_stack(center_ref) # this is using default number of pairs (1) center_calc = find_rotation_center(arrays=projs, angles=OMEGAS, in_degrees=False) # with atol center_calc2 = find_rotation_center(arrays=projs, angles=OMEGAS, in_degrees=False, atol=0.5) # verify # NOTE: # answer within the same pixel should be sufficient for most cases np.testing.assert_allclose(center_calc, center_ref, atol=0.2) np.testing.assert_allclose(center_calc2, center_ref, atol=0.2) def test_wrong_dimension(): Loading tests/unit/backend/diagnostics/test_tilt.py +7 −0 Original line number Diff line number Diff line Loading @@ -227,6 +227,13 @@ def test_find_180_deg_pairs(): # verify np.testing.assert_equal(low_range_idx, np.array([0, 1, 2, 3, 4])) np.testing.assert_equal(high_range_idx, np.array([5, 6, 7, 8, 9])) # test explicit atol # NOTE: use the same formula to compute atol outside the function sorted_indices = np.argsort(omegas) atol = np.min(np.diff(omegas[sorted_indices])) / 2.0 low_range_idx, high_range_idx = find_180_deg_pairs_idx(omegas, in_degrees=False, atol=atol) np.testing.assert_equal(low_range_idx, np.array([0, 1, 2, 3, 4])) np.testing.assert_equal(high_range_idx, np.array([5, 6, 7, 8, 9])) # test incorrect input omegas = np.random.random(5 * 5) * np.pi omegas = omegas.reshape(5, 5) Loading Loading
docs/api/imars3d.backend.corrections.rst +2 −2 Original line number Diff line number Diff line Loading @@ -34,7 +34,7 @@ imars3d.backend.corrections.intensity\_fluctuation\_correction module :members: :undoc-members: :show-inheritance: :exclude-members: ct, air_pixels, max_workers, name, sigma, tqdm_class :exclude-members: ct, air_pixels, max_workers, name, sigma, tqdm_class, roi imars3d.backend.corrections.ring\_removal module ------------------------------------------------ Loading @@ -43,4 +43,4 @@ imars3d.backend.corrections.ring\_removal module :members: :undoc-members: :show-inheritance: :exclude-members: arrays, correction_range, kernel_size, max_workers, name, sub_division, tqdm_class, sinogram :exclude-members: arrays, correction_range, kernel_size, max_workers, name, sub_division, tqdm_class, sinogram, extreme_streak_iterations, extreme_detect_lambda, extreme_detect_size, extreme_replace_size, max_bin_iter_horizontal, bin_vertical, filter_strength, use_slices, slice_sizes, slice_step_sizes, denoise_indices
src/imars3d/backend/diagnostics/rotation.py +7 −7 Original line number Diff line number Diff line Loading @@ -26,8 +26,8 @@ class find_rotation_center(param.ParameterizedFunction): array of angles in degrees or radians, which must match the order of arrays in_degrees: bool = True whether angles are in degrees or radians, default is True (degrees) atol_deg: float = 1e-3 tolerance for the search of 180 deg paris, default is 0.1 degrees atol_deg: Optional[float] = None tolerance for the search of 180 deg paris, default is None ("auto") num_pairs: int = 1 Number of pairs to look for. Specifying -1 means as many pairs as possible. max_workers: int = 0 Loading @@ -46,8 +46,8 @@ class find_rotation_center(param.ParameterizedFunction): ) in_degrees = param.Boolean(default=True, doc="whether angles are in degrees or radians, default is True (degrees)") atol_deg = param.Number( default=1e-3, doc="tolerance for the search of 180 deg paris, default is 0.1 degrees", default=None, doc="tolerance for the search of 180 deg paris, default is None (auto)", ) num_pairs = param.Integer( default=1, bounds=(-1, None), doc="Number of pairs to look for. Specifying -1 means as many pairs as possible." Loading @@ -72,7 +72,7 @@ class find_rotation_center(param.ParameterizedFunction): arrays=params.arrays, angles=params.angles, in_degrees=params.in_degrees, atol_deg=params.atol_deg, atol=params.atol_deg, num_pairs=params.num_pairs, max_workers=self.max_workers, tqdm_class=params.tqdm_class, Loading @@ -85,7 +85,7 @@ class find_rotation_center(param.ParameterizedFunction): arrays: np.ndarray, angles: np.ndarray, in_degrees: bool = True, atol_deg: float = 1e-3, atol: float = None, num_pairs: int = 1, max_workers: int = -1, tqdm_class=None, Loading @@ -96,8 +96,8 @@ class find_rotation_center(param.ParameterizedFunction): logger.error(msg) raise ValueError(msg) # locate 180 degree pairs atol = atol_deg if in_degrees else np.radians(atol_deg) idx_low, idx_hgh = find_180_deg_pairs_idx(angles, atol=atol, in_degrees=in_degrees) # decide how many pairs to use if num_pairs <= 0 or num_pairs >= idx_low.size: logger.info("Using all pairs of angles") elif num_pairs == 1: Loading
src/imars3d/backend/diagnostics/tilt.py +10 −2 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ logger = logging.getLogger(__name__) def find_180_deg_pairs_idx( angles: np.ndarray, atol: float = 1e-3, atol: float = None, in_degrees: bool = True, ) -> Tuple[np.ndarray, np.ndarray]: """ Loading @@ -31,7 +31,7 @@ def find_180_deg_pairs_idx( angles: The list of angles as a 1d array. atol: The absolute tolerance in degree for the 180 degree pairs. The absolute tolerance for the 180 degree pairs. in_degrees: Whether the angles are in degrees or radians, default is in degrees. Loading @@ -45,6 +45,14 @@ def find_180_deg_pairs_idx( raise ValueError("angles must be a 1d array") # ensure angles are in degrees angles = angles if in_degrees else np.degrees(angles) # compute atol if not specified if atol is None: sorted_indices = np.argsort(angles) atol = np.min(np.diff(angles[sorted_indices])) / 2.0 del sorted_indices logger.debug(f"use computed atol = {atol}") else: atol = atol if in_degrees else np.degrees(atol) # compute the self difference matrix angles = angles[..., np.newaxis] diff_matrix = angles.T - angles Loading
tests/unit/backend/diagnostics/test_rotation.py +3 −0 Original line number Diff line number Diff line Loading @@ -72,10 +72,13 @@ def test_differrent_centers(center_ref): projs = get_synthetic_stack(center_ref) # this is using default number of pairs (1) center_calc = find_rotation_center(arrays=projs, angles=OMEGAS, in_degrees=False) # with atol center_calc2 = find_rotation_center(arrays=projs, angles=OMEGAS, in_degrees=False, atol=0.5) # verify # NOTE: # answer within the same pixel should be sufficient for most cases np.testing.assert_allclose(center_calc, center_ref, atol=0.2) np.testing.assert_allclose(center_calc2, center_ref, atol=0.2) def test_wrong_dimension(): Loading
tests/unit/backend/diagnostics/test_tilt.py +7 −0 Original line number Diff line number Diff line Loading @@ -227,6 +227,13 @@ def test_find_180_deg_pairs(): # verify np.testing.assert_equal(low_range_idx, np.array([0, 1, 2, 3, 4])) np.testing.assert_equal(high_range_idx, np.array([5, 6, 7, 8, 9])) # test explicit atol # NOTE: use the same formula to compute atol outside the function sorted_indices = np.argsort(omegas) atol = np.min(np.diff(omegas[sorted_indices])) / 2.0 low_range_idx, high_range_idx = find_180_deg_pairs_idx(omegas, in_degrees=False, atol=atol) np.testing.assert_equal(low_range_idx, np.array([0, 1, 2, 3, 4])) np.testing.assert_equal(high_range_idx, np.array([5, 6, 7, 8, 9])) # test incorrect input omegas = np.random.random(5 * 5) * np.pi omegas = omegas.reshape(5, 5) Loading