RegistrationInfo classes
RegistrationInfo classes are the interface to registration that are
used in SiffPy. The point of this class is that there are many registration methods
one might want to use, but most of them don’t accept a .siff file. If you convert
it to a .tiff file, you usually end up duplicating your data and you also lose the
FLIM data. So these classes are used to bridge your .siff file’s intensity data to
a format palatable for registration and then retain the way that the images were warped
so that the transformations can be applied to photons in the .siff file.
Core implementation
SiffIO frame objects perform registration during reads, meaning they accept
an argument registration_dict : Dict[int, Tuple[int,int]] to functions like
get_frames(...), where each key is the index of a frame and each value is the
pixelwise shifts in the y and x direction respectively. This means that the current
implementations only perform rigid registration – future implementations may
permit non-rigid registration, but it will be more complicated to store (especially
without duplicating the whole file the way many pipelines do). The additional latency
in rigid registration of frames as they are read is nearly-negligible, so I have not
spent time worrying about implementing duplicative-type registration methods that are
fixed. TODO: provide this option?
Any RegistrationInfo class must define the following methods:
register(self, siffio : SiffIO, *args, alignment_color_channel : int =0, **kwargs)->None:This function is usually the one called on a file opened by a _siffio<``SiffIO`>` object. It accepts whatever other arguments and keyword arguments are needed to perform the registration. It should then modify the
SiffIOobject in place to store the registration parameters, e.g. in areference_framesoryx_shiftsparameter.
Any RegistrationInfo class can, but is not required to define the following
class attributes:
multithreaading_compatible : boolmultithreaading_compatibledefines whether or not you can run theregistermethod outside of the main thread. Some packages, e.g.suite2p, do not permit this, because they use multithreading internally already and some of their tools fail in nested threads
backend : RegistrationTypeThe registration_type<``RegistrationType`>` enum defined in
registration_info.pyenumerates the list of implemented coreRegistrationInfoclasses and provides typicalstrnames for them, making it easier for automated code inspection to generate GUI tools (as insiff-napari) and providing aliases that can be stored in metadata to reconstruct the class of tool being used (as in the base class’sloadmethod).
Saving and loading
registration_info_abc<``RegistrationInfo`>` classes are designed to be saved and loaded from disk. The
RegistrationInfo base class provides a save and load_as_dict method that stores
the basic paremeters in a .h5 file (with no custom suffix, in this case). The stored
attributes are:
filenameThe filename of the source
.sifffile. This only saves the stem (e.g. a file nameda_long_custom_path/in_a_private_directory/on_a_machine_that_deanonymizes_the_user/imaging.siffwill be stored asimaging) – it’s not intended to perfectly uniquely identify a file, but provide a reminder.
registration_typeA string that can be mapped using the registration_type<``RegistrationType`>`
Enumto the class ofRegistrationInfothat was used to register the file.
registration_colorThe color channel used for registration
yx_shiftsThe framewise shifts in the y and x direction for that frame, stored as a
Groupwithh5py. TheDatasetsstored are: -frame_indexthe indices for stored frames -shift_valuestuples of (y,x) shifts -reference_framesthe reference frames used for registration, if any
Rather than a direct load class function or staticmethod, this package uses
load_as_dict to return a dict object which can be parsed (and passed through
inspection tools) to determine the class of RegistrationInfo (and reinstantiate it
if needed). This is partly to get around needing a SiffIO object if you don’t need
to work directly with a file anymore and partly to make it easy for others to use the
objects without learning to use this specific framework if they want…
- class siffpy.core.utils.registration_tools.registration_info.RegistrationType(value)
Bases:
EnumAn enumeration.
- Average = 'average'
- Caiman = 'caiman'
- Other = 'other'
- Siffpy = 'siffpy'
- Suite2p = 'suite2p'
- class siffpy.core.utils.registration_tools.registration_info.RegistrationInfo(siffio: SiffIO, im_params: ImParams)
Bases:
ABCBase class for all Registration implementations
- REGISTRATION_INFO_SUFFIX = '.h5'
- align_to_reference(images: ndarray, z_plane: int) Tuple[int, int]
- assign_siffio(siffio: SiffIO)
Required to call if you load a RegistrationInfo from a file and want to use new frames.
- backend: RegistrationType = 'siffpy'
- from_dict(dict: Dict)
- classmethod load_as_dict(path: str | Path) dict
Returns a dict that can be used to instantiate a RegistrationInfo subclass
- multithreading_compatible: bool = True
- abstract register(siffio: SiffIO, *args, alignment_color_channel: int = 0, **kwargs)
Register a virtual subclass of an ABC.
Returns the subclass, to allow usage as a class decorator.
- property registration_type: RegistrationType
- save(save_path: str | Path | None = None)
- class siffpy.core.utils.registration_tools.suite2p.Suite2pRegistrationInfo(siffio: SiffIO, im_params: ImParams)
Bases:
RegistrationInfo- align_to_reference(image: ndarray, z_plane: int) Tuple[int, int]
- backend: RegistrationType = 'suite2p'
- multithreading_compatible: bool = False
- register(siffio: SiffIO, *args, alignment_color_channel: int = 0, **kwargs)
Registers individual planes using suite2p’s registration method.
If a kwarg called ops is provided, that’s passed to suite2p’s registration_wrapper function. Otherwise, the default_ops are used.
- registration_params: Dict[str, Parameter] = {'align_by_chan2': <Parameter "align_by_chan2: bool = False">, 'batch_size': <Parameter "batch_size: int = 500">, 'do_bidiphase': <Parameter "do_bidiphase: bool = True">, 'maxregshift': <Parameter "maxregshift: float = 0.1">, 'nimg_init': <Parameter "nimg_init: int = 300">, 'nonrigid': <Parameter "nonrigid: bool = False">, 'norm_frames': <Parameter "norm_frames: bool = True">, 'smooth_sigma': <Parameter "smooth_sigma: float = 2.0">, 'smooth_sigma_time': <Parameter "smooth_sigma_time: int = 0">, 'two_step_registration': <Parameter "two_step_registration: bool = False">}
- class siffpy.core.utils.registration_tools.siffpy.SiffpyRegistrationInfo(siffio: SiffIO, im_params: ImParams)
Bases:
RegistrationInfoA lightweight and simple version of suite2p’s registration method. Benefits from being able to use the SiffIO object, rather than needing all of the frames provided as a numpy array up front. For very large arrays, this is very helpful. For small ones, you’re likely better off using suite2p’s registration method.
- align_reference_frames()
- align_to_reference(image: ndarray, z_plane: int, *args, **kwargs) Tuple[int, int]
- backend: RegistrationType = 'siffpy'
- multithreading_compatible: bool = True
- register(siffio, *args, alignment_color_channel: int = 0, num_cycles: int = 2, align_z: bool = False, **kwargs)
Registers using the siffpy registration method, which is fairly similar to suite2p’s registration method. Overview of the algorithm:
Sample a subset of frames, take their average
Take another subset of frames, find those most
correlated to the average, and take their average to use as a reference. - Align all frames to these references by finding the location of the maximum of the ratio of their FFT to the reference image’s FFT.
Each successive cycle takes the preceding one’s final alignment shifts as the starting point for creating a new reference image (from which the next batch of most-correlated frames is produced).
Keyword args are passed to siffpy.core.utils.registration_tools.siffpy.registration_method.register_frames.
Parameters
num_cycles : int
The number of cycles to run registration. This is how many times to run all of the steps enumerated above.
Calling with SiffReader
You can call the register method of a SiffReader object to
perform registration:
from siffpy import SiffReader
from siffpy.core.utils.registration_tools import RegistrationType
reader = SiffReader("path/to/file.siff")
reader.register(
registration_method = 'suite2p',
alignment_color_channel = 0,
batch_size = 200,
do_bidiphase = True,
smooth_sigma_time = 5,
norm_frames = False
)
The convention and syntax for calling register is:
- class siffpy.core.siffreader.SiffReader(filename: str | Path | None = None, open: bool = True)
Centralized Pythonic interface to the SiffReader module implemented in C.
Designed to streamline several types of operations one might perform with a single file, so it operates by opening a file and then taking arguments that relate to that specific file, e.g. frame numbers or slice numbers, as opposed to accepting numpy arrays of frames.
- register(registration_method='siffpy', save_path: str | Path | None = None, alignment_color_channel: int = 0, **kwargs) Dict
Performs image registration dependent on the registration method called
Arguments
- registration_method (optional)string
String version of the RegistrationInfo class to use. Defaults to “siffpy”.
- alignment_color_channelint
Color channel to use for alignment (0-indexed). Defaults to 0, the green channel, if present.
- save_path (optional)PathLike
Whether or not to save the dict. Name will be as TODO
Other kwargs are passed to the registration method!