Skip to content

Commit

Permalink
Removed unnecessary IStatsImageItemType interface and `BaseImage.ge…
Browse files Browse the repository at this point in the history
…t_stats` method
  • Loading branch information
PierreRaybaut committed Jun 25, 2024
1 parent b24f74a commit 0ee2cd5
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 114 deletions.
1 change: 0 additions & 1 deletion plotpy/interfaces/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
IItemType,
ISerializableType,
IShapeItemType,
IStatsImageItemType,
ITrackableItemType,
IVoiImageItemType,
)
Expand Down
25 changes: 0 additions & 25 deletions plotpy/interfaces/items.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,31 +148,6 @@ def export_roi(
pass


class IStatsImageItemType(IItemType):
"""An image supporting stats computations"""

def get_stats(
self,
x0: float,
y0: float,
x1: float,
y1: float,
show_surface: bool = False,
show_integral: bool = False,
) -> str:
"""Return formatted string with stats on image rectangular area
(output should be compatible with AnnotatedShape.get_infos)
Args:
x0: X0
y0: Y0
x1: X1
y1: Y1
show_surface: Show surface (Default value = False)
show_integral: Show integral (Default value = False)
"""


class ICSImageItemType(IItemType):
"""An image supporting X/Y cross sections"""

Expand Down
84 changes: 0 additions & 84 deletions plotpy/items/image/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
IHistDataSource,
IImageItemType,
ISerializableType,
IStatsImageItemType,
ITrackableItemType,
IVoiImageItemType,
)
Expand Down Expand Up @@ -75,7 +74,6 @@ class BaseImageItem(QwtPlotItem):
IHistDataSource,
IVoiImageItemType,
ICSImageItemType,
IStatsImageItemType,
IExportROIImageItemType,
)
_can_select = True
Expand Down Expand Up @@ -720,8 +718,6 @@ def types(self) -> tuple[type[IItemType], ...]:
ITrackableItemType,
ICSImageItemType,
IExportROIImageItemType,
IStatsImageItemType,
IStatsImageItemType,
)

def set_readonly(self, state: bool) -> None:
Expand Down Expand Up @@ -998,85 +994,6 @@ def __process_cross_section(self, ydata, apply_lut):
else:
return ydata

def get_stats(
self,
x0: float,
y0: float,
x1: float,
y1: float,
show_surface: bool = False,
show_integral: bool = False,
) -> str:
"""Return formatted string with stats on image rectangular area
(output should be compatible with AnnotatedShape.get_infos)
Args:
x0: X0
y0: Y0
x1: X1
y1: Y1
show_surface: Show surface (Default value = False)
show_integral: Show integral (Default value = False)
"""
ix0, iy0, ix1, iy1 = self.get_closest_index_rect(x0, y0, x1, y1)
data = self.data[iy0:iy1, ix0:ix1]
xfmt = self.param.xformat
yfmt = self.param.yformat
zfmt = self.param.zformat
try:
xunit = xfmt.split()[1]
except IndexError:
xunit = ""
try:
yunit = yfmt.split()[1]
except IndexError:
yunit = ""
try:
zunit = zfmt.split()[1]
except IndexError:
zunit = ""
if show_integral:
integral = data.sum()
infos = "<br>".join(
[
"<b>%s</b>" % self.param.label,
"%sx%s %s"
% (self.data.shape[1], self.data.shape[0], str(self.data.dtype)),
"",
"%s ≤ x ≤ %s" % (xfmt % x0, xfmt % x1),
"%s ≤ y ≤ %s" % (yfmt % y0, yfmt % y1),
"%s ≤ z ≤ %s" % (zfmt % data.min(), zfmt % data.max()),
"‹z› = " + zfmt % data.mean(),
"σ(z) = " + zfmt % data.std(),
]
)
if show_surface and xunit == yunit:
surfacefmt = xfmt.split()[0] + " " + xunit
if xunit != "":
surfacefmt = surfacefmt + "²"
surface = abs((x1 - x0) * (y1 - y0))
infos = infos + "<br>" + _("surface = %s") % (surfacefmt % surface)
if show_integral:
integral = data.sum()
integral_fmt = r"%.3e " + zunit
infos = infos + "<br>" + _("sum = %s") % (integral_fmt % integral)
if (
show_surface
and xunit == yunit
and xunit is not None
and show_integral
and zunit is not None
):
if surface != 0:
density = integral / surface
densityfmt = r"%.3e " + zunit + "/" + xunit
if xunit != "":
densityfmt = densityfmt + "²"
infos = infos + "<br>" + _("density = %s") % (densityfmt % density)
else:
infos = infos + "<br>" + _("density not computed : surface is null !")
return infos

