Skip to content

nd2

get_image(images, fov, channel, use_z=None)

Using dask array from nd2 file, this loads the image of the desired fov and channel.

Parameters:

Name Type Description Default
images np.ndarray

Dask array with fov, channel, y, x, z as index order.

required
fov int

fov index of desired image

required
channel int

channel of desired image

required
use_z Optional[List[int]]

int [n_use_z]. Which z-planes of image to load. If None, will load all z-planes.

None

Returns:

Type Description
np.ndarray

uint16 [im_sz_y x im_sz_x x n_use_z]. Image of the desired fov and channel.

Source code in coppafish/utils/nd2.py
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
def get_image(images: np.ndarray, fov: int, channel: int, use_z: Optional[List[int]] = None) -> np.ndarray:
    """
    Using dask array from nd2 file, this loads the image of the desired fov and channel.

    Args:
        images: Dask array with `fov`, `channel`, y, x, z as index order.
        fov: `fov` index of desired image
        channel: `channel` of desired image
        use_z: `int [n_use_z]`.
            Which z-planes of image to load.
            If `None`, will load all z-planes.

    Returns:
        `uint16 [im_sz_y x im_sz_x x n_use_z]`.
            Image of the desired `fov` and `channel`.
    """
    if use_z is None:
        use_z = np.arange(images.shape[-1])
    return np.asarray(images[fov, channel, :, :, use_z])

get_metadata(file_path)

Gets metadata containing information from nd2 data about pixel sizes, position of tiles and numbers of tiles/channels/z-planes.

Parameters:

Name Type Description Default
file_path str

Path to desired nd2 file.

required

Returns:

Type Description
dict

Dictionary containing -

dict
  • xy_pos - List [n_tiles x 2]. xy position of tiles in pixels.
dict
  • pixel_microns - float. xy pixel size in microns.
dict
  • pixel_microns_z - float. z pixel size in microns.
dict
  • sizes - dict with fov (t), channels (c), y, x, z-planes (z) dimensions.
Source code in coppafish/utils/nd2.py
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
def get_metadata(file_path: str) -> dict:
    """
    Gets metadata containing information from nd2 data about pixel sizes, position of tiles and numbers of
    tiles/channels/z-planes.

    Args:
        file_path: Path to desired nd2 file.

    Returns:
        Dictionary containing -

        - `xy_pos` - `List [n_tiles x 2]`. xy position of tiles in pixels.
        - `pixel_microns` - `float`. xy pixel size in microns.
        - `pixel_microns_z` - `float`. z pixel size in microns.
        - `sizes` - dict with fov (`t`), channels (`c`), y, x, z-planes (`z`) dimensions.
    """
    if not os.path.isfile(file_path):
        raise errors.NoFileError(file_path)
    images = nd2.ND2File(file_path)
    metadata = {'sizes': {'t': images.sizes['P'], 'c': images.sizes['C'], 'y': images.sizes['Y'],
                          'x': images.sizes['X'], 'z': images.sizes['Z']},
                'pixel_microns': images.metadata.channels[0].volume.axesCalibration[0],
                'pixel_microns_z': images.metadata.channels[0].volume.axesCalibration[2]}
    xy_pos = np.array([images.experiment[0].parameters.points[i].stagePositionUm[:2]
                       for i in range(images.sizes['P'])])
    metadata['xy_pos'] = (xy_pos - np.min(xy_pos, 0)) / metadata['pixel_microns']
    metadata['xy_pos'] = metadata['xy_pos'].tolist()
    return metadata

get_nd2_tile_ind(tile_ind_npy, tile_pos_yx_nd2, tile_pos_yx_npy)

Gets index of tiles in nd2 file from tile index of npy file.

Parameters:

Name Type Description Default
tile_ind_npy Union[int, List[int]]

Indices of tiles in npy file

required
tile_pos_yx_nd2 np.ndarray

int [n_tiles x 2]. [i,:] contains YX position of tile with nd2 index i. Index 0 refers to YX = [0, 0]. Index 1 refers to YX = [0, 1] if MaxX > 0.

required
tile_pos_yx_npy np.ndarray

int [n_tiles x 2]. [i,:] contains YX position of tile with npy index i. Index 0 refers to YX = [MaxY, MaxX]. Index 1 refers to YX = [MaxY, MaxX - 1] if MaxX > 0.

