nd2¶
nd2: A Python library for reading and writing ND2 files.
ND2File
¶
Main objecting for opening and extracting data from an nd2 file.
with nd2.ND2File("path/to/file.nd2") as nd2_file:
...
The key metadata outputs are:
Some files may also have:
Tip
For a simple way to read nd2 file data into an array, see nd2.imread.
Parameters:
-
path
(Path | str
) –Filename of an nd2 file.
-
validate_frames
(bool
, default:False
) –Whether to verify (and attempt to fix) frames whose positions have been shifted relative to the predicted offset (i.e. in a corrupted file). This comes at a slight performance penalty at file open, but may "rescue" some corrupt files. by default False.
-
search_window
(int
, default:100
) –When validate_frames is true, this is the search window (in KB) that will be used to try to find the actual chunk position. by default 100 KB
attributes: Attributes
cached
property
¶
Core image attributes.
Example Output
Attributes(
bitsPerComponentInMemory=16,
bitsPerComponentSignificant=16,
componentCount=2,
heightPx=32,
pixelDataType="unsigned",
sequenceCount=60,
widthBytes=128,
widthPx=32,
compressionLevel=None,
compressionType=None,
tileHeightPx=None,
tileWidthPx=None,
channelCount=2,
)
Returns:
-
attrs
(Attributes
) –Core image attributes
binary_data: BinaryLayers | None
cached
property
¶
Return binary layers embedded in the file.
The returned BinaryLayers
object is an immutable sequence of BinaryLayer
objects, one for each binary layer in the file (there will usually be a binary
layer associated with each channel in the dataset).
Each BinaryLayer
object in the sequence has a name
attribute, and a data
attribute which is list of numpy arrays (or None
if there was no binary mask
for that frame). The length of the list will be the same as the number of
sequence frames in this file (i.e. self.attributes.sequenceCount
).
BinaryLayers
can be indexed directly with an integer corresponding to the
frame index.
Both the BinaryLayers
and individual BinaryLayer
objects can be cast to a
numpy array with np.asarray()
, or by using the .asarray()
method
Returns:
-
BinaryLayers | None
–The binary layers embedded in the file, or None if there are no binary layers.
Examples:
>>> f = ND2File("path/to/file.nd2")
>>> f.binary_data
<BinaryLayers with 4 layers>
>>> first_layer = f.binary_data[0] # the first binary layer
>>> first_layer
BinaryLayer(name='attached Widefield green (green color)',
comp_name='Widefield Green', comp_order=2, color=65280, color_mode=0,
state=524288, file_tag='RleZipBinarySequence_1_v1', layer_id=2)
>>> first_layer.data # list of arrays
# you can also index in to the BinaryLayers object itself
>>> first_layer[0] # get binary data for first frame (or None if missing)
>>> np.asarray(first_layer) # cast to array matching shape of full sequence
>>> np.asarray(f.binary_data).shape # cast all layers to array
(4, 3, 4, 5, 32, 32)
closed: bool
property
¶
Return True
if the file is closed.
components_per_channel: int
property
¶
Number of components per channel (e.g. 3 for rgb).
custom_data: dict[str, Any]
cached
property
¶
Dict of various unstructured custom metadata.
dtype: np.dtype
cached
property
¶
Image data type.
experiment: list[ExpLoop]
cached
property
¶
Loop information for each axis of an nD acquisition.
Example Output
[
TimeLoop(
count=3,
nestingLevel=0,
parameters=TimeLoopParams(
startMs=0.0,
periodMs=1.0,
durationMs=0.0,
periodDiff=PeriodDiff(
avg=3674.199951171875,
max=3701.219970703125,
min=3647.179931640625,
),
),
type="TimeLoop",
),
ZStackLoop(
count=5,
nestingLevel=1,
parameters=ZStackLoopParams(
homeIndex=2,
stepUm=1.0,
bottomToTop=True,
deviceName="Ti2 ZDrive",
),
type="ZStackLoop",
),
]
Returns:
is_legacy: bool
property
¶
Whether file is a legacy nd2 (JPEG2000) file.
is_rgb: bool
property
¶
Whether the image is rgb (i.e. it has 3 or 4 components per channel).
loop_indices: tuple[dict[str, int], ...]
cached
property
¶
Return a tuple of dicts of loop indices for each frame.
Examples:
>>> with nd2.ND2File("path/to/file.nd2") as f:
... f.loop_indices
(
{'Z': 0, 'T': 0, 'C': 0},
{'Z': 0, 'T': 0, 'C': 1},
{'Z': 0, 'T': 0, 'C': 2},
...
)
metadata: Metadata
cached
property
¶
Various metadata (will be dict
only if legacy format).
Example output
Metadata(
contents=Contents(channelCount=2, frameCount=15),
channels=[
Channel(
channel=ChannelMeta(
name="Widefield Green",
index=0,
color=Color(r=91, g=255, b=0, a=1.0),
emissionLambdaNm=535.0,
excitationLambdaNm=None,
),
loops=LoopIndices(
NETimeLoop=None, TimeLoop=0, XYPosLoop=None, ZStackLoop=1
),
microscope=Microscope(
objectiveMagnification=10.0,
objectiveName="Plan Fluor 10x Ph1 DLL",
objectiveNumericalAperture=0.3,
zoomMagnification=1.0,
immersionRefractiveIndex=1.0,
projectiveMagnification=None,
pinholeDiameterUm=None,
modalityFlags=["fluorescence"],
),
volume=Volume(
axesCalibrated=[True, True, True],
axesCalibration=[0.652452890023035, 0.652452890023035, 1.0],
axesInterpretation=["distance", "distance", "distance"],
bitsPerComponentInMemory=16,
bitsPerComponentSignificant=16,
cameraTransformationMatrix=[
-0.9998932296054086,
-0.014612644841559427,
0.014612644841559427,
-0.9998932296054086,
],
componentCount=1,
componentDataType="unsigned",
voxelCount=[32, 32, 5],
componentMaxima=[0.0],
componentMinima=[0.0],
pixelToStageTransformationMatrix=None,
),
),
Channel(
channel=ChannelMeta(
name="Widefield Red",
index=1,
color=Color(r=255, g=85, b=0, a=1.0),
emissionLambdaNm=620.0,
excitationLambdaNm=None,
),
loops=LoopIndices(
NETimeLoop=None, TimeLoop=0, XYPosLoop=None, ZStackLoop=1
),
microscope=Microscope(
objectiveMagnification=10.0,
objectiveName="Plan Fluor 10x Ph1 DLL",
objectiveNumericalAperture=0.3,
zoomMagnification=1.0,
immersionRefractiveIndex=1.0,
projectiveMagnification=None,
pinholeDiameterUm=None,
modalityFlags=["fluorescence"],
),
volume=Volume(
axesCalibrated=[True, True, True],
axesCalibration=[0.652452890023035, 0.652452890023035, 1.0],
axesInterpretation=["distance", "distance", "distance"],
bitsPerComponentInMemory=16,
bitsPerComponentSignificant=16,
cameraTransformationMatrix=[
-0.9998932296054086,
-0.014612644841559427,
0.014612644841559427,
-0.9998932296054086,
],
componentCount=1,
componentDataType="unsigned",
voxelCount=[32, 32, 5],
componentMaxima=[0.0],
componentMinima=[0.0],
pixelToStageTransformationMatrix=None,
),
),
],
)
Returns:
nbytes: int
property
¶
Total bytes of image data.
ndim: int
cached
property
¶
Number of dimensions (i.e. len(
self.shape
)
).
path: str
property
¶
Path of the image.
rois: dict[int, ROI]
cached
property
¶
shape: tuple[int, ...]
cached
property
¶
Size of each axis.
Examples:
>>> ndfile.shape
(3, 5, 2, 512, 512)
size: int
property
¶
Total number of voxels in the volume (the product of the shape).
sizes: Mapping[str, int]
cached
property
¶
Names and sizes for each axis.
This is an ordered dict, with the same order as the corresponding shape
Examples:
>>> ndfile.sizes
{'T': 3, 'Z': 5, 'C': 2, 'Y': 512, 'X': 512}
>>> ndfile.shape
(3, 5, 2, 512, 512)
text_info: TextInfo
cached
property
¶
Miscellaneous text info.
Example Output
{
'description': 'Metadata:\r\nDimensions: T(3) x XY(4) x λ(2) x Z(5)...'
'capturing': 'Flash4.0, SN:101412\r\nSample 1:\r\n Exposure: 100 ms...'
'date': '9/28/2021 9:41:27 AM',
'optics': 'Plan Fluor 10x Ph1 DLL'
}
Returns:
version: tuple[int, ...]
cached
property
¶
Return the file format version as a tuple of ints.
Likely values are:
(1, 0)
= a legacy nd2 file (JPEG2000)(2, 0)
,(2, 1)
= non-JPEG2000 nd2 with xml metadata(3, 0)
= new format nd2 file with lite variant metadata(-1, -1)
=
Returns:
Raises:
-
ValueError
–If the file is not a valid nd2 file.
asarray(position: int | None = None) -> np.ndarray
¶
Read image into a numpy.ndarray.
For a simple way to read a file into a numpy array, see nd2.imread.
Parameters:
-
position
(int
, default:None
) –A specific XY position to extract, by default (None) reads all.
Returns:
-
array
(ndarray
) –
Raises:
-
ValueError
–if
position
is a string and is not a valid position name -
IndexError
–if
position
is provided and is out of range
close() -> None
¶
Close file.
Note
Files are best opened using a context manager:
with nd2.ND2File("path/to/file.nd2") as nd2_file:
...
This will automatically close the file when the context exits.
events(*, orient: Literal['records', 'list', 'dict'] = 'records', null_value: Any = float('nan')) -> ListOfDicts | DictOfLists | DictOfDicts
¶
Return tabular data recorded for each frame and/or event of the experiment.
This method returns tabular data in the format specified by the orient
argument:
- 'records' : list of dict - [{column -> value}, ...]
(default)
- 'dict' : dict of dict - {column -> {index -> value}, ...}
- 'list' : dict of list - {column -> [value, ...]}
All return types are passable to pd.DataFrame(). It matches the tabular data reported in the Image Properties > Recorded Data tab of the NIS Viewer.
There will be a column for each tag in the CustomDataV2_0
section of
ND2File.custom_data
, as well columns for any events recorded in the
data. Not all cells will be populated, and empty cells will be filled
with null_value
(default float('nan')
).
Legacy ND2 files are not supported.
Parameters:
-
orient
(('records', 'dict', 'list')
, default:'records'
) –The format of the returned data. See
pandas.DataFrame - 'records' : list of dict -
[{column -> value}, ...](default) - 'dict' : dict of dict -
{column -> {index -> value}, ...}- 'list' : dict of list -
{column -> [value, ...]}` -
null_value
(Any
, default:float('nan')
) –The value to use for missing data.
Returns:
-
ListOfDicts | DictOfLists | DictOfDicts
–Tabular data in the format specified by
orient
.
frame_metadata(seq_index: int | tuple) -> FrameMetadata | dict
¶
Metadata for specific frame.
See also: metadata
This includes the global metadata from the metadata function. (will be dict if legacy format).
Example output
FrameMetadata(
contents=Contents(channelCount=2, frameCount=15),
channels=[
FrameChannel(
channel=ChannelMeta(
name="Widefield Green",
index=0,
color=Color(r=91, g=255, b=0, a=1.0),
emissionLambdaNm=535.0,
excitationLambdaNm=None,
),
loops=LoopIndices(
NETimeLoop=None, TimeLoop=0, XYPosLoop=None, ZStackLoop=1
),
microscope=Microscope(
objectiveMagnification=10.0,
objectiveName="Plan Fluor 10x Ph1 DLL",
objectiveNumericalAperture=0.3,
zoomMagnification=1.0,
immersionRefractiveIndex=1.0,
projectiveMagnification=None,
pinholeDiameterUm=None,
modalityFlags=["fluorescence"],
),
volume=Volume(
axesCalibrated=[True, True, True],
axesCalibration=[0.652452890023035, 0.652452890023035, 1.0],
axesInterpretation=["distance", "distance", "distance"],
bitsPerComponentInMemory=16,
bitsPerComponentSignificant=16,
cameraTransformationMatrix=[
-0.9998932296054086,
-0.014612644841559427,
0.014612644841559427,
-0.9998932296054086,
],
componentCount=1,
componentDataType="unsigned",
voxelCount=[32, 32, 5],
componentMaxima=[0.0],
componentMinima=[0.0],
pixelToStageTransformationMatrix=None,
),
position=Position(
stagePositionUm=StagePosition(
x=26950.2, y=-1801.6000000000001, z=494.3
),
pfsOffset=None,
name=None,
),
time=TimeStamp(
absoluteJulianDayNumber=2459486.0682717753,
relativeTimeMs=580.3582921028137,
),
),
FrameChannel(
channel=ChannelMeta(
name="Widefield Red",
index=1,
color=Color(r=255, g=85, b=0, a=1.0),
emissionLambdaNm=620.0,
excitationLambdaNm=None,
),
loops=LoopIndices(
NETimeLoop=None, TimeLoop=0, XYPosLoop=None, ZStackLoop=1
),
microscope=Microscope(
objectiveMagnification=10.0,
objectiveName="Plan Fluor 10x Ph1 DLL",
objectiveNumericalAperture=0.3,
zoomMagnification=1.0,
immersionRefractiveIndex=1.0,
projectiveMagnification=None,
pinholeDiameterUm=None,
modalityFlags=["fluorescence"],
),
volume=Volume(
axesCalibrated=[True, True, True],
axesCalibration=[0.652452890023035, 0.652452890023035, 1.0],
axesInterpretation=["distance", "distance", "distance"],
bitsPerComponentInMemory=16,
bitsPerComponentSignificant=16,
cameraTransformationMatrix=[
-0.9998932296054086,
-0.014612644841559427,
0.014612644841559427,
-0.9998932296054086,
],
componentCount=1,
componentDataType="unsigned",
voxelCount=[32, 32, 5],
componentMaxima=[0.0],
componentMinima=[0.0],
pixelToStageTransformationMatrix=None,
),
position=Position(
stagePositionUm=StagePosition(
x=26950.2, y=-1801.6000000000001, z=494.3
),
pfsOffset=None,
name=None,
),
time=TimeStamp(
absoluteJulianDayNumber=2459486.0682717753,
relativeTimeMs=580.3582921028137,
),
),
],
)
Parameters:
Returns:
-
FrameMetadata | dict
–dict if legacy format, else FrameMetadata
is_supported_file(path: StrOrPath) -> bool
staticmethod
¶
Return True
if the file is supported by this reader.
ome_metadata(*, include_unstructured: bool = True, tiff_file_name: str | None = None) -> OME
¶
Return ome_types.OME
metadata object for this file.
See the ome_types.OME
documentation for details on this object.
Parameters:
-
include_unstructured
(bool
, default:True
) –Whether to include all available metadata in the OME file. If
True
, (the default), theunstructured_metadata
method is used to fetch all retrievable metadata, and the output is added to OME.structured_annotations, where each key is the chunk key, and the value is a JSON-serialized dict of the metadata. IfFalse
, only metadata which can be directly added to the OME data model are included. -
tiff_file_name
(str | None
, default:None
) –If provided,
ome_types.model.TiffData
block entries are added for eachome_types.model.Plane
in the OME object, with theTiffData.uuid.file_name
set to this value. (Useful for exporting to tiff.)
Examples:
import nd2
with nd2.ND2File("path/to/file.nd2") as f:
ome = f.ome_metadata()
xml = ome.to_xml()
open() -> None
¶
Open file for reading.
Note
Files are best opened using a context manager:
with nd2.ND2File("path/to/file.nd2") as nd2_file:
...
This will automatically close the file when the context exits.
read_frame(frame_index: SupportsInt) -> np.ndarray
¶
Read a single frame from the file, indexed by frame number.
to_dask(wrapper: bool = True, copy: bool = True) -> dask.array.core.Array
¶
Create dask array (delayed reader) representing image.
This generally works well, but it remains to be seen whether performance
is optimized, or if we're duplicating safety mechanisms. You may try
various combinations of wrapper
and copy
, setting both to False
will very likely cause segmentation faults in many cases. But setting
one of them to False
, may slightly improve read speed in certain
cases.
Parameters:
-
wrapper
(bool
, default:True
) –If
True
(the default), the returned object will be a thin subclass of adask.array.Array
(aResourceBackedDaskArray
) that manages the opening and closing of this file when getting chunks via compute(). Ifwrapper
isFalse
, then a puredask.array.core.Array
will be returned. However, when that array is computed, it will incur a file open/close on every chunk that is read (in the_dask_block
method). As suchwrapper
will generally be much faster, however, it may fail (i.e. result in segmentation faults) with certain dask schedulers. -
copy
(bool
, default:True
) –If
True
(the default), the dask chunk-reading function will return an array copy. This can avoid segfaults in certain cases, though it may also add overhead.
Returns:
-
dask_array
(Array
) –A dask array representing the image data.
to_xarray(delayed: bool = True, squeeze: bool = True, position: int | None = None, copy: bool = True) -> xr.DataArray
¶
Return a labeled xarray.DataArray representing image.
Xarrays are a powerful way to label and manipulate n-dimensional data with axis-associated coordinates.
array.dims
will be populated according to image metadata, and coordinates
will be populated based on pixel spacings. Additional metadata is available
in array.attrs['metadata']
.
Parameters:
-
delayed
(bool
, default:True
) –Whether the DataArray should be backed by dask array or numpy array, by default True (dask).
-
squeeze
(bool
, default:True
) –Whether to squeeze singleton dimensions, by default True
-
position
(int
, default:None
) –A specific XY position to extract, by default (None) reads all.
-
copy
(bool
, default:True
) –Only applies when
delayed==True
. Seeto_dask
for details.
Returns:
-
DataArray
–xarray with all axes labeled.
unstructured_metadata(*, strip_prefix: bool = True, include: set[str] | None = None, exclude: set[str] | None = None) -> dict[str, Any]
¶
Exposes, and attempts to decode, each metadata chunk in the file.
This is provided as a experimental fallback in the event that
ND2File.experiment
does not contain all of the information you need. No
attempt is made to parse or validate the metadata, and the format of various
sections, may change in future versions of nd2. Consumption of this metadata
should use appropriate exception handling!
The 'ImageMetadataLV' chunk is the most likely to contain useful information, but if you're generally looking for "hidden" metadata, it may be helpful to look at the full output.
Parameters:
-
strip_prefix
(bool
, default:True
) –Whether to strip the type information from the front of the keys in the dict. For example, if
True
:uiModeFQ
becomesModeFQ
andbUsePFS
becomesUsePFS
, etc... by defaultTrue
-
include
(set[str] | None
, default:None
) –If provided, only include the specified keys in the output. by default, all metadata sections found in the file are included.
-
exclude
(set[str] | None
, default:None
) –If provided, exclude the specified keys from the output. by default
None
Returns:
voxel_size(channel: int = 0) -> _util.VoxelSize
¶
XYZ voxel size in microns.
Parameters:
-
channel
(int
, default:0
) –Channel for which to retrieve voxel info, by default 0. (Not yet implemented.)
Returns:
-
VoxelSize
–Named tuple with attrs
x
,y
, andz
.
write_tiff(dest: str | PathLike, *, include_unstructured_metadata: bool = True, progress: bool = False, on_frame: Callable[[int, int, dict[str, int]], None] | None | None = None, modify_ome: Callable[[ome_types.OME], None] | None = None) -> None
¶
Export to an (OME)-TIFF file.
To include OME-XML metadata, use extension .ome.tif
or .ome.tiff
.
Parameters:
-
dest
(str | PathLike
) –The destination TIFF file.
-
include_unstructured_metadata
(bool
, default:True
) –Whether to include unstructured metadata in the OME-XML. This includes all of the metadata that we can find in the ND2 file in the StructuredAnnotations section of the OME-XML (as mapping of metadata chunk name to JSON-encoded string). By default
True
. -
progress
(bool
, default:False
) –Whether to display progress bar. If
True
andtqdm
is installed, it will be used. Otherwise, a simple text counter will be printed to the console. By defaultFalse
. -
on_frame
(Callable[[int, int, dict[str, int]], None] | None
, default:None
) –A function to call after each frame is written. The function should accept three arguments: the current frame number, the total number of frames, and a dictionary of the current frame's indices (e.g.
{"T": 0, "Z": 1}
) (Useful for integrating custom progress bars or logging.) -
modify_ome
(Callable[[OME], None]
, default:None
) –A function to modify the OME metadata before writing it to the file. Accepts an
ome_types.OME
object and should modify it in place. (reminder: OME-XML is only written if the file extension is.ome.tif
or.ome.tiff
)
imread(file: Path | str, *, dask: bool = False, xarray: bool = False, validate_frames: bool = False) -> np.ndarray | xr.DataArray | dask.array.core.Array
¶
Open file
, return requested array type, and close file
.
Parameters:
-
file
(Path | str
) –Filepath (
str
) orPath
object to ND2 file. -
dask
(bool
, default:False
) –If
True
, returns a (delayed)dask.array.Array
. This will avoid reading any data from disk until specifically requested by using.compute()
or casting to a numpy array withnp.asarray()
. By defaultFalse
. -
xarray
(bool
, default:False
) –If
True
, returns anxarray.DataArray
,array.dims
will be populated according to image metadata, and coordinates will be populated based on pixel spacings. Additional metadata is available inarray.attrs['metadata']
. Ifdask
is alsoTrue
, will return an xarray backed by a delayed dask array. By defaultFalse
. -
validate_frames
(bool
, default:False
) –Whether to verify (and attempt to fix) frames whose positions have been shifted relative to the predicted offset (i.e. in a corrupted file). This comes at a slight performance penalty at file open, but may "rescue" some corrupt files. by default False.
Returns:
is_legacy(path: StrOrPath) -> bool
¶
is_supported_file(path: FileOrBinaryIO, open_: Callable[[StrOrPath], BinaryIO] = _open_binary) -> bool
¶
nd2_to_tiff(source: str | PathLike | ND2File, dest: str | PathLike, *, include_unstructured_metadata: bool = True, progress: bool = False, on_frame: Callable[[int, int, dict[str, int]], None] | None = None, modify_ome: Callable[[ome_types.OME], None] | None = None) -> None
¶
Export an ND2 file to an (OME)-TIFF file.
To include OME-XML metadata, use extension .ome.tif
or .ome.tiff
.
https://docs.openmicroscopy.org/ome-model/6.3.1/ome-tiff/specification.html
Parameters:
-
source
(str | PathLike | ND2File
) –The ND2 file path or an open ND2File object.
-
dest
(str | PathLike
) –The destination TIFF file.
-
include_unstructured_metadata
(bool
, default:True
) –Whether to include unstructured metadata in the OME-XML. This includes all of the metadata that we can find in the ND2 file in the StructuredAnnotations section of the OME-XML (as mapping of metadata chunk name to JSON-encoded string). By default
True
. -
progress
(bool
, default:False
) –Whether to display progress bar. If
True
andtqdm
is installed, it will be used. Otherwise, a simple text counter will be printed to the console. By defaultFalse
. -
on_frame
(Callable[[int, int, dict[str, int]], None] | None
, default:None
) –A function to call after each frame is written. The function should accept three arguments: the current frame number, the total number of frames, and a dictionary of the current frame's indices (e.g.
{"T": 0, "Z": 1}
) (Useful for integrating custom progress bars or logging.) -
modify_ome
(Callable[[OME], None]
, default:None
) –A function to modify the OME metadata before writing it to the file. Accepts an
ome_types.OME
object and should modify it in place. (reminder: OME-XML is only written if the file extension is.ome.tif
or.ome.tiff
)
rescue_nd2(handle: BinaryIO | str, frame_shape: tuple[int, ...] = (), dtype: DTypeLike = 'uint16', max_iters: int | None = None, verbose: bool = True, chunk_start: bytes = _default_chunk_start) -> Iterator[np.ndarray]
¶
Iterator that yields all discovered frames in a file handle.
In nd2 files, each "frame" contains XY and all channel info (both true
channels as well as RGB components). Frames are laid out as (Y, X, C),
and the frame_shape
should match the expected frame size. If
frame_shape
is not provided, a guess will be made about the vector shape
of each frame, but it may be incorrect.
Parameters:
-
handle
(BinaryIO | str
) –Filepath string, or binary file handle (For example
handle = open('some.nd2', 'rb')
) -
frame_shape
(Tuple[int, ...]
, default:()
) –expected shape of each frame, by default a 1 dimensional array will be yielded for each frame, which can be reshaped later if desired. NOTE: nd2 frames are generally ordered as (height, width, true_channels, rgbcomponents). So unlike numpy, which would use (channels, Y, X), you should use (Y, X, channels)
-
dtype
(dtype
, default:'uint16'
) –Data type, by default np.uint16
-
max_iters
(Optional[int]
, default:None
) –A maximum number of frames to yield, by default will yield until the end of the file is reached
-
verbose
(bool
, default:True
) –whether to print info
-
chunk_start
(bytes
, default:_default_chunk_start
) –The bytes that start each chunk, by default 0x0ABECEDA.to_bytes(4, "little")
Yields:
-
ndarray
–each discovered frame in the file
Examples:
>>> with open('some_bad.nd2', 'rb') as fh:
>>> frames = rescue_nd2(fh, (512, 512, 4), 'uint16')
>>> ary = np.stack(frames)
You will likely want to reshape ary
after that.