Skip to content
Snippets Groups Projects
Select Git revision
  • 58fc8405f9d633998164464eeb7c955f0aebf229
  • main default protected
  • interactive-widget
  • v0.2.5
  • v0.2.4
  • v0.2.3
  • v0.2.2
  • v0.2.1
  • v0.2.0
  • v0.1.4
  • v0.1.3
  • v0.1.2
  • v0.1.1
  • v0.1
14 results

_reader.py

Blame
  • _reader.py 4.52 KiB
    """
    This module is an example of a barebones numpy reader plugin for napari.
    
    It implements the Reader specification, but your plugin may choose to
    implement multiple readers or even other plugin contributions. see:
    https://napari.org/plugins/stable/guides.html#readers
    """
    import json
    import os
    
    import dask
    import nd2
    import numpy as np
    
    
    def napari_get_reader(path):
        """A basic implementation of a Reader contribution.
    
        Parameters
        ----------
        path : str or list of str
            Path to file, or list of paths.
    
        Returns
        -------
        function or None
            If the path is a recognized format, return a function that accepts the
            same path or list of paths, and returns a list of layer data tuples.
        """
        if isinstance(path, list):
            # reader plugins may be handed single path, or a list of paths.
            # if it is a list, it is assumed to be an image stack...
            # so we are only going to look at the first file.
            path = path[0]
    
        # if we know we cannot read the file, we immediately return None.
        if path.endswith(".nd2"):
            return read_nd2
    
        if path.endswith(".zarr"):
            return read_zarr
    
        # otherwise we return the *function* that can read ``path``.
        return reader_function
    
    
    def read_zarr(path):
        print(f"reading {path}")
        try:
            attrs = json.load(open(os.path.join(path, ".zattrs")))
            info = attrs["multiscales"]["multiscales"][0]
            channel_axis = info["channel_axis"]
            print(f"found channel axis {channel_axis}")
            dataset_paths = [
                os.path.join(path, d["path"]) for d in info["datasets"]
            ]
            datasets = [dask.array.from_zarr(p) for p in dataset_paths]
        except Exception as e:
            raise e
    
        try:
            contrast_limits = info["lut"]
        except KeyError:
            contrast_limits = None
    
        try:
            colormap = info["colormap"]
        except KeyError:
            colormap = None
    
        try:
            name = info["name"]
        except KeyError:
            print("name not found")
            name = [os.path.basename(path)] * datasets[0].shape[channel_axis]
        except Exception as e:
            print("name exception", e.args)
            name = os.path.basename(path)
    
        return [
            (
                datasets,
                {
                    "channel_axis": channel_axis,
                    "colormap": colormap,
                    "contrast_limits": contrast_limits,
                    "name": name,
                },
                "image",
            )
        ]
    
    
    def read_nd2(path):
        print(f"opening {path}")
        data = nd2.ND2File(path)
        print(data.sizes)
        ddata = data.to_dask()
        # colormap = ["gray", "green"]
        try:
            channel_axis = list(data.sizes.keys()).index("C")
        except ValueError:
            print(f"No channels, {data.sizes}")
            channel_axis = None
            # colormap = ["gray"]
        return [
            (
                ddata,
                {"channel_axis": channel_axis},
                # dict(
                #     channel_axis=channel_axis,
                #     name=[ch.channel.name for ch in data.metadata.channels],
                # colormap=colormap,
                # scale=data.metadata.channels[0].volume.axesCalibration[:]
                # contrast_limits=[(8500, 35000), (150, 20000)],
                # ),
                "image",
            )
        ]
    
    
    def reader_function(path):
        """Take a path or list of paths and return a list of LayerData tuples.
    
        Readers are expected to return data as a list of tuples, where each tuple
        is (data, [add_kwargs, [layer_type]]), "add_kwargs" and "layer_type" are
        both optional.
    
        Parameters
        ----------
        path : str or list of str
            Path to file, or list of paths.
    
        Returns
        -------
        layer_data : list of tuples
            A list of LayerData tuples where each tuple in the list contains
            (data, metadata, layer_type), where data is a numpy array, metadata is
            a dict of keyword arguments for the corresponding viewer.add_* method
            in napari, and layer_type is a lower-case string naming the type of
            layer.
            Both "meta", and "layer_type" are optional. napari will default to
            layer_type=="image" if not provided
        """
        # handle both a string and a list of strings
        paths = [path] if isinstance(path, str) else path
        # load all files into array
        arrays = [np.load(_path) for _path in paths]
        # stack arrays into single array
        data = np.squeeze(np.stack(arrays))
    
        # optional kwargs for the corresponding viewer.add_* method
        add_kwargs = {}
    
        layer_type = "image"  # optional, default is "image"
        return [(data, add_kwargs, layer_type)]