tomwer 1.4.19__py3-none-any.whl → 1.5.2rc0__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.
Files changed (123) hide show
  1. orangecontrib/tomwer/tutorials/simple_volume_local_reconstruction.ows +11 -8
  2. orangecontrib/tomwer/tutorials/simple_volume_to_slurm_reconstruction.ows +12 -9
  3. orangecontrib/tomwer/widgets/control/DataDiscoveryOW.py +1 -1
  4. orangecontrib/tomwer/widgets/control/NXTomomillMixIn.py +21 -10
  5. tomwer/app/axis.py +1 -1
  6. tomwer/app/reducedarkflat.py +2 -2
  7. tomwer/core/process/control/datalistener/rpcserver.py +2 -8
  8. tomwer/core/process/drac/binning.py +2 -2
  9. tomwer/core/process/drac/output.py +1 -1
  10. tomwer/core/process/edit/imagekeyeditor.py +4 -6
  11. tomwer/core/process/edit/nxtomoeditor.py +58 -20
  12. tomwer/core/process/output.py +6 -5
  13. tomwer/core/process/reconstruction/axis/anglemode.py +2 -2
  14. tomwer/core/process/reconstruction/axis/axis.py +1 -0
  15. tomwer/core/process/reconstruction/axis/mode.py +2 -2
  16. tomwer/core/process/reconstruction/axis/params.py +4 -4
  17. tomwer/core/process/reconstruction/axis/projectiontype.py +1 -1
  18. tomwer/core/process/reconstruction/axis/side.py +1 -1
  19. tomwer/core/process/reconstruction/darkref/darkrefs.py +2 -2
  20. tomwer/core/process/reconstruction/darkref/darkrefscopy.py +1 -1
  21. tomwer/core/process/reconstruction/darkref/params.py +2 -3
  22. tomwer/core/process/reconstruction/nabu/castvolume.py +4 -1
  23. tomwer/core/process/reconstruction/nabu/helical.py +3 -1
  24. tomwer/core/process/reconstruction/nabu/nabucommon.py +2 -2
  25. tomwer/core/process/reconstruction/nabu/nabuscores.py +1 -1
  26. tomwer/core/process/reconstruction/nabu/nabuslices.py +4 -4
  27. tomwer/core/process/reconstruction/nabu/plane.py +2 -2
  28. tomwer/core/process/reconstruction/nabu/target.py +1 -1
  29. tomwer/core/process/reconstruction/nabu/test/test_castvolume.py +2 -0
  30. tomwer/core/process/reconstruction/nabu/utils.py +15 -14
  31. tomwer/core/process/reconstruction/normalization/normalization.py +1 -1
  32. tomwer/core/process/reconstruction/normalization/params.py +4 -4
  33. tomwer/core/process/reconstruction/output.py +2 -2
  34. tomwer/core/process/reconstruction/saaxis/params.py +3 -3
  35. tomwer/core/process/reconstruction/saaxis/saaxis.py +1 -1
  36. tomwer/core/process/reconstruction/scores/params.py +2 -2
  37. tomwer/core/process/reconstruction/scores/scores.py +3 -3
  38. tomwer/core/process/reconstruction/tests/test_axis.py +1 -1
  39. tomwer/core/process/stitching/metadataholder.py +5 -5
  40. tomwer/core/process/stitching/nabustitcher.py +1 -4
  41. tomwer/core/process/tests/test_normalization.py +2 -1
  42. tomwer/core/scan/edfscan.py +3 -3
  43. tomwer/core/scan/nxtomoscan.py +3 -3
  44. tomwer/core/scan/scanbase.py +3 -3
  45. tomwer/core/scan/scantype.py +1 -1
  46. tomwer/core/settings.py +1 -1
  47. tomwer/core/tomwer_object.py +1 -1
  48. tomwer/core/utils/nxtomoutils.py +2 -2
  49. tomwer/core/utils/spec.py +6 -3
  50. tomwer/gui/cluster/slurm.py +3 -3
  51. tomwer/gui/configuration/level.py +1 -1
  52. tomwer/gui/control/actions.py +1 -1
  53. tomwer/gui/control/datadiscovery.py +1 -1
  54. tomwer/gui/control/datalist.py +1 -1
  55. tomwer/gui/control/reducedarkflatselector.py +4 -4
  56. tomwer/gui/control/series/seriescreator.py +5 -5
  57. tomwer/gui/control/tomoobjdisplaymode.py +1 -1
  58. tomwer/gui/dataportal/gallery.py +6 -6
  59. tomwer/gui/edit/imagekeyeditor.py +7 -9
  60. tomwer/gui/edit/nxtomoeditor.py +420 -112
  61. tomwer/gui/edit/tests/test_nx_editor.py +155 -83
  62. tomwer/gui/reconstruction/axis/CalculationWidget.py +1 -1
  63. tomwer/gui/reconstruction/axis/EstimatedCORWidget.py +12 -8
  64. tomwer/gui/reconstruction/axis/EstimatedCorComboBox.py +2 -2
  65. tomwer/gui/reconstruction/axis/InputWidget.py +3 -3
  66. tomwer/gui/reconstruction/darkref/darkrefwidget.py +2 -2
  67. tomwer/gui/reconstruction/nabu/castvolume.py +16 -1
  68. tomwer/gui/reconstruction/nabu/nabuconfig/base.py +2 -4
  69. tomwer/gui/reconstruction/nabu/nabuconfig/ctf.py +6 -6
  70. tomwer/gui/reconstruction/nabu/nabuconfig/nabuconfig.py +1 -1
  71. tomwer/gui/reconstruction/nabu/nabuconfig/phase.py +5 -5
  72. tomwer/gui/reconstruction/nabu/nabuconfig/preprocessing.py +2 -4
  73. tomwer/gui/reconstruction/nabu/nabuconfig/reconstruction.py +78 -52
  74. tomwer/gui/reconstruction/nabu/nabuflow.py +3 -13
  75. tomwer/gui/reconstruction/nabu/slices.py +11 -11
  76. tomwer/gui/reconstruction/nabu/test/test_cast_volume.py +19 -0
  77. tomwer/gui/reconstruction/nabu/volume.py +1 -1
  78. tomwer/gui/reconstruction/normalization/intensity.py +8 -12
  79. tomwer/gui/reconstruction/saaxis/corrangeselector.py +2 -2
  80. tomwer/gui/reconstruction/saaxis/dimensionwidget.py +71 -67
  81. tomwer/gui/reconstruction/sacommon.py +1 -1
  82. tomwer/gui/reconstruction/scores/scoreplot.py +18 -10
  83. tomwer/gui/reconstruction/tests/test_saaxis.py +18 -16
  84. tomwer/gui/stitching/SingleAxisStitchingWidget.py +8 -8
  85. tomwer/gui/stitching/StitchingOptionsWidget.py +1 -1
  86. tomwer/gui/stitching/alignment.py +8 -8
  87. tomwer/gui/stitching/config/axisparams.py +2 -2
  88. tomwer/gui/stitching/config/output.py +1 -1
  89. tomwer/gui/stitching/config/positionoveraxis.py +1 -1
  90. tomwer/gui/stitching/config/stitchingstrategies.py +4 -6
  91. tomwer/gui/stitching/config/tomoobjdetails.py +21 -13
  92. tomwer/gui/stitching/normalization.py +6 -6
  93. tomwer/gui/stitching/tests/test_ZStitchingWindow.py +8 -1
  94. tomwer/gui/stitching/tests/test_preview.py +10 -7
  95. tomwer/gui/stitching/tests/utils.py +27 -18
  96. tomwer/gui/stitching/z_stitching/fineestimation.py +7 -9
  97. tomwer/gui/stitching/z_stitching/tests/test_raw_estimation.py +18 -7
  98. tomwer/gui/stitching/z_stitching/tests/test_stitching_window.py +7 -2
  99. tomwer/gui/utils/buttons.py +53 -35
  100. tomwer/gui/utils/flow.py +2 -2
  101. tomwer/gui/utils/loadingmode.py +1 -1
  102. tomwer/gui/utils/unitsystem.py +44 -33
  103. tomwer/gui/utils/vignettes.py +1 -1
  104. tomwer/gui/visualization/dataviewer.py +7 -7
  105. tomwer/gui/visualization/diffviewer/diffviewer.py +4 -4
  106. tomwer/gui/visualization/diffviewer/shiftwidget.py +4 -6
  107. tomwer/gui/visualization/reconstructionparameters.py +35 -23
  108. tomwer/gui/visualization/scanoverview.py +28 -11
  109. tomwer/gui/visualization/test/test_nx_tomo_metadata_viewer.py +25 -13
  110. tomwer/gui/visualization/test/test_reconstruction_parameters.py +2 -2
  111. tomwer/model/dataset.py +0 -0
  112. tomwer/synctools/utils/scanstages.py +3 -3
  113. tomwer/tasks/reconstruction/cleardarkflat.py +42 -0
  114. tomwer/tests/app/test_stitching.py +1 -1
  115. tomwer/tests/orangecontrib/tomwer/widgets/edit/tests/test_nxtomo_editor.py +32 -20
  116. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_nabu_widget.py +1 -1
  117. tomwer/version.py +3 -3
  118. {tomwer-1.4.19.dist-info → tomwer-1.5.2rc0.dist-info}/METADATA +8 -8
  119. {tomwer-1.4.19.dist-info → tomwer-1.5.2rc0.dist-info}/RECORD +123 -121
  120. {tomwer-1.4.19.dist-info → tomwer-1.5.2rc0.dist-info}/WHEEL +1 -1
  121. {tomwer-1.4.19.dist-info → tomwer-1.5.2rc0.dist-info}/entry_points.txt +0 -0
  122. {tomwer-1.4.19.dist-info → tomwer-1.5.2rc0.dist-info}/licenses/LICENSE +0 -0
  123. {tomwer-1.4.19.dist-info → tomwer-1.5.2rc0.dist-info}/top_level.txt +0 -0
@@ -5,7 +5,7 @@ from __future__ import annotations
5
5
  import logging
6
6
 
7
7
  from silx.gui import qt
8
- from silx.utils.enum import Enum as _Enum
8
+ from enum import Enum as _Enum
9
9
 
10
10
  from tomwer.core.process.reconstruction.nabu.utils import _NabuPhaseMethod, _NabuStages
11
11
  from tomwer.core.utils.char import BETA_CHAR, DELTA_CHAR
@@ -102,7 +102,7 @@ class _NabuPhaseConfig(qt.QWidget, base._NabuStageConfigBase):
102
102
  self.sigConfChanged.emit(param)
103
103
 
104
104
  def getMethod(self) -> _NabuPhaseMethod:
105
- return _NabuPhaseMethod.from_value(self._methodCB.currentText())
105
+ return _NabuPhaseMethod(self._methodCB.currentText())
106
106
 
107
107
  @docstring(base._NabuStageConfigBase)
108
108
  def setConfiguration(self, config) -> None:
@@ -111,7 +111,7 @@ class _NabuPhaseConfig(qt.QWidget, base._NabuStageConfigBase):
111
111
  if method == "none":
112
112
  method = _NabuPhaseMethod.NONE
113
113
  self._paganinOpts.setConfiguration(config)
114
- method = _NabuPhaseMethod.from_value(method)
114
+ method = _NabuPhaseMethod(method)
115
115
  index_method = self._methodCB.findText(method.value)
116
116
  if index_method >= 0:
117
117
  self._methodCB.setCurrentIndex(index_method)
