tomwer 1.3.26__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.26.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.26.dist-info → tomwer-1.4.0.dist-info}/WHEEL +1 -1
  553. {tomwer-1.3.26.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 -1392
  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.26-py3.11-nspkg.pth +0 -1
  607. tomwer-1.3.26.dist-info/METADATA +0 -292
  608. tomwer-1.3.26.dist-info/RECORD +0 -785
  609. tomwer-1.3.26.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.26.dist-info → tomwer-1.4.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,797 @@
1
+ from __future__ import annotations
2
+
3
+ import enum
4
+ import logging
5
+
6
+ from silx.gui import qt
7
+
8
+ from tomwer.core.process.reconstruction.axis import mode as axis_mode
9
+ from tomwer.gui.utils.qt_utils import block_signals
10
+ from tomwer.gui.utils.step import StepSizeSelectorWidget
11
+ from tomwer.synctools.axis import QAxisRP
12
+ from tomwer.gui.settings import EDITING_BACKGROUND_COLOR
13
+
14
+ from .AxisOptionsWidget import AxisOptionsWidget
15
+ from .CalculationWidget import CalculationWidget
16
+ from .InputWidget import InputWidget
17
+
18
+
19
+ _logger = logging.getLogger(__name__)
20
+
21
+
22
+ @enum.unique
23
+ class ShiftMode(enum.Enum):
24
+ x_only = 0
25
+ y_only = 1
26
+ x_and_y = 2
27
+
28
+
29
+ class AxisSettingsWidget(qt.QWidget):
30
+ """
31
+ Widget to define settings for COR search (which algorithm to use...)
32
+ """
33
+
34
+ sigShiftChanged = qt.Signal(float, float)
35
+ """Signal emitted when requested shift changed. Parameter is x, y"""
36
+
37
+ sigModeLockChanged = qt.Signal(bool)
38
+ """Signal emitted when the mode is lock or unlock"""
39
+
40
+ sigResetZoomRequested = qt.Signal()
41
+ """Signal emitted when request a zoom reset from the plot"""
42
+
43
+ sigSubSamplingChanged = qt.Signal()
44
+ """Signal emitted when sub-sampling change"""
45
+
46
+ sigUrlChanged = qt.Signal()
47
+ """Signal emit when frames urls changed"""
48
+
49
+ sigModeChanged = qt.Signal(str)
50
+ """Signal emit when mode (algorithm) is changed"""
51
+
52
+ sigRoiChanged = qt.Signal(object)
53
+ """Signal emitted when the ROI changed"""
54
+
55
+ sigAuto = qt.Signal()
56
+ """Signal emitted when the auto button is activated"""
57
+
58
+ def __init__(self, parent, reconsParams):
59
+ assert isinstance(reconsParams, QAxisRP)
60
+ qt.QWidget.__init__(self, parent)
61
+ self._xShift = 0
62
+ self._yShift = 0
63
+ self._recons_params = reconsParams
64
+ self._axisParams = None
65
+
66
+ self.setLayout(qt.QVBoxLayout())
67
+
68
+ self._manualSelectionWidget = ManualAxisSelectionWidget(
69
+ parent=self, shift_mode=ShiftMode.x_only
70
+ )
71
+ self._manualSelectionWidget.layout().setContentsMargins(0, 0, 0, 0)
72
+
73
+ self._displacementSelector = self._manualSelectionWidget._displacementSelector
74
+ self._shiftControl = self._manualSelectionWidget._shiftControl
75
+ self._roiControl = self._manualSelectionWidget._roiControl
76
+ self._imgOpts = self._manualSelectionWidget._imgOpts
77
+
78
+ self._mainWidget = AxisSettingsTabWidget(
79
+ parent=self,
80
+ recons_params=self._recons_params,
81
+ )
82
+ # append the Manual selection to the AxisTabWidget to have all widget related to axis settings together
83
+ self._mainWidget._calculationWidget.layout().addWidget(
84
+ self._manualSelectionWidget
85
+ )
86
+
87
+ self.layout().addWidget(self._mainWidget)
88
+
89
+ # signal / slot connection
90
+ self._shiftControl.sigShiftLeft.connect(self._incrementLeftShift)
91
+ self._shiftControl.sigShiftRight.connect(self._incrementRightShift)
92
+ self._shiftControl.sigShiftTop.connect(self._incrementTopShift)
93
+ self._shiftControl.sigShiftBottom.connect(self._incrementBottomShift)
94
+ self._shiftControl.sigReset.connect(self._resetShift)
95
+ self._shiftControl.sigShiftChanged.connect(self._setShiftAndSignal)
96
+ self._mainWidget.sigLockModeChanged.connect(self._modeLockChanged)
97
+ self._manualSelectionWidget.sigResetZoomRequested.connect(
98
+ self._requestZoomReset
99
+ )
100
+ self._imgOpts.sigSubSamplingChanged.connect(self.sigSubSamplingChanged)
101
+ self._mainWidget.sigUrlChanged.connect(self.sigUrlChanged)
102
+ self._roiControl.sigRoiChanged.connect(self.sigRoiChanged)
103
+ self._shiftControl.sigAuto.connect(self.sigAuto)
104
+ self._mainWidget.sigModeChanged.connect(self.sigModeChanged)
105
+
106
+ # set up interface
107
+ self.setAxisParams(self._recons_params)
108
+
109
+ def setScan(self, scan):
110
+ self._mainWidget.setScan(scan=scan)
111
+ self._roiControl.setScan(scan=scan)
112
+
113
+ def manual_uses_full_image(self, value):
114
+ self._roiControl.manual_uses_full_image(value)
115
+
116
+ def _incrementLeftShift(self):
117
+ self._incrementShift("left")
118
+
119
+ def _incrementRightShift(self):
120
+ self._incrementShift("right")
121
+
122
+ def _incrementTopShift(self):
123
+ self._incrementShift("top")
124
+
125
+ def _incrementBottomShift(self):
126
+ self._incrementShift("bottom")
127
+
128
+ def _setShiftAndSignal(self, x, y):
129
+ if x == self._xShift and y == self._yShift:
130
+ return
131
+ self.setShift(x, y)
132
+ self._shiftControl._updateShiftInfo(x=x, y=y)
133
+ self.sigShiftChanged.emit(x, y)
134
+
135
+ def setAxisParams(self, axis):
136
+ if axis == self._axisParams:
137
+ return
138
+ assert isinstance(axis, QAxisRP)
139
+ with block_signals(self):
140
+ if self._axisParams:
141
+ self._axisParams.sigChanged.disconnect(self._updateAxisView)
142
+ self._axisParams = axis
143
+ self.setXShift(self._axisParams.relative_cor_value)
144
+ self._mainWidget.setAxisParams(self._axisParams)
145
+ self._updateAxisView()
146
+ self._axisParams.sigChanged.connect(self._updateAxisView)
147
+
148
+ def _modeLockChanged(self, lock):
149
+ self.sigModeLockChanged.emit(lock)
150
+
151
+ def setMode(self, mode):
152
+ with block_signals(self._axisParams):
153
+ self._axisParams.mode = mode
154
+ self._mainWidget._calculationWidget.setMode(mode)
155
+ self._mainWidget._optionsWidget.setMode(mode)
156
+ self._updateAxisView()
157
+ self._axisParams.sigChanged.emit()
158
+
159
+ def _updateAxisView(self):
160
+ with block_signals(self._axisParams):
161
+ if self._axisParams.relative_cor_value not in (None, "..."):
162
+ self.setXShift(self._axisParams.relative_cor_value)
163
+
164
+ self._manualSelectionWidget.setVisible(
165
+ self._axisParams.mode is axis_mode.AxisMode.manual
166
+ )
167
+
168
+ def getAxisParams(self):
169
+ return self._axisParams
170
+
171
+ def _incrementShift(self, direction):
172
+ assert direction in ("left", "right", "top", "bottom")
173
+ if direction == "left":
174
+ self.setXShift(self._xShift - self.getShiftStep())
175
+ elif direction == "right":
176
+ self.setXShift(self._xShift + self.getShiftStep())
177
+ elif direction == "top":
178
+ self.setYShift(self._yShift + self.getShiftStep())
179
+ else:
180
+ self.setYShift(self._yShift - self.getShiftStep())
181
+
182
+ self._shiftControl._updateShiftInfo(x=self._xShift, y=self._yShift)
183
+
184
+ def _resetShift(self):
185
+ with block_signals(self._axisParams):
186
+ self.setXShift(0)
187
+ self.setYShift(0)
188
+ self._shiftControl._updateShiftInfo(x=self._xShift, y=self._yShift)
189
+
190
+ self.sigShiftChanged.emit(self._xShift, self._yShift)
191
+
192
+ def getXShift(self):
193
+ if self._xShift == "...":
194
+ return 0
195
+ return self._xShift
196
+
197
+ def getYShift(self):
198
+ if self._yShift == "...":
199
+ return 0
200
+ return self._yShift
201
+
202
+ def setXShift(self, x: float):
203
+ self.setShift(x=x, y=self._yShift)
204
+
205
+ def setYShift(self, y):
206
+ self.setShift(x=self._xShift, y=y)
207
+
208
+ def setShift(self, x, y):
209
+ if x == self._xShift and y == self._yShift:
210
+ return
211
+ self._xShift = x if x is not None else 0.0
212
+ self._yShift = y if y is not None else 0.0
213
+ if self._axisParams:
214
+ with block_signals(self._axisParams):
215
+ self._axisParams.set_relative_value(x)
216
+ self._shiftControl._updateShiftInfo(x=self._xShift, y=self._yShift)
217
+ if not isinstance(self._xShift, str):
218
+ # filter `...` and `?` values (used for issues or processing)
219
+ self.sigShiftChanged.emit(self._xShift, self._yShift)
220
+
221
+ def reset(self):
222
+ with block_signals(self):
223
+ self.setShift(0, 0)
224
+ self.sigShiftChanged.emit(self._xShift, self._yShift)
225
+
226
+ def setLocked(self, locked):
227
+ self._mainWidget.setEnabled(not locked)
228
+
229
+ def _requestZoomReset(self):
230
+ self.sigResetZoomRequested.emit()
231
+
232
+ # expose API
233
+
234
+ def setEstimatedCor(self, value):
235
+ self._mainWidget.setEstimatedCorValue(value=value)
236
+
237
+ def updateXRotationAxisPixelPositionOnNewScan(self) -> bool:
238
+ return self._mainWidget.updateXRotationAxisPixelPositionOnNewScan()
239
+
240
+ def setUpdateXRotationAxisPixelPositionOnNewScan(self, update: bool):
241
+ self._mainWidget.setUpdateXRotationAxisPixelPositionOnNewScan(update=update)
242
+
243
+ def getEstimatedCor(self):
244
+ return self._mainWidget.getEstimatedCor()
245
+
246
+ def getROIDims(self):
247
+ return self._roiControl.getROIDims()
248
+
249
+ def getShiftStep(self):
250
+ return self._displacementSelector.getStepSize()
251
+
252
+ def setShiftStep(self, value):
253
+ self._displacementSelector.setStepSize(value=value)
254
+
255
+ def getROIOrigin(self):
256
+ return self._roiControl.getROIOrigin()
257
+
258
+ def getImgSubSampling(self):
259
+ return self._imgOpts.getSubSampling()
260
+
261
+ def getMode(self):
262
+ return self._mainWidget.getMode()
263
+
264
+ def isModeLock(self):
265
+ return self._mainWidget.isModeLock()
266
+
267
+ def setModeLock(self, mode):
268
+ return self._mainWidget.setModeLock(mode=mode)
269
+
270
+ def isYAxisInverted(self) -> bool:
271
+ return self._mainWidget.isYAxisInverted()
272
+
273
+ def setYAxisInverted(self, checked: bool):
274
+ return self._mainWidget.setYAxisInverted(checked=checked)
275
+
276
+
277
+ class ManualAxisSelectionWidget(qt.QWidget):
278
+ sigResetZoomRequested = qt.Signal()
279
+ """Signal emitted when a zoom request is necessary (when change to full
280
+ image)"""
281
+
282
+ def __init__(self, parent, shift_mode):
283
+ qt.QWidget.__init__(self, parent)
284
+ self.setLayout(qt.QVBoxLayout())
285
+ self._displacementSelector = StepSizeSelectorWidget(
286
+ parent=self,
287
+ fine_value=0.1,
288
+ medium_value=1.0,
289
+ rough_value=None,
290
+ dtype=float,
291
+ )
292
+ self.layout().addWidget(self._displacementSelector)
293
+
294
+ self._shiftControl = _ShiftControl(parent=self, shift_mode=shift_mode)
295
+ self.layout().addWidget(self._shiftControl)
296
+
297
+ self._roiControl = _ROIControl(parent=self)
298
+ self.layout().addWidget(self._roiControl)
299
+
300
+ self._imgOpts = _ImgOpts(parent=self)
301
+ self.layout().addWidget(self._imgOpts)
302
+
303
+ # connect signal / slot
304
+ self._roiControl.sigResetZoomRequested.connect(self.sigResetZoomRequested)
305
+
306
+
307
+ class _ROIControl(qt.QGroupBox):
308
+ """
309
+ Widget used to define the ROI on images to compare
310
+ """
311
+
312
+ sigRoiChanged = qt.Signal(object)
313
+ """Signal emitted when the ROI changed"""
314
+ sigResetZoomRequested = qt.Signal()
315
+ """Signal emitted when a zoom request is necessary (when change to full
316
+ image)"""
317
+
318
+ def __init__(self, parent):
319
+ qt.QGroupBox.__init__(self, "ROI selection", parent)
320
+ self.setLayout(qt.QVBoxLayout())
321
+
322
+ self._buttonGrp = qt.QButtonGroup(parent=self)
323
+ self._buttonGrp.setExclusive(True)
324
+
325
+ self._roiWidget = qt.QWidget(parent=self)
326
+ self._roiWidget.setLayout(qt.QHBoxLayout())
327
+ self._roiWidget.layout().setContentsMargins(0, 0, 0, 0)
328
+ self._fullImgButton = qt.QRadioButton("full image", parent=self)
329
+ self._buttonGrp.addButton(self._fullImgButton)
330
+ self.layout().addWidget(self._fullImgButton)
331
+ self._roiButton = qt.QRadioButton("ROI", parent=self._roiWidget)
332
+ self._roiWidget.layout().addWidget(self._roiButton)
333
+ self._buttonGrp.addButton(self._roiButton)
334
+ self._roiDefinition = _ROIDefinition(parent=self)
335
+ self._roiWidget.layout().addWidget(self._roiDefinition)
336
+ self.layout().addWidget(self._roiWidget)
337
+
338
+ # connect signal / Slot
339
+ self._roiButton.toggled.connect(self._roiDefinition.setEnabled)
340
+ self._fullImgButton.toggled.connect(self.sigResetZoomRequested)
341
+ self._roiButton.toggled.connect(self.sigResetZoomRequested)
342
+ self._roiDefinition.sigRoiChanged.connect(self.sigRoiChanged)
343
+
344
+ # setup for full image
345
+ self._fullImgButton.setChecked(True)
346
+
347
+ def getROIDims(self):
348
+ if self._roiButton.isChecked():
349
+ return self._roiDefinition.getROIDims()
350
+ else:
351
+ return None
352
+
353
+ def manual_uses_full_image(self, activate):
354
+ if activate:
355
+ self._fullImgButton.setChecked(True)
356
+ else:
357
+ self._roiButton.setChecked(True)
358
+
359
+ # expose API
360
+ def getROIOrigin(self):
361
+ return self._roiDefinition.getROIOrigin()
362
+
363
+ def setLimits(self, width, height):
364
+ self._roiDefinition.setLimits(width=width, height=height)
365
+
366
+ def setScan(self, scan):
367
+ self._roiDefinition.setScan(scan=scan)
368
+
369
+
370
+ class _ROIDefinition(qt.QWidget):
371
+ """
372
+ Widget used to define ROI width and height.
373
+
374
+ :note: emit ROI == None if setDisabled
375
+ """
376
+
377
+ sigRoiChanged = qt.Signal(object)
378
+ """Signal emitted when the ROI changed"""
379
+
380
+ def __init__(self, parent):
381
+ qt.QWidget.__init__(self, parent)
382
+ self.setLayout(qt.QGridLayout())
383
+ self._already_set = False
384
+
385
+ # width & height
386
+ self.layout().addWidget(qt.QLabel("dims", self), 0, 0)
387
+ self._widthSB = qt.QSpinBox(parent=self)
388
+ self._widthSB.setSingleStep(2)
389
+ self._widthSB.setMaximum(10000)
390
+ self._widthSB.setSuffix(" px")
391
+ self._widthSB.setPrefix("w: ")
392
+ self._widthSB.setToolTip("ROI width")
393
+ self.layout().addWidget(self._widthSB, 0, 1)
394
+ self._heightSB = qt.QSpinBox(parent=self)
395
+ self._heightSB.setSingleStep(2)
396
+ self._heightSB.setSuffix(" px")
397
+ self._heightSB.setPrefix("h: ")
398
+ self._heightSB.setToolTip("ROI height")
399
+ self._heightSB.setMaximum(10000)
400
+ self.layout().addWidget(self._heightSB, 0, 2)
401
+
402
+ # origin x and y position
403
+ self.layout().addWidget(qt.QLabel("origin", self), 1, 0)
404
+ self._xOriginSB = qt.QSpinBox(parent=self)
405
+ self._xOriginSB.setSingleStep(10)
406
+ self._xOriginSB.setMaximum(10000)
407
+ self._xOriginSB.setPrefix("x: ")
408
+ self.layout().addWidget(self._xOriginSB, 1, 1)
409
+ self._yOriginSB = qt.QSpinBox(parent=self)
410
+ self._yOriginSB.setSingleStep(10)
411
+ self._yOriginSB.setPrefix("y: ")
412
+ self._yOriginSB.setMaximum(10000)
413
+ self.layout().addWidget(self._yOriginSB, 1, 2)
414
+
415
+ # Signal / Slot connection
416
+ self._widthSB.editingFinished.connect(self.__roiChanged)
417
+ self._heightSB.editingFinished.connect(self.__roiChanged)
418
+ self._xOriginSB.editingFinished.connect(self.__roiChanged)
419
+ self._yOriginSB.editingFinished.connect(self.__roiChanged)
420
+
421
+ def __roiChanged(self, *args, **kwargs):
422
+ self.sigRoiChanged.emit((self.getROIDims(), self.getROIOrigin()))
423
+
424
+ def setLimits(self, width, height):
425
+ """
426
+
427
+ :param x: width maximum value
428
+ :param height: height maximum value
429
+ """
430
+ for spinButton in (self._widthSB, self._heightSB):
431
+ spinButton.blockSignals(True)
432
+ assert type(width) is int
433
+ assert type(height) is int
434
+ valueChanged = False
435
+ if self._widthSB.value() > width:
436
+ self._widthSB.setValue(width)
437
+ valueChanged = True
438
+ if self._heightSB.value() > height:
439
+ self._heightSB.setValue(height)
440
+ valueChanged = True
441
+
442
+ # if this is the first limit definition, propose default width and
443
+ # height
444
+ if self._widthSB.value() == 0:
445
+ self._widthSB.setValue(min(256, width))
446
+ valueChanged = True
447
+ if self._heightSB.value() == 0:
448
+ self._heightSB.setValue(min(256, height))
449
+ valueChanged = True
450
+
451
+ # define minimum / maximum
452
+ self._widthSB.setRange(1, width)
453
+ self._heightSB.setRange(1, height)
454
+ for spinButton in (self._widthSB, self._heightSB):
455
+ spinButton.blockSignals(False)
456
+ if valueChanged is True:
457
+ self.__roiChanged()
458
+
459
+ def getROIDims(self) -> tuple | None:
460
+ """
461
+
462
+ :return: (width, height) or None
463
+ """
464
+ if self.isEnabled():
465
+ return (self._widthSB.value(), self._heightSB.value())
466
+ else:
467
+ return None
468
+
469
+ def getROIOrigin(self):
470
+ return (self._xOriginSB.value(), self._yOriginSB.value())
471
+
472
+ def setEnabled(self, *arg, **kwargs):
473
+ qt.QWidget.setEnabled(self, *arg, **kwargs)
474
+ self.__roiChanged()
475
+
476
+ def setScan(self, scan):
477
+ if not self._already_set:
478
+ self._already_set = True
479
+ try:
480
+ x_origin = scan.dim_1 // 2
481
+ y_origin = scan.dim_2 // 2
482
+ self._xOriginSB.setValue(x_origin)
483
+ self._yOriginSB.setValue(y_origin)
484
+ except Exception:
485
+ _logger.warning(f"unable to determine origin for {scan}")
486
+
487
+
488
+ class AxisSettingsTabWidget(qt.QTabWidget):
489
+ """
490
+ TabWidget containing all the settings of the AxisTask
491
+ """
492
+
493
+ sigLockModeChanged = qt.Signal(bool)
494
+ """signal emitted when the mode lock change"""
495
+
496
+ sigUrlChanged = qt.Signal()
497
+ """Signal emit when frames urls changed"""
498
+
499
+ sigModeChanged = qt.Signal(str)
500
+ """Signal emit when mode (algorithm) is changed"""
501
+
502
+ sigUpdateXRotAxisPixelPosOnNewScan = qt.Signal()
503
+
504
+ def __init__(
505
+ self,
506
+ recons_params: QAxisRP | None,
507
+ parent=None,
508
+ ):
509
+ """
510
+
511
+ :param recons_params: reconstruction parameters edited by the widget
512
+ """
513
+ qt.QTabWidget.__init__(self, parent)
514
+ assert recons_params is not None
515
+ # first tab 'calculation widget'
516
+ self._calculationWidget = CalculationWidget(
517
+ parent=self, axis_params=recons_params
518
+ )
519
+
520
+ # second tab: options
521
+ self._optionsWidget = AxisOptionsWidget(parent=self, axis_params=recons_params)
522
+ self._inputWidget = InputWidget(parent=self, axis_params=recons_params)
523
+
524
+ for widget in self._calculationWidget, self._optionsWidget:
525
+ spacer = qt.QWidget(self)
526
+ spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding)
527
+ widget.layout().addWidget(spacer)
528
+
529
+ self.addTab(self._calculationWidget, "calculation")
530
+ self.addTab(self._optionsWidget, "options")
531
+ # simplify set up. Hide options
532
+ self.addTab(self._inputWidget, "input")
533
+
534
+ # set up
535
+ self.setAxisParams(recons_params)
536
+ self._updatePossibleInput()
537
+
538
+ # connect signal / slot
539
+ self._calculationWidget.sigLockModeChanged.connect(self.sigLockModeChanged)
540
+ self.sigModeChanged.connect(self._updatePossibleInput)
541
+ self.sigModeChanged.connect(self._updatePossibleOptions)
542
+ self._inputWidget._sigUrlChanged.connect(self._urlChanged)
543
+ self._calculationWidget.sigModeChanged.connect(self.sigModeChanged)
544
+ self._calculationWidget.sigUpdateXRotAxisPixelPosOnNewScan.connect(
545
+ self.sigUpdateXRotAxisPixelPosOnNewScan
546
+ )
547
+
548
+ def _urlChanged(self):
549
+ self.sigUrlChanged.emit()
550
+
551
+ def setScan(self, scan):
552
+ if scan is not None:
553
+ self._calculationWidget.setScan(scan)
554
+ self._inputWidget.setScan(scan)
555
+
556
+ def setAxisParams(self, axis):
557
+ with block_signals(self):
558
+ self._calculationWidget.setAxisParams(axis)
559
+ self._optionsWidget.setAxisParams(axis)
560
+ self._inputWidget.setAxisParams(axis)
561
+
562
+ def _updatePossibleInput(self):
563
+ """Update Input tab according to the current mode"""
564
+ current_mode = self.getMode()
565
+ valid_inputs = axis_mode.AXIS_MODE_METADATAS[current_mode].valid_inputs
566
+ if valid_inputs is None:
567
+ self._inputWidget.setEnabled(False)
568
+ else:
569
+ self._inputWidget.setEnabled(True)
570
+ self._inputWidget.setValidInputs(valid_inputs)
571
+
572
+ def _updatePossibleOptions(self):
573
+ mode = self.getMode()
574
+ self._optionsWidget.setMode(mode)
575
+
576
+ # expose API
577
+ def isModeLock(self) -> bool:
578
+ return self._calculationWidget.isModeLock()
579
+
580
+ def setModeLock(self, mode):
581
+ self._calculationWidget.setModeLock(mode=mode)
582
+
583
+ def setEstimatedCorValue(self, value):
584
+ self._calculationWidget.setEstimatedCorValue(value=value)
585
+
586
+ def getEstimatedCor(self):
587
+ return self._calculationWidget.getEstimatedCor()
588
+
589
+ def updateXRotationAxisPixelPositionOnNewScan(self) -> bool:
590
+ return self._calculationWidget.updateXRotationAxisPixelPositionOnNewScan()
591
+
592
+ def setUpdateXRotationAxisPixelPositionOnNewScan(self, update: bool):
593
+ self._calculationWidget.setUpdateXRotationAxisPixelPositionOnNewScan(
594
+ update=update
595
+ )
596
+
597
+ def getMode(self):
598
+ """Return algorithm to use for axis calculation"""
599
+ return self._calculationWidget.getMode()
600
+
601
+ def isYAxisInverted(self) -> bool:
602
+ return self._calculationWidget._estimatedCorWidget.isYAxisInverted()
603
+
604
+ def setYAxisInverted(self, checked: bool):
605
+ return self._calculationWidget._estimatedCorWidget.setYAxisInverted(
606
+ checked=checked
607
+ )
608
+
609
+
610
+ class _ShiftControl(qt.QWidget):
611
+ """
612
+ Widget to control the shift step we want to apply
613
+ """
614
+
615
+ sigShiftLeft = qt.Signal()
616
+ """Signal emitted when the left button is activated"""
617
+ sigShiftRight = qt.Signal()
618
+ """Signal emitted when the right button is activated"""
619
+ sigShiftTop = qt.Signal()
620
+ """Signal emitted when the top button is activated"""
621
+ sigShiftBottom = qt.Signal()
622
+ """Signal emitted when the bottom button is activated"""
623
+ sigReset = qt.Signal()
624
+ """Signal emitted when the reset button is activated"""
625
+ sigAuto = qt.Signal()
626
+ """Signal emitted when the auto button is activated"""
627
+ sigShiftChanged = qt.Signal(float, float)
628
+ """Signal emitted ony when xLE and yLE edition is finished"""
629
+
630
+ def __init__(self, parent, shift_mode: ShiftMode):
631
+ """
632
+
633
+ :param parent: qt.QWidget
634
+ :param shift_mode: what are the shift we want to control
635
+ """
636
+ qt.QWidget.__init__(self, parent)
637
+ self.setLayout(qt.QGridLayout())
638
+ self.layout().setContentsMargins(0, 0, 0, 0)
639
+
640
+ self._leftButton = qt.QPushButton("left", parent=self)
641
+ self.layout().addWidget(self._leftButton, 1, 0)
642
+
643
+ self._rightButton = qt.QPushButton("right", parent=self)
644
+ self.layout().addWidget(self._rightButton, 1, 3)
645
+
646
+ self._shiftInfo = _ShiftInformation(parent=self)
647
+ self.layout().addWidget(self._shiftInfo, 1, 1)
648
+ self._shiftInfo._updateShiftInfo(x=0.0, y=0.0)
649
+
650
+ self._topButton = qt.QPushButton("top", parent=self)
651
+ self.layout().addWidget(self._topButton, 0, 1)
652
+
653
+ self._bottomButton = qt.QPushButton("bottom", parent=self)
654
+ self.layout().addWidget(self._bottomButton, 2, 1)
655
+
656
+ self._resetButton = qt.QPushButton("reset", parent=self)
657
+ self.layout().addWidget(self._resetButton, 3, 2, 3, 4)
658
+
659
+ self._autoButton = qt.QPushButton("auto", parent=self)
660
+ self.layout().addWidget(self._autoButton, 3, 0, 3, 2)
661
+ self._autoButton.hide()
662
+
663
+ # Signal / Slot connection
664
+ self._leftButton.pressed.connect(self.sigShiftLeft.emit)
665
+ self._rightButton.pressed.connect(self.sigShiftRight.emit)
666
+ self._topButton.pressed.connect(self.sigShiftTop.emit)
667
+ self._bottomButton.pressed.connect(self.sigShiftBottom.emit)
668
+ self._resetButton.pressed.connect(self.sigReset.emit)
669
+ self._autoButton.pressed.connect(self.sigAuto.emit)
670
+ self._shiftInfo.sigShiftChanged.connect(self.sigShiftChanged.emit)
671
+
672
+ # expose API
673
+ self._updateShiftInfo = self._shiftInfo._updateShiftInfo
674
+
675
+ self.setShiftMode(shift_mode)
676
+
677
+ def setShiftMode(self, shift_mode):
678
+ show_x_shift = shift_mode in (ShiftMode.x_only, ShiftMode.x_and_y)
679
+ show_y_shift = shift_mode in (ShiftMode.y_only, ShiftMode.x_and_y)
680
+ self._leftButton.setVisible(show_x_shift)
681
+ self._rightButton.setVisible(show_x_shift)
682
+ self._topButton.setVisible(show_y_shift)
683
+ self._bottomButton.setVisible(show_y_shift)
684
+ self._shiftInfo._xLE.setVisible(show_x_shift)
685
+ self._shiftInfo._xLabel.setVisible(show_x_shift)
686
+ self._shiftInfo._yLE.setVisible(show_y_shift)
687
+ self._shiftInfo._yLabel.setVisible(show_y_shift)
688
+
689
+
690
+ class _ImgOpts(qt.QGroupBox):
691
+ sigSubSamplingChanged = qt.Signal()
692
+ """Signal emitted when the sub sampling change"""
693
+
694
+ def __init__(self, parent, title="Image Option"):
695
+ super().__init__(title, parent)
696
+ self.setLayout(qt.QFormLayout())
697
+ self._subSamplingQSpinBox = qt.QSpinBox(self)
698
+ self.layout().addRow("sub-sampling:", self._subSamplingQSpinBox)
699
+ self._subSamplingQSpinBox.setMinimum(1)
700
+
701
+ # set up
702
+ self._subSamplingQSpinBox.setValue(1)
703
+
704
+ # connect signal / slot
705
+ self._subSamplingQSpinBox.valueChanged.connect(self._subSamplingChanged)
706
+
707
+ def _subSamplingChanged(self):
708
+ self.sigSubSamplingChanged.emit()
709
+
710
+ def getSubSampling(self):
711
+ return self._subSamplingQSpinBox.value()
712
+
713
+ def setSubSampling(self, value):
714
+ return self._subSamplingQSpinBox.setValue(int(value))
715
+
716
+
717
+ class _ShiftInformation(qt.QWidget):
718
+ """
719
+ Widget displaying information about the current x and y shift.
720
+ Both x shift and y shift are editable.
721
+ """
722
+
723
+ class _ShiftLineEdit(qt.QLineEdit):
724
+ def __init__(self, *args, **kwargs):
725
+ qt.QLineEdit.__init__(self, *args, **kwargs)
726
+ self._defaultBackgroundColor = None
727
+ # validator
728
+ validator = qt.QDoubleValidator(parent=self, decimals=2)
729
+ self.setValidator(validator)
730
+ self._getDefaultBackgroundColor()
731
+ # connect signal / slot
732
+ self.textEdited.connect(self._userEditing)
733
+ self.editingFinished.connect(self._userEndEditing)
734
+
735
+ def sizeHint(self):
736
+ return qt.QSize(40, 10)
737
+
738
+ def _getDefaultBackgroundColor(self):
739
+ if self._defaultBackgroundColor is None:
740
+ self._defaultBackgroundColor = self.palette().color(
741
+ self.backgroundRole()
742
+ )
743
+ return self._defaultBackgroundColor
744
+
745
+ def _userEditing(self, *args, **kwargs):
746
+ palette = self.palette()
747
+ palette.setColor(self.backgroundRole(), EDITING_BACKGROUND_COLOR)
748
+ self.setPalette(palette)
749
+
750
+ def _userEndEditing(self, *args, **kwargs):
751
+ palette = self.palette()
752
+ palette.setColor(
753
+ self.backgroundRole(),
754
+ self._getDefaultBackgroundColor(),
755
+ )
756
+ self.setPalette(palette)
757
+
758
+ sigShiftChanged = qt.Signal(float, float)
759
+ """Signal emitted ony when xLE and yLE edition is finished"""
760
+
761
+ def __init__(self, parent):
762
+ qt.QWidget.__init__(self, parent)
763
+ self.setLayout(qt.QHBoxLayout())
764
+ self.layout().setContentsMargins(0, 0, 0, 0)
765
+ self.layout().setSpacing(0)
766
+
767
+ self._xLabel = qt.QLabel("x=", parent=self)
768
+ self.layout().addWidget(self._xLabel)
769
+ self._xLE = _ShiftInformation._ShiftLineEdit("", parent=self)
770
+ self.layout().addWidget(self._xLE)
771
+
772
+ self._yLabel = qt.QLabel("y=", parent=self)
773
+ self.layout().addWidget(self._yLabel)
774
+ self._yLE = _ShiftInformation._ShiftLineEdit("", parent=self)
775
+ self.layout().addWidget(self._yLE)
776
+
777
+ # connect Signal / Slot
778
+ self._xLE.editingFinished.connect(self._shiftChanged)
779
+ self._yLE.editingFinished.connect(self._shiftChanged)
780
+
781
+ def _updateShiftInfo(self, x, y):
782
+ with block_signals(self):
783
+ if x is None:
784
+ x = 0.0
785
+ if y is None:
786
+ y = 0.0
787
+ x_text = x
788
+ if x_text != "...":
789
+ x_text = "%.1f" % float(x)
790
+ y_text = y
791
+ if y_text != "...":
792
+ y_text = "%.1f" % float(y)
793
+ self._xLE.setText(x_text)
794
+ self._yLE.setText(y_text)
795
+
796
+ def _shiftChanged(self, *args, **kwargs):
797
+ self.sigShiftChanged.emit(float(self._xLE.text()), float(self._yLE.text()))