tomwer 1.4.19__py3-none-any.whl → 1.5.0rc0__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 (84) 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/reducedarkflat.py +2 -2
  6. tomwer/core/process/edit/imagekeyeditor.py +4 -6
  7. tomwer/core/process/edit/nxtomoeditor.py +58 -20
  8. tomwer/core/process/output.py +6 -5
  9. tomwer/core/process/reconstruction/axis/anglemode.py +2 -2
  10. tomwer/core/process/reconstruction/axis/axis.py +1 -0
  11. tomwer/core/process/reconstruction/darkref/darkrefs.py +2 -2
  12. tomwer/core/process/reconstruction/darkref/darkrefscopy.py +1 -1
  13. tomwer/core/process/reconstruction/darkref/params.py +1 -1
  14. tomwer/core/process/reconstruction/nabu/castvolume.py +4 -1
  15. tomwer/core/process/reconstruction/nabu/helical.py +3 -1
  16. tomwer/core/process/reconstruction/nabu/nabuscores.py +1 -1
  17. tomwer/core/process/reconstruction/nabu/nabuslices.py +4 -4
  18. tomwer/core/process/reconstruction/nabu/plane.py +2 -2
  19. tomwer/core/process/reconstruction/nabu/test/test_castvolume.py +2 -0
  20. tomwer/core/process/reconstruction/nabu/utils.py +15 -14
  21. tomwer/core/process/reconstruction/normalization/params.py +1 -1
  22. tomwer/core/process/reconstruction/output.py +2 -2
  23. tomwer/core/process/reconstruction/tests/test_axis.py +1 -1
  24. tomwer/core/process/stitching/metadataholder.py +5 -5
  25. tomwer/core/process/stitching/nabustitcher.py +1 -4
  26. tomwer/core/scan/edfscan.py +3 -3
  27. tomwer/core/scan/nxtomoscan.py +3 -3
  28. tomwer/core/scan/scanbase.py +2 -2
  29. tomwer/core/tomwer_object.py +1 -1
  30. tomwer/core/utils/nxtomoutils.py +2 -2
  31. tomwer/core/utils/spec.py +6 -3
  32. tomwer/gui/control/datadiscovery.py +1 -1
  33. tomwer/gui/control/reducedarkflatselector.py +4 -4
  34. tomwer/gui/edit/imagekeyeditor.py +7 -9
  35. tomwer/gui/edit/nxtomoeditor.py +420 -112
  36. tomwer/gui/edit/tests/test_nx_editor.py +154 -82
  37. tomwer/gui/reconstruction/axis/CalculationWidget.py +1 -1
  38. tomwer/gui/reconstruction/axis/EstimatedCORWidget.py +12 -8
  39. tomwer/gui/reconstruction/darkref/darkrefwidget.py +2 -2
  40. tomwer/gui/reconstruction/nabu/castvolume.py +16 -1
  41. tomwer/gui/reconstruction/nabu/nabuconfig/base.py +1 -1
  42. tomwer/gui/reconstruction/nabu/nabuconfig/nabuconfig.py +1 -1
  43. tomwer/gui/reconstruction/nabu/nabuconfig/phase.py +2 -2
  44. tomwer/gui/reconstruction/nabu/nabuconfig/preprocessing.py +2 -4
  45. tomwer/gui/reconstruction/nabu/nabuconfig/reconstruction.py +71 -49
  46. tomwer/gui/reconstruction/nabu/nabuflow.py +3 -13
  47. tomwer/gui/reconstruction/nabu/slices.py +6 -6
  48. tomwer/gui/reconstruction/nabu/test/test_cast_volume.py +19 -0
  49. tomwer/gui/reconstruction/normalization/intensity.py +2 -2
  50. tomwer/gui/reconstruction/saaxis/dimensionwidget.py +71 -67
  51. tomwer/gui/reconstruction/scores/scoreplot.py +15 -7
  52. tomwer/gui/reconstruction/tests/test_saaxis.py +18 -16
  53. tomwer/gui/stitching/SingleAxisStitchingWidget.py +8 -8
  54. tomwer/gui/stitching/StitchingOptionsWidget.py +1 -1
  55. tomwer/gui/stitching/alignment.py +8 -8
  56. tomwer/gui/stitching/config/axisparams.py +2 -2
  57. tomwer/gui/stitching/config/output.py +1 -1
  58. tomwer/gui/stitching/config/stitchingstrategies.py +4 -6
  59. tomwer/gui/stitching/config/tomoobjdetails.py +21 -13
  60. tomwer/gui/stitching/normalization.py +6 -6
  61. tomwer/gui/stitching/tests/test_ZStitchingWindow.py +8 -1
  62. tomwer/gui/stitching/tests/test_preview.py +10 -7
  63. tomwer/gui/stitching/tests/utils.py +27 -18
  64. tomwer/gui/stitching/z_stitching/fineestimation.py +7 -9
  65. tomwer/gui/stitching/z_stitching/tests/test_raw_estimation.py +18 -7
  66. tomwer/gui/stitching/z_stitching/tests/test_stitching_window.py +7 -2
  67. tomwer/gui/utils/buttons.py +53 -35
  68. tomwer/gui/utils/flow.py +1 -1
  69. tomwer/gui/utils/unitsystem.py +44 -33
  70. tomwer/gui/visualization/diffviewer/diffviewer.py +4 -4
  71. tomwer/gui/visualization/diffviewer/shiftwidget.py +4 -6
  72. tomwer/gui/visualization/test/test_nx_tomo_metadata_viewer.py +25 -13
  73. tomwer/model/dataset.py +0 -0
  74. tomwer/tasks/reconstruction/cleardarkflat.py +42 -0
  75. tomwer/tests/app/test_stitching.py +1 -1
  76. tomwer/tests/orangecontrib/tomwer/widgets/edit/tests/test_nxtomo_editor.py +32 -20
  77. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_nabu_widget.py +1 -1
  78. tomwer/version.py +3 -3
  79. {tomwer-1.4.19.dist-info → tomwer-1.5.0rc0.dist-info}/METADATA +8 -8
  80. {tomwer-1.4.19.dist-info → tomwer-1.5.0rc0.dist-info}/RECORD +84 -82
  81. {tomwer-1.4.19.dist-info → tomwer-1.5.0rc0.dist-info}/WHEEL +1 -1
  82. {tomwer-1.4.19.dist-info → tomwer-1.5.0rc0.dist-info}/entry_points.txt +0 -0
  83. {tomwer-1.4.19.dist-info → tomwer-1.5.0rc0.dist-info}/licenses/LICENSE +0 -0
  84. {tomwer-1.4.19.dist-info → tomwer-1.5.0rc0.dist-info}/top_level.txt +0 -0