@@ -212,10 +212,10 @@ class NabuPaganinConfig(qt.QWidget, base._NabuStageConfigBase):
212
212
 
213
213
  def getPaddingType(self) -> PaddingMode:
214
214
  current_text = self._paddingTypeCB.currentText()
215
- return PaddingMode.from_value(current_text)
215
+ return PaddingMode(current_text)
216
216
 
217
217
  def setPaddingType(self, padding_type):
218
- padding_type = PaddingMode.from_value(padding_type)
218
+ padding_type = PaddingMode(padding_type)
219
219
  item_index = self._paddingTypeCB.findText(padding_type.value)
220
220
  self._paddingTypeCB.setCurrentIndex(item_index)
221
221
 
@@ -401,9 +401,7 @@ class _NabuPreProcessingConfig(_NabuStageConfigBase, qt.QWidget):
401
401
  if sino_rings_correction is not None:
402
402
  if sino_rings_correction == "":
403
403
  sino_rings_correction = RingCorrectionMethod.NONE
404
- sino_rings_correction = RingCorrectionMethod.from_value(
405
- sino_rings_correction
406
- ).value
404
+ sino_rings_correction = RingCorrectionMethod(sino_rings_correction).value
407
405
  idx = self._sinoRingCorrectionMthd.findText(sino_rings_correction)
408
406
  if idx >= 0:
409
407
  self._sinoRingCorrectionMthd.setCurrentIndex(idx)
@@ -581,7 +579,7 @@ class SinoRingsOptions(qt.QWidget):
581
579
  self._sigmaHigh.setValue(float(high_pass))
582
580
 
583
581
  def setMethod(self, method: RingCorrectionMethod):
584
- method = RingCorrectionMethod.from_value(method)
582
+ method = RingCorrectionMethod(method)
585
583
  self._method = method
586
584
  # handle munch options
587
585
  self._sigmaMunch.setVisible(method is RingCorrectionMethod.MUNCH)
@@ -7,7 +7,7 @@ import logging
7
7
 
8
8
  from silx.gui import qt
9
9
  from silx.gui.dialog.DataFileDialog import DataFileDialog
10
- from silx.utils.enum import Enum as _Enum
10
+ from enum import Enum as _Enum
11
11
 
12
12
  from nxtomomill.io.utils import convert_str_to_tuple
13
13
  from tomwer.core.utils.char import DEGREE_CHAR
@@ -97,7 +97,7 @@ class SliceGroupBox(qt.QGroupBox):
97
97
  )
98
98
 
99
99
  def setMode(self, mode: NabuSliceMode):
100
- mode = NabuSliceMode.from_value(mode)
100
+ mode = NabuSliceMode(mode)
101
101
  item_index = self._modeCB.findText(mode.value)
102
102
  self._modeCB.setCurrentIndex(item_index)
103
103
  old = self.blockSignals(True)
@@ -105,7 +105,7 @@ class SliceGroupBox(qt.QGroupBox):
105
105
  self.blockSignals(old)
106
106
 
107
107
  def getMode(self) -> NabuSliceMode:
108
- mode = NabuSliceMode.from_value(self._modeCB.currentText())
108
+ mode = NabuSliceMode(self._modeCB.currentText())
109
109
  return mode
110
110
 
111
111
  def _getSliceSelected(self):
@@ -159,9 +159,13 @@ class TranslationMvtFileWidget(qt.QWidget):
159
159
  self._grpBox.layout().setContentsMargins(0, 0, 0, 0)
160
160
  self._grpBox.layout().setSpacing(0)
161
161
 
162
- self._hdf5FileRB = qt.QRadioButton(self.Mode.HDF5.value, self)
162
+ self._hdf5FileRB = qt.QRadioButton(
163
+ TranslationMvtFileWidget.Mode.HDF5.value, self
164
+ )
163
165
  self._grpBox.layout().addWidget(self._hdf5FileRB)
164
- self._textFileRB = qt.QRadioButton(self.Mode.TEXT.value, self)
166
+ self._textFileRB = qt.QRadioButton(
167
+ TranslationMvtFileWidget.Mode.TEXT.value, self
168
+ )
165
169
  self._grpBox.layout().addWidget(self._textFileRB)
166
170
  self.layout().addWidget(self._grpBox)
167
171
 
@@ -334,45 +338,52 @@ class _NabuReconstructionConfig(qt.QWidget, _NabuStageConfigBase):
334
338
  self.registerWidget(self._methodLabel, "required")
335
339
  self.registerWidget(self._methodQCB, "required")
336
340
 
341
+ self._methodWarningLabel = qt.QLabel(
342
+ f"\tWARNING: \n\t1.' {_NabuReconstructionMethods.MLEM.value}' can be EXTREMELY SLOW on transmission\n\tdata and may produce erroneous results.\n\t2.MLEM should only be used with XRFCT data."
343
+ )
344
+ self._methodWarningLabel.setStyleSheet("color: red")
345
+ self._methodWarningLabel.setVisible(False)
346
+ self.layout().addWidget(self._methodWarningLabel, 3, 0, 1, 2)
347
+
337
348
  # angle_offset
338
349
  self._labelOffsetLabel = qt.QLabel("angle offset (in degree)", self)
339
- self.layout().addWidget(self._labelOffsetLabel, 3, 0, 1, 1)
350
+ self.layout().addWidget(self._labelOffsetLabel, 4, 0, 1, 1)
340
351
  self._angleOffsetQDSB = QDoubleSpinBoxIgnoreWheel(self)
341
352
  self._angleOffsetQDSB.setMaximum(-180)
342
353
  self._angleOffsetQDSB.setMaximum(180)
343
- self.layout().addWidget(self._angleOffsetQDSB, 3, 1, 1, 1)
354
+ self.layout().addWidget(self._angleOffsetQDSB, 4, 1, 1, 1)
344
355
  self.registerWidget(self._labelOffsetLabel, "advanced")
