imcflibs.imagej.bioformats

Bio-Formats related helper functions.

NOTE: this is NOT about using python-bioformats but rather about calling the corresponding functions provided by ImageJ.

  1"""Bio-Formats related helper functions.
  2
  3NOTE: this is *NOT* about using [python-bioformats][1] but rather about calling
  4the corresponding functions provided by ImageJ.
  5
  6[1]: https://pypi.org/project/python-bioformats/
  7
  8"""
  9
 10# Mosts imports will fail with plain C-Python / pylint:
 11# pylint: disable-msg=import-error
 12
 13import os
 14
 15from ij import IJ
 16
 17## disabled while running pdoc ## from ._loci import ImporterOptions  
 18from ._loci import BF, ImageReader, Memoizer
 19
 20from ..pathtools import gen_name_from_orig
 21from ..log import LOG as log
 22
 23
 24def import_image(
 25    filename,
 26    color_mode="color",
 27    split_c=False,
 28    split_z=False,
 29    split_t=False,
 30    series_number=None,
 31    c_start=None,
 32    c_end=None,
 33    c_interval=None,
 34    z_start=None,
 35    z_end=None,
 36    z_interval=None,
 37    t_start=None,
 38    t_end=None,
 39    t_interval=None,
 40):
 41    """Open an image file using the Bio-Formats importer.
 42
 43    Parameters
 44    ----------
 45    filename : str
 46        The full path to the file to be imported through Bio-Formats.
 47    color_mode : str, optional
 48        The color mode to be used for the resulting ImagePlus, one of 'color',
 49        'composite', 'gray' and 'default'.
 50    split_c : bool, optional
 51        Whether to split the channels into separate ImagePlus objects.
 52    split_z : bool, optional
 53        Whether to split the z-slices into separate ImagePlus objects.
 54    split_t : bool, optional
 55        Whether to split the time points into separate ImagePlus objects.
 56    series_number : int, optional
 57        open a specific Bio-Formats series
 58    c_start : int, optional
 59        only import a subset of channel starting with this one. Requires to set
 60        c_end and c_interval.
 61    c_end : int, optional
 62        only import channel(s) ending with this one. Requires to set c_start and
 63        c_interval.
 64    c_interval : int, optional
 65        only import a subset of channel with this interval. Requires to set
 66        c_start and c_end.
 67    z_start : int, optional
 68        only import a subset of planes starting with this one. Requires to set
 69        z_end and z_interval.
 70    z_end : int, optional
 71        only import a subset of planes ending with this one. Requires to set
 72        z_start and z_interval.
 73    z_interval : int, optional
 74        only import a subset of planes with this interval. Requires to set
 75        z_start and z_end.
 76    t_start : int, optional
 77        only import a subset of time points starting with this one. Requires to
 78        set t_end and t_interval.
 79    t_end : int, optional
 80        only import a subset of time points ending with this one. Requires to
 81        set t_start and t_interval.
 82    t_interval : int, optional
 83        only import a subset of time points with thsi interval. Requires to set
 84        t_start and t_end.
 85
 86    Returns
 87    -------
 88    ij.ImagePlus[]
 89        A list of ImagePlus objects resulting from the import.
 90    """
 91    options = ImporterOptions()
 92    mode = {
 93        "color": ImporterOptions.COLOR_MODE_COLORIZED,
 94        "composite": ImporterOptions.COLOR_MODE_COMPOSITE,
 95        "gray": ImporterOptions.COLOR_MODE_GRAYSCALE,
 96        "default": ImporterOptions.COLOR_MODE_DEFAULT,
 97    }
 98    options.setColorMode(mode[color_mode])
 99    options.setSplitChannels(split_c)
100    options.setSplitFocalPlanes(split_z)
101    options.setSplitTimepoints(split_t)
102    options.setId(filename)
103    if series_number is not None:
104        options.setSeriesOn(series_number, True)
105
106    if c_start is not None:
107        if series_number is None:
108            series_number = 0
109        options.setSpecifyRanges(True)
110        options.setCBegin(series_number, c_start)
111        options.setCEnd(series_number, c_end)
112        options.setCStep(series_number, c_interval)
113
114    if z_start is not None:
115        if series_number is None:
116            series_number = 0
117        options.setSpecifyRanges(True)
118        options.setZBegin(series_number, z_start)
119        options.setZEnd(series_number, z_end)
120        options.setZStep(series_number, z_interval)
121
122    if t_start is not None:
123        if series_number is None:
124            series_number = 0
125        options.setSpecifyRanges(True)
126        options.setTBegin(series_number, t_start)
127        options.setTEnd(series_number, t_end)
128        options.setTStep(series_number, t_interval)
129
130    log.info("Reading [%s]", filename)
131    orig_imps = BF.openImagePlus(options)
132    log.debug("Opened [%s] %s", filename, type(orig_imps))
133    return orig_imps
134
135
136def export(imp, filename, overwrite=False):
137    """Simple wrapper to export an image to a given file.
138
139    Parameters
140    ----------
141    imp : ij.ImagePlus
142        The ImagePlus object to be exported by Bio-Formats.
143    filename : str
144        The output filename, may include a full path.
145    overwrite : bool
146        A switch to indicate existing files should be overwritten. Default is to
147        keep existing files, in this case an IOError is raised.
148    """
149    log.info("Exporting to [%s]", filename)
150    suffix = filename[-3:].lower()
151    try:
152        unit = imp.calibration.unit
153        log.debug("Detected calibration unit: %s", unit)
154    except Exception as err:
155        log.error("Unable to detect spatial unit: %s", err)
156        raise RuntimeError("Error detecting image calibration: %s" % err)
157    if unit == "pixel" and (suffix == "ics" or suffix == "ids"):
158        log.warn(
159            "Forcing unit to be 'm' instead of 'pixel' to avoid "
160            "Bio-Formats 6.0.x Exporter bug!"
161        )
162        imp.calibration.unit = "m"
163    if os.path.exists(filename):
164        if not overwrite:
165            raise IOError("file [%s] already exists!" % filename)
166        log.debug("Removing existing file [%s]...", filename)
167        os.remove(filename)
168
169    IJ.run(imp, "Bio-Formats Exporter", "save=[" + filename + "]")
170    log.debug("Exporting finished.")
171
172
173def export_using_orig_name(imp, path, orig_name, tag, suffix, overwrite=False):
174    """Export an image to a given path, deriving the name from the input file.
175
176    The input filename is stripped to its pure file name, without any path or
177    suffix components, then an optional tag (e.g. "-avg") and the new format
178    suffix is added.
179
180    Parameters
181    ----------
182    imp : ij.ImagePlus
183        The ImagePlus object to be exported by Bio-Formats.
184    path : str or object that can be cast to a str
185        The output path.
186    orig_name : str or object that can be cast to a str
187        The input file name, may contain arbitrary path components.
188    tag : str
189        An optional tag to be added at the end of the new file name, can be used
190        to denote information like "-avg" for an average projection image.
191    suffix : str
192        The new file name suffix, which also sets the file format for BF.
193    overwrite : bool
194        A switch to indicate existing files should be overwritten.
195
196    Returns
197    -------
198    out_file : str
199        The full name of the exported file.
200    """
201    out_file = gen_name_from_orig(path, orig_name, tag, suffix)
202    export(imp, out_file, overwrite)
203    return out_file
204
205
206def get_series_count_from_ome_metadata(path_to_file):
207    """Get the Bio-Formates series count from a file on disk.
208
209    Useful to access a specific image in a container format like .czi, .nd2, .lif...
210
211    Parameters
212    ----------
213    path_to_file : str
214        The full path to the image file.
215
216    Returns
217    -------
218    int
219        The number of Bio-Formats series detected in the image file metadata.
220    """
221    reader = ImageReader()
222    ome_meta = MetadataTools.createOMEXMLMetadata()
223    reader.setMetadataStore(ome_meta)
224    reader.setId(path_to_file)
225    series_count = reader.getSeriesCount()
226    reader.close()
227
228    return series_count
229
230
231def write_bf_memoryfile(path_to_file):
232    """Write a BF memo-file so subsequent access to the same file is faster.
233
234    The Bio-Formats memo-file is written next to the image file (i.e. in the
235    same folder as the given file).
236
237    Parameters
238    ----------
239    path_to_file : string
240        The full path to the image file.
241    """
242    reader = Memoizer(ImageReader())
243    reader.setId(path_to_file)
244    reader.close()
def import_image( filename, color_mode='color', split_c=False, split_z=False, split_t=False, series_number=None, c_start=None, c_end=None, c_interval=None, z_start=None, z_end=None, z_interval=None, t_start=None, t_end=None, t_interval=None):
 25def import_image(
 26    filename,
 27    color_mode="color",
 28    split_c=False,
 29    split_z=False,
 30    split_t=False,
 31    series_number=None,
 32    c_start=None,
 33    c_end=None,
 34    c_interval=None,
 35    z_start=None,
 36    z_end=None,
 37    z_interval=None,
 38    t_start=None,
 39    t_end=None,
 40    t_interval=None,
 41):
 42    """Open an image file using the Bio-Formats importer.
 43
 44    Parameters
 45    ----------
 46    filename : str
 47        The full path to the file to be imported through Bio-Formats.
 48    color_mode : str, optional
 49        The color mode to be used for the resulting ImagePlus, one of 'color',
 50        'composite', 'gray' and 'default'.
 51    split_c : bool, optional
 52        Whether to split the channels into separate ImagePlus objects.
 53    split_z : bool, optional
 54        Whether to split the z-slices into separate ImagePlus objects.
 55    split_t : bool, optional
 56        Whether to split the time points into separate ImagePlus objects.
 57    series_number : int, optional
 58        open a specific Bio-Formats series
 59    c_start : int, optional
 60        only import a subset of channel starting with this one. Requires to set
 61        c_end and c_interval.
 62    c_end : int, optional
 63        only import channel(s) ending with this one. Requires to set c_start and
 64        c_interval.
 65    c_interval : int, optional
 66        only import a subset of channel with this interval. Requires to set
 67        c_start and c_end.
 68    z_start : int, optional
 69        only import a subset of planes starting with this one. Requires to set
 70        z_end and z_interval.
 71    z_end : int, optional
 72        only import a subset of planes ending with this one. Requires to set
 73        z_start and z_interval.
 74    z_interval : int, optional
 75        only import a subset of planes with this interval. Requires to set
 76        z_start and z_end.
 77    t_start : int, optional
 78        only import a subset of time points starting with this one. Requires to
 79        set t_end and t_interval.
 80    t_end : int, optional
 81        only import a subset of time points ending with this one. Requires to
 82        set t_start and t_interval.
 83    t_interval : int, optional
 84        only import a subset of time points with thsi interval. Requires to set
 85        t_start and t_end.
 86
 87    Returns
 88    -------
 89    ij.ImagePlus[]
 90        A list of ImagePlus objects resulting from the import.
 91    """
 92    options = ImporterOptions()
 93    mode = {
 94        "color": ImporterOptions.COLOR_MODE_COLORIZED,
 95        "composite": ImporterOptions.COLOR_MODE_COMPOSITE,
 96        "gray": ImporterOptions.COLOR_MODE_GRAYSCALE,
 97        "default": ImporterOptions.COLOR_MODE_DEFAULT,
 98    }
 99    options.setColorMode(mode[color_mode])
100    options.setSplitChannels(split_c)
101    options.setSplitFocalPlanes(split_z)
102    options.setSplitTimepoints(split_t)
103    options.setId(filename)
104    if series_number is not None:
105        options.setSeriesOn(series_number, True)
106
107    if c_start is not None:
108        if series_number is None:
109            series_number = 0
110        options.setSpecifyRanges(True)
111        options.setCBegin(series_number, c_start)
112        options.setCEnd(series_number, c_end)
113        options.setCStep(series_number, c_interval)
114
115    if z_start is not None:
116        if series_number is None:
117            series_number = 0
118        options.setSpecifyRanges(True)
119        options.setZBegin(series_number, z_start)
120        options.setZEnd(series_number, z_end)
121        options.setZStep(series_number, z_interval)
122
123    if t_start is not None:
124        if series_number is None:
125            series_number = 0
126        options.setSpecifyRanges(True)
127        options.setTBegin(series_number, t_start)
128        options.setTEnd(series_number, t_end)
129        options.setTStep(series_number, t_interval)
130
131    log.info("Reading [%s]", filename)
132    orig_imps = BF.openImagePlus(options)
133    log.debug("Opened [%s] %s", filename, type(orig_imps))
134    return orig_imps

Open an image file using the Bio-Formats importer.

