diff --git a/qim3d/io/convert.py b/qim3d/io/convert.py index 09694d7822f63cfc10a85bec9ca58cbb59ce6b40..6568965e896dbe096db4c02e2e9dfc0a14e092d2 100644 --- a/qim3d/io/convert.py +++ b/qim3d/io/convert.py @@ -22,6 +22,7 @@ class Convert: """ self.chunk_shape = kwargs.get("chunk_shape", (64, 64, 64)) self.base_name = kwargs.get("base_name", None) + self.contains = kwargs.get("contains", None) def convert(self, input_path, output_path): def get_file_extension(file_path): @@ -37,7 +38,10 @@ class Convert: output_ext = get_file_extension(output_path) output_path = stringify_path(output_path) - if os.path.isfile(input_path) and os.path.isfile(output_path): + print("sdf", os.path.isdir(input_path) , input_ext, output_ext) + + + if os.path.isfile(input_path) and output_ext: match input_ext, output_ext: case (".tif", ".zarr") | (".tiff", ".zarr"): return self.convert_tif_to_zarr(input_path, output_path) @@ -45,11 +49,6 @@ class Convert: return self.convert_nifti_to_zarr(input_path, output_path) case _: raise ValueError("Unsupported file format") - elif os.path.isfile(input_path) and os.path.isdir(output_path): - if input_ext == ".zarr" and not output_ext: - return self.convert_zarr_to_tiff_stack(input_path, output_path) - else: - raise ValueError("Unsupported file format") # Load a directory elif os.path.isdir(input_path): match input_ext, output_ext: @@ -59,13 +58,14 @@ class Convert: return self.convert_zarr_to_nifti(input_path, output_path) case (".zarr", ".nii.gz"): return self.convert_zarr_to_nifti(input_path, output_path, compression=True) + case (".zarr", ""): + print("1") + self.convert_zarr_to_tiff_stack(input_path, output_path) + case ("", ".zarr"): + print("2") + return self.convert_tiff_stack_to_zarr(input_path, output_path) case _: raise ValueError("Unsupported file format") - elif os.path.isdir(input_path) and os.path.isfile(output_path): - if not input_ext and output_ext == ".zarr": - return self.convert_tiff_stack_to_zarr(input_path, output_path) - else: - raise ValueError("Unsupported file format") # Fail else: # Find the closest matching path to warn the user @@ -75,7 +75,7 @@ class Convert: similar_paths = difflib.get_close_matches(input_path, valid_paths) if similar_paths: suggestion = similar_paths[0] # Get the closest match - message = f"Invalid path. Did you mean '{suggestion}'?" + message = f"Invalid path '{input_path}'. Did you mean '{suggestion}'?" raise ValueError(repr(message)) else: raise ValueError("Invalid path") @@ -141,7 +141,7 @@ class Convert: zarr.core.Array: zarr array containing the data from the tiff stack """ # ! tiff stack memmap is stored as slices on disk and not as a single file, making assignments to blocks slow. - vol = load(tiff_stack_path, virtual_stack=True) + vol = load(tiff_stack_path, virtual_stack=True, contains=self.contains) return self._save_zarr(zarr_path, vol) def convert_zarr_to_tiff_stack(self, zarr_path, tiff_stack_path): @@ -184,7 +184,11 @@ class Convert: save(nifti_path, z, compression=compression) -def convert(input_path: str, output_path: str, chunk_shape: tuple = (64, 64, 64), base_name: str = None): +def convert(input_path: str, + output_path: str, + chunk_shape: tuple = (64, 64, 64), + base_name: str = None, + contains: str = None): """Convert a file to another format without loading the entire file into memory Args: @@ -193,5 +197,7 @@ def convert(input_path: str, output_path: str, chunk_shape: tuple = (64, 64, 64) chunk_shape (tuple, optional): chunk size for the zarr file. Defaults to (64, 64, 64). base_name (str, optional): base name for the tiff stack. Defaults to None. """ - converter = Convert(chunk_shape=chunk_shape,base_name=base_name) + converter = Convert(chunk_shape=chunk_shape, + base_name=base_name, + contains=contains) converter.convert(input_path, output_path) diff --git a/qim3d/io/saving.py b/qim3d/io/saving.py index b163c3126705962e0c437a50a86aeb28ed043254..f5b62b939c28e07668ec2243c257ad6d93a65cba 100644 --- a/qim3d/io/saving.py +++ b/qim3d/io/saving.py @@ -34,11 +34,13 @@ import tifffile import zarr from pydicom.dataset import FileDataset, FileMetaDataset from pydicom.uid import UID +from tqdm import tqdm from qim3d.io.logger import log from qim3d.utils.internal_tools import sizeof, stringify_path + class DataSaver: """Utility class for saving data to different file formats. @@ -111,7 +113,7 @@ class DataSaver: idx = [slice(None)] * data.ndim # Iterate through each slice and save - for i in range(no_slices): + for i in tqdm(range(no_slices)): idx[self.sliced_dim] = i sliced = data[tuple(idx)] filename = self.basename + str(i).zfill(zfill_val) + extension diff --git a/qim3d/utils/cli.py b/qim3d/utils/cli.py index c22d6b134095b604da8df073fd70aa5b2ff373f3..d99e781b4a7126097c0f69be1642bd5b35bf3873 100644 --- a/qim3d/utils/cli.py +++ b/qim3d/utils/cli.py @@ -84,8 +84,9 @@ def main(): preview_parser = subparsers.add_parser('convert', help= 'Convert files to different formats without loading the entire file into memory') preview_parser.add_argument('input_path',type = str, metavar = 'Input path', help = 'Path to image that will be converted') preview_parser.add_argument('output_path',type = str, metavar = 'Output path', help = 'Path to save converted image') - preview_parser.add_argument('chunk_shape',type = tuple, metavar = 'Chunk shape', help = 'Chunk size for the zarr file', default = (64,64,64)) - preview_parser.add_argument('base_name',type = str, metavar = 'Base name', help = 'Base name for the zarr file', default = None) + preview_parser.add_argument('--chunk_shape',type = tuple, metavar = 'Chunk shape', help = 'Chunk size for the zarr file', default = (64,64,64)) + preview_parser.add_argument('--base_name',type = str, metavar = 'Base name', help = 'Base name for the zarr file', default = None) + preview_parser.add_argument('--contains',type = str, metavar = 'Contains', help = 'Part of the name that is common for the TIFF file stack', default = None) args = parser.parse_args() @@ -144,7 +145,14 @@ def main(): slice=args.slice, relative_intensity=args.absolute_values, ) - + + elif args.subcommand == 'convert': + qim3d.io.convert(args.input_path, + args.output_path, + args.chunk_shape, + args.base_name, + args.contains) + elif args.subcommand is None: welcome_text = ( "\n" @@ -172,8 +180,7 @@ def main(): parser.print_help() print("\n") - elif args.subcommand == 'convert': - qim3d.io.convert(args.input_path, args.output_path, args.chunk_shape, args.base_name) + if __name__ == "__main__":