From a5c85da24b235f5c36737a6d47e740bc645da222 Mon Sep 17 00:00:00 2001 From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com> Date: Mon, 7 Jul 2025 14:17:38 +0200 Subject: [PATCH 1/6] use binning option for fusion --- src/napari_stitcher/_stitcher_widget.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/napari_stitcher/_stitcher_widget.py b/src/napari_stitcher/_stitcher_widget.py index 8ed463f..548a482 100644 --- a/src/napari_stitcher/_stitcher_widget.py +++ b/src/napari_stitcher/_stitcher_widget.py @@ -77,7 +77,7 @@ def __init__(self, napari_viewer): choices=[], tooltip='Choose a file to process using napari-stitcher.') - self.custom_reg_binning = widgets.CheckBox(value=False, text='Use custom registration binning') + self.custom_reg_binning = widgets.CheckBox(value=False, text='Use custom binning') self.x_reg_binning = widgets.Slider(value=1, min=1, max=10, label='X binning:') self.y_reg_binning = widgets.Slider(value=1, min=1, max=10, label='Y binning:') @@ -363,6 +363,10 @@ def run_fusion(self): """ channels = self.reg_ch_picker.choices + if self.custom_reg_binning.value: + fusion_binning = {'y': self.x_reg_binning.value, 'x': self.y_reg_binning.value} + else: + fusion_binning = None for _, ch in enumerate(channels): @@ -382,6 +386,7 @@ def run_fusion(self): transform_key='affine_registered' if self.visualization_type_rbuttons.value == CHOICE_REGISTERED else 'affine_metadata', + output_spacing=fusion_binning, ) fused = fused.expand_dims({'c': [sims[0].coords['c'].values]}) From cf545e9c7d0aa9ffdfc3cba04a51a4a35bea23e7 Mon Sep 17 00:00:00 2001 From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com> Date: Mon, 7 Jul 2025 14:29:34 +0200 Subject: [PATCH 2/6] retrieve z-spacing since it's not set --- src/napari_stitcher/_stitcher_widget.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/napari_stitcher/_stitcher_widget.py b/src/napari_stitcher/_stitcher_widget.py index 548a482..b3a2dda 100644 --- a/src/napari_stitcher/_stitcher_widget.py +++ b/src/napari_stitcher/_stitcher_widget.py @@ -381,6 +381,13 @@ def run_fusion(self): self.times_slider.value[1] + 1)]}) for sim in sims] + # check which keys are in spacing that are missing in fusion_binning and add them + if fusion_binning is not None: + spacing = spatial_image_utils.get_spacing_from_sim(sims[0]) + for key in spacing.keys(): + if key not in fusion_binning: + fusion_binning[key] = spacing[key] + fused = fusion.fuse( sims, transform_key='affine_registered' From ce76d199ae6a3ce7501db4969e758a91d80bfc87 Mon Sep 17 00:00:00 2001 From: Johannes Soltwedel <38459088+jo-mueller@users.noreply.github.com> Date: Mon, 7 Jul 2025 14:57:43 +0200 Subject: [PATCH 3/6] add test for binning in fusion --- src/napari_stitcher/_tests/test_stitcher_widget.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/napari_stitcher/_tests/test_stitcher_widget.py b/src/napari_stitcher/_tests/test_stitcher_widget.py index 5973657..1eae550 100644 --- a/src/napari_stitcher/_tests/test_stitcher_widget.py +++ b/src/napari_stitcher/_tests/test_stitcher_widget.py @@ -224,6 +224,12 @@ def test_fusion_without_registration(make_napari_viewer): #check that fusion can also be run twice stitcher_widget.run_fusion() + # turn on custom binning + stitcher_widget.custom_reg_binning.value = True + + #run fusion with binning + stitcher_widget.run_fusion() + def test_vanilla_layers_2D_no_time(make_napari_viewer): From 534eabd4a23285df407a1e626a57215d83ccbedb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= <38459088+jo-mueller@users.noreply.github.com> Date: Tue, 15 Jul 2025 09:54:21 +0200 Subject: [PATCH 4/6] added fusion binning as separate option in UI --- src/napari_stitcher/_stitcher_widget.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/napari_stitcher/_stitcher_widget.py b/src/napari_stitcher/_stitcher_widget.py index b3a2dda..cdb5147 100644 --- a/src/napari_stitcher/_stitcher_widget.py +++ b/src/napari_stitcher/_stitcher_widget.py @@ -77,10 +77,14 @@ def __init__(self, napari_viewer): choices=[], tooltip='Choose a file to process using napari-stitcher.') - self.custom_reg_binning = widgets.CheckBox(value=False, text='Use custom binning') + self.custom_reg_binning = widgets.CheckBox(value=False, text='Use custom binning for registration') self.x_reg_binning = widgets.Slider(value=1, min=1, max=10, label='X binning:') self.y_reg_binning = widgets.Slider(value=1, min=1, max=10, label='Y binning:') + self.custom_fuse_binning = widgets.CheckBox(value=False, text='Use custom binning for fusion') + self.x_fuse_binning = widgets.Slider(value=1, min=1, max=10, label='X binning:') + self.y_fuse_binning = widgets.Slider(value=1, min=1, max=10, label='Y binning:') + self.do_quality_filter = widgets.CheckBox(value=False, text='Filter registrations by quality') self.quality_threshold = widgets.FloatSlider(value=0.2, min=0, max=1, label='Quality threshold:') From e5ced9800d1bdd4805d9cbc357bebf970c7ee417 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= <38459088+jo-mueller@users.noreply.github.com> Date: Tue, 15 Jul 2025 09:54:31 +0200 Subject: [PATCH 5/6] add new widgets to UI --- src/napari_stitcher/_stitcher_widget.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/napari_stitcher/_stitcher_widget.py b/src/napari_stitcher/_stitcher_widget.py index cdb5147..9eac23c 100644 --- a/src/napari_stitcher/_stitcher_widget.py +++ b/src/napari_stitcher/_stitcher_widget.py @@ -139,6 +139,9 @@ def __init__(self, napari_viewer): self.custom_reg_binning, self.x_reg_binning, self.y_reg_binning, + self.custom_fuse_binning, + self.x_fuse_binning, + self.y_fuse_binning, self.do_quality_filter, self.quality_threshold, self.pair_pruning_method, From b5b4bf623c0bbe8d53e4953fe8497b1436342219 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= <38459088+jo-mueller@users.noreply.github.com> Date: Tue, 15 Jul 2025 09:54:56 +0200 Subject: [PATCH 6/6] correctly infer new spacing from binning --- src/napari_stitcher/_stitcher_widget.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/napari_stitcher/_stitcher_widget.py b/src/napari_stitcher/_stitcher_widget.py index 9eac23c..4e05ae0 100644 --- a/src/napari_stitcher/_stitcher_widget.py +++ b/src/napari_stitcher/_stitcher_widget.py @@ -370,10 +370,6 @@ def run_fusion(self): """ channels = self.reg_ch_picker.choices - if self.custom_reg_binning.value: - fusion_binning = {'y': self.x_reg_binning.value, 'x': self.y_reg_binning.value} - else: - fusion_binning = None for _, ch in enumerate(channels): @@ -389,18 +385,22 @@ def run_fusion(self): for sim in sims] # check which keys are in spacing that are missing in fusion_binning and add them - if fusion_binning is not None: - spacing = spatial_image_utils.get_spacing_from_sim(sims[0]) - for key in spacing.keys(): - if key not in fusion_binning: - fusion_binning[key] = spacing[key] + if self.custom_fuse_binning.value: + fusion_binning = {'y': self.x_fuse_binning.value, 'x': self.x_fuse_binning.value} + fusing_spacing = spatial_image_utils.get_spacing_from_sim(sims[0]) + fusing_spacing = { + key: fusing_spacing[key] * fusion_binning[key] + for key in fusing_spacing.keys() if key in fusion_binning + } + else: + fusing_spacing = None fused = fusion.fuse( sims, transform_key='affine_registered' if self.visualization_type_rbuttons.value == CHOICE_REGISTERED else 'affine_metadata', - output_spacing=fusion_binning, + output_spacing=fusing_spacing, ) fused = fused.expand_dims({'c': [sims[0].coords['c'].values]})