From c669c0f0a6dae6aa497920ef4b38c7b27b19de6b Mon Sep 17 00:00:00 2001 From: Laurent Guerard Date: Thu, 8 Jan 2026 16:50:14 +0100 Subject: [PATCH 01/14] feat(bdv): Fix methods to work with latest BDV version * Add optional list_files parameter to define_dataset_manual * Update processing options to use bdv.ProcessingOptions * Improve logging for manual dataset definition options * Refactor fuse_dataset_bdvp parameters for clarity * Introduce join_files_with_channel_suffix function for file handling --- src/imcflibs/imagej/bdv.py | 128 ++++++++++++++++++++++++++----------- 1 file changed, 89 insertions(+), 39 deletions(-) diff --git a/src/imcflibs/imagej/bdv.py b/src/imcflibs/imagej/bdv.py index 5cc7b412..1ffe9024 100644 --- a/src/imcflibs/imagej/bdv.py +++ b/src/imcflibs/imagej/bdv.py @@ -13,6 +13,7 @@ import shutil import sys +from bdv.util.source.fused import AlphaFusedResampledSource from ch.epfl.biop.scijava.command.spimdata import ( FuseBigStitcherDatasetIntoOMETiffCommand, ) @@ -21,7 +22,6 @@ from .. import pathtools from ..log import LOG as log - # internal template strings used in string formatting (note: the `"""@private"""` # pseudo-decorator is there to instruct [pdoc] to omit those variables when generating # API documentation): @@ -902,6 +902,7 @@ def define_dataset_manual( image_file_pattern, dataset_organisation, definition_opts=None, + list_files=None, ): """Run "Define Multi-View Dataset" using the "Manual Loader" option. @@ -920,20 +921,26 @@ def define_dataset_manual( Looks like "timepoints_=%s-%s channels_=0-%s tiles_=%s-%s" definition_opts : dict Dictionary containing the details about the file repartitions. + list_files : list of str, optional + If provided, a list of file names to pass directly to the manual + loader in "show_list" mode. When `list_files` is given the + function will include the filenames in the options string instead + of relying on a file pattern; items should be either basenames or + paths appropriate for the selected ``image_file_directory``. + """ - xml_filename = project_filename + ".xml" + # xml_filename = project_filename + ".xml" if definition_opts is None: - definition_opts = DefinitionOptions() + definition_opts = bdv.DefinitionOptions() - temp = os.path.join(source_directory, project_filename + "_temp") - os.path.join(temp, project_filename) + show_list_options = "" if not list_files else "show_list " + " ".join(list_files) options = ( "define_dataset=[Manual Loader (Bioformats based)] " + "project_filename=[" - + xml_filename + + project_filename + "] " + "_____" + definition_opts.fmt_acitt_options() @@ -943,11 +950,12 @@ def define_dataset_manual( + " " + "image_file_pattern=" + image_file_pattern + + " " + dataset_organisation + " " + "calibration_type=[Same voxel-size for all views] " + "calibration_definition=[Load voxel-size(s) from file(s)] " - # + "imglib2_data_container=[ArrayImg (faster)]" + + show_list_options ) log.debug("Manual dataset definition options: <%s>", options) @@ -991,7 +999,7 @@ def resave_as_h5( """ if not processing_opts: - processing_opts = ProcessingOptions() + processing_opts = bdv.ProcessingOptions() if use_deflate_compression: use_deflate_compression_arg = "use_deflate_compression " @@ -1032,7 +1040,7 @@ def resave_as_h5( ) log.debug("Resave as HDF5 options: <%s>", options) - IJ.run("As HDF5", str(options)) + IJ.run("Resave as HDF5 (local)", str(options)) def flip_axes(source_xml_file, x=False, y=True, z=False): @@ -1593,14 +1601,17 @@ def fuse_dataset( def fuse_dataset_bdvp( project_path, command, - processing_opts=None, result_path=None, - compression="LZW", + n_resolution_levels=5, + use_lzw_compression=True, + fusion_method="SMOOTH " + AlphaFusedResampledSource.AVERAGE, ): """Export a BigDataViewer project using the BIOP Kheops exporter. - Use the BIOP Kheops exporter to convert a BigDataViewer project into - OME-TIFF files, with optional compression. + Convert a BigDataViewer project into OME-TIFF files using the BIOP + Kheops exporter. This wraps the Scijava export command and allows + setting the output directory, compression and number of resolution + levels. Parameters ---------- @@ -1608,43 +1619,82 @@ def fuse_dataset_bdvp( Full path to the BigDataViewer XML project file. command : CommandService The Scijava CommandService instance to execute the export command. - processing_opts : ProcessingOptions, optional - Options defining which parts of the dataset to process. If None, default - processing options will be used (process all angles, channels, etc.). result_path : str, optional - Path where to store the exported files. If None, files will be saved in - the same directory as the input project. - compression : str, optional - Compression method to use for the TIFF files. Default is "LZW". + Path where to store the exported files. If ``None``, files will be + saved in the same directory as the input project. + n_resolution_levels : int, optional + Number of resolution levels to export (default 5). + use_lzw_compression : bool, optional + Whether to use LZW compression for the output TIFFs (default True). + fusion_method : str, optional + Fusion method to use for exporting (default ``"SMOOTH AVERAGE"``). Notes ----- - This function requires the PTBIOP update site to be enabled in Fiji/ImageJ. + This function requires the PTBIOP update site to be enabled in Fiji/ + ImageJ. + """ - if processing_opts is None: - processing_opts = ProcessingOptions() file_info = pathtools.parse_path(project_path) + if not result_path: result_path = file_info["path"] - # if not os.path.exists(result_path): - # os.makedirs(result_path) command.run( FuseBigStitcherDatasetIntoOMETiffCommand, - True, - "image", + False, + "xml_bigstitcher_file", project_path, - "output_dir", + "output_path_directory", result_path, - "compression", - compression, - "subset_channels", - "", - "subset_slices", - "", - "subset_frames", - "", - "compress_temp_files", - False, - ) + "n_resolution_levels", + n_resolution_levels, + "use_lzw_compression", + use_lzw_compression, + "fusion_method", + fusion_method, + ).get() + + +def join_files_with_channel_suffix(files, nchannels): + """Join filenames and append channel-suffixed copies. + + For each filename in ``files``, return a list where original filenames + appear first followed by copies with suffixes ``_0`` .. ``_{n-2}`` + (inserted before the file extension). This is suitable for passing + to Bioformats/Jython in ``show_list`` mode when each channel is stored + as a separate file. + + Parameters + ---------- + files : list or tuple + List or tuple of filename strings. + nchannels : int + Number of channels (>=1). If ``nchannels`` is 1 no suffixed copies + are added. + + Returns + ------- + list of str + Ordered list of filenames (originals then suffixed copies). + """ + import os + + if not files: + return "" + try: + x = range(int(nchannels) - 1) + except Exception: + x = [0] + suff = "_" + str(x) + out = [] + # keep original order, then add suffixed copies + for f in files: + out.append(f) + for i in x: + suff = "_" + str(i) + for f in files: + base, ext = os.path.splitext(f) + out.append(base + suff + ext) + return out From d19462df0b6f72f6f2b674b78f949a60098385b7 Mon Sep 17 00:00:00 2001 From: Laurent Guerard Date: Wed, 14 Jan 2026 13:55:56 +0100 Subject: [PATCH 02/14] Merge modifications made by @cellkai in #106 --- src/imcflibs/imagej/bdv.py | 71 +++++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 13 deletions(-) diff --git a/src/imcflibs/imagej/bdv.py b/src/imcflibs/imagej/bdv.py index 1ffe9024..a4f83e3a 100644 --- a/src/imcflibs/imagej/bdv.py +++ b/src/imcflibs/imagej/bdv.py @@ -13,7 +13,6 @@ import shutil import sys -from bdv.util.source.fused import AlphaFusedResampledSource from ch.epfl.biop.scijava.command.spimdata import ( FuseBigStitcherDatasetIntoOMETiffCommand, ) @@ -1602,16 +1601,23 @@ def fuse_dataset_bdvp( project_path, command, result_path=None, + fusion_method="SMOOTH AVERAGE", + range_channels="", + range_slices="", + range_frames="", n_resolution_levels=5, use_lzw_compression=True, - fusion_method="SMOOTH " + AlphaFusedResampledSource.AVERAGE, + split_slices=False, + split_channels=False, + split_frames=False, + override_z_ratio=False, + z_ratio=1.0, + use_interpolation=True, ): """Export a BigDataViewer project using the BIOP Kheops exporter. - Convert a BigDataViewer project into OME-TIFF files using the BIOP - Kheops exporter. This wraps the Scijava export command and allows - setting the output directory, compression and number of resolution - levels. + Use BIOP Kheops exporter to fuse a BigDataViewer project and save + it as pyramidal OME-TIFF. Parameters ---------- @@ -1622,18 +1628,39 @@ def fuse_dataset_bdvp( result_path : str, optional Path where to store the exported files. If ``None``, files will be saved in the same directory as the input project. - n_resolution_levels : int, optional - Number of resolution levels to export (default 5). - use_lzw_compression : bool, optional - Whether to use LZW compression for the output TIFFs (default True). fusion_method : str, optional Fusion method to use for exporting (default ``"SMOOTH AVERAGE"``). + range_channels : str, optional + Channels to include in the export. Default is all channels. + range_slices : str, optional + Slices to include in the export. Default is all slices. + range_frames : str, optional + Frames to include in the export. Default is all frames. + n_resolution_levels : int, optional + Number of pyramid resolution levels to use for the export. Default is 5. + use_lzw_compression : bool, optional + If True, compressed the output file using LZW. Default is True. + split_slices : bool, optional + If True, splits the output into separate files for each slice. Default is False. + split_channels : bool, optional + If True, splits the output into separate files for each channel. Default is False. + split_frames : bool, optional + If True, splits the output into separate files for each frame. Default is False. + override_z_ratio : bool, optional + If True, overrides the default z_ratio value. Default is False. + z_ratio : float, optional + The z ratio to use for the export. Default is 1.0. + use_interpolation : bool, optional + If True, interpolates during fusion (takes ~4x longer). Default is True. Notes ----- This function requires the PTBIOP update site to be enabled in Fiji/ ImageJ. + Examples + -------- + fuse_dataset_bdvp(xml_input, cs) """ file_info = pathtools.parse_path(project_path) @@ -1643,17 +1670,35 @@ def fuse_dataset_bdvp( command.run( FuseBigStitcherDatasetIntoOMETiffCommand, - False, + True, "xml_bigstitcher_file", project_path, "output_path_directory", result_path, + "range_channels", + range_channels, + "range_slices", + range_slices, + "range_frames", + range_frames, "n_resolution_levels", n_resolution_levels, - "use_lzw_compression", - use_lzw_compression, "fusion_method", fusion_method, + "use_lzw_compression", + use_lzw_compression, + "split_slices", + split_slices, + "split_channels", + split_channels, + "split_frames", + split_frames, + "override_z_ratio", + override_z_ratio, + "z_ratio", + z_ratio, + "use_interpolation", + use_interpolation, ).get() From 679e5d3498262b6e7b62c70924cd1ac971c68cb2 Mon Sep 17 00:00:00 2001 From: Laurent Guerard Date: Wed, 14 Jan 2026 15:00:28 +0100 Subject: [PATCH 03/14] fix(bdv): Clarify boolean parameter for headless command execution --- src/imcflibs/imagej/bdv.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/imcflibs/imagej/bdv.py b/src/imcflibs/imagej/bdv.py index a4f83e3a..374230f5 100644 --- a/src/imcflibs/imagej/bdv.py +++ b/src/imcflibs/imagej/bdv.py @@ -1670,7 +1670,7 @@ def fuse_dataset_bdvp( command.run( FuseBigStitcherDatasetIntoOMETiffCommand, - True, + True, # From my understanding, this boolean indicates whether to run the command headless or not. "xml_bigstitcher_file", project_path, "output_path_directory", From 24126c795debd2e9810c361760cccc032ce2a075 Mon Sep 17 00:00:00 2001 From: Niko Ehrenfeuchter Date: Wed, 14 Jan 2026 18:24:15 +0100 Subject: [PATCH 04/14] Shorten comment on headless command execution --- src/imcflibs/imagej/bdv.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/imcflibs/imagej/bdv.py b/src/imcflibs/imagej/bdv.py index 374230f5..828c5d4f 100644 --- a/src/imcflibs/imagej/bdv.py +++ b/src/imcflibs/imagej/bdv.py @@ -1670,7 +1670,7 @@ def fuse_dataset_bdvp( command.run( FuseBigStitcherDatasetIntoOMETiffCommand, - True, # From my understanding, this boolean indicates whether to run the command headless or not. + True, # seems to indicate whether to run the command headless or not "xml_bigstitcher_file", project_path, "output_path_directory", From 4700635fffcab107bc8d2357c05dbe46111da2c3 Mon Sep 17 00:00:00 2001 From: Niko Ehrenfeuchter Date: Fri, 16 Jan 2026 10:15:11 +0100 Subject: [PATCH 05/14] Update 'list_files' parameter documentation Use the Python function parameter name ('source_directory') instead of the parameter name used by the IJ macro. --- src/imcflibs/imagej/bdv.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/imcflibs/imagej/bdv.py b/src/imcflibs/imagej/bdv.py index 828c5d4f..d6c0a27a 100644 --- a/src/imcflibs/imagej/bdv.py +++ b/src/imcflibs/imagej/bdv.py @@ -921,14 +921,11 @@ def define_dataset_manual( definition_opts : dict Dictionary containing the details about the file repartitions. list_files : list of str, optional - If provided, a list of file names to pass directly to the manual - loader in "show_list" mode. When `list_files` is given the - function will include the filenames in the options string instead - of relying on a file pattern; items should be either basenames or - paths appropriate for the selected ``image_file_directory``. - + An optional list of file names to pass directly to the manual loader in + "show_list" mode. When provided, the function will include the filenames + in the options string instead of relying on a file pattern; items should + be either full paths or relative to the selected `source_directory`. """ - # xml_filename = project_filename + ".xml" if definition_opts is None: From 8137c3c263d90d001e40981fb5a36c23bb7eeadc Mon Sep 17 00:00:00 2001 From: Niko Ehrenfeuchter Date: Fri, 16 Jan 2026 10:43:44 +0100 Subject: [PATCH 06/14] Explain the 'p' in the function name --- src/imcflibs/imagej/bdv.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/imcflibs/imagej/bdv.py b/src/imcflibs/imagej/bdv.py index d6c0a27a..1370109d 100644 --- a/src/imcflibs/imagej/bdv.py +++ b/src/imcflibs/imagej/bdv.py @@ -1611,10 +1611,10 @@ def fuse_dataset_bdvp( z_ratio=1.0, use_interpolation=True, ): - """Export a BigDataViewer project using the BIOP Kheops exporter. + """Export a project using the BigDataViewer playground (`bdvp`) exporter. - Use BIOP Kheops exporter to fuse a BigDataViewer project and save - it as pyramidal OME-TIFF. + Use the BigDataViewer playground / BIOP Kheops exporter to fuse a + BigDataViewer project and save it as pyramidal OME-TIFF. Parameters ---------- From db65398104d459f5d1ec701f9cc1423d9f86c04a Mon Sep 17 00:00:00 2001 From: Niko Ehrenfeuchter Date: Fri, 16 Jan 2026 10:43:58 +0100 Subject: [PATCH 07/14] Fix syntax --- src/imcflibs/imagej/bdv.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/imcflibs/imagej/bdv.py b/src/imcflibs/imagej/bdv.py index 1370109d..451c230d 100644 --- a/src/imcflibs/imagej/bdv.py +++ b/src/imcflibs/imagej/bdv.py @@ -1623,10 +1623,10 @@ def fuse_dataset_bdvp( command : CommandService The Scijava CommandService instance to execute the export command. result_path : str, optional - Path where to store the exported files. If ``None``, files will be + Path where to store the exported files. If `None`, files will be saved in the same directory as the input project. fusion_method : str, optional - Fusion method to use for exporting (default ``"SMOOTH AVERAGE"``). + Fusion method to use for exporting (default `SMOOTH AVERAGE`). range_channels : str, optional Channels to include in the export. Default is all channels. range_slices : str, optional From a03a62ea29f75990798164b58fa6dd336e2a0293 Mon Sep 17 00:00:00 2001 From: Niko Ehrenfeuchter Date: Fri, 16 Jan 2026 10:44:23 +0100 Subject: [PATCH 08/14] Shorten descriptions, use imperative mood --- src/imcflibs/imagej/bdv.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/imcflibs/imagej/bdv.py b/src/imcflibs/imagej/bdv.py index 451c230d..5e3a4669 100644 --- a/src/imcflibs/imagej/bdv.py +++ b/src/imcflibs/imagej/bdv.py @@ -1636,24 +1636,23 @@ def fuse_dataset_bdvp( n_resolution_levels : int, optional Number of pyramid resolution levels to use for the export. Default is 5. use_lzw_compression : bool, optional - If True, compressed the output file using LZW. Default is True. + Compress the output file using LZW. Default is True. split_slices : bool, optional - If True, splits the output into separate files for each slice. Default is False. + Split output into separate files for each slice. Default is False. split_channels : bool, optional - If True, splits the output into separate files for each channel. Default is False. + Split output into separate files for each channel. Default is False. split_frames : bool, optional - If True, splits the output into separate files for each frame. Default is False. + Split output into separate files for each frame. Default is False. override_z_ratio : bool, optional - If True, overrides the default z_ratio value. Default is False. + Override the default `z_ratio` value. Default is False. z_ratio : float, optional The z ratio to use for the export. Default is 1.0. use_interpolation : bool, optional - If True, interpolates during fusion (takes ~4x longer). Default is True. + Interpolate during fusion (takes ~4x longer). Default is True. Notes ----- - This function requires the PTBIOP update site to be enabled in Fiji/ - ImageJ. + Requires the `PTBIOP` update site to be enabled in Fiji/ImageJ. Examples -------- From ee68e96884d0971df16d78357c592f63510f3061 Mon Sep 17 00:00:00 2001 From: Laurent Guerard Date: Mon, 19 Jan 2026 13:58:55 +0100 Subject: [PATCH 09/14] refactor(bdv): replace bdv class references with local definitions * Update `define_dataset_manual` to use local `DefinitionOptions`. * Update `resave_as_h5` to use local `ProcessingOptions`. --- src/imcflibs/imagej/bdv.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/imcflibs/imagej/bdv.py b/src/imcflibs/imagej/bdv.py index 5e3a4669..91e3afb6 100644 --- a/src/imcflibs/imagej/bdv.py +++ b/src/imcflibs/imagej/bdv.py @@ -929,7 +929,7 @@ def define_dataset_manual( # xml_filename = project_filename + ".xml" if definition_opts is None: - definition_opts = bdv.DefinitionOptions() + definition_opts = DefinitionOptions() show_list_options = "" if not list_files else "show_list " + " ".join(list_files) @@ -995,7 +995,7 @@ def resave_as_h5( """ if not processing_opts: - processing_opts = bdv.ProcessingOptions() + processing_opts = ProcessingOptions() if use_deflate_compression: use_deflate_compression_arg = "use_deflate_compression " From 6e7bdfe5ed75d36bc33b7454982f45dbc4f40ebd Mon Sep 17 00:00:00 2001 From: Laurent Guerard Date: Mon, 19 Jan 2026 14:03:02 +0100 Subject: [PATCH 10/14] docs(bdv): update usage examples for fuse_dataset_bdvp function - Added typical usage examples in doctest style - Included two examples demonstrating basic and explicit options --- src/imcflibs/imagej/bdv.py | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/imcflibs/imagej/bdv.py b/src/imcflibs/imagej/bdv.py index 91e3afb6..2da7af70 100644 --- a/src/imcflibs/imagej/bdv.py +++ b/src/imcflibs/imagej/bdv.py @@ -1656,7 +1656,35 @@ def fuse_dataset_bdvp( Examples -------- - fuse_dataset_bdvp(xml_input, cs) + Typical usage examples (doctest-style): + + Example 1 - basic export using a CommandService instance available as + ``command``:: + + >>> #@ CommandService command + >>> xml_input = "/path/to/project.xml" + >>> # run with default options, output placed next to the input xml + >>> fuse_dataset_bdvp(xml_input, command) + + Example 2 - explicit options (custom output path, specific channels, + no interpolation, override z ratio):: + + >>> #@ CommandService command + >>> xml_input = "/path/to/project.xml" + >>> out_dir = "/path/to/output_dir" + >>> fuse_dataset_bdvp( + ... xml_input, + ... command, + ... result_path=out_dir, + ... fusion_method="SMOOTH AVERAGE", + ... range_channels="0-1", + ... n_resolution_levels=4, + ... use_lzw_compression=False, + ... split_channels=True, + ... override_z_ratio=True, + ... z_ratio=2.0, + ... use_interpolation=False, + ... ) """ file_info = pathtools.parse_path(project_path) From 6308fbec454305a0950e9b12a04370f7872036dd Mon Sep 17 00:00:00 2001 From: Laurent Guerard Date: Mon, 19 Jan 2026 14:05:07 +0100 Subject: [PATCH 11/14] feat(pathtools): Refactor method in `pathtools` * Implement function to join filenames with channel suffixes. * Suitable for Bioformats/Jython in show_list mode. * Includes detailed docstring with parameters and return values. --- src/imcflibs/imagej/bdv.py | 43 -------------------------------------- src/imcflibs/pathtools.py | 43 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/imcflibs/imagej/bdv.py b/src/imcflibs/imagej/bdv.py index 2da7af70..99cbaf92 100644 --- a/src/imcflibs/imagej/bdv.py +++ b/src/imcflibs/imagej/bdv.py @@ -1724,46 +1724,3 @@ def fuse_dataset_bdvp( "use_interpolation", use_interpolation, ).get() - - -def join_files_with_channel_suffix(files, nchannels): - """Join filenames and append channel-suffixed copies. - - For each filename in ``files``, return a list where original filenames - appear first followed by copies with suffixes ``_0`` .. ``_{n-2}`` - (inserted before the file extension). This is suitable for passing - to Bioformats/Jython in ``show_list`` mode when each channel is stored - as a separate file. - - Parameters - ---------- - files : list or tuple - List or tuple of filename strings. - nchannels : int - Number of channels (>=1). If ``nchannels`` is 1 no suffixed copies - are added. - - Returns - ------- - list of str - Ordered list of filenames (originals then suffixed copies). - """ - import os - - if not files: - return "" - try: - x = range(int(nchannels) - 1) - except Exception: - x = [0] - suff = "_" + str(x) - out = [] - # keep original order, then add suffixed copies - for f in files: - out.append(f) - for i in x: - suff = "_" + str(i) - for f in files: - base, ext = os.path.splitext(f) - out.append(base + suff + ext) - return out diff --git a/src/imcflibs/pathtools.py b/src/imcflibs/pathtools.py index 166a5186..4b2daed9 100644 --- a/src/imcflibs/pathtools.py +++ b/src/imcflibs/pathtools.py @@ -385,3 +385,46 @@ def create_directory(new_path): exists = jython_fiji_exists else: exists = os.path.exists + + +def join_files_with_channel_suffix(files, nchannels): + """Join filenames and append channel-suffixed copies. + + For each filename in `files`, return a list where original filenames + appear first followed by copies with suffixes `_0` .. `_{n-2}` + (inserted before the file extension). This is suitable for passing + to Bioformats/Jython in ``show_list`` mode when each channel is stored + as a separate file. + + Parameters + ---------- + files : list or tuple + List or tuple of filename strings. + nchannels : int + Number of channels (>=1). If ``nchannels`` is 1 no suffixed copies + are added. + + Returns + ------- + list of str + Ordered list of filenames (originals then suffixed copies). + """ + import os + + if not files: + return "" + try: + x = range(int(nchannels) - 1) + except Exception: + x = [0] + suff = "_" + str(x) + out = [] + # Keep original order, then add suffixed copies + for f in files: + out.append(f) + for i in x: + suff = "_" + str(i) + for f in files: + base, ext = os.path.splitext(f) + out.append(base + suff + ext) + return out From a17e0a983033fd3aa9a516bb73c45d7f17fa9233 Mon Sep 17 00:00:00 2001 From: Laurent Guerard Date: Mon, 19 Jan 2026 14:05:42 +0100 Subject: [PATCH 12/14] chore(pathtools): remove redundant import of os in join_files_with_channel_suffix --- src/imcflibs/pathtools.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/imcflibs/pathtools.py b/src/imcflibs/pathtools.py index 4b2daed9..40fd5797 100644 --- a/src/imcflibs/pathtools.py +++ b/src/imcflibs/pathtools.py @@ -1,5 +1,6 @@ """Helper functions to work with filenames, directories etc.""" +import os import os.path import platform import re @@ -409,8 +410,6 @@ def join_files_with_channel_suffix(files, nchannels): list of str Ordered list of filenames (originals then suffixed copies). """ - import os - if not files: return "" try: From 451f84cc9f927bbb549f8932849e0f73cddf4fd2 Mon Sep 17 00:00:00 2001 From: Niko Ehrenfeuchter Date: Mon, 19 Jan 2026 15:19:09 +0100 Subject: [PATCH 13/14] Docstring syntax of usage examples --- src/imcflibs/imagej/bdv.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/imcflibs/imagej/bdv.py b/src/imcflibs/imagej/bdv.py index 99cbaf92..edef99bc 100644 --- a/src/imcflibs/imagej/bdv.py +++ b/src/imcflibs/imagej/bdv.py @@ -1656,18 +1656,17 @@ def fuse_dataset_bdvp( Examples -------- - Typical usage examples (doctest-style): - Example 1 - basic export using a CommandService instance available as - ``command``:: + Example 1 - simple export using a CommandService instance available as + `command`, using the default options and placing the output next to the + input xml: >>> #@ CommandService command >>> xml_input = "/path/to/project.xml" - >>> # run with default options, output placed next to the input xml >>> fuse_dataset_bdvp(xml_input, command) - Example 2 - explicit options (custom output path, specific channels, - no interpolation, override z ratio):: + Example 2 - explicit options using a custom output path, specific channels, + disabling interpolation and overriding the z-ratio: >>> #@ CommandService command >>> xml_input = "/path/to/project.xml" @@ -1686,7 +1685,6 @@ def fuse_dataset_bdvp( ... use_interpolation=False, ... ) """ - file_info = pathtools.parse_path(project_path) if not result_path: From 4ebc0244ec1419c6693f851680e1d51b643a69b7 Mon Sep 17 00:00:00 2001 From: Niko Ehrenfeuchter Date: Wed, 21 Jan 2026 11:14:00 +0100 Subject: [PATCH 14/14] Docstring fix for ruff D412 blank-lines-between-header-and-content --- src/imcflibs/imagej/bdv.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/imcflibs/imagej/bdv.py b/src/imcflibs/imagej/bdv.py index 607e83b4..f5f81e7e 100644 --- a/src/imcflibs/imagej/bdv.py +++ b/src/imcflibs/imagej/bdv.py @@ -1678,7 +1678,6 @@ def fuse_dataset_bdvp( Examples -------- - Example 1 - simple export using a CommandService instance available as `command`, using the default options and placing the output next to the input xml: