Utilities

cellector.utils.broadcastable(x: ndarray, y: ndarray) bool[source]

Check if two numpy arrays are broadcastable.

Parameters:
  • x (np.ndarray) – Two numpy arrays to check for broadcast compatibility.

  • y (np.ndarray) – Two numpy arrays to check for broadcast compatibility.

Returns:

True if the arrays are broadcastable, False otherwise.

Return type:

bool

cellector.utils.deprecated(reason: str, version: str | None = None)[source]

Decorator to mark functions as deprecated.

Parameters:
  • reason (str) – Reason why the function is being deprecated and what to use instead.

  • version (str, optional) – Version the function will be removed in.

cellector.utils.transpose(sequence: Sequence) List[source]

Return a transpose of a sequence of elements in a list or tuple.

This function helps manage transposing the order of elements in a list or tuple. For example, if you have a list of lists, this will return a list of lists where the first element of each sublist in the input becomes the elements of the first sublist of the output (and second elements in each list will make up the second sublist).

Parameters:

sequence (Sequence) – A sequence of elements to transpose. Can be a list or tuple, but each should have the same number of elements.

Return type:

map of lists

Examples

To transpose a list of lists:

>>> transpose([[1, 2, 3], [4, 5, 6]])
[[1, 4], [2, 5], [3, 6]]

If you perform a function that outputs tuples in a list comprehension, but want to organize the results by the elements of the tuple rather than the iterable on the list comprehension:

>>> def func(x):
...     return x, x ** 2
>>> results = [func(i) for i in range(3)]
[(0, 0), (1, 1), (2, 4)]
>>> transpose(results)
[(0, 1, 2), (0, 1, 4)]
cellector.utils.cat_planes(list_of_sequences: List[Sequence | ndarray]) List[Sequence | ndarray][source]

Concatenate a sequence of sequences into a single sequence.

Parameters:

list_of_sequences (List[Union[Sequence, np.ndarray]]) – A list of sequences to concatenate.

Returns:

A single list containing all elements from the input sequences. If all the input sequences are numpy arrays, the output will be a single numpy array.

Return type:

list or numpy.ndarray

Notes

This function is used to concatenate list of ROI data from across planes because we can optimize operations by performing them on all ROIs at once rather than performing them on each plane separately. To return to lists of each plane independently, use the split_planes function. Note that cat_planes and split_planes are not inverse operations unless the ROIs start in order of planes.

cellector.utils.split_planes(array: ndarray, plane_idx: ndarray) List[ndarray][source]

Split a numpy array into a list of numpy arrays based on the plane index.

Parameters:
  • array (np.ndarray) – A single numpy array to split into multiple numpy arrays.

  • plane_idx (np.ndarray) – An array of integers indicating the plane index for each element in the sequence.

Returns:

A list of numpy arrays, each containing the elements for a single plane.

Return type:

list

Notes

This function is used to split concatenated ROI data back into separate lists for each plane after operations have been performed on all ROIs at once using the cat_planes function. It is not the inverse of cat_planes, because ROIs need not be contiguous but cat_planes will just concatenate them!

cellector.utils.flatten_roi_data(lam: List[ndarray], ypix: List[ndarray], xpix: List[ndarray], zpix: List[ndarray] | None = None) Dict[str, ndarray][source]

Get flattened ROI data for use in parallel processing.

Returns flattened arrays for intensity values, y-coordinates, x-coordinates in which the data is concatenated across ROIs such that each is a single numpy array. The ROI index is also returned as a single numpy array with the same length as the other arrays to indicate which ROI each value belongs to.

Parameters:
  • lam (list of np.ndarrays) – Intensity values for each pixel in each ROI.

  • zpix (list of Union[np.ndarrays, np.ndarray]) – Z-coordinates for each ROI. If 2D data, this should be a single np.ndarray of the z-plane. If volumetric data, this should be a list of np.ndarrays, one for each ROI.

  • ypix (list of np.ndarrays) – Y-coordinates of pixels in each ROI.

  • xpix (list of np.ndarrays) – X-coordinates of pixels in each ROI.

Returns:

A dictionary containing the flattened arrays for intensity values, z-coordinates, y-coordinates, x-coordinates, and ROI index associated with each lam/z/y/x value. If zpix is not provided, then it will not be included in the output dictionary.

Return type:

dict

cellector.utils.get_roi_centroid(lam: ndarray, zpix: ndarray | int, ypix: ndarray, xpix: ndarray, method: str = 'weightedmean', asint: bool = True) Tuple[int, int][source]

Calculate the centroid coordinates of an ROI.

Parameters:
  • lam (np.ndarray) – Intensity values for each pixel in the ROI.

  • zpix (Union[np.ndarray, int]) – Z-coordinates of pixels in the ROI for volumetric data, or just the z-plane for 2D data.

  • ypix (np.ndarray) – Y-coordinates of pixels in the ROI.

  • xpix (np.ndarray) – X-coordinates of pixels in the ROI.

  • method ({'weightedmean', 'median'}, optional) – Method to calculate the centroid: - ‘weightedmean’: weighted average using pixel intensities (default) - ‘median’: median position of pixels (independent for y & x pixels)

  • asint (bool, optional) – Whether to return the centroid as an integer (default). If set to False, will return a float when method=”weightedmean”.

Returns:

zc, yc, xc – Z, Y, and X coordinates of the centroid. Returns as integers by default, but will return floats if asint=False and method=”weightedmean”.

Return type:

tuple of int or float

cellector.utils.get_roi_centroids(lam: List[ndarray], zpix: ndarray | List[ndarray], ypix: List[ndarray], xpix: List[ndarray], method: str = 'weightedmean', asint: bool = True) Tuple[ndarray, ndarray][source]

Get the centroid of each ROI in a list of ROIs.

Parameters:
  • lam (list of np.ndarrays) – Intensity values for each pixel in each ROI.

  • zpix (Union[np.ndarray, List[np.ndarray]]) – Z-coordinates of each ROI – if volumetric data this is a list of np.ndarrays for each ROI, if not volumetric this is a single np.ndarray of the z-plane for each ROI.

  • ypix (list of np.ndarrays) – Y-coordinates of pixels in each ROI.

  • xpix (list of np.ndarrays) – X-coordinates of pixels in each ROI.

  • method ({'weightedmean', 'median'}, optional) – Method to calculate the centroid: - ‘weightedmean’: weighted average using pixel intensities (default) - ‘median’: median position of pixels (independent for y & x pixels)

  • asint (bool, optional) – Whether to return the centroid as an integer (default). If set to False, will return a float when method=”weightedmean”.

Returns:

zc, yc, xc – Z, Y, and X coordinates of each ROI centroid. Returns as integers by default, but will return floats if asint=False and method=”weightedmean”.

Return type:

tuple of np.ndarrays of int or float

See also

get_roi_centroid

The underlying function for centroid calculation.

cellector.utils.get_mask_volume(flattened_roi_data: Dict[str, ndarray], num_rois: int, shape: Tuple[int, int], volumetric: bool = False) ndarray[source]

Create a mask stack using Numba for parallel processing.

For optimization with numba, the input is flattened arrays of pixel coordinates and intensities concatenated across ROIs, with the ROI index indicated by roi_idx. The volume is created by assigning the intensity values to the appropriate pixel coordinates in the mask stack with zeros everywhere else. Each slice of the mask stack corresponds to a single ROI.

Parameters:
  • flattened_roi_data (Dict[str, np.ndarray]) –

    lam_flatnp.ndarray

    Intensity values for each pixel in each ROI. In format (num_pixels,) with values from each ROI concatenated with each other.

    zpixnp.ndarray

    Z-coordinates of pixels in each ROI. Same format as lam.

    ypix_flatnp.ndarray

    Y-coordinates of pixels in each ROI. Same format as lam.

    xpix_flatnp.ndarray

    X-coordinates of pixels in each ROI. Same format as lam.

    roi_idxnp.ndarray

    ROI index for each value in lam, ypix, xpix

  • num_rois (int) – Number of ROIs described in the input arrays.

  • shape (tuple of int) – Shape of the mask stack to create (height and width).

  • volumetric (bool, optional) – Whether the data is volumetric. If True, will include all planes. Default is False.

