This package needs a little more attention... I wrote it when I was a much less experienced programmer, and it certainly has some obvious issues in implementation.
TODO:
- Rework
UsesReferenceFramesMixinto make it opt-out: if there's no reference frames, it can use thePHOTON_COUNTSlayer or something similar. Maybe this is asiff-naparithing to change how to pass in the data, though... - Import different
Regionobjects on demand, rather than at initialization.
Tools for ROI annotation, segmentation, etc.
This is meant to be napari agnostic without being too
napari agnostic. So it will only expect things like np.ndarray
types, but it will expect those arrays to be formatted like
napari outputs, e.g. Shapes or Image layers. This should make
it easy 1) to interact with data in napari and then pipe annotated
versions of those data into an ROIProtocol just by collecting attributes
and Layer information and 2) to make napari widgets to directly
interact with your data in napari (say, with a plugin like
siff-napari).
The goal here is to implement only the parts that are actually
segmenting numpy arrays into sets of masks with various additional
metadata -- everything else that an ROIProtocol or ROI describes
is purely for convenience, e.g. to make it easy to inspect with
the inspect module and put into other toolkits. This comes at the
expense of seeming a little abstract.
Makes use of two primary classes: ROIProtocol and ROI.
The ROIProtocol superclass contains the metadata needed to figure
out what input are needed to produce an ROI from data and some
annotations. The general structure is that an ROIProtocol implements
a function extract(self, *args, **kwargs)->'ROI', where often
the ROI class is a subclass itself. The arguments of
extract, as well as the Mixins that the ROIProtocol subclasses,
can tell other tools (e.g. siff-napari) which types of data
the ROIProtocol expects without the ROIProtocol needing to
know the exact framework being passed in. This allows nice
automated formatting of segmentation code, for example by
providing a particular type of tweakable parameter if an ROIProtocol
also subclasses UsesFrameDataMixin or UsesReferenceFramesMixin,
which can be reflected by the property uses_frame_data or
uses_reference_frames.
Please note that for siff-napari's Segmentation Widget to work properly, the
return annotations on extract must be the ACTUAL class and
not a string hint. Otherwise the object's __annotations__['return']
will read a str. TODO: make the siff-napari part smarter (convert
the string to an import)
The ROI base class has a few attributes, not all of which
are necessary to instantiate any specific ROI:
mask, annp.ndarrayofboolvalues that indicate where the ROI ispolygon, annp.ndarrayof vertices that bound the ROIimage_shape, atupleofints that describe the shape of the image theROIis embedded in.
If mask is provided, polygon and image_shape are
unnecessary, and depending on the type of ROI can sometimes
even be generated from mask alone (image_shape, for example,
almost always can). If mask is not provided but polygon and
image_shape are, it is expected that a given ROI class is capable
of producing a useful mask with the property mask. A generic
ROI could, for example, take the convex hull of polygon and
fill it within an array of size image_shape, but this would
only be useful for the most basic ROI (others, like Ellipse
or Fan should produce more useful masks).
ROI objects can be saved with the save(self, path : PathLike)
method, where PathLike = Union[str, pathlib.Path]. This will
store the ROI in a .h5roi file, which is just an h5 file
saved with the various datatypes.
ROIs can be initialized with other parameters, such as a name,
an integer with the slice index from which it was drawn, or a
pre-made list of subROIs.
Often an ROI will be split further (e.g. wedges of an Ellipse).
Most ROI classes will implement a segment function that takes
the primary ROI and populates its subROIs attribute with a list
of the ROI subclass subROI.
The module implements many different region-specific segmentation
algorithms. To provide a common access point, a list of
objects of class Region is provided in siffroi. A Region
consists of:
alias_list: a list of aliases (strthat all can be used to refer to the region)module: themodulewithinsiffroithat containsRegion-specificROIProtocolobjects and methodsdefault_fcn_str: a default protocol referred to by astrversion of itsname(for readability -- it can be accessed withRegion.default_protocolwhich produces the actualROIProtocolinstead of the string)region_enum, aRegionEnumattribute
These are defined in siffroi.utils.regions