Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

typing for NumpySegmentationExtractor #333

Open
bendichter opened this issue May 18, 2024 · 0 comments
Open

typing for NumpySegmentationExtractor #333

bendichter opened this issue May 18, 2024 · 0 comments

Comments

@bendichter
Copy link
Contributor

class NumpySegmentationExtractor(SegmentationExtractor):
"""A Segmentation extractor specified by image masks and traces .npy files.
NumpySegmentationExtractor objects are built to contain all data coming from
a file format for which there is currently no support. To construct this,
all data must be entered manually as arguments.
"""
extractor_name = "NumpySegmentationExtractor"
installed = True # check at class level if installed or not
is_writable = True
mode = "file"
installation_mesg = "" # error message when not installed
def __init__(
self,
image_masks,
raw=None,
dff=None,
deconvolved=None,
neuropil=None,
accepted_lst=None,
mean_image=None,
correlation_image=None,
roi_ids=None,
roi_locations=None,
sampling_frequency=None,
rejected_list=None,
channel_names=None,
movie_dims=None,
):
"""Create a NumpySegmentationExtractor from a .npy file.
Parameters
----------
image_masks: np.ndarray
Binary image for each of the regions of interest
raw: np.ndarray
Fluorescence response of each of the ROI in time
dff: np.ndarray
DfOverF response of each of the ROI in time
deconvolved: np.ndarray
deconvolved response of each of the ROI in time
neuropil: np.ndarray
neuropil response of each of the ROI in time
mean_image: np.ndarray
Mean image
correlation_image: np.ndarray
correlation image
roi_ids: int list
Unique ids of the ROIs if any
roi_locations: np.ndarray
x and y location representative of ROI mask
sampling_frequency: float
Frame rate of the movie
rejected_list: list
list of ROI ids that are rejected manually or via automated rejection
channel_names: list
list of strings representing channel names
movie_dims: tuple
height x width of the movie
"""
SegmentationExtractor.__init__(self)
if isinstance(image_masks, (str, Path)):
image_masks = Path(image_masks)
if image_masks.is_file():
assert image_masks.suffix == ".npy", "'image_masks' file is not a numpy file (.npy)"
self.is_dumpable = True
self._image_masks = np.load(image_masks, mmap_mode="r")
if raw is not None:
raw = Path(raw)
assert raw.suffix == ".npy", "'raw' file is not a numpy file (.npy)"
self._roi_response_raw = np.load(raw, mmap_mode="r")
if dff is not None:
dff = Path(dff)
assert dff.suffix == ".npy", "'dff' file is not a numpy file (.npy)"
self._roi_response_dff = np.load(dff, mmap_mode="r")
self._roi_response_neuropil = np.load(neuropil, mmap_mode="r")
if deconvolved is not None:
deconvolved = Path(deconvolved)
assert deconvolved.suffix == ".npy", "'deconvolved' file is not a numpy file (.npy)"
self._roi_response_deconvolved = np.load(deconvolved, mmap_mode="r")
if neuropil is not None:
neuropil = Path(neuropil)
assert neuropil.suffix == ".npy", "'neuropil' file is not a numpy file (.npy)"
self._roi_response_neuropil = np.load(neuropil, mmap_mode="r")
self._kwargs = {"image_masks": str(Path(image_masks).absolute())}
if raw is not None:
self._kwargs.update({"raw": str(Path(raw).absolute())})
if raw is not None:
self._kwargs.update({"dff": str(Path(dff).absolute())})
if raw is not None:
self._kwargs.update({"neuropil": str(Path(neuropil).absolute())})
if raw is not None:
self._kwargs.update({"deconvolved": str(Path(deconvolved).absolute())})
else:
raise ValueError("'timeeseries' is does not exist")
elif isinstance(image_masks, np.ndarray):
NoneType = type(None)
assert isinstance(raw, (np.ndarray, NoneType))
assert isinstance(dff, (np.ndarray, NoneType))
assert isinstance(neuropil, (np.ndarray, NoneType))
assert isinstance(deconvolved, (np.ndarray, NoneType))
self.is_dumpable = False
self._image_masks = image_masks
self._roi_response_raw = raw
assert self._image_masks.shape[-1] == self._roi_response_raw.shape[-1], (
"Inconsistency between image masks and raw traces. "
"Image masks must be (px, py, num_rois), "
"traces must be (num_frames, num_rois)"
)
self._roi_response_dff = dff
if self._roi_response_dff is not None:
assert self._image_masks.shape[-1] == self._roi_response_dff.shape[-1], (
"Inconsistency between image masks and raw traces. "
"Image masks must be (px, py, num_rois), "
"traces must be (num_frames, num_rois)"
)
self._roi_response_neuropil = neuropil
if self._roi_response_neuropil is not None:
assert self._image_masks.shape[-1] == self._roi_response_neuropil.shape[-1], (
"Inconsistency between image masks and raw traces. "
"Image masks must be (px, py, num_rois), "
"traces must be (num_frames, num_rois)"
)
self._roi_response_deconvolved = deconvolved
if self._roi_response_deconvolved is not None:
assert self._image_masks.shape[-1] == self._roi_response_deconvolved.shape[-1], (
"Inconsistency between image masks and raw traces. "
"Image masks must be (px, py, num_rois), "
"traces must be (num_frames, num_rois)"
)
self._kwargs = {
"image_masks": image_masks,
"signal": raw,
"dff": dff,
"neuropil": neuropil,
"deconvolved": deconvolved,
}
else:
raise TypeError("'image_masks' can be a str or a numpy array")
self._movie_dims = movie_dims if movie_dims is not None else image_masks.shape
self._image_mean = mean_image
self._image_correlation = correlation_image
if roi_ids is None:
self._roi_ids = list(np.arange(image_masks.shape[2]))
else:
assert all([isinstance(roi_id, (int, np.integer)) for roi_id in roi_ids]), "'roi_ids' must be int!"
self._roi_ids = roi_ids
self._roi_locs = roi_locations
self._sampling_frequency = sampling_frequency
self._channel_names = channel_names
self._rejected_list = rejected_list
self._accepted_list = accepted_lst

The typing here is a bit confused and going in a few different directions.

  • There are no typehints for the __init__
  • The docstrings say that the types should be np.ndarray, but if you look at the code they are all clearly meant to be strings that are filepaths.
  • This seems to be an attempt to be analogous to SpikeInterface NumpySorting and NumpyRecording, however the __init__s for both of these classes take in-memory np.ndarray objects (as the docstring types would suggest), not filepaths (as the code actually implements.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant