diff --git a/etspy/base.py b/etspy/base.py index f591cf5f..0c3f3270 100644 --- a/etspy/base.py +++ b/etspy/base.py @@ -2085,17 +2085,15 @@ def recon_error( def extract_sinogram( self, - column: Optional[Union[int, float]] = None, - row: Optional[Union[int, float]] = None, + column: Union[int, float], # noqa: PYI041 ) -> Signal2D: """ - Extract a sinogram from a single row or column of the TomoStack. + Extract a sinogram from a single column of the TomoStack. - Exactly one of either "column" (x-axis location) or "row" (y-axis - location) must be provided. The value to use can be supplied as either + The value to use for ``column`` can be supplied as either an integer for pixel-based indexing, or as a float for unit-based indexing. The resulting image will have the stack's projection axis - oriented vertically and the opposite axis horizontally. + oriented vertically and the y-axis horizontally. Parameters ---------- @@ -2103,51 +2101,36 @@ def extract_sinogram( The x-axis position to use for computing the sinogram. If an integer, pixel-basd indexing will be used. If a float, unit-based indexing will be used. - row - The y-axis position to use for computing the sinogram. If an integer, - pixel-basd indexing will be used. If a float, unit-based indexing will - be used. Returns ------- sino : Signal2D - A single image representing the row or column data over the range of + A single image representing the single column data over the range of projections in the original TomoStack. Raises ------ - ValueError - Raised if both column and row arguments are provided, or if neither - are provided. + TypeError + Raised if column is neither a float or int """ - if (column is not None) and (row is not None): - msg = 'Only one of "column" or "row" may be provided.' - raise ValueError(msg) - if (column is None) and (row is None): - msg = 'One of "column" or "row" must be provided.' - raise ValueError(msg) + if not isinstance(column, (float, int)): + msg = ( + '"column" argument must be either a float or an integer ' + f"(was {type(column)})" + ) + raise TypeError(msg) # hide isig warning from TomoStackSlicer orig_logger_state = logger.disabled logger.disabled = True try: - sino = self - if row: - sino = self.isig[:, row] - sino.set_signal_type("") - sino = cast(Signal2D, sino.as_signal2D((1, 0))) - if isinstance(row, float): - title = f"Sinogram at y = {row} {self.axes_manager[2].units}" # type: ignore - else: - title = f"Sinogram at row {row}" + sino = self.isig[column, :] + sino.set_signal_type("") + sino = cast(Signal2D, sino.as_signal2D((2, 0))) + if isinstance(column, float): + title = f"Sinogram at x = {column} {self.axes_manager[1].units}" # type: ignore else: - sino = self.isig[column, :] - sino.set_signal_type("") - sino = cast(Signal2D, sino.as_signal2D((2, 0))) - if isinstance(column, float): - title = f"Sinogram at x = {column} {self.axes_manager[1].units}" # type: ignore - else: - title = f"Sinogram at column {column}" + title = f"Sinogram at column {column}" except Exception: # if there was an error above, reset the logger state # before raising it diff --git a/etspy/tests/test_base.py b/etspy/tests/test_base.py index 663afbda..1b3e4982 100644 --- a/etspy/tests/test_base.py +++ b/etspy/tests/test_base.py @@ -862,29 +862,9 @@ def test_recstack_sig_slicer(self, caplog): class TestExtractSinogram: """Test extract_sinogram method.""" - def test_extract_sinogram_row(self): + def test_extract_sinogram(self): stack = ds.get_catalyst_data() - sino = stack.extract_sinogram(row=300) - ax_0, ax_1 = cast(list[Uda], [sino.axes_manager[i] for i in range(2)]) - assert sino.axes_manager.shape == (600, 90) - assert sino.metadata.get_item("Signal.signal_type") == "" - assert ax_0.name == "x" - assert ax_1.name == "Projections" - assert sino.metadata.get_item("General.title") == "Sinogram at row 300" - - def test_extract_sinogram_row_float(self): - stack = ds.get_catalyst_data() - sino = stack.extract_sinogram(row=102.3) - ax_0, ax_1 = cast(list[Uda], [sino.axes_manager[i] for i in range(2)]) - assert sino.axes_manager.shape == (600, 90) - assert sino.metadata.get_item("Signal.signal_type") == "" - assert ax_0.name == "x" - assert ax_1.name == "Projections" - assert sino.metadata.get_item("General.title") == "Sinogram at y = 102.3 nm" - - def test_extract_sinogram_column(self): - stack = ds.get_catalyst_data() - sino = stack.extract_sinogram(column=300) + sino = stack.extract_sinogram(300) ax_0, ax_1 = cast(list[Uda], [sino.axes_manager[i] for i in range(2)]) assert sino.axes_manager.shape == (600, 90) assert sino.metadata.get_item("Signal.signal_type") == "" @@ -892,9 +872,9 @@ def test_extract_sinogram_column(self): assert ax_1.name == "Projections" assert sino.metadata.get_item("General.title") == "Sinogram at column 300" - def test_extract_sinogram_column_float(self): + def test_extract_sinogram_float(self): stack = ds.get_catalyst_data() - sino = stack.extract_sinogram(column=106.32) + sino = stack.extract_sinogram(106.32) ax_0, ax_1 = cast(list[Uda], [sino.axes_manager[i] for i in range(2)]) assert sino.axes_manager.shape == (600, 90) assert sino.metadata.get_item("Signal.signal_type") == "" @@ -902,28 +882,25 @@ def test_extract_sinogram_column_float(self): assert ax_1.name == "Projections" assert sino.metadata.get_item("General.title") == "Sinogram at x = 106.32 nm" - def test_extract_sinogram_neither_row_nor_column(self): + def test_extract_sinogram_bad_argument_type(self): stack = ds.get_catalyst_data() with pytest.raises( - ValueError, - match=re.escape('One of "column" or "row" must be provided.'), + TypeError, + match=re.escape( + '"column" argument must be either a float or an integer ' + "(was )", + ), ): - stack.extract_sinogram() + stack.extract_sinogram("bad_val") # type: ignore - def test_extract_sinogram_both_row_and_column(self): - stack = ds.get_catalyst_data() - with pytest.raises( - ValueError, - match=re.escape('Only one of "column" or "row" may be provided.'), - ): - stack.extract_sinogram(row=300, column=200) def test_extract_sinogram_exception_handling(self): # test that on exception, logger is still enabled stack = ds.get_catalyst_data() assert logging.getLogger("etspy.base").disabled is False with pytest.raises(IndexError): - stack.extract_sinogram(column="weird") # type: ignore + # using too large of a value should trigger an error + stack.extract_sinogram(column=10000) assert logging.getLogger("etspy.base").disabled is False class TestFiltering: