tomwer 1.2.9__py3-none-any.whl → 1.3.0a0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (253) hide show
  1. orangecontrib/tomwer/tutorials/icat_publication.ows +58 -0
  2. orangecontrib/tomwer/widgets/__init__.py +1 -0
  3. orangecontrib/tomwer/widgets/control/DataDiscoveryOW.py +2 -2
  4. orangecontrib/tomwer/widgets/control/DataListOW.py +9 -7
  5. orangecontrib/tomwer/widgets/control/DataSelectorOW.py +21 -10
  6. orangecontrib/tomwer/widgets/control/EDF2NXTomomillOW.py +11 -5
  7. orangecontrib/tomwer/widgets/control/EmailOW.py +4 -4
  8. orangecontrib/tomwer/widgets/control/NXTomomillOW.py +31 -18
  9. orangecontrib/tomwer/widgets/control/NXtomoConcatenate.py +14 -7
  10. orangecontrib/tomwer/widgets/control/NotifierOW.py +1 -0
  11. orangecontrib/tomwer/widgets/control/VolumeSelector.py +7 -4
  12. orangecontrib/tomwer/widgets/control/VolumeSymLinkOW.py +182 -182
  13. orangecontrib/tomwer/widgets/debugtools/DatasetGeneratorOW.py +4 -4
  14. orangecontrib/tomwer/widgets/edit/DarkFlatPatchOW.py +4 -4
  15. orangecontrib/tomwer/widgets/edit/ImageKeyEditorOW.py +3 -3
  16. orangecontrib/tomwer/widgets/edit/ImageKeyUpgraderOW.py +2 -0
  17. orangecontrib/tomwer/widgets/edit/NXtomoEditorOW.py +3 -3
  18. orangecontrib/tomwer/widgets/edit/test/test_nxtomo_editor.py +3 -3
  19. orangecontrib/tomwer/widgets/icat/PublishProcessedDataOW.py +115 -0
  20. orangecontrib/tomwer/widgets/icat/RawDataScreenshotCreatorOW.py +98 -0
  21. orangecontrib/tomwer/widgets/icat/SaveToGalleryAndPublishOW.py +129 -0
  22. orangecontrib/tomwer/widgets/icat/__init__.py +13 -0
  23. orangecontrib/tomwer/widgets/icat/icons/add_gallery.png +0 -0
  24. orangecontrib/tomwer/widgets/icat/icons/add_gallery.svg +82 -0
  25. orangecontrib/tomwer/widgets/icat/icons/publish_processed_data.png +0 -0
  26. orangecontrib/tomwer/widgets/icat/icons/publish_processed_data.svg +95 -0
  27. orangecontrib/tomwer/widgets/icat/icons/raw_screenshots.png +0 -0
  28. orangecontrib/tomwer/widgets/icat/icons/raw_screenshots.svg +143 -0
  29. orangecontrib/tomwer/widgets/icons/tomwer_data_portal.png +0 -0
  30. orangecontrib/tomwer/widgets/icons/tomwer_data_portal.svg +76 -0
  31. orangecontrib/tomwer/widgets/reconstruction/AxisOW.py +9 -8
  32. orangecontrib/tomwer/widgets/reconstruction/CastNabuVolumeOW.py +3 -3
  33. orangecontrib/tomwer/widgets/reconstruction/NabuHelicalPrepareWeightsDoubleOW.py +179 -169
  34. orangecontrib/tomwer/widgets/reconstruction/NabuOW.py +23 -0
  35. orangecontrib/tomwer/widgets/reconstruction/NabuVolumeOW.py +39 -5
  36. orangecontrib/tomwer/widgets/reconstruction/SAAxisOW.py +7 -13
  37. orangecontrib/tomwer/widgets/reconstruction/SADeltaBetaOW.py +7 -17
  38. orangecontrib/tomwer/widgets/reconstruction/SinoNormOW.py +3 -4
  39. orangecontrib/tomwer/widgets/visualization/LivesliceOW.py +1 -1
  40. orangecontrib/tomwer/widgets/visualization/NXtomoMetadataViewerOW.py +3 -3
  41. orangecontrib/tomwer/widgets/visualization/VolumeViewerOW.py +3 -29
  42. tomwer/__main__.py +11 -58
  43. tomwer/app/canvas.py +8 -0
  44. tomwer/app/canvas_launcher/config.py +13 -11
  45. tomwer/app/darkref.py +1 -1
  46. tomwer/app/darkrefpatch.py +1 -1
  47. tomwer/app/imagekeyeditor.py +5 -5
  48. tomwer/app/imagekeyupgrader.py +5 -5
  49. tomwer/app/intensitynormalization.py +2 -2
  50. tomwer/app/radiostack.py +2 -2
  51. tomwer/app/zstitching.py +74 -3
  52. tomwer/core/cluster/cluster.py +26 -0
  53. tomwer/core/log/logger.py +7 -5
  54. tomwer/core/process/conditions/filters.py +1 -1
  55. tomwer/core/process/control/datalistener/datalistener.py +3 -3
  56. tomwer/core/process/control/nxtomoconcatenate.py +13 -13
  57. tomwer/core/process/control/nxtomomill.py +83 -25
  58. tomwer/core/process/control/scantransfer.py +11 -10
  59. tomwer/core/process/control/scanvalidator.py +3 -2
  60. tomwer/core/process/control/test/test_concatenate_nxtomos.py +9 -9
  61. tomwer/core/process/control/test/test_email.py +4 -4
  62. tomwer/core/process/control/test/test_h52nx_process.py +59 -7
  63. tomwer/core/process/control/test/test_volume_link.py +64 -64
  64. tomwer/core/process/control/timer.py +1 -1
  65. tomwer/core/process/control/volumesymlink.py +200 -200
  66. tomwer/core/process/edit/darkflatpatch.py +6 -6
  67. tomwer/core/process/edit/imagekeyeditor.py +17 -18
  68. tomwer/core/process/icat/__init__.py +0 -0
  69. tomwer/core/process/icat/createscreenshots.py +100 -0
  70. tomwer/core/process/icat/gallery.py +377 -0
  71. tomwer/core/process/icat/icatbase.py +36 -0
  72. tomwer/core/process/icat/publish.py +228 -0
  73. tomwer/core/process/icat/screenshots.py +26 -0
  74. tomwer/core/process/output.py +52 -0
  75. tomwer/core/process/reconstruction/axis/axis.py +17 -10
  76. tomwer/core/process/reconstruction/axis/mode.py +4 -0
  77. tomwer/core/process/reconstruction/axis/params.py +9 -4
  78. tomwer/core/process/reconstruction/darkref/darkrefs.py +8 -6
  79. tomwer/core/process/reconstruction/darkref/darkrefscopy.py +1 -1
  80. tomwer/core/process/reconstruction/darkref/params.py +1 -1
  81. tomwer/core/process/reconstruction/lamino/tofu.py +4 -4
  82. tomwer/core/process/reconstruction/nabu/castvolume.py +1 -1
  83. tomwer/core/process/reconstruction/nabu/helical.py +9 -5
  84. tomwer/core/process/reconstruction/nabu/nabucommon.py +32 -62
  85. tomwer/core/process/reconstruction/nabu/nabuscores.py +387 -61
  86. tomwer/core/process/reconstruction/nabu/nabuslices.py +33 -21
  87. tomwer/core/process/reconstruction/nabu/nabuvolume.py +37 -14
  88. tomwer/core/process/reconstruction/nabu/settings.py +2 -2
  89. tomwer/core/process/reconstruction/nabu/utils.py +129 -24
  90. tomwer/core/process/reconstruction/output.py +108 -0
  91. tomwer/core/process/reconstruction/saaxis/saaxis.py +233 -263
  92. tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py +140 -86
  93. tomwer/core/process/reconstruction/scores/params.py +4 -1
  94. tomwer/core/process/reconstruction/scores/scores.py +13 -0
  95. tomwer/core/process/reconstruction/test/test_axis_params.py +2 -2
  96. tomwer/core/process/reconstruction/test/test_darkref.py +3 -3
  97. tomwer/core/process/reconstruction/test/test_darkref_copy.py +3 -3
  98. tomwer/core/process/reconstruction/test/test_saaxis.py +3 -4
  99. tomwer/core/process/reconstruction/test/test_sadeltabeta.py +2 -2
  100. tomwer/core/process/stitching/nabustitcher.py +2 -2
  101. tomwer/core/process/test/test_axis.py +6 -6
  102. tomwer/core/process/test/test_dark_and_flat.py +10 -7
  103. tomwer/core/process/test/test_data_transfer.py +7 -6
  104. tomwer/core/process/test/test_nabu.py +4 -4
  105. tomwer/core/process/test/test_normalization.py +2 -2
  106. tomwer/core/scan/edfscan.py +4 -1
  107. tomwer/core/scan/hdf5scan.py +19 -500
  108. tomwer/core/scan/nxtomoscan.py +532 -0
  109. tomwer/core/scan/scanbase.py +42 -20
  110. tomwer/core/scan/scanfactory.py +13 -13
  111. tomwer/core/scan/test/test_future_scan.py +2 -2
  112. tomwer/core/scan/test/test_h5.py +12 -10
  113. tomwer/core/scan/test/test_process_registration.py +2 -2
  114. tomwer/core/scan/test/test_scan.py +4 -3
  115. tomwer/core/settings.py +20 -0
  116. tomwer/core/test/test_scanutils.py +8 -7
  117. tomwer/core/test/test_utils.py +33 -26
  118. tomwer/core/utils/__init__.py +0 -466
  119. tomwer/core/utils/deprecation.py +1 -1
  120. tomwer/core/utils/dictutils.py +14 -0
  121. tomwer/core/utils/lbsram.py +35 -0
  122. tomwer/core/utils/nxtomoutils.py +1 -1
  123. tomwer/core/utils/scanutils.py +6 -6
  124. tomwer/core/utils/spec.py +263 -0
  125. tomwer/core/volume/volumefactory.py +2 -2
  126. tomwer/gui/cluster/slurm.py +260 -60
  127. tomwer/gui/cluster/test/test_cluster.py +13 -0
  128. tomwer/gui/cluster/test/test_supervisor.py +2 -2
  129. tomwer/gui/configuration/__init__.py +0 -0
  130. tomwer/gui/{reconstruction/nabu → configuration}/action.py +1 -32
  131. tomwer/gui/configuration/level.py +22 -0
  132. tomwer/gui/control/actions.py +54 -0
  133. tomwer/gui/control/datalist.py +78 -16
  134. tomwer/gui/control/datalistener.py +4 -16
  135. tomwer/gui/control/{email.py → emailnotifier.py} +9 -18
  136. tomwer/gui/control/history.py +2 -2
  137. tomwer/gui/control/observations.py +2 -2
  138. tomwer/gui/control/reducedarkflatselector.py +1 -1
  139. tomwer/gui/control/selectorwidgetbase.py +36 -9
  140. tomwer/gui/control/serie/seriecreator.py +5 -22
  141. tomwer/gui/control/test/test_email.py +1 -1
  142. tomwer/gui/control/test/test_scanvalidator.py +6 -5
  143. tomwer/gui/control/test/test_single_tomo_obj.py +2 -2
  144. tomwer/gui/control/tomoobjdisplaymode.py +8 -0
  145. tomwer/gui/debugtools/datasetgenerator.py +3 -3
  146. tomwer/gui/edit/dkrfpatch.py +16 -22
  147. tomwer/gui/edit/imagekeyeditor.py +8 -11
  148. tomwer/gui/edit/nxtomoeditor.py +111 -44
  149. tomwer/gui/edit/nxtomowarmer.py +4 -4
  150. tomwer/gui/edit/test/test_dkrf_patch.py +7 -7
  151. tomwer/gui/edit/test/test_image_key_editor.py +3 -3
  152. tomwer/gui/edit/test/test_nx_editor.py +40 -16
  153. tomwer/gui/icat/__init__.py +0 -0
  154. tomwer/gui/icat/createscreenshots.py +80 -0
  155. tomwer/gui/icat/gallery.py +214 -0
  156. tomwer/gui/icat/publish.py +187 -0
  157. tomwer/gui/reconstruction/axis/axis.py +171 -57
  158. tomwer/gui/reconstruction/axis/radioaxis.py +80 -95
  159. tomwer/gui/reconstruction/darkref/darkrefcopywidget.py +3 -2
  160. tomwer/gui/reconstruction/lamino/tofu/projections.py +1 -1
  161. tomwer/gui/reconstruction/lamino/tofu/tofuoutput.py +3 -6
  162. tomwer/gui/reconstruction/nabu/castvolume.py +1 -1
  163. tomwer/gui/reconstruction/nabu/check.py +9 -9
  164. tomwer/gui/reconstruction/nabu/helical.py +29 -12
  165. tomwer/gui/reconstruction/nabu/nabuconfig/base.py +2 -4
  166. tomwer/gui/reconstruction/nabu/nabuconfig/output.py +110 -33
  167. tomwer/gui/reconstruction/nabu/nabuconfig/phase.py +9 -12
  168. tomwer/gui/reconstruction/nabu/nabuconfig/preprocessing.py +219 -29
  169. tomwer/gui/reconstruction/nabu/nabuconfig/reconstruction.py +3 -6
  170. tomwer/gui/reconstruction/nabu/nabuflow.py +12 -20
  171. tomwer/gui/reconstruction/nabu/slices.py +6 -7
  172. tomwer/gui/reconstruction/nabu/volume.py +22 -10
  173. tomwer/gui/reconstruction/normalization/intensity.py +15 -23
  174. tomwer/gui/reconstruction/saaxis/corrangeselector.py +7 -23
  175. tomwer/gui/reconstruction/saaxis/dimensionwidget.py +1 -1
  176. tomwer/gui/reconstruction/saaxis/saaxis.py +7 -9
  177. tomwer/gui/reconstruction/sadeltabeta/saadeltabeta.py +2 -1
  178. tomwer/gui/reconstruction/scores/control.py +2 -9
  179. tomwer/gui/reconstruction/scores/scoreplot.py +11 -5
  180. tomwer/gui/reconstruction/test/test_axis.py +23 -12
  181. tomwer/gui/reconstruction/test/test_lamino.py +8 -3
  182. tomwer/gui/reconstruction/test/test_nabu.py +28 -9
  183. tomwer/gui/reconstruction/test/test_saaxis.py +3 -3
  184. tomwer/gui/reconstruction/test/test_sadeltabeta.py +2 -2
  185. tomwer/gui/settings.py +5 -28
  186. tomwer/gui/stackplot.py +2 -5
  187. tomwer/gui/stitching/action.py +49 -0
  188. tomwer/gui/stitching/config/axisparams.py +7 -24
  189. tomwer/gui/stitching/config/output.py +10 -8
  190. tomwer/gui/stitching/config/positionoveraxis.py +22 -23
  191. tomwer/gui/stitching/normalization.py +117 -0
  192. tomwer/gui/stitching/stitchandbackground.py +4 -6
  193. tomwer/gui/stitching/stitching.py +265 -43
  194. tomwer/gui/stitching/stitching_preview.py +62 -5
  195. tomwer/gui/stitching/stitching_raw.py +2 -5
  196. tomwer/gui/stitching/z_stitching/fineestimation.py +0 -60
  197. tomwer/gui/utils/buttons.py +112 -29
  198. tomwer/gui/utils/inputwidget.py +33 -25
  199. tomwer/gui/utils/scandescription.py +4 -0
  200. tomwer/gui/utils/step.py +144 -0
  201. tomwer/gui/utils/unitsystem.py +2 -5
  202. tomwer/gui/utils/vignettes.py +176 -15
  203. tomwer/gui/visualization/dataviewer.py +1 -4
  204. tomwer/gui/visualization/diffviewer/diffviewer.py +7 -16
  205. tomwer/gui/visualization/diffviewer/shiftwidget.py +2 -5
  206. tomwer/gui/visualization/scanoverview.py +1 -1
  207. tomwer/gui/visualization/sinogramviewer.py +1 -10
  208. tomwer/gui/visualization/test/test_diffviewer.py +3 -3
  209. tomwer/gui/visualization/test/test_nx_tomo_metadata_viewer.py +4 -4
  210. tomwer/gui/visualization/test/test_sinogramviewer.py +2 -2
  211. tomwer/gui/visualization/test/test_stacks.py +3 -3
  212. tomwer/gui/visualization/test/test_volumeviewer.py +2 -2
  213. tomwer/io/utils/raw_and_processed_data.py +84 -0
  214. tomwer/io/utils/tomoobj.py +4 -6
  215. tomwer/resources/gui/icons/ruler.png +0 -0
  216. tomwer/resources/gui/icons/ruler.svg +273 -0
  217. tomwer/resources/gui/icons/short_description.png +0 -0
  218. tomwer/resources/gui/icons/short_description.svg +58 -0
  219. tomwer/resources/gui/icons/url.png +0 -0
  220. tomwer/resources/gui/icons/url.svg +58 -0
  221. tomwer/synctools/stacks/edit/darkflatpatch.py +2 -2
  222. tomwer/synctools/stacks/edit/imagekeyeditor.py +2 -2
  223. tomwer/synctools/stacks/reconstruction/axis.py +4 -4
  224. tomwer/synctools/stacks/reconstruction/castvolume.py +2 -2
  225. tomwer/synctools/stacks/reconstruction/dkrefcopy.py +4 -10
  226. tomwer/synctools/stacks/reconstruction/nabu.py +2 -2
  227. tomwer/synctools/stacks/reconstruction/normalization.py +2 -2
  228. tomwer/synctools/stacks/reconstruction/saaxis.py +2 -2
  229. tomwer/synctools/stacks/reconstruction/sadeltabeta.py +2 -2
  230. tomwer/synctools/test/test_darkRefs.py +7 -58
  231. tomwer/synctools/test/test_foldertransfer.py +6 -6
  232. tomwer/synctools/utils/scanstages.py +6 -6
  233. tomwer/tests/conftest.py +34 -0
  234. tomwer/tests/datasets.py +13 -0
  235. tomwer/tests/test_scripts.py +92 -39
  236. tomwer/tests/utils.py +5 -0
  237. tomwer/version.py +3 -3
  238. {tomwer-1.2.9.dist-info → tomwer-1.3.0a0.dist-info}/METADATA +39 -39
  239. {tomwer-1.2.9.dist-info → tomwer-1.3.0a0.dist-info}/RECORD +248 -209
  240. tomwer/resources/gui/icons/esrf_1.svg +0 -307
  241. tomwer/resources/gui/icons/triangle.svg +0 -80
  242. tomwer/synctools/test/test_scanstages.py +0 -162
  243. tomwer/tests/utils/__init__.py +0 -247
  244. tomwer/tests/utils/utilstest.py +0 -220
  245. /tomwer/app/{saaxis.py → multicor.py} +0 -0
  246. /tomwer/app/{sadeltabeta.py → multipag.py} +0 -0
  247. /tomwer/core/process/control/{email.py → emailnotifier.py} +0 -0
  248. /tomwer-1.2.9-py3.11-nspkg.pth → /tomwer-1.3.0a0-py3.11-nspkg.pth +0 -0
  249. {tomwer-1.2.9.dist-info → tomwer-1.3.0a0.dist-info}/LICENSE +0 -0
  250. {tomwer-1.2.9.dist-info → tomwer-1.3.0a0.dist-info}/WHEEL +0 -0
  251. {tomwer-1.2.9.dist-info → tomwer-1.3.0a0.dist-info}/entry_points.txt +0 -0
  252. {tomwer-1.2.9.dist-info → tomwer-1.3.0a0.dist-info}/namespace_packages.txt +0 -0
  253. {tomwer-1.2.9.dist-info → tomwer-1.3.0a0.dist-info}/top_level.txt +0 -0