Parameters
  • filename (str): The full path to the file to be imported through Bio-Formats.
  • color_mode (str, optional): The color mode to be used for the resulting ImagePlus, one of 'color', 'composite', 'gray' and 'default'.
  • split_c (bool, optional): Whether to split the channels into separate ImagePlus objects.
  • split_z (bool, optional): Whether to split the z-slices into separate ImagePlus objects.
  • split_t (bool, optional): Whether to split the time points into separate ImagePlus objects.
  • series_number (int, optional): open a specific Bio-Formats series
  • c_start (int, optional): only import a subset of channel starting with this one. Requires to set c_end and c_interval.
  • c_end (int, optional): only import channel(s) ending with this one. Requires to set c_start and c_interval.
  • c_interval (int, optional): only import a subset of channel with this interval. Requires to set c_start and c_end.
  • z_start (int, optional): only import a subset of planes starting with this one. Requires to set z_end and z_interval.
  • z_end (int, optional): only import a subset of planes ending with this one. Requires to set z_start and z_interval.
  • z_interval (int, optional): only import a subset of planes with this interval. Requires to set z_start and z_end.
  • t_start (int, optional): only import a subset of time points starting with this one. Requires to set t_end and t_interval.
  • t_end (int, optional): only import a subset of time points ending with this one. Requires to set t_start and t_interval.
  • t_interval (int, optional): only import a subset of time points with thsi interval. Requires to set t_start and t_end.
Returns
  • ij.ImagePlus[]: A list of ImagePlus objects resulting from the import.
def export(imp, filename, overwrite=False):
137def export(imp, filename, overwrite=False):
138    """Simple wrapper to export an image to a given file.
139
140    Parameters
141    ----------
142    imp : ij.ImagePlus
143        The ImagePlus object to be exported by Bio-Formats.
144    filename : str
145        The output filename, may include a full path.
146    overwrite : bool
147        A switch to indicate existing files should be overwritten. Default is to
148        keep existing files, in this case an IOError is raised.
149    """
150    log.info("Exporting to [%s]", filename)
151    suffix = filename[-3:].lower()
152    try:
153        unit = imp.calibration.unit
154        log.debug("Detected calibration unit: %s", unit)
155    except Exception as err:
156        log.error("Unable to detect spatial unit: %s", err)
157        raise RuntimeError("Error detecting image calibration: %s" % err)
158    if unit == "pixel" and (suffix == "ics" or suffix == "ids"):
159        log.warn(
160            "Forcing unit to be 'm' instead of 'pixel' to avoid "
161            "Bio-Formats 6.0.x Exporter bug!"
162        )
163        imp.calibration.unit = "m"
164    if os.path.exists(filename):
165        if not overwrite:
166            raise IOError("file [%s] already exists!" % filename)
167        log.debug("Removing existing file [%s]...", filename)
168        os.remove(filename)
169
170    IJ.run(imp, "Bio-Formats Exporter", "save=[" + filename + "]")
171    log.debug("Exporting finished.")

Simple wrapper to export an image to a given file.

Parameters
  • imp (ij.ImagePlus): The ImagePlus object to be exported by Bio-Formats.
  • filename (str): The output filename, may include a full path.
  • overwrite (bool): A switch to indicate existing files should be overwritten. Default is to keep existing files, in this case an IOError is raised.
def export_using_orig_name(imp, path, orig_name, tag, suffix, overwrite=False):
174def export_using_orig_name(imp, path, orig_name, tag, suffix, overwrite=False):
175    """Export an image to a given path, deriving the name from the input file.
176
177    The input filename is stripped to its pure file name, without any path or
178    suffix components, then an optional tag (e.g. "-avg") and the new format
179    suffix is added.
180
181    Parameters
182    ----------
183    imp : ij.ImagePlus
184        The ImagePlus object to be exported by Bio-Formats.
185    path : str or object that can be cast to a str
186        The output path.
187    orig_name : str or object that can be cast to a str
188        The input file name, may contain arbitrary path components.
189    tag : str
190        An optional tag to be added at the end of the new file name, can be used
191        to denote information like "-avg" for an average projection image.
192    suffix : str
193        The new file name suffix, which also sets the file format for BF.
194    overwrite : bool
195        A switch to indicate existing files should be overwritten.
196
197    Returns
198    -------
199    out_file : str
200        The full name of the exported file.
201    """
202    out_file = gen_name_from_orig(path, orig_name, tag, suffix)
203    export(imp, out_file, overwrite)
204    return out_file

Export an image to a given path, deriving the name from the input file.

The input filename is stripped to its pure file name, without any path or suffix components, then an optional tag (e.g. "-avg") and the new format suffix is added.

Parameters
  • imp (ij.ImagePlus): The ImagePlus object to be exported by Bio-Formats.
  • path (str or object that can be cast to a str): The output path.
  • orig_name (str or object that can be cast to a str): The input file name, may contain arbitrary path components.
  • tag (str): An optional tag to be added at the end of the new file name, can be used to denote information like "-avg" for an average projection image.
  • suffix (str): The new file name suffix, which also sets the file format for BF.
  • overwrite (bool): A switch to indicate existing files should be overwritten.
Returns
  • out_file (str): The full name of the exported file.
def get_series_count_from_ome_metadata(path_to_file):
207def get_series_count_from_ome_metadata(path_to_file):
208    """Get the Bio-Formates series count from a file on disk.
209
210    Useful to access a specific image in a container format like .czi, .nd2, .lif...
211
212    Parameters
213    ----------
214    path_to_file : str
215        The full path to the image file.
216
217    Returns
218    -------
219    int
220        The number of Bio-Formats series detected in the image file metadata.
221    """
222    reader = ImageReader()
223    ome_meta = MetadataTools.createOMEXMLMetadata()
224    reader.setMetadataStore(ome_meta)
225    reader.setId(path_to_file)
226    series_count = reader.getSeriesCount()
227    reader.close()
228
229    return series_count

Get the Bio-Formates series count from a file on disk.

Useful to access a specific image in a container format like .czi, .nd2, .lif...

Parameters
  • path_to_file (str): The full path to the image file.
Returns
  • int: The number of Bio-Formats series detected in the image file metadata.
def write_bf_memoryfile(path_to_file):
232def write_bf_memoryfile(path_to_file):
233    """Write a BF memo-file so subsequent access to the same file is faster.
234
235    The Bio-Formats memo-file is written next to the image file (i.e. in the
236    same folder as the given file).
237
238    Parameters
239    ----------
240    path_to_file : string
241        The full path to the image file.
242    """
243    reader = Memoizer(ImageReader())
244    reader.setId(path_to_file)
245    reader.close()

Write a BF memo-file so subsequent access to the same file is faster.

The Bio-Formats memo-file is written next to the image file (i.e. in the same folder as the given file).

Parameters
  • path_to_file (string): The full path to the image file.