345
356
  self.registerWidget(self._angleOffsetQDSB, "advanced")
346
357
 
347
358
  # fbp filter type
348
359
  self._fbpFilterCB = qt.QCheckBox("fbp filter", self)
349
- self.layout().addWidget(self._fbpFilterCB, 4, 0, 1, 1)
360
+ self.layout().addWidget(self._fbpFilterCB, 5, 0, 1, 1)
350
361
  self._fbpFilterType = QComboBoxIgnoreWheel(self)
351
362
  for filter_type in _NabuFBPFilterType:
352
363
  self._fbpFilterType.addItem(filter_type.value)
353
- self.layout().addWidget(self._fbpFilterType, 4, 1, 1, 1)
364
+ self.layout().addWidget(self._fbpFilterType, 5, 1, 1, 1)
354
365
  self.registerWidget(self._fbpFilterCB, "advanced")
355
366
  self.registerWidget(self._fbpFilterType, "advanced")
356
367
 
357
368
  # padding type
358
369
  self._paddingTypeLabel = qt.QLabel("padding type", self)
359
- self.layout().addWidget(self._paddingTypeLabel, 5, 0, 1, 1)
370
+ self.layout().addWidget(self._paddingTypeLabel, 6, 0, 1, 1)
360
371
  self._paddingType = QComboBoxIgnoreWheel(self)
361
372
  for fbp_padding_type in _NabuPaddingType:
362
373
  self._paddingType.addItem(fbp_padding_type.value)
363
- self.layout().addWidget(self._paddingType, 5, 1, 1, 1)
374
+ self.layout().addWidget(self._paddingType, 6, 1, 1, 1)
364
375
  self.registerWidget(self._paddingTypeLabel, "optional")
365
376
  self.registerWidget(self._paddingType, "optional")
366
377
 
367
378
  # sub region
368
379
  self._subRegionSelector = _NabuReconstructionSubRegion(parent=self)
369
- self.layout().addWidget(self._subRegionSelector, 7, 0, 1, 2)
380
+ self.layout().addWidget(self._subRegionSelector, 8, 0, 1, 2)
370
381
 
371
382
  # iterations
372
383
  self._iterationsLabel = qt.QLabel("iterations", self)
373
- self.layout().addWidget(self._iterationsLabel, 8, 0, 1, 1)
384
+ self.layout().addWidget(self._iterationsLabel, 9, 0, 1, 1)
374
385
  self._iterationSB = qt.QSpinBox(parent=self)
375
- self.layout().addWidget(self._iterationSB, 8, 1, 1, 1)
386
+ self.layout().addWidget(self._iterationSB, 9, 1, 1, 1)
376
387
  self._iterationSB.setMinimum(1)
377
388
  self._iterationSB.setMaximum(9999)
378
389
  # not supported for now so hidden
@@ -383,20 +394,20 @@ class _NabuReconstructionConfig(qt.QWidget, _NabuStageConfigBase):
383
394
  self._binSubSamplingGB = _BinSubSampling(
384
395
  "binning and sub-sampling", parent=self
385
396
  )
386
- self.layout().addWidget(self._binSubSamplingGB, 9, 0, 1, 2)
397
+ self.layout().addWidget(self._binSubSamplingGB, 10, 0, 1, 2)
387
398
 
388
399
  # optimization algorithm:
389
400
  # set has default value for now, because has only one at the moment
390
401
 
391
402
  # weight total variation
392
403
  self._tvLabel = qt.QLabel("total variation weight", self)
393
- self.layout().addWidget(self._tvLabel, 10, 0, 1, 1)
404
+ self.layout().addWidget(self._tvLabel, 11, 0, 1, 1)
394
405
  self._totalVariationWeight = qt.QDoubleSpinBox(self)
395
406
  self._totalVariationWeight.setMinimum(0.0)
396
407
  self._totalVariationWeight.setMaximum(1.0)
397
408
  self._totalVariationWeight.setDecimals(4)
398
409
  self._totalVariationWeight.setSingleStep(0.002)
399
- self.layout().addWidget(self._totalVariationWeight, 9, 1, 1, 1)
410
+ self.layout().addWidget(self._totalVariationWeight, 10, 1, 1, 1)
400
411
  # not supported for now so hidden
401
412
  self._tvLabel.hide()
402
413
  self._totalVariationWeight.hide()
@@ -406,7 +417,7 @@ class _NabuReconstructionConfig(qt.QWidget, _NabuStageConfigBase):
406
417
  self._preconditioningFilter.setToolTip(
407
418
  'Whether to enable "filter ' 'preconditioning" for iterative' " methods"
408
419
  )
409
- self.layout().addWidget(self._preconditioningFilter, 10, 0, 1, 2)
420
+ self.layout().addWidget(self._preconditioningFilter, 11, 0, 1, 2)
410
421
  # not supported for now so hidden
411
422
  self._preconditioningFilter.hide()
412
423
 
@@ -415,7 +426,7 @@ class _NabuReconstructionConfig(qt.QWidget, _NabuStageConfigBase):
415
426
  self._positivityConstraintCB.setToolTip(
416
427
  "Whether to enforce a " "positivity constraint in the " "reconstruction."
417
428
  )
418
- self.layout().addWidget(self._positivityConstraintCB, 11, 0, 1, 2)
429
+ self.layout().addWidget(self._positivityConstraintCB, 12, 0, 1, 2)
419
430
  # not supported for now so hidden
420
431
  self._positivityConstraintCB.hide()
421
432
 
@@ -424,13 +435,13 @@ class _NabuReconstructionConfig(qt.QWidget, _NabuStageConfigBase):
424
435
  self._clipOuterCircleCB.setToolTip(
425
436
  "Whether to set to zero voxels falling outside of the reconstruction region"
426
437
  )