@@ -36,11 +36,11 @@ from silx.gui import qt
36
36
  from silx.gui.dialog.DataFileDialog import DataFileDialog
37
37
  from silx.io.url import DataUrl
38
38
  from silx.io.utils import h5py_read_dataset
39
- from tomoscan.esrf.scan.hdf5scan import ImageKey
39
+ from nxtomo.nxobject.nxdetector import ImageKey
40
40
  from tomoscan.io import HDF5File
41
41
 
42
42
  import tomwer.core.utils.nxtomoutils as nxtomo_utils
43
- from tomwer.core.scan.hdf5scan import HDF5TomoScan
43
+ from tomwer.core.scan.nxtomoscan import NXtomoScan
44
44
  from tomwer.io.utils import get_default_directory
45
45
 
46
46
  _logger = logging.getLogger(__name__)
@@ -67,11 +67,8 @@ class _DarkOrFlatUrl(qt.QWidget):
67
67
 
68
68
  # connect signal / slot
69
69
  self._qle.editingFinished.connect(self._tryUpdateOptions)
70
- self._qle.editingFinished.connect(self._editingFinished)
71
- self._optionsCB.currentIndexChanged.connect(self._editingFinished)
72
-
73
- def _editingFinished(self):
74
- self.editingFinished.emit()
70
+ self._qle.editingFinished.connect(self.editingFinished)
71
+ self._optionsCB.currentIndexChanged.connect(self.editingFinished)
75
72
 
76
73
  def setUrl(self, url):
77
74
  """
@@ -102,7 +99,7 @@ class _DarkOrFlatUrl(qt.QWidget):
102
99
  self._qle.setText(url.path())
103
100
  self._updateOptions(url)
104
101
  self.blockSignals(old)
105
- self._editingFinished()
102
+ self.editingFinished.emit()
106
103
 
107
104
  def setSerie(self, serie):
108
105
  type_name = self._type.name.lower().replace("_", " ")
@@ -119,7 +116,7 @@ class _DarkOrFlatUrl(qt.QWidget):
119
116
  with HDF5File(url.file_path(), mode="r") as h5s:
120
117
  node = h5s[url.data_path()]
121
118
 
122
- if HDF5TomoScan.entry_is_nx_tomo(node):
119
+ if NXtomoScan.entry_is_nx_tomo(node):
123
120
  if (
124
121
  "detector" in node["instrument"]
125
122
  and "data" in node["instrument"]["detector"]
@@ -133,7 +130,7 @@ class _DarkOrFlatUrl(qt.QWidget):
133
130
  (url.data_path(), "instrument", "detector", "data")
134
131
  )
135
132
  url = DataUrl(file_path=url.file_path(), data_path=data_path)
136
- elif HDF5TomoScan.is_nxdetector(node):
133
+ elif NXtomoScan.is_nxdetector(node):
137
134
  if "data" in node:
138
135
  if logger:
139
136
  _logger.info(
@@ -194,7 +191,7 @@ class _DarkOrFlatUrl(qt.QWidget):
194
191
  with HDF5File(url.file_path(), mode="r") as h5s:
195
192
  dataset = h5s[url.data_path()]
196
193
  grp_parent = dataset.parent
197
- if grp_parent is not None and HDF5TomoScan.is_nxdetector(grp_parent):
194
+ if grp_parent is not None and NXtomoScan.is_nxdetector(grp_parent):
198
195
  if "image_key" in grp_parent:
199
196
  return h5py_read_dataset(grp_parent["image_key"])
200
197
  return None
@@ -319,17 +316,14 @@ class DarkRefPatchWidget(qt.QWidget):
319
316
  self._efCB.toggled.connect(self._toggleEF)
320
317
 
321
318
  # connect QLE modifications
322
- self._sdQLE.editingFinished.connect(self._configurationChanged)
323
- self._sdCB.toggled.connect(self._configurationChanged)
324
- self._sfQLE.editingFinished.connect(self._configurationChanged)
325
- self._sfCB.toggled.connect(self._configurationChanged)
326
- self._efQLE.editingFinished.connect(self._configurationChanged)
327
- self._efCB.toggled.connect(self._configurationChanged)
328
- self._edQLE.editingFinished.connect(self._configurationChanged)
329
- self._edCB.toggled.connect(self._configurationChanged)
330
-
331
- def _configurationChanged(self):
332
- self.sigConfigurationChanged.emit()
319
+ self._sdQLE.editingFinished.connect(self.sigConfigurationChanged)
320
+ self._sdCB.toggled.connect(self.sigConfigurationChanged)
321
+ self._sfQLE.editingFinished.connect(self.sigConfigurationChanged)
322
+ self._sfCB.toggled.connect(self.sigConfigurationChanged)
323
+ self._efQLE.editingFinished.connect(self.sigConfigurationChanged)
324
+ self._efCB.toggled.connect(self.sigConfigurationChanged)
325
+ self._edQLE.editingFinished.connect(self.sigConfigurationChanged)
326
+ self._edCB.toggled.connect(self.sigConfigurationChanged)
333
327
 
334
328
  def _selectSDDataset(self):
335
329
  self._selectDataset("start dark", self._sdQLE)
@@ -35,10 +35,10 @@ from collections.abc import Iterable
35
35
  from typing import Union
36
36
 
37
37
  from silx.gui import qt
38
- from tomoscan.esrf.scan.hdf5scan import ImageKey as _ImageKey
38
+ from nxtomo.nxobject.nxdetector import ImageKey as _ImageKey
39
39
 
40
40
  from tomwer.core.process.edit.imagekeyeditor import IMAGE_KEYS
41
- from tomwer.core.scan.hdf5scan import HDF5TomoScan
41
+ from tomwer.core.scan.nxtomoscan import NXtomoScan
42
42
 
43
43
  _logger = logging.getLogger(__name__)
44
44
 
@@ -93,7 +93,7 @@ class ImageKeyDialog(qt.QDialog):
93
93
  def setScan(self, scan):
94
94
  """
