darfix 4.2.0__py3-none-any.whl → 4.3.0__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 (144) hide show
  1. darfix/core/data_selection.py +11 -2
  2. darfix/core/dataset.py +72 -157
  3. darfix/core/grainplot.py +44 -56
  4. darfix/core/{imageStack.py → image_stack.py} +9 -15
  5. darfix/core/moment_types.py +6 -0
  6. darfix/core/{noiseremoval.py → noise_removal.py} +25 -24
  7. darfix/core/noise_removal_type.py +14 -0
  8. darfix/core/positioners.py +6 -0
  9. darfix/core/rocking_curves.py +6 -3
  10. darfix/core/rocking_curves_map.py +1 -1
  11. darfix/core/{shiftcorrection.py → shift_correction.py} +1 -2
  12. darfix/core/state_of_operation.py +7 -46
  13. darfix/core/utils.py +0 -39
  14. darfix/dtypes.py +1 -9
  15. darfix/gui/{binningWidget.py → binning_widget.py} +2 -29
  16. darfix/gui/{blindSourceSeparationWidget.py → blind_source_separation_widget.py} +4 -16
  17. darfix/gui/{chooseDimensions.py → choose_dimensions.py} +1 -1
  18. darfix/gui/concatenate_scans.py +4 -4
  19. darfix/gui/data_selection/{hdf5_data_selection_widgets.py → hdf5_dataset_selection_widget.py} +3 -56
  20. darfix/gui/data_selection/line_edits.py +54 -8
  21. darfix/gui/data_selection/scan_selection_widgets.py +24 -11
  22. darfix/gui/data_selection/utils.py +11 -0
  23. darfix/gui/data_selection/{WorkingDirSelectionWidget.py → working_dir_selection_widget.py} +15 -14
  24. darfix/gui/{dimensionsWidget.py → dimensions_widget.py} +1 -1
  25. darfix/gui/{displayComponentsWidget.py → display_components_widget.py} +1 -1
  26. darfix/gui/{filterByDimension.py → filter_by_dimension.py} +1 -1
  27. darfix/gui/{grainplot/dimensionRangeSlider2D.py → grain_plot/dimension_range_slider_2d.py} +2 -2
  28. darfix/gui/{grainplot/grainPlotWidget.py → grain_plot/grain_plot_widget.py} +1 -1
  29. darfix/gui/{grainplot/mosaicityWidget.py → grain_plot/mosaicity_widget.py} +21 -23
  30. darfix/gui/{magnificationWidget.py → magnification_widget.py} +1 -1
  31. darfix/gui/{noiseremoval → noise_removal}/noise_removal_widget.py +12 -16
  32. darfix/gui/{noiseremoval → noise_removal}/operation_list_widget.py +2 -2
  33. darfix/gui/{noiseremoval → noise_removal}/parameters_widget.py +6 -6
  34. darfix/gui/{PCAWidget.py → pca_widget.py} +2 -4
  35. darfix/gui/{projectionWidget.py → projection_widget.py} +1 -1
  36. darfix/gui/rocking_curves/{rockingCurvesPlot.py → rocking_curves_plot.py} +13 -13
  37. darfix/gui/rocking_curves/{rockingCurvesWidget.py → rocking_curves_widget.py} +10 -18
  38. darfix/gui/{roiSelectionWidget.py → roi_selection_widget.py} +9 -101
  39. darfix/gui/{shiftcorrection/shiftCorrectionWidget.py → shift_correction/shift_correction_widget.py} +4 -7
  40. darfix/gui/utils/data_path_completer.py +7 -7
  41. darfix/gui/utils/data_path_selection.py +4 -4
  42. darfix/gui/utils/{rangeSlider.py → range_slider.py} +1 -1
  43. darfix/gui/{weakBeamWidget.py → weak_beam_widget.py} +13 -28
  44. darfix/gui/{zSumWidget.py → zsum_widget.py} +1 -2
  45. darfix/main.py +19 -3
  46. darfix/processing/rocking_curves.py +12 -13
  47. darfix/tasks/binning.py +6 -17
  48. darfix/tasks/blind_source_separation.py +121 -0
  49. darfix/tasks/blindsourceseparation.py +8 -131
  50. darfix/tasks/copy.py +0 -2
  51. darfix/tasks/data_partition.py +39 -0
  52. darfix/tasks/datapartition.py +8 -50
  53. darfix/tasks/dimension_definition.py +197 -0
  54. darfix/tasks/dimensiondefinition.py +8 -197
  55. darfix/tasks/grain_plot.py +93 -0
  56. darfix/tasks/grainplot.py +8 -103
  57. darfix/tasks/hdf5_data_selection.py +5 -11
  58. darfix/tasks/hdf5_scans_concatenation.py +4 -4
  59. darfix/tasks/noise_removal.py +88 -0
  60. darfix/tasks/noiseremoval.py +8 -86
  61. darfix/tasks/pca.py +1 -3
  62. darfix/tasks/projection.py +1 -6
  63. darfix/tasks/rocking_curves.py +10 -5
  64. darfix/tasks/roi.py +0 -2
  65. darfix/tasks/shift_correction.py +45 -0
  66. darfix/tasks/shiftcorrection.py +8 -43
  67. darfix/tasks/transformation.py +0 -2
  68. darfix/tasks/weak_beam.py +71 -0
  69. darfix/tasks/weakbeam.py +8 -67
  70. darfix/tasks/zsum.py +1 -1
  71. darfix/tests/conftest.py +1 -1
  72. darfix/tests/gui/test_data_path_completer.py +4 -4
  73. darfix/tests/gui/test_dimension_range_slider_2d.py +2 -2
  74. darfix/tests/gui/test_range_slider_with_spinboxes.py +1 -1
  75. darfix/tests/orange/test_ewoks.py +13 -9
  76. darfix/tests/orange/widgets/test_hdf5_data_selection.py +93 -0
  77. darfix/tests/tasks/test_data_copy.py +0 -2
  78. darfix/tests/tasks/{test_dimensiondefinition.py → test_dimension_definition.py} +1 -1
  79. darfix/tests/tasks/test_weak_beam.py +9 -0
  80. darfix/tests/test_components_matching.py +2 -2
  81. darfix/tests/test_dataset.py +2 -28
  82. darfix/tests/test_dimension.py +1 -1
  83. darfix/tests/test_generate_grain_maps_nxdict.py +4 -5
  84. darfix/tests/test_image_operations.py +4 -4
  85. darfix/tests/test_image_registration.py +17 -17
  86. darfix/tests/test_image_stack.py +2 -13
  87. darfix/tests/test_mask.py +1 -1
  88. darfix/tests/test_moments.py +2 -2
  89. darfix/tests/test_rocking_curves.py +1 -3
  90. darfix/tests/test_shift.py +7 -7
  91. darfix/tests/test_workflow.py +4 -4
  92. darfix/tests/test_zsum.py +3 -6
  93. {darfix-4.2.0.dist-info → darfix-4.3.0.dist-info}/METADATA +5 -3
  94. {darfix-4.2.0.dist-info → darfix-4.3.0.dist-info}/RECORD +141 -135
  95. orangecontrib/darfix/widgets/__init__.py +10 -1
  96. orangecontrib/darfix/widgets/binning.py +3 -3
  97. orangecontrib/darfix/widgets/blindsourceseparation.py +4 -6
  98. orangecontrib/darfix/widgets/concatenateHDF5.py +1 -1
  99. orangecontrib/darfix/widgets/datacopy.py +1 -1
  100. orangecontrib/darfix/widgets/datapartition.py +7 -102
  101. orangecontrib/darfix/widgets/{datasetWidgetBase.py → dataset_widget_base.py} +17 -5
  102. orangecontrib/darfix/widgets/dimensions.py +6 -6
  103. orangecontrib/darfix/widgets/grainplot.py +3 -3
  104. orangecontrib/darfix/widgets/hdf5dataselection.py +34 -14
  105. orangecontrib/darfix/widgets/metadata.py +2 -2
  106. orangecontrib/darfix/widgets/noiseremoval.py +4 -4
  107. orangecontrib/darfix/widgets/{operationWidgetBase.py → operation_widget_base.py} +2 -2
  108. orangecontrib/darfix/widgets/pca.py +2 -2
  109. orangecontrib/darfix/widgets/projection.py +2 -2
  110. orangecontrib/darfix/widgets/rockingcurves.py +5 -2
  111. orangecontrib/darfix/widgets/roiselection.py +24 -106
  112. orangecontrib/darfix/widgets/rsmhistogram.py +2 -2
  113. orangecontrib/darfix/widgets/shiftcorrection.py +3 -3
  114. orangecontrib/darfix/widgets/transformation.py +4 -4
  115. orangecontrib/darfix/widgets/weakbeam.py +20 -103
  116. orangecontrib/darfix/widgets/zsum.py +3 -5
  117. darfix/gui/dataPartitionWidget.py +0 -167
  118. darfix/gui/data_selection/DataSelectionBase.py +0 -59
  119. darfix/tests/tasks/test_datapartition.py +0 -52
  120. /darfix/core/{componentsMatching.py → components_matching.py} +0 -0
  121. /darfix/core/{datapathfinder.py → data_path_finder.py} +0 -0
  122. /darfix/core/{imageRegistration.py → image_registration.py} +0 -0
  123. /darfix/gui/{grainplot → grain_plot}/__init__.py +0 -0
  124. /darfix/gui/{grainplot → grain_plot}/_oridist_toolbar_buttons.py +0 -0
  125. /darfix/gui/{grainplot → grain_plot}/flashlight.py +0 -0
  126. /darfix/gui/{grainplot → grain_plot}/flashlight_mode_action.py +0 -0
  127. /darfix/gui/{grainplot → grain_plot}/oridist_toolbar.py +0 -0
  128. /darfix/gui/{grainplot → grain_plot}/utils.py +0 -0
  129. /darfix/gui/{metadataWidget.py → metadata_widget.py} +0 -0
  130. /darfix/gui/{operationProcess.py → parallel/operation_process.py} +0 -0
  131. /darfix/gui/{operationThread.py → parallel/operation_thread.py} +0 -0
  132. /darfix/gui/rocking_curves/{fitComboBox.py → fit_combobox.py} +0 -0
  133. /darfix/gui/{roiLimitsToolbar.py → roi_limits_toolbar.py} +0 -0
  134. /darfix/gui/{rsmHistogramWidget.py → rsm_histogram_widget.py} +0 -0
  135. /darfix/gui/{rsmWidget.py → rsm_widget.py} +0 -0
  136. /darfix/gui/{shiftcorrection → shift_correction}/__init__.py +0 -0
  137. /darfix/gui/{shiftcorrection/shiftInput.py → shift_correction/shift_input.py} +0 -0
  138. /darfix/gui/utils/{standardButtonBox.py → standard_buttonbox.py} +0 -0
  139. /darfix/processing/{imageOperations.py → image_operations.py} +0 -0
  140. /darfix/tests/{test_datapathfinder.py → test_data_path_finder.py} +0 -0
  141. {darfix-4.2.0.dist-info → darfix-4.3.0.dist-info}/WHEEL +0 -0
  142. {darfix-4.2.0.dist-info → darfix-4.3.0.dist-info}/entry_points.txt +0 -0
  143. {darfix-4.2.0.dist-info → darfix-4.3.0.dist-info}/licenses/LICENSE +0 -0
  144. {darfix-4.2.0.dist-info → darfix-4.3.0.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from ewoksorange.bindings.owwidgets import OWEwoksWidgetOneThread
3
+ from ewoksorange.gui.owwidgets.threaded import OWEwoksWidgetOneThread
4
4
  from silx.gui import qt
5
5
 
6
6
  from darfix import dtypes
@@ -27,6 +27,8 @@ class DatasetWidgetBase(OWEwoksWidgetOneThread, openclass=True):
27
27
  self.task_executor.finished.connect(self.__onFinishTask)
28
28
  self.task_executor.started.connect(self.__onStartEwoksTask)
29
29
 
30
+ self.__widgetToDisableWhenRunning = self.mainArea
31
+
30
32
  self.__datasetMenu: qt.QMenu = self.menuBar().addMenu("&Dataset")
31
33
 
32
34
  loadAction = self.__datasetMenu.addAction("Load")
@@ -65,12 +67,22 @@ class DatasetWidgetBase(OWEwoksWidgetOneThread, openclass=True):
65
67
  self.setDataset(dataset)
66
68
 
67
69
  def __onFinishTask(self):
68
- if self.mainArea is not None:
69
- self.mainArea.setEnabled(True)
70
+ if self.__widgetToDisableWhenRunning is not None:
71
+ self.__widgetToDisableWhenRunning.setEnabled(True)
70
72
 
71
73
  def __onStartEwoksTask(self):
72
- if self.mainArea is not None:
73
- self.mainArea.setDisabled(True)
74
+ if self.__widgetToDisableWhenRunning is not None:
75
+ self.__widgetToDisableWhenRunning.setDisabled(True)
74
76
 
75
77
  def getDatasetMenu(self) -> qt.QMenu:
76
78
  return self.__datasetMenu
79
+
80
+ def setWidgetToDisableWhenRunning(self, widget: qt.QWidget | None):
81
+ """
82
+ Set Widget to disable when a task is running.
83
+
84
+ Set to `None` if nothing to disable.
85
+
86
+ Default widget is `self.mainArea`
87
+ """
88
+ self.__widgetToDisableWhenRunning = widget
@@ -4,7 +4,7 @@ import logging
4
4
  from typing import Any
5
5
 
6
6
  from ewokscore.missing_data import is_missing_data
7
- from ewoksorange.gui.parameterform import block_signals
7
+ from ewoksorange.gui.widgets.parameter_form import block_signals
8
8
  from silx.gui import qt
9
9
 
10
10
  from darfix import dtypes
@@ -12,11 +12,11 @@ from darfix.core.dataset import ImageDataset
12
12
  from darfix.core.dimension import Dimension
13
13
  from darfix.core.dimension import find_dimensions_from_metadata
14
14
  from darfix.core.fscan_parser import fscan_get_dimensions
15
- from darfix.gui.dimensionsWidget import DimensionItem
16
- from darfix.gui.dimensionsWidget import DimensionWidget
17
- from darfix.tasks.dimensiondefinition import DimensionDefinition
18
- from darfix.tasks.dimensiondefinition import get_dimensions_error
19
- from orangecontrib.darfix.widgets.datasetWidgetBase import DatasetWidgetBase
15
+ from darfix.gui.dimensions_widget import DimensionItem
16
+ from darfix.gui.dimensions_widget import DimensionWidget
17
+ from darfix.tasks.dimension_definition import DimensionDefinition
18
+ from darfix.tasks.dimension_definition import get_dimensions_error
19
+ from orangecontrib.darfix.widgets.dataset_widget_base import DatasetWidgetBase
20
20
 
21
21
  _logger = logging.getLogger(__file__)
22
22
 
@@ -2,9 +2,9 @@ from __future__ import annotations
2
2
 
3
3
  from darfix import dtypes
4
4
  from darfix.core.grainplot import GrainPlotMaps
5
- from darfix.gui.grainplot.grainPlotWidget import GrainPlotWidget
6
- from darfix.tasks.grainplot import GrainPlot
7
- from orangecontrib.darfix.widgets.datasetWidgetBase import DatasetWidgetBase
5
+ from darfix.gui.grain_plot.grain_plot_widget import GrainPlotWidget
6
+ from darfix.tasks.grain_plot import GrainPlot
7
+ from orangecontrib.darfix.widgets.dataset_widget_base import DatasetWidgetBase
8
8
 
9
9
 
10
10
  class GrainPlotWidgetOW(DatasetWidgetBase, ewokstaskclass=GrainPlot):
@@ -1,15 +1,18 @@
1
1
  from __future__ import annotations
2
2
 
3
- from functools import partial
4
3
  from typing import Any
5
4
 
6
- from ewoksorange.bindings.owwidgets import OWEwoksWidgetOneThread
5
+ from ewoksorange.gui.owwidgets.threaded import OWEwoksWidgetOneThread
7
6
  from silx.gui import qt
8
7
 
8
+ from darfix.core.data_selection import get_default_output_directory
9
9
  from darfix.gui.data_selection.scan_selection_widgets import ScanSelectionWidget
10
10
  from darfix.gui.data_selection.scan_selection_widgets import (
11
11
  ScanSelectionWidgetWithPositioners,
12
12
  )
13
+ from darfix.gui.data_selection.working_dir_selection_widget import (
14
+ WorkingDirSelectionWidget,
15
+ )
13
16
  from darfix.gui.utils.message import show_error_msg
14
17
  from darfix.tasks.hdf5_data_selection import HDF5DataSelection
15
18
 
@@ -59,8 +62,8 @@ class HDF5DataSelectionWidgetOW(
59
62
  layout.addWidget(self._darkDataGroup)
60
63
 
61
64
  workingDirLayout = qt.QFormLayout()
62
- self._workingDirLineEdit = qt.QLineEdit()
63
- workingDirLayout.addRow("Working directory", self._workingDirLineEdit)
65
+ self._workingDirSelection = WorkingDirSelectionWidget()
66
+ workingDirLayout.addRow("Working directory", self._workingDirSelection)
64
67
  self._workflowTitleLineEdit = qt.QLineEdit()
65
68
  workingDirLayout.addRow("Workflow title", self._workflowTitleLineEdit)
66
69
  layout.addLayout(workingDirLayout)
@@ -76,14 +79,22 @@ class HDF5DataSelectionWidgetOW(
76
79
  self._loadInputs(self.get_task_input_values())
77
80
 
78
81
  # connect signal / slot
79
- self.task_executor.finished.connect(
80
- self.information,
81
- )
82
- self.task_executor.finished.connect(lambda: self.mainArea.setEnabled(True))
83
- self.task_executor.started.connect(
84
- partial(self.information, "Downloading dataset. This can take a while...")
82
+ self.task_executor.finished.connect(self._onTaskFinished)
83
+ self.task_executor.started.connect(self._onTaskStarted)
84
+ self._rawDataSelection.sigNewFileSelected.connect(self._onNewFileSelected)
85
+
86
+ def _onNewFileSelected(self):
87
+ self._workingDirSelection.setDefaultDir(
88
+ get_default_output_directory(self._rawDataSelection.getFilePath())
85
89
  )
86
- self.task_executor.started.connect(lambda: self.mainArea.setDisabled(True))
90
+
91
+ def _onTaskStarted(self):
92
+ self.information("Downloading dataset. This can take a while...")
93
+ self.mainArea.setDisabled(True)
94
+
95
+ def _onTaskFinished(self):
96
+ self.information()
97
+ self.mainArea.setEnabled(True)
87
98
 
88
99
  def task_output_changed(self) -> None:
89
100
  if self.task_succeeded:
@@ -101,6 +112,7 @@ class HDF5DataSelectionWidgetOW(
101
112
  rawDetectorDataPath = taskInputValues.get("raw_detector_data_path")
102
113
  if rawDetectorDataPath:
103
114
  self._rawDataSelection.setDetectorPath(rawDetectorDataPath)
115
+ self._onNewFileSelected()
104
116
 
105
117
  rawMetadataPath = taskInputValues.get("raw_metadata_path")
106
118
  if rawMetadataPath:
@@ -118,7 +130,7 @@ class HDF5DataSelectionWidgetOW(
118
130
 
119
131
  treatedDataDir = taskInputValues.get("treated_data_dir")
120
132
  if treatedDataDir is not None:
121
- self._workingDirLineEdit.setText(treatedDataDir)
133
+ self._workingDirSelection.setDir(treatedDataDir)
122
134
 
123
135
  workflowTitle = taskInputValues.get("workflow_title")
124
136
  if workflowTitle is not None:
@@ -138,10 +150,10 @@ class HDF5DataSelectionWidgetOW(
138
150
  "dark_detector_data_path": self._darkDataSelection.getDetectorPath(),
139
151
  }
140
152
 
141
- if self._workingDirLineEdit.text():
153
+ if self._workingDirSelection.getDir():
142
154
  inputs = {
143
155
  **inputs,
144
- "treated_data_dir": self._workingDirLineEdit.text(),
156
+ "treated_data_dir": self._workingDirSelection.getDir(),
145
157
  }
146
158
 
147
159
  if self._workflowTitleLineEdit.text():
@@ -161,7 +173,15 @@ class HDF5DataSelectionWidgetOW(
161
173
  self.set_default_input(key, value)
162
174
 
163
175
  def _executeTask(self):
176
+ rawDataSelectionInvalid = not self._rawDataSelection.validateSelection()
177
+ darkDataSelectionInvalid = (
178
+ self._darkDataGroup.isChecked()
179
+ and not self._darkDataSelection.validateSelection()
180
+ )
164
181
  self.saveInputs()
182
+ if rawDataSelectionInvalid or darkDataSelectionInvalid:
183
+ show_error_msg("One of the inputs of the form is invalid.")
184
+ return
165
185
  self.execute_ewoks_task()
166
186
 
167
187
  def closeEvent(self, *a, **kw):
@@ -1,9 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
- from ewoksorange.bindings.owwidgets import OWEwoksWidgetOneThread
3
+ from ewoksorange.gui.owwidgets.threaded import OWEwoksWidgetOneThread
4
4
 
5
5
  from darfix import dtypes
6
- from darfix.gui.metadataWidget import MetadataWidget
6
+ from darfix.gui.metadata_widget import MetadataWidget
7
7
  from darfix.tasks.metadata import MetadataTask
8
8
 
9
9
 
@@ -1,9 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
- from darfix.core.noiseremoval import clean_operation_dict
4
- from darfix.gui.noiseremoval.noise_removal_widget import NoiseRemovalWidget
5
- from darfix.tasks.noiseremoval import NoiseRemoval
6
- from orangecontrib.darfix.widgets.operationWidgetBase import OperationWidgetBase
3
+ from darfix.core.noise_removal import clean_operation_dict
4
+ from darfix.gui.noise_removal.noise_removal_widget import NoiseRemovalWidget
5
+ from darfix.tasks.noise_removal import NoiseRemoval
6
+ from orangecontrib.darfix.widgets.operation_widget_base import OperationWidgetBase
7
7
 
8
8
 
9
9
  class NoiseRemovalWidgetOW(OperationWidgetBase, ewokstaskclass=NoiseRemoval):
@@ -5,8 +5,8 @@ from silx.gui import qt
5
5
  from darfix import dtypes
6
6
  from darfix.core.utils import OperationAborted
7
7
  from darfix.gui.utils.message import missing_dataset_msg
8
- from darfix.gui.utils.standardButtonBox import StandardButtonBox
9
- from orangecontrib.darfix.widgets.datasetWidgetBase import DatasetWidgetBase
8
+ from darfix.gui.utils.standard_buttonbox import StandardButtonBox
9
+ from orangecontrib.darfix.widgets.dataset_widget_base import DatasetWidgetBase
10
10
 
11
11
 
12
12
  class OperationWidgetBase(DatasetWidgetBase, openclass=True):
@@ -1,10 +1,10 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from ewokscore.missing_data import is_missing_data
4
- from ewoksorange.bindings.owwidgets import OWEwoksWidgetOneThread
4
+ from ewoksorange.gui.owwidgets.threaded import OWEwoksWidgetOneThread
5
5
 
6
6
  from darfix.dtypes import Dataset
7
- from darfix.gui.PCAWidget import PCAPlot
7
+ from darfix.gui.pca_widget import PCAPlot
8
8
  from darfix.tasks.pca import PCA
9
9
 
10
10
 
@@ -1,9 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
- from ewoksorange.bindings.owwidgets import OWEwoksWidgetOneThread
3
+ from ewoksorange.gui.owwidgets.threaded import OWEwoksWidgetOneThread
4
4
 
5
5
  from darfix.dtypes import Dataset
6
- from darfix.gui.projectionWidget import ProjectionWidget
6
+ from darfix.gui.projection_widget import ProjectionWidget
7
7
  from darfix.tasks.projection import Projection
8
8
 
9
9
 
@@ -1,9 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from darfix import dtypes
4
- from darfix.gui.rocking_curves.rockingCurvesWidget import RockingCurvesWidget
4
+ from darfix.gui.rocking_curves.rocking_curves_widget import RockingCurvesWidget
5
5
  from darfix.tasks.rocking_curves import RockingCurves
6
- from orangecontrib.darfix.widgets.datasetWidgetBase import DatasetWidgetBase
6
+ from orangecontrib.darfix.widgets.dataset_widget_base import DatasetWidgetBase
7
7
 
8
8
 
9
9
  class RockingCurvesWidgetOW(DatasetWidgetBase, ewokstaskclass=RockingCurves):
@@ -17,6 +17,8 @@ class RockingCurvesWidgetOW(DatasetWidgetBase, ewokstaskclass=RockingCurves):
17
17
  def __init__(self):
18
18
  super().__init__()
19
19
 
20
+ self.setWidgetToDisableWhenRunning(None)
21
+
20
22
  self._widget = RockingCurvesWidget(parent=self)
21
23
  self._widget.sigFitClicked.connect(self._launch_fit)
22
24
  self.mainArea.layout().addWidget(self._widget)
@@ -27,6 +29,7 @@ class RockingCurvesWidgetOW(DatasetWidgetBase, ewokstaskclass=RockingCurves):
27
29
  if method is not None:
28
30
  self._widget.setFitMethod(method)
29
31
  self.datasetChanged.connect(self._onDatasetChanged)
32
+ self._widget.sigAbortClicked.connect(self.cancel_running_task)
30
33
 
31
34
  def _onDatasetChanged(self, dataset: dtypes.Dataset):
32
35
  self._widget.setDataset(dataset)
@@ -1,29 +1,15 @@
1
1
  from __future__ import annotations
2
2
 
3
- import logging
4
- from enum import Enum
5
-
6
3
  import numpy
7
4
  from ewokscore.missing_data import is_missing_data
8
5
 
9
6
  from darfix import dtypes
10
- from darfix.gui.roiSelectionWidget import ROISelectionWidget
7
+ from darfix.gui.roi_selection_widget import ROISelectionWidget
11
8
  from darfix.tasks.roi import RoiSelection
12
- from orangecontrib.darfix.widgets.datasetWidgetBase import DatasetWidgetBase
13
-
14
- _logger = logging.getLogger(__name__)
15
-
16
-
17
- class _ROIBehavior(Enum):
18
- """Define the different behavior we can have regarding ROI"""
19
-
20
- FIT_TO_DATASET = "fit-to-dataset"
21
- """When a ROI is applied we want to update the ROI to the shape to show the user that the ROI has been applied"""
22
- PROPOSE_USER_ROI = "propose-ROI-to-user"
23
- """When a new dataset is set (or when resetting) we want to propose to the user a subset of the frame (one fifth of the current frame shape)"""
9
+ from orangecontrib.darfix.widgets.operation_widget_base import OperationWidgetBase
24
10
 
25
11
 
26
- class RoiSelectionWidgetOW(DatasetWidgetBase, ewokstaskclass=RoiSelection):
12
+ class RoiSelectionWidgetOW(OperationWidgetBase, ewokstaskclass=RoiSelection):
27
13
  name = "roi selection"
28
14
  icon = "icons/roi.png"
29
15
  want_main_area = True
@@ -34,85 +20,34 @@ class RoiSelectionWidgetOW(DatasetWidgetBase, ewokstaskclass=RoiSelection):
34
20
  def __init__(self):
35
21
  super().__init__()
36
22
 
37
- self._widget = ROISelectionWidget(parent=self)
38
- self.mainArea.layout().addWidget(self._widget)
39
- self._widget.sigApply.connect(self._updateActiveDataset)
40
- self._widget.sigValidate.connect(self._validateResult)
41
- self._widget.sigReset.connect(self._reset)
42
-
43
- self._update_dataset: dtypes.Dataset = None
44
- """Dataset updated when the users press 'apply'"""
45
- self._dataset: dtypes.Dataset = None
46
- """Original input dataset"""
47
-
48
- self._nextRoiInteractionBehavior: _ROIBehavior = _ROIBehavior.PROPOSE_USER_ROI
49
- """When a new output is received we want either to:
50
- * propose a ROI fitting the dataset shape (if a ROI - subset of the dataset - has been applied)
51
- * propose a ROI on a subset of the dataset (in the case a new dataset has been received)
52
- """
23
+ # Connect Signals / Slots
53
24
 
54
25
  self.datasetChanged.connect(self.onDatasetChanged)
26
+ self.sigOperationApplied.connect(self.onRoiApplied)
55
27
 
56
- def _validateResult(self):
57
- self._nextRoiInteractionBehavior = _ROIBehavior.PROPOSE_USER_ROI
58
- self.propagate_downstream()
59
- self.accept()
28
+ def createMainWidget(self, default_inputs: dict) -> ROISelectionWidget:
29
+ widget = ROISelectionWidget()
30
+ return widget
60
31
 
61
- def onDatasetChanged(self, dataset: dtypes.Dataset):
32
+ def saveMainWidget(self) -> dict:
33
+ self.set_default_input(
34
+ "roi_origin", tuple(self.mainWidget.getRoi().getOrigin())
35
+ )
36
+ self.set_default_input("roi_size", tuple(self.mainWidget.getRoi().getSize()))
62
37
 
63
- self._dataset = self._update_dataset = dataset
38
+ @property
39
+ def mainWidget(self) -> ROISelectionWidget:
40
+ return super().mainWidget
64
41
 
65
- self._widget.setDataset(dataset)
66
- self._nextRoiInteractionBehavior = _ROIBehavior.PROPOSE_USER_ROI
42
+ def onRoiApplied(self, newDataset: dtypes.Dataset):
43
+ self.mainWidget.setDataset(newDataset, roiEnabled=False)
67
44
 
45
+ def onDatasetChanged(self, dataset: dtypes.Dataset):
46
+ self.mainWidget.setDataset(dataset)
68
47
  if not self._tryRecoverLastRoi():
69
- self._resetTaskAndROI(dataset=dataset)
70
-
71
- def _updateActiveDataset(self):
72
-
73
- self._widget.clampRoiToDataset(self._update_dataset.dataset)
74
- roi = self._widget.getRoi()
75
-
76
- self.set_default_input("roi_origin", roi.getOrigin().tolist())
77
- self.set_default_input("roi_size", roi.getSize().tolist())
78
- self._nextRoiInteractionBehavior = _ROIBehavior.FIT_TO_DATASET
79
- self.execute_ewoks_task_without_propagation()
80
- self._widget.enableApplyingROI(False)
81
-
82
- def _updateROI(self):
83
- if self._nextRoiInteractionBehavior is _ROIBehavior.FIT_TO_DATASET:
84
- # Apply
85
- self._widget.enableValidation(True)
86
- self._widget._fitROIToDataset(self._update_dataset.dataset)
87
- elif self._nextRoiInteractionBehavior is _ROIBehavior.PROPOSE_USER_ROI:
88
- # Reset
89
- self._widget.enableValidation(False)
90
- self._widget._setROIForNewDataset(self._update_dataset.dataset)
48
+ self.mainWidget.setROIForNewDataset(dataset.dataset)
91
49
  else:
92
- raise NotImplementedError(
93
- f"Behavior not defined ({self._nextRoiInteractionBehavior})"
94
- )
95
-
96
- def task_output_changed(self):
97
- super().task_output_changed()
98
- self._update_dataset = self.get_task_output_value("dataset")
99
-
100
- if is_missing_data(self._update_dataset):
101
- _logger.error("Roi application failed (or cancelled)")
102
- return
103
-
104
- self._updateROI()
105
-
106
- self._widget.setStack(self._update_dataset.dataset)
107
- # update the input dataset for next iteration
108
- self.set_dynamic_input("dataset", self._update_dataset)
109
-
110
- def _reset(self):
111
- self._update_dataset = self._dataset
112
-
113
- self._nextRoiInteractionBehavior = _ROIBehavior.PROPOSE_USER_ROI
114
- self._widget.setDataset(self._update_dataset)
115
- self._resetTaskAndROI(dataset=self._update_dataset)
50
+ self.mainWidget.clampRoiToDataset(dataset.dataset)
116
51
 
117
52
  def _tryRecoverLastRoi(self) -> bool:
118
53
  """Look at saved default input in .ows and try propose the roi on the current dataset."""
@@ -129,23 +64,6 @@ class RoiSelectionWidgetOW(DatasetWidgetBase, ewokstaskclass=RoiSelection):
129
64
 
130
65
  origin = numpy.array(origin)
131
66
  size = numpy.array(size)
132
- self._widget.setRoi(size=size, origin=origin)
133
- self._widget.enableValidation(False)
134
- self._widget.enableApplyingROI(True)
135
- return True
67
+ self.mainWidget.setRoi(size=size, origin=origin)
136
68
 
137
- def _resetTaskAndROI(self, dataset: dtypes.Dataset):
138
- """
139
- Reset the original dataset (last dataset received) and the ROI.
140
-
141
- When receiving a new dataset or resetting it, we need to process the task to
142
- retrieve the task output dataset when the user presses ok.
143
- To speed up process in this specific case (ROI match frame shape), the task will simply propagate the original dataset.
144
- """
145
- self.set_default_input("roi_origin", (0, 0))
146
- self.set_default_input("roi_size", dataset.dataset.frame_shape)
147
- self.set_dynamic_input("dataset", dataset)
148
- self.execute_ewoks_task_without_propagation()
149
-
150
- self._widget.enableValidation(False)
151
- self._widget.enableApplyingROI(True)
69
+ return True
@@ -1,10 +1,10 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import numpy
4
- from ewoksorange.bindings.owwidgets import OWEwoksWidgetOneThread
4
+ from ewoksorange.gui.owwidgets.threaded import OWEwoksWidgetOneThread
5
5
 
6
6
  from darfix.dtypes import Dataset
7
- from darfix.gui.rsmHistogramWidget import RSMHistogramWidget
7
+ from darfix.gui.rsm_histogram_widget import RSMHistogramWidget
8
8
  from darfix.tasks.rsm_histogram import RSMHistogram
9
9
 
10
10
 
@@ -3,9 +3,9 @@ from __future__ import annotations
3
3
  import numpy
4
4
  from silx.gui import qt
5
5
 
6
- from darfix.gui.shiftcorrection.shiftCorrectionWidget import ShiftCorrectionWidget
7
- from darfix.tasks.shiftcorrection import ShiftCorrection
8
- from orangecontrib.darfix.widgets.operationWidgetBase import OperationWidgetBase
6
+ from darfix.gui.shift_correction.shift_correction_widget import ShiftCorrectionWidget
7
+ from darfix.tasks.shift_correction import ShiftCorrection
8
+ from orangecontrib.darfix.widgets.operation_widget_base import OperationWidgetBase
9
9
 
10
10
 
11
11
  class ShiftCorrectionWidgetOW(OperationWidgetBase, ewokstaskclass=ShiftCorrection):
@@ -3,13 +3,13 @@ from __future__ import annotations
3
3
  from typing import Any
4
4
  from typing import Dict
5
5
 
6
- from ewoksorange.bindings.owwidgets import OWEwoksWidgetOneThread
7
- from ewoksorange.gui.parameterform import block_signals
6
+ from ewoksorange.gui.owwidgets.threaded import OWEwoksWidgetOneThread
7
+ from ewoksorange.gui.widgets.parameter_form import block_signals
8
8
  from silx.gui import qt
9
9
 
10
10
  from darfix import dtypes
11
- from darfix.gui.magnificationWidget import MagnificationWidget
12
- from darfix.gui.rsmWidget import RSMWidget
11
+ from darfix.gui.magnification_widget import MagnificationWidget
12
+ from darfix.gui.rsm_widget import RSMWidget
13
13
  from darfix.tasks.transformation import TransformationMatrixComputation
14
14
 
15
15
 
@@ -1,21 +1,15 @@
1
1
  import logging
2
- from typing import Optional
3
-
4
- from ewokscore.missing_data import MISSING_DATA
5
- from ewoksorange.bindings.owwidgets import OWEwoksWidgetOneThread
6
- from ewoksorange.gui.parameterform import block_signals
7
2
 
8
3
  from darfix import dtypes
9
- from darfix.gui.operationThread import OperationThread
10
- from darfix.gui.utils.message import missing_dataset_msg
11
- from darfix.gui.weakBeamWidget import WeakBeamWidget
12
- from darfix.tasks.weakbeam import WeakBeam
4
+ from darfix.gui.weak_beam_widget import WeakBeamWidget
5
+ from darfix.tasks.weak_beam import WeakBeam
6
+ from orangecontrib.darfix.widgets.operation_widget_base import OperationWidgetBase
13
7
 
14
8
  _logger = logging.getLogger(__name__)
15
9
 
16
10
 
17
11
  class WeakBeamWidgetOW(
18
- OWEwoksWidgetOneThread,
12
+ OperationWidgetBase,
19
13
  ewokstaskclass=WeakBeam,
20
14
  ):
21
15
  """
@@ -27,103 +21,26 @@ class WeakBeamWidgetOW(
27
21
  want_main_area = True
28
22
  want_control_area = False
29
23
 
30
- _ewoks_inputs_to_hide_from_orange = ("nvalue", "indices", "title")
24
+ _ewoks_inputs_to_hide_from_orange = ("nvalue", "title")
31
25
 
32
26
  def __init__(self):
33
27
  super().__init__()
34
- self._thread = None
35
-
36
- self._widget = WeakBeamWidget(parent=self)
37
- self.mainArea.layout().addWidget(self._widget)
38
- nvalue = self.get_default_input_value("nvalue", MISSING_DATA)
39
- if nvalue is not MISSING_DATA:
40
- with block_signals(self._widget):
41
- self._widget.nvalue = nvalue
42
- else:
43
- self.set_default_input("nvalue", self._widget.nvalue)
44
-
45
- # connect signal / slot
46
- self._widget.sigValidate.connect(self.execute_ewoks_task)
47
- self._widget.sigApplyThreshold.connect(self._launch_recover_weak_beam)
48
- self._widget.sigNValueChanged.connect(self._nValueChanged)
49
-
50
- def setDataset(self, dataset: Optional[dtypes.Dataset], pop_up: bool = False):
51
- if dataset is None:
52
- return
53
- if pop_up:
54
- self.open()
55
- self.set_dynamic_input("dataset", dataset=dataset)
56
- # if some processing on-going with the previous dataset stop it.
57
- self._stop_thread()
58
-
59
- def _nValueChanged(self):
60
- self.set_default_input("nvalue", self._widget.nvalue)
61
-
62
- def handleNewSignals(self) -> None:
63
- dataset = self.get_task_input_value("dataset", None)
64
- if dataset is None:
65
- return
66
-
67
- self.setDataset(dataset=dataset, pop_up=True)
68
-
69
- if isinstance(dataset, dtypes.Dataset):
70
- self.set_dynamic_input("indices", dataset.indices)
71
- title = dataset.dataset.title
72
- self.set_default_input(
73
- "title",
74
- title if title is not None else MISSING_DATA,
75
- )
76
-
77
- # warning: do not call to make sure the processing is not triggered
78
- # return super().handleNewSignals()
79
-
80
- def task_output_changed(self) -> None:
81
- dataset = self.get_task_output_value("dataset", MISSING_DATA)
82
- self.setDataset(dataset)
83
-
84
- def _launch_recover_weak_beam(self):
85
- """callback when the user modify the 'nvalue'"""
86
- if self._thread is not None:
87
- _logger.warning("recover weak beam already on going")
88
-
89
- dataset = self.get_task_input_value("dataset", None)
90
- if dataset is None:
91
- missing_dataset_msg()
92
- return
93
- if not isinstance(dataset, dtypes.Dataset):
94
- raise dtypes.DatasetTypeError(dataset)
28
+ self.sigOperationApplied.connect(self.__onOperationApplied)
29
+ self.buttons.resetButton.hide()
95
30
 
96
- self._widget.setProcessingButtonsEnabled(False)
97
- nvalue = self.get_task_input_value("nvalue", MISSING_DATA)
98
- # FIXME: all processing should be in done in a ewoks task. See https://gitlab.esrf.fr/XRD/darfix/-/issues/130
99
- self._thread = OperationThread(self, dataset.dataset.recover_weak_beam)
100
- self._thread.setArgs(
101
- n=nvalue,
102
- indices=dataset.indices,
103
- )
104
- self._thread.finished.connect(self._recover_weak_beam_finished)
105
- self._thread.start()
31
+ def createMainWidget(self, default_inputs: dict) -> WeakBeamWidget:
32
+ widget = WeakBeamWidget()
33
+ widget.nvalue = default_inputs.get("nvalue", 1.0)
34
+ return widget
106
35
 
107
- def _stop_thread(self):
108
- if self._thread is not None:
109
- self._thread.finished.disconnect(self._recover_weak_beam_finished)
110
- self._thread = None
111
- self._widget.setProcessingButtonsEnabled(True)
36
+ def saveMainWidget(self) -> dict:
37
+ self.set_default_input("nvalue", self.mainWidget.nvalue)
112
38
 
113
- def _recover_weak_beam_finished(self):
114
- sender = self.sender()
115
- dataset = self._thread.data
116
- self._stop_thread()
39
+ def __onOperationApplied(self, dataset: dtypes.Dataset):
40
+ self.mainWidget.updateDataset(dataset)
41
+ # this trick re-enable button apply directly
42
+ self.reset()
117
43
 
118
- if dataset in (None, MISSING_DATA):
119
- raise RuntimeError("An exception occured when trying to recover weakbeam")
120
- assert isinstance(
121
- dataset, dtypes.ImageDataset
122
- ), f"dataset is expected to be an instance of {dtypes.ImageDataset}. Get {type(dataset)}"
123
- self._widget.setResult(
124
- center_of_mass=dataset.apply_moments(indices=sender.kwargs["indices"])[0][
125
- 0
126
- ],
127
- transformation=dataset.transformation,
128
- )
129
- self._stop_thread()
44
+ @property
45
+ def mainWidget(self) -> WeakBeamWidget:
46
+ return super().mainWidget