Returns:

A stack of masks images for each ROI. If volumetric=False, has shape (num_rois, height, width). If volumetric=True, has shape (num_rois, num_planes, height, width).

Return type:

np.ndarray

cellector.utils.get_centered_masks(flattened_roi_data: Dict[str, ndarray], centroids: Dict[str, ndarray], width: int | None = 15, fill_value: float | None = 0.0, num_planes: int | None = None, volumetric: bool = False) ndarray[source]

Create a stack of centered masks for each ROI.

For optimization with numba, the input is flattened arrays of pixel coordinates and intensities concatenated across ROIs, with the ROI index indicated by roi_idx. The centroids are provided as a tuple of y and x coordinates for each ROI. The mask stack is created by centering each mask around the centroid of the ROI, with a width of width pixels on each side. Any pixels outside the mask footprint are filled with the value specified by fill_value.

Parameters:
  • flattened_roi_data (Dict[str, np.ndarray]) –

    lamnp.ndarray

    Intensity values for each pixel in each ROI. In format (num_pixels,) with values from each ROI concatenated with each other.

    zpixnp.ndarray

    Z-coordinates of pixels in each ROI. Same format as lam.

    ypixnp.ndarray

    Y-coordinates of pixels in each ROI. Same format as lam.

    xpixnp.ndarray

    X-coordinates of pixels in each ROI. Same format as lam.

    roi_idxnp.ndarray

    ROI index for each value in lam, ypix, xpix, zpix

  • centroids (Dict[str, np.ndarray]) – Dictionary of z, y, and x centroids for each ROI.

  • width (int, optional) – Width in pixels around the ROI centroid. Default is 15.

  • fill_value (float, optional) – Value to use as the background. Default is 0.0.

  • num_planes (int, optional) – Number of planes in the data. Required if volumetric is True.

  • volumetric (bool, optional) – Whether the data is volumetric. If True, will include all planes. Default is False.

Returns:

A stack of centered masks for each ROI. If volumetric=False, has shape (num_rois, 2 * width + 1, 2 * width + 1). If volumetric=True, has shape (num_rois, num_planes, 2 * width + 1, 2 * width + 1).

Return type:

np.ndarray

cellector.utils.get_centered_reference(reference: ndarray, centroids: Dict[str, ndarray], width: int | None = 15, fill_value: float | None = 0.0, volumetric: bool = False) ndarray[source]

Create a stack of centered reference images on each ROI.

Parameters:
  • reference (np.ndarray) – Reference images for each plane (stack of 2D images).

  • centroids (Dict[str, np.ndarray]) – Dictionary of z, y, and x centroids for each ROI.

  • width (int, optional) – Width in pixels around the ROI centroid. Default is 15.

  • fill_value (float, optional) – Value to use as the background. Default is 0.0.

  • volumetric (bool, optional) – Whether the data is volumetric. If True, will include all planes. Default is False.

Returns:

A 3D stack of centered reference images for each ROI. If volumetric=False, has shape (num_rois, 2 * width + 1, 2 * width + 1). If volumetric=True, has shape (num_rois, num_planes, 2 * width + 1, 2 * width + 1).

Return type:

np.ndarray

cellector.utils.center_surround(centered_masks: ndarray, iterations: int | None = 7, volumetric: bool = False) Tuple[ndarray, ndarray][source]

Calculate the center and surround footprints of a stack of centered masks.

The center footprint is the binary mask of the ROI itself, while the surround footprint is a binary mask of the surrounding region of the ROI. The surround region is defined as the dilation of the center region by a 3x3 cross structuring element for 7 iterations.

Parameters:
  • centered_masks (np.ndarray) – The centered mask images for each ROI. Should have shape (num_rois, height, width). If volumetric=True, should have shape (num_rois, num_planes, height, width).

  • iterations (int, optional) – The number of iterations for the binary dilation. Default is 7.

  • volumetric (bool, optional) – Whether the data is volumetric. If True, will include the z-axis in the computation. Default is False.

Returns:

center, surround – The center and surround binary masks for each ROI.

Return type:

Tuple[np.ndarray, np.ndarray]

cellector.utils.surround_filter(centered_masks: ndarray, centered_references: ndarray, iterations: int | None = 7, volumetric: bool = False) Tuple[ndarray, ndarray][source]

Filter centered masks and references to include only the surround region of each mask.

Uses the center_surround function to calculate the center and surround footprints, which is based on a binary dilation of the mask footprint. The surround region is then used to filter the centered masks and references, filling anything outside the surround region with np.nan.

Parameters:
  • centered_masks (np.ndarray) – The centered mask images for each ROI. Should have shape (num_rois, height, width).

  • centered_references (np.ndarray) – The centered reference images around each ROI. Should have shape (num_rois, height, width).

  • iterations (int, optional) – The number of iterations for the binary dilation. Default is 7.

  • volumetric (bool, optional) – Whether the data is volumetric. If True, will include the z-axis in the computation. Default is False.

Returns:

masks_surround, references_surround – The centered mask and reference images for the surround region of each ROI. Anything outside the surround region will be filled with np.nan.

Return type:

Tuple[np.ndarray, np.ndarray]

cellector.utils.cross_power_spectrum(static_image: ndarray, moving_image: ndarray, eps: float = 1000000.0, volumetric: bool = False) ndarray[source]

Measure the cross-power spectrum between two images.

Computes the cross-power spectrum in the fourier domain with the following formula:

\[R = F(static\_image) * conj(F(moving\_image))\]

where F is the fourier transform and conj is the complex conjugate.

Parameters:
  • static_image (np.ndarray with shape (..., M, N)) – The static image.

  • moving_image (np.ndarray with shape (..., M, N)) – The moving image. This image is shifted and the resulting phase correlation is measured.

  • eps (float, optional) – Small value to avoid division by zero. Default is 1e-8.

  • volumetric (bool, optional) – Whether to compute the cross-power spectrum for volumetric data. If so, will include the z-axis in the computation. Default is False.

Returns:

The cross-power spectrum, with the same shape as the input images.

Return type:

np.ndarray

cellector.utils.phase_correlation(static_image: ndarray, moving_image: ndarray, eps: float = 1e-08) ndarray[source]

Measure the phase correlation between two images.

Computes the phase correlation in the fourier domain with the following formula:

\[R = F^{-1}(F(static\_image) * conj(F(moving\_image)))\]

where F is the fourier transform and conj is the complex conjugate.

Returns the real part, which describes the phase correlation of the two images after shifting the moving image.

Note: broadcasting between the two images is accepted as long as the last two dimensions have equal shapes, which represent the “image” dimensions.

Parameters:
  • static_image (np.ndarray with shape (..., M, N)) – The static image.

  • moving_image (np.ndarray with shape (..., M, N)) – The moving image. This image is shifted and the resulting phase correlation is measured.

  • eps (float, optional) – Small value to avoid division by zero. Default is 1e-8.

Returns:

The phase correlation map, representing the correlation for every shift of moving_image relative to static_image. The shape will be equal to the (broadcasted) shape of the input images.

Return type:

np.ndarray

cellector.utils.phase_correlation_zero(centered_masks: ndarray, centered_reference: ndarray, eps: float = 1000000.0, volumetric: bool = False) ndarray[source]

Measure the zero-offset phase correlation between two images.

Computes the phase correlation in the fourier domain with the following formula:

\[R = F^{-1}(F(static\_image) * conj(F(moving\_image)))\]

where F is the fourier transform and conj is the complex conjugate. Returns the zero-offset real component, which describes the phase correlation of the two images without any shift.

Note: broadcasting between the two images is accepted as long as the last two dimensions have equal shapes, which represent the “image” dimensions.

Parameters:
  • centered_masks (np.ndarray with shape (..., M, N)) – The centered mask images for each ROI.

  • centered_reference (np.ndarray with shape (..., M, N)) – The centered reference image (centered on each ROI).

  • eps (float, optional) – Offset value to avoid division by zero. Default is 1e6.

  • volumetric (bool, optional) – Whether to compute the phase correlation for volumetric data. If so, will include the z-axis in the computation. Default is False.