427
- self.layout().addWidget(self._clipOuterCircleCB, 12, 0, 1, 2)
438
+ self.layout().addWidget(self._clipOuterCircleCB, 13, 0, 1, 2)
428
439
  self.registerWidget(self._clipOuterCircleCB, "optional")
429
440
 
430
441
  # centered axis option
431
442
  self._centeredAxisCB = qt.QCheckBox("centered axis", self)
432
443
  self._centeredAxisCB.setToolTip("")
433
- self.layout().addWidget(self._centeredAxisCB, 13, 0, 1, 2)
444
+ self.layout().addWidget(self._centeredAxisCB, 14, 0, 1, 2)
434
445
  self.registerWidget(self._centeredAxisCB, "optional")
435
446
 
436
447
  # translation movement file
@@ -440,6 +451,12 @@ class _NabuReconstructionConfig(qt.QWidget, _NabuStageConfigBase):
440
451
  self.layout().addWidget(self._transMvtFileWidget, 22, 1, 1, 1)
441
452
  self.registerWidget(self._transMvtFileLabel, "advanced")
442
453
  self.registerWidget(self._transMvtFileWidget, "advanced")
454
+ translation_movement_tooltip = """
455
+ A file where each line describes the horizontal and vertical translations of the sample (or detector).
456
+ The order is 'horizontal, vertical'
457
+ It can be created from a numpy array saved with 'numpy.savetxt'"""
458
+ self._transMvtFileLabel.setToolTip(translation_movement_tooltip)
459
+ self._transMvtFileWidget.setToolTip(translation_movement_tooltip)
443
460
 
444
461
  # angle files (if the user want's to overwrite rotation angles)
445
462
  self._angleFileLabel = qt.QLabel("angles file", self)
@@ -527,8 +544,12 @@ class _NabuReconstructionConfig(qt.QWidget, _NabuStageConfigBase):
527
544
  def _slicesChanged(self, *args, **kwargs):
528
545
  self._signalConfChanged("tomwer_slices")
529
546
 
530
- def _methodChanged(self, *args, **kwargs):
547
+ def _methodChanged(self, index): # *args, **kwargs):
531
548
  self._signalConfChanged("method")
549
+ selected_method = self.getMethod()
550
+ self._methodWarningLabel.setVisible(
551
+ selected_method == _NabuReconstructionMethods.MLEM
552
+ )
532
553
 
533
554
  def _angleOffsetChanged(self, *args, **kwargs):
534
555
  self._signalConfChanged("angle_offset")
@@ -574,10 +595,10 @@ class _NabuReconstructionConfig(qt.QWidget, _NabuStageConfigBase):
574
595
  raise NotImplementedError()
575
596
 
576
597
  def getMethod(self) -> _NabuReconstructionMethods:
577
- return _NabuReconstructionMethods.from_value(self._methodQCB.currentText())
598
+ return _NabuReconstructionMethods(self._methodQCB.currentText())
578
599
 
579
600
  def setMethod(self, method):
580
- method = _NabuReconstructionMethods.from_value(method)
601
+ method = _NabuReconstructionMethods(method)
581
602
  item_index = self._methodQCB.findText(method.value)
582
603
  self._methodQCB.setCurrentIndex(item_index)
583
604
 
@@ -589,7 +610,7 @@ class _NabuReconstructionConfig(qt.QWidget, _NabuStageConfigBase):
589
610
 
590
611
  def getFBPFilterType(self) -> _NabuFBPFilterType | None:
591
612
  if self._fbpFilterCB.isChecked():
592
- return _NabuFBPFilterType.from_value(self._fbpFilterType.currentText())
613
+ return _NabuFBPFilterType(self._fbpFilterType.currentText())
593
614
  else:
594
615
  return None
595
616
 
@@ -605,10 +626,10 @@ class _NabuReconstructionConfig(qt.QWidget, _NabuStageConfigBase):
605
626
  self._fbpFilterType.setCurrentIndex(filter_index)
606
627
 
607
628
  def getFBPPaddingType(self) -> _NabuPaddingType:
608
- return _NabuPaddingType.from_value(self._paddingType.currentText())
629
+ return _NabuPaddingType(self._paddingType.currentText())
609
630
 
610
631
  def setFBPPaddingType(self, padding):
611
- padding = _NabuPaddingType.from_value(padding)
632
+ padding = _NabuPaddingType(padding)
612
633
  padding_index = self._paddingType.findText(padding.value)
613
634
  self._paddingType.setCurrentIndex(padding_index)
614
635
 
@@ -1012,17 +1033,22 @@ class _BinSubSampling(qt.QGroupBox):
1012
1033
  def __init__(self, text, parent):
1013
1034
  qt.QGroupBox.__init__(self, text)
1014
1035
  self.setLayout(qt.QFormLayout())
1015
- # horizontal binning
1016
- self._hBinningSB = QSpinBoxIgnoreWheel(self)
1017
- self._hBinningSB.setMinimum(1)
1018
- self._hBinningSB.setMaximum(3)
1019
- self.layout().addRow("horizontal binning", self._hBinningSB)
1020
- # vertical binning
1021
- self._vBinningSB = qt.QSpinBox(self)
1022
- self._vBinningSB.setMinimum(1)
1023
- self._vBinningSB.setMaximum(100)
1024
- # self.layout().addRow('vertical binning', self._vBinningSB)
1025
- self._vBinningSB.setVisible(False)
1036
+ # binning
1037
+ self._binningSB = QSpinBoxIgnoreWheel(self)
1038
+ self._binningSB.setMinimum(1)
1039
+ self._binningSB.setMaximum(3)
1040
+ self.layout().addRow("binning", self._binningSB)
1041
+ self._binningSB.setToolTip(
1042
+ "Binning factor in the horizontal dimension when reading the data. \nThe final slices dimensions will be divided by this factor."
1043
+ )
1044
+ # z binning
1045
+ self._zBinningSB = qt.QSpinBox(self)
1046
+ self._zBinningSB.setMinimum(1)
1047
+ self._zBinningSB.setMaximum(100)
1048
+ self.layout().addRow("vertical binning", self._zBinningSB)
1049
+ self._zBinningSB.setToolTip(
1050
+ "Binning factor in the vertical dimension when reading the data. \nThis results in a lesser number of reconstructed slices."
1051
+ )
1026
1052
  # projection sub-sampling
