tomwer 1.2.8__py3-none-any.whl → 1.3.0a0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- orangecontrib/tomwer/tutorials/icat_publication.ows +58 -0
- orangecontrib/tomwer/widgets/__init__.py +1 -0
- orangecontrib/tomwer/widgets/control/DataDiscoveryOW.py +2 -2
- orangecontrib/tomwer/widgets/control/DataListOW.py +9 -7
- orangecontrib/tomwer/widgets/control/DataSelectorOW.py +21 -10
- orangecontrib/tomwer/widgets/control/EDF2NXTomomillOW.py +11 -5
- orangecontrib/tomwer/widgets/control/EmailOW.py +4 -4
- orangecontrib/tomwer/widgets/control/NXTomomillOW.py +31 -18
- orangecontrib/tomwer/widgets/control/NXtomoConcatenate.py +14 -7
- orangecontrib/tomwer/widgets/control/NotifierOW.py +1 -0
- orangecontrib/tomwer/widgets/control/VolumeSelector.py +7 -4
- orangecontrib/tomwer/widgets/control/VolumeSymLinkOW.py +182 -182
- orangecontrib/tomwer/widgets/debugtools/DatasetGeneratorOW.py +4 -4
- orangecontrib/tomwer/widgets/edit/DarkFlatPatchOW.py +4 -4
- orangecontrib/tomwer/widgets/edit/ImageKeyEditorOW.py +3 -3
- orangecontrib/tomwer/widgets/edit/ImageKeyUpgraderOW.py +2 -0
- orangecontrib/tomwer/widgets/edit/NXtomoEditorOW.py +3 -3
- orangecontrib/tomwer/widgets/edit/test/test_nxtomo_editor.py +3 -3
- orangecontrib/tomwer/widgets/icat/PublishProcessedDataOW.py +115 -0
- orangecontrib/tomwer/widgets/icat/RawDataScreenshotCreatorOW.py +98 -0
- orangecontrib/tomwer/widgets/icat/SaveToGalleryAndPublishOW.py +129 -0
- orangecontrib/tomwer/widgets/icat/__init__.py +13 -0
- orangecontrib/tomwer/widgets/icat/icons/add_gallery.png +0 -0
- orangecontrib/tomwer/widgets/icat/icons/add_gallery.svg +82 -0
- orangecontrib/tomwer/widgets/icat/icons/publish_processed_data.png +0 -0
- orangecontrib/tomwer/widgets/icat/icons/publish_processed_data.svg +95 -0
- orangecontrib/tomwer/widgets/icat/icons/raw_screenshots.png +0 -0
- orangecontrib/tomwer/widgets/icat/icons/raw_screenshots.svg +143 -0
- orangecontrib/tomwer/widgets/icons/tomwer_data_portal.png +0 -0
- orangecontrib/tomwer/widgets/icons/tomwer_data_portal.svg +76 -0
- orangecontrib/tomwer/widgets/reconstruction/AxisOW.py +9 -8
- orangecontrib/tomwer/widgets/reconstruction/CastNabuVolumeOW.py +3 -3
- orangecontrib/tomwer/widgets/reconstruction/NabuHelicalPrepareWeightsDoubleOW.py +179 -169
- orangecontrib/tomwer/widgets/reconstruction/NabuOW.py +23 -0
- orangecontrib/tomwer/widgets/reconstruction/NabuVolumeOW.py +39 -5
- orangecontrib/tomwer/widgets/reconstruction/SAAxisOW.py +7 -13
- orangecontrib/tomwer/widgets/reconstruction/SADeltaBetaOW.py +7 -17
- orangecontrib/tomwer/widgets/reconstruction/SinoNormOW.py +3 -4
- orangecontrib/tomwer/widgets/visualization/LivesliceOW.py +1 -1
- orangecontrib/tomwer/widgets/visualization/NXtomoMetadataViewerOW.py +3 -3
- orangecontrib/tomwer/widgets/visualization/VolumeViewerOW.py +3 -29
- tomwer/__main__.py +11 -58
- tomwer/app/canvas.py +8 -0
- tomwer/app/canvas_launcher/config.py +13 -11
- tomwer/app/darkref.py +1 -1
- tomwer/app/darkrefpatch.py +1 -1
- tomwer/app/imagekeyeditor.py +5 -5
- tomwer/app/imagekeyupgrader.py +5 -5
- tomwer/app/intensitynormalization.py +2 -2
- tomwer/app/radiostack.py +2 -2
- tomwer/app/zstitching.py +74 -3
- tomwer/core/cluster/cluster.py +26 -0
- tomwer/core/log/logger.py +7 -5
- tomwer/core/process/conditions/filters.py +1 -1
- tomwer/core/process/control/datalistener/datalistener.py +3 -3
- tomwer/core/process/control/nxtomoconcatenate.py +13 -13
- tomwer/core/process/control/nxtomomill.py +83 -25
- tomwer/core/process/control/scantransfer.py +11 -10
- tomwer/core/process/control/scanvalidator.py +3 -2
- tomwer/core/process/control/test/test_concatenate_nxtomos.py +9 -9
- tomwer/core/process/control/test/test_email.py +4 -4
- tomwer/core/process/control/test/test_h52nx_process.py +59 -7
- tomwer/core/process/control/test/test_volume_link.py +64 -64
- tomwer/core/process/control/timer.py +1 -1
- tomwer/core/process/control/volumesymlink.py +200 -200
- tomwer/core/process/edit/darkflatpatch.py +6 -6
- tomwer/core/process/edit/imagekeyeditor.py +17 -18
- tomwer/core/process/icat/__init__.py +0 -0
- tomwer/core/process/icat/createscreenshots.py +100 -0
- tomwer/core/process/icat/gallery.py +377 -0
- tomwer/core/process/icat/icatbase.py +36 -0
- tomwer/core/process/icat/publish.py +228 -0
- tomwer/core/process/icat/screenshots.py +26 -0
- tomwer/core/process/output.py +52 -0
- tomwer/core/process/reconstruction/axis/axis.py +17 -10
- tomwer/core/process/reconstruction/axis/mode.py +4 -0
- tomwer/core/process/reconstruction/axis/params.py +9 -4
- tomwer/core/process/reconstruction/darkref/darkrefs.py +8 -6
- tomwer/core/process/reconstruction/darkref/darkrefscopy.py +1 -1
- tomwer/core/process/reconstruction/darkref/params.py +1 -1
- tomwer/core/process/reconstruction/lamino/tofu.py +4 -4
- tomwer/core/process/reconstruction/nabu/castvolume.py +1 -1
- tomwer/core/process/reconstruction/nabu/helical.py +9 -5
- tomwer/core/process/reconstruction/nabu/nabucommon.py +32 -62
- tomwer/core/process/reconstruction/nabu/nabuscores.py +387 -61
- tomwer/core/process/reconstruction/nabu/nabuslices.py +33 -21
- tomwer/core/process/reconstruction/nabu/nabuvolume.py +37 -14
- tomwer/core/process/reconstruction/nabu/settings.py +2 -2
- tomwer/core/process/reconstruction/nabu/utils.py +129 -24
- tomwer/core/process/reconstruction/output.py +108 -0
- tomwer/core/process/reconstruction/saaxis/saaxis.py +233 -263
- tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py +140 -86
- tomwer/core/process/reconstruction/scores/params.py +4 -1
- tomwer/core/process/reconstruction/scores/scores.py +13 -0
- tomwer/core/process/reconstruction/test/test_axis_params.py +2 -2
- tomwer/core/process/reconstruction/test/test_darkref.py +3 -3
- tomwer/core/process/reconstruction/test/test_darkref_copy.py +3 -3
- tomwer/core/process/reconstruction/test/test_saaxis.py +3 -4
- tomwer/core/process/reconstruction/test/test_sadeltabeta.py +2 -2
- tomwer/core/process/stitching/nabustitcher.py +2 -2
- tomwer/core/process/test/test_axis.py +6 -6
- tomwer/core/process/test/test_dark_and_flat.py +10 -7
- tomwer/core/process/test/test_data_transfer.py +7 -6
- tomwer/core/process/test/test_nabu.py +4 -4
- tomwer/core/process/test/test_normalization.py +2 -2
- tomwer/core/scan/edfscan.py +4 -1
- tomwer/core/scan/hdf5scan.py +19 -500
- tomwer/core/scan/nxtomoscan.py +532 -0
- tomwer/core/scan/scanbase.py +42 -20
- tomwer/core/scan/scanfactory.py +13 -13
- tomwer/core/scan/test/test_future_scan.py +2 -2
- tomwer/core/scan/test/test_h5.py +12 -10
- tomwer/core/scan/test/test_process_registration.py +2 -2
- tomwer/core/scan/test/test_scan.py +4 -3
- tomwer/core/settings.py +20 -0
- tomwer/core/test/test_scanutils.py +8 -7
- tomwer/core/test/test_utils.py +33 -26
- tomwer/core/utils/__init__.py +0 -466
- tomwer/core/utils/deprecation.py +1 -1
- tomwer/core/utils/dictutils.py +14 -0
- tomwer/core/utils/lbsram.py +35 -0
- tomwer/core/utils/nxtomoutils.py +1 -1
- tomwer/core/utils/scanutils.py +6 -6
- tomwer/core/utils/spec.py +263 -0
- tomwer/core/volume/volumefactory.py +2 -2
- tomwer/gui/cluster/slurm.py +260 -60
- tomwer/gui/cluster/test/test_cluster.py +13 -0
- tomwer/gui/cluster/test/test_supervisor.py +2 -2
- tomwer/gui/configuration/__init__.py +0 -0
- tomwer/gui/{reconstruction/nabu → configuration}/action.py +1 -32
- tomwer/gui/configuration/level.py +22 -0
- tomwer/gui/control/actions.py +54 -0
- tomwer/gui/control/datalist.py +78 -16
- tomwer/gui/control/datalistener.py +4 -16
- tomwer/gui/control/{email.py → emailnotifier.py} +9 -18
- tomwer/gui/control/history.py +2 -2
- tomwer/gui/control/observations.py +2 -2
- tomwer/gui/control/reducedarkflatselector.py +1 -1
- tomwer/gui/control/selectorwidgetbase.py +36 -9
- tomwer/gui/control/serie/seriecreator.py +5 -22
- tomwer/gui/control/test/test_email.py +1 -1
- tomwer/gui/control/test/test_scanvalidator.py +6 -5
- tomwer/gui/control/test/test_single_tomo_obj.py +2 -2
- tomwer/gui/control/tomoobjdisplaymode.py +8 -0
- tomwer/gui/debugtools/datasetgenerator.py +3 -3
- tomwer/gui/edit/dkrfpatch.py +16 -22
- tomwer/gui/edit/imagekeyeditor.py +8 -11
- tomwer/gui/edit/nxtomoeditor.py +111 -44
- tomwer/gui/edit/nxtomowarmer.py +4 -4
- tomwer/gui/edit/test/test_dkrf_patch.py +7 -7
- tomwer/gui/edit/test/test_image_key_editor.py +3 -3
- tomwer/gui/edit/test/test_nx_editor.py +40 -16
- tomwer/gui/icat/__init__.py +0 -0
- tomwer/gui/icat/createscreenshots.py +80 -0
- tomwer/gui/icat/gallery.py +214 -0
- tomwer/gui/icat/publish.py +187 -0
- tomwer/gui/reconstruction/axis/axis.py +171 -57
- tomwer/gui/reconstruction/axis/radioaxis.py +80 -95
- tomwer/gui/reconstruction/darkref/darkrefcopywidget.py +3 -2
- tomwer/gui/reconstruction/lamino/tofu/projections.py +1 -1
- tomwer/gui/reconstruction/lamino/tofu/tofuoutput.py +3 -6
- tomwer/gui/reconstruction/nabu/castvolume.py +1 -1
- tomwer/gui/reconstruction/nabu/check.py +9 -9
- tomwer/gui/reconstruction/nabu/helical.py +29 -12
- tomwer/gui/reconstruction/nabu/nabuconfig/base.py +2 -4
- tomwer/gui/reconstruction/nabu/nabuconfig/output.py +110 -33
- tomwer/gui/reconstruction/nabu/nabuconfig/phase.py +9 -12
- tomwer/gui/reconstruction/nabu/nabuconfig/preprocessing.py +219 -29
- tomwer/gui/reconstruction/nabu/nabuconfig/reconstruction.py +3 -6
- tomwer/gui/reconstruction/nabu/nabuflow.py +12 -20
- tomwer/gui/reconstruction/nabu/slices.py +6 -7
- tomwer/gui/reconstruction/nabu/volume.py +22 -10
- tomwer/gui/reconstruction/normalization/intensity.py +15 -23
- tomwer/gui/reconstruction/saaxis/corrangeselector.py +7 -23
- tomwer/gui/reconstruction/saaxis/dimensionwidget.py +1 -1
- tomwer/gui/reconstruction/saaxis/saaxis.py +7 -9
- tomwer/gui/reconstruction/sadeltabeta/saadeltabeta.py +2 -1
- tomwer/gui/reconstruction/scores/control.py +2 -9
- tomwer/gui/reconstruction/scores/scoreplot.py +11 -5
- tomwer/gui/reconstruction/test/test_axis.py +23 -12
- tomwer/gui/reconstruction/test/test_lamino.py +8 -3
- tomwer/gui/reconstruction/test/test_nabu.py +28 -9
- tomwer/gui/reconstruction/test/test_saaxis.py +3 -3
- tomwer/gui/reconstruction/test/test_sadeltabeta.py +2 -2
- tomwer/gui/settings.py +5 -28
- tomwer/gui/stackplot.py +2 -5
- tomwer/gui/stitching/action.py +49 -0
- tomwer/gui/stitching/config/axisparams.py +7 -24
- tomwer/gui/stitching/config/output.py +10 -8
- tomwer/gui/stitching/config/positionoveraxis.py +22 -23
- tomwer/gui/stitching/normalization.py +117 -0
- tomwer/gui/stitching/stitchandbackground.py +4 -6
- tomwer/gui/stitching/stitching.py +265 -43
- tomwer/gui/stitching/stitching_preview.py +62 -5
- tomwer/gui/stitching/stitching_raw.py +2 -5
- tomwer/gui/stitching/z_stitching/fineestimation.py +0 -60
- tomwer/gui/utils/buttons.py +112 -29
- tomwer/gui/utils/inputwidget.py +33 -25
- tomwer/gui/utils/scandescription.py +4 -0
- tomwer/gui/utils/step.py +144 -0
- tomwer/gui/utils/unitsystem.py +2 -5
- tomwer/gui/utils/vignettes.py +176 -15
- tomwer/gui/visualization/dataviewer.py +1 -18
- tomwer/gui/visualization/diffviewer/diffviewer.py +7 -16
- tomwer/gui/visualization/diffviewer/shiftwidget.py +2 -5
- tomwer/gui/visualization/scanoverview.py +1 -1
- tomwer/gui/visualization/sinogramviewer.py +1 -10
- tomwer/gui/visualization/test/test_diffviewer.py +3 -3
- tomwer/gui/visualization/test/test_nx_tomo_metadata_viewer.py +4 -4
- tomwer/gui/visualization/test/test_sinogramviewer.py +2 -2
- tomwer/gui/visualization/test/test_stacks.py +3 -3
- tomwer/gui/visualization/test/test_volumeviewer.py +2 -2
- tomwer/io/utils/raw_and_processed_data.py +84 -0
- tomwer/io/utils/tomoobj.py +4 -6
- tomwer/resources/gui/icons/ruler.png +0 -0
- tomwer/resources/gui/icons/ruler.svg +273 -0
- tomwer/resources/gui/icons/short_description.png +0 -0
- tomwer/resources/gui/icons/short_description.svg +58 -0
- tomwer/resources/gui/icons/url.png +0 -0
- tomwer/resources/gui/icons/url.svg +58 -0
- tomwer/synctools/stacks/edit/darkflatpatch.py +2 -2
- tomwer/synctools/stacks/edit/imagekeyeditor.py +2 -2
- tomwer/synctools/stacks/reconstruction/axis.py +4 -4
- tomwer/synctools/stacks/reconstruction/castvolume.py +2 -2
- tomwer/synctools/stacks/reconstruction/dkrefcopy.py +4 -10
- tomwer/synctools/stacks/reconstruction/nabu.py +2 -2
- tomwer/synctools/stacks/reconstruction/normalization.py +2 -2
- tomwer/synctools/stacks/reconstruction/saaxis.py +2 -2
- tomwer/synctools/stacks/reconstruction/sadeltabeta.py +2 -2
- tomwer/synctools/test/test_darkRefs.py +7 -58
- tomwer/synctools/test/test_foldertransfer.py +6 -6
- tomwer/synctools/utils/scanstages.py +6 -6
- tomwer/tests/conftest.py +34 -0
- tomwer/tests/datasets.py +13 -0
- tomwer/tests/test_scripts.py +92 -39
- tomwer/tests/utils.py +5 -0
- tomwer/version.py +3 -3
- {tomwer-1.2.8.dist-info → tomwer-1.3.0a0.dist-info}/METADATA +39 -44
- {tomwer-1.2.8.dist-info → tomwer-1.3.0a0.dist-info}/RECORD +248 -209
- tomwer/resources/gui/icons/esrf_1.svg +0 -307
- tomwer/resources/gui/icons/triangle.svg +0 -80
- tomwer/synctools/test/test_scanstages.py +0 -162
- tomwer/tests/utils/__init__.py +0 -247
- tomwer/tests/utils/utilstest.py +0 -220
- /tomwer/app/{saaxis.py → multicor.py} +0 -0
- /tomwer/app/{sadeltabeta.py → multipag.py} +0 -0
- /tomwer/core/process/control/{email.py → emailnotifier.py} +0 -0
- /tomwer-1.2.8-py3.11-nspkg.pth → /tomwer-1.3.0a0-py3.11-nspkg.pth +0 -0
- {tomwer-1.2.8.dist-info → tomwer-1.3.0a0.dist-info}/LICENSE +0 -0
- {tomwer-1.2.8.dist-info → tomwer-1.3.0a0.dist-info}/WHEEL +0 -0
- {tomwer-1.2.8.dist-info → tomwer-1.3.0a0.dist-info}/entry_points.txt +0 -0
- {tomwer-1.2.8.dist-info → tomwer-1.3.0a0.dist-info}/namespace_packages.txt +0 -0
- {tomwer-1.2.8.dist-info → tomwer-1.3.0a0.dist-info}/top_level.txt +0 -0
@@ -37,7 +37,8 @@ from silx.gui import qt
|
|
37
37
|
|
38
38
|
from tomwer.core import settings
|
39
39
|
from tomwer.gui.reconstruction.lamino.tofu import TofuWindow
|
40
|
-
from tomwer.tests.
|
40
|
+
from tomwer.tests.datasets import TomwerCIDatasets
|
41
|
+
from tomwer.tests.utils import skip_gui_test
|
41
42
|
|
42
43
|
|
43
44
|
@pytest.mark.skipif(skip_gui_test(), reason="skip gui test")
|
@@ -59,7 +60,9 @@ class TestLamino(unittest.TestCase):
|
|
59
60
|
|
60
61
|
def testSetup(self):
|
61
62
|
"""Make sure the widget is correctly setting parameters from a scan"""
|
62
|
-
dataset =
|
63
|
+
dataset = TomwerCIDatasets.get_dataset(
|
64
|
+
"edf_datasets/test01",
|
65
|
+
)
|
63
66
|
self._window.loadFromScan(dataset)
|
64
67
|
reconsParams = self._widget.getParameters()
|
65
68
|
# check general information
|
@@ -101,7 +104,9 @@ class TestLamino(unittest.TestCase):
|
|
101
104
|
outputWidget.setOutput("toto")
|
102
105
|
outputWidget.lockOutput()
|
103
106
|
|
104
|
-
dataset =
|
107
|
+
dataset = TomwerCIDatasets.get_dataset(
|
108
|
+
"edf_datasets/test01",
|
109
|
+
)
|
105
110
|
self._window.loadFromScan(dataset)
|
106
111
|
|
107
112
|
self.assertTrue(inputWidget.rotationAngle._overallAngle.getAngle() == 12.0)
|
@@ -37,7 +37,7 @@ from tomwer.gui.reconstruction.nabu.nabuconfig.output import _NabuOutputConfig
|
|
37
37
|
from tomwer.gui.reconstruction.nabu.nabuconfig.phase import _NabuPhaseConfig
|
38
38
|
from tomwer.gui.reconstruction.nabu.nabuconfig.preprocessing import (
|
39
39
|
_NabuPreProcessingConfig,
|
40
|
-
|
40
|
+
RingCorrectionMethod,
|
41
41
|
)
|
42
42
|
from tomwer.gui.reconstruction.nabu.nabuconfig.reconstruction import (
|
43
43
|
_NabuReconstructionConfig,
|
@@ -45,6 +45,7 @@ from tomwer.gui.reconstruction.nabu.nabuconfig.reconstruction import (
|
|
45
45
|
from tomwer.gui.reconstruction.nabu.nabuflow import NabuFlowControl
|
46
46
|
from tomwer.gui.reconstruction.nabu.volume import NabuVolumeWidget
|
47
47
|
from tomwer.tests.utils import skip_gui_test
|
48
|
+
from tomwer.core.process.output import ProcessDataOutputDirMode
|
48
49
|
|
49
50
|
|
50
51
|
class ProcessClass:
|
@@ -119,8 +120,8 @@ class TestNabuPreProcConfig(TestCaseQt):
|
|
119
120
|
"log_max_clip": 10.0,
|
120
121
|
"take_logarithm": True,
|
121
122
|
"normalize_srcurrent": 0,
|
122
|
-
"sino_rings_correction":
|
123
|
-
"sino_rings_options": "sigma=1.0 ; levels=10",
|
123
|
+
"sino_rings_correction": RingCorrectionMethod.NONE.value,
|
124
|
+
"sino_rings_options": "sigma=1.0 ; levels=10 ; padding=False",
|
124
125
|
"tilt_correction": "",
|
125
126
|
"autotilt_options": "",
|
126
127
|
}
|
@@ -138,8 +139,8 @@ class TestNabuPreProcConfig(TestCaseQt):
|
|
138
139
|
"log_max_clip": 250.0,
|
139
140
|
"take_logarithm": False,
|
140
141
|
"normalize_srcurrent": 1,
|
141
|
-
"sino_rings_correction":
|
142
|
-
"sino_rings_options": "sigma=1.4 ; levels=11",
|
142
|
+
"sino_rings_correction": RingCorrectionMethod.MUNCH.value,
|
143
|
+
"sino_rings_options": "sigma=1.4 ; levels=11 ; padding=True",
|
143
144
|
"tilt_correction": "1d-correlation",
|
144
145
|
"autotilt_options": "low_pass=1; high_pass=20",
|
145
146
|
}
|
@@ -303,17 +304,25 @@ class TestNabuOutputConfig(TestCaseQt):
|
|
303
304
|
self.qapp.processEvents()
|
304
305
|
|
305
306
|
def testGetConfiguration(self):
|
306
|
-
ini_conf = {
|
307
|
+
ini_conf = {
|
308
|
+
"file_format": "hdf5",
|
309
|
+
"location": "",
|
310
|
+
"output_dir_mode": "same folder as scan",
|
311
|
+
}
|
307
312
|
self.assertEqual(self.nabuWidget.getConfiguration(), ini_conf)
|
308
313
|
|
309
314
|
def testSetConfiguration(self):
|
310
|
-
conf = {
|
315
|
+
conf = {
|
316
|
+
"file_format": "tiff",
|
317
|
+
"location": os.sep.join(("tmp", "my_output")),
|
318
|
+
"output_dir_mode": "other",
|
319
|
+
}
|
311
320
|
self.nabuWidget.setConfiguration(conf)
|
312
321
|
self.nabuWidget.show()
|
313
322
|
self.qapp.processEvents()
|
314
323
|
# check some widget visibility
|
315
324
|
self.assertTrue(self.nabuWidget._output_dir_widget._outputDirQLE.isVisible())
|
316
|
-
self.
|
325
|
+
self.assertTrue(self.nabuWidget._output_dir_widget._otherDirRB.isChecked())
|
317
326
|
|
318
327
|
self.assertEqual(self.nabuWidget.getConfiguration(), conf)
|
319
328
|
|
@@ -323,6 +332,7 @@ class TestNabuVolumeWidget(TestCaseQt):
|
|
323
332
|
def setUp(self):
|
324
333
|
TestCaseQt.setUp(self)
|
325
334
|
self.nabuWidget = NabuVolumeWidget(parent=None)
|
335
|
+
self.nabuWidget.setConfigurationLevel("advanced")
|
326
336
|
|
327
337
|
def tearDown(self):
|
328
338
|
self.nabuWidget.setAttribute(qt.Qt.WA_DeleteOnClose)
|
@@ -334,6 +344,8 @@ class TestNabuVolumeWidget(TestCaseQt):
|
|
334
344
|
"start_z": 0,
|
335
345
|
"end_z": -1,
|
336
346
|
"gpu_mem_fraction": 0.9,
|
347
|
+
"output_dir_mode": ProcessDataOutputDirMode.IN_SCAN_FOLDER.value,
|
348
|
+
"overwrite_output_location": False,
|
337
349
|
"postproc": {"output_histogram": 1},
|
338
350
|
"cpu_mem_fraction": 0.9,
|
339
351
|
"use_phase_margin": True,
|
@@ -354,6 +366,13 @@ class TestNabuVolumeWidget(TestCaseQt):
|
|
354
366
|
"new_output_location": "/new/location",
|
355
367
|
}
|
356
368
|
self.nabuWidget.setConfiguration(conf)
|
357
|
-
self.nabuWidget.show()
|
358
369
|
self.qapp.processEvents()
|
370
|
+
|
371
|
+
# update the config dict has setting an other custom output directory update some items
|
372
|
+
conf.update(
|
373
|
+
{
|
374
|
+
"overwrite_output_location": True,
|
375
|
+
"output_dir_mode": ProcessDataOutputDirMode.OTHER.value,
|
376
|
+
}
|
377
|
+
)
|
359
378
|
self.assertEqual(self.nabuWidget.getConfiguration(), conf)
|
@@ -37,7 +37,7 @@ import pytest
|
|
37
37
|
from silx.gui import qt
|
38
38
|
from silx.gui.utils.testutils import TestCaseQt
|
39
39
|
from silx.io.url import DataUrl
|
40
|
-
from
|
40
|
+
from pyunitsystem import metricsystem
|
41
41
|
|
42
42
|
from tomwer.core.process.reconstruction.saaxis.params import (
|
43
43
|
ReconstructionMode,
|
@@ -45,7 +45,7 @@ from tomwer.core.process.reconstruction.saaxis.params import (
|
|
45
45
|
)
|
46
46
|
from tomwer.core.process.reconstruction.scores import ComputedScore
|
47
47
|
from tomwer.core.process.reconstruction.scores.params import ScoreMethod
|
48
|
-
from tomwer.core.utils.scanutils import
|
48
|
+
from tomwer.core.utils.scanutils import MockNXtomo
|
49
49
|
from tomwer.gui.reconstruction.saaxis.dimensionwidget import DimensionWidget
|
50
50
|
from tomwer.gui.reconstruction.saaxis.saaxis import SAAxisWindow
|
51
51
|
from tomwer.tests.utils import skip_gui_test
|
@@ -144,7 +144,7 @@ class TestSAAxisWindow(TestCaseQt):
|
|
144
144
|
# create a scan
|
145
145
|
self.folder = tempfile.mkdtemp()
|
146
146
|
dim = 10
|
147
|
-
mock =
|
147
|
+
mock = MockNXtomo(
|
148
148
|
scan_path=self.folder, n_proj=10, n_ini_proj=10, scan_range=180, dim=dim
|
149
149
|
)
|
150
150
|
mock.add_alignment_radio(index=10, angle=90)
|
@@ -41,7 +41,7 @@ from silx.io.url import DataUrl
|
|
41
41
|
from tomwer.core.process.reconstruction.sadeltabeta.params import SADeltaBetaParams
|
42
42
|
from tomwer.core.process.reconstruction.scores import ComputedScore
|
43
43
|
from tomwer.core.process.reconstruction.scores.params import ScoreMethod
|
44
|
-
from tomwer.core.utils.scanutils import
|
44
|
+
from tomwer.core.utils.scanutils import MockNXtomo
|
45
45
|
from tomwer.gui.reconstruction.sadeltabeta import SADeltaBetaWindow
|
46
46
|
from tomwer.tests.utils import skip_gui_test
|
47
47
|
|
@@ -75,7 +75,7 @@ class TestSADeltaBetaWindow(TestCaseQt):
|
|
75
75
|
# create a scan
|
76
76
|
self.folder = tempfile.mkdtemp()
|
77
77
|
dim = 10
|
78
|
-
mock =
|
78
|
+
mock = MockNXtomo(
|
79
79
|
scan_path=self.folder, n_proj=10, n_ini_proj=10, scan_range=180, dim=dim
|
80
80
|
)
|
81
81
|
mock.add_alignment_radio(index=10, angle=90)
|
tomwer/gui/settings.py
CHANGED
@@ -1,31 +1,8 @@
|
|
1
|
-
|
2
|
-
# /*##########################################################################
|
3
|
-
#
|
4
|
-
# Copyright (c) 2016-2017 European Synchrotron Radiation Facility
|
5
|
-
#
|
6
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
-
# of this software and associated documentation files (the "Software"), to deal
|
8
|
-
# in the Software without restriction, including without limitation the rights
|
9
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
-
# copies of the Software, and to permit persons to whom the Software is
|
11
|
-
# furnished to do so, subject to the following conditions:
|
12
|
-
#
|
13
|
-
# The above copyright notice and this permission notice shall be included in
|
14
|
-
# all copies or substantial portions of the Software.
|
15
|
-
#
|
16
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22
|
-
# THE SOFTWARE.
|
23
|
-
#
|
24
|
-
# ###########################################################################*/
|
25
|
-
|
26
|
-
__authors__ = ["H. Payno"]
|
27
|
-
__license__ = "MIT"
|
28
|
-
__date__ = "05/11/2018"
|
1
|
+
from silx.gui import qt
|
29
2
|
|
30
3
|
|
31
4
|
Y_AXIS_DOWNWARD = True
|
5
|
+
"""Default axis direction Y"""
|
6
|
+
|
7
|
+
EDITING_BACKGROUND_COLOR = qt.QColor("#c3d0d6")
|
8
|
+
"""Background color used to notify the user that application waits end of edition before taking it into account"""
|
tomwer/gui/stackplot.py
CHANGED
@@ -555,7 +555,7 @@ class _StackImageToLoad(_StackImage, qt.QObject):
|
|
555
555
|
|
556
556
|
def clear(self):
|
557
557
|
for img in self._images.values():
|
558
|
-
img.sigLoaded.disconnect(self.
|
558
|
+
img.sigLoaded.disconnect(self.sigImageLoaded)
|
559
559
|
_StackImage.clear(self)
|
560
560
|
self._url_to_index.clear()
|
561
561
|
|
@@ -568,7 +568,7 @@ class _StackImageToLoad(_StackImage, qt.QObject):
|
|
568
568
|
raise TypeError(f"Unmanaged type: {type(image)}")
|
569
569
|
self._url_to_index[image_.url.path()] = self.nextIndex
|
570
570
|
_StackImage.addImage(self, image_)
|
571
|
-
image_.sigLoaded.connect(self.
|
571
|
+
image_.sigLoaded.connect(self.sigImageLoaded)
|
572
572
|
if self._mode == ASAP_LOADING:
|
573
573
|
image_.load(self._force_sync)
|
574
574
|
|
@@ -615,9 +615,6 @@ class _StackImageToLoad(_StackImage, qt.QObject):
|
|
615
615
|
except Exception as e:
|
616
616
|
logger.error(e)
|
617
617
|
|
618
|
-
def _loaded(self, url_path):
|
619
|
-
self.sigImageLoaded.emit(url_path)
|
620
|
-
|
621
618
|
def setForceSync(self, value):
|
622
619
|
self._force_sync = value
|
623
620
|
|
@@ -0,0 +1,49 @@
|
|
1
|
+
from silx.gui import qt
|
2
|
+
from silx.gui import icons as silx_icons
|
3
|
+
from tomwer.gui import icons as tomwer_icons
|
4
|
+
|
5
|
+
|
6
|
+
class LoadConfigurationAction(qt.QAction):
|
7
|
+
"""Action to trigger load of a stitching configuration"""
|
8
|
+
|
9
|
+
def __init__(self, parent=None, text=None):
|
10
|
+
super().__init__(parent)
|
11
|
+
if text is not None:
|
12
|
+
self.setText(text)
|
13
|
+
self.setToolTip("load nabu-stitching configuration")
|
14
|
+
load_icon = silx_icons.getQIcon("document-open")
|
15
|
+
self.setIcon(load_icon)
|
16
|
+
|
17
|
+
|
18
|
+
class SaveConfigurationAction(qt.QAction):
|
19
|
+
"""Action to trigger save of a stitching configuration"""
|
20
|
+
|
21
|
+
def __init__(self, parent=None, text=None):
|
22
|
+
super().__init__(parent)
|
23
|
+
if text is not None:
|
24
|
+
self.setText(text)
|
25
|
+
self.setToolTip("save nabu-stitching configuration")
|
26
|
+
save_icon = silx_icons.getQIcon("document-save")
|
27
|
+
self.setIcon(save_icon)
|
28
|
+
|
29
|
+
|
30
|
+
class AddTomoObjectAction(qt.QAction):
|
31
|
+
"""Action to trigger add a volume to a stitching configuration"""
|
32
|
+
|
33
|
+
def __init__(self, parent=None, text=None):
|
34
|
+
super().__init__(parent)
|
35
|
+
if text is not None:
|
36
|
+
self.setText(text)
|
37
|
+
self.setToolTip(
|
38
|
+
"Add a NXtomo or a (nabu) reconstructed volume to the stitching"
|
39
|
+
)
|
40
|
+
add_icon = tomwer_icons.getQIcon("add")
|
41
|
+
self.setIcon(add_icon)
|
42
|
+
|
43
|
+
|
44
|
+
class PreviewAction(qt.QAction):
|
45
|
+
def __init__(self, parent=None):
|
46
|
+
super().__init__(parent)
|
47
|
+
self.setToolTip("Compute preview with current settings (shortcut: F5)")
|
48
|
+
update_preview_icon = tomwer_icons.getQIcon("update_stitching_preview")
|
49
|
+
self.setIcon(update_preview_icon)
|
@@ -2,11 +2,11 @@ import logging
|
|
2
2
|
from typing import Union
|
3
3
|
|
4
4
|
from nabu.stitching import config as stitching_config
|
5
|
-
from nabu.stitching.utils import ScoreMethod
|
6
5
|
from nabu.stitching.utils import ShiftAlgorithm as StitchShiftAlgorithm
|
7
6
|
from silx.gui import qt
|
8
7
|
|
9
8
|
from tomwer.gui.utils.qt_utils import block_signals
|
9
|
+
from tomwer.gui.configuration.level import ConfigurationLevel
|
10
10
|
|
11
11
|
_logger = logging.getLogger(__name__)
|
12
12
|
|
@@ -34,7 +34,6 @@ class StitcherAxisParams(qt.QWidget):
|
|
34
34
|
axis_0_shift_search_method = [
|
35
35
|
StitchShiftAlgorithm.NABU_FFT,
|
36
36
|
StitchShiftAlgorithm.SKIMAGE,
|
37
|
-
StitchShiftAlgorithm.SHIFT_GRID,
|
38
37
|
StitchShiftAlgorithm.ITK_IMG_REG_V4,
|
39
38
|
StitchShiftAlgorithm.NONE,
|
40
39
|
]
|
@@ -54,13 +53,6 @@ class StitcherAxisParams(qt.QWidget):
|
|
54
53
|
tooltip = "size of the window to try to refine shift"
|
55
54
|
self._windowSizeLabel.setToolTip(tooltip)
|
56
55
|
self._windowSizeSB.setToolTip(tooltip)
|
57
|
-
# score method
|
58
|
-
self._scoreMethodLabel = qt.QLabel("score method", self)
|
59
|
-
self.layout().addWidget(self._scoreMethodLabel, 2, 0, 1, 1)
|
60
|
-
self._scoreMethodCB = qt.QComboBox(self)
|
61
|
-
for method in ScoreMethod:
|
62
|
-
self._scoreMethodCB.addItem(method.value)
|
63
|
-
self.layout().addWidget(self._scoreMethodCB, 2, 1, 1, 1)
|
64
56
|
|
65
57
|
# filter options
|
66
58
|
self._filteringGroup = _FilteringGroupBox("filter for shift search", self)
|
@@ -68,7 +60,7 @@ class StitcherAxisParams(qt.QWidget):
|
|
68
60
|
self._filteringGroup.setChecked(False)
|
69
61
|
self._filteringGroup.setLowPassValue(1)
|
70
62
|
self._filteringGroup.setHighPassValue(20)
|
71
|
-
self.layout().addWidget(self._filteringGroup,
|
63
|
+
self.layout().addWidget(self._filteringGroup, 2, 0, 2, 3)
|
72
64
|
|
73
65
|
# set up
|
74
66
|
self._methodChanged()
|
@@ -76,7 +68,6 @@ class StitcherAxisParams(qt.QWidget):
|
|
76
68
|
# connect signal / slot
|
77
69
|
self._shiftSearchMethodCB.currentIndexChanged.connect(self._methodChanged)
|
78
70
|
self._windowSizeSB.valueChanged.connect(self._notifyConfigChanged)
|
79
|
-
self._scoreMethodCB.currentIndexChanged.connect(self._notifyConfigChanged)
|
80
71
|
self._filteringGroup.sigValueChanged.connect(self._notifyConfigChanged)
|
81
72
|
|
82
73
|
@property
|
@@ -91,21 +82,12 @@ class StitcherAxisParams(qt.QWidget):
|
|
91
82
|
idx = self._shiftSearchMethodCB.findText(method.value)
|
92
83
|
self._shiftSearchMethodCB.setCurrentIndex(idx)
|
93
84
|
|
94
|
-
def setScoreMethod(self, method: Union[ScoreMethod, str]) -> None:
|
95
|
-
method = ScoreMethod.from_value(method)
|
96
|
-
idx = self._scoreMethodCB.findText(method.value)
|
97
|
-
self._scoreMethodCB.setCurrentIndex(idx)
|
98
|
-
|
99
85
|
def getConfiguration(self) -> dict:
|
100
86
|
method = self.getShiftSearchMethod()
|
101
87
|
param_opts = [
|
102
88
|
f"{stitching_config.KEY_IMG_REG_METHOD}={method.value}",
|
103
89
|
f"{stitching_config.KEY_WINDOW_SIZE}={self._windowSizeSB.value()}",
|
104
90
|
]
|
105
|
-
if method is StitchShiftAlgorithm.SHIFT_GRID:
|
106
|
-
param_opts.append(
|
107
|
-
f"{stitching_config.KEY_SCORE_METHOD}='{self._scoreMethodCB.currentText()}'"
|
108
|
-
)
|
109
91
|
if self._filteringGroup.isChecked():
|
110
92
|
param_opts.append(
|
111
93
|
f"{stitching_config.KEY_LOW_PASS_FILTER}='{self._filteringGroup.getLowPassValue()}'"
|
@@ -136,8 +118,6 @@ class StitcherAxisParams(qt.QWidget):
|
|
136
118
|
self.setShiftSearchMethod(opt_value)
|
137
119
|
elif opt_name == stitching_config.KEY_WINDOW_SIZE:
|
138
120
|
self._windowSizeSB.setValue(int(opt_value))
|
139
|
-
elif opt_name == stitching_config.KEY_SCORE_METHOD:
|
140
|
-
self.setScoreMethod(opt_value)
|
141
121
|
elif opt_name == stitching_config.KEY_LOW_PASS_FILTER:
|
142
122
|
self._filteringGroup.setLowPassValue(int(opt_value))
|
143
123
|
self._filteringGroup.setEnabled(True)
|
@@ -153,8 +133,6 @@ class StitcherAxisParams(qt.QWidget):
|
|
153
133
|
def _methodChanged(self) -> None:
|
154
134
|
method = self.getShiftSearchMethod()
|
155
135
|
with block_signals(self):
|
156
|
-
self._scoreMethodCB.setVisible(method is StitchShiftAlgorithm.SHIFT_GRID)
|
157
|
-
self._scoreMethodLabel.setVisible(method is StitchShiftAlgorithm.SHIFT_GRID)
|
158
136
|
self._windowSizeSB.setVisible(method is not StitchShiftAlgorithm.NONE)
|
159
137
|
self._windowSizeLabel.setVisible(method is not StitchShiftAlgorithm.NONE)
|
160
138
|
self._notifyConfigChanged()
|
@@ -162,6 +140,11 @@ class StitcherAxisParams(qt.QWidget):
|
|
162
140
|
def _notifyConfigChanged(self, *args, **kwargs) -> None:
|
163
141
|
self.sigConfigChanged.emit()
|
164
142
|
|
143
|
+
def setConfigurationLevel(self, level: ConfigurationLevel):
|
144
|
+
self._windowSizeLabel.setVisible(level >= ConfigurationLevel.OPTIONAL)
|
145
|
+
self._windowSizeSB.setVisible(level >= ConfigurationLevel.OPTIONAL)
|
146
|
+
self._filteringGroup.setVisible(level >= ConfigurationLevel.ADVANCED)
|
147
|
+
|
165
148
|
|
166
149
|
class _FilteringGroupBox(qt.QGroupBox):
|
167
150
|
sigValueChanged = qt.Signal()
|
@@ -5,9 +5,10 @@ from nabu.stitching.config import StitchingType
|
|
5
5
|
from nxtomomill.io.utils import convert_str_to_bool
|
6
6
|
from silx.gui import qt
|
7
7
|
|
8
|
-
from tomwer.core.scan.
|
8
|
+
from tomwer.core.scan.nxtomoscan import NXtomoScan, NXtomoScanIdentifier
|
9
9
|
from tomwer.core.scan.scanfactory import ScanFactory
|
10
10
|
from tomwer.gui.utils.inputwidget import OutputVolumeDefinition
|
11
|
+
from tomwer.gui.qlefilesystem import QLFileSystem
|
11
12
|
|
12
13
|
_logger = logging.getLogger(__name__)
|
13
14
|
|
@@ -21,21 +22,21 @@ class _PreProcessingOutput(qt.QWidget):
|
|
21
22
|
super().__init__(parent)
|
22
23
|
self.setLayout(qt.QFormLayout())
|
23
24
|
# TODO: check if the widget with output .nx file exists somewhere
|
24
|
-
self._outputFile =
|
25
|
+
self._outputFile = QLFileSystem("stitching/stitched.nx", self)
|
25
26
|
self.layout().addRow("output nexus file", self._outputFile)
|
26
27
|
self._outputDataPath = qt.QLineEdit("entry0000", self)
|
27
28
|
self.layout().addRow("output data path", self._outputDataPath)
|
28
29
|
|
29
30
|
def getUrl(self) -> str:
|
30
|
-
return
|
31
|
-
object=
|
31
|
+
return NXtomoScanIdentifier(
|
32
|
+
object=NXtomoScan,
|
32
33
|
hdf5_file=self._outputFile.text(),
|
33
34
|
entry=self._outputDataPath.text(),
|
34
35
|
)
|
35
36
|
|
36
37
|
def setUrl(self, url: str):
|
37
38
|
try:
|
38
|
-
identifier =
|
39
|
+
identifier = NXtomoScanIdentifier.from_str(url)
|
39
40
|
except Exception as e:
|
40
41
|
_logger.warning(f"Fail to create an identifier from {url}. Error is {e}")
|
41
42
|
else:
|
@@ -71,6 +72,7 @@ class StitchingOutput(qt.QWidget):
|
|
71
72
|
self._postProcOutput = _PostProcessingOutput(parent=self)
|
72
73
|
self.layout().addWidget(self._postProcOutput)
|
73
74
|
self._overwritePB = qt.QCheckBox("overwrite", self)
|
75
|
+
self._overwritePB.setChecked(True)
|
74
76
|
self.layout().addWidget(self._overwritePB)
|
75
77
|
|
76
78
|
# add a vertical spacer for display
|
@@ -110,7 +112,7 @@ class StitchingOutput(qt.QWidget):
|
|
110
112
|
except Exception:
|
111
113
|
scan = None
|
112
114
|
|
113
|
-
if not isinstance(scan,
|
115
|
+
if not isinstance(scan, NXtomoScan):
|
114
116
|
_logger.info("Failed to create an HDFTomoscan from url")
|
115
117
|
return None
|
116
118
|
else:
|
@@ -146,8 +148,8 @@ class StitchingOutput(qt.QWidget):
|
|
146
148
|
stitching_config.DATA_PATH_FIELD, None
|
147
149
|
)
|
148
150
|
if location is not None:
|
149
|
-
identifier =
|
150
|
-
object=
|
151
|
+
identifier = NXtomoScanIdentifier(
|
152
|
+
object=NXtomoScan, hdf5_file=location, entry=data_path
|
151
153
|
)
|
152
154
|
self._preProcOutput.setUrl(identifier.to_str())
|
153
155
|
|
@@ -3,6 +3,7 @@ import numpy
|
|
3
3
|
from silx.gui import qt
|
4
4
|
|
5
5
|
from tomwer.gui.stitching.axisorderedlist import AxisOrderedTomoObjsModel
|
6
|
+
from tomwer.gui.utils.step import StepSizeSelectorWidget
|
6
7
|
|
7
8
|
|
8
9
|
class PosEditorOverOneAxis(qt.QWidget):
|
@@ -15,7 +16,6 @@ class PosEditorOverOneAxis(qt.QWidget):
|
|
15
16
|
) -> None:
|
16
17
|
assert axis_edited in (0, 1, 2)
|
17
18
|
super().__init__(parent, *args, **kwargs)
|
18
|
-
self._stepSize = 1
|
19
19
|
self._axisEdited = axis_edited
|
20
20
|
# the axis the spin boxes are editing
|
21
21
|
self._axisOrder = axis_order if axis_order is not None else axis_edited
|
@@ -25,7 +25,13 @@ class PosEditorOverOneAxis(qt.QWidget):
|
|
25
25
|
self.__spinBoxescallback = {}
|
26
26
|
self.setLayout(qt.QVBoxLayout())
|
27
27
|
# widget to define step size
|
28
|
-
self._stepSizeWidget =
|
28
|
+
self._stepSizeWidget = StepSizeSelectorWidget(
|
29
|
+
self,
|
30
|
+
fine_value=1,
|
31
|
+
medium_value=5,
|
32
|
+
rough_value=25,
|
33
|
+
dtype=int,
|
34
|
+
)
|
29
35
|
self.layout().addWidget(self._stepSizeWidget)
|
30
36
|
|
31
37
|
# table with the different Tomo objects
|
@@ -35,22 +41,28 @@ class PosEditorOverOneAxis(qt.QWidget):
|
|
35
41
|
|
36
42
|
self.layout().addWidget(self._tomoObjsTableView)
|
37
43
|
|
44
|
+
# connect signal / slot
|
45
|
+
self._stepSizeWidget.valueChanged.connect(self._updateStepSize)
|
46
|
+
|
38
47
|
# tune table view
|
39
48
|
self._tomoObjsTableView.setColumnWidth(0, 15)
|
40
49
|
self._tomoObjsTableView.setColumnWidth(2, 120)
|
41
50
|
self._tomoObjsTableView.horizontalHeader().setSectionResizeMode(
|
42
51
|
1, qt.QHeaderView.Stretch
|
43
52
|
)
|
53
|
+
self.setStepSize(1)
|
44
54
|
|
45
|
-
|
46
|
-
self.
|
47
|
-
self.
|
55
|
+
def _updateStepSize(self):
|
56
|
+
step_size = self.getStepSize()
|
57
|
+
for sb in self._tomoObjtoSpinBoxes.values():
|
58
|
+
sb.setSingleStep(step_size)
|
48
59
|
|
49
60
|
def setStepSize(self, step_size: int):
|
50
|
-
self.
|
51
|
-
|
52
|
-
|
53
|
-
|
61
|
+
self._stepSizeWidget.setStepSize(step_size)
|
62
|
+
self._updateStepSize()
|
63
|
+
|
64
|
+
def getStepSize(self) -> int:
|
65
|
+
return self._stepSizeWidget.getStepSize()
|
54
66
|
|
55
67
|
def addTomoObj(self, tomo_obj):
|
56
68
|
if tomo_obj is None:
|
@@ -68,7 +80,7 @@ class PosEditorOverOneAxis(qt.QWidget):
|
|
68
80
|
spinBox = qt.QSpinBox(parent=self)
|
69
81
|
spinBox.setRange(numpy.iinfo(numpy.int32).min, numpy.iinfo(numpy.int32).max)
|
70
82
|
spinBox.setSuffix("px")
|
71
|
-
spinBox.setSingleStep(self.
|
83
|
+
spinBox.setSingleStep(self.getStepSize())
|
72
84
|
spinBox.setValue(
|
73
85
|
tomo_obj.stitching_metadata.get_abs_position_px(axis=self._axisEdited)
|
74
86
|
or self.DEFAULT_VALUE_WHEM_MISSING
|
@@ -154,16 +166,3 @@ class EditableAxisOrderedTomoObjsModel(AxisOrderedTomoObjsModel):
|
|
154
166
|
def __init__(self, axis: int, parent=None) -> None:
|
155
167
|
super().__init__(axis, parent)
|
156
168
|
self._headers = ["index", "tomo obj", f"axis {axis} pos (px)"]
|
157
|
-
|
158
|
-
|
159
|
-
class StepSizeWidget(qt.QWidget):
|
160
|
-
def __init__(self, parent=None) -> None:
|
161
|
-
super().__init__(parent)
|
162
|
-
self.setLayout(qt.QFormLayout())
|
163
|
-
self._stepSB = qt.QSpinBox(self)
|
164
|
-
self._stepSB.setRange(1, 9999)
|
165
|
-
self.layout().addRow("step size", self._stepSB)
|
166
|
-
|
167
|
-
@property
|
168
|
-
def stepSB(self):
|
169
|
-
return self._stepSB
|
@@ -0,0 +1,117 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from silx.gui import qt
|
3
|
+
from nabu.stitching.sample_normalization import (
|
4
|
+
SampleSide as _SampleSide,
|
5
|
+
Method as _SampleNormalizationMethod,
|
6
|
+
)
|
7
|
+
from nabu.stitching import config as _config_stitching
|
8
|
+
from tomwer.gui.utils.qt_utils import block_signals
|
9
|
+
|
10
|
+
|
11
|
+
class NormalizationBySampleGroupBox(qt.QGroupBox):
|
12
|
+
"""
|
13
|
+
Widget to define the normalization to apply to frames"""
|
14
|
+
|
15
|
+
sigConfigChanged = qt.Signal()
|
16
|
+
"""Emit when the configuration is changed"""
|
17
|
+
|
18
|
+
def __init__(self, title: str = "normalization by sample", parent=None):
|
19
|
+
# FIXME: add a way to the user for requesting a view of the region picked ???
|
20
|
+
super().__init__(title, parent)
|
21
|
+
self.setCheckable(True)
|
22
|
+
self.setLayout(qt.QFormLayout())
|
23
|
+
|
24
|
+
# method
|
25
|
+
self._methodCB = qt.QComboBox(self)
|
26
|
+
self._methodCB.addItems(_SampleNormalizationMethod.values())
|
27
|
+
self._methodCB.setCurrentText(_SampleNormalizationMethod.MEDIAN.value)
|
28
|
+
self.layout().addRow("method", self._methodCB)
|
29
|
+
|
30
|
+
# side
|
31
|
+
self._sideCB = qt.QComboBox(self)
|
32
|
+
self._sideCB.addItems(_SampleSide.values())
|
33
|
+
self._sideCB.setCurrentText(_SampleSide.LEFT.value)
|
34
|
+
self.layout().addRow("sampling side", self._sideCB)
|
35
|
+
|
36
|
+
# width
|
37
|
+
self._widthSB = qt.QSpinBox(self)
|
38
|
+
self._widthSB.setRange(1, 9999999)
|
39
|
+
self._widthSB.setValue(30)
|
40
|
+
self._widthSB.setSingleStep(10)
|
41
|
+
self.layout().addRow("sampling width", self._widthSB)
|
42
|
+
|
43
|
+
# margin
|
44
|
+
self._marginSB = qt.QSpinBox(self)
|
45
|
+
self._marginSB.setRange(0, 999999)
|
46
|
+
self._marginSB.setValue(0)
|
47
|
+
self.layout().addRow("sampling margin", self._marginSB)
|
48
|
+
|
49
|
+
# connect signal / slot
|
50
|
+
self._methodCB.currentIndexChanged.connect(self._configChanged)
|
51
|
+
self._sideCB.currentIndexChanged.connect(self._configChanged)
|
52
|
+
self._widthSB.valueChanged.connect(self._configChanged)
|
53
|
+
self._marginSB.valueChanged.connect(self._configChanged)
|
54
|
+
|
55
|
+
def _configChanged(self, *args, **kwargs):
|
56
|
+
self.sigConfigChanged.emit()
|
57
|
+
|
58
|
+
def getMethod(self) -> _SampleNormalizationMethod:
|
59
|
+
return _SampleNormalizationMethod.from_value(self._methodCB.currentText())
|
60
|
+
|
61
|
+
def setMethod(self, method: _SampleNormalizationMethod | str):
|
62
|
+
method = _SampleNormalizationMethod.from_value(method)
|
63
|
+
self._methodCB.setCurrentText(method.value)
|
64
|
+
|
65
|
+
def getSide(self) -> _SampleSide:
|
66
|
+
return _SampleSide.from_value(self._sideCB.currentText())
|
67
|
+
|
68
|
+
def setSide(self, side: _SampleSide):
|
69
|
+
side = _SampleSide.from_value(side)
|
70
|
+
self._sideCB.setCurrentText(side.value)
|
71
|
+
|
72
|
+
def getMargin(self) -> int:
|
73
|
+
return self._marginSB.value()
|
74
|
+
|
75
|
+
def setMargin(self, margin: int):
|
76
|
+
self._marginSB.setValue(int(margin))
|
77
|
+
|
78
|
+
def getWidth(self) -> int:
|
79
|
+
return self._widthSB.value()
|
80
|
+
|
81
|
+
def setWidth(self, width: int):
|
82
|
+
self._widthSB.setValue(int(width))
|
83
|
+
|
84
|
+
def getConfiguration(self) -> dict:
|
85
|
+
return {
|
86
|
+
_config_stitching.NORMALIZATION_BY_SAMPLE_ACTIVE_FIELD: self.isChecked(),
|
87
|
+
_config_stitching.NORMALIZATION_BY_SAMPLE_METHOD: self.getMethod().value,
|
88
|
+
_config_stitching.NORMALIZATION_BY_SAMPLE_SIDE: self.getSide().value,
|
89
|
+
_config_stitching.NORMALIZATION_BY_SAMPLE_MARGIN: self.getMargin(),
|
90
|
+
_config_stitching.NORMALIZATION_BY_SAMPLE_WIDTH: self.getWidth(),
|
91
|
+
}
|
92
|
+
|
93
|
+
def setConfiguration(self, config: dict) -> None:
|
94
|
+
with block_signals(self):
|
95
|
+
method = config.get(_config_stitching.NORMALIZATION_BY_SAMPLE_METHOD, None)
|
96
|
+
if method is not None:
|
97
|
+
self.setMethod(method=method)
|
98
|
+
|
99
|
+
side = config.get(_config_stitching.NORMALIZATION_BY_SAMPLE_SIDE, None)
|
100
|
+
if side is not None:
|
101
|
+
self.setSide(side=side)
|
102
|
+
|
103
|
+
margin = config.get(_config_stitching.NORMALIZATION_BY_SAMPLE_MARGIN, None)
|
104
|
+
if margin is not None:
|
105
|
+
self.setMargin(margin=margin)
|
106
|
+
|
107
|
+
width = config.get(_config_stitching.NORMALIZATION_BY_SAMPLE_WIDTH, None)
|
108
|
+
if width is not None:
|
109
|
+
self.setWidth(width=width)
|
110
|
+
|
111
|
+
active = config.get(
|
112
|
+
_config_stitching.NORMALIZATION_BY_SAMPLE_ACTIVE_FIELD, None
|
113
|
+
)
|
114
|
+
if active is not None:
|
115
|
+
self.setChecked(active in (True, 1, "1", "True"))
|
116
|
+
|
117
|
+
self._configChanged()
|