From ac935758598a128473109e0a1cedc9d865d5de67 Mon Sep 17 00:00:00 2001 From: Damian Martinez Date: Mon, 19 Jan 2026 10:15:02 +0000 Subject: [PATCH 01/17] method to load custom metric in parameter sweep --- src/vlab4mic/sweep_generator.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/vlab4mic/sweep_generator.py b/src/vlab4mic/sweep_generator.py index 184e541..08705a1 100644 --- a/src/vlab4mic/sweep_generator.py +++ b/src/vlab4mic/sweep_generator.py @@ -1314,6 +1314,31 @@ def save_images(self, output_name=None, output_directory=None, floats_as=float): #name_ref = output_directory + "reference.tiff" tiff.imwrite(dir_name_ref, self.reference_image) + def add_custom_analysis_metric(self, metric_function: callable, metric_name: str): + """ + Add a custom analysis metric function to the sweep generator. + + Parameters + ---------- + :param metric_function: callable + A function that takes two numpy arrays (image output and reference image) + and returns a float representing the calculated metric. + :param metric_name: str + The name of the custom metric to be added. + + Returns + ------- + None + + Notes + ----- + The custom metric function should have the following signature: + def custom_metric(image_output: np.ndarray, reference_image: np.ndarray) -> float: + # Calculate and return the metric value + """ + self.analysis_parameters["metrics_list"].append(metric_name) + self.custom_metrics[metric_name] = metric_function + def run_parameter_sweep( structures: list[str] = None, From 71b0bbca00d6d67f33fe39fcd139bb4e28719b83 Mon Sep 17 00:00:00 2001 From: Damian Martinez Date: Mon, 19 Jan 2026 23:54:22 +0000 Subject: [PATCH 02/17] pass custom metric to image compare --- src/vlab4mic/analysis/metrics.py | 10 +++++++++- src/vlab4mic/analysis/sweep.py | 2 ++ src/vlab4mic/sweep_generator.py | 11 ++++++++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/vlab4mic/analysis/metrics.py b/src/vlab4mic/analysis/metrics.py index db1fd3c..f3a381c 100644 --- a/src/vlab4mic/analysis/metrics.py +++ b/src/vlab4mic/analysis/metrics.py @@ -6,7 +6,7 @@ from scipy.stats import pearsonr import cv2 -def img_compare(ref, query, metric=["ssim",], force_match=False, zoom_in=0, ref_mask = None, query_mask = None, **kwargs): +def img_compare(ref, query, metric=["ssim",], force_match=False, zoom_in=0, ref_mask = None, query_mask = None, custom_metrics = None, **kwargs): """ Compare two images using specified similarity metrics. @@ -74,6 +74,14 @@ def img_compare(ref, query, metric=["ssim",], force_match=False, zoom_in=0, ref_ elif method == "pearson": similarity, pval = pearsonr(ref[union_mask].flatten(), query[union_mask].flatten()) similarity_vector.append(similarity) + elif method in custom_metrics.keys(): + custom_measure = custom_metrics[method]( + ref, + query, + union_mask, + **kwargs) + print(f"custom meatric measurement: {custom_measure}") + similarity_vector.append(custom_measure) return similarity_vector, ref, query, masks_used diff --git a/src/vlab4mic/analysis/sweep.py b/src/vlab4mic/analysis/sweep.py index 1ad0d1b..dfd9cab 100644 --- a/src/vlab4mic/analysis/sweep.py +++ b/src/vlab4mic/analysis/sweep.py @@ -559,6 +559,7 @@ def analyse_sweep_single_reference( metrics_list: list = [ "ssim", ], + custom_metrics = None, **kwargs, ): """ @@ -613,6 +614,7 @@ def analyse_sweep_single_reference( force_match=True, zoom_in=zoom_in, metric=metrics_list, + custom_metrics = custom_metrics ) r_vector = list([params_id, rep_number]) + list([*rep_measurement]) measurement_vectors.append(r_vector) diff --git a/src/vlab4mic/sweep_generator.py b/src/vlab4mic/sweep_generator.py index 08705a1..5461846 100644 --- a/src/vlab4mic/sweep_generator.py +++ b/src/vlab4mic/sweep_generator.py @@ -103,6 +103,7 @@ def __init__(self): self.param_settings = self.parameter_settings self.use_experiment_structure = False self.reference_parameters_unsorted = dict() + self.custom_metrics = dict() print("vLab4mic sweep generator initialised") def set_number_of_repetitions(self, repeats: int = 3): @@ -825,6 +826,7 @@ def run_analysis( reference_image=reference_image, reference_image_mask=reference_image_mask, reference_params=self.reference_image_parameters, + custom_metrics=self.custom_metrics, **self.analysis_parameters, ) ) @@ -1336,7 +1338,8 @@ def add_custom_analysis_metric(self, metric_function: callable, metric_name: str def custom_metric(image_output: np.ndarray, reference_image: np.ndarray) -> float: # Calculate and return the metric value """ - self.analysis_parameters["metrics_list"].append(metric_name) + if metric_name not in self.analysis_parameters["metrics_list"]: + self.analysis_parameters["metrics_list"].append(metric_name) self.custom_metrics[metric_name] = metric_function @@ -1388,6 +1391,8 @@ def run_parameter_sweep( exp_time = None, # for plot generation na_as_zero = True, + custom_metric: callable = None, + custom_metric_name: str = None # Add more as needed for your sweep ): """ @@ -1534,6 +1539,10 @@ def run_parameter_sweep( reference_probe=reference_probe, **reference_parameters) sweep_gen.set_na_as_zero_in_plots(na_as_zero=na_as_zero) + if custom_metric is not None and custom_metric_name is not None: + sweep_gen.add_custom_analysis_metric( + metric_function=custom_metric, + metric_name=custom_metric_name) if run_analysis: sweep_gen.run_analysis( save=save_analysis_results, From c22dda9cb72b6ad3a9753a79bf10e8e8c96480bc Mon Sep 17 00:00:00 2001 From: Damian Martinez Date: Tue, 20 Jan 2026 01:25:29 +0000 Subject: [PATCH 03/17] generate plots from custom metric --- src/vlab4mic/analysis/_plots.py | 1 - src/vlab4mic/analysis/metrics.py | 2 +- src/vlab4mic/sweep_generator.py | 21 +++++++++++++++++++-- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/vlab4mic/analysis/_plots.py b/src/vlab4mic/analysis/_plots.py index 9a30a7e..02435b8 100644 --- a/src/vlab4mic/analysis/_plots.py +++ b/src/vlab4mic/analysis/_plots.py @@ -26,7 +26,6 @@ def sns_heatmap_pivots( f, axes = plt.subplots(nconditions, 2, figsize=figsize, squeeze = False) plot_num = 0 if cmaps_range == "same": - # min and max here correspond to SSIM hist_params = dict(vmin=0, vmax=1) elif cmaps_range == "each": hist_params = dict() diff --git a/src/vlab4mic/analysis/metrics.py b/src/vlab4mic/analysis/metrics.py index f3a381c..3ceacfe 100644 --- a/src/vlab4mic/analysis/metrics.py +++ b/src/vlab4mic/analysis/metrics.py @@ -80,7 +80,7 @@ def img_compare(ref, query, metric=["ssim",], force_match=False, zoom_in=0, ref_ query, union_mask, **kwargs) - print(f"custom meatric measurement: {custom_measure}") + print(f"custom metric measurement: {custom_measure}") similarity_vector.append(custom_measure) return similarity_vector, ref, query, masks_used diff --git a/src/vlab4mic/sweep_generator.py b/src/vlab4mic/sweep_generator.py index 5461846..901e9ee 100644 --- a/src/vlab4mic/sweep_generator.py +++ b/src/vlab4mic/sweep_generator.py @@ -81,6 +81,12 @@ def __init__(self): "pearson" ] self.plot_parameters = {} + self.plot_parameters["ssim"] = {} + self.plot_parameters["ssim"]["heatmaps"] = {} + self.plot_parameters["ssim"]["lineplots"] = {} + self.plot_parameters["pearson"] = {} + self.plot_parameters["pearson"]["heatmaps"] = {} + self.plot_parameters["pearson"]["lineplots"] = {} self.plot_parameters["heatmaps"] = {} self.plot_parameters["heatmaps"]["category"] = "modality_name" self.plot_parameters["heatmaps"]["param1"] = None @@ -839,13 +845,14 @@ def run_analysis( if plots: print("Generating analysis plots...") for metric_name in self.analysis_parameters["metrics_list"]: - for plot_type in self.plot_parameters.keys(): + for plot_type in ["heatmaps", "lineplots"]: self.generate_analysis_plots( plot_type=plot_type, return_figure=True, metric_name=metric_name, filter_dictionary=None, na_as_zero=self.plot_parameters["general"]["na_as_zero"], + **self.plot_parameters[metric_name][plot_type] ) print("Analysis plots generated.") if save: @@ -1316,7 +1323,7 @@ def save_images(self, output_name=None, output_directory=None, floats_as=float): #name_ref = output_directory + "reference.tiff" tiff.imwrite(dir_name_ref, self.reference_image) - def add_custom_analysis_metric(self, metric_function: callable, metric_name: str): + def add_custom_analysis_metric(self, metric_function: callable, metric_name: str, heatmap_params=None, lineplots_params =None, **kwargs): """ Add a custom analysis metric function to the sweep generator. @@ -1340,7 +1347,17 @@ def custom_metric(image_output: np.ndarray, reference_image: np.ndarray) -> floa """ if metric_name not in self.analysis_parameters["metrics_list"]: self.analysis_parameters["metrics_list"].append(metric_name) + self.plot_parameters[metric_name] = dict() + if heatmap_params is not None: + self.plot_parameters[metric_name]["heatmaps"] = heatmap_params + else: + self.plot_parameters[metric_name]["heatmaps"] = {} + if lineplots_params is not None: + self.plot_parameters[metric_name]["lineplots"] = lineplots_params + else: + self.plot_parameters[metric_name]["lineplots"] = {} self.custom_metrics[metric_name] = metric_function + def run_parameter_sweep( From 932533b4a6b4c3b6f0821093d08f33a5cbbd7174 Mon Sep 17 00:00:00 2001 From: Damian Martinez Date: Wed, 21 Jan 2026 14:06:05 +0000 Subject: [PATCH 04/17] pass plot parameters for param sweep --- src/vlab4mic/analysis/metrics.py | 1 - src/vlab4mic/sweep_generator.py | 9 ++++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/vlab4mic/analysis/metrics.py b/src/vlab4mic/analysis/metrics.py index 3ceacfe..ca225bc 100644 --- a/src/vlab4mic/analysis/metrics.py +++ b/src/vlab4mic/analysis/metrics.py @@ -80,7 +80,6 @@ def img_compare(ref, query, metric=["ssim",], force_match=False, zoom_in=0, ref_ query, union_mask, **kwargs) - print(f"custom metric measurement: {custom_measure}") similarity_vector.append(custom_measure) return similarity_vector, ref, query, masks_used diff --git a/src/vlab4mic/sweep_generator.py b/src/vlab4mic/sweep_generator.py index 901e9ee..19b1d43 100644 --- a/src/vlab4mic/sweep_generator.py +++ b/src/vlab4mic/sweep_generator.py @@ -1409,7 +1409,8 @@ def run_parameter_sweep( # for plot generation na_as_zero = True, custom_metric: callable = None, - custom_metric_name: str = None + custom_metric_name: str = None, + plot_parameters=None # Add more as needed for your sweep ): """ @@ -1560,6 +1561,12 @@ def run_parameter_sweep( sweep_gen.add_custom_analysis_metric( metric_function=custom_metric, metric_name=custom_metric_name) + if plot_parameters is not None: + for plot_type, parameters in plot_parameters.items(): + sweep_gen.set_plot_parameters( + plot_type=plot_type, + **parameters) + if run_analysis: sweep_gen.run_analysis( save=save_analysis_results, From b127fe33e7189be0fadfc2092972a791abd2a401 Mon Sep 17 00:00:00 2001 From: Damian Martinez Date: Wed, 21 Jan 2026 14:16:58 +0000 Subject: [PATCH 05/17] add test for custom metrics --- src/vlab4mic/sweep_generator.py | 3 ++- tests/test_sweeps.py | 22 ++++++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/vlab4mic/sweep_generator.py b/src/vlab4mic/sweep_generator.py index 19b1d43..01a21fb 100644 --- a/src/vlab4mic/sweep_generator.py +++ b/src/vlab4mic/sweep_generator.py @@ -1560,7 +1560,8 @@ def run_parameter_sweep( if custom_metric is not None and custom_metric_name is not None: sweep_gen.add_custom_analysis_metric( metric_function=custom_metric, - metric_name=custom_metric_name) + metric_name=custom_metric_name, + heatmap_params={"cmaps_range": "each"}) if plot_parameters is not None: for plot_type, parameters in plot_parameters.items(): sweep_gen.set_plot_parameters( diff --git a/tests/test_sweeps.py b/tests/test_sweeps.py index 97132d2..f219151 100644 --- a/tests/test_sweeps.py +++ b/tests/test_sweeps.py @@ -19,7 +19,7 @@ def test_run_parameter_sweep(): output_name="vlab_script", return_generator=True, save_sweep_images=False, - save_analysis_results=True, + save_analysis_results=False, run_analysis=True ) @@ -33,4 +33,22 @@ def test_run_parameter_sweep(): sweep_gen_test.params_by_group[group_name][param_name] ) vsamples_unique_ids = len(sweep_gen_test.virtual_samples_parameters.keys()) - assert total_combinations == vsamples_unique_ids \ No newline at end of file + assert total_combinations == vsamples_unique_ids + +def test_custom_metric(): + + def mean_of_image(ref=None, query=None, union_mask=None, **kwargs): + return np.mean(query) + + sweep_gen = sweep_generator.run_parameter_sweep( + sweep_repetitions=3, + # parameters for sweep + labelling_efficiency=(0, 1, 0.5), # values between 0 and 1 with step of 0.5 + return_generator=True, + analysis_plots=True, + save_sweep_images=False, # By default, the saving directory is set to the home path of the user + save_analysis_results=False, + run_analysis=True, + custom_metric=mean_of_image, + custom_metric_name="mean_intensity", + ) \ No newline at end of file From de3e8f5f9697fbaca4e1b6366b08745f30984c36 Mon Sep 17 00:00:00 2001 From: Damian Martinez Date: Wed, 21 Jan 2026 16:05:58 +0000 Subject: [PATCH 06/17] fix input image as reference in sweep --- src/vlab4mic/sweep_generator.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/vlab4mic/sweep_generator.py b/src/vlab4mic/sweep_generator.py index 01a21fb..a935cc5 100644 --- a/src/vlab4mic/sweep_generator.py +++ b/src/vlab4mic/sweep_generator.py @@ -374,7 +374,10 @@ def load_reference_image( image_mask = tiff.imread(ref_image_mask_path) ref_image_mask = image_mask > 0 else: - image_mask = np.ones(shape=ref_image[0].shape) + if len(ref_image.shape) == 3: + image_mask = np.ones(shape=ref_image[0].shape) + else: + image_mask = np.ones(shape=ref_image.shape) ref_image_mask = image_mask > 0 if override: self.reference_image = ref_image @@ -466,7 +469,10 @@ def preview_reference_image(self, return_image=False, cmap="Grays_r"): if return_image: return self.reference_image else: - plt.imshow(self.reference_image[0], cmap=cmap) + if len(self.reference_image.shape) > 2: + plt.imshow(self.reference_image[0], cmap=cmap) + else: + plt.imshow(self.reference_image, cmap=cmap) print(self.reference_image_parameters) # set and change parameters From 9ede2e13e0312d28bf7d2fb6ef75b236108ca249 Mon Sep 17 00:00:00 2001 From: Damian Martinez Date: Wed, 21 Jan 2026 16:29:17 +0000 Subject: [PATCH 07/17] update documentation for method to add custom metric --- src/vlab4mic/sweep_generator.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/vlab4mic/sweep_generator.py b/src/vlab4mic/sweep_generator.py index a935cc5..e4d4e23 100644 --- a/src/vlab4mic/sweep_generator.py +++ b/src/vlab4mic/sweep_generator.py @@ -1336,7 +1336,7 @@ def add_custom_analysis_metric(self, metric_function: callable, metric_name: str Parameters ---------- :param metric_function: callable - A function that takes two numpy arrays (image output and reference image) + A function that takes two numpy arrays (reference image and query image) and returns a float representing the calculated metric. :param metric_name: str The name of the custom metric to be added. @@ -1348,7 +1348,8 @@ def add_custom_analysis_metric(self, metric_function: callable, metric_name: str Notes ----- The custom metric function should have the following signature: - def custom_metric(image_output: np.ndarray, reference_image: np.ndarray) -> float: + def custom_metric(ref: np.ndarray, query: np.ndarray, union_mask, **kwargs) -> float: + # here union_mask is a binary mask that can be used to filter pixel to use for calculations # Calculate and return the metric value """ if metric_name not in self.analysis_parameters["metrics_list"]: From 19599d2c0144cb7b185106ea9b9105d4542c96a4 Mon Sep 17 00:00:00 2001 From: Damian Martinez Date: Thu, 22 Jan 2026 15:56:32 +0000 Subject: [PATCH 08/17] calculate metric by calling as a class --- src/vlab4mic/analysis/metrics.py | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/vlab4mic/analysis/metrics.py b/src/vlab4mic/analysis/metrics.py index ca225bc..e88f6e9 100644 --- a/src/vlab4mic/analysis/metrics.py +++ b/src/vlab4mic/analysis/metrics.py @@ -5,6 +5,7 @@ from skimage.feature import peak_local_max from scipy.stats import pearsonr import cv2 +import copy def img_compare(ref, query, metric=["ssim",], force_match=False, zoom_in=0, ref_mask = None, query_mask = None, custom_metrics = None, **kwargs): """ @@ -34,8 +35,14 @@ def img_compare(ref, query, metric=["ssim",], force_match=False, zoom_in=0, ref_ query : numpy.ndarray (Possibly resized) query image. """ + reference_image = ref.copy() + query_image = query.copy() + ref_pixelsize = None + query_pixelsize = None if force_match: if 'ref_pixelsize' in kwargs and 'modality_pixelsize' in kwargs: + ref_pixelsize = copy.copy(kwargs['ref_pixelsize']) + query_pixelsize = copy.copy(kwargs['modality_pixelsize']) ref, query = resize_images_interpolation( img1=ref, img2=query, @@ -66,7 +73,6 @@ def img_compare(ref, query, metric=["ssim",], force_match=False, zoom_in=0, ref_ zoom_in=zoom_in ) similarity_vector = [] - for method in metric: if method == "ssim": similarity = ssim(ref[union_mask], query[union_mask], data_range=query[union_mask].max() - query[union_mask].min()) @@ -75,12 +81,21 @@ def img_compare(ref, query, metric=["ssim",], force_match=False, zoom_in=0, ref_ similarity, pval = pearsonr(ref[union_mask].flatten(), query[union_mask].flatten()) similarity_vector.append(similarity) elif method in custom_metrics.keys(): - custom_measure = custom_metrics[method]( - ref, - query, - union_mask, - **kwargs) - similarity_vector.append(custom_measure) + metric_calculator = custom_metrics[method]( + reference_image = reference_image, + reference_image_pixelsize_nm = ref_pixelsize, + simulated_image = query_image, + simulated_image_pixelsize_nm = query_pixelsize, + image_mask = union_mask, + resized_reference_image = ref, + resized_simulated_image = query, + **kwargs + ) + custom_measurement = metric_calculator.run_metric() + if isinstance(custom_measurement, float): + similarity_vector.append(custom_measurement) + else: + similarity_vector.append(None) return similarity_vector, ref, query, masks_used From 034fa7821898d1d70a45491baa5fca206286506d Mon Sep 17 00:00:00 2001 From: Damian Martinez Date: Thu, 22 Jan 2026 15:57:21 +0000 Subject: [PATCH 09/17] Change custom metrics to be list of classes --- src/vlab4mic/sweep_generator.py | 43 ++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/vlab4mic/sweep_generator.py b/src/vlab4mic/sweep_generator.py index e4d4e23..06f6037 100644 --- a/src/vlab4mic/sweep_generator.py +++ b/src/vlab4mic/sweep_generator.py @@ -1329,7 +1329,7 @@ def save_images(self, output_name=None, output_directory=None, floats_as=float): #name_ref = output_directory + "reference.tiff" tiff.imwrite(dir_name_ref, self.reference_image) - def add_custom_analysis_metric(self, metric_function: callable, metric_name: str, heatmap_params=None, lineplots_params =None, **kwargs): + def add_custom_analysis_metrics(self, custom_metrics: list = None, heatmap_params={"cmaps_range": "each"}, lineplots_params=None, **kwargs): """ Add a custom analysis metric function to the sweep generator. @@ -1352,18 +1352,22 @@ def custom_metric(ref: np.ndarray, query: np.ndarray, union_mask, **kwargs) -> f # here union_mask is a binary mask that can be used to filter pixel to use for calculations # Calculate and return the metric value """ - if metric_name not in self.analysis_parameters["metrics_list"]: - self.analysis_parameters["metrics_list"].append(metric_name) - self.plot_parameters[metric_name] = dict() - if heatmap_params is not None: - self.plot_parameters[metric_name]["heatmaps"] = heatmap_params - else: - self.plot_parameters[metric_name]["heatmaps"] = {} - if lineplots_params is not None: - self.plot_parameters[metric_name]["lineplots"] = lineplots_params - else: - self.plot_parameters[metric_name]["lineplots"] = {} - self.custom_metrics[metric_name] = metric_function + for custom_class in custom_metrics: + metric_callable = custom_class() + if metric_callable.get_metric_name() not in self.analysis_parameters["metrics_list"]: + metric_name = metric_callable.get_metric_name() + self.analysis_parameters["metrics_list"].append(metric_name) + self.plot_parameters[metric_name] = dict() + # change plot parameters to different method + if heatmap_params is not None: + self.plot_parameters[metric_name]["heatmaps"] = heatmap_params + else: + self.plot_parameters[metric_name]["heatmaps"] = {} + if lineplots_params is not None: + self.plot_parameters[metric_name]["lineplots"] = lineplots_params + else: + self.plot_parameters[metric_name]["lineplots"] = {} + self.custom_metrics[metric_name] = custom_class @@ -1415,8 +1419,8 @@ def run_parameter_sweep( exp_time = None, # for plot generation na_as_zero = True, - custom_metric: callable = None, - custom_metric_name: str = None, + custom_metrics: list = None, + #custom_metric_name: str = None, plot_parameters=None # Add more as needed for your sweep ): @@ -1564,11 +1568,10 @@ def run_parameter_sweep( reference_probe=reference_probe, **reference_parameters) sweep_gen.set_na_as_zero_in_plots(na_as_zero=na_as_zero) - if custom_metric is not None and custom_metric_name is not None: - sweep_gen.add_custom_analysis_metric( - metric_function=custom_metric, - metric_name=custom_metric_name, - heatmap_params={"cmaps_range": "each"}) + if custom_metrics is not None: + sweep_gen.add_custom_analysis_metrics( + custom_metrics=custom_metrics + ) if plot_parameters is not None: for plot_type, parameters in plot_parameters.items(): sweep_gen.set_plot_parameters( From 997e4877770d29d14fae319aff1f77470747221c Mon Sep 17 00:00:00 2001 From: Damian Martinez Date: Thu, 22 Jan 2026 15:57:54 +0000 Subject: [PATCH 10/17] remove unused prints in sweep module --- src/vlab4mic/analysis/sweep.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/vlab4mic/analysis/sweep.py b/src/vlab4mic/analysis/sweep.py index dfd9cab..5bb427e 100644 --- a/src/vlab4mic/analysis/sweep.py +++ b/src/vlab4mic/analysis/sweep.py @@ -602,7 +602,6 @@ def analyse_sweep_single_reference( for img_r, img_mask in zip(img_outputs[params_id], img_outputs_masks[params_id]): im1 = img_r[0] im1_mask = img_mask - #print(f"query: {im1.shape},{im1_mask.shape}") im_ref = reference_image rep_measurement, ref_used, qry_used, masks_used = metrics.img_compare( ref = im_ref, From f34d33f59bee20e588451502851afac21080d411 Mon Sep 17 00:00:00 2001 From: Damian Martinez Date: Thu, 22 Jan 2026 16:41:26 +0000 Subject: [PATCH 11/17] update sweep custom metrics to callables --- src/vlab4mic/analysis/metrics.py | 4 ++-- src/vlab4mic/sweep_generator.py | 13 ++++++------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/vlab4mic/analysis/metrics.py b/src/vlab4mic/analysis/metrics.py index e88f6e9..c7c16f8 100644 --- a/src/vlab4mic/analysis/metrics.py +++ b/src/vlab4mic/analysis/metrics.py @@ -81,7 +81,7 @@ def img_compare(ref, query, metric=["ssim",], force_match=False, zoom_in=0, ref_ similarity, pval = pearsonr(ref[union_mask].flatten(), query[union_mask].flatten()) similarity_vector.append(similarity) elif method in custom_metrics.keys(): - metric_calculator = custom_metrics[method]( + custom_measurement = custom_metrics[method]( reference_image = reference_image, reference_image_pixelsize_nm = ref_pixelsize, simulated_image = query_image, @@ -91,7 +91,7 @@ def img_compare(ref, query, metric=["ssim",], force_match=False, zoom_in=0, ref_ resized_simulated_image = query, **kwargs ) - custom_measurement = metric_calculator.run_metric() + #custom_measurement = metric_calculator.run_metric() if isinstance(custom_measurement, float): similarity_vector.append(custom_measurement) else: diff --git a/src/vlab4mic/sweep_generator.py b/src/vlab4mic/sweep_generator.py index 06f6037..2538ed4 100644 --- a/src/vlab4mic/sweep_generator.py +++ b/src/vlab4mic/sweep_generator.py @@ -1329,7 +1329,7 @@ def save_images(self, output_name=None, output_directory=None, floats_as=float): #name_ref = output_directory + "reference.tiff" tiff.imwrite(dir_name_ref, self.reference_image) - def add_custom_analysis_metrics(self, custom_metrics: list = None, heatmap_params={"cmaps_range": "each"}, lineplots_params=None, **kwargs): + def add_custom_analysis_metrics(self, custom_metrics: list[callable] = None, heatmap_params={"cmaps_range": "each"}, lineplots_params=None, **kwargs): """ Add a custom analysis metric function to the sweep generator. @@ -1352,10 +1352,9 @@ def custom_metric(ref: np.ndarray, query: np.ndarray, union_mask, **kwargs) -> f # here union_mask is a binary mask that can be used to filter pixel to use for calculations # Calculate and return the metric value """ - for custom_class in custom_metrics: - metric_callable = custom_class() - if metric_callable.get_metric_name() not in self.analysis_parameters["metrics_list"]: - metric_name = metric_callable.get_metric_name() + for m in range(len(custom_metrics)): + metric_name = custom_metrics[m].__name__ + if metric_name not in self.analysis_parameters["metrics_list"]: self.analysis_parameters["metrics_list"].append(metric_name) self.plot_parameters[metric_name] = dict() # change plot parameters to different method @@ -1367,7 +1366,7 @@ def custom_metric(ref: np.ndarray, query: np.ndarray, union_mask, **kwargs) -> f self.plot_parameters[metric_name]["lineplots"] = lineplots_params else: self.plot_parameters[metric_name]["lineplots"] = {} - self.custom_metrics[metric_name] = custom_class + self.custom_metrics[metric_name] = custom_metrics[m] @@ -1419,7 +1418,7 @@ def run_parameter_sweep( exp_time = None, # for plot generation na_as_zero = True, - custom_metrics: list = None, + custom_metrics: list[callable] = None, #custom_metric_name: str = None, plot_parameters=None # Add more as needed for your sweep From 0d466ef610c4cd4d42c42910fd00c5b6f5d1cf8a Mon Sep 17 00:00:00 2001 From: Damian Martinez Date: Thu, 22 Jan 2026 18:01:35 +0000 Subject: [PATCH 12/17] remove deprecated function --- src/vlab4mic/analysis/sweep.py | 45 ---------------------------------- 1 file changed, 45 deletions(-) diff --git a/src/vlab4mic/analysis/sweep.py b/src/vlab4mic/analysis/sweep.py index 5bb427e..afd1c6c 100644 --- a/src/vlab4mic/analysis/sweep.py +++ b/src/vlab4mic/analysis/sweep.py @@ -503,51 +503,6 @@ def generate_global_reference_modality( return reference_output[modality]["ch0"], reference_parameters, reference_output_mask -def analyse_image_sweep( - img_outputs, img_params, reference, analysis_case_params=None -): - """ - Analyse a sweep of images against a reference image. - - Parameters - ---------- - img_outputs : dict - Dictionary of simulated image outputs. - img_params : dict - Dictionary of image parameters. - reference : numpy.ndarray - Reference image. - analysis_case_params : dict, optional - Additional parameters for analysis. - - Returns - ------- - measurement_vectors : list - List of measurement results for each image. - inputs : dict - Dictionary of input images and used references. - """ - measurement_vectors = [] - # ref_pixelsize = analysis_case_params["ref_pixelsize"] - inputs = dict() - for params_id in img_params.keys(): - inputs[params_id] = dict() - rep_number = 0 - mod_name = img_params[params_id][5] # 5th item corresponds to Modality - for img_r in img_outputs[params_id]: - im1 = img_r[0] - im_ref = reference[0] - rep_measurement, ref_used, qry_used_, masks_used = metrics.img_compare( - im_ref, im1, **analysis_case_params[mod_name] - ) - measurement_vectors.append( - [params_id, rep_number, rep_measurement] - ) - inputs[params_id][rep_number] = [qry_used, im1] - rep_number += 1 - return measurement_vectors, inputs - - def analyse_sweep_single_reference( img_outputs, img_outputs_masks, From b54f2cd47b0c901830f751c33a832888f28713fb Mon Sep 17 00:00:00 2001 From: Damian Martinez Date: Thu, 22 Jan 2026 18:02:38 +0000 Subject: [PATCH 13/17] make function for matching image sizes based on their pixelsize --- src/vlab4mic/analysis/metrics.py | 37 ++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/vlab4mic/analysis/metrics.py b/src/vlab4mic/analysis/metrics.py index c7c16f8..7dab3a8 100644 --- a/src/vlab4mic/analysis/metrics.py +++ b/src/vlab4mic/analysis/metrics.py @@ -7,6 +7,43 @@ import cv2 import copy +def match_image_sizes( + reference_image = None, + reference_image_pixelsize_nm = None, + reference_image_mask = None, + simulated_image = None, + simulated_image_pixelsize_nm = None, + simulated_image_mask = None + ): + masks_used = dict() + if reference_image_pixelsize_nm and simulated_image_pixelsize_nm: + reference_interpolated, simulated_image_interpolated = resize_images_interpolation( + img1=reference_image, + img2=simulated_image, + px_size_im1=reference_image_pixelsize_nm, + px_size_im2=simulated_image_pixelsize_nm, + ) + if reference_image_mask is not None and simulated_image_mask is not None: + reference_mask_interpolated, simulated_image_mask_interpolated = resize_images_interpolation( + img1=reference_image_mask, + img2=simulated_image_mask, + px_size_im1=reference_image_pixelsize_nm, + px_size_im2=simulated_image_pixelsize_nm, + interpolation_order=0 # becauese they are masks + ) + union_mask = np.logical_or( + reference_mask_interpolated, + simulated_image_mask_interpolated) + masks_used["reference_mask"] = reference_mask_interpolated + masks_used["query_mask"] = simulated_image_mask_interpolated + masks_used["union_mask"] = union_mask + else: + masks_used["reference_mask"] = None + masks_used["query_mask"] = None + masks_used["union_mask"] = None + return reference_interpolated, simulated_image_interpolated, masks_used + + def img_compare(ref, query, metric=["ssim",], force_match=False, zoom_in=0, ref_mask = None, query_mask = None, custom_metrics = None, **kwargs): """ Compare two images using specified similarity metrics. From 3124f35a66ddf4b3596467a5a4d9cf7e106052fb Mon Sep 17 00:00:00 2001 From: Damian Martinez Date: Thu, 22 Jan 2026 18:10:42 +0000 Subject: [PATCH 14/17] create wrapper functions for default metrics --- src/vlab4mic/analysis/metrics.py | 59 +++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 8 deletions(-) diff --git a/src/vlab4mic/analysis/metrics.py b/src/vlab4mic/analysis/metrics.py index 7dab3a8..3cbcb0a 100644 --- a/src/vlab4mic/analysis/metrics.py +++ b/src/vlab4mic/analysis/metrics.py @@ -34,14 +34,57 @@ def match_image_sizes( union_mask = np.logical_or( reference_mask_interpolated, simulated_image_mask_interpolated) - masks_used["reference_mask"] = reference_mask_interpolated - masks_used["query_mask"] = simulated_image_mask_interpolated - masks_used["union_mask"] = union_mask - else: - masks_used["reference_mask"] = None - masks_used["query_mask"] = None - masks_used["union_mask"] = None - return reference_interpolated, simulated_image_interpolated, masks_used + #masks_interpolated["reference_mask"] = reference_mask_interpolated + #masks_interpolated["query_mask"] = simulated_image_mask_interpolated + #masks_interpolated["union_mask"] = union_mask + return reference_interpolated, simulated_image_interpolated, union_mask + + +def calculate_ssim( + reference_image = None, + reference_image_pixelsize_nm = None, + reference_image_mask = None, + simulated_image = None, + simulated_image_pixelsize_nm = None, + simulated_image_mask = None +): + reference_interpolated, simulated_image_interpolated, union_mask = match_image_sizes( + reference_image = reference_image, + reference_image_pixelsize_nm = reference_image_pixelsize_nm, + reference_image_mask = reference_image_mask, + simulated_image = simulated_image, + simulated_image_pixelsize_nm = simulated_image_pixelsize_nm, + simulated_image_mask = simulated_image_mask + ) + similarity = ssim( + reference_interpolated[union_mask], + simulated_image_interpolated[union_mask], + data_range=simulated_image_interpolated[union_mask].max() - simulated_image_interpolated[union_mask].min() + ) + return similarity + + +def calculate_pearson_correlation( + reference_image = None, + reference_image_pixelsize_nm = None, + reference_image_mask = None, + simulated_image = None, + simulated_image_pixelsize_nm = None, + simulated_image_mask = None +): + reference_interpolated, simulated_image_interpolated, union_mask = match_image_sizes( + reference_image = reference_image, + reference_image_pixelsize_nm = reference_image_pixelsize_nm, + reference_image_mask = reference_image_mask, + simulated_image = simulated_image, + simulated_image_pixelsize_nm = simulated_image_pixelsize_nm, + simulated_image_mask = simulated_image_mask + ) + pearson_correlation, pval = pearsonr( + reference_interpolated[union_mask].flatten(), + simulated_image_interpolated[union_mask].flatten() + ) + return pearson_correlation def img_compare(ref, query, metric=["ssim",], force_match=False, zoom_in=0, ref_mask = None, query_mask = None, custom_metrics = None, **kwargs): From 885cefd947e9081c214d6669c9d4395f691d3f96 Mon Sep 17 00:00:00 2001 From: Damian Martinez Date: Thu, 22 Jan 2026 18:25:50 +0000 Subject: [PATCH 15/17] pass custom metrics as list of callables and import defaults --- src/vlab4mic/analysis/metrics.py | 6 ++-- src/vlab4mic/analysis/sweep.py | 53 +++++++++++++++++++------------- src/vlab4mic/sweep_generator.py | 10 ++++-- 3 files changed, 42 insertions(+), 27 deletions(-) diff --git a/src/vlab4mic/analysis/metrics.py b/src/vlab4mic/analysis/metrics.py index 3cbcb0a..f1119fb 100644 --- a/src/vlab4mic/analysis/metrics.py +++ b/src/vlab4mic/analysis/metrics.py @@ -15,7 +15,7 @@ def match_image_sizes( simulated_image_pixelsize_nm = None, simulated_image_mask = None ): - masks_used = dict() + union_mask = None if reference_image_pixelsize_nm and simulated_image_pixelsize_nm: reference_interpolated, simulated_image_interpolated = resize_images_interpolation( img1=reference_image, @@ -40,7 +40,7 @@ def match_image_sizes( return reference_interpolated, simulated_image_interpolated, union_mask -def calculate_ssim( +def structural_similarity( reference_image = None, reference_image_pixelsize_nm = None, reference_image_mask = None, @@ -64,7 +64,7 @@ def calculate_ssim( return similarity -def calculate_pearson_correlation( +def pearson_correlation( reference_image = None, reference_image_pixelsize_nm = None, reference_image_mask = None, diff --git a/src/vlab4mic/analysis/sweep.py b/src/vlab4mic/analysis/sweep.py index afd1c6c..3bbd549 100644 --- a/src/vlab4mic/analysis/sweep.py +++ b/src/vlab4mic/analysis/sweep.py @@ -511,10 +511,8 @@ def analyse_sweep_single_reference( reference_image_mask, reference_params, zoom_in=0, - metrics_list: list = [ - "ssim", - ], - custom_metrics = None, + metrics: dict = None, + #custom_metrics = None, **kwargs, ): """ @@ -556,26 +554,39 @@ def analyse_sweep_single_reference( modality_pixelsize = img_params[params_id][6]["pixelsize"] for img_r, img_mask in zip(img_outputs[params_id], img_outputs_masks[params_id]): im1 = img_r[0] - im1_mask = img_mask - im_ref = reference_image - rep_measurement, ref_used, qry_used, masks_used = metrics.img_compare( - ref = im_ref, - ref_mask=reference_image_mask, - query=im1, - query_mask=im1_mask, - modality_pixelsize=modality_pixelsize, - ref_pixelsize=reference_params["ref_pixelsize"], - force_match=True, - zoom_in=zoom_in, - metric=metrics_list, - custom_metrics = custom_metrics - ) - r_vector = list([params_id, rep_number]) + list([*rep_measurement]) + #im1_mask = img_mask + #im_ref = reference_image + similarity_vector = [] + metrics_names_list = [] + for metric_name, metric in metrics.items(): + metrics_names_list.append(metric_name) + similarity_vector.append(metric( + reference_image = reference_image, + reference_image_pixelsize_nm = reference_params["ref_pixelsize"], + reference_image_mask = reference_image_mask, + simulated_image = im1, + simulated_image_pixelsize_nm = modality_pixelsize, + simulated_image_mask = img_mask, + ) + ) + #rep_measurement, ref_used, qry_used, masks_used = metrics.img_compare( + # ref = im_ref, + # ref_mask=reference_image_mask, + # query=im1, + # query_mask=im1_mask, + # modality_pixelsize=modality_pixelsize, + # ref_pixelsize=reference_params["ref_pixelsize"], + # force_match=True, + # zoom_in=zoom_in, + # metrics = metrics + #) + r_vector = list([params_id, rep_number]) + list([*similarity_vector]) measurement_vectors.append(r_vector) # measurement_vectors = measurement_vectors + rep_measurement[0] - inputs[params_id][rep_number] = [qry_used, im1, ref_used, masks_used] + # for methods that require image resizing + #inputs[params_id][rep_number] = [qry_used, im1, ref_used, masks_used] rep_number += 1 - return measurement_vectors, inputs, metrics_list + return measurement_vectors, inputs, metrics_names_list def measurements_dataframe( diff --git a/src/vlab4mic/sweep_generator.py b/src/vlab4mic/sweep_generator.py index 2538ed4..2015bfc 100644 --- a/src/vlab4mic/sweep_generator.py +++ b/src/vlab4mic/sweep_generator.py @@ -13,6 +13,7 @@ import copy import tifffile as tiff from pandas.api.types import is_numeric_dtype +from .analysis.metrics import structural_similarity, pearson_correlation #output_dir = Path.home() / "vlab4mic_outputs" @@ -109,7 +110,10 @@ def __init__(self): self.param_settings = self.parameter_settings self.use_experiment_structure = False self.reference_parameters_unsorted = dict() - self.custom_metrics = dict() + self.metrics = { + "ssim": structural_similarity, + "pearson": pearson_correlation + } print("vLab4mic sweep generator initialised") def set_number_of_repetitions(self, repeats: int = 3): @@ -838,7 +842,7 @@ def run_analysis( reference_image=reference_image, reference_image_mask=reference_image_mask, reference_params=self.reference_image_parameters, - custom_metrics=self.custom_metrics, + metrics=self.metrics, **self.analysis_parameters, ) ) @@ -1366,7 +1370,7 @@ def custom_metric(ref: np.ndarray, query: np.ndarray, union_mask, **kwargs) -> f self.plot_parameters[metric_name]["lineplots"] = lineplots_params else: self.plot_parameters[metric_name]["lineplots"] = {} - self.custom_metrics[metric_name] = custom_metrics[m] + self.metrics[metric_name] = custom_metrics[m] From cb09d7f0c91e224755867c86f501d313cf83c9f8 Mon Sep 17 00:00:00 2001 From: Damian Martinez Date: Fri, 23 Jan 2026 14:51:57 +0000 Subject: [PATCH 16/17] update test for custom metrics --- tests/test_sweeps.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/tests/test_sweeps.py b/tests/test_sweeps.py index f219151..c416821 100644 --- a/tests/test_sweeps.py +++ b/tests/test_sweeps.py @@ -37,8 +37,16 @@ def test_run_parameter_sweep(): def test_custom_metric(): - def mean_of_image(ref=None, query=None, union_mask=None, **kwargs): - return np.mean(query) + def mean_value(reference_image = None, + reference_image_pixelsize_nm = None, + simulated_image = None, + simulated_image_pixelsize_nm = None, + image_mask = None, + resized_reference_image = None, + resized_simulated_image = None, + *args,**kwargs): + return np.mean(simulated_image) + sweep_gen = sweep_generator.run_parameter_sweep( sweep_repetitions=3, @@ -49,6 +57,5 @@ def mean_of_image(ref=None, query=None, union_mask=None, **kwargs): save_sweep_images=False, # By default, the saving directory is set to the home path of the user save_analysis_results=False, run_analysis=True, - custom_metric=mean_of_image, - custom_metric_name="mean_intensity", + custom_metrics=[mean_value,], ) \ No newline at end of file From 77a4ab11ea08bba793ef8f75bc59a6db360fa502 Mon Sep 17 00:00:00 2001 From: Damian Martinez Date: Fri, 23 Jan 2026 19:29:14 +0000 Subject: [PATCH 17/17] default metrics for sweep --- src/vlab4mic/analysis/sweep.py | 35 +++++++++++++++++---------------- src/vlab4mic/sweep_generator.py | 35 ++++++++++++++++++++------------- 2 files changed, 39 insertions(+), 31 deletions(-) diff --git a/src/vlab4mic/analysis/sweep.py b/src/vlab4mic/analysis/sweep.py index 3bbd549..949c185 100644 --- a/src/vlab4mic/analysis/sweep.py +++ b/src/vlab4mic/analysis/sweep.py @@ -559,7 +559,7 @@ def analyse_sweep_single_reference( similarity_vector = [] metrics_names_list = [] for metric_name, metric in metrics.items(): - metrics_names_list.append(metric_name) + #metrics_names_list.append(metric_name) similarity_vector.append(metric( reference_image = reference_image, reference_image_pixelsize_nm = reference_params["ref_pixelsize"], @@ -569,22 +569,22 @@ def analyse_sweep_single_reference( simulated_image_mask = img_mask, ) ) - #rep_measurement, ref_used, qry_used, masks_used = metrics.img_compare( - # ref = im_ref, - # ref_mask=reference_image_mask, - # query=im1, - # query_mask=im1_mask, - # modality_pixelsize=modality_pixelsize, - # ref_pixelsize=reference_params["ref_pixelsize"], - # force_match=True, - # zoom_in=zoom_in, - # metrics = metrics - #) - r_vector = list([params_id, rep_number]) + list([*similarity_vector]) - measurement_vectors.append(r_vector) - # measurement_vectors = measurement_vectors + rep_measurement[0] - # for methods that require image resizing - #inputs[params_id][rep_number] = [qry_used, im1, ref_used, masks_used] + #rep_measurement, ref_used, qry_used, masks_used = metrics.img_compare( + # ref = im_ref, + # ref_mask=reference_image_mask, + # query=im1, + # query_mask=im1_mask, + # modality_pixelsize=modality_pixelsize, + # ref_pixelsize=reference_params["ref_pixelsize"], + # force_match=True, + # zoom_in=zoom_in, + # metrics = metrics + #) + # each image as its ID, a replica number and the metrics associated to it + replicaID_repN_metrics = list([params_id, rep_number]) + list([*similarity_vector]) + measurement_vectors.append(replicaID_repN_metrics) + # for methods that require image resizing + #inputs[params_id][rep_number] = [qry_used, im1, ref_used, masks_used] rep_number += 1 return measurement_vectors, inputs, metrics_names_list @@ -650,6 +650,7 @@ def measurements_dataframe( nmetrics = len(metric_names) metrics_dictionary = dict() for metric_number in range(nmetrics): + # first two indices are ID and replica number, then one value per metric metricvector = measurement_array[:, 2 + metric_number] metrics_dictionary[metric_names[metric_number]] = np.array( metricvector, dtype=np.float64 diff --git a/src/vlab4mic/sweep_generator.py b/src/vlab4mic/sweep_generator.py index 2015bfc..ec15c84 100644 --- a/src/vlab4mic/sweep_generator.py +++ b/src/vlab4mic/sweep_generator.py @@ -77,10 +77,6 @@ def __init__(self): self.parameter_settings = load_yaml(param_settings_file) self.analysis_parameters = {} self.analysis_parameters["zoom_in"] = 0 - self.analysis_parameters["metrics_list"] = [ - "ssim", - "pearson" - ] self.plot_parameters = {} self.plot_parameters["ssim"] = {} self.plot_parameters["ssim"]["heatmaps"] = {} @@ -110,10 +106,11 @@ def __init__(self): self.param_settings = self.parameter_settings self.use_experiment_structure = False self.reference_parameters_unsorted = dict() - self.metrics = { + self.default_metrics = { "ssim": structural_similarity, "pearson": pearson_correlation } + self.metrics = {} print("vLab4mic sweep generator initialised") def set_number_of_repetitions(self, repeats: int = 3): @@ -751,8 +748,8 @@ def set_analysis_parameters( ------- None """ - if metrics_list is not None and type(metrics_list) == list: - self.analysis_parameters["metrics_list"] = metrics_list + #if metrics_list is not None and type(metrics_list) == list: + # self.analysis_parameters["metrics_list"] = metrics_list if zoom_in is not None: self.analysis_parameters["zoom_in"] = zoom_in @@ -788,7 +785,12 @@ def set_na_as_zero_in_plots(self, na_as_zero: bool = True): ------- None """ - self.plot_parameters["general"]["na_as_zero"] = na_as_zero + self.plot_parameters["general"]["na_as_zero"] = na_as_zero + + def use_default_metrics(self, metrics = ["ssim", "pearson"]): + if metrics is not None: + for metric_name in metrics: + self.metrics[metric_name] = self.default_metrics[metric_name] def run_analysis( self, @@ -833,6 +835,8 @@ def run_analysis( else: reference_image = self.reference_image reference_image_mask = self.reference_image_mask + if len(self.metrics.keys()) == 0: + self.use_default_metrics() print("Running analysis...") measurement_vectors, inputs, metric = ( sweep.analyse_sweep_single_reference( @@ -854,7 +858,7 @@ def run_analysis( print("Analysis dataframe generated.") if plots: print("Generating analysis plots...") - for metric_name in self.analysis_parameters["metrics_list"]: + for metric_name in self.metrics.keys(): for plot_type in ["heatmaps", "lineplots"]: self.generate_analysis_plots( plot_type=plot_type, @@ -892,7 +896,7 @@ def gen_analysis_dataframe(self): mod_acq=self.acquisition_parameters, mod_names=self.modalities, mod_params=self.modality_parameters, - metric_names=self.analysis_parameters["metrics_list"], + metric_names=list(self.metrics.keys()), ) ) @@ -1025,7 +1029,7 @@ def _gen_heatmaps( The generated heatmap figure. """ if metric_name is None: - metric_name = self.analysis_parameters["metrics_list"][0] + metric_name = list(self.metrics.keys())[0] if category is None: category = "modality_name" if param1 is None: @@ -1130,7 +1134,7 @@ def _gen_lineplots( else: x_param = "labelling_efficiency" if metric_name is None: - metric_name = self.analysis_parameters["metrics_list"][0] + metric_name = list(self.metrics.keys())[0] if style is None and len(self.parameters_with_set_values) > 1: style = self.parameters_with_set_values[1] fig, axes = plt.subplots(figsize=figsize) @@ -1356,10 +1360,11 @@ def custom_metric(ref: np.ndarray, query: np.ndarray, union_mask, **kwargs) -> f # here union_mask is a binary mask that can be used to filter pixel to use for calculations # Calculate and return the metric value """ + current_metrics = list(self.metrics.keys()) for m in range(len(custom_metrics)): metric_name = custom_metrics[m].__name__ - if metric_name not in self.analysis_parameters["metrics_list"]: - self.analysis_parameters["metrics_list"].append(metric_name) + if metric_name not in current_metrics: + #self.analysis_parameters["metrics_list"].append(metric_name) self.plot_parameters[metric_name] = dict() # change plot parameters to different method if heatmap_params is not None: @@ -1423,6 +1428,7 @@ def run_parameter_sweep( # for plot generation na_as_zero = True, custom_metrics: list[callable] = None, + default_metrics = ["ssim", "pearson"], #custom_metric_name: str = None, plot_parameters=None # Add more as needed for your sweep @@ -1571,6 +1577,7 @@ def run_parameter_sweep( reference_probe=reference_probe, **reference_parameters) sweep_gen.set_na_as_zero_in_plots(na_as_zero=na_as_zero) + sweep_gen.use_default_metrics(metrics=default_metrics) if custom_metrics is not None: sweep_gen.add_custom_analysis_metrics( custom_metrics=custom_metrics