95
95
 
96
- :param HDF5TomoScan scan: scan to be edited
96
+ :param NXtomoScan scan: scan to be edited
97
97
  """
98
98
  self._widget.setScan(scan)
99
99
 
@@ -120,7 +120,7 @@ class ImageKeyWindow(qt.QMainWindow):
120
120
  def setScan(self, scan) -> None:
121
121
  """
122
122
 
123
- :param HDF5TomoScan scan: scan to be edited
123
+ :param NXtomoScan scan: scan to be edited
124
124
  """
125
125
  self._mainWindow.setScan(scan=scan)
126
126
  self._editorControl.setScan(scan=scan)
@@ -213,7 +213,7 @@ class _ImageKeyEditor(qt.QDialog):
213
213
  self._selectionModeCB.currentTextChanged.connect(
214
214
  self._selectionWidget.setSelectionMode
215
215
  )
216
- self._buttons.button(qt.QDialogButtonBox.Ok).clicked.connect(self._apply)
216
+ self._buttons.button(qt.QDialogButtonBox.Ok).clicked.connect(self.sigApply)
217
217
 
218
218
  def getUpgradeToImagKey(self) -> str:
219
219
  """
@@ -243,9 +243,6 @@ class _ImageKeyEditor(qt.QDialog):
243
243
  else:
244
244
  raise NotImplementedError("Not implemented")
245
245
 
246
- def _apply(self):
247
- self.sigApply.emit()
248
-
249
246
  def setScan(self, scan):
250
247
  self._selectionWidget.setScan(scan=scan)
251
248
  if scan is not None:
@@ -450,7 +447,7 @@ class _ImageKeyList(qt.QTableWidget):
450
447
  """
451
448
  Update the QTableWidget for the provided frames
452
449
 
453
- :param Iterable frames: Iterable of tomoscan.esrf.scan.HDF5TomoScan.Frame
450
+ :param Iterable frames: Iterable of tomoscan.esrf.scan.NXtomoScan.Frame
454
451
  :param dict frames_new_keys: dictionary with frame edited. key is frame
455
452
  index. Value is the new `image_key` value
456
453
  """
@@ -627,9 +624,9 @@ class _ImageKeyListFiltered(qt.QWidget):
627
624
  return self._filterCB.currentText()
628
625
 
629
626
  def setScan(self, scan):
630
- if not isinstance(scan, HDF5TomoScan):
627
+ if not isinstance(scan, NXtomoScan):
631
628
  raise TypeError(
632
- f"scan should be an instance of {HDF5TomoScan}. {type(scan)} provided"
629
+ f"scan should be an instance of {NXtomoScan}. {type(scan)} provided"
633
630
  )
634
631
  self.__frames_modifications = {}
635
632
  self._scan = weakref.ref(scan)
@@ -1,17 +1,26 @@
1
1
  import logging
2
2
  import weakref
3
3
  from typing import Optional
4
+ from functools import lru_cache as cache
4
5
 
5
6
  import h5py
6
7
  import numpy
7
8
  from silx.gui import qt
8
9
  from silx.io.utils import h5py_read_dataset
9
- from tomoscan.esrf.scan.hdf5scan import ImageKey
10
- from tomoscan.io import HDF5File
11
- from tomoscan.nexus.paths.nxtomo import get_paths as get_nexus_paths
12
- from tomoscan.scanbase import _FOV
10
+ from silx.io.dictdump import dicttonx
13
11
 
14
- from tomwer.core.scan.hdf5scan import HDF5TomoScan
12
+ from tomoscan.io import HDF5File
13
+ from nxtomo.paths.nxtomo import get_paths as get_nexus_paths
14
+ from nxtomo.nxobject.nxdetector import ImageKey
15
+ from nxtomo.nxobject.nxdetector import FOV
16
+ from nxtomo.nxobject.nxtransformations import NXtransformations
17
+ from nxtomo.utils.transformation import (
18
+ build_matrix,
19
+ UDDetTransformation,
20
+ LRDetTransformation,
21
+ )
22
+
23
+ from tomwer.core.scan.nxtomoscan import NXtomoScan
15
24
  from tomwer.gui.utils.buttons import PadlockButton
16
25
  from tomwer.gui.utils.scandescription import ScanNameLabelAndShape
17
26
  from tomwer.gui.utils.unitsystem import MetricEntry
@@ -149,7 +158,7 @@ class NXtomoEditor(qt.QWidget):
149
158
  self._fieldOfViewQTWI = qt.QTreeWidgetItem(self._detectorQTWI)
150
159
  self._fieldOfViewQTWI.setText(0, "field of view")
151
160
  self._fieldOfViewCB = qt.QComboBox(self)
152
- for value in _FOV.values():
161
+ for value in FOV.values():
153
162
  self._fieldOfViewCB.addItem(value)
154
163
  self._tree.setItemWidget(self._fieldOfViewQTWI, 1, self._fieldOfViewCB)
155
164
  self._editableWidgets.append(self._fieldOfViewCB)
@@ -235,9 +244,9 @@ class NXtomoEditor(qt.QWidget):
235
244
  def setScan(self, scan):
236
245
  if scan is None:
237
246
  self._scan = scan
238
- elif not isinstance(scan, HDF5TomoScan):
247
+ elif not isinstance(scan, NXtomoScan):
239
248
  raise TypeError(
240
- f"{scan} is expected to be an instance of {HDF5TomoScan}. Not {type(scan)}"
249
+ f"{scan} is expected to be an instance of {NXtomoScan}. Not {type(scan)}"
241
250
  )
242
251
  else:
243
252
  self._scan = weakref.ref(scan)
@@ -281,8 +290,8 @@ class NXtomoEditor(qt.QWidget):
281
290
  else:
282
291
  self._updateTranslations(scan=scan)
283
292
 
284
- def _updateTranslations(self, scan: HDF5TomoScan):
285
- assert isinstance(scan, HDF5TomoScan)
293
+ def _updateTranslations(self, scan: NXtomoScan):
294
+ assert isinstance(scan, NXtomoScan)
286
295
 
287
296
  # note: for now and in order to allow edition we expect to have at most a unique value. Will fail for helicoidal
288
297
  def reduce(values):
@@ -307,17 +316,61 @@ class NXtomoEditor(qt.QWidget):
307
316
  def _updateFieldOfView(self, scan):
308
317
  if not self._fieldOfViewLB.isLocked():
309
318
  # if in ''auto mode: we want to overwrite the NXtomo existing value by the one of the GUI
310
- idx = self._fieldOfViewCB.findText(
311
- _FOV.from_value(scan.field_of_view).value
312
- )
319
+ idx = self._fieldOfViewCB.findText(FOV.from_value(scan.field_of_view).value)
313
320
  if idx > 0:
314
321
  self._fieldOfViewCB.setCurrentIndex(idx)
315
322
 
323
+ @staticmethod
324
+ @cache(maxsize=None)
325
+ def _get_UD_flip_matrix():
326
+ return UDDetTransformation().as_matrix()
327
+
328
+ @staticmethod
329
+ @cache(maxsize=None)
330
+ def _get_LR_flip_matrix():
331
+ return LRDetTransformation().as_matrix()
332
+
333
+ @staticmethod
334
+ @cache(maxsize=None)
335
+ def _get_UD_AND_LR_flip_matrix():
336
+ return numpy.matmul(
337
+ NXtomoEditor._get_UD_flip_matrix(),
338
+ NXtomoEditor._get_LR_flip_matrix(),
339
+ )
340
+
316
341
  def _updateFlipped(self, scan):
317
- if (not self._xFlippedLB.isLocked()) and scan.x_flipped is not None:
318
- self._xFlippedCB.setChecked(scan.x_flipped)
319
- if (not self._yFlippedLB.isLocked()) and scan.y_flipped is not None:
320
- self._yFlippedCB.setChecked(scan.y_flipped)
342
+ transformations = list(scan.get_detector_transformations(tuple()))
343
+ transformation_matrix_det_space = build_matrix(transformations)
344
+ if transformation_matrix_det_space is None or numpy.allclose(
345
+ transformation_matrix_det_space, numpy.identity(3)
346
+ ):
347
+ flip_ud = False
348
+ flip_lr = False
349
+ elif numpy.array_equal(
350
+ transformation_matrix_det_space, NXtomoEditor._get_UD_flip_matrix()
351
+ ):
352
+ flip_ud = True
353
+ flip_lr = False
354
+ elif numpy.allclose(
355
+ transformation_matrix_det_space, NXtomoEditor._get_LR_flip_matrix()
356
+ ):
357
+ flip_ud = False
358
+ flip_lr = True
359
+ elif numpy.allclose(
360
+ transformation_matrix_det_space, NXtomoEditor._get_UD_AND_LR_flip_matrix()
361
+ ):
362
+ flip_ud = True
363
+ flip_lr = True
364
+ else:
365
+ flip_ud = None
366
+ flip_lr = None
367
+ _logger.warning(
368
+ "detector transformations provided not handled... For now only handle up-down flip as left-right flip"
369
+ )
370
+ if (not self._xFlippedLB.isLocked()) and flip_lr is not None:
371
+ self._xFlippedCB.setChecked(flip_lr)
372
+ if (not self._yFlippedLB.isLocked()) and flip_ud is not None:
373
+ self._yFlippedCB.setChecked(flip_ud)
321
374
 
322
375
  def _updateDistance(self, scan):
323
376
  if not self._distanceLB.isLocked():
@@ -325,14 +378,14 @@ class NXtomoEditor(qt.QWidget):
325
378
  self._distanceMetricEntry.setValue(scan.distance)
326
379
 
327
380
  def _updateEnergy(self, scan):
328
- assert isinstance(scan, HDF5TomoScan)
381
+ assert isinstance(scan, NXtomoScan)
329
382
  if not self._energyLockerLB.isLocked():
330
383
  # if in ''auto mode: we want to overwrite the NXtomo existing value by the one of the GUI
331
384
  energy = scan.energy
332
385
  self._energyEntry.setValue(energy)
333
386
 
334
387
  def _updatePixelSize(self, scan):
335
- assert isinstance(scan, HDF5TomoScan)
388
+ assert isinstance(scan, NXtomoScan)
336
389
  if not self._xPixelSizeLB.isLocked():
337
390
  x_pixel_size = scan.x_pixel_size
338
391
  self._xPixelSizeMetricEntry.setValue(x_pixel_size)
@@ -433,7 +486,7 @@ class NXtomoEditor(qt.QWidget):
433
486
  _logger.warning("no scan found to be saved")
434
487
  return
435
488
  nexus_paths = get_nexus_paths(scan.nexus_version)
436
- assert isinstance(scan, HDF5TomoScan)
489
+ assert isinstance(scan, NXtomoScan)
437
490
  with HDF5File(scan.master_file, mode="a") as h5f:
438
491
  entry = h5f[scan.entry]
439
492
  # overwrite energy
@@ -503,37 +556,49 @@ class NXtomoEditor(qt.QWidget):
503
556
  name="field of view",
504
557
  expected_type=str,
505
558
  )