@@ -9,14 +9,14 @@ from __future__ import annotations
9
9
 
10
10
 
11
11
  import logging
12
+ import pint
12
13
 
13
14
  from silx.gui import qt
14
- from pyunitsystem.metricsystem import MetricSystem
15
-
16
- from tomwer.core.utils.char import MU_CHAR
17
15
 
18
16
  _logger = logging.getLogger(__name__)
19
17
 
18
+ _ureg = pint.get_application_registry()
19
+
20
20
 
21
21
  class PixelEntry(qt.QWidget):
22
22
  valueChanged = qt.Signal()
@@ -69,6 +69,17 @@ class MetricEntry(qt.QWidget):
69
69
  editingFinished = qt.Signal()
70
70
  """emit when editing is finished"""
71
71
 
72
+ valueChanged = qt.Signal()
73
+ """emit when the metric value change"""
74
+
75
+ _ExposedUnits: set[_ureg.Unit] = {
76
+ _ureg.nanometer,
77
+ _ureg.micrometer,
78
+ _ureg.mm,
79
+ _ureg.cm,
80
+ _ureg.m,
81
+ }
82
+
72
83
  class DoubleValidator(qt.QDoubleValidator):
73
84
  def __init__(self, *args, **kwargs):
74
85
  super().__init__(*args, **kwargs)
@@ -80,22 +91,15 @@ class MetricEntry(qt.QWidget):
80
91
  else:
81
92
  return super().validate(a0, a1)
82
93
 
83
- _CONVERSION = {
84
- "nm": MetricSystem.NANOMETER.value,
85
- f"{MU_CHAR}m": MetricSystem.MICROMETER.value,
86
- "mm": MetricSystem.MILLIMETER.value,
87
- "cm": MetricSystem.CENTIMETER.value,
88
- "m": MetricSystem.METER.value,
89
- }
90
-
91
- valueChanged = qt.Signal()
92
- """emit when the metric value change"""
93
-
94
- def __init__(self, name, value=0.0, default_unit="m", parent=None):
94
+ def __init__(
95
+ self, name, value=0.0, default_unit: pint.Unit = _ureg.meter, parent=None
96
+ ):
95
97
  qt.QWidget.__init__(self, parent)