def get_xsection(self, y0: float | int, apply_lut: bool = False) -> np.ndarray:
"""Return cross section along x-axis at y=y0
Expand Down Expand Up @@ -1287,7 +1204,6 @@ def types(self) -> tuple[type[IItemType], ...]:
ICSImageItemType,
ISerializableType,
IExportROIImageItemType,
IStatsImageItemType,
)

def update_item_parameters(self) -> None:
Expand Down
88 changes: 84 additions & 4 deletions plotpy/tools/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from plotpy.events import QtDragHandler, setup_standard_tool_filter
from plotpy.interfaces import (
IColormapImageItemType,
IStatsImageItemType,
IImageItemType,
IVoiImageItemType,
)
from plotpy.items import (
Expand Down Expand Up @@ -63,6 +63,86 @@
from plotpy.styles.shape import AnnotationParam


def get_stats(
item: BaseImageItem,
x0: float,
y0: float,
x1: float,
y1: float,
show_surface: bool = False,
show_integral: bool = False,
) -> str:
"""Return formatted string with stats on image rectangular area
(output should be compatible with AnnotatedShape.get_infos)
Args:
x0: X0
y0: Y0
x1: X1
y1: Y1
show_surface: Show surface (Default value = False)
show_integral: Show integral (Default value = False)
"""
ix0, iy0, ix1, iy1 = item.get_closest_index_rect(x0, y0, x1, y1)
data = item.data[iy0:iy1, ix0:ix1]
param: BaseImageParam = item.param
xfmt = param.xformat
yfmt = param.yformat
zfmt = param.zformat
try:
xunit = xfmt.split()[1]
except IndexError:
xunit = ""
try:
yunit = yfmt.split()[1]
except IndexError:
yunit = ""
try:
zunit = zfmt.split()[1]
except IndexError:
zunit = ""
if show_integral:
integral = data.sum()
infos = "<br>".join(
[
"<b>%s</b>" % param.label,
"%sx%s %s" % (item.data.shape[1], item.data.shape[0], str(item.data.dtype)),
"",
"%s ≤ x ≤ %s" % (xfmt % x0, xfmt % x1),
"%s ≤ y ≤ %s" % (yfmt % y0, yfmt % y1),
"%s ≤ z ≤ %s" % (zfmt % data.min(), zfmt % data.max()),
"‹z› = " + zfmt % data.mean(),
"σ(z) = " + zfmt % data.std(),
]
)
if show_surface and xunit == yunit:
surfacefmt = xfmt.split()[0] + " " + xunit
if xunit != "":
surfacefmt = surfacefmt + "²"
surface = abs((x1 - x0) * (y1 - y0))
infos = infos + "<br>" + _("surface = %s") % (surfacefmt % surface)
if show_integral:
integral = data.sum()
integral_fmt = r"%.3e " + zunit
infos = infos + "<br>" + _("sum = %s") % (integral_fmt % integral)
if (
show_surface
and xunit == yunit
and xunit is not None
and show_integral
and zunit is not None
):
if surface != 0:
density = integral / surface
densityfmt = r"%.3e " + zunit + "/" + xunit
if xunit != "":
densityfmt = densityfmt + "²"
infos = infos + "<br>" + _("density = %s") % (densityfmt % density)
else:
infos = infos + "<br>" + _("density not computed : surface is null !")
return infos


class ImageStatsRectangle(AnnotatedRectangle):
"""Rectangle used to display image statistics
Expand Down Expand Up @@ -129,8 +209,8 @@ def get_infos(self) -> str | None:
return _("No available data")
else:
return _("No available data")
return self.image_item.get_stats(
*self.get_rect(), self.show_surface, self.show_integral
return get_stats(
self.image_item, *self.get_rect(), self.show_surface, self.show_integral
)


Expand Down Expand Up @@ -258,7 +338,7 @@ def get_associated_item(self, plot: BasePlot) -> BaseImageItem | None:
Returns:
Reference to the last image item associated with the tool
"""
items = plot.get_selected_items(item_type=IStatsImageItemType)
items = plot.get_selected_items(item_type=IImageItemType)
if len(items) == 1:
self._last_item = weakref.ref(items[0])
return self.get_last_item()
Expand Down

0 comments on commit 0ee2cd5

Please sign in to comment.