506
- # overwrite x flipped
507
- self.__write_to_file(
508
- entry=entry,
509
- path="/".join(
559
+
560
+ # solve NXtranformations
561
+ nx_transformations = NXtransformations()
562
+ if self._xFlippedCB.isChecked():
563
+ nx_transformations.add_transformation(LRDetTransformation())
564
+ if self._yFlippedCB.isChecked():
565
+ nx_transformations.add_transformation(UDDetTransformation())
566
+
567
+ nx_dict = nx_transformations.to_nx_dict(
568
+ nexus_path_version=scan.nexus_version,
569
+ data_path="/".join(
510
570
  (
511
571
  nexus_paths.INSTRUMENT_PATH,
512
572
  nexus_paths.nx_instrument_paths.DETECTOR_PATH,
513
- nexus_paths.nx_detector_paths.X_FLIPPED,
514
573
  )
515
574
  ),
516
- value=self._xFlippedCB.isChecked(),
517
- name="x flipped",
518
- expected_type=bool,
575
+ solve_empty_dependency=True,
519
576
  )
520
- # overwrite y flipped
521
- self.__write_to_file(
522
- entry=entry,
523
- path="/".join(
524
- (
525
- nexus_paths.INSTRUMENT_PATH,
526
- nexus_paths.nx_instrument_paths.DETECTOR_PATH,
527
- nexus_paths.nx_detector_paths.Y_FLIPPED,
528
- )
577
+ detector_transformation_path = "/".join(
578
+ (
579
+ nexus_paths.INSTRUMENT_PATH,
580
+ nexus_paths.nx_instrument_paths.DETECTOR_PATH,
581
+ nexus_paths.nx_detector_paths.NX_TRANSFORMATIONS,
529
582
  ),
530
- value=self._yFlippedCB.isChecked(),
531
- name="y flipped",
532
- expected_type=bool,
533
583
  )
534
- # clear caches to make sure all modifications will be considered
535
- scan.clear_caches()
536
- scan.clear_frames_caches()
584
+ if detector_transformation_path in entry:
585
+ del entry[detector_transformation_path]
586
+
587
+ detector_transformation_path = "/".join(
588
+ (scan.entry, detector_transformation_path)
589
+ )
590
+
591
+ dicttonx(
592
+ nx_dict,
593
+ h5file=scan.master_file,
594
+ h5path=detector_transformation_path,
595
+ update_mode="replace",
596
+ mode="a",
597
+ )
598
+
599
+ # clear caches to make sure all modifications will be considered
600
+ scan.clear_caches()
601
+ scan.clear_frames_caches()
537
602
 
538
603
  @staticmethod
539
604
  def _newValueIsExistingValue(dataset: h5py.Dataset, new_value, units):
@@ -557,7 +622,9 @@ class NXtomoEditor(qt.QWidget):
557
622
  return False
558
623
 
559
624
  @staticmethod
560
- def __write_to_file(entry, path, value, name, expected_type, n_value=1, units=None):
625
+ def __write_to_file(
626
+ entry: h5py.Group, path: str, value, name, expected_type, n_value=1, units=None
627
+ ):
561
628
  if path is None:
562
629
  # if the path does not exists (no handled by this version of nexus for example)
563
630
  return
@@ -1,7 +1,7 @@
1
1
  from typing import Optional
2
2
  import h5py
3
3
  from silx.gui import qt
4
- from tomwer.core.scan.hdf5scan import HDF5TomoScan
4
+ from tomwer.core.scan.nxtomoscan import NXtomoScan
5
5
  from tomwer.gui import icons
6
6
  from tomoscan.io import HDF5File
7
7
 
@@ -40,17 +40,17 @@ class NXtomoProxyWarmer(qt.QWidget):
40
40
  # set up
41
41
  self.setScan(None)
42
42
 
43
- def setScan(self, scan: Optional[HDF5TomoScan]):
43
+ def setScan(self, scan: Optional[NXtomoScan]):
44
44
  if scan is None:
45
45
  self._activateWarning(False)
46
- elif isinstance(scan, HDF5TomoScan):
46
+ elif isinstance(scan, NXtomoScan):
47
47
  with HDF5File(scan.master_file, mode="r") as h5f:
48
48
  entry = h5f.get(
49
49
  name=scan.entry, getclass=True, getlink=True, default=None
50
50
  )
51
51
  self._activateWarning(entry in (h5py.ExternalLink, h5py.SoftLink))
52
52
  else:
53
- raise TypeError(f"{scan} is expected to be an instance of {HDF5TomoScan}")
53
+ raise TypeError(f"{scan} is expected to be an instance of {NXtomoScan}")
54
54
 
55
55
  def _activateWarning(self, activate: bool):
56
56
  self._warningIcon.setVisible(activate)
@@ -37,11 +37,11 @@ from nxtomomill.utils import add_dark_flat_nx_file
37
37
  from silx.gui import qt
38
38
  from silx.gui.utils.testutils import TestCaseQt
39
39
  from silx.io.url import DataUrl
40
- from tomoscan.esrf.scan.hdf5scan import ImageKey
40
+ from nxtomo.nxobject.nxdetector import ImageKey
41
41
  from tomoscan.esrf.scan.utils import get_data
42
42
 
43
- from tomwer.core.scan.hdf5scan import HDF5TomoScan
44
- from tomwer.core.utils.scanutils import MockHDF5
43
+ from tomwer.core.scan.nxtomoscan import NXtomoScan
44
+ from tomwer.core.utils.scanutils import MockNXtomo
45
45
  from tomwer.gui.edit.dkrfpatch import DarkRefPatchWidget, _DarkOrFlatUrl
46
46
  from tomwer.tests.utils import skip_gui_test
47
47
 
@@ -62,7 +62,7 @@ class TestDarkOrFlatUrl(TestCaseQt):
62
62
  )
63
63
  self.output_folder = tempfile.mkdtemp()
64
64
  #
65
- hdf5_mock = MockHDF5(
65
+ hdf5_mock = MockNXtomo(
66
66
  scan_path=self.output_folder,
67
67
  n_ini_proj=20,
68
68
  n_proj=20,
@@ -130,7 +130,7 @@ class TestDarkRefPatchWidget(TestCaseQt):
130
130
  self.output_folder1 = tempfile.mkdtemp()
131
131
  self.output_folder2 = tempfile.mkdtemp()
132
132
 
133
- hdf5_mock = MockHDF5(
133
+ hdf5_mock = MockNXtomo(
134
134
  scan_path=self.output_folder1,
135
135
  n_ini_proj=20,
136
136
  n_proj=20,
@@ -140,7 +140,7 @@ class TestDarkRefPatchWidget(TestCaseQt):
140
140
  )
141
141
  self._scanWithDarkAndRef = hdf5_mock.scan
142
142
 
143
- hdf5_mock = MockHDF5(
143
+ hdf5_mock = MockNXtomo(
144
144
  scan_path=self.output_folder2,
145
145
  n_ini_proj=20,
146
146
  n_proj=20,
@@ -176,7 +176,7 @@ class TestDarkRefPatchWidget(TestCaseQt):
176
176
  self.assertTrue(self._widget.getEndDarkUrl() is None)
177
177
  self.assertTrue(self._widget.getEndFlatUrl() is None)
178
178
  self.process()
179
- new_scan = HDF5TomoScan(scan=self._scan.master_file, entry=self._scan.entry)
179
+ new_scan = NXtomoScan(scan=self._scan.master_file, entry=self._scan.entry)
180
180
  self.assertEqual(len(new_scan.darks), 1)
181
181
  self.assertTrue(0 in new_scan.darks)
182
182
  numpy.testing.assert_array_equal(
@@ -33,9 +33,9 @@ import tempfile
33
33
  import pytest
34
34
  from silx.gui import qt
35
35
  from silx.gui.utils.testutils import SignalListener, TestCaseQt
36
- from tomoscan.esrf.scan.hdf5scan import ImageKey
36
+ from nxtomo.nxobject.nxdetector import ImageKey
37
37
 
38
- from tomwer.core.utils.scanutils import MockHDF5
38
+ from tomwer.core.utils.scanutils import MockNXtomo
39
39
  from tomwer.gui.edit.imagekeyeditor import (
40
40
  ImageKeyDialog,
41
41
  ImageKeyUpgraderWidget,
@@ -55,7 +55,7 @@ class TestImageKeyEditorGUI(TestCaseQt):
55
55
  self._widget = ImageKeyDialog(parent=None)
56
56
  self.output_folder = tempfile.mkdtemp()
57
57
 
58
- hdf5_mock = MockHDF5(
58
+ hdf5_mock = MockNXtomo(
59
59
  scan_path=self.output_folder,
60
60
  n_ini_proj=20,
61
61
  n_proj=20,
@@ -2,21 +2,28 @@ import os
2
2
 
3
3
  import numpy
4
4
  import pytest
5
- from nxtomomill.nexus.nxtomo import NXtomo
6
5
  from silx.gui import qt
7
- from tomoscan.esrf.scan.hdf5scan import ImageKey
8
- from tomoscan.scanbase import _FOV
9
- from tomoscan.unitsystem.energysystem import EnergySI
10
- from tomoscan.unitsystem.metricsystem import MetricSystem
11
6
 
12
- from tomwer.core.scan.hdf5scan import HDF5TomoScan
7
+ from pyunitsystem.energysystem import EnergySI
8
+ from pyunitsystem.metricsystem import MetricSystem
9
+
10
+ from nxtomo.application.nxtomo import NXtomo
11
+ from nxtomo.nxobject.nxdetector import ImageKey, FOV
12
+ from nxtomo.utils.transformation import (
13
+ build_matrix,
14
+ UDDetTransformation,
15
+ LRDetTransformation,
16
+ )
17
+ from nxtomo.nxobject.nxtransformations import NXtransformations
18
+
19
+ from tomwer.core.scan.nxtomoscan import NXtomoScan
13
20
  from tomwer.gui.edit.nxtomoeditor import NXtomoEditor, _TranslationMetricEntry
14
21
  from tomwer.tests.conftest import qtapp # noqa F401
15
22
 
16
23
 
17
24
  @pytest.mark.parametrize("x_pixel_size", (None, 0.12))
18
25
  @pytest.mark.parametrize("y_pixel_size", (None, 0.0065))
19
- @pytest.mark.parametrize("field_of_view", _FOV.values())
26
+ @pytest.mark.parametrize("field_of_view", FOV.values())
20
27
  @pytest.mark.parametrize("distance", (None, 1.2))
21
28
  @pytest.mark.parametrize("energy", (None, 23.5))
22
29
  @pytest.mark.parametrize("x_flipped", (True, False))
@@ -42,14 +49,20 @@ def test_nx_editor(
42
49
  nx_tomo.instrument.detector.y_pixel_size = y_pixel_size
43
50
  nx_tomo.instrument.detector.field_of_view = field_of_view
44
51
  nx_tomo.instrument.detector.distance = distance
45
- nx_tomo.instrument.detector.x_flipped = x_flipped
46
- nx_tomo.instrument.detector.y_flipped = y_flipped
47
52
  nx_tomo.energy = energy
48
53
  nx_tomo.sample.x_translation = x_translation
49
54
  nx_tomo.sample.z_translation = z_translation
50
55
  nx_tomo.instrument.detector.image_key_control = [ImageKey.PROJECTION.value] * 12
51
56
  nx_tomo.instrument.detector.data = numpy.empty(shape=(12, 10, 10))
52
57
  nx_tomo.sample.rotation_angle = numpy.linspace(0, 20, num=12)
58
+ if x_flipped:
59
+ nx_tomo.instrument.detector.transformations.add_transformation(
60
+ LRDetTransformation()
61
+ )
62
+ if y_flipped:
63
+ nx_tomo.instrument.detector.transformations.add_transformation(
64
+ UDDetTransformation()
65
+ )
53
66
 
54
67
  file_path = os.path.join(tmp_path, "nxtomo.nx")
55
68
  entry = "entry0000"
@@ -58,7 +71,7 @@ def test_nx_editor(
58
71
  data_path=entry,
59
72
  )
60
73
 
61
- scan = HDF5TomoScan(file_path, entry)
74
+ scan = NXtomoScan(file_path, entry)
62
75
 
63
76
  # 2.0 create the widget and do the edition
64
77
  widget = NXtomoEditor()
@@ -107,7 +120,7 @@ def test_nx_editor(
107
120
  widget._xPixelSizeMetricEntry.setUnit("nm")
108
121
  widget._yPixelSizeMetricEntry.setValue(2.1e-7)
109
122
  widget._distanceMetricEntry.setValue("unknown")
110
- widget._fieldOfViewCB.setCurrentText(_FOV.HALF.value)
123
+ widget._fieldOfViewCB.setCurrentText(FOV.HALF.value)
111
124
  widget._xFlippedCB.setChecked(not x_flipped)
112
125
  widget._xTranslationQLE.setValue(1.8)
113
126
  widget._xTranslationQLE.setUnit("mm")
@@ -135,10 +148,21 @@ def test_nx_editor(
135
148
  assert overwrite_nx_tomo.instrument.detector.y_pixel_size.value == 2.1e-7
136
149
 
137
150
  assert overwrite_nx_tomo.instrument.detector.distance.value is None
138
- assert overwrite_nx_tomo.instrument.detector.field_of_view is _FOV.HALF
151
+ assert overwrite_nx_tomo.instrument.detector.field_of_view is FOV.HALF
139
152
 
140
- assert overwrite_nx_tomo.instrument.detector.x_flipped is not x_flipped
141
- assert overwrite_nx_tomo.instrument.detector.y_flipped is y_flipped
153
+ final_transformation = NXtransformations()
154
+
155
+ if y_flipped:
156
+ final_transformation.add_transformation(UDDetTransformation())
157
+ if not x_flipped: # as we invert _xFlippedCB combobox
158
+ final_transformation.add_transformation(LRDetTransformation())
159
+
160
+ numpy.testing.assert_allclose(
161
+ build_matrix(
162
+ overwrite_nx_tomo.instrument.detector.transformations.transformations
163
+ ),
164
+ build_matrix(final_transformation.transformations),
165
+ )
142
166
 
143
167
  numpy.testing.assert_array_almost_equal(
144
168
  overwrite_nx_tomo.sample.x_translation.value,
@@ -181,7 +205,7 @@ def test_nx_editor_lock(
181
205
  data_path=entry,
182
206
  )
183
207
 
184
- scan_1 = HDF5TomoScan(file_path, entry)
208
+ scan_1 = NXtomoScan(file_path, entry)
185
209
 
186
210
  nx_tomo_2 = NXtomo()
187
211
  nx_tomo_2.instrument.detector.x_pixel_size = 4.023
@@ -206,7 +230,7 @@ def test_nx_editor_lock(
206
230
  data_path=entry,
207
231
  )
208
232
 
209
- scan_2 = HDF5TomoScan(file_path, entry)
233
+ scan_2 = NXtomoScan(file_path, entry)
210
234
 
211
235
  # 2.0 create the widget and do the edition
212
236
  widget = NXtomoEditor()
File without changes