1027
1053
  self._projSubsamplingSB = QSpinBoxIgnoreWheel(self)
1028
1054
  self._projSubsamplingSB.setMinimum(1)
@@ -1030,35 +1056,35 @@ class _BinSubSampling(qt.QGroupBox):
1030
1056
  self.layout().addRow("projection sub-sampling", self._projSubsamplingSB)
1031
1057
 
1032
1058
  # connect signal / slot
1033
- self._vBinningSB.valueChanged.connect(self._valueUpdated)
1034
- self._hBinningSB.valueChanged.connect(self._valueUpdated)
1059
+ self._zBinningSB.valueChanged.connect(self._valueUpdated)
1060
+ self._binningSB.valueChanged.connect(self._valueUpdated)
1035
1061
 
1036
- def getHorizontalBinning(self):
1037
- return self._hBinningSB.value()
1062
+ def getHorizontalBinning(self) -> int:
1063
+ return self._binningSB.value()
1038
1064
 
1039
- def setHorizontalBinning(self, binning):
1040
- return self._hBinningSB.setValue(int(binning))
1065
+ def setHorizontalBinning(self, binning: int):
1066
+ return self._binningSB.setValue(int(binning))
1041
1067
 
1042
- def getVerticalBinning(self):
1043
- return self._vBinningSB.value()
1068
+ def getVerticalBinning(self) -> int:
1069
+ return self._zBinningSB.value()
1044
1070
 
1045
- def setVerticalBinning(self, binning):
1046
- return self._vBinningSB.setValue(int(binning))
1071
+ def setVerticalBinning(self, binning: int):
1072
+ return self._zBinningSB.setValue(int(binning))
1047
1073
 
1048
- def getProjSubsampling(self):
1074
+ def getProjSubsampling(self) -> int:
1049
1075
  return self._projSubsamplingSB.value()
1050
1076
 
1051
- def setProjSubsampling(self, subsampling):
1077
+ def setProjSubsampling(self, subsampling: int):
1052
1078
  return self._projSubsamplingSB.setValue(int(subsampling))
1053
1079
 
1054
- def getConfiguration(self):
1080
+ def getConfiguration(self) -> dict:
1055
1081
  return {
1056
1082
  "binning": self.getHorizontalBinning(),
1057
1083
  "binning_z": self.getVerticalBinning(),
1058
1084
  "projections_subsampling": self.getProjSubsampling(),
1059
1085
  }
1060
1086
 
1061
- def setConfiguration(self, config):
1087
+ def setConfiguration(self, config: dict):
1062
1088
  if "binning" in config:
1063
1089
  self.setHorizontalBinning(config["binning"])
1064
1090
  if "binning_z" in config:
@@ -9,7 +9,6 @@ from silx.gui import qt
9
9
 
10
10
  from tomwer.core.process.reconstruction.nabu.utils import _NabuStages
11
11
  from tomwer.gui import icons
12
- from tomwer.gui.utils.illustrations import _IllustrationWidget
13
12
  from tomwer.utils import docstring
14
13
 
15
14
  from ...utils.flow import FlowCanvas, FlowDirection
@@ -32,7 +31,7 @@ class NabuFlowControl(qt.QWidget):
32
31
  def __init__(self, parent, direction):
33
32
  qt.QWidget.__init__(self, parent=parent)
34
33
 
35
- self._direction = FlowDirection.from_value(direction)
34
+ self._direction = FlowDirection(direction)
36
35
 
37
36
  if self._direction is FlowDirection.VERTICAL:
38
37
  self.setLayout(qt.QVBoxLayout())
@@ -113,7 +112,7 @@ class NabuFlowControl(qt.QWidget):
113
112
  self.setPostVisible(True)
114
113
 
115
114
  def _updateActiveProcess(self, stage):
116
- stage = _NabuStages.from_value(stage)
115
+ stage = _NabuStages(stage)
117
116
 
118
117
  if stage is _NabuStages.INI:
119
118
  activeWidget = self._iniProcessWidgets
@@ -330,20 +329,13 @@ class NabuFlowArea(qt.QWidget):
330
329
 
331
330
  def __init__(self, parent, direction):
332
331
  qt.QWidget.__init__(self, parent=parent)
333
- direction = FlowDirection.from_value(direction)
332
+ direction = FlowDirection(direction)
334
333
 
335
334
  if direction is FlowDirection.VERTICAL:
336
335
  self.setLayout(qt.QHBoxLayout(self))
337
- img_flow = "flow_down"
338
336
  else:
339
337
  self.setLayout(qt.QVBoxLayout(self))
340
- img_flow = "flow_right"
341
338
 
342
- self._flowIllustration = _IllustrationWidget(parent=self, img=img_flow)
343
- self._flowIllustration.setFixedWidth(50)
344
- self._flowIllustration.setSizePolicy(
345
- qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum
346
- )
347
339
  self._control = NabuFlowControl(parent=self, direction=direction)
348
340
  self._control.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum)
349
341
  self._addRmWidget = _AddRemoveProcessWidget(parent=self, direction=direction)
@@ -352,13 +344,11 @@ class NabuFlowArea(qt.QWidget):
352
344
 
353
345
  if direction is FlowDirection.VERTICAL:
354
346
  # if vertical illustration left sided
355
- self.layout().addWidget(self._flowIllustration)
356
347
  self.layout().addWidget(self._control)
357
348
  self.layout().addWidget(self._addRmWidget)
358
349
  else:
359
350
  # if horizontal illustration bottom sided
360
351
  self.layout().addWidget(self._control)
361
- self.layout().addWidget(self._flowIllustration)
362
352
  self.layout().addWidget(self._addRmWidget)
363
353
 
364
354
  # set up
@@ -10,7 +10,7 @@ from nabu.pipeline.fullfield.nabu_config import (
10
10
  )
11
11
  from silx.gui import icons as silx_icons
12
12
  from silx.gui import qt
13
- from silx.utils.enum import Enum as _Enum
13
+ from enum import Enum as _Enum
14
14
  from nxtomo.nxobject.nxdetector import FOV
15
15
 
16
16
  from tomwer.core.utils.dictutils import concatenate_dict
@@ -56,7 +56,7 @@ class _NabuStages(_Enum):
56
56
  @staticmethod
57
57
  def getProcessEnum(stage):
58
58
  """Return the process Enum associated to the stage"""
59
- stage = _NabuStages.from_value(stage)
59
+ stage = _NabuStages(stage)
60
60
  if stage is _NabuStages.INI:
61
61
  raise NotImplementedError()
62
62
  elif stage is _NabuStages.PRE:
@@ -113,8 +113,8 @@ class _NabuProcess(qt.QWidget):
113
113
  qt.QWidget.__init__(self, parent=parent)
114
114
  self.setLayout(qt.QGridLayout())
115
115
  self._stageCB = qt.QComboBox(parent=self)
116
- for stage in _NabuStages.values():
117
- self._stageCB.addItem(stage)
116
+ for stage in _NabuStages:
117
+ self._stageCB.addItem(stage.value)
118
118
 
119
119
  self.layout().addWidget(qt.QLabel("stage:", self), 0, 0, 1, 1)
120
120
  self.layout().addWidget(self._stageCB, 0, 1, 1, 1)
@@ -147,7 +147,7 @@ class _NabuConfiguration(qt.QWidget):
147
147
  self.addStage(stage=stage, processes=processes)
148
148
 
149
149
  def addStage(self, stage, processes):
150
- stage = _NabuStages.from_value(value=stage)
150
+ stage = _NabuStages(value=stage)
151
151
  for process in processes:
152
152
  _NabuStages.getProcessEnum(stage=stage)
153
153
 
@@ -377,7 +377,7 @@ class NabuWindow(qt.QMainWindow):
377
377
  return self._filterAction.isChecked()
378
378
 
379
379
  def setConfigurationLevel(self, level):
380
- level = ConfigurationLevel.from_value(level)
380
+ level = ConfigurationLevel(level)
381
381
  if level == ConfigurationLevel.REQUIRED:
382
382
  self._minimalisticAction.setChecked(True)
383
383
  elif level == ConfigurationLevel.ADVANCED:
@@ -436,7 +436,7 @@ class NabuWidget(qt.QWidget):
436
436
 
437
437
  def __init__(self, parent, flow_direction="vertical"):
438
438
  qt.QWidget.__init__(self, parent=parent)
439
- flow_direction = FlowDirection.from_value(flow_direction)
439
+ flow_direction = FlowDirection(flow_direction)
440
440
  self.setLayout(qt.QGridLayout())
441
441
  self._filteringActive = True
442
442
  self._configuration_level = ConfigurationLevel.OPTIONAL
@@ -485,7 +485,7 @@ class NabuWidget(qt.QWidget):
485
485
  qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum
486
486
  )
487
487
  self._configurationScrollArea.setSizePolicy(
488
- qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum
488
+ qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum
489
489
  )
490
490
 
491
491
  # expose API
@@ -575,10 +575,10 @@ class NabuWidget(qt.QWidget):
575
575
  self._configuration.hidePaganinInterface()
576
576
 
577
577
  def getMode(self):
578
- return _NabuMode.from_value(self._nabuModeCB.currentText())
578
+ return _NabuMode(self._nabuModeCB.currentText())
579
579
 
580
580
  def setMode(self, mode):
581
- mode = _NabuMode.from_value(mode)
581
+ mode = _NabuMode(mode)
582
582
  idx = self._nabuModeCB.findText(mode.value)
583
583
  self._nabuModeCB.setCurrentIndex(idx)
584
584
 
@@ -601,7 +601,7 @@ class NabuWidget(qt.QWidget):
601
601
  self._configurationScrollArea.updateGeometry()
602
602
 
603
603
  def setConfigurationLevel(self, level):
604
- level = ConfigurationLevel.from_value(level)
604
+ level = ConfigurationLevel(level)
605
605
  self._configuration_level = level
606
606
  self.updateConfigurationFilter()
607
607
 
@@ -15,6 +15,7 @@ def test_CastVolumeWidget(qtapp): # noqa F811
15
15
  "overwrite": True,
16
16
  "rescale_max_percentile": 90,
17
17
  "rescale_min_percentile": 10,
18
+ "remove_input_volume": False,
18
19
  }
19
20
 
20
21
  widget._minMaxAuto.setChecked(False)
@@ -28,6 +29,7 @@ def test_CastVolumeWidget(qtapp): # noqa F811
28
29
  "overwrite": True,
29
30
  "rescale_max_percentile": None,
30
31
  "rescale_min_percentile": None,
32
+ "remove_input_volume": False,
31
33
  }
32
34
 
33
35
  widget.setDataMin(1.0)
@@ -43,6 +45,7 @@ def test_CastVolumeWidget(qtapp): # noqa F811
43
45
  "overwrite": True,
44
46
  "rescale_max_percentile": None,
45
47
  "rescale_min_percentile": None,
48
+ "remove_input_volume": False,
46
49
  }
47
50
  widget.setOutputFileformat("edf")
48
51
  assert widget.getConfiguration() == {
@@ -55,6 +58,7 @@ def test_CastVolumeWidget(qtapp): # noqa F811
55
58
  "overwrite": True,
56
59
  "rescale_max_percentile": None,
57
60
  "rescale_min_percentile": None,
61
+ "remove_input_volume": False,
58
62
  }
59
63
  widget.setOverwrite(False)
60
64
  assert widget.getConfiguration() == {
@@ -67,6 +71,7 @@ def test_CastVolumeWidget(qtapp): # noqa F811
67
71
  "overwrite": False,
68
72
  "rescale_max_percentile": None,
69
73
  "rescale_min_percentile": None,
74
+ "remove_input_volume": False,
70
75
  }
71
76
  widget.setOutputDataType("float32")
72
77
  assert widget.getConfiguration() == {
@@ -79,4 +84,18 @@ def test_CastVolumeWidget(qtapp): # noqa F811
79
84
  "overwrite": False,
80
85
  "rescale_max_percentile": None,
81
86
  "rescale_min_percentile": None,
87
+ "remove_input_volume": False,
88
+ }
89
+ widget.setRemoveInputVolume(True)
90
+ assert widget.getConfiguration() == {
91
+ "compression_ratios": None,
92
+ "data_max": 10.0,
93
+ "data_min": 1.0,
94
+ "output_data_type": "float32",
95
+ "output_dir": "{volume_data_parent_folder}/cast_volume",
96
+ "output_file_format": "edf",
97
+ "overwrite": False,
98
+ "rescale_max_percentile": None,
99
+ "rescale_min_percentile": None,
100
+ "remove_input_volume": True,
82
101
  }
@@ -330,7 +330,7 @@ class NabuVolumeWidget(_NabuStageConfigBase, qt.QWidget):
330
330
  self.setHistogramRequested(requested=bool(config["output_histogram"]))
331
331
 
332
332
  def setConfigurationLevel(self, level):
333
- level = ConfigurationLevel.from_value(level)
333
+ level = ConfigurationLevel(level)
334
334
  _NabuStageConfigBase.setConfigurationLevel(self, level)
335
335
 
336
336
  def getConfigurationLevel(self):
@@ -493,21 +493,21 @@ class _NormIntensityOptions(qt.QWidget):
493
493
  self._lockButton.hide()
494
494
 
495
495
  def getCurrentMethod(self):
496
- return Method.from_value(self._modeCB.currentText())
496
+ return Method(self._modeCB.currentText())
497
497
 
498
498
  def setCurrentMethod(self, method):
499
- method = Method.from_value(method)
499
+ method = Method(method)
500
500
  idx = self._modeCB.findText(method.value)
501
501
  self._modeCB.setCurrentIndex(idx)
502
502
 
503
503
  def getCurrentSource(self):
504
504
  if self.getCurrentMethod() in (Method.DIVISION, Method.SUBTRACTION):
505
- return _ValueSource.from_value(self._sourceCB.currentText())
505
+ return _ValueSource(self._sourceCB.currentText())
506
506
  else:
507
507
  return _ValueSource.NONE
508
508
 
509
509
  def setCurrentSource(self, source):
510
- source = _ValueSource.from_value(source)
510
+ source = _ValueSource(source)
511
511
  idx = self._sourceCB.findText(source.value)
512
512
  self._sourceCB.setCurrentIndex(idx)
513
513
 
@@ -601,8 +601,8 @@ class _NormIntensityCalcOpts(qt.QWidget):
601
601
  self.setLayout(qt.QFormLayout())
602
602
  # calculation function
603
603
  self._calculationModeCB = qt.QComboBox(self)
604
- for fct in _normParams._ValueCalculationFct.values():
605
- self._calculationModeCB.addItem(fct)
604
+ for fct in _normParams._ValueCalculationFct:
605
+ self._calculationModeCB.addItem(fct.value)
606
606
  self._calculationModeLabel = qt.QLabel("calculation fct", self)
607
607
  self.layout().addRow(self._calculationModeLabel, self._calculationModeCB)
608
608
 
@@ -616,14 +616,10 @@ class _NormIntensityCalcOpts(qt.QWidget):
616
616
  self._calculationModeCB.setVisible(visible)
617
617
 
618
618
  def getCalculationFct(self):
619
- return _normParams._ValueCalculationFct.from_value(
620
- self._calculationModeCB.currentText()
621
- )
619
+ return _normParams._ValueCalculationFct(self._calculationModeCB.currentText())
622
620
 
623
621
  def setCalculationFct(self, fct):
624
- idx = self._calculationModeCB.findText(
625
- _normParams._ValueCalculationFct.from_value(fct)
626
- )
622
+ idx = self._calculationModeCB.findText(_normParams._ValueCalculationFct(fct))
627
623
  self._calculationModeCB.setCurrentIndex(idx)
628
624
 
629
625
 
@@ -13,7 +13,7 @@ from silx.gui import icons as silxicons
13
13
  from silx.gui import qt
14
14
  from silx.gui.dialog.ImageFileDialog import ImageFileDialog
15
15
  from silx.gui.plot import items
16
- from silx.utils.enum import Enum as _Enum
16
+ from enum import Enum as _Enum
17
17
  from tomoscan.esrf.scan.utils import get_data
18
18
 
19
19
  from tomwer.core.process.reconstruction.utils.cor import (
@@ -308,7 +308,7 @@ class _ReconstructionModeGB(qt.QGroupBox):
308
308
  raise ValueError("No reconstruction mode selected")
309
309
 
310
310
  def setReconstructionMode(self, mode: ReconstructionMode | str) -> None:
311
- mode = ReconstructionMode.from_value(mode)
311
+ mode = ReconstructionMode(mode)
312
312
  if mode is ReconstructionMode.TILT_CORRECTION:
313
313
  self._tiltCorrectionRB.setChecked(True)
314
314
  elif mode is ReconstructionMode.VERTICAL: