From db95b17151a0c8afc5d75191b8d121064638f446 Mon Sep 17 00:00:00 2001 From: s214735 <s214735@dtu.dk> Date: Fri, 27 Dec 2024 11:13:22 +0100 Subject: [PATCH] Checked docstrings for minor errors w main focus on example code --- qim3d/detection/_common_detection_methods.py | 7 ++-- qim3d/features/_common_features_methods.py | 28 ++++++++-------- qim3d/filters/_common_filter_methods.py | 8 ++--- qim3d/generate/_aggregators.py | 20 ++++++------ qim3d/generate/_generators.py | 24 +++++++------- qim3d/gui/data_explorer.py | 2 +- qim3d/io/_convert.py | 1 - qim3d/io/_downloader.py | 2 +- qim3d/io/_loading.py | 4 +++ qim3d/io/_saving.py | 16 +++++----- qim3d/mesh/_common_mesh_methods.py | 4 +-- qim3d/ml/_ml_utils.py | 12 ++++--- qim3d/ml/models/_unet.py | 4 +-- .../operations/_common_operations_methods.py | 13 ++++---- qim3d/processing/_layers.py | 2 +- qim3d/processing/_local_thickness.py | 2 +- .../_common_segmentation_methods.py | 10 +++--- qim3d/segmentation/_connected_components.py | 2 +- qim3d/utils/__init__.py | 2 +- qim3d/utils/_doi.py | 5 +-- qim3d/utils/_misc.py | 5 +-- qim3d/viz/_cc.py | 24 +++++++------- qim3d/viz/_data_exploration.py | 13 +++++--- qim3d/viz/_detection.py | 32 ++++++++++++++++--- qim3d/viz/_k3d.py | 5 ++- qim3d/viz/_local_thickness.py | 2 +- qim3d/viz/_metrics.py | 5 +-- 27 files changed, 145 insertions(+), 109 deletions(-) diff --git a/qim3d/detection/_common_detection_methods.py b/qim3d/detection/_common_detection_methods.py index 131ec1e4..9ed48334 100644 --- a/qim3d/detection/_common_detection_methods.py +++ b/qim3d/detection/_common_detection_methods.py @@ -37,13 +37,14 @@ def blobs( Example: ```python import qim3d + import qim3d.detection # Get data vol = qim3d.examples.cement_128x128x128 - vol_blurred = qim3d.processing.gaussian(vol, sigma=2) + vol_blurred = qim3d.filters.gaussian(vol, sigma=2) # Detect blobs, and get binary mask - blobs, mask = qim3d.processing.blob_detection( + blobs, mask = qim3d.detection.blobs( vol_blurred, min_sigma=1, max_sigma=8, @@ -55,7 +56,7 @@ def blobs( # Visualize detected blobs qim3d.viz.circles(blobs, vol, alpha=0.8, color='blue') ``` -  +  ```python # Visualize binary mask diff --git a/qim3d/features/_common_features_methods.py b/qim3d/features/_common_features_methods.py index 63838ef1..574d8b89 100644 --- a/qim3d/features/_common_features_methods.py +++ b/qim3d/features/_common_features_methods.py @@ -27,8 +27,8 @@ def volume(obj: np.ndarray|trimesh.Trimesh, mesh = qim3d.io.load_mesh('path/to/mesh.obj') # Compute the volume of the mesh - volume = qim3d.processing.volume(mesh) - print('Volume:', volume) + vol = qim3d.features.volume(mesh) + print('Volume:', vol) ``` Compute volume from a np.ndarray: @@ -36,10 +36,10 @@ def volume(obj: np.ndarray|trimesh.Trimesh, import qim3d # Generate a 3D blob - synthetic_blob = qim3d.generate.blob(noise_scale = 0.015) + synthetic_blob = qim3d.generate.noise_object(noise_scale = 0.015) # Compute the volume of the blob - volume = qim3d.processing.volume(synthetic_blob, level=0.5) + volume = qim3d.features.volume(synthetic_blob, level=0.5) print('Volume:', volume) ``` @@ -73,7 +73,7 @@ def area(obj: np.ndarray|trimesh.Trimesh, mesh = qim3d.io.load_mesh('path/to/mesh.obj') # Compute the surface area of the mesh - area = qim3d.processing.area(mesh) + area = qim3d.features.area(mesh) print(f"Area: {area}") ``` @@ -82,16 +82,16 @@ def area(obj: np.ndarray|trimesh.Trimesh, import qim3d # Generate a 3D blob - synthetic_blob = qim3d.generate.blob(noise_scale = 0.015) + synthetic_blob = qim3d.generate.noise_object(noise_scale = 0.015) # Compute the surface area of the blob - volume = qim3d.processing.area(synthetic_blob, level=0.5) + volume = qim3d.features.area(synthetic_blob, level=0.5) print('Area:', volume) ``` """ if isinstance(obj, np.ndarray): log.info("Converting volume to mesh.") - obj = qim3d.processing.create_mesh(obj, **mesh_kwargs) + obj = qim3d.mesh.from_volume(obj, **mesh_kwargs) return obj.area @@ -122,7 +122,7 @@ def sphericity(obj: np.ndarray|trimesh.Trimesh, mesh = qim3d.io.load_mesh('path/to/mesh.obj') # Compute the sphericity of the mesh - sphericity = qim3d.processing.sphericity(mesh) + sphericity = qim3d.features.sphericity(mesh) ``` Compute sphericity from a np.ndarray: @@ -130,10 +130,10 @@ def sphericity(obj: np.ndarray|trimesh.Trimesh, import qim3d # Generate a 3D blob - synthetic_blob = qim3d.generate.blob(noise_scale = 0.015) + synthetic_blob = qim3d.generate.noise_object(noise_scale = 0.015) # Compute the sphericity of the blob - sphericity = qim3d.processing.sphericity(synthetic_blob, level=0.5) + sphericity = qim3d.features.sphericity(synthetic_blob, level=0.5) ``` !!! info "Limitations due to pixelation" @@ -143,10 +143,10 @@ def sphericity(obj: np.ndarray|trimesh.Trimesh, """ if isinstance(obj, np.ndarray): log.info("Converting volume to mesh.") - obj = qim3d.processing.create_mesh(obj, **mesh_kwargs) + obj = qim3d.mesh.from_volume(obj, **mesh_kwargs) - volume = qim3d.processing.volume(obj) - area = qim3d.processing.area(obj) + volume = qim3d.features.volume(obj) + area = qim3d.features.area(obj) if area == 0: log.warning("Surface area is zero, sphericity is undefined.") diff --git a/qim3d/filters/_common_filter_methods.py b/qim3d/filters/_common_filter_methods.py index 59b0be12..ddd663fa 100644 --- a/qim3d/filters/_common_filter_methods.py +++ b/qim3d/filters/_common_filter_methods.py @@ -116,13 +116,13 @@ class Pipeline: Example: ```python import qim3d - from qim3d.processing import Pipeline, Median, Gaussian, Maximum, Minimum + from qim3d.filters import Pipeline, Median, Gaussian, Maximum, Minimum # Get data vol = qim3d.examples.fly_150x256x256 # Show original - qim3d.viz.slices_grid(vol, axis=0, show=True) + fig1 = qim3d.viz.slices_grid(vol, num_slices=5, display_figure=True) # Create filter pipeline pipeline = Pipeline( @@ -137,7 +137,7 @@ class Pipeline: vol_filtered = pipeline(vol) # Show filtered - qim3d.viz.slices_grid(vol_filtered, axis=0) + fig2 = qim3d.viz.slices_grid(vol_filtered, num_slices=5, display_figure=True) ```   @@ -185,7 +185,7 @@ class Pipeline: Example: ```python import qim3d - from qim3d.processing import Pipeline, Maximum, Median + from qim3d.filters import Pipeline, Maximum, Median # Create filter pipeline pipeline = Pipeline( diff --git a/qim3d/generate/_aggregators.py b/qim3d/generate/_aggregators.py index 262b047e..5635e6c3 100644 --- a/qim3d/generate/_aggregators.py +++ b/qim3d/generate/_aggregators.py @@ -189,10 +189,10 @@ def noise_object_collection( # Generate synthetic collection of objects num_objects = 15 - synthetic_collection, labels = qim3d.generate.collection(num_objects = num_objects) + synthetic_collection, labels = qim3d.generate.noise_object_collection(num_objects = num_objects) # Visualize synthetic collection - qim3d.viz.vol(synthetic_collection) + qim3d.viz.volumetric(synthetic_collection) ``` <iframe src="https://platform.qim.dk/k3d/synthetic_collection_default.html" width="100%" height="500" frameborder="0"></iframe> @@ -203,8 +203,8 @@ def noise_object_collection( ```python # Visualize labels - cmap = qim3d.viz.colormaps.objects(nlabels=num_objects) - qim3d.viz.slicer(labels, cmap=cmap, vmax=num_objects) + cmap = qim3d.viz.colormaps.segmentation(num_labels=num_objects) + qim3d.viz.slicer(labels, color_map=cmap, value_max=num_objects) ```  @@ -233,7 +233,7 @@ def noise_object_collection( import qim3d # Generate synthetic collection of cylindrical structures - vol, labels = qim3d.generate.collection(num_objects = 40, + vol, labels = qim3d.generate.noise_object_collection(num_objects = 40, collection_shape = (300, 150, 150), min_shape = (280, 10, 10), max_shape = (290, 15, 15), @@ -248,14 +248,14 @@ def noise_object_collection( ) # Visualize synthetic collection - qim3d.viz.vol(vol) + qim3d.viz.volumetric(vol) ``` <iframe src="https://platform.qim.dk/k3d/synthetic_collection_cylinder.html" width="100%" height="500" frameborder="0"></iframe> ```python # Visualize slices - qim3d.viz.slices_grid(vol, n_slices=15) + qim3d.viz.slices_grid(vol, num_slices=15) ```  @@ -264,7 +264,7 @@ def noise_object_collection( import qim3d # Generate synthetic collection of tubular (hollow) structures - vol, labels = qim3d.generate.collection(num_objects = 10, + vol, labels = qim3d.generate.noise_object_collection(num_objects = 10, collection_shape = (200, 200, 200), min_shape = (180, 25, 25), max_shape = (190, 35, 35), @@ -279,13 +279,13 @@ def noise_object_collection( ) # Visualize synthetic collection - qim3d.viz.vol(vol) + qim3d.viz.volumetric(vol) ``` <iframe src="https://platform.qim.dk/k3d/synthetic_collection_tube.html" width="100%" height="500" frameborder="0"></iframe> ```python # Visualize slices - qim3d.viz.slices_grid(vol, n_slices=15, axis=1) + qim3d.viz.slices_grid(vol, num_slices=15, slice_axis=1) ```  """ diff --git a/qim3d/generate/_generators.py b/qim3d/generate/_generators.py index 78bf607b..5cab885d 100644 --- a/qim3d/generate/_generators.py +++ b/qim3d/generate/_generators.py @@ -43,16 +43,16 @@ def noise_object( import qim3d # Generate synthetic blob - synthetic_blob = qim3d.generate.blob(noise_scale = 0.015) + synthetic_blob = qim3d.generate.noise_object(noise_scale = 0.015) # Visualize 3D volume - qim3d.viz.vol(synthetic_blob) + qim3d.viz.volumetric(synthetic_blob) ``` <iframe src="https://platform.qim.dk/k3d/synthetic_blob.html" width="100%" height="500" frameborder="0"></iframe> ```python # Visualize slices - qim3d.viz.slices_grid(synthetic_blob, vmin = 0, vmax = 255, n_slices = 15) + qim3d.viz.slices_grid(synthetic_blob, value_min = 0, value_max = 255, num_slices = 15) ```  @@ -61,7 +61,7 @@ def noise_object( import qim3d # Generate tubular synthetic blob - vol = qim3d.generate.blob(base_shape = (10, 300, 300), + vol = qim3d.generate.noise_object(base_shape = (10, 300, 300), final_shape = (100, 100, 100), noise_scale = 0.3, gamma = 2, @@ -70,13 +70,13 @@ def noise_object( ) # Visualize synthetic object - qim3d.viz.vol(vol) + qim3d.viz.volumetric(vol) ``` <iframe src="https://platform.qim.dk/k3d/synthetic_blob_cylinder.html" width="100%" height="500" frameborder="0"></iframe> ```python # Visualize slices - qim3d.viz.slices_grid(vol, n_slices=15, axis=1) + qim3d.viz.slices_grid(vol, num_slices=15, slice_axis=1) ```  @@ -85,7 +85,7 @@ def noise_object( import qim3d # Generate tubular synthetic blob - vol = qim3d.generate.blob(base_shape = (200, 100, 100), + vol = qim3d.generate.noise_object(base_shape = (200, 100, 100), final_shape = (400, 100, 100), noise_scale = 0.03, gamma = 0.12, @@ -94,13 +94,13 @@ def noise_object( ) # Visualize synthetic blob - qim3d.viz.vol(vol) + qim3d.viz.volumetric(vol) ``` <iframe src="https://platform.qim.dk/k3d/synthetic_blob_tube.html" width="100%" height="500" frameborder="0"></iframe> ```python # Visualize - qim3d.viz.slices_grid(vol, n_slices=15) + qim3d.viz.slices_grid(vol, num_slices=15) ```  """ @@ -178,7 +178,7 @@ def noise_object( axis = np.argmax(volume.shape) # Fade along the dimension where the object is the largest target_max_normalized_distance = 1.4 # This value ensures that the object will become cylindrical - volume = qim3d.processing.operations.fade_mask(volume, + volume = qim3d.operations.fade_mask(volume, geometry = geometry, axis = axis, target_max_normalized_distance = target_max_normalized_distance @@ -193,7 +193,7 @@ def noise_object( target_max_normalized_distance = 1.4 # This value ensures that the object will become cylindrical # Fade once for making the object cylindrical - volume = qim3d.processing.operations.fade_mask(volume, + volume = qim3d.operations.fade_mask(volume, geometry = geometry, axis = axis, decay_rate = decay_rate, @@ -202,7 +202,7 @@ def noise_object( ) # Fade again with invert = True for making the object a tube (i.e. with a hole in the middle) - volume = qim3d.processing.operations.fade_mask(volume, + volume = qim3d.operations.fade_mask(volume, geometry = geometry, axis = axis, decay_rate = decay_rate, diff --git a/qim3d/gui/data_explorer.py b/qim3d/gui/data_explorer.py index ee3ba16d..fb800ab2 100644 --- a/qim3d/gui/data_explorer.py +++ b/qim3d/gui/data_explorer.py @@ -43,9 +43,9 @@ class Interface(BaseInterface): """ Parameters: ----------- - show_header (bool, optional): If true, prints starting info into terminal. Default is False verbose (bool, optional): If true, prints info during session into terminal. Defualt is False. figsize (int, optional): Sets the size of plots displaying the slices. Default is 8. + display_saturation_percentile (int, optional): Sets the display saturation percentile. Defaults to 99. """ super().__init__( title = "Data Explorer", diff --git a/qim3d/io/_convert.py b/qim3d/io/_convert.py index 0d776822..02614358 100644 --- a/qim3d/io/_convert.py +++ b/qim3d/io/_convert.py @@ -74,7 +74,6 @@ class Convert: Args: tif_path (str): path to the tiff file zarr_path (str): path to the zarr file - chunks (tuple, optional): chunk size for the zarr file. Defaults to (64, 64, 64). Returns: zarr.core.Array: zarr array containing the data from the tiff file diff --git a/qim3d/io/_downloader.py b/qim3d/io/_downloader.py index 18e36ca5..1dff4f11 100644 --- a/qim3d/io/_downloader.py +++ b/qim3d/io/_downloader.py @@ -52,7 +52,7 @@ class Downloader: downloader = qim3d.io.Downloader() data = downloader.Cowry_Shell.Cowry_DOWNSAMPLED(load_file=True) - qim3d.viz.orthogonal(data, cmap = "magma") + qim3d.viz.slicer_orthogonal(data, color_map="magma") ```  """ diff --git a/qim3d/io/_loading.py b/qim3d/io/_loading.py index e3d7d45b..2eb2c773 100644 --- a/qim3d/io/_loading.py +++ b/qim3d/io/_loading.py @@ -570,6 +570,10 @@ class DataLoader: Args: path (str): Directory path + + returns: + numpy.ndarray, numpy.memmap or tuple: The loaded volume. + If 'self.return_metadata' is True, returns a tuple (volume, metadata). """ import pydicom diff --git a/qim3d/io/_saving.py b/qim3d/io/_saving.py index a7053c00..eb6c39e5 100644 --- a/qim3d/io/_saving.py +++ b/qim3d/io/_saving.py @@ -7,7 +7,7 @@ Example: import qim3d # Generate synthetic blob - synthetic_blob = qim3d.generate.blob(noise_scale = 0.015) + synthetic_blob = qim3d.generate.noise_object(noise_scale = 0.015) qim3d.io.save("fly.tif", synthetic_blob) ``` @@ -17,7 +17,7 @@ Example: import qim3d # Generate synthetic blob - synthetic_blob = qim3d.generate.blob(noise_scale = 0.015) + synthetic_blob = qim3d.generate.noise_object(noise_scale = 0.015) qim3d.io.save("slices", synthetic_blob, basename="fly-slices", sliced_dim=0) ``` @@ -438,9 +438,9 @@ def save( import qim3d # Generate synthetic blob - synthetic_blob = qim3d.generate.blob(noise_scale = 0.015) + vol = qim3d.generate.noise_object(noise_scale = 0.015) - qim3d.io.save("blob.tif", synthetic_blob, replace=True) + qim3d.io.save("blob.tif", vol, replace=True) ``` Volumes can also be saved with one file per slice: @@ -448,9 +448,9 @@ def save( import qim3d # Generate synthetic blob - synthetic_blob = qim3d.generate.blob(noise_scale = 0.015) + vol = qim3d.generate.noise_object(noise_scale = 0.015) - qim3d.io.save("slices", synthetic_blob, basename="blob-slices", sliced_dim=0) + qim3d.io.save("slices", vol, basename="blob-slices", sliced_dim=0) ``` """ @@ -479,14 +479,14 @@ def save_mesh( ```python import qim3d - vol = qim3d.generate.blob(base_shape=(32, 32, 32), + vol = qim3d.generate.noise_object(base_shape=(32, 32, 32), final_shape=(32, 32, 32), noise_scale=0.05, order=1, gamma=1.0, max_value=255, threshold=0.5) - mesh = qim3d.processing.create_mesh(vol) + mesh = qim3d.mesh.from_volume(vol) qim3d.io.save_mesh("mesh.obj", mesh) ``` """ diff --git a/qim3d/mesh/_common_mesh_methods.py b/qim3d/mesh/_common_mesh_methods.py index 87cb9d8b..d6f184dc 100644 --- a/qim3d/mesh/_common_mesh_methods.py +++ b/qim3d/mesh/_common_mesh_methods.py @@ -31,7 +31,7 @@ def from_volume( Example: ```python import qim3d - vol = qim3d.generate.blob(base_shape=(128,128,128), + vol = qim3d.generate.noise_object(base_shape=(128,128,128), final_shape=(128,128,128), noise_scale=0.03, order=1, @@ -40,7 +40,7 @@ def from_volume( threshold=0.5, dtype='uint8' ) - mesh = qim3d.processing.create_mesh(vol, step_size=3) + mesh = qim3d.mesh.from_volume(vol, step_size=3) qim3d.viz.mesh(mesh.vertices, mesh.faces) ``` <iframe src="https://platform.qim.dk/k3d/mesh_visualization.html" width="100%" height="500" frameborder="0"></iframe> diff --git a/qim3d/ml/_ml_utils.py b/qim3d/ml/_ml_utils.py index f46a7481..59309266 100644 --- a/qim3d/ml/_ml_utils.py +++ b/qim3d/ml/_ml_utils.py @@ -40,18 +40,21 @@ def train_model( val_loss (dict): Dictionary with average losses and batch losses for validation loop. Example: + import qim3d + from qim3d.ml import train_model + # defining the model. - model = qim3d.utils.UNet() + model = qim3d.ml.UNet() # choosing the hyperparameters - hyperparameters = qim3d.utils.hyperparameters(model) + hyperparameters = qim3d.ml.models.Hyperparameters(model) # DataLoaders train_loader = MyTrainLoader() val_loader = MyValLoader() # training the model. - train_loss,val_loss = train_model(model, hyperparameters, train_loader, val_loader) + train_loss,val_loss = qim3d.ml.train_model(model, hyperparameters, train_loader, val_loader) """ params_dict = hyperparameters() n_epochs = params_dict["n_epochs"] @@ -186,9 +189,10 @@ def inference(data: torch.utils.data.Dataset, model: torch.nn.Module) -> tuple[t - The function does not assume the model is already in evaluation mode (model.eval()). Example: + import qim3d dataset = MySegmentationDataset() model = MySegmentationModel() - inference(data,model) + qim3d.ml.inference(data,model) """ # Get device diff --git a/qim3d/ml/models/_unet.py b/qim3d/ml/models/_unet.py index 27ee78a4..f27f7410 100644 --- a/qim3d/ml/models/_unet.py +++ b/qim3d/ml/models/_unet.py @@ -104,10 +104,10 @@ class Hyperparameters: # This examples shows how to define a UNet model and its hyperparameters. # Defining the model - my_model = qim3d.models.UNet(size='medium') + my_model = qim3d.ml.UNet(size='medium') # Choosing the hyperparameters - hyperparams = qim3d.models.Hyperparameters(model=my_model, n_epochs=20, learning_rate=0.001) + hyperparams = qim3d.ml.Hyperparameters(model=my_model, n_epochs=20, learning_rate=0.001) params_dict = hyperparams() # Get the hyperparameters optimizer = params_dict['optimizer'] diff --git a/qim3d/operations/_common_operations_methods.py b/qim3d/operations/_common_operations_methods.py index 5975c30e..680f2d1d 100644 --- a/qim3d/operations/_common_operations_methods.py +++ b/qim3d/operations/_common_operations_methods.py @@ -30,15 +30,15 @@ def remove_background( import qim3d vol = qim3d.examples.cement_128x128x128 - qim3d.viz.slices_grid(vol, vmin=0, vmax=255) + fig1 = qim3d.viz.slices_grid(vol, value_min=0, value_max=255, num_slices=5, display_figure=True) ```  ```python - vol_filtered = qim3d.processing.operations.remove_background(vol, + vol_filtered = qim3d.operations.remove_background(vol, min_object_radius=3, background="bright") - qim3d.viz.slices_grid(vol_filtered, vmin=0, vmax=255) + fig2 = qim3d.viz.slices_grid(vol_filtered, value_min=0, value_max=255, num_slices=5, display_figure=True) ```  """ @@ -81,15 +81,16 @@ def fade_mask( Example: ```python import qim3d - qim3d.viz.vol(vol) + vol = qim3d.io.load('yourVolume.tif') + qim3d.viz.volumetric(vol) ``` Image before edge fading has visible artifacts from the support. Which obscures the object of interest.  ```python import qim3d - vol_faded = qim3d.processing.operations.edge_fade(vol, decay_rate=4, ratio=0.45, geometric='cylindrical') - qim3d.viz.vol(vol_faded) + vol_faded = qim3d.operations.fade_mask(vol, decay_rate=4, ratio=0.45, geometric='cylindrical') + qim3d.viz.volumetrics(vol_faded) ``` Afterwards the artifacts are faded out, making the object of interest more visible for visualization purposes.  diff --git a/qim3d/processing/_layers.py b/qim3d/processing/_layers.py index 306a1284..65fdbbd6 100644 --- a/qim3d/processing/_layers.py +++ b/qim3d/processing/_layers.py @@ -40,7 +40,7 @@ def segment_layers(data: np.ndarray, layers = qim3d.processing.segment_layers(layers_image, n_layers = 2) layer_lines = qim3d.processing.get_lines(layers) - from matplotlib import pyplot as plt + import matplotlib.pyplot as plt plt.imshow(layers_image, cmap='gray') plt.axis('off') diff --git a/qim3d/processing/_local_thickness.py b/qim3d/processing/_local_thickness.py index 947f8865..5396fedb 100644 --- a/qim3d/processing/_local_thickness.py +++ b/qim3d/processing/_local_thickness.py @@ -50,7 +50,7 @@ def local_thickness( # Generate synthetic collection of blobs num_objects = 15 - synthetic_collection, labels = qim3d.generate.collection(num_objects = num_objects) + synthetic_collection, labels = qim3d.generate.noise_object_collection(num_objects = num_objects) # Extract one slice to show that localthickness works on 2D slices too slice = synthetic_collection[:,:,50] diff --git a/qim3d/segmentation/_common_segmentation_methods.py b/qim3d/segmentation/_common_segmentation_methods.py index ba4f231d..979ab6fd 100644 --- a/qim3d/segmentation/_common_segmentation_methods.py +++ b/qim3d/segmentation/_common_segmentation_methods.py @@ -24,17 +24,17 @@ def watershed(bin_vol: np.ndarray, min_distance: int = 5) -> tuple[np.ndarray, i import qim3d vol = qim3d.examples.cement_128x128x128 - binary = qim3d.processing.filters.gaussian(vol, sigma = 2)<60 + bin_vol = qim3d.filters.gaussian(vol, sigma = 2)<60 - qim3d.viz.slices_grid(binary, axis=1) + fig1 = qim3d.viz.slices_grid(bin_vol, slice_axis=1, display_figure=True) ```  ```python - labeled_volume, num_labels = qim3d.processing.operations.watershed(binary) + labeled_volume, num_labels = qim3d.segmentation.watershed(bin_vol) - cmap = qim3d.viz.colormaps.objects(num_labels) - qim3d.viz.slices_grid(labeled_volume, axis = 1, cmap = cmap) + cmap = qim3d.viz.colormaps.segmentation(num_labels) + fig2 = qim3d.viz.slices_grid(labeled_volume, slice_axis=1, color_map=cmap, display_figure=True) ```  diff --git a/qim3d/segmentation/_connected_components.py b/qim3d/segmentation/_connected_components.py index 45725fee..190266d4 100644 --- a/qim3d/segmentation/_connected_components.py +++ b/qim3d/segmentation/_connected_components.py @@ -83,7 +83,7 @@ def get_3d_cc(image: np.ndarray) -> CC: ```python import qim3d vol = qim3d.examples.cement_128x128x128[50:150]<60 - cc = qim3d.processing.get_3d_cc(vol) + cc = qim3d.segmentation.get_3d_cc(vol) ``` """ connected_components, num_connected_components = label(image) diff --git a/qim3d/utils/__init__.py b/qim3d/utils/__init__.py index 0c7d5b30..c996bbb6 100644 --- a/qim3d/utils/__init__.py +++ b/qim3d/utils/__init__.py @@ -1,4 +1,4 @@ -from . import _doi +from ._doi import * from ._system import Memory from ._misc import ( diff --git a/qim3d/utils/_doi.py b/qim3d/utils/_doi.py index 02095f33..1859ed53 100644 --- a/qim3d/utils/_doi.py +++ b/qim3d/utils/_doi.py @@ -59,10 +59,11 @@ def get_bibtex(doi: str): def custom_header(doi: str, header: str) -> str: """Allows a custom header to be passed - For example: + Example: + import qim3d doi = "https://doi.org/10.1101/2022.11.08.515664" header = {"Accept": "text/bibliography"} - response = qim3d.utils.doi.cusom_header(doi, header) + custom_header = qim3d.utils.custom_header(doi, header) """ return _log_and_get_text(doi, header) diff --git a/qim3d/utils/_misc.py b/qim3d/utils/_misc.py index 3d8660b4..8ccc2258 100644 --- a/qim3d/utils/_misc.py +++ b/qim3d/utils/_misc.py @@ -119,9 +119,10 @@ def sizeof(num: float, suffix: str = "B") -> str: Example: - >>> sizeof(1024) + >>> import qim3d + >>> qim3d.utils.sizeof(1024) '1.0 KB' - >>> sizeof(1234567890) + >>> qim3d.utils.sizeof(1234567890) '1.1 GB' """ for unit in ["", "K", "M", "G", "T", "P", "E", "Z"]: diff --git a/qim3d/viz/_cc.py b/qim3d/viz/_cc.py index 083b53cb..875980be 100644 --- a/qim3d/viz/_cc.py +++ b/qim3d/viz/_cc.py @@ -25,23 +25,23 @@ def plot_cc( max_cc_to_plot (int, optional): The maximum number of connected components to plot. Defaults to 32. overlay (optional): Overlay image. Defaults to None. crop (bool, optional): Whether to crop the image to the cc. Defaults to False. - show (bool, optional): Whether to show the figure. Defaults to True. - cmap (str, optional): Specifies the color map for the image. Defaults to "viridis". - vmin (float, optional): Together with vmax define the data range the colormap covers. By default colormap covers the full range. Defaults to None. - vmax (float, optional): Together with vmin define the data range the colormap covers. By default colormap covers the full range. Defaults to None + display_figure (bool, optional): Whether to show the figure. Defaults to True. + color_map (str, optional): Specifies the color map for the image. Defaults to "viridis". + value_min (float, optional): Together with vmax define the data range the colormap covers. By default colormap covers the full range. Defaults to None. + value_max (float, optional): Together with vmin define the data range the colormap covers. By default colormap covers the full range. Defaults to None **kwargs: Additional keyword arguments to pass to `qim3d.viz.slices_grid`. Returns: - figs (list[plt.Figure]): List of figures, if `show=False`. + figs (list[plt.Figure]): List of figures, if `display_figure=False`. Example: ```python import qim3d vol = qim3d.examples.cement_128x128x128[50:150] vol_bin = vol<80 - cc = qim3d.processing.get_3d_cc(vol_bin) - qim3d.viz.plot_cc(cc, crop=True, show=True, overlay=None, n_slices=5, component_indexs=[4,6,7]) - qim3d.viz.plot_cc(cc, crop=True, show=True, overlay=vol, n_slices=5, component_indexs=[4,6,7]) + cc = qim3d.segmentation.get_3d_cc(vol_bin) + qim3d.viz.plot_cc(cc, crop=True, display_figure=True, overlay=None, num_slices=5, component_indexs=[4,6,7]) + qim3d.viz.plot_cc(cc, crop=True, display_figure=True, overlay=vol, num_slices=5, component_indexs=[4,6,7]) ```   @@ -79,17 +79,17 @@ def plot_cc( ) else: # assigns discrete color map to each connected component if not given - if "cmap" not in kwargs: - kwargs["cmap"] = qim3d.viz.colormaps.segmentation(len(component_indexs)) + if "color_map" not in kwargs: + kwargs["color_map"] = qim3d.viz.colormaps.segmentation(len(component_indexs)) # Plot the connected component without overlay fig = qim3d.viz.slices_grid( - connected_components.get_cc(component, crop=crop), show=show, **kwargs + connected_components.get_cc(component, crop=crop), display_figure=display_figure, **kwargs ) figs.append(fig) - if not show: + if not display_figure: return figs return diff --git a/qim3d/viz/_data_exploration.py b/qim3d/viz/_data_exploration.py index e03f0852..a578edd5 100644 --- a/qim3d/viz/_data_exploration.py +++ b/qim3d/viz/_data_exploration.py @@ -79,7 +79,7 @@ def slices_grid( import qim3d vol = qim3d.examples.shell_225x128x128 - qim3d.viz.slices_grid_grid(vol, num_slices=15) + qim3d.viz.slices_grid(vol, num_slices=15) ```  """ @@ -475,6 +475,9 @@ def fade_mask( value_min (float, optional): Together with value_max define the data range the colormap covers. By default colormap covers the full range. Defaults to None. value_max (float, optional): Together with value_min define the data range the colormap covers. By default colormap covers the full range. Defaults to None + Returns: + slicer_obj (widgets.HBox): The interactive widget for visualizing fade mask on slices of a 3D volume. + Example: ```python import qim3d @@ -504,12 +507,12 @@ def fade_mask( ) axes[0].imshow( - slice_img, cmap=color_map, value_min=new_value_min, value_max=new_value_max + slice_img, cmap=color_map, vmin=new_value_min, vmax=new_value_max ) axes[0].set_title("Original") axes[0].axis("off") - mask = qim3d.processing.operations.fade_mask( + mask = qim3d.operations.fade_mask( np.ones_like(volume), decay_rate=decay_rate, ratio=ratio, @@ -521,7 +524,7 @@ def fade_mask( axes[1].set_title("Mask") axes[1].axis("off") - masked_volume = qim3d.processing.operations.fade_mask( + masked_volume = qim3d.operations.fade_mask( volume, decay_rate=decay_rate, ratio=ratio, @@ -692,7 +695,7 @@ def chunks(zarr_path: str, **kwargs)-> widgets.interactive: viz_widget = widgets.Output() with viz_widget: viz_widget.clear_output(wait=True) - fig = qim3d.viz.slices_grid_grid(chunk, **kwargs) + fig = qim3d.viz.slices_grid(chunk, **kwargs) display(fig) elif visualization_method == "volume": viz_widget = widgets.Output() diff --git a/qim3d/viz/_detection.py b/qim3d/viz/_detection.py index 14ba42bf..d10fc32c 100644 --- a/qim3d/viz/_detection.py +++ b/qim3d/viz/_detection.py @@ -25,16 +25,38 @@ def circles(blobs: tuple[float,float,float,float], vol: np.ndarray, alpha: float Returns: slicer_obj (ipywidgets.interactive): An interactive widget for visualizing the blobs. + Example: + ```python + import qim3d + import qim3d.detection + + # Get data + vol = qim3d.examples.cement_128x128x128 + + # Detect blobs, and get binary mask + blobs, _ = qim3d.detection.blobs( + vol, + min_sigma=1, + max_sigma=8, + threshold=0.001, + overlap=0.1, + background="bright" + ) + + # Visualize detected blobs with circles method + qim3d.viz.circles(blobs, vol, alpha=0.8, color='blue') + ``` +  """ def _slicer(z_slice): clear_output(wait=True) fig = qim3d.viz.slices_grid( - vol, - n_slices=1, - position=z_slice, - cmap="gray", - show_position=False, + vol[z_slice:z_slice + 1], + num_slices=1, + color_map="gray", + display_figure=False, + display_positions=False, **kwargs ) # Add circles from deteced blobs diff --git a/qim3d/viz/_k3d.py b/qim3d/viz/_k3d.py index b45a138c..f86ff9b8 100644 --- a/qim3d/viz/_k3d.py +++ b/qim3d/viz/_k3d.py @@ -35,7 +35,6 @@ def volumetric( Args: img (numpy.ndarray): The input 3D image data. It should be a 3D numpy array. aspectmode (str, optional): Determines the proportions of the scene's axes. Defaults to "data". - If `'data'`, the axes are drawn in proportion with the axes' ranges. If `'cube'`, the axes are drawn as a cube, regardless of the axes' ranges. show (bool, optional): If True, displays the visualization inline. Defaults to True. @@ -206,7 +205,7 @@ def mesh( ```python import qim3d - vol = qim3d.generate.blob(base_shape=(128,128,128), + vol = qim3d.generate.noise_object(base_shape=(128,128,128), final_shape=(128,128,128), noise_scale=0.03, order=1, @@ -215,7 +214,7 @@ def mesh( threshold=0.5, dtype='uint8' ) - mesh = qim3d.processing.create_mesh(vol, step_size=3) + mesh = qim3d.mesh.from_volume(vol, step_size=3) qim3d.viz.mesh(mesh.vertices, mesh.faces) ``` <iframe src="https://platform.qim.dk/k3d/mesh_visualization.html" width="100%" height="500" frameborder="0"></iframe> diff --git a/qim3d/viz/_local_thickness.py b/qim3d/viz/_local_thickness.py index c07438ee..243dc360 100644 --- a/qim3d/viz/_local_thickness.py +++ b/qim3d/viz/_local_thickness.py @@ -42,7 +42,7 @@ def local_thickness( ```python import qim3d - fly = qim3d.examples.fly_150x256x256 # 3D volume + fly = qim3d.examples.fly_150x256x256 lt_fly = qim3d.processing.local_thickness(fly) qim3d.viz.local_thickness(fly, lt_fly, axis=0) ``` diff --git a/qim3d/viz/_metrics.py b/qim3d/viz/_metrics.py index 16d7c7ce..f1f41785 100644 --- a/qim3d/viz/_metrics.py +++ b/qim3d/viz/_metrics.py @@ -215,10 +215,11 @@ def grid_pred( None Example: + import qim3d dataset = MySegmentationDataset() model = MySegmentationModel() - in_targ_preds = qim3d.utils.models.inference(dataset,model) - grid_pred(in_targ_preds, cmap_im='viridis', alpha=0.5) + in_targ_preds = qim3d.ml.inference(dataset,model) + qim3d.viz.grid_pred(in_targ_preds, cmap_im='viridis', alpha=0.5) """ import torch -- GitLab