96
- assert type(default_unit) is str
97
- assert default_unit in ("nm", "mm", "cm", "m", f"{MU_CHAR}m")
98
- self._base_unit = default_unit
98
+ if default_unit not in self._ExposedUnits:
99
+ raise ValueError(
100
+ f"Unable to use {default_unit} as default unit. Must be in {self._ExposedUnits}"
101
+ )
102
+ self._base_unit: pint.Unit = default_unit
99
103
 
100
104
  self.setLayout(qt.QHBoxLayout())
101
105
  self._label = qt.QLabel(name, parent=self)
@@ -105,11 +109,9 @@ class MetricEntry(qt.QWidget):
105
109
  self.layout().addWidget(self._qlePixelSize)
106
110
 
107
111
  self._qcbUnit = qt.QComboBox(parent=self)
108
- self._qcbUnit.addItem("nm")
109
- self._qcbUnit.addItem(f"{MU_CHAR}m")
110
- self._qcbUnit.addItem("mm")
111
- self._qcbUnit.addItem("cm")
112
- self._qcbUnit.addItem("m")
112
+ for unit in self._ExposedUnits:
113
+ self._qcbUnit.addItem(f"{unit:~}")
114
+
113
115
  self.layout().addWidget(self._qcbUnit)
114
116
  self._resetBaseUnit()
115
117
 
@@ -128,10 +130,9 @@ class MetricEntry(qt.QWidget):
128
130
  self._label.setText(text)
129
131
 
130
132
  def getCurrentUnit(self):
131
- assert self._qcbUnit.currentText() in self._CONVERSION
132
- return self._CONVERSION[self._qcbUnit.currentText()]
133
+ return _ureg.Unit(self._qcbUnit.currentText())
133
134
 
134
- def setValue(self, value_m, displayed_unit: str = "m"):
135
+ def setValue(self, value_m, displayed_unit: pint.Unit = _ureg.meter):
135
136
  """
136
137
 
137
138
  :param value: pixel size in international metric system (meter)
@@ -155,16 +156,20 @@ class MetricEntry(qt.QWidget):
155
156
  self._qlePixelSize.setText(txt)
156
157
  self._resetBaseUnit(displayed_unit=displayed_unit)
157
158
 
158
- def _resetBaseUnit(self, displayed_unit=None):
159
+ def _resetBaseUnit(self, displayed_unit: pint.Unit | None = None):
159
160
  """Simple reset of the combobox according to the base_unit"""
161
+ if displayed_unit is not None and not isinstance(displayed_unit, pint.Unit):
162
+ raise TypeError(
163
+ f"'displayed_unit' should be a {pint.Unit}. Got {type(displayed_unit)}"
164
+ )
160
165
  displayed_unit = displayed_unit or self._base_unit
161
- index = self._qcbUnit.findText(displayed_unit)
162
- if index is None:
166
+ index = self._qcbUnit.findText(f"{displayed_unit:~}")
167
+ if index < 0:
163
168
  raise ValueError("unrecognized base unit")
164
169
  else:
165
170
  self._qcbUnit.setCurrentIndex(index)
166
171
 
167
- def getValue(self) -> float:
172
+ def getValue(self) -> pint.Quantity | None:
168
173
  """
169
174
 
170
175
  :return: the value in meter
@@ -177,7 +182,13 @@ class MetricEntry(qt.QWidget):
177
182
  def setValidator(self, validator):
178
183
  self._qlePixelSize.setValidator(validator)
179
184
 
180
- def setUnit(self, unit):
181
- unit = str(MetricSystem.from_value(unit))
185
+ def setUnit(self, unit: pint.Unit):
186
+ assert isinstance(
187
+ unit, pint.Unit
188
+ ), f"unit is expected to be a pint.Unit. Got {type(unit)}"
189
+ unit = f"{unit:~}"
182
190
  idx = self._qcbUnit.findText(unit)
183
- self._qcbUnit.setCurrentIndex(idx)
191
+ if idx >= 0:
192
+ self._qcbUnit.setCurrentIndex(idx)
193
+ else:
194
+ _logger.error(f"Unhandled unit ({unit})")
@@ -7,13 +7,13 @@ from __future__ import annotations
7
7
  import functools
8
8
  import logging
9
9
  import os
10
+ from enum import Enum
10
11
 
11
12
  import numpy