required

Returns:

Type Description
Union[int, List[int]]

Corresponding indices in nd2 file

Source code in coppafish/utils/nd2.py
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
def get_nd2_tile_ind(tile_ind_npy: Union[int, List[int]], tile_pos_yx_nd2: np.ndarray,
                     tile_pos_yx_npy: np.ndarray) -> Union[int, List[int]]:
    """
    Gets index of tiles in nd2 file from tile index of npy file.

    Args:
        tile_ind_npy: Indices of tiles in npy file
        tile_pos_yx_nd2: ```int [n_tiles x 2]```.
            ```[i,:]``` contains YX position of tile with nd2 index ```i```.
            Index 0 refers to ```YX = [0, 0]```.
            Index 1 refers to ```YX = [0, 1] if MaxX > 0```.
        tile_pos_yx_npy: ```int [n_tiles x 2]```.
            ```[i,:]``` contains YX position of tile with npy index ```i```.
            Index 0 refers to ```YX = [MaxY, MaxX]```.
            Index 1 refers to ```YX = [MaxY, MaxX - 1] if MaxX > 0```.

    Returns:
        Corresponding indices in nd2 file
    """
    if isinstance(tile_ind_npy, numbers.Number):
        tile_ind_npy = [tile_ind_npy]
    nd2_index = numpy_indexed.indices(tile_pos_yx_nd2, tile_pos_yx_npy[tile_ind_npy]).tolist()
    if len(nd2_index) == 1:
        return nd2_index[0]
    else:
        return nd2_index

load(file_path)

Returns dask array with indices in order fov, channel, y, x, z.

Parameters:

Name Type Description Default
file_path str

Path to desired nd2 file.

required

Returns:

Type Description
np.ndarray

Dask array indices in order fov, channel, y, x, z.

Source code in coppafish/utils/nd2.py
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def load(file_path: str) -> np.ndarray:
    """
    Returns dask array with indices in order `fov`, `channel`, `y`, `x`, `z`.

    Args:
        file_path: Path to desired nd2 file.

    Returns:
        Dask array indices in order `fov`, `channel`, `y`, `x`, `z`.
    """
    if not os.path.isfile(file_path):
        raise errors.NoFileError(file_path)
    images = nd2.ND2File(file_path)
    images = images.to_dask()
    # images = nd2.imread(file_name, dask=True)  # get python crashing with this in get_image for some reason
    images = np.moveaxis(images, 1, -1)  # put z index to end
    return images

save_metadata(json_file, nd2_file, use_channels=None)

Saves the required metadata as a json file which will contain

  • xy_pos - List [n_tiles x 2]. xy position of tiles in pixels.
  • pixel_microns - float. xy pixel size in microns.
  • pixel_microns_z - float. z pixel size in microns.
  • sizes - dict with fov (t), channels (c), y, x, z-planes (z) dimensions.

Parameters:

Name Type Description Default
json_file str

Where to save json file

required
nd2_file str

Path to nd2 file

required
use_channels Optional[List]

The channels which have been extracted from the nd2 file. If None, assume all channels in nd2 file used

None
Source code in coppafish/utils/nd2.py
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
def save_metadata(json_file: str, nd2_file: str, use_channels: Optional[List] = None):
    """
    Saves the required metadata as a json file which will contain

    - `xy_pos` - `List [n_tiles x 2]`. xy position of tiles in pixels.
    - `pixel_microns` - `float`. xy pixel size in microns.
    - `pixel_microns_z` - `float`. z pixel size in microns.
    - `sizes` - dict with fov (`t`), channels (`c`), y, x, z-planes (`z`) dimensions.

    Args:
        json_file: Where to save json file
        nd2_file: Path to nd2 file
        use_channels: The channels which have been extracted from the nd2 file.
            If `None`, assume all channels in nd2 file used

    """
    metadata = get_metadata(nd2_file)
    if use_channels is not None:
        if len(use_channels) > metadata['sizes']['c']:
            raise ValueError(f"use_channels contains {len(use_channels)} channels but there "
                             f"are only {metadata['sizes']['c']} channels in the nd2 metadata.")
        metadata['sizes']['c'] = len(use_channels)
        metadata['use_channels'] = use_channels   # channels extracted from nd2 file
    json.dump(metadata, open(json_file, 'w'))