tomwer 1.3.27__py3-none-any.whl → 1.4.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 (638) hide show
  1. orangecontrib/tomwer/orange/managedprocess.py +1 -29
  2. orangecontrib/tomwer/orange/settings.py +2 -28
  3. orangecontrib/tomwer/tests/TestAcquisition.py +220 -0
  4. orangecontrib/tomwer/tutorials/append_raw_darks_and_flats_frames_to_NXtomos.ows +2 -2
  5. orangecontrib/tomwer/tutorials/copy_reduced_darks_and_flats_meth1.ows +1 -1
  6. orangecontrib/tomwer/tutorials/{icat_publication.ows → drac_publication.ows} +7 -21
  7. orangecontrib/tomwer/tutorials/id16b/ID16b_full_volume.ows +22 -0
  8. orangecontrib/tomwer/tutorials/id16b/ID16b_insitu.ows +302 -0
  9. orangecontrib/tomwer/tutorials/id16b/ID16b_normalization.ows +218 -0
  10. orangecontrib/tomwer/tutorials/simple_volume_to_slurm_reconstruction.ows +29 -24
  11. orangecontrib/tomwer/tutorials/test_cor.ows +19 -0
  12. orangecontrib/tomwer/tutorials/volume_casting_on_slurm.ows +54 -0
  13. orangecontrib/tomwer/widgets/__init__.py +3 -5
  14. orangecontrib/tomwer/widgets/cluster/FutureSupervisorOW.py +35 -54
  15. orangecontrib/tomwer/widgets/cluster/SlurmClusterOW.py +1 -31
  16. orangecontrib/tomwer/widgets/control/AdvancementOW.py +1 -29
  17. orangecontrib/tomwer/widgets/control/DataDiscoveryOW.py +5 -4
  18. orangecontrib/tomwer/widgets/control/DataListenerOW.py +1 -29
  19. orangecontrib/tomwer/widgets/control/DataSelectorOW.py +11 -30
  20. orangecontrib/tomwer/widgets/control/DataTransfertOW.py +2 -28
  21. orangecontrib/tomwer/widgets/control/DataValidatorOW.py +1 -28
  22. orangecontrib/tomwer/widgets/control/DataWatcherOW.py +1 -28
  23. orangecontrib/tomwer/widgets/control/EDF2NXTomomillOW.py +48 -51
  24. orangecontrib/tomwer/widgets/control/EmailOW.py +12 -2
  25. orangecontrib/tomwer/widgets/control/FilterOW.py +1 -28
  26. orangecontrib/tomwer/widgets/control/NXTomomillOW.py +37 -53
  27. orangecontrib/tomwer/widgets/control/NXtomoConcatenate.py +21 -20
  28. orangecontrib/tomwer/widgets/control/NotifierOW.py +9 -28
  29. orangecontrib/tomwer/widgets/control/ReduceDarkFlatSelectorOW.py +3 -2
  30. orangecontrib/tomwer/widgets/control/SingleTomoObjOW.py +1 -27
  31. orangecontrib/tomwer/widgets/control/TimerOW.py +9 -28
  32. orangecontrib/tomwer/widgets/control/TomoObjSeriesOW.py +58 -0
  33. orangecontrib/tomwer/widgets/control/VolumeSelector.py +8 -30
  34. orangecontrib/tomwer/widgets/control/icons/nxtomomill.svg +173 -119
  35. orangecontrib/tomwer/widgets/control/icons/reduced_darkflat_selector.png +0 -0
  36. orangecontrib/tomwer/widgets/control/icons/reduced_darkflat_selector.svg +55 -195
  37. orangecontrib/tomwer/widgets/control/icons/{tomoobjserie.svg → tomoobjseries.svg} +2 -2
  38. orangecontrib/tomwer/widgets/dataportal/PublishProcessedDataOW.py +172 -0
  39. orangecontrib/tomwer/widgets/{icat → dataportal}/__init__.py +2 -2
  40. orangecontrib/tomwer/widgets/debugtools/DatasetGeneratorOW.py +2 -29
  41. orangecontrib/tomwer/widgets/debugtools/ObjectInspectorOW.py +1 -29
  42. orangecontrib/tomwer/widgets/edit/DarkFlatPatchOW.py +48 -73
  43. orangecontrib/tomwer/widgets/edit/ImageKeyEditorOW.py +48 -75
  44. orangecontrib/tomwer/widgets/edit/ImageKeyUpgraderOW.py +5 -30
  45. orangecontrib/tomwer/widgets/edit/NXtomoEditorOW.py +51 -52
  46. orangecontrib/tomwer/widgets/other/PythonScriptOW.py +22 -10
  47. orangecontrib/tomwer/widgets/reconstruction/AxisOW.py +51 -60
  48. orangecontrib/tomwer/widgets/reconstruction/CastNabuVolumeOW.py +22 -68
  49. orangecontrib/tomwer/widgets/reconstruction/DarkRefAndCopyOW.py +3 -30
  50. orangecontrib/tomwer/widgets/reconstruction/NabuHelicalPrepareWeightsDoubleOW.py +21 -19
  51. orangecontrib/tomwer/widgets/reconstruction/NabuOW.py +7 -70
  52. orangecontrib/tomwer/widgets/reconstruction/NabuVolumeOW.py +41 -84
  53. orangecontrib/tomwer/widgets/reconstruction/SAAxisOW.py +15 -40
  54. orangecontrib/tomwer/widgets/reconstruction/SADeltaBetaOW.py +13 -35
  55. orangecontrib/tomwer/widgets/reconstruction/SinoNormOW.py +2 -30
  56. orangecontrib/tomwer/widgets/stitching/ZStitchingConfigOW.py +11 -11
  57. orangecontrib/tomwer/widgets/utils.py +2 -29
  58. orangecontrib/tomwer/widgets/visualization/DataViewerOW.py +1 -27
  59. orangecontrib/tomwer/widgets/visualization/DiffViewerOW.py +1 -27
  60. orangecontrib/tomwer/widgets/visualization/NXtomoMetadataViewerOW.py +1 -1
  61. orangecontrib/tomwer/widgets/visualization/RadioStackOW.py +2 -28
  62. orangecontrib/tomwer/widgets/visualization/SampleMovedOW.py +1 -27
  63. orangecontrib/tomwer/widgets/visualization/SinogramViewerOW.py +1 -27
  64. orangecontrib/tomwer/widgets/visualization/SliceStackOW.py +2 -28
  65. tomwer/__init__.py +3 -28
  66. tomwer/__main__.py +8 -4
  67. tomwer/app/__init__.py +2 -0
  68. tomwer/app/axis.py +8 -10
  69. tomwer/app/canvas.py +23 -29
  70. tomwer/app/canvas_launcher/config.py +14 -102
  71. tomwer/app/canvas_launcher/environ.py +5 -8
  72. tomwer/app/canvas_launcher/mainwindow.py +175 -69
  73. tomwer/app/canvas_launcher/splash.py +1 -3
  74. tomwer/app/canvas_launcher/utils.py +47 -0
  75. tomwer/app/canvas_launcher/widgetsscheme.py +3 -10
  76. tomwer/app/diffframe.py +2 -0
  77. tomwer/app/imagekeyeditor.py +2 -1
  78. tomwer/app/imagekeyupgrader.py +2 -0
  79. tomwer/app/multicor.py +5 -2
  80. tomwer/app/multipag.py +16 -5
  81. tomwer/app/nabuapp.py +2 -1
  82. tomwer/app/nxtomoeditor.py +17 -12
  83. tomwer/app/patchrawdarkflat.py +2 -0
  84. tomwer/app/radiostack.py +3 -2
  85. tomwer/app/reducedarkflat.py +3 -0
  86. tomwer/app/samplemoved.py +2 -0
  87. tomwer/app/scanviewer.py +2 -0
  88. tomwer/app/sinogramviewer.py +2 -0
  89. tomwer/app/slicestack.py +11 -13
  90. tomwer/app/stitching/common.py +431 -0
  91. tomwer/app/stopdatalistener.py +3 -0
  92. tomwer/app/ystitching.py +26 -0
  93. tomwer/app/zstitching.py +8 -363
  94. tomwer/core/__init__.py +2 -28
  95. tomwer/core/cluster/__init__.py +3 -0
  96. tomwer/core/cluster/cluster.py +10 -26
  97. tomwer/core/futureobject.py +17 -43
  98. tomwer/core/log/__init__.py +2 -0
  99. tomwer/core/log/processlog.py +0 -28
  100. tomwer/core/process/cluster/supervisor.py +52 -34
  101. tomwer/core/process/conditions/filters.py +3 -28
  102. tomwer/core/process/control/datalistener/datalistener.py +7 -75
  103. tomwer/core/process/control/datalistener/rpcserver.py +8 -38
  104. tomwer/core/process/control/datawatcher/datawatcher.py +11 -40
  105. tomwer/core/process/control/datawatcher/datawatcherobserver.py +30 -64
  106. tomwer/core/process/control/datawatcher/datawatcherprocess.py +11 -32
  107. tomwer/core/process/control/datawatcher/edfdwprocess.py +2 -27
  108. tomwer/core/process/control/datawatcher/hdf5dwprocess.py +1 -26
  109. tomwer/core/process/control/datawatcher/status.py +1 -26
  110. tomwer/core/process/control/emailnotifier.py +11 -23
  111. tomwer/core/process/control/nxtomoconcatenate.py +20 -18
  112. tomwer/core/process/control/nxtomomill.py +9 -44
  113. tomwer/core/process/control/scanlist.py +0 -27
  114. tomwer/core/process/control/scantransfer.py +15 -13
  115. tomwer/core/process/control/scanvalidator.py +4 -30
  116. tomwer/core/process/control/{test → tests}/test_concatenate_nxtomos.py +5 -5
  117. tomwer/core/process/control/timer.py +1 -27
  118. tomwer/core/process/control/tomoobjseries.py +12 -0
  119. tomwer/core/process/drac/binning.py +37 -0
  120. tomwer/core/process/drac/dracbase.py +170 -0
  121. tomwer/core/process/drac/gallery.py +109 -0
  122. tomwer/core/process/drac/output.py +12 -0
  123. tomwer/core/process/drac/processeddataset.py +147 -0
  124. tomwer/core/process/drac/publish.py +118 -0
  125. tomwer/core/process/drac/rawdataset.py +142 -0
  126. tomwer/core/process/drac/tests/test_gallery.py +71 -0
  127. tomwer/core/process/drac/tests/test_icat_processed_dataset.py +80 -0
  128. tomwer/core/process/drac/tests/test_icat_raw_dataset.py +90 -0
  129. tomwer/core/process/edit/darkflatpatch.py +1 -28
  130. tomwer/core/process/edit/imagekeyeditor.py +4 -32
  131. tomwer/core/process/edit/nxtomoeditor.py +307 -0
  132. tomwer/core/process/edit/tests/test_darkflatpatch.py +243 -0
  133. tomwer/core/process/edit/tests/test_imagekey_editor.py +99 -0
  134. tomwer/core/process/output.py +9 -2
  135. tomwer/core/process/reconstruction/__init__.py +0 -26
  136. tomwer/core/process/reconstruction/axis/anglemode.py +1 -29
  137. tomwer/core/process/reconstruction/axis/axis.py +47 -804
  138. tomwer/core/process/reconstruction/axis/mode.py +89 -25
  139. tomwer/core/process/reconstruction/axis/params.py +131 -283
  140. tomwer/core/process/reconstruction/axis/projectiontype.py +0 -28
  141. tomwer/core/process/reconstruction/axis/side.py +8 -0
  142. tomwer/core/process/reconstruction/darkref/darkrefs.py +14 -39
  143. tomwer/core/process/reconstruction/darkref/darkrefscopy.py +7 -39
  144. tomwer/core/process/reconstruction/darkref/params.py +1 -28
  145. tomwer/core/process/reconstruction/nabu/castvolume.py +19 -34
  146. tomwer/core/process/reconstruction/nabu/nabucommon.py +18 -43
  147. tomwer/core/process/reconstruction/nabu/nabuscores.py +64 -68
  148. tomwer/core/process/reconstruction/nabu/nabuslices.py +63 -105
  149. tomwer/core/process/reconstruction/nabu/nabuvolume.py +44 -70
  150. tomwer/core/process/reconstruction/nabu/plane.py +10 -0
  151. tomwer/core/process/reconstruction/nabu/settings.py +1 -28
  152. tomwer/core/process/reconstruction/nabu/target.py +0 -28
  153. tomwer/core/process/reconstruction/nabu/test/test_castvolume.py +116 -0
  154. tomwer/core/process/reconstruction/nabu/test/test_nabu_utils.py +277 -0
  155. tomwer/core/process/reconstruction/nabu/test/test_nabunormalization.py +199 -0
  156. tomwer/core/process/reconstruction/nabu/utils.py +11 -60
  157. tomwer/core/process/reconstruction/normalization/normalization.py +2 -32
  158. tomwer/core/process/reconstruction/normalization/params.py +3 -35
  159. tomwer/core/process/reconstruction/output.py +14 -19
  160. tomwer/core/process/reconstruction/paramsbase.py +4 -33
  161. tomwer/core/process/reconstruction/saaxis/params.py +5 -33
  162. tomwer/core/process/reconstruction/saaxis/saaxis.py +22 -51
  163. tomwer/core/process/reconstruction/sadeltabeta/params.py +2 -31
  164. tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py +18 -46
  165. tomwer/core/process/reconstruction/scores/params.py +9 -39
  166. tomwer/core/process/reconstruction/scores/scores.py +10 -42
  167. tomwer/core/process/reconstruction/tests/__init__.py +0 -0
  168. tomwer/core/process/reconstruction/tests/test_axis.py +46 -0
  169. tomwer/core/process/reconstruction/tests/test_darkref.py +33 -0
  170. tomwer/core/process/reconstruction/{test → tests}/test_saaxis.py +1 -27
  171. tomwer/core/process/reconstruction/tests/test_sadeltabeta.py +48 -0
  172. tomwer/core/process/reconstruction/{test → tests}/test_utils.py +4 -4
  173. tomwer/core/process/reconstruction/utils/cor.py +8 -4
  174. tomwer/core/process/script/python.py +1 -27
  175. tomwer/core/process/script/tests/test_script.py +41 -0
  176. tomwer/core/process/stitching/metadataholder.py +5 -4
  177. tomwer/core/process/stitching/nabustitcher.py +35 -5
  178. tomwer/core/process/stitching/tests/test_metadataholder.py +17 -0
  179. tomwer/core/process/task.py +20 -63
  180. tomwer/core/process/tests/__init__.py +0 -0
  181. tomwer/core/process/{test → tests}/test_conditions.py +1 -28
  182. tomwer/core/process/{test → tests}/test_dark_and_flat.py +1 -27
  183. tomwer/core/process/{test → tests}/test_data_listener.py +1 -27
  184. tomwer/core/process/{test → tests}/test_data_transfer.py +2 -28
  185. tomwer/core/process/{test → tests}/test_data_watcher.py +1 -27
  186. tomwer/core/process/{test → tests}/test_nabu.py +2 -33
  187. tomwer/core/process/{test → tests}/test_normalization.py +1 -26
  188. tomwer/core/process/{test → tests}/test_timer.py +1 -27
  189. tomwer/core/process/utils.py +2 -31
  190. tomwer/core/process/visualization/dataviewer.py +1 -26
  191. tomwer/core/process/visualization/diffviewer.py +1 -26
  192. tomwer/core/process/visualization/imagestackviewer.py +0 -26
  193. tomwer/core/process/visualization/radiostack.py +0 -26
  194. tomwer/core/process/visualization/samplemoved.py +0 -28
  195. tomwer/core/process/visualization/sinogramviewer.py +0 -27
  196. tomwer/core/process/visualization/slicestack.py +0 -28
  197. tomwer/core/process/visualization/tests/test_data_viewer.py +12 -0
  198. tomwer/core/process/visualization/tests/test_diff_viewer.py +12 -0
  199. tomwer/core/process/visualization/tests/test_image_stack_viewer.py +14 -0
  200. tomwer/core/process/visualization/tests/test_radio_stack.py +12 -0
  201. tomwer/core/process/visualization/tests/test_sample_moved.py +14 -0
  202. tomwer/core/process/visualization/tests/test_sinogram_viewer.py +13 -0
  203. tomwer/core/process/visualization/tests/test_slice_stack.py +13 -0
  204. tomwer/core/process/visualization/tests/test_volume_viewer.py +12 -0
  205. tomwer/core/process/visualization/volumeviewer.py +0 -29
  206. tomwer/core/scan/__init__.py +3 -27
  207. tomwer/core/scan/blissscan.py +5 -34
  208. tomwer/core/scan/edfscan.py +19 -53
  209. tomwer/core/scan/hdf5scan.py +2 -2
  210. tomwer/core/scan/nxtomoscan.py +48 -54
  211. tomwer/core/scan/scanbase.py +107 -203
  212. tomwer/core/scan/scanfactory.py +11 -41
  213. tomwer/core/scan/tests/__init__.py +0 -0
  214. tomwer/core/scan/tests/test_edf.py +25 -0
  215. tomwer/core/scan/tests/test_future_scan.py +35 -0
  216. tomwer/core/scan/tests/test_nxtomoscan.py +143 -0
  217. tomwer/core/scan/tests/test_process_registration.py +64 -0
  218. tomwer/core/settings.py +18 -40
  219. tomwer/core/tests/__init__.py +0 -0
  220. tomwer/core/tests/test_scanutils.py +26 -0
  221. tomwer/core/{test → tests}/test_utils.py +1 -28
  222. tomwer/core/tomwer_object.py +4 -0
  223. tomwer/core/utils/__init__.py +2 -0
  224. tomwer/core/utils/char.py +0 -28
  225. tomwer/core/utils/deprecation.py +12 -38
  226. tomwer/core/utils/dictutils.py +1 -3
  227. tomwer/core/utils/ftseriesutils.py +1 -27
  228. tomwer/core/utils/gpu.py +0 -28
  229. tomwer/core/utils/image.py +8 -39
  230. tomwer/core/utils/locker.py +1 -28
  231. tomwer/core/utils/logconfig.py +0 -27
  232. tomwer/core/utils/normalization.py +4 -31
  233. tomwer/core/utils/nxtomoutils.py +8 -38
  234. tomwer/core/utils/resource.py +0 -26
  235. tomwer/core/utils/scanutils.py +23 -52
  236. tomwer/core/utils/slurm.py +7 -30
  237. tomwer/core/utils/spec.py +6 -6
  238. tomwer/core/utils/tests/__init__.py +0 -0
  239. tomwer/core/utils/tests/test_image.py +30 -0
  240. tomwer/core/utils/tests/test_nxtomo.py +38 -0
  241. tomwer/core/utils/tests/test_scan_utils.py +46 -0
  242. tomwer/core/utils/tests/test_time.py +6 -0
  243. tomwer/core/utils/threads.py +0 -26
  244. tomwer/core/utils/time.py +0 -27
  245. tomwer/core/volume/__init__.py +4 -0
  246. tomwer/core/volume/edfvolume.py +1 -28
  247. tomwer/core/volume/hdf5volume.py +1 -28
  248. tomwer/core/volume/jp2kvolume.py +1 -27
  249. tomwer/core/volume/rawvolume.py +1 -28
  250. tomwer/core/volume/tests/test_volumes.py +21 -0
  251. tomwer/core/volume/tiffvolume.py +1 -28
  252. tomwer/core/volume/volumebase.py +5 -0
  253. tomwer/core/volume/volumefactory.py +7 -33
  254. tomwer/gui/__init__.py +0 -28
  255. tomwer/gui/cluster/__init__.py +2 -0
  256. tomwer/gui/cluster/slurm.py +297 -95
  257. tomwer/gui/cluster/supervisor.py +1 -27
  258. tomwer/gui/cluster/tests/__init__.py +0 -0
  259. tomwer/gui/cluster/{test → tests}/test_cluster.py +21 -26
  260. tomwer/gui/cluster/{test → tests}/test_supervisor.py +1 -27
  261. tomwer/gui/conditions/__init__.py +2 -0
  262. tomwer/gui/conditions/filter.py +1 -26
  263. tomwer/gui/configuration/__init__.py +2 -0
  264. tomwer/gui/control/__init__.py +2 -0
  265. tomwer/gui/control/actions.py +2 -28
  266. tomwer/gui/control/datadiscovery.py +4 -3
  267. tomwer/gui/control/datalist.py +64 -69
  268. tomwer/gui/control/datalistener.py +1 -39
  269. tomwer/gui/control/datareacheractions.py +1 -28
  270. tomwer/gui/control/datatransfert.py +2 -29
  271. tomwer/gui/control/datavalidator.py +3 -37
  272. tomwer/gui/control/datawatcher/__init__.py +0 -28
  273. tomwer/gui/control/datawatcher/configuration.py +1 -28
  274. tomwer/gui/control/datawatcher/datawatcher.py +3 -32
  275. tomwer/gui/control/datawatcher/datawatcherobserver.py +2 -28
  276. tomwer/gui/control/history.py +5 -35
  277. tomwer/gui/control/nxtomomill.py +3 -30
  278. tomwer/gui/control/observations.py +61 -55
  279. tomwer/gui/control/reducedarkflatselector.py +24 -20
  280. tomwer/gui/control/scanselectorwidget.py +2 -28
  281. tomwer/gui/control/selectorwidgetbase.py +17 -17
  282. tomwer/gui/control/series/__init__.py +0 -0
  283. tomwer/gui/control/{serie/seriecreator.py → series/seriescreator.py} +214 -235
  284. tomwer/gui/control/series/serieswaiter.py +0 -0
  285. tomwer/gui/control/series/test/test_creator.py +424 -0
  286. tomwer/gui/control/series/test/test_nxtomo_concatenate.py +21 -0
  287. tomwer/gui/control/singletomoobj.py +1 -1
  288. tomwer/gui/control/tests/__init__.py +0 -0
  289. tomwer/gui/control/tests/test_datalist.py +47 -0
  290. tomwer/gui/control/{test → tests}/test_datalistener.py +1 -28
  291. tomwer/gui/control/tests/test_datavalidator.py +27 -0
  292. tomwer/gui/control/{test → tests}/test_inputwidget.py +1 -27
  293. tomwer/gui/control/tests/test_process_manager.py +38 -0
  294. tomwer/gui/control/tests/test_scan_observations.py +23 -0
  295. tomwer/gui/control/tests/test_scanselector.py +42 -0
  296. tomwer/gui/control/{test → tests}/test_scanvalidator.py +1 -27
  297. tomwer/gui/control/{test → tests}/test_volume_dialog.py +2 -30
  298. tomwer/gui/control/{test → tests}/test_volumeselector.py +1 -27
  299. tomwer/gui/control/volumeselectorwidget.py +2 -30
  300. tomwer/gui/dataportal/__init__.py +2 -0
  301. tomwer/gui/{icat → dataportal}/createscreenshots.py +3 -2
  302. tomwer/gui/dataportal/gallery.py +133 -0
  303. tomwer/gui/dataportal/outputformat.py +0 -0
  304. tomwer/gui/dataportal/publish.py +96 -0
  305. tomwer/gui/dataportal/tests/test_create_screenshots_gui.py +23 -0
  306. tomwer/gui/dataportal/tests/test_gallery_gui.py +21 -0
  307. tomwer/gui/debugtools/__init__.py +2 -0
  308. tomwer/gui/debugtools/datasetgenerator.py +1 -30
  309. tomwer/gui/debugtools/objectinspector.py +1 -29
  310. tomwer/gui/dialog/QDataDialog.py +89 -0
  311. tomwer/gui/{qfolderdialog.py → dialog/QVolumeDialog.py} +8 -107
  312. tomwer/gui/dialog/__init__.py +1 -0
  313. tomwer/gui/edit/__init__.py +2 -0
  314. tomwer/gui/edit/dkrfpatch.py +52 -87
  315. tomwer/gui/edit/imagekeyeditor.py +18 -54
  316. tomwer/gui/edit/nxtomoeditor.py +113 -300
  317. tomwer/gui/edit/nxtomowarmer.py +3 -2
  318. tomwer/gui/edit/tests/__init__.py +0 -0
  319. tomwer/gui/edit/{test → tests}/test_dkrf_patch.py +3 -29
  320. tomwer/gui/edit/{test → tests}/test_image_key_editor.py +1 -27
  321. tomwer/gui/edit/{test → tests}/test_nx_editor.py +45 -23
  322. tomwer/gui/fonts.py +5 -0
  323. tomwer/gui/icons.py +28 -66
  324. tomwer/gui/illustrations.py +4 -34
  325. tomwer/gui/imagefromfile.py +5 -30
  326. tomwer/gui/metadataloader.py +36 -0
  327. tomwer/gui/qconfigfile.py +3 -0
  328. tomwer/gui/qlefilesystem.py +3 -0
  329. tomwer/gui/reconstruction/__init__.py +2 -0
  330. tomwer/gui/reconstruction/axis/AxisMainWindow.py +275 -0
  331. tomwer/gui/reconstruction/axis/AxisOptionsWidget.py +313 -0
  332. tomwer/gui/reconstruction/axis/AxisSettingsWidget.py +797 -0
  333. tomwer/gui/reconstruction/axis/AxisWidget.py +534 -0
  334. tomwer/gui/reconstruction/axis/CalculationWidget.py +218 -0
  335. tomwer/gui/reconstruction/axis/CompareImages.py +11 -44
  336. tomwer/gui/reconstruction/axis/ControlWidget.py +285 -0
  337. tomwer/gui/reconstruction/axis/EstimatedCORWidget.py +394 -0
  338. tomwer/gui/reconstruction/axis/EstimatedCorComboBox.py +118 -0
  339. tomwer/gui/reconstruction/axis/InputWidget.py +347 -0
  340. tomwer/gui/reconstruction/axis/ManualFramesSelection.py +168 -0
  341. tomwer/gui/reconstruction/axis/__init__.py +2 -2
  342. tomwer/gui/reconstruction/darkref/__init__.py +0 -27
  343. tomwer/gui/reconstruction/darkref/darkrefcopywidget.py +5 -34
  344. tomwer/gui/reconstruction/darkref/darkrefwidget.py +1 -27
  345. tomwer/gui/reconstruction/nabu/castvolume.py +40 -59
  346. tomwer/gui/reconstruction/nabu/check.py +7 -33
  347. tomwer/gui/reconstruction/nabu/nabuconfig/base.py +7 -34
  348. tomwer/gui/reconstruction/nabu/nabuconfig/ctf.py +6 -5
  349. tomwer/gui/reconstruction/nabu/nabuconfig/nabuconfig.py +10 -69
  350. tomwer/gui/reconstruction/nabu/nabuconfig/output.py +3 -47
  351. tomwer/gui/reconstruction/nabu/nabuconfig/phase.py +54 -36
  352. tomwer/gui/reconstruction/nabu/nabuconfig/preprocessing.py +103 -54
  353. tomwer/gui/reconstruction/nabu/nabuconfig/reconstruction.py +116 -65
  354. tomwer/gui/reconstruction/nabu/nabuflow.py +31 -61
  355. tomwer/gui/reconstruction/nabu/platform.py +94 -0
  356. tomwer/gui/reconstruction/nabu/slices.py +81 -45
  357. tomwer/gui/reconstruction/nabu/slurm.py +1 -27
  358. tomwer/gui/reconstruction/nabu/test/test_cast_volume.py +82 -0
  359. tomwer/gui/reconstruction/nabu/test/test_check.py +66 -0
  360. tomwer/gui/reconstruction/nabu/test/test_ctf.py +46 -0
  361. tomwer/gui/reconstruction/nabu/test/test_helical.py +21 -0
  362. tomwer/gui/reconstruction/nabu/test/test_nabu_preprocessing.py +81 -0
  363. tomwer/gui/reconstruction/nabu/volume.py +62 -90
  364. tomwer/gui/reconstruction/normalization/intensity.py +5 -32
  365. tomwer/gui/reconstruction/normalization/test/test_intensity.py +89 -0
  366. tomwer/gui/reconstruction/saaxis/corrangeselector.py +32 -56
  367. tomwer/gui/reconstruction/saaxis/dimensionwidget.py +56 -96
  368. tomwer/gui/reconstruction/saaxis/saaxis.py +17 -38
  369. tomwer/gui/reconstruction/saaxis/sliceselector.py +8 -39
  370. tomwer/gui/reconstruction/sadeltabeta/saadeltabeta.py +19 -37
  371. tomwer/gui/reconstruction/scores/control.py +2 -30
  372. tomwer/gui/reconstruction/scores/scoreplot.py +23 -49
  373. tomwer/gui/reconstruction/tests/__init__.py +0 -0
  374. tomwer/gui/reconstruction/{test → tests}/test_axis.py +23 -49
  375. tomwer/gui/reconstruction/{test → tests}/test_nabu.py +16 -31
  376. tomwer/gui/reconstruction/{test → tests}/test_saaxis.py +10 -37
  377. tomwer/gui/reconstruction/{test → tests}/test_sadeltabeta.py +1 -26
  378. tomwer/gui/samplemoved/__init__.py +2 -30
  379. tomwer/gui/samplemoved/selectiontable.py +3 -33
  380. tomwer/gui/settings.py +7 -0
  381. tomwer/gui/stackplot.py +33 -661
  382. tomwer/gui/stacks.py +261 -135
  383. tomwer/gui/stitching/SingleAxisStitchingWidget.py +326 -0
  384. tomwer/gui/stitching/StitchingOptionsWidget.py +438 -0
  385. tomwer/gui/stitching/StitchingWindow.py +586 -0
  386. tomwer/gui/stitching/__init__.py +2 -0
  387. tomwer/gui/stitching/alignment.py +90 -0
  388. tomwer/gui/stitching/axisorderedlist.py +44 -34
  389. tomwer/gui/stitching/config/axisparams.py +25 -11
  390. tomwer/gui/stitching/config/output.py +6 -5
  391. tomwer/gui/stitching/config/positionoveraxis.py +313 -51
  392. tomwer/gui/stitching/config/stitchingstrategies.py +22 -16
  393. tomwer/gui/stitching/config/tests/test_axisparams.py +25 -0
  394. tomwer/gui/stitching/config/tomoobjdetails.py +3 -5
  395. tomwer/gui/stitching/normalization.py +1 -0
  396. tomwer/gui/stitching/preview.py +59 -0
  397. tomwer/gui/stitching/singleaxis.py +57 -0
  398. tomwer/gui/stitching/stitchandbackground.py +3 -2
  399. tomwer/gui/stitching/stitching_preview.py +44 -36
  400. tomwer/gui/stitching/stitching_raw.py +5 -3
  401. tomwer/gui/stitching/tests/test_ZStitchingWindow.py +88 -0
  402. tomwer/gui/stitching/tests/test_axis_ordered_list.py +21 -0
  403. tomwer/gui/stitching/tests/test_normalization.py +27 -0
  404. tomwer/gui/stitching/tests/test_preview.py +68 -0
  405. tomwer/gui/stitching/tests/test_stitching_raw.py +110 -0
  406. tomwer/gui/stitching/tests/utils.py +92 -0
  407. tomwer/gui/stitching/utils.py +14 -0
  408. tomwer/gui/stitching/z_stitching/fineestimation.py +5 -33
  409. tomwer/gui/stitching/z_stitching/tests/test_fine_estimation.py +35 -0
  410. tomwer/gui/stitching/z_stitching/tests/test_raw_estimation.py +215 -0
  411. tomwer/gui/stitching/z_stitching/tests/test_stitching_window.py +51 -0
  412. tomwer/gui/tests/__init__.py +0 -0
  413. tomwer/gui/tests/test_axis_gui.py +43 -0
  414. tomwer/gui/{test → tests}/test_qfolder_dialog.py +1 -1
  415. tomwer/gui/utils/RangeWidget.py +44 -0
  416. tomwer/gui/utils/buttons.py +4 -3
  417. tomwer/gui/utils/completer.py +2 -33
  418. tomwer/gui/utils/flow.py +11 -40
  419. tomwer/gui/utils/gpu.py +60 -0
  420. tomwer/gui/utils/illustrations.py +1 -26
  421. tomwer/gui/utils/inputwidget.py +35 -73
  422. tomwer/gui/utils/lineselector/lineselector.py +9 -46
  423. tomwer/gui/utils/loadingmode.py +81 -0
  424. tomwer/gui/utils/qt_utils.py +9 -0
  425. tomwer/gui/utils/sandboxes.py +1 -26
  426. tomwer/gui/utils/scandescription.py +2 -31
  427. tomwer/gui/utils/scrollarea.py +6 -55
  428. tomwer/gui/utils/slider.py +4 -28
  429. tomwer/gui/utils/splashscreen.py +0 -28
  430. tomwer/gui/utils/step.py +14 -13
  431. tomwer/gui/utils/tests/test_completer.py +41 -0
  432. tomwer/gui/utils/tests/test_line_selector.py +21 -0
  433. tomwer/gui/utils/tests/test_splashscreen.py +8 -0
  434. tomwer/gui/utils/tests/test_vignettes.py +68 -0
  435. tomwer/gui/utils/unitsystem.py +15 -69
  436. tomwer/gui/utils/utils.py +4 -5
  437. tomwer/gui/utils/vignettes.py +10 -41
  438. tomwer/gui/utils/waiterthread.py +0 -26
  439. tomwer/gui/visualization/__init__.py +2 -0
  440. tomwer/gui/visualization/dataviewer.py +68 -421
  441. tomwer/gui/visualization/diffviewer/diffviewer.py +2 -30
  442. tomwer/gui/visualization/diffviewer/shiftwidget.py +4 -29
  443. tomwer/gui/visualization/fullscreenplot.py +5 -5
  444. tomwer/gui/visualization/imagestack.py +403 -0
  445. tomwer/gui/visualization/nxtomometadata.py +0 -4
  446. tomwer/gui/visualization/reconstructionparameters.py +14 -32
  447. tomwer/gui/visualization/scanoverview.py +33 -66
  448. tomwer/gui/visualization/sinogramviewer.py +2 -28
  449. tomwer/gui/visualization/test/__init__.py +0 -28
  450. tomwer/gui/visualization/test/test_dataviewer.py +1 -28
  451. tomwer/gui/visualization/test/test_diffviewer.py +1 -28
  452. tomwer/gui/visualization/test/test_nx_tomo_metadata_viewer.py +0 -5
  453. tomwer/gui/visualization/test/test_reconstruction_parameters.py +1 -27
  454. tomwer/gui/visualization/test/test_sinogramviewer.py +1 -28
  455. tomwer/gui/visualization/test/test_stacks.py +184 -115
  456. tomwer/gui/visualization/test/test_volumeviewer.py +3 -2
  457. tomwer/gui/visualization/tomoobjoverview.py +2 -2
  458. tomwer/gui/visualization/volumeoverview.py +3 -2
  459. tomwer/gui/visualization/volumeviewer.py +47 -43
  460. tomwer/io/__init__.py +2 -0
  461. tomwer/io/utils/h5pyutils.py +1 -27
  462. tomwer/io/utils/test/test_raw_and_processed_data.py +10 -0
  463. tomwer/io/utils/test/test_utils.py +67 -0
  464. tomwer/io/utils/utils.py +2 -31
  465. tomwer/resources/__init__.py +13 -33
  466. tomwer/resources/gui/icons/edit_downstream.svg +114 -0
  467. tomwer/resources/gui/icons/edit_upstream.svg +112 -0
  468. tomwer/resources/gui/icons/free_edition.svg +23 -0
  469. tomwer/resources/gui/icons/icat_gallery_opts.png +0 -0
  470. tomwer/resources/gui/icons/icat_gallery_opts.svg +80 -0
  471. tomwer/resources/gui/icons/search.png +0 -0
  472. tomwer/resources/gui/icons/search.svg +23 -0
  473. tomwer/resources/gui/icons/warning.png +0 -0
  474. tomwer/synctools/__init__.py +2 -0
  475. tomwer/synctools/axis.py +1 -27
  476. tomwer/synctools/darkref.py +1 -26
  477. tomwer/synctools/datalistener.py +1 -27
  478. tomwer/synctools/datatransfert.py +2 -27
  479. tomwer/synctools/imageloaderthread.py +1 -28
  480. tomwer/synctools/rsyncmanager.py +1 -25
  481. tomwer/synctools/saaxis.py +1 -26
  482. tomwer/synctools/sadeltabeta.py +1 -26
  483. tomwer/synctools/stacks/control/datalistener.py +1 -26
  484. tomwer/synctools/stacks/processingstack.py +4 -33
  485. tomwer/synctools/stacks/reconstruction/axis.py +6 -53
  486. tomwer/synctools/stacks/reconstruction/castvolume.py +12 -43
  487. tomwer/synctools/stacks/reconstruction/dkrefcopy.py +4 -27
  488. tomwer/synctools/stacks/reconstruction/nabu.py +3 -28
  489. tomwer/synctools/stacks/reconstruction/normalization.py +2 -27
  490. tomwer/synctools/stacks/reconstruction/saaxis.py +2 -27
  491. tomwer/synctools/stacks/reconstruction/sadeltabeta.py +2 -27
  492. tomwer/synctools/tests/__init__.py +0 -0
  493. tomwer/synctools/{test → tests}/test_darkRefs.py +16 -40
  494. tomwer/synctools/{test → tests}/test_foldertransfer.py +2 -33
  495. tomwer/synctools/utils/scanstages.py +2 -31
  496. tomwer/tests/__init__.py +1 -0
  497. tomwer/tests/app/test_stitching.py +95 -0
  498. tomwer/tests/datasets.py +1 -5
  499. tomwer/tests/orangecontrib/tomwer/widgets/cluster/tests/test_future_supervisorow.py +48 -0
  500. tomwer/tests/orangecontrib/tomwer/widgets/cluster/tests/test_slurm_clusterow.py +40 -0
  501. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_advancement.py +8 -0
  502. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_data_validator.py +55 -0
  503. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_datadiscovery.py +129 -0
  504. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_datalistener.py +111 -0
  505. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_dataselector.py +69 -0
  506. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_datawatcher.py +411 -0
  507. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_emailow.py +29 -0
  508. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_notifier.py +24 -0
  509. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_nxtomo_concatenate_ow.py +64 -0
  510. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_nxtomomill.py +133 -0
  511. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_reduce_dark_flat_selector.py +40 -0
  512. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_singletomoobj.py +40 -0
  513. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_timerow.py +25 -0
  514. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_tomoobj_series.py +96 -0
  515. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_volume_selector.py +69 -0
  516. orangecontrib/tomwer/widgets/edit/test/test_image_key_editor.py → tomwer/tests/orangecontrib/tomwer/widgets/debugtools/tests/test_dataset_generator.py +17 -16
  517. tomwer/tests/orangecontrib/tomwer/widgets/debugtools/tests/test_object_inspector.py +36 -0
  518. {orangecontrib/tomwer/widgets/edit/test → tomwer/tests/orangecontrib/tomwer/widgets/edit/tests}/test_dark_flat_patch.py +1 -27
  519. tomwer/tests/orangecontrib/tomwer/widgets/edit/tests/test_image_key_editor.py +30 -0
  520. tomwer/tests/orangecontrib/tomwer/widgets/edit/tests/test_nxtomo_editor.py +138 -0
  521. tomwer/tests/orangecontrib/tomwer/widgets/other/tests/test_pythonscript.py +31 -0
  522. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_axis.py +199 -0
  523. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_cast_volumeow.py +58 -0
  524. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_dark_refs_widget.py +136 -0
  525. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_delta_beta_selector.py +15 -0
  526. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_i_norm.py +200 -0
  527. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_nabu_helical_prepare_weights_double.py +20 -0
  528. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_nabu_volume.py +74 -0
  529. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_nabu_widget.py +107 -0
  530. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_sa_delta_beta.py +194 -0
  531. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_saaxis.py +194 -0
  532. tomwer/tests/orangecontrib/tomwer/widgets/stitching/tests/test_zstitching.py +313 -0
  533. tomwer/tests/orangecontrib/tomwer/widgets/tests/test_conditions.py +85 -0
  534. tomwer/tests/orangecontrib/tomwer/widgets/tests/test_darkref.py +225 -0
  535. tomwer/tests/orangecontrib/tomwer/widgets/tests/test_foldertransfert.py +105 -0
  536. tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_dataviewerow.py +57 -0
  537. tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_diffviewerow.py +39 -0
  538. tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_nxtomo_metadata_viewer.py +29 -0
  539. tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_radio_stackow.py +31 -0
  540. tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_sample_movedow.py +46 -0
  541. tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_sinogram_viewerow.py +31 -0
  542. tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_slice_stackow.py +31 -0
  543. tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_volume_viewerow.py +32 -0
  544. tomwer/tests/test_ewoks/test_conversion.py +104 -0
  545. tomwer/tests/test_ewoks/test_single_node_execution.py +87 -0
  546. tomwer/tests/test_ewoks/test_workflows.py +138 -0
  547. tomwer/utils.py +11 -39
  548. tomwer/version.py +2 -2
  549. {tomwer-1.3.27.dist-info → tomwer-1.4.0.dist-info}/LICENSE +3 -3
  550. tomwer-1.4.0.dist-info/METADATA +337 -0
  551. tomwer-1.4.0.dist-info/RECORD +912 -0
  552. {tomwer-1.3.27.dist-info → tomwer-1.4.0.dist-info}/WHEEL +1 -1
  553. {tomwer-1.3.27.dist-info → tomwer-1.4.0.dist-info}/entry_points.txt +1 -0
  554. orangecontrib/tomwer/widgets/control/DataListOW.py +0 -129
  555. orangecontrib/tomwer/widgets/control/TomoObjSerieOW.py +0 -86
  556. orangecontrib/tomwer/widgets/control/VolumeSymLinkOW.py +0 -182
  557. orangecontrib/tomwer/widgets/edit/test/test_nxtomo_editor.py +0 -141
  558. orangecontrib/tomwer/widgets/icat/PublishProcessedDataOW.py +0 -115
  559. orangecontrib/tomwer/widgets/icat/RawDataScreenshotCreatorOW.py +0 -98
  560. orangecontrib/tomwer/widgets/icat/SaveToGalleryAndPublishOW.py +0 -129
  561. orangecontrib/tomwer/widgets/icat/icons/add_gallery.png +0 -0
  562. orangecontrib/tomwer/widgets/icat/icons/add_gallery.svg +0 -82
  563. orangecontrib/tomwer/widgets/icat/icons/raw_screenshots.png +0 -0
  564. orangecontrib/tomwer/widgets/icat/icons/raw_screenshots.svg +0 -143
  565. orangecontrib/tomwer/widgets/visualization/LivesliceOW.py +0 -87
  566. orangecontrib/tomwer/widgets/visualization/icons/liveslice.png +0 -0
  567. orangecontrib/tomwer/widgets/visualization/icons/liveslice.svg +0 -110
  568. tomwer/core/log/logger.py +0 -130
  569. tomwer/core/process/control/test/test_volume_link.py +0 -74
  570. tomwer/core/process/control/tomoobjserie.py +0 -12
  571. tomwer/core/process/control/volumesymlink.py +0 -200
  572. tomwer/core/process/icat/createscreenshots.py +0 -100
  573. tomwer/core/process/icat/gallery.py +0 -377
  574. tomwer/core/process/icat/icatbase.py +0 -36
  575. tomwer/core/process/icat/publish.py +0 -228
  576. tomwer/core/process/icat/screenshots.py +0 -27
  577. tomwer/core/process/reconstruction/test/test_darkref.py +0 -60
  578. tomwer/core/process/reconstruction/test/test_sadeltabeta.py +0 -74
  579. tomwer/core/process/test/test_axis.py +0 -309
  580. tomwer/core/process/visualization/liveslice.py +0 -6
  581. tomwer/core/progress.py +0 -100
  582. tomwer/core/scan/test/test_edf.py +0 -53
  583. tomwer/core/scan/test/test_future_scan.py +0 -61
  584. tomwer/core/scan/test/test_h5.py +0 -96
  585. tomwer/core/scan/test/test_process_registration.py +0 -109
  586. tomwer/core/test/test_scanutils.py +0 -53
  587. tomwer/gui/control/emailnotifier.py +0 -174
  588. tomwer/gui/control/serie/seriewaiter.py +0 -28
  589. tomwer/gui/control/test/__init__.py +0 -28
  590. tomwer/gui/control/test/test_datalist.py +0 -96
  591. tomwer/gui/control/test/test_datavalidator.py +0 -54
  592. tomwer/gui/control/test/test_email.py +0 -35
  593. tomwer/gui/control/test/test_process_manager.py +0 -65
  594. tomwer/gui/control/test/test_scanselector.py +0 -67
  595. tomwer/gui/edit/test/__init__.py +0 -28
  596. tomwer/gui/icat/gallery.py +0 -214
  597. tomwer/gui/icat/publish.py +0 -187
  598. tomwer/gui/reconstruction/axis/axis.py +0 -733
  599. tomwer/gui/reconstruction/axis/radioaxis.py +0 -2467
  600. tomwer/gui/stitching/stitching.py +0 -1388
  601. tomwer/gui/test/__init__.py +0 -28
  602. tomwer/gui/test/test_axis_gui.py +0 -34
  603. tomwer/synctools/stacks/edit/darkflatpatch.py +0 -169
  604. tomwer/synctools/stacks/edit/imagekeyeditor.py +0 -135
  605. tomwer/third_part/WaitingOverlay.py +0 -110
  606. tomwer-1.3.27-py3.11-nspkg.pth +0 -1
  607. tomwer-1.3.27.dist-info/METADATA +0 -292
  608. tomwer-1.3.27.dist-info/RECORD +0 -785
  609. tomwer-1.3.27.dist-info/namespace_packages.txt +0 -1
  610. /orangecontrib/tomwer/{widgets/edit/test → tests}/__init__.py +0 -0
  611. {tomwer/core/process/control/test → orangecontrib/tomwer/tutorials/id16b}/__init__.py +0 -0
  612. {tomwer/core/process/icat → orangecontrib/tomwer/widgets/cluster/tests}/__init__.py +0 -0
  613. /orangecontrib/tomwer/widgets/control/icons/{tomoobjserie.png → tomoobjseries.png} +0 -0
  614. {tomwer/core/process/reconstruction/test → orangecontrib/tomwer/widgets/control/tests}/__init__.py +0 -0
  615. /orangecontrib/tomwer/widgets/{icat → dataportal}/icons/publish_processed_data.png +0 -0
  616. /orangecontrib/tomwer/widgets/{icat → dataportal}/icons/publish_processed_data.svg +0 -0
  617. {tomwer/core/process/test → orangecontrib/tomwer/widgets/debugtools/tests}/__init__.py +0 -0
  618. {tomwer/core/scan/test → orangecontrib/tomwer/widgets/edit/tests}/__init__.py +0 -0
  619. {tomwer/core/test → orangecontrib/tomwer/widgets/other/tests}/__init__.py +0 -0
  620. {tomwer/gui/cluster/test → orangecontrib/tomwer/widgets/reconstruction/tests}/__init__.py +0 -0
  621. {tomwer/gui/control/serie → orangecontrib/tomwer/widgets/stitching/tests}/__init__.py +0 -0
  622. {tomwer/gui/icat → orangecontrib/tomwer/widgets/tests}/__init__.py +0 -0
  623. {tomwer/gui/reconstruction/test → orangecontrib/tomwer/widgets/visualization/tests}/__init__.py +0 -0
  624. /tomwer/{synctools/stacks/edit → app/stitching}/__init__.py +0 -0
  625. /tomwer/{synctools/test → core/process/control/tests}/__init__.py +0 -0
  626. /tomwer/core/process/control/{test → tests}/test_email.py +0 -0
  627. /tomwer/core/process/control/{test → tests}/test_h52nx_process.py +0 -0
  628. /tomwer/{third_part → core/process/drac}/__init__.py +0 -0
  629. /tomwer/core/process/reconstruction/{test → tests}/test_axis_params.py +0 -0
  630. /tomwer/core/process/reconstruction/{test → tests}/test_darkref_copy.py +0 -0
  631. /tomwer/core/process/reconstruction/{test → tests}/test_paramsbase.py +0 -0
  632. /tomwer/core/scan/{test → tests}/test_scan.py +0 -0
  633. /tomwer/gui/control/{serie → series}/nxtomoconcatenate.py +0 -0
  634. /tomwer/gui/control/{test → tests}/test_datadiscovery.py +0 -0
  635. /tomwer/gui/control/{test → tests}/test_reducedarkflat_selector.py +0 -0
  636. /tomwer/gui/control/{test → tests}/test_single_tomo_obj.py +0 -0
  637. {orangecontrib/tomwer/widgets/edit/test → tomwer/tests/orangecontrib/tomwer/widgets/edit/tests}/test_image_key_upgrader.py +0 -0
  638. {tomwer-1.3.27.dist-info → tomwer-1.4.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,586 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ import os
5
+ import shutil
6
+ import tempfile
7
+ import functools
8
+
9
+ from nabu.stitching.config import StitchingType
10
+ from nabu.pipeline.config import generate_nabu_configfile, parse_nabu_config_file
11
+ from nabu.stitching.config import (
12
+ get_default_stitching_config,
13
+ SECTIONS_COMMENTS as _SECTIONS_COMMENTS,
14
+ )
15
+
16
+ from silx.gui import qt
17
+
18
+ from tomwer.core.scan.nxtomoscan import NXtomoScan, NXtomoScanIdentifier
19
+ from tomwer.core.volume.hdf5volume import HDF5Volume, HDF5VolumeIdentifier
20
+ from tomwer.gui.qconfigfile import QConfigFileDialog
21
+ from tomwer.gui.stitching.config.positionoveraxis import PosEditorOverOneAxis
22
+ from tomwer.gui.stitching.config.output import StitchingOutput
23
+ from tomwer.gui.stitching.StitchingOptionsWidget import StitchingOptionsWidget
24
+ from tomwer.gui.configuration.action import (
25
+ BasicConfigurationAction,
26
+ ExpertConfigurationAction,
27
+ MinimalisticConfigurationAction,
28
+ )
29
+ from tomwer.gui.configuration.level import ConfigurationLevel
30
+ from tomwer.gui.stitching import action as stitching_action
31
+ from tomwer.gui.stitching.preview import PreviewThread
32
+ from tomwer.gui.stitching.singleaxis import SingleAxisMetaClass, _SingleAxisMixIn
33
+ from tomwer.gui.stitching.SingleAxisStitchingWidget import SingleAxisStitchingWidget
34
+
35
+ from .utils import concatenate_dict
36
+
37
+ _logger = logging.getLogger(__name__)
38
+
39
+
40
+ class _SingleAxisStitchingWindow(
41
+ qt.QMainWindow, _SingleAxisMixIn, metaclass=SingleAxisMetaClass
42
+ ):
43
+ """
44
+ Main widget containing all the options to define the stitching to be done
45
+
46
+ :param with_configuration_action: if True append the load and save stitching configuration tool button.
47
+ In some cases those can also be part of Menu so we want to avoid having those twice
48
+ """
49
+
50
+ sigChanged = qt.Signal()
51
+ """Signal emit each time the configuration is modified"""
52
+
53
+ def __init__(self, parent=None, with_configuration_action=True) -> None:
54
+ super().__init__(parent)
55
+ assert self._axis in (0, 1, 2)
56
+ """axis along which we want to apply stitching"""
57
+ self._previewFolder = None
58
+ # folder to store files (volume or NXtomo) for previews
59
+ self._previewThread = None
60
+ # thread to compute the stitching for preview
61
+ self._callbackToGetSlurmConfig = None
62
+ self._callbackToSetSlurmConfig = None
63
+ # convenient work around to avoid having to redefine the n=interface for slurm and the API
64
+ # to load and save settings
65
+ # if it is defined upper
66
+
67
+ toolbar = qt.QToolBar(self)
68
+ self.addToolBar(qt.Qt.TopToolBarArea, toolbar)
69
+ style = qt.QApplication.instance().style()
70
+
71
+ # clean option
72
+ self.__cleanAction = qt.QAction(self)
73
+ self.__cleanAction.setToolTip("clear")
74
+ clear_icon = style.standardIcon(qt.QStyle.SP_DialogResetButton)
75
+ self.__cleanAction.setIcon(clear_icon)
76
+ toolbar.addAction(self.__cleanAction)
77
+ self.__cleanAction.triggered.connect(self.clean)
78
+
79
+ # separator
80
+ toolbar.addSeparator()
81
+
82
+ if with_configuration_action:
83
+ # load action
84
+ self.__loadAction = stitching_action.LoadConfigurationAction(self)
85
+ toolbar.addAction(self.__loadAction)
86
+ self.__loadAction.triggered.connect(
87
+ functools.partial(self._loadSettings, file_path=None)
88
+ )
89
+
90
+ # save action
91
+ self.__saveAction = stitching_action.SaveConfigurationAction(self)
92
+ toolbar.addAction(self.__saveAction)
93
+ self.__saveAction.triggered.connect(
94
+ functools.partial(self._saveSettings, file_path=None)
95
+ )
96
+
97
+ # separator
98
+ toolbar.addSeparator()
99
+
100
+ # update preview action
101
+ self.__updatePreviewAction = stitching_action.PreviewAction(self)
102
+ toolbar.addAction(self.__updatePreviewAction)
103
+ self.__updatePreviewAction.triggered.connect(self._trigger_update_preview)
104
+
105
+ # separator
106
+ toolbar.addSeparator()
107
+
108
+ # configuration level / mode
109
+ self.__configurationModesAction = qt.QAction(self)
110
+ self.__configurationModesAction.setCheckable(False)
111
+ menu = qt.QMenu(self)
112
+ self.__configurationModesAction.setMenu(menu)
113
+ toolbar.addAction(self.__configurationModesAction)
114
+
115
+ self.__configurationModesGroup = qt.QActionGroup(self)
116
+ self.__configurationModesGroup.setExclusive(True)
117
+ self.__configurationModesGroup.triggered.connect(self._userModeChanged)
118
+
119
+ self._minimalisticAction = MinimalisticConfigurationAction(toolbar)
120
+ menu.addAction(self._minimalisticAction)
121
+ self.__configurationModesGroup.addAction(self._minimalisticAction)
122
+ self._basicConfigAction = BasicConfigurationAction(toolbar)
123
+ menu.addAction(self._basicConfigAction)
124
+ self.__configurationModesGroup.addAction(self._basicConfigAction)
125
+ self._expertConfiguration = ExpertConfigurationAction(toolbar)
126
+ menu.addAction(self._expertConfiguration)
127
+ self.__configurationModesGroup.addAction(self._expertConfiguration)
128
+
129
+ # separator
130
+ toolbar.addSeparator()
131
+
132
+ # create central widget
133
+ self._widget = SingleAxisStitchingWidget(parent=self, axis=self.first_axis)
134
+ self.setCentralWidget(self._widget)
135
+
136
+ # create Dock widgets
137
+ ## output
138
+ self._outputWidget = StitchingOutput(parent=self)
139
+ self._outputWidget.setObjectName("outputSettingsWidget")
140
+ self._outputDockWidget = qt.QDockWidget(parent=self)
141
+ self._outputDockWidget.setWindowTitle("output")
142
+ self._outputDockWidget.layout().setContentsMargins(0, 0, 0, 0)
143
+ self._outputDockWidget.setFeatures(qt.QDockWidget.DockWidgetMovable)
144
+ self._outputDockWidget.setWidget(self._outputWidget)
145
+ self.addDockWidget(qt.Qt.RightDockWidgetArea, self._outputDockWidget)
146
+ self._outputDockWidget.setToolTip(
147
+ "options to where and how to save the stitching"
148
+ )
149
+ ## stitching strategies
150
+ self._stitchingOptsWidget = StitchingOptionsWidget(
151
+ parent=self, first_axis=self.first_axis, second_axis=self.second_axis
152
+ )
153
+ self._stitchingOptsScrollArea = qt.QScrollArea(self)
154
+ self._stitchingOptsScrollArea.setWidget(self._stitchingOptsWidget)
155
+ self._stitchingOptsScrollArea.setWidgetResizable(True)
156
+ self._stitchingOptsScrollArea.setHorizontalScrollBarPolicy(
157
+ qt.Qt.ScrollBarAlwaysOff
158
+ )
159
+ self._stitchingOptsDockWidget = qt.QDockWidget(parent=self)
160
+ self._stitchingOptsDockWidget.layout().setContentsMargins(0, 0, 0, 0)
161
+ self._stitchingOptsDockWidget.setFeatures(qt.QDockWidget.DockWidgetMovable)
162
+ self._stitchingOptsDockWidget.setWidget(self._stitchingOptsScrollArea)
163
+ self._stitchingOptsDockWidget.setWindowTitle("processing options")
164
+ self.addDockWidget(qt.Qt.RightDockWidgetArea, self._stitchingOptsDockWidget)
165
+
166
+ ## all scan z positions
167
+ self._editTomoObjFirstAxisPositionsWidget = PosEditorOverOneAxis(
168
+ parent=self,
169
+ axis_edited=self.first_axis,
170
+ axis_order=self.first_axis,
171
+ )
172
+ self._editTomoObjFirstAxisPositionsDockWidget = qt.QDockWidget(parent=self)
173
+ self._editTomoObjFirstAxisPositionsDockWidget.layout().setContentsMargins(
174
+ 0, 0, 0, 0
175
+ )
176
+ self._editTomoObjFirstAxisPositionsDockWidget.setFeatures(
177
+ qt.QDockWidget.DockWidgetMovable
178
+ )
179
+ self._editTomoObjFirstAxisPositionsDockWidget.setWidget(
180
+ self._editTomoObjFirstAxisPositionsWidget
181
+ )
182
+ self._editTomoObjFirstAxisPositionsDockWidget.setWindowTitle(
183
+ f"edit positions over axis {self.first_axis} (px) - aka {self.axis_alias(self.first_axis)}"
184
+ )
185
+ self._editTomoObjFirstAxisPositionsDockWidget.setToolTip(
186
+ f"This allows to edit tomo objects positions along the axis {self.first_axis} (aka {self.axis_alias(self.first_axis)})"
187
+ )
188
+ self.addDockWidget(
189
+ qt.Qt.RightDockWidgetArea, self._editTomoObjFirstAxisPositionsDockWidget
190
+ )
191
+ ### add a check box to update position from preview if asked by the user
192
+ self._updateFirstAxisPosFromPreviewCalc = qt.QCheckBox(
193
+ f"update position {self.first_axis} from preview calc",
194
+ self,
195
+ )
196
+ self._updateFirstAxisPosFromPreviewCalc.setToolTip(
197
+ f"When the user trigger a preview, if some shift search refined over axis {self.first_axis} is done then will update the axis 0 positions",
198
+ )
199
+ self._updateFirstAxisPosFromPreviewCalc.setChecked(True)
200
+ self._editTomoObjFirstAxisPositionsWidget.layout().insertWidget(
201
+ 0, self._updateFirstAxisPosFromPreviewCalc
202
+ )
203
+
204
+ ## all scan axis 1 positions
205
+ self._editTomoObjSecondAxisPositionsWidget = PosEditorOverOneAxis(
206
+ parent=self,
207
+ axis_edited=self.second_axis,
208
+ axis_order=0,
209
+ )
210
+ self._editTomoObjSecondAxisPositionsDockWidget = qt.QDockWidget(parent=self)
211
+ self._editTomoObjSecondAxisPositionsDockWidget.layout().setContentsMargins(
212
+ 0, 0, 0, 0
213
+ )
214
+ self._editTomoObjSecondAxisPositionsDockWidget.setFeatures(
215
+ qt.QDockWidget.DockWidgetMovable
216
+ )
217
+ self._editTomoObjSecondAxisPositionsDockWidget.setWidget(
218
+ self._editTomoObjSecondAxisPositionsWidget
219
+ )
220
+ self._editTomoObjSecondAxisPositionsDockWidget.setWindowTitle(
221
+ f"edit positions over axis {self.second_axis} (px)"
222
+ )
223
+ self._editTomoObjSecondAxisPositionsDockWidget.setToolTip(
224
+ f"This allows to edit tomo objects positions along the axis {self.second_axis}"
225
+ )
226
+ self.addDockWidget(
227
+ qt.Qt.RightDockWidgetArea, self._editTomoObjSecondAxisPositionsDockWidget
228
+ )
229
+ ### add a check box to update position from preview if asked by the user
230
+ self._updateSecondAxisPosFromPreviewCalc = qt.QCheckBox(
231
+ f"update position {self.second_axis} from preview calc", self
232
+ )
233
+ self._updateSecondAxisPosFromPreviewCalc.setToolTip(
234
+ f"When the user trigger a preview, if some position refinement can be done will update axis {self.second_axis}"
235
+ )
236
+ self._updateSecondAxisPosFromPreviewCalc.setChecked(True)
237
+ self._editTomoObjSecondAxisPositionsWidget.layout().insertWidget(
238
+ 0, self._updateSecondAxisPosFromPreviewCalc
239
+ )
240
+
241
+ self._widget.setAddTomoObjCallbacks(
242
+ (
243
+ self._editTomoObjFirstAxisPositionsWidget.addTomoObj,
244
+ self._editTomoObjSecondAxisPositionsWidget.addTomoObj,
245
+ self.getRawDisplayPlot().addTomoObj,
246
+ )
247
+ )
248
+ self._widget.setRemoveTomoObjCallbacks(
249
+ (
250
+ self._editTomoObjFirstAxisPositionsWidget.removeTomoObj,
251
+ self._editTomoObjSecondAxisPositionsWidget.removeTomoObj,
252
+ self.getRawDisplayPlot().removeTomoObj,
253
+ )
254
+ )
255
+
256
+ # update layout: for now lets tabify some widget
257
+ self.tabifyDockWidget(self._outputDockWidget, self._stitchingOptsDockWidget)
258
+ self.tabifyDockWidget(
259
+ self._outputDockWidget, self._editTomoObjSecondAxisPositionsDockWidget
260
+ )
261
+ self.tabifyDockWidget(
262
+ self._outputDockWidget, self._editTomoObjFirstAxisPositionsDockWidget
263
+ )
264
+
265
+ # handle raw display plot. By display avoid displaying raw data as this can be resource consuming
266
+ self._widget._mainWidget._rawDisplayCB.setChecked(False)
267
+ self._widget._mainWidget._rawDisplayPlot.setActive(False)
268
+
269
+ # connect signal / slot
270
+ self._widget._mainWidget._rawDisplayCB.toggled.connect(
271
+ self._handleRawDisplayConnection
272
+ )
273
+ self._outputWidget.sigChanged.connect(self._changed)
274
+ self._stitchingOptsWidget.sigChanged.connect(self._changed)
275
+ self._widget.sigStitchingTypeChanged.connect(
276
+ self._outputWidget._updateOutputForStitchingType
277
+ )
278
+ self._widget.sigStitchingTypeChanged.connect(
279
+ self._stitchingOptsWidget._stitchingTypeChanged
280
+ )
281
+
282
+ ## handle raw plot preview
283
+ self._stitchingOptsWidget.sigFlipLRChanged.connect(
284
+ self.getRawDisplayPlot().setFlipLRFrames
285
+ )
286
+ self._stitchingOptsWidget.sigFlipUDChanged.connect(
287
+ self.getRawDisplayPlot().setFlipUDFrames
288
+ )
289
+ self._stitchingOptsWidget.sigSliceForPreviewChanged.connect(
290
+ self.getRawDisplayPlot().setSliceForPreview
291
+ )
292
+
293
+ ## handle tomo obj loading from settings
294
+ self._widget.sigTomoObjsLoaded.connect(
295
+ self._editTomoObjFirstAxisPositionsWidget.setTomoObjs
296
+ )
297
+ self._widget.sigTomoObjsLoaded.connect(
298
+ self._editTomoObjSecondAxisPositionsWidget.setTomoObjs
299
+ )
300
+ self._widget.sigTomoObjsLoaded.connect(self.getRawDisplayPlot().setTomoObjs)
301
+
302
+ # set up
303
+ self._basicConfigAction.setChecked(True)
304
+ self._userModeChanged(self._basicConfigAction)
305
+
306
+ def setCallbackToGetSlurmConfig(self, callback):
307
+ self._callbackToGetSlurmConfig = callback
308
+
309
+ def setCallbackToSetSlurmConfig(self, callback):
310
+ self._callbackToSetSlurmConfig = callback
311
+
312
+ def close(self):
313
+ # remove folder used for preview
314
+ if self._previewFolder is not None:
315
+ shutil.rmtree(self._previewFolder, ignore_errors=True)
316
+ self._widget.close()
317
+ # requested for the waiting plot update
318
+ super().close()
319
+
320
+ def getRawDisplayPlot(self):
321
+ return self._widget._mainWidget._rawDisplayPlot
322
+
323
+ def _handleRawDisplayConnection(self, toggled: bool):
324
+ raw_display_plot = self.getRawDisplayPlot()
325
+ raw_display_plot.setActive(toggled)
326
+
327
+ def getPreviewAction(self):
328
+ return self.__updatePreviewAction
329
+
330
+ def getPreviewFolder(self):
331
+ if self._previewFolder is None:
332
+ self._previewFolder = tempfile.mkdtemp(prefix="tomwer_stitcher_preview")
333
+ return self._previewFolder
334
+
335
+ def getVolumeIdentifierPreview(self) -> HDF5VolumeIdentifier:
336
+ folder = self.getPreviewFolder()
337
+ # for now use hdf5 by default
338
+ return HDF5VolumeIdentifier(
339
+ object=HDF5Volume,
340
+ hdf5_file=os.path.join(folder, "vol_stitching_preview.hdf5"),
341
+ entry="my_volume",
342
+ )
343
+
344
+ def getNXtomoIdentifierForPreview(self):
345
+ folder = self.getPreviewFolder()
346
+ return NXtomoScanIdentifier(
347
+ object=NXtomoScan,
348
+ hdf5_file=os.path.join(folder, "nxtomo_stiching_preview.hdf5"),
349
+ entry="entry0000",
350
+ )
351
+
352
+ def _changed(self, *args, **kwargs):
353
+ self.sigChanged.emit()
354
+
355
+ def _saveSettings(self, file_path=None, **kwargs):
356
+ """
357
+ dump current configuration into a txt file
358
+ """
359
+ # get a file if necessary
360
+ if file_path is None:
361
+ dialog = QConfigFileDialog(self)
362
+ dialog.setAcceptMode(qt.QFileDialog.AcceptSave)
363
+ if not dialog.exec_():
364
+ return
365
+
366
+ selected_file = dialog.selectedFiles()
367
+ if len(selected_file) == 0:
368
+ return
369
+ file_path = selected_file[0]
370
+
371
+ configuration = self.getConfiguration()
372
+ if self._callbackToGetSlurmConfig is not None:
373
+ slurm_config = {"slurm": self._callbackToGetSlurmConfig()}
374
+ configuration = concatenate_dict(configuration, slurm_config)
375
+
376
+ _, ext = os.path.splitext(file_path)
377
+ if ext == "":
378
+ file_path = f"{file_path}.cfg"
379
+ # dump configuration
380
+ generate_nabu_configfile(
381
+ fname=file_path,
382
+ default_config=get_default_stitching_config(self.getStitchingType()),
383
+ comments=True,
384
+ sections_comments=_SECTIONS_COMMENTS,
385
+ options_level="advanced",
386
+ prefilled_values=configuration,
387
+ )
388
+
389
+ def _loadSettings(self, file_path=None, **kwargs):
390
+ """
391
+ load configuration from a txt file
392
+ """
393
+ # get a file if necessary
394
+ if file_path is None:
395
+ dialog = QConfigFileDialog(self)
396
+ dialog.setAcceptMode(qt.QFileDialog.AcceptOpen)
397
+ dialog.setFileMode(qt.QFileDialog.ExistingFiles)
398
+
399
+ if not dialog.exec_():
400
+ return
401
+
402
+ selected_file = dialog.selectedFiles()
403
+ if len(selected_file) == 0:
404
+ return
405
+ file_path = selected_file[0]
406
+
407
+ # Do configuration load
408
+ conf_dict = parse_nabu_config_file(file_path, allow_no_value=True)
409
+ self.setConfiguration(config=conf_dict)
410
+ if self._callbackToSetSlurmConfig is not None:
411
+ self._callbackToSetSlurmConfig(conf_dict.get("slurm", {}))
412
+
413
+ def _trigger_update_preview(self):
414
+ if self._previewThread is not None:
415
+ _logger.warning(
416
+ "some preview is already running. Please wait before relaunching it"
417
+ )
418
+ return
419
+ config = self.getConfiguration()
420
+ # update the output file to set if from raw...
421
+ stitching_type = config.get("stitching", {}).get("type", None)
422
+ if stitching_type in ("z-preproc", "y-preproc"):
423
+ output_identifier = self.getNXtomoIdentifierForPreview()
424
+ config["preproc"]["location"] = output_identifier.file_path
425
+ config["preproc"]["data_path"] = output_identifier.data_path
426
+ assert "postproc" not in config
427
+ elif stitching_type == "z-postproc":
428
+ config["postproc"][
429
+ "output_volume"
430
+ ] = self.getVolumeIdentifierPreview().to_str()
431
+ assert "preproc" not in config
432
+ else:
433
+ raise NotImplementedError
434
+
435
+ # update the slice to avoid doing the stitching on all the frames
436
+ config["inputs"]["slices"] = self.getSlicesForPreview()
437
+
438
+ # update to force overwrite
439
+ config["output"]["overwrite_results"] = True
440
+
441
+ # clean current preview to notify some calculation is going on
442
+ preview_plot = self._widget._mainWidget._previewPlot
443
+ preview_plot._waitingOverlay.show()
444
+
445
+ # start stitching on a thread
446
+ self._previewThread = PreviewThread(stitching_config=config)
447
+ self._previewThread.finished.connect(self._previewCalculationFinished)
448
+ self._previewThread.start()
449
+
450
+ def getSlicesForPreview(self):
451
+ return self._stitchingOptsWidget.getSlicesForPreview()
452
+
453
+ def _previewCalculationFinished(self):
454
+ sender = self.sender()
455
+ assert isinstance(sender, PreviewThread)
456
+ composition = sender.frame_composition
457
+ tomo_objs_new_axis_positions = sender.final_tomo_objs_positions
458
+ assert isinstance(
459
+ tomo_objs_new_axis_positions, dict
460
+ ), f"final_tomo_objs_positions is expected to be a dict with obj identifier as key and the tuple of position as value. Got {type(tomo_objs_new_axis_positions)}"
461
+ # expect it to be a dict with tomo obj identifier as key and a tuple of (axis_2_pos, axis_1_pos, axis_0_pos) as value
462
+ output_obj_identifier = sender.output_identifier
463
+
464
+ preview_plot = self._widget._mainWidget._previewPlot
465
+ preview_plot._waitingOverlay.hide()
466
+
467
+ self._previewThread.finished.disconnect(self._previewCalculationFinished)
468
+ self._previewThread = None
469
+
470
+ if output_obj_identifier is None:
471
+ _logger.error("preview of stitching failed")
472
+ else:
473
+ preview_plot.setStitchedTomoObj(
474
+ tomo_obj_id=output_obj_identifier,
475
+ composition=composition,
476
+ )
477
+
478
+ # update object values if requested
479
+ update_requested = {
480
+ self.first_axis: self._updateFirstAxisPosFromPreviewCalc.isChecked(),
481
+ self.second_axis: self._updateSecondAxisPosFromPreviewCalc.isChecked(),
482
+ }
483
+
484
+ if update_requested[self.first_axis] or update_requested[self.second_axis]:
485
+ existing_tomo_obj = {
486
+ tomo_obj.get_identifier().to_str(): tomo_obj
487
+ for tomo_obj in self._widget._mainWidget.getTomoObjs()
488
+ }
489
+
490
+ for tomo_obj_id, value in tomo_objs_new_axis_positions.items():
491
+ assert (
492
+ isinstance(value, tuple) and len(value) == 3
493
+ ), "value is expected to be (new_pos_axis_0, new_pos_axis_1, new_pos_axis_2)"
494
+ new_first_axis_pos = value[self.first_axis]
495
+ new_second_axis_pos = value[self.second_axis]
496
+ tomo_obj = existing_tomo_obj.get(tomo_obj_id, None)
497
+ if tomo_obj is None:
498
+ continue
499
+
500
+ if update_requested[self.first_axis]:
501
+ tomo_obj.stitching_metadata.setPxPos(
502
+ int(new_first_axis_pos), self.first_axis
503
+ )
504
+ if update_requested[self.second_axis]:
505
+ tomo_obj.stitching_metadata.setPxPos(
506
+ int(new_second_axis_pos), self.second_axis
507
+ )
508
+ if update_requested[self.first_axis]:
509
+ self._editTomoObjFirstAxisPositionsWidget._orderedMightHaveChanged(
510
+ force_sb_update=True
511
+ )
512
+ if update_requested[self.second_axis]:
513
+ self._editTomoObjSecondAxisPositionsWidget._orderedMightHaveChanged(
514
+ force_sb_update=True
515
+ )
516
+
517
+ def clean(self):
518
+ self._widget.clean()
519
+ self._editTomoObjFirstAxisPositionsWidget.clean()
520
+ self._editTomoObjSecondAxisPositionsWidget.clean()
521
+
522
+ def setSeries(self, series):
523
+ self.clean()
524
+ self._widget._mainWidget.setSeries(series)
525
+ self._editTomoObjFirstAxisPositionsWidget.clean()
526
+ self._editTomoObjSecondAxisPositionsWidget.clean()
527
+ for tomo_obj in series:
528
+ self._editTomoObjFirstAxisPositionsWidget.addTomoObj(tomo_obj)
529
+ self._editTomoObjSecondAxisPositionsWidget.addTomoObj(tomo_obj)
530
+ self.getRawDisplayPlot().setTomoObjs(tomo_objs=series[:])
531
+
532
+ def addTomoObj(self, tomo_obj):
533
+ self._widget.addTomoObj(tomo_obj)
534
+ self._editTomoObjFirstAxisPositionsWidget.addTomoObj(tomo_obj)
535
+ self._editTomoObjSecondAxisPositionsWidget.addTomoObj(tomo_obj)
536
+ self.getRawDisplayPlot().addTomoObj(tomo_obj=tomo_obj)
537
+
538
+ def removeTomoObj(self, tomo_obj):
539
+ self._widget.removeTomoObj(tomo_obj)
540
+ self.getRawDisplayPlot().removeTomoObj(tomo_obj=tomo_obj)
541
+
542
+ def getConfiguration(self) -> dict:
543
+ # make sure the sync is fine between the two
544
+ configs = (
545
+ self._widget.getConfiguration(),
546
+ self._outputWidget.getConfiguration(),
547
+ self._stitchingOptsWidget.getConfiguration(),
548
+ )
549
+ result = {}
550
+ for config in configs:
551
+ result = concatenate_dict(result, config)
552
+ return result
553
+
554
+ def setConfiguration(self, config: dict):
555
+ self._widget.setConfiguration(config)
556
+ self._outputWidget.setConfiguration(config)
557
+ self._stitchingOptsWidget.setConfiguration(config)
558
+
559
+ # expose API
560
+ def getStitchingType(self) -> StitchingType:
561
+ return self._widget.getStitchingType()
562
+
563
+ def setStitchingType(self, stitching_type: StitchingType):
564
+ self._widget.setStitchingType(stitching_type)
565
+
566
+ def _userModeChanged(self, action):
567
+ self.__configurationModesAction.setIcon(action.icon())
568
+ self.__configurationModesAction.setToolTip(action.tooltip())
569
+ if action is self._basicConfigAction:
570
+ level = ConfigurationLevel.OPTIONAL
571
+ elif action is self._expertConfiguration:
572
+ level = ConfigurationLevel.ADVANCED
573
+ else:
574
+ level = ConfigurationLevel.REQUIRED
575
+ self._stitchingOptsWidget.setConfigurationLevel(level)
576
+ self._editTomoObjSecondAxisPositionsDockWidget.setVisible(
577
+ level >= ConfigurationLevel.ADVANCED
578
+ )
579
+
580
+
581
+ class YStitchingWindow(_SingleAxisStitchingWindow, axis=1):
582
+ pass
583
+
584
+
585
+ class ZStitchingWindow(_SingleAxisStitchingWindow, axis=0):
586
+ pass
@@ -0,0 +1,2 @@
1
+ """Widgets for stitching scans or volumes
2
+ """
@@ -0,0 +1,90 @@
1
+ from __future__ import annotations
2
+
3
+ from silx.gui import qt
4
+ from nabu.stitching.alignment import AlignmentAxis1, AlignmentAxis2
5
+
6
+
7
+ class _AlignmentGroupBox(qt.QGroupBox):
8
+ DEFAULT_PAD_MODE = "constant"
9
+
10
+ ALIGNMENT_DOC = (
11
+ "https://tomotools.gitlab-pages.esrf.fr/nabu/stitching/alignment.html"
12
+ )
13
+
14
+ DEFAULT_ALIGNMENT_AXIS_1 = AlignmentAxis1.CENTER
15
+ DEFAULT_ALIGNMENT_AXIS_2 = AlignmentAxis2.CENTER
16
+
17
+ _PAD_MODES = (
18
+ "constant", # Pads with a constant value.
19
+ "edge", # Pads with the edge values of array.
20
+ "linear_ramp", # Pads with the linear ramp between end_value and the array edge value.
21
+ "maximum", # Pads with the maximum value of all or part of the vector along each axis.
22
+ "mean", # Pads with the mean value of all or part of the vector along each axis.
23
+ "median", # Pads with the median value of all or part of the vector along each axis.
24
+ "minimum", # Pads with the minimum value of all or part of the vector along each axis.
25
+ "reflect", # Pads with the reflection of the vector mirrored on the first and last values of the vector along each axis.
26
+ "symmetric", # Pads with the reflection of the vector mirrored along the edge of the array.
27
+ "wrap", # Pads with the wrap of the vector along the axis. The first values are used to pad the end and the end values are used to pad the beginning.
28
+ )
29
+
30
+ def __init__(self, parent: qt.QWidget = None, title="alignment") -> None:
31
+ super().__init__(title, parent)
32
+ self.setLayout(qt.QFormLayout())
33
+
34
+ # alignment axis 1
35
+ self._alignmentAxis1CB = qt.QComboBox(self)
36
+ for alignment in AlignmentAxis1.values():
37
+ self._alignmentAxis1CB.addItem(alignment)
38
+ self.layout().addRow("Axis 1 alignment", self._alignmentAxis1CB)
39
+ self._alignmentAxis1CB.setToolTip(
40
+ f"Alignment to do in case of volumes with different size over axis 1. Only possible for post-processing (reconstructed volume). See {self.ALIGNMENT_DOC} for details."
41
+ )
42
+
43
+ # alignment axis 2
44
+ self._alignmentAxis2CB = qt.QComboBox(self)
45
+ for alignment in AlignmentAxis2.values():
46
+ self._alignmentAxis2CB.addItem(alignment)
47
+ self.layout().addRow("Axis 2 alignment", self._alignmentAxis2CB)
48
+ self._alignmentAxis2CB.setToolTip(
49
+ f"Alignment to do in case of frames with different size over axis 2. See {self.ALIGNMENT_DOC} for details."
50
+ )
51
+
52
+ # pad mode
53
+ self._padModeCB = qt.QComboBox(self)
54
+ for pad_mode in self._PAD_MODES:
55
+ self._padModeCB.addItem(pad_mode)
56
+ self.layout().addRow("pad mode", self._padModeCB)
57
+ self._padModeCB.setToolTip("padding mode to apply for alignment")
58
+
59
+ # set up
60
+ self.setAlignmentAxis1(self.DEFAULT_ALIGNMENT_AXIS_1)
61
+ self.setAlignmentAxis2(self.DEFAULT_ALIGNMENT_AXIS_2)
62
+
63
+ def getAlignmentAxis1(self) -> AlignmentAxis1:
64
+ return AlignmentAxis1.from_value(self._alignmentAxis1CB.currentText())
65
+
66
+ def setAlignmentAxis1(self, alignment: AlignmentAxis1):
67
+ alignment = AlignmentAxis1.from_value(alignment)
68
+ self._alignmentAxis1CB.setCurrentIndex(
69
+ self._alignmentAxis1CB.findText(alignment.value)
70
+ )
71
+
72
+ def getAlignmentAxis2(self) -> AlignmentAxis2:
73
+ return AlignmentAxis2.from_value(self._alignmentAxis2CB.currentText())
74
+
75
+ def setAlignmentAxis2(self, alignment: AlignmentAxis2):
76
+ alignment = AlignmentAxis2.from_value(alignment)
77
+ self._alignmentAxis2CB.setCurrentIndex(
78
+ self._alignmentAxis2CB.findText(alignment.value)
79
+ )
80
+
81
+ def getPadMode(self) -> str:
82
+ return self._padModeCB.currentText()
83
+
84
+ def setPadMode(self, pad_mode: str):
85
+ idx = self._padModeCB.findText(pad_mode)
86
+ if idx >= 0:
87
+ self._padModeCB.setCurrentIndex(idx)
88
+
89
+ def setAlignmentAxis1Enabled(self, enabled: bool):
90
+ self._alignmentAxis1CB.setEnabled(enabled)