Returns:

The central pixel value of the phase correlation, representing the correlation between the masks and the reference images without any shift. Shape will be (…) for input images of shape (…, M, N).

Return type:

float or np.ndarray

See also

phase_correlation

Full version that returns the entire correlation map.

cellector.utils.in_vs_out(centered_masks: ndarray, centered_reference: ndarray, iterations: int = 7, volumetric: bool = False) ndarray[source]

Measure the ratio of the intensity inside the mask to the local intensity surrounding the mask.

The intensity inside the mask is the sum of the reference image inside the mask, and the intensity surrounding the mask is the sum of the reference image inside and outside the mask. The ratio of these two values is a measure of how much the mask is pointing toward intensity features in the reference image.

Note: this is the closest feature to the native suite2p red cell probability feature. So, in the case where the suite2p red cell probability isn’t available, this is a good alternative (and it might be useful on it’s own). The suite2p method uses a similar concept but the surround region is based on the neuropil model rather than a footprint as in this function.

Parameters:
  • centered_masks (np.ndarray with shape (..., (Z), M, N)) – The centered mask images for each ROI.

  • centered_reference (np.ndarray with shape (..., (Z), M, N)) – The centered reference image (centered on each ROI).

  • iterations (int, optional) – The number of iterations to dilate the mask for the surround. Default is 7.

  • volumetric (bool, optional) – Whether to compute the in vs. out feature for volumetric data. If so, will include the z-axis in the computation. Default is False.

Returns:

The ratio of the intensity inside the mask to the intensity inside plus outside the mask. Shape will be (N,), where N is the number of ROIs. If the total sum of the inside and outside intensities is 0, then the value will return as 0.

Return type:

np.ndarray

cellector.utils.dot_product(lam: List[ndarray], ypix: List[ndarray], xpix: List[ndarray], zpix: ndarray | List[ndarray], reference: ndarray, volumetric: bool = False) ndarray[source]

Measure the normalized dot product between the masks and the reference images.

Will take the inner product of the mask weights with the reference image, and divide by the norm of the mask weights. This is a measure of how well the mask points toward intensity features in the reference image.

Uses lam, xpix, ypix (and zpix if volumetric=True) instead of mask images for efficiency.

Parameters:
  • lam (List[np.ndarray]) – List of mask weights for each ROI.

  • ypix (List[np.ndarray]) – List of y-pixel indices for each ROI.

  • xpix (List[np.ndarray]) – List of x-pixel indices for each ROI.

  • zpix (Union[np.ndarray, List[np.ndarray]]) – List of plane indices for each ROI, unless volumetric=True, in which case it is a list of z-plane indices for each ROI.

  • reference (np.ndarray) – The reference images.

  • volumetric (bool, optional) – Whether to compute the dot product for volumetric data. If so, will include the z-axis in the computation. Default is False.

Returns:

The dot product between the masks and the reference images. Shape will be (N,), where N is the number of ROIs.

Return type:

np.ndarray

cellector.utils.compute_correlation(centered_masks: ndarray, centered_references: ndarray, volumetric: bool = False) ndarray[source]

Measure the correlation coefficient between the masks and the reference images.

The masks and reference images should have the same shape and be centered on each other. It is expected (but not required) that the masks and references are filtered to have np.nan outside the surround of each ROI to focus the correlation on the local structure near the ROI rather than the full square provided by the centering stacks. Since the surround is larger than the ROI by definition, this is effectively comparing the local data in the ROI with the zeros outside the ROI.

Parameters:
  • centered_masks (np.ndarray with shape (..., (Z), M, N)) – The centered mask images for each ROI.

  • centered_reference (np.ndarray with shape (..., (Z), M, N)) – The centered reference image (centered on each ROI).

  • volumetric (bool, optional) – Whether the data is volumetric. If True, will include the z-axis in the computation. Default is False.

Returns:

The correlation coefficient between the masks and the reference images. Shape will be (N,), where N is the number of ROIs.

Return type:

np.ndarray

See also

surround_filter

Function to filter the masks and references to have np.nan outside the ROI.