12
13
  from processview.core.dataset import DatasetIdentifier
13
14
  from silx.gui import icons as silx_icons
14
15
  from silx.gui import qt
15
16
  from silx.io.url import DataUrl
16
- from silx.utils.enum import Enum as _Enum
17
17
 
18
18
  from tomwer.core.scan.nxtomoscan import NXtomoScan
19
19
  from tomwer.core.scan.scanbase import TomwerScanBase
@@ -55,7 +55,7 @@ class _FrameSelector(qt.QWidget):
55
55
  sigSelectedUrlChanged = qt.Signal()
56
56
  """signal emitted when the selected url changed"""
57
57
 
58
- class FrameType(_Enum):
58
+ class FrameType(Enum):
59
59
  DARKS = "darks"
60
60
  FLATS = "flats"
61
61
  PROJ = "projections"
@@ -110,10 +110,10 @@ class _FrameSelector(qt.QWidget):
110
110
  return None
111
111
 
112
112
  def getTypeSelected(self):
113
- return self.FrameType.from_value(self._frameTypeCB.currentText())
113
+ return self.FrameType(self._frameTypeCB.currentText())
114
114
 
115
115
  def _typeChanged(self, *args, **kwargs):
116
- type_selected = self.FrameType.from_value(self.getTypeSelected())
116
+ type_selected = self.FrameType(self.getTypeSelected())
117
117
  self._proj_normalized.setVisible(
118
118
  type_selected in (self.FrameType.PROJ, self.FrameType.ALIGN_PROJ)
119
119
  )
@@ -5,11 +5,11 @@ contains gui for diffviewer shift
5
5
  """
6
6
  from __future__ import annotations
7
7
 
8
+ from enum import Enum
8
9
 
9
10
  import sys
10
11
 
11
12
  from silx.gui import qt
12
- from silx.utils.enum import Enum as _Enum
13
13
 
14
14
  from tomwer.utils import docstring
15
15
 
@@ -54,7 +54,7 @@ class TwoFramesShiftTab(qt.QTabWidget, _FrameShiftsBase):
54
54
  lrflip is a boolean notifying if we should flip image or not before applying the shift
55
55
  """
56
56
 
57
- class ShiftMode(_Enum):
57
+ class ShiftMode(Enum):
58
58
  RELATIVE = "relative shift"
59
59
  ABSOLUTE = "absolute shift"
60
60
 
@@ -206,7 +206,7 @@ class Relative2FramesShift(qt.QWidget, _FrameShiftsBase):
206
206
  self._controlWidget.setFocus(qt.Qt.OtherFocusReason)
207
207
 
208
208
  def move(self, direction: str):
209
- direction = _ControlArrowWidget.Direction.from_value(direction)
209
+ direction = _ControlArrowWidget.Direction(direction)
210
210
  shift = self._shiftStepSize.value()
211
211
  if direction is _ControlArrowWidget.Direction.RIGHT:
212
212
  self._xShiftQLE.setValue(self._xShiftQLE.value() + shift)
@@ -290,14 +290,12 @@ class _ControlArrowWidget(qt.QWidget):
290
290
  sigMoved = qt.Signal(str)
291
291
  """signal emit when one direction is activated. Will contain the direction in which we want to move"""
292
292
 
293
- class Direction(_Enum):
293
+ class Direction(Enum):
294
294
  LEFT = "left"
295
295
  RIGHT = "right"
296
296
  UP = "up"
297
297
  DOWN = "down"
298
298
 
299
- VALID_DIRECTIONS = Direction.members()
300
-
301
299
  ARROW_BUTTON_SIZE = 30
302
300
 
303
301
  QKEY_TO_DIR = {
@@ -1,6 +1,7 @@
1
1
  import os
2
2
 
3
3
  import numpy
4
+ import pint
4
5
  from nxtomo.application.nxtomo import NXtomo
5
6
  from silx.gui import qt
6
7
  from nxtomo.nxobject.nxdetector import ImageKey
@@ -9,6 +10,8 @@ from tomwer.core.scan.nxtomoscan import NXtomoScan
9
10
  from tomwer.gui.visualization.nxtomometadata import NXtomoMetadataViewer
10
11
  from tomwer.tests.conftest import qtapp # noqa F401
11
12
 
13
+ _ureg = pint.get_application_registry()
14
+
12
15
 
13
16
  def test_nx_editor(
14
17
  tmp_path,
@@ -16,18 +19,18 @@ def test_nx_editor(
16
19
  ):
17
20
  # 1.0 create nx tomo with raw data
18
21
  nx_tomo = NXtomo()
19
- nx_tomo.instrument.detector.x_pixel_size = 2.6e-6
20
- nx_tomo.instrument.detector.y_pixel_size = 2.5e-6
22
+ nx_tomo.instrument.detector.x_pixel_size = 2.6e-6 * _ureg.meter
23
+ nx_tomo.instrument.detector.y_pixel_size = 2.5e-6 * _ureg.meter
21
24
  nx_tomo.instrument.detector.field_of_view = "Half"
22
- nx_tomo.instrument.detector.distance = 59.0
25
+ nx_tomo.instrument.detector.distance = 59.0 * _ureg.meter
23
26
  nx_tomo.instrument.detector.x_flipped = True
24
27
  nx_tomo.instrument.detector.y_flipped = False
25
- nx_tomo.energy = 12.8
26
- nx_tomo.sample.x_translation = numpy.arange(12)
27
- nx_tomo.sample.z_translation = numpy.arange(2, 14)
28
+ nx_tomo.energy = 12.8 * _ureg.keV
29
+ nx_tomo.sample.x_translation = numpy.arange(12) * _ureg.meter
30
+ nx_tomo.sample.z_translation = numpy.arange(2, 14) * _ureg.meter
28
31
  nx_tomo.instrument.detector.image_key_control = [ImageKey.PROJECTION.value] * 12
29
32
  nx_tomo.instrument.detector.data = numpy.empty(shape=(12, 10, 10))
30
- nx_tomo.sample.rotation_angle = numpy.linspace(0, 180, num=12)
33
+ nx_tomo.sample.rotation_angle = numpy.linspace(0, 180, num=12) * _ureg.degree
31
34
 
32
35
  file_path = os.path.join(tmp_path, "nxtomo.nx")
33
36
  entry = "entry0000"
@@ -49,13 +52,22 @@ def test_nx_editor(
49
52
  return current_value is None
50
53
  return expected_value == current_value
51
54
 
52
- assert check_metric(2.6e-6, widget._xPixelSizeMetricEntry.getValue())
53
- assert widget._xPixelSizeMetricEntry._qcbUnit.currentText() == "m"
54
- assert check_metric(2.5e-6, widget._yPixelSizeMetricEntry.getValue())
55
- assert widget._yPixelSizeMetricEntry._qcbUnit.currentText() == "m"
55
+ assert check_metric(
56
+ 2.6e-6,
57
+ widget._xDetectorPixelSizeMetricEntry.getValue().to(_ureg.meter).magnitude,
58
+ )
59
+ assert widget._xDetectorPixelSizeMetricEntry._qcbUnit.currentText() == "m"
60
+ assert check_metric(
61
+ 2.5e-6,
62
+ widget._yDetectorPixelSizeMetricEntry.getValue().to(_ureg.meter).magnitude,
63
+ )
64
+ assert widget._yDetectorPixelSizeMetricEntry._qcbUnit.currentText() == "m"
56
65
 
57
- assert check_metric(59, widget._distanceMetricEntry.getValue())
58
- assert widget._distanceMetricEntry._qcbUnit.currentText() == "m"
66
+ assert check_metric(
67
+ 59,
68
+ widget._sampleDetectorDistanceMetricEntry.getValue().to(_ureg.meter).magnitude,
69
+ )
70
+ assert widget._sampleDetectorDistanceMetricEntry._qcbUnit.currentText() == "m"
59
71
 
60
72
  assert "Half" == widget._fieldOfViewCB.currentText()
61
73
  assert widget._xFlippedCB.isChecked()
File without changes
@@ -0,0 +1,42 @@
1
+ """
2
+ Contains task to clear reduced dark and flat frames
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ from tomoscan.scanbase import TomoScanBase as TomoscanScanBase
8
+
9
+ from processview.core.manager import DatasetState, ProcessManager
10
+ from processview.core.superviseprocess import SuperviseProcess
11
+
12
+ from tomwer.tasks.task import Task
13
+ from tomwer.core.scan.scanbase import TomwerScanBase
14
+ from tomwer.core.scan.scanfactory import ScanFactory
15
+ from tomwer.core.utils.scanutils import data_identifier_to_scan
16
+ from tomwer.core.reconstruction.darkflat import params as dkrf_reconsparams
17
+ from tomwer.utils import docstring
18
+
19
+
20
+ class ClearReducedDarkAndFlat(
21
+ Task,
22
+ SuperviseProcess,
23
+ input_names=("data",),
24
+ output_names=("data",),
25
+ ):
26
+ """
27
+ Task to clear reduced darks and flats. Both on disk and on the object cache.
28
+ th goal of this task is to make sure the scan is cleared of any reduced frames to reprocess it later.
29
+ """
30
+
31
+ def run(self):
32
+ scan = self.inputs.data
33
+ if not isinstance(scan, TomoscanScanBase):
34
+ raise TypeError(
35
+ f"scan should be an instance of {TomoscanScanBase}. Got {type(scan)}"
36
+ )
37
+ scan.set_reduced_flats(None)
38
+ scan.reduced_flats_infos = None
39
+ scan.set_reduced_darks(None)
40
+ scan.reduced_darks_infos = None
41
+
42
+ self.outputs.data = scan
@@ -32,7 +32,7 @@ def _create_objects_for_stitching(stitching_type: StitchingType, output_dir) ->
32
32
  ]
33
33
  )
34
34
 
35
- stitching_type = StitchingType.from_value(stitching_type)
35
+ stitching_type = StitchingType(stitching_type)
36
36
  if stitching_type is StitchingType.Y_PREPROC:
37
37
  nxtomos, positions, _ = test_y_preprocessing_stitching.build_nxtomos(
38
38
  output_dir=output_dir, flip_lr=False, flip_ud=False
@@ -3,6 +3,7 @@ import pickle
3
3
 
4
4
  import numpy
5
5
  import pytest
6
+ import pint
6
7
  from nxtomomill.nexus.nxtomo import NXtomo
7
8
  from orangecanvas.scheme.readwrite import literal_dumps
8
9
  from silx.gui.utils.testutils import SignalListener
@@ -15,15 +16,21 @@ from tomwer.tests.utils import skip_gui_test
15
16
  from tomwer.gui.utils.qt_utils import QSignalSpy
16
17
  from tomwer.tests.conftest import qtapp # noqa F401
17
18
 
19
+ _ureg = pint.get_application_registry()
20
+
18
21
 
19
22
  def getDefaultConfig() -> dict:
20
23
  """return the configuration of the NXtomo editor. First value is the value of the field, second is: is the associated lock button locked or not"""
21
24
  return {
22
25
  NXtomoEditorKeys.ENERGY: (5.9, False),
26
+ NXtomoEditorKeys.SAMPLE_SOURCE_DISTANCE: (-55.2, False),
27
+ NXtomoEditorKeys.PROPAGATION_DISTANCE: (10.1, True),
23
28
  NXtomoEditorKeys.SAMPLE_DETECTOR_DISTANCE: (2.4, True),
24
29
  NXtomoEditorKeys.FIELD_OF_VIEW: ("Full", False),
25
- NXtomoEditorKeys.X_PIXEL_SIZE: (0.023, True),
26
- NXtomoEditorKeys.Y_PIXEL_SIZE: (0.025, True),
30
+ NXtomoEditorKeys.DETECTOR_X_PIXEL_SIZE: (0.023, True),
31
+ NXtomoEditorKeys.DETECTOR_Y_PIXEL_SIZE: (0.025, True),
32
+ NXtomoEditorKeys.SAMPLE_X_PIXEL_SIZE: (0.24, True),
33
+ NXtomoEditorKeys.SAMPLE_Y_PIXEL_SIZE: (0.26, True),
27
34
  NXtomoEditorKeys.X_FLIPPED: (True, True),
28
35
  NXtomoEditorKeys.Y_FLIPPED: (False, False),
29
36
  NXtomoEditorKeys.X_TRANSLATION: (0.0,),
@@ -49,41 +56,41 @@ def test_NXtomoEditorOW(
49
56
  signal_listener = SignalListener()
50
57
  window.sigScanReady.connect(signal_listener)
51
58
  # set up the widget to define and lock distance, energy and x pixel size
52
- distance_widget = window.widget.mainWidget._distanceMetricEntry
53
- distance_widget.setValue(0.6)
54
- distance_widget.setUnit("mm")
55
- distance_locker = window.widget.mainWidget._distanceLB
59
+ distance_widget = window.widget.mainWidget._sampleDetectorDistanceMetricEntry
60
+ distance_widget.setValue(value_m=0.6)
61
+ distance_widget.setUnit(_ureg.millimeter)
62
+ distance_locker = window.widget.mainWidget._sampleDetectorDistanceLB
56
63
  distance_locker.setLock(True)
57
64
  energy_widget = window.widget.mainWidget._energyEntry
58
65
  energy_widget.setValue(88.058)
59
66
  energy_locker = window.widget.mainWidget._energyLockerLB
60
67
  energy_locker.setLock(True)
61
- x_pixel_widget = window.widget.mainWidget._xPixelSizeMetricEntry
62
- x_pixel_widget.setValue(45)
63
- x_pixel_widget.setUnit("nm")
64
- x_pixel_locker = window.widget.mainWidget._xPixelSizeLB
68
+ x_pixel_widget = window.widget.mainWidget._xDetectorPixelSizeMetricEntry
69
+ x_pixel_widget.setValue(value_m=45)
70
+ x_pixel_widget.setUnit(_ureg.nanometer)
71
+ x_pixel_locker = window.widget.mainWidget._xDetectorPixelSizeLB
65
72
  x_pixel_locker.setLock(True)
66
73
 
67
74
  # 1.0 create nx tomos with raw data
68
75
  nx_tomo = NXtomo()
69
76
  nx_tomo.instrument.detector.x_pixel_size = (
70
- 0.023 # should be overwrite by the configuration / lock buttons
77
+ 0.023 * _ureg.meter # should be overwrite by the configuration / lock buttons
71
78
  )
72
79
  nx_tomo.instrument.detector.y_pixel_size = (
73
- 0.025 # should be overwrite by the configuration / lock buttons
80
+ 0.025 * _ureg.meter # should be overwrite by the configuration / lock buttons
74
81
  )
75
82
  nx_tomo.instrument.detector.field_of_view = "full"
76
83
  nx_tomo.instrument.detector.distance = (
77
- 2.4 # should be overwrite by the configuration / lock buttons
84
+ 2.4 * _ureg.meter # should be overwrite by the configuration / lock buttons
78
85
  )
79
86
  nx_tomo.instrument.detector.x_flipped = (
80
87
  False # should be overwrite by the configuration / lock buttons
81
88
  )
82
89
  nx_tomo.instrument.detector.y_flipped = True
83
- nx_tomo.energy = 5.9
90
+ nx_tomo.energy = 5.9 * _ureg.keV
84
91
  nx_tomo.instrument.detector.image_key_control = [ImageKey.PROJECTION.value] * 12
85
92
  nx_tomo.instrument.detector.data = numpy.empty(shape=(12, 10, 10))
86
- nx_tomo.sample.rotation_angle = numpy.linspace(0, 20, num=12)
93
+ nx_tomo.sample.rotation_angle = numpy.linspace(0, 20, num=12) * _ureg.degree
87
94
 
88
95
  file_path = os.path.join(tmp_path, "nxtomo.nx")
89
96
  entry = "entry0000"
@@ -109,18 +116,20 @@ def test_NXtomoEditorOW(
109
116
  detector_data_as="as_numpy_array",
110
117
  )
111
118
  numpy.testing.assert_almost_equal(
112
- overwrite_nx_tomo.instrument.detector.x_pixel_size.si_value, 45e-9
119
+ overwrite_nx_tomo.instrument.detector.x_pixel_size.to_base_units().magnitude,
120
+ (45e-9 * _ureg.meter).to_base_units().magnitude,
113
121
  )
114
122
  assert (
115
- overwrite_nx_tomo.instrument.detector.y_pixel_size.si_value
116
- == nx_tomo.instrument.detector.y_pixel_size.si_value
123
+ overwrite_nx_tomo.instrument.detector.y_pixel_size
124
+ == nx_tomo.instrument.detector.y_pixel_size
117
125
  )
118
126
  assert (
119
127
  overwrite_nx_tomo.instrument.detector.field_of_view
120
128
  == nx_tomo.instrument.detector.field_of_view
121
129
  )
122
130
  numpy.testing.assert_almost_equal(
123
- overwrite_nx_tomo.instrument.detector.distance.value, 6.0e-4
131
+ overwrite_nx_tomo.instrument.detector.distance.to_base_units().magnitude,
132
+ (6.0e-4 * _ureg.meter).to_base_units().magnitude,
124
133
  )
125
134
  assert (
126
135
  overwrite_nx_tomo.instrument.detector.x_flipped
@@ -131,7 +140,10 @@ def test_NXtomoEditorOW(
131
140
  overwrite_nx_tomo.instrument.detector.y_flipped
132
141
  == True # is not locked and is initially set to False (should load it and ignore overwriting)
133
142
  )
134
- numpy.testing.assert_almost_equal(overwrite_nx_tomo.energy.value, 88.058)
143
+ numpy.testing.assert_almost_equal(
144
+ overwrite_nx_tomo.energy.to_base_units().magnitude,
145
+ (88.058 * _ureg.keV).to_base_units().magnitude,
146
+ )
135
147
  numpy.testing.assert_array_almost_equal(
136
148
  overwrite_nx_tomo.instrument.detector.data,
137
149
  nx_tomo.instrument.detector.data,
@@ -101,7 +101,7 @@ class TestNabuWidget(TestCaseQt):
101
101
  self.wait_processing()
102
102
  self.assertEqual(self.widget.getMode(), _NabuMode.HALF_ACQ)
103
103
  self.patch_fov(value=FOV.FULL.value)
104
- self.scan.clear_caches()
104
+ self.scan.clear_cache()
105
105
  self.widget.process(self.scan)
106
106
  self.wait_processing()
107
107
  self.assertEqual(self.widget.getMode(), _NabuMode.FULL_FIELD)
tomwer/version.py CHANGED
@@ -76,9 +76,9 @@ RELEASE_LEVEL_VALUE = {
76
76
  }
77
77
 
78
78
  MAJOR = 1
79
- MINOR = 4
80
- MICRO = 19
81
- RELEV = "final" # <16
79
+ MINOR = 5
80
+ MICRO = 0
81
+ RELEV = "rc" # <16
82
82
  SERIAL = 0 # <16
83
83
 
84
84
  date = __date__
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tomwer
3
- Version: 1.4.19
3
+ Version: 1.5.0rc0
4
4
  Summary: "tomography workflow tools"
5
5
  Home-page: https://gitlab.esrf.fr/tomotools/tomwer
6
6
  Author: Henri Payno, Pierre Paleo, Pierre-Olivier Autran, Jérôme Lesaint, Alessandro Mirone
@@ -18,22 +18,22 @@ Classifier: Operating System :: POSIX
18
18
  Classifier: Natural Language :: English
19
19
  Classifier: Topic :: Scientific/Engineering :: Physics
20
20
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
- Requires-Python: >=3.6
21
+ Requires-Python: >=3.9
22
22
  Description-Content-Type: text/x-rst
23
23
  License-File: LICENSE
24
24
  Requires-Dist: numpy
25
25
  Requires-Dist: setuptools
26
26
  Requires-Dist: psutil
27
- Requires-Dist: silx[full]<2.1.1,>=2.0
28
- Requires-Dist: tomoscan>=2.1.0a18
29
- Requires-Dist: nxtomo<2.0,>=1.3.0dev4
30
- Requires-Dist: nxtomomill>=1.1.0a0
27
+ Requires-Dist: silx[full]>=2.1.1
28
+ Requires-Dist: tomoscan>=2.2.0a6
29
+ Requires-Dist: nxtomo>=2.0.0dev2
30
+ Requires-Dist: nxtomomill>=1.2.0dev1
31
31
  Requires-Dist: processview>=1.5.0
32
32
  Requires-Dist: ewoks>=0.1.1
33
33
  Requires-Dist: ewokscore<1.1.0
34
34
  Requires-Dist: sluurp>=0.4.1
35
35
  Requires-Dist: packaging
36
- Requires-Dist: pyunitsystem>=2.0.0a
36
+ Requires-Dist: pint
37
37
  Requires-Dist: tqdm
38
38
  Provides-Extra: full-base
39
39
  Requires-Dist: orange-canvas-core; extra == "full-base"
@@ -227,7 +227,7 @@ Requires-Dist: ewoksnotify[full]; extra == "test"
227
227
  Requires-Dist: pyicat_plus; extra == "test"
228
228
  Requires-Dist: nabu>=2023.3.1dev; extra == "test"
229
229
  Requires-Dist: pytest-asyncio; extra == "test"
230
- Requires-Dist: tomoscan[test]>=2.1.0a18; extra == "test"
230
+ Requires-Dist: tomoscan[test]>=2.2.0a6; extra == "test"
231
231
  Provides-Extra: setup-requires
232
232
  Requires-Dist: setuptools; extra == "setup-requires"
233
233
  Requires-Dist: numpy>=1.12; extra == "setup-requires"