tomwer 1.3.27__py3-none-any.whl → 1.4.0rc0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (632) 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 +48 -49
  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 +40 -85
  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 -7
  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 +7 -4
  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 +63 -111
  138. tomwer/core/process/reconstruction/axis/mode.py +5 -3
  139. tomwer/core/process/reconstruction/axis/params.py +5 -146
  140. tomwer/core/process/reconstruction/axis/projectiontype.py +0 -28
  141. tomwer/core/process/reconstruction/darkref/darkrefs.py +14 -39
  142. tomwer/core/process/reconstruction/darkref/darkrefscopy.py +7 -39
  143. tomwer/core/process/reconstruction/darkref/params.py +1 -28
  144. tomwer/core/process/reconstruction/nabu/castvolume.py +19 -34
  145. tomwer/core/process/reconstruction/nabu/nabucommon.py +18 -43
  146. tomwer/core/process/reconstruction/nabu/nabuscores.py +47 -48
  147. tomwer/core/process/reconstruction/nabu/nabuslices.py +59 -105
  148. tomwer/core/process/reconstruction/nabu/nabuvolume.py +44 -70
  149. tomwer/core/process/reconstruction/nabu/plane.py +10 -0
  150. tomwer/core/process/reconstruction/nabu/settings.py +1 -28
  151. tomwer/core/process/reconstruction/nabu/target.py +0 -28
  152. tomwer/core/process/reconstruction/nabu/test/test_castvolume.py +116 -0
  153. tomwer/core/process/reconstruction/nabu/test/test_nabu_utils.py +277 -0
  154. tomwer/core/process/reconstruction/nabu/test/test_nabunormalization.py +199 -0
  155. tomwer/core/process/reconstruction/nabu/utils.py +11 -60
  156. tomwer/core/process/reconstruction/normalization/normalization.py +2 -32
  157. tomwer/core/process/reconstruction/normalization/params.py +3 -35
  158. tomwer/core/process/reconstruction/output.py +14 -19
  159. tomwer/core/process/reconstruction/paramsbase.py +4 -33
  160. tomwer/core/process/reconstruction/saaxis/params.py +5 -33
  161. tomwer/core/process/reconstruction/saaxis/saaxis.py +18 -47
  162. tomwer/core/process/reconstruction/sadeltabeta/params.py +2 -31
  163. tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py +16 -44
  164. tomwer/core/process/reconstruction/scores/params.py +9 -39
  165. tomwer/core/process/reconstruction/scores/scores.py +10 -42
  166. tomwer/core/process/reconstruction/tests/__init__.py +0 -0
  167. tomwer/core/process/reconstruction/tests/test_axis.py +46 -0
  168. tomwer/core/process/reconstruction/tests/test_darkref.py +33 -0
  169. tomwer/core/process/reconstruction/{test → tests}/test_saaxis.py +1 -27
  170. tomwer/core/process/reconstruction/tests/test_sadeltabeta.py +48 -0
  171. tomwer/core/process/script/python.py +1 -27
  172. tomwer/core/process/script/tests/test_script.py +41 -0
  173. tomwer/core/process/stitching/metadataholder.py +5 -4
  174. tomwer/core/process/stitching/nabustitcher.py +35 -5
  175. tomwer/core/process/stitching/tests/test_metadataholder.py +17 -0
  176. tomwer/core/process/task.py +20 -63
  177. tomwer/core/process/tests/__init__.py +0 -0
  178. tomwer/core/process/{test → tests}/test_axis.py +1 -79
  179. tomwer/core/process/{test → tests}/test_conditions.py +1 -28
  180. tomwer/core/process/{test → tests}/test_dark_and_flat.py +1 -27
  181. tomwer/core/process/{test → tests}/test_data_listener.py +1 -27
  182. tomwer/core/process/{test → tests}/test_data_transfer.py +2 -28
  183. tomwer/core/process/{test → tests}/test_data_watcher.py +1 -27
  184. tomwer/core/process/{test → tests}/test_nabu.py +4 -33
  185. tomwer/core/process/{test → tests}/test_normalization.py +1 -26
  186. tomwer/core/process/{test → tests}/test_timer.py +1 -27
  187. tomwer/core/process/utils.py +2 -31
  188. tomwer/core/process/visualization/dataviewer.py +1 -26
  189. tomwer/core/process/visualization/diffviewer.py +1 -26
  190. tomwer/core/process/visualization/imagestackviewer.py +0 -26
  191. tomwer/core/process/visualization/radiostack.py +0 -26
  192. tomwer/core/process/visualization/samplemoved.py +0 -28
  193. tomwer/core/process/visualization/sinogramviewer.py +0 -27
  194. tomwer/core/process/visualization/slicestack.py +0 -28
  195. tomwer/core/process/visualization/tests/test_data_viewer.py +12 -0
  196. tomwer/core/process/visualization/tests/test_diff_viewer.py +12 -0
  197. tomwer/core/process/visualization/tests/test_image_stack_viewer.py +14 -0
  198. tomwer/core/process/visualization/tests/test_radio_stack.py +12 -0
  199. tomwer/core/process/visualization/tests/test_sample_moved.py +14 -0
  200. tomwer/core/process/visualization/tests/test_sinogram_viewer.py +13 -0
  201. tomwer/core/process/visualization/tests/test_slice_stack.py +13 -0
  202. tomwer/core/process/visualization/tests/test_volume_viewer.py +12 -0
  203. tomwer/core/process/visualization/volumeviewer.py +0 -29
  204. tomwer/core/scan/__init__.py +3 -27
  205. tomwer/core/scan/blissscan.py +5 -34
  206. tomwer/core/scan/edfscan.py +19 -53
  207. tomwer/core/scan/hdf5scan.py +2 -2
  208. tomwer/core/scan/nxtomoscan.py +46 -54
  209. tomwer/core/scan/scanbase.py +104 -200
  210. tomwer/core/scan/scanfactory.py +11 -41
  211. tomwer/core/scan/tests/__init__.py +0 -0
  212. tomwer/core/scan/tests/test_edf.py +25 -0
  213. tomwer/core/scan/tests/test_future_scan.py +35 -0
  214. tomwer/core/scan/tests/test_nxtomoscan.py +143 -0
  215. tomwer/core/scan/{test → tests}/test_process_registration.py +1 -28
  216. tomwer/core/settings.py +18 -40
  217. tomwer/core/tests/__init__.py +0 -0
  218. tomwer/core/tests/test_scanutils.py +26 -0
  219. tomwer/core/{test → tests}/test_utils.py +1 -28
  220. tomwer/core/tomwer_object.py +4 -0
  221. tomwer/core/utils/__init__.py +2 -0
  222. tomwer/core/utils/char.py +0 -28
  223. tomwer/core/utils/deprecation.py +12 -38
  224. tomwer/core/utils/dictutils.py +1 -3
  225. tomwer/core/utils/ftseriesutils.py +1 -27
  226. tomwer/core/utils/gpu.py +0 -28
  227. tomwer/core/utils/image.py +8 -39
  228. tomwer/core/utils/locker.py +1 -28
  229. tomwer/core/utils/logconfig.py +0 -27
  230. tomwer/core/utils/normalization.py +4 -31
  231. tomwer/core/utils/nxtomoutils.py +8 -38
  232. tomwer/core/utils/resource.py +0 -26
  233. tomwer/core/utils/scanutils.py +23 -52
  234. tomwer/core/utils/slurm.py +7 -30
  235. tomwer/core/utils/spec.py +6 -6
  236. tomwer/core/utils/tests/__init__.py +0 -0
  237. tomwer/core/utils/tests/test_image.py +30 -0
  238. tomwer/core/utils/tests/test_nxtomo.py +38 -0
  239. tomwer/core/utils/tests/test_scan_utils.py +46 -0
  240. tomwer/core/utils/tests/test_time.py +6 -0
  241. tomwer/core/utils/threads.py +0 -26
  242. tomwer/core/utils/time.py +0 -27
  243. tomwer/core/volume/__init__.py +4 -0
  244. tomwer/core/volume/edfvolume.py +1 -28
  245. tomwer/core/volume/hdf5volume.py +1 -28
  246. tomwer/core/volume/jp2kvolume.py +1 -27
  247. tomwer/core/volume/rawvolume.py +1 -28
  248. tomwer/core/volume/tests/test_volumes.py +21 -0
  249. tomwer/core/volume/tiffvolume.py +1 -28
  250. tomwer/core/volume/volumebase.py +5 -0
  251. tomwer/core/volume/volumefactory.py +7 -33
  252. tomwer/gui/__init__.py +0 -28
  253. tomwer/gui/cluster/__init__.py +2 -0
  254. tomwer/gui/cluster/slurm.py +297 -95
  255. tomwer/gui/cluster/supervisor.py +1 -27
  256. tomwer/gui/cluster/tests/__init__.py +0 -0
  257. tomwer/gui/cluster/{test → tests}/test_cluster.py +21 -26
  258. tomwer/gui/cluster/{test → tests}/test_supervisor.py +1 -27
  259. tomwer/gui/conditions/__init__.py +2 -0
  260. tomwer/gui/conditions/filter.py +1 -26
  261. tomwer/gui/configuration/__init__.py +2 -0
  262. tomwer/gui/control/__init__.py +2 -0
  263. tomwer/gui/control/actions.py +2 -28
  264. tomwer/gui/control/datadiscovery.py +4 -3
  265. tomwer/gui/control/datalist.py +64 -69
  266. tomwer/gui/control/datalistener.py +1 -39
  267. tomwer/gui/control/datareacheractions.py +1 -28
  268. tomwer/gui/control/datatransfert.py +2 -29
  269. tomwer/gui/control/datavalidator.py +3 -37
  270. tomwer/gui/control/datawatcher/__init__.py +0 -28
  271. tomwer/gui/control/datawatcher/configuration.py +1 -28
  272. tomwer/gui/control/datawatcher/datawatcher.py +3 -32
  273. tomwer/gui/control/datawatcher/datawatcherobserver.py +2 -28
  274. tomwer/gui/control/history.py +5 -35
  275. tomwer/gui/control/nxtomomill.py +3 -30
  276. tomwer/gui/control/observations.py +61 -55
  277. tomwer/gui/control/reducedarkflatselector.py +24 -20
  278. tomwer/gui/control/scanselectorwidget.py +2 -28
  279. tomwer/gui/control/selectorwidgetbase.py +17 -17
  280. tomwer/gui/control/series/__init__.py +0 -0
  281. tomwer/gui/control/{serie/seriecreator.py → series/seriescreator.py} +214 -235
  282. tomwer/gui/control/series/serieswaiter.py +0 -0
  283. tomwer/gui/control/series/test/test_creator.py +424 -0
  284. tomwer/gui/control/series/test/test_nxtomo_concatenate.py +21 -0
  285. tomwer/gui/control/singletomoobj.py +1 -1
  286. tomwer/gui/control/tests/__init__.py +0 -0
  287. tomwer/gui/control/tests/test_datalist.py +47 -0
  288. tomwer/gui/control/{test → tests}/test_datalistener.py +1 -28
  289. tomwer/gui/control/tests/test_datavalidator.py +27 -0
  290. tomwer/gui/control/{test → tests}/test_inputwidget.py +1 -27
  291. tomwer/gui/control/tests/test_process_manager.py +38 -0
  292. tomwer/gui/control/tests/test_scan_observations.py +23 -0
  293. tomwer/gui/control/tests/test_scanselector.py +42 -0
  294. tomwer/gui/control/{test → tests}/test_scanvalidator.py +1 -27
  295. tomwer/gui/control/{test → tests}/test_volume_dialog.py +2 -30
  296. tomwer/gui/control/{test → tests}/test_volumeselector.py +1 -27
  297. tomwer/gui/control/volumeselectorwidget.py +2 -30
  298. tomwer/gui/dataportal/__init__.py +2 -0
  299. tomwer/gui/{icat → dataportal}/createscreenshots.py +3 -2
  300. tomwer/gui/dataportal/gallery.py +133 -0
  301. tomwer/gui/dataportal/outputformat.py +0 -0
  302. tomwer/gui/dataportal/publish.py +96 -0
  303. tomwer/gui/dataportal/tests/test_create_screenshots_gui.py +23 -0
  304. tomwer/gui/dataportal/tests/test_gallery_gui.py +21 -0
  305. tomwer/gui/debugtools/__init__.py +2 -0
  306. tomwer/gui/debugtools/datasetgenerator.py +1 -30
  307. tomwer/gui/debugtools/objectinspector.py +1 -29
  308. tomwer/gui/dialog/QDataDialog.py +89 -0
  309. tomwer/gui/{qfolderdialog.py → dialog/QVolumeDialog.py} +8 -107
  310. tomwer/gui/dialog/__init__.py +1 -0
  311. tomwer/gui/edit/__init__.py +2 -0
  312. tomwer/gui/edit/dkrfpatch.py +52 -87
  313. tomwer/gui/edit/imagekeyeditor.py +18 -54
  314. tomwer/gui/edit/nxtomoeditor.py +113 -300
  315. tomwer/gui/edit/nxtomowarmer.py +3 -2
  316. tomwer/gui/edit/tests/__init__.py +0 -0
  317. tomwer/gui/edit/{test → tests}/test_dkrf_patch.py +3 -29
  318. tomwer/gui/edit/{test → tests}/test_image_key_editor.py +1 -27
  319. tomwer/gui/edit/{test → tests}/test_nx_editor.py +45 -23
  320. tomwer/gui/icons.py +28 -66
  321. tomwer/gui/illustrations.py +4 -34
  322. tomwer/gui/imagefromfile.py +5 -30
  323. tomwer/gui/metadataloader.py +36 -0
  324. tomwer/gui/qconfigfile.py +3 -0
  325. tomwer/gui/qlefilesystem.py +3 -0
  326. tomwer/gui/reconstruction/__init__.py +2 -0
  327. tomwer/gui/reconstruction/axis/AxisMainWindow.py +264 -0
  328. tomwer/gui/reconstruction/axis/AxisOptionsWidget.py +153 -0
  329. tomwer/gui/reconstruction/axis/AxisSettingsWidget.py +776 -0
  330. tomwer/gui/reconstruction/axis/AxisWidget.py +526 -0
  331. tomwer/gui/reconstruction/axis/CalculationWidget.py +374 -0
  332. tomwer/gui/reconstruction/axis/CompareImages.py +11 -44
  333. tomwer/gui/reconstruction/axis/ControlWidget.py +277 -0
  334. tomwer/gui/reconstruction/axis/InputWidget.py +491 -0
  335. tomwer/gui/reconstruction/axis/ManualFramesSelection.py +168 -0
  336. tomwer/gui/reconstruction/axis/__init__.py +2 -2
  337. tomwer/gui/reconstruction/darkref/__init__.py +0 -27
  338. tomwer/gui/reconstruction/darkref/darkrefcopywidget.py +5 -34
  339. tomwer/gui/reconstruction/darkref/darkrefwidget.py +1 -27
  340. tomwer/gui/reconstruction/nabu/castvolume.py +40 -59
  341. tomwer/gui/reconstruction/nabu/check.py +7 -33
  342. tomwer/gui/reconstruction/nabu/nabuconfig/base.py +7 -34
  343. tomwer/gui/reconstruction/nabu/nabuconfig/ctf.py +6 -5
  344. tomwer/gui/reconstruction/nabu/nabuconfig/nabuconfig.py +10 -69
  345. tomwer/gui/reconstruction/nabu/nabuconfig/output.py +3 -47
  346. tomwer/gui/reconstruction/nabu/nabuconfig/phase.py +54 -36
  347. tomwer/gui/reconstruction/nabu/nabuconfig/preprocessing.py +103 -54
  348. tomwer/gui/reconstruction/nabu/nabuconfig/reconstruction.py +116 -65
  349. tomwer/gui/reconstruction/nabu/nabuflow.py +31 -61
  350. tomwer/gui/reconstruction/nabu/platform.py +94 -0
  351. tomwer/gui/reconstruction/nabu/slices.py +81 -45
  352. tomwer/gui/reconstruction/nabu/slurm.py +1 -27
  353. tomwer/gui/reconstruction/nabu/test/test_cast_volume.py +82 -0
  354. tomwer/gui/reconstruction/nabu/test/test_check.py +66 -0
  355. tomwer/gui/reconstruction/nabu/test/test_ctf.py +46 -0
  356. tomwer/gui/reconstruction/nabu/test/test_helical.py +21 -0
  357. tomwer/gui/reconstruction/nabu/test/test_nabu_preprocessing.py +81 -0
  358. tomwer/gui/reconstruction/nabu/volume.py +62 -90
  359. tomwer/gui/reconstruction/normalization/intensity.py +5 -32
  360. tomwer/gui/reconstruction/normalization/test/test_intensity.py +89 -0
  361. tomwer/gui/reconstruction/saaxis/corrangeselector.py +16 -49
  362. tomwer/gui/reconstruction/saaxis/dimensionwidget.py +56 -96
  363. tomwer/gui/reconstruction/saaxis/saaxis.py +17 -38
  364. tomwer/gui/reconstruction/saaxis/sliceselector.py +8 -39
  365. tomwer/gui/reconstruction/sadeltabeta/saadeltabeta.py +19 -37
  366. tomwer/gui/reconstruction/scores/control.py +2 -30
  367. tomwer/gui/reconstruction/scores/scoreplot.py +19 -48
  368. tomwer/gui/reconstruction/tests/__init__.py +0 -0
  369. tomwer/gui/reconstruction/{test → tests}/test_axis.py +23 -49
  370. tomwer/gui/reconstruction/{test → tests}/test_nabu.py +8 -31
  371. tomwer/gui/reconstruction/{test → tests}/test_saaxis.py +10 -37
  372. tomwer/gui/reconstruction/{test → tests}/test_sadeltabeta.py +1 -26
  373. tomwer/gui/samplemoved/__init__.py +2 -30
  374. tomwer/gui/samplemoved/selectiontable.py +3 -33
  375. tomwer/gui/settings.py +7 -0
  376. tomwer/gui/stackplot.py +33 -661
  377. tomwer/gui/stacks.py +261 -135
  378. tomwer/gui/stitching/SingleAxisStitchingWidget.py +326 -0
  379. tomwer/gui/stitching/StitchingOptionsWidget.py +438 -0
  380. tomwer/gui/stitching/StitchingWindow.py +586 -0
  381. tomwer/gui/stitching/__init__.py +2 -0
  382. tomwer/gui/stitching/alignment.py +90 -0
  383. tomwer/gui/stitching/axisorderedlist.py +44 -34
  384. tomwer/gui/stitching/config/axisparams.py +23 -11
  385. tomwer/gui/stitching/config/output.py +6 -5
  386. tomwer/gui/stitching/config/positionoveraxis.py +313 -51
  387. tomwer/gui/stitching/config/stitchingstrategies.py +22 -16
  388. tomwer/gui/stitching/config/tests/test_axisparams.py +25 -0
  389. tomwer/gui/stitching/config/tomoobjdetails.py +3 -5
  390. tomwer/gui/stitching/normalization.py +1 -0
  391. tomwer/gui/stitching/preview.py +59 -0
  392. tomwer/gui/stitching/singleaxis.py +57 -0
  393. tomwer/gui/stitching/stitchandbackground.py +3 -2
  394. tomwer/gui/stitching/stitching_preview.py +44 -36
  395. tomwer/gui/stitching/stitching_raw.py +5 -3
  396. tomwer/gui/stitching/tests/test_ZStitchingWindow.py +88 -0
  397. tomwer/gui/stitching/tests/test_axis_ordered_list.py +21 -0
  398. tomwer/gui/stitching/tests/test_normalization.py +27 -0
  399. tomwer/gui/stitching/tests/test_preview.py +68 -0
  400. tomwer/gui/stitching/tests/test_stitching_raw.py +110 -0
  401. tomwer/gui/stitching/tests/utils.py +92 -0
  402. tomwer/gui/stitching/utils.py +14 -0
  403. tomwer/gui/stitching/z_stitching/fineestimation.py +4 -32
  404. tomwer/gui/stitching/z_stitching/tests/test_fine_estimation.py +35 -0
  405. tomwer/gui/stitching/z_stitching/tests/test_raw_estimation.py +215 -0
  406. tomwer/gui/stitching/z_stitching/tests/test_stitching_window.py +51 -0
  407. tomwer/gui/tests/__init__.py +0 -0
  408. tomwer/gui/tests/test_axis_gui.py +27 -0
  409. tomwer/gui/{test → tests}/test_qfolder_dialog.py +1 -1
  410. tomwer/gui/utils/RangeWidget.py +44 -0
  411. tomwer/gui/utils/buttons.py +4 -3
  412. tomwer/gui/utils/completer.py +2 -33
  413. tomwer/gui/utils/flow.py +11 -40
  414. tomwer/gui/utils/gpu.py +60 -0
  415. tomwer/gui/utils/illustrations.py +1 -26
  416. tomwer/gui/utils/inputwidget.py +35 -73
  417. tomwer/gui/utils/lineselector/lineselector.py +9 -46
  418. tomwer/gui/utils/loadingmode.py +81 -0
  419. tomwer/gui/utils/qt_utils.py +9 -0
  420. tomwer/gui/utils/sandboxes.py +1 -26
  421. tomwer/gui/utils/scandescription.py +2 -31
  422. tomwer/gui/utils/scrollarea.py +6 -55
  423. tomwer/gui/utils/slider.py +4 -28
  424. tomwer/gui/utils/splashscreen.py +0 -28
  425. tomwer/gui/utils/step.py +14 -13
  426. tomwer/gui/utils/tests/test_completer.py +41 -0
  427. tomwer/gui/utils/tests/test_line_selector.py +21 -0
  428. tomwer/gui/utils/tests/test_splashscreen.py +8 -0
  429. tomwer/gui/utils/tests/test_vignettes.py +68 -0
  430. tomwer/gui/utils/unitsystem.py +15 -69
  431. tomwer/gui/utils/utils.py +4 -5
  432. tomwer/gui/utils/vignettes.py +10 -41
  433. tomwer/gui/utils/waiterthread.py +0 -26
  434. tomwer/gui/visualization/__init__.py +2 -0
  435. tomwer/gui/visualization/dataviewer.py +68 -421
  436. tomwer/gui/visualization/diffviewer/diffviewer.py +2 -30
  437. tomwer/gui/visualization/diffviewer/shiftwidget.py +4 -29
  438. tomwer/gui/visualization/fullscreenplot.py +5 -5
  439. tomwer/gui/visualization/imagestack.py +403 -0
  440. tomwer/gui/visualization/nxtomometadata.py +0 -4
  441. tomwer/gui/visualization/reconstructionparameters.py +14 -32
  442. tomwer/gui/visualization/scanoverview.py +33 -66
  443. tomwer/gui/visualization/sinogramviewer.py +2 -28
  444. tomwer/gui/visualization/test/__init__.py +0 -28
  445. tomwer/gui/visualization/test/test_dataviewer.py +1 -28
  446. tomwer/gui/visualization/test/test_diffviewer.py +1 -28
  447. tomwer/gui/visualization/test/test_nx_tomo_metadata_viewer.py +0 -5
  448. tomwer/gui/visualization/test/test_reconstruction_parameters.py +1 -27
  449. tomwer/gui/visualization/test/test_sinogramviewer.py +1 -28
  450. tomwer/gui/visualization/test/test_stacks.py +184 -115
  451. tomwer/gui/visualization/test/test_volumeviewer.py +3 -2
  452. tomwer/gui/visualization/tomoobjoverview.py +2 -2
  453. tomwer/gui/visualization/volumeoverview.py +3 -2
  454. tomwer/gui/visualization/volumeviewer.py +47 -43
  455. tomwer/io/__init__.py +2 -0
  456. tomwer/io/utils/h5pyutils.py +1 -27
  457. tomwer/io/utils/test/test_raw_and_processed_data.py +10 -0
  458. tomwer/io/utils/test/test_utils.py +67 -0
  459. tomwer/io/utils/utils.py +2 -31
  460. tomwer/resources/__init__.py +13 -33
  461. tomwer/resources/gui/icons/edit_downstream.svg +114 -0
  462. tomwer/resources/gui/icons/edit_upstream.svg +112 -0
  463. tomwer/resources/gui/icons/free_edition.svg +23 -0
  464. tomwer/resources/gui/icons/icat_gallery_opts.png +0 -0
  465. tomwer/resources/gui/icons/icat_gallery_opts.svg +80 -0
  466. tomwer/resources/gui/icons/search.png +0 -0
  467. tomwer/resources/gui/icons/search.svg +23 -0
  468. tomwer/resources/gui/icons/warning.png +0 -0
  469. tomwer/synctools/__init__.py +2 -0
  470. tomwer/synctools/axis.py +1 -27
  471. tomwer/synctools/darkref.py +1 -26
  472. tomwer/synctools/datalistener.py +1 -27
  473. tomwer/synctools/datatransfert.py +2 -27
  474. tomwer/synctools/imageloaderthread.py +1 -28
  475. tomwer/synctools/rsyncmanager.py +1 -25
  476. tomwer/synctools/saaxis.py +1 -26
  477. tomwer/synctools/sadeltabeta.py +1 -26
  478. tomwer/synctools/stacks/control/datalistener.py +1 -26
  479. tomwer/synctools/stacks/processingstack.py +4 -33
  480. tomwer/synctools/stacks/reconstruction/axis.py +2 -31
  481. tomwer/synctools/stacks/reconstruction/castvolume.py +12 -43
  482. tomwer/synctools/stacks/reconstruction/dkrefcopy.py +3 -26
  483. tomwer/synctools/stacks/reconstruction/nabu.py +1 -26
  484. tomwer/synctools/stacks/reconstruction/normalization.py +1 -26
  485. tomwer/synctools/stacks/reconstruction/saaxis.py +1 -26
  486. tomwer/synctools/stacks/reconstruction/sadeltabeta.py +1 -26
  487. tomwer/synctools/tests/__init__.py +0 -0
  488. tomwer/synctools/{test → tests}/test_darkRefs.py +16 -40
  489. tomwer/synctools/{test → tests}/test_foldertransfer.py +2 -33
  490. tomwer/synctools/utils/scanstages.py +2 -31
  491. tomwer/tests/__init__.py +1 -0
  492. tomwer/tests/app/test_stitching.py +95 -0
  493. tomwer/tests/datasets.py +1 -5
  494. tomwer/tests/orangecontrib/tomwer/widgets/cluster/tests/test_future_supervisorow.py +48 -0
  495. tomwer/tests/orangecontrib/tomwer/widgets/cluster/tests/test_slurm_clusterow.py +40 -0
  496. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_advancement.py +8 -0
  497. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_data_validator.py +55 -0
  498. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_datadiscovery.py +129 -0
  499. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_datalistener.py +111 -0
  500. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_dataselector.py +69 -0
  501. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_datawatcher.py +411 -0
  502. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_emailow.py +29 -0
  503. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_notifier.py +24 -0
  504. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_nxtomo_concatenate_ow.py +64 -0
  505. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_nxtomomill.py +133 -0
  506. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_reduce_dark_flat_selector.py +40 -0
  507. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_singletomoobj.py +40 -0
  508. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_timerow.py +25 -0
  509. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_tomoobj_series.py +96 -0
  510. tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_volume_selector.py +69 -0
  511. orangecontrib/tomwer/widgets/edit/test/test_image_key_editor.py → tomwer/tests/orangecontrib/tomwer/widgets/debugtools/tests/test_dataset_generator.py +17 -16
  512. tomwer/tests/orangecontrib/tomwer/widgets/debugtools/tests/test_object_inspector.py +36 -0
  513. {orangecontrib/tomwer/widgets/edit/test → tomwer/tests/orangecontrib/tomwer/widgets/edit/tests}/test_dark_flat_patch.py +1 -27
  514. tomwer/tests/orangecontrib/tomwer/widgets/edit/tests/test_image_key_editor.py +30 -0
  515. tomwer/tests/orangecontrib/tomwer/widgets/edit/tests/test_nxtomo_editor.py +138 -0
  516. tomwer/tests/orangecontrib/tomwer/widgets/other/tests/test_pythonscript.py +31 -0
  517. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_axis.py +215 -0
  518. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_cast_volumeow.py +58 -0
  519. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_dark_refs_widget.py +136 -0
  520. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_delta_beta_selector.py +15 -0
  521. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_i_norm.py +200 -0
  522. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_nabu_helical_prepare_weights_double.py +20 -0
  523. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_nabu_volume.py +74 -0
  524. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_nabu_widget.py +107 -0
  525. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_sa_delta_beta.py +194 -0
  526. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_saaxis.py +194 -0
  527. tomwer/tests/orangecontrib/tomwer/widgets/stitching/tests/test_zstitching.py +313 -0
  528. tomwer/tests/orangecontrib/tomwer/widgets/tests/test_conditions.py +85 -0
  529. tomwer/tests/orangecontrib/tomwer/widgets/tests/test_darkref.py +225 -0
  530. tomwer/tests/orangecontrib/tomwer/widgets/tests/test_foldertransfert.py +105 -0
  531. tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_dataviewerow.py +57 -0
  532. tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_diffviewerow.py +39 -0
  533. tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_nxtomo_metadata_viewer.py +29 -0
  534. tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_radio_stackow.py +31 -0
  535. tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_sample_movedow.py +46 -0
  536. tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_sinogram_viewerow.py +31 -0
  537. tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_slice_stackow.py +31 -0
  538. tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_volume_viewerow.py +32 -0
  539. tomwer/tests/test_ewoks/test_conversion.py +104 -0
  540. tomwer/tests/test_ewoks/test_single_node_execution.py +87 -0
  541. tomwer/tests/test_ewoks/test_workflows.py +138 -0
  542. tomwer/utils.py +11 -39
  543. tomwer/version.py +3 -3
  544. {tomwer-1.3.27.dist-info → tomwer-1.4.0rc0.dist-info}/LICENSE +3 -3
  545. tomwer-1.4.0rc0.dist-info/METADATA +337 -0
  546. tomwer-1.4.0rc0.dist-info/RECORD +909 -0
  547. {tomwer-1.3.27.dist-info → tomwer-1.4.0rc0.dist-info}/WHEEL +1 -1
  548. {tomwer-1.3.27.dist-info → tomwer-1.4.0rc0.dist-info}/entry_points.txt +1 -0
  549. orangecontrib/tomwer/widgets/control/DataListOW.py +0 -129
  550. orangecontrib/tomwer/widgets/control/TomoObjSerieOW.py +0 -86
  551. orangecontrib/tomwer/widgets/control/VolumeSymLinkOW.py +0 -182
  552. orangecontrib/tomwer/widgets/edit/test/test_nxtomo_editor.py +0 -141
  553. orangecontrib/tomwer/widgets/icat/PublishProcessedDataOW.py +0 -115
  554. orangecontrib/tomwer/widgets/icat/RawDataScreenshotCreatorOW.py +0 -98
  555. orangecontrib/tomwer/widgets/icat/SaveToGalleryAndPublishOW.py +0 -129
  556. orangecontrib/tomwer/widgets/icat/icons/add_gallery.png +0 -0
  557. orangecontrib/tomwer/widgets/icat/icons/add_gallery.svg +0 -82
  558. orangecontrib/tomwer/widgets/icat/icons/raw_screenshots.png +0 -0
  559. orangecontrib/tomwer/widgets/icat/icons/raw_screenshots.svg +0 -143
  560. orangecontrib/tomwer/widgets/visualization/LivesliceOW.py +0 -87
  561. orangecontrib/tomwer/widgets/visualization/icons/liveslice.png +0 -0
  562. orangecontrib/tomwer/widgets/visualization/icons/liveslice.svg +0 -110
  563. tomwer/core/log/logger.py +0 -130
  564. tomwer/core/process/control/test/test_volume_link.py +0 -74
  565. tomwer/core/process/control/tomoobjserie.py +0 -12
  566. tomwer/core/process/control/volumesymlink.py +0 -200
  567. tomwer/core/process/icat/createscreenshots.py +0 -100
  568. tomwer/core/process/icat/gallery.py +0 -377
  569. tomwer/core/process/icat/icatbase.py +0 -36
  570. tomwer/core/process/icat/publish.py +0 -228
  571. tomwer/core/process/icat/screenshots.py +0 -27
  572. tomwer/core/process/reconstruction/test/test_darkref.py +0 -60
  573. tomwer/core/process/reconstruction/test/test_sadeltabeta.py +0 -74
  574. tomwer/core/process/visualization/liveslice.py +0 -6
  575. tomwer/core/progress.py +0 -100
  576. tomwer/core/scan/test/test_edf.py +0 -53
  577. tomwer/core/scan/test/test_future_scan.py +0 -61
  578. tomwer/core/scan/test/test_h5.py +0 -96
  579. tomwer/core/test/test_scanutils.py +0 -53
  580. tomwer/gui/control/emailnotifier.py +0 -174
  581. tomwer/gui/control/serie/seriewaiter.py +0 -28
  582. tomwer/gui/control/test/__init__.py +0 -28
  583. tomwer/gui/control/test/test_datalist.py +0 -96
  584. tomwer/gui/control/test/test_datavalidator.py +0 -54
  585. tomwer/gui/control/test/test_email.py +0 -35
  586. tomwer/gui/control/test/test_process_manager.py +0 -65
  587. tomwer/gui/control/test/test_scanselector.py +0 -67
  588. tomwer/gui/edit/test/__init__.py +0 -28
  589. tomwer/gui/icat/gallery.py +0 -214
  590. tomwer/gui/icat/publish.py +0 -187
  591. tomwer/gui/reconstruction/axis/axis.py +0 -733
  592. tomwer/gui/reconstruction/axis/radioaxis.py +0 -2467
  593. tomwer/gui/stitching/stitching.py +0 -1388
  594. tomwer/gui/test/__init__.py +0 -28
  595. tomwer/gui/test/test_axis_gui.py +0 -34
  596. tomwer/synctools/stacks/edit/darkflatpatch.py +0 -169
  597. tomwer/synctools/stacks/edit/imagekeyeditor.py +0 -135
  598. tomwer/third_part/WaitingOverlay.py +0 -110
  599. tomwer-1.3.27-py3.11-nspkg.pth +0 -1
  600. tomwer-1.3.27.dist-info/METADATA +0 -292
  601. tomwer-1.3.27.dist-info/RECORD +0 -785
  602. tomwer-1.3.27.dist-info/namespace_packages.txt +0 -1
  603. /orangecontrib/tomwer/{widgets/edit/test → tests}/__init__.py +0 -0
  604. {tomwer/core/process/control/test → orangecontrib/tomwer/tutorials/id16b}/__init__.py +0 -0
  605. {tomwer/core/process/icat → orangecontrib/tomwer/widgets/cluster/tests}/__init__.py +0 -0
  606. /orangecontrib/tomwer/widgets/control/icons/{tomoobjserie.png → tomoobjseries.png} +0 -0
  607. {tomwer/core/process/reconstruction/test → orangecontrib/tomwer/widgets/control/tests}/__init__.py +0 -0
  608. /orangecontrib/tomwer/widgets/{icat → dataportal}/icons/publish_processed_data.png +0 -0
  609. /orangecontrib/tomwer/widgets/{icat → dataportal}/icons/publish_processed_data.svg +0 -0
  610. {tomwer/core/process/test → orangecontrib/tomwer/widgets/debugtools/tests}/__init__.py +0 -0
  611. {tomwer/core/scan/test → orangecontrib/tomwer/widgets/edit/tests}/__init__.py +0 -0
  612. {tomwer/core/test → orangecontrib/tomwer/widgets/other/tests}/__init__.py +0 -0
  613. {tomwer/gui/cluster/test → orangecontrib/tomwer/widgets/reconstruction/tests}/__init__.py +0 -0
  614. {tomwer/gui/control/serie → orangecontrib/tomwer/widgets/stitching/tests}/__init__.py +0 -0
  615. {tomwer/gui/icat → orangecontrib/tomwer/widgets/tests}/__init__.py +0 -0
  616. {tomwer/gui/reconstruction/test → orangecontrib/tomwer/widgets/visualization/tests}/__init__.py +0 -0
  617. /tomwer/{synctools/stacks/edit → app/stitching}/__init__.py +0 -0
  618. /tomwer/{synctools/test → core/process/control/tests}/__init__.py +0 -0
  619. /tomwer/core/process/control/{test → tests}/test_email.py +0 -0
  620. /tomwer/core/process/control/{test → tests}/test_h52nx_process.py +0 -0
  621. /tomwer/{third_part → core/process/drac}/__init__.py +0 -0
  622. /tomwer/core/process/reconstruction/{test → tests}/test_axis_params.py +0 -0
  623. /tomwer/core/process/reconstruction/{test → tests}/test_darkref_copy.py +0 -0
  624. /tomwer/core/process/reconstruction/{test → tests}/test_paramsbase.py +0 -0
  625. /tomwer/core/process/reconstruction/{test → tests}/test_utils.py +0 -0
  626. /tomwer/core/scan/{test → tests}/test_scan.py +0 -0
  627. /tomwer/gui/control/{serie → series}/nxtomoconcatenate.py +0 -0
  628. /tomwer/gui/control/{test → tests}/test_datadiscovery.py +0 -0
  629. /tomwer/gui/control/{test → tests}/test_reducedarkflat_selector.py +0 -0
  630. /tomwer/gui/control/{test → tests}/test_single_tomo_obj.py +0 -0
  631. {orangecontrib/tomwer/widgets/edit/test → tomwer/tests/orangecontrib/tomwer/widgets/edit/tests}/test_image_key_upgrader.py +0 -0
  632. {tomwer-1.3.27.dist-info → tomwer-1.4.0rc0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,776 @@
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._updateAxisView()
156
+ self._axisParams.sigChanged.emit()
157
+
158
+ def _updateAxisView(self):
159
+ with block_signals(self._axisParams):
160
+ if self._axisParams.relative_cor_value not in (None, "..."):
161
+ self.setXShift(self._axisParams.relative_cor_value)
162
+
163
+ self._manualSelectionWidget.setVisible(
164
+ self._axisParams.mode is axis_mode.AxisMode.manual
165
+ )
166
+
167
+ def getAxisParams(self):
168
+ return self._axisParams
169
+
170
+ def _incrementShift(self, direction):
171
+ assert direction in ("left", "right", "top", "bottom")
172
+ if direction == "left":
173
+ self.setXShift(self._xShift - self.getShiftStep())
174
+ elif direction == "right":
175
+ self.setXShift(self._xShift + self.getShiftStep())
176
+ elif direction == "top":
177
+ self.setYShift(self._yShift + self.getShiftStep())
178
+ else:
179
+ self.setYShift(self._yShift - self.getShiftStep())
180
+
181
+ self._shiftControl._updateShiftInfo(x=self._xShift, y=self._yShift)
182
+
183
+ def _resetShift(self):
184
+ with block_signals(self._axisParams):
185
+ self.setXShift(0)
186
+ self.setYShift(0)
187
+ self._shiftControl._updateShiftInfo(x=self._xShift, y=self._yShift)
188
+
189
+ self.sigShiftChanged.emit(self._xShift, self._yShift)
190
+
191
+ def getXShift(self):
192
+ if self._xShift == "...":
193
+ return 0
194
+ return self._xShift
195
+
196
+ def getYShift(self):
197
+ if self._yShift == "...":
198
+ return 0
199
+ return self._yShift
200
+
201
+ def setXShift(self, x: float):
202
+ self.setShift(x=x, y=self._yShift)
203
+
204
+ def setYShift(self, y):
205
+ self.setShift(x=self._xShift, y=y)
206
+
207
+ def setShift(self, x, y):
208
+ if x == self._xShift and y == self._yShift:
209
+ return
210
+ self._xShift = x if x is not None else 0.0
211
+ self._yShift = y if y is not None else 0.0
212
+ if self._axisParams:
213
+ with block_signals(self._axisParams):
214
+ self._axisParams.set_relative_value(x)
215
+ self._shiftControl._updateShiftInfo(x=self._xShift, y=self._yShift)
216
+ if not isinstance(self._xShift, str):
217
+ # filter `...` and `?` values (used for issues or processing)
218
+ self.sigShiftChanged.emit(self._xShift, self._yShift)
219
+
220
+ def reset(self):
221
+ with block_signals(self):
222
+ self.setShift(0, 0)
223
+ self.sigShiftChanged.emit(self._xShift, self._yShift)
224
+
225
+ def setLocked(self, locked):
226
+ self._mainWidget.setEnabled(not locked)
227
+
228
+ def _requestZoomReset(self):
229
+ self.sigResetZoomRequested.emit()
230
+
231
+ # expose API
232
+
233
+ def updateAutomaticallyEstimatedCor(self):
234
+ return self._mainWidget.updateAutomaticallyEstimatedCor()
235
+
236
+ def setUpdateAutomaticallyEstimatedCor(self, value):
237
+ self._mainWidget.setUpdateAutomaticallyEstimatedCor(value)
238
+
239
+ def setEstimatedCor(self, value):
240
+ self._mainWidget.setEstimatedCorValue(value=value)
241
+
242
+ def getEstimatedCor(self):
243
+ return self._mainWidget.getEstimatedCor()
244
+
245
+ def getROIDims(self):
246
+ return self._roiControl.getROIDims()
247
+
248
+ def getShiftStep(self):
249
+ return self._displacementSelector.getStepSize()
250
+
251
+ def setShiftStep(self, value):
252
+ self._displacementSelector.setStepSize(value=value)
253
+
254
+ def getROIOrigin(self):
255
+ return self._roiControl.getROIOrigin()
256
+
257
+ def getImgSubSampling(self):
258
+ return self._imgOpts.getSubSampling()
259
+
260
+ def getMode(self):
261
+ return self._mainWidget.getMode()
262
+
263
+ def isModeLock(self):
264
+ return self._mainWidget.isModeLock()
265
+
266
+ def setModeLock(self, mode):
267
+ return self._mainWidget.setModeLock(mode=mode)
268
+
269
+
270
+ class ManualAxisSelectionWidget(qt.QWidget):
271
+ sigResetZoomRequested = qt.Signal()
272
+ """Signal emitted when a zoom request is necessary (when change to full
273
+ image)"""
274
+
275
+ def __init__(self, parent, shift_mode):
276
+ qt.QWidget.__init__(self, parent)
277
+ self.setLayout(qt.QVBoxLayout())
278
+ self._displacementSelector = StepSizeSelectorWidget(
279
+ parent=self,
280
+ fine_value=0.1,
281
+ medium_value=1.0,
282
+ rough_value=None,
283
+ dtype=float,
284
+ )
285
+ self.layout().addWidget(self._displacementSelector)
286
+
287
+ self._shiftControl = _ShiftControl(parent=self, shift_mode=shift_mode)
288
+ self.layout().addWidget(self._shiftControl)
289
+
290
+ self._roiControl = _ROIControl(parent=self)
291
+ self.layout().addWidget(self._roiControl)
292
+
293
+ self._imgOpts = _ImgOpts(parent=self)
294
+ self.layout().addWidget(self._imgOpts)
295
+
296
+ # connect signal / slot
297
+ self._roiControl.sigResetZoomRequested.connect(self.sigResetZoomRequested)
298
+
299
+
300
+ class _ROIControl(qt.QGroupBox):
301
+ """
302
+ Widget used to define the ROI on images to compare
303
+ """
304
+
305
+ sigRoiChanged = qt.Signal(object)
306
+ """Signal emitted when the ROI changed"""
307
+ sigResetZoomRequested = qt.Signal()
308
+ """Signal emitted when a zoom request is necessary (when change to full
309
+ image)"""
310
+
311
+ def __init__(self, parent):
312
+ qt.QGroupBox.__init__(self, "ROI selection", parent)
313
+ self.setLayout(qt.QVBoxLayout())
314
+
315
+ self._buttonGrp = qt.QButtonGroup(parent=self)
316
+ self._buttonGrp.setExclusive(True)
317
+
318
+ self._roiWidget = qt.QWidget(parent=self)
319
+ self._roiWidget.setLayout(qt.QHBoxLayout())
320
+ self._roiWidget.layout().setContentsMargins(0, 0, 0, 0)
321
+ self._fullImgButton = qt.QRadioButton("full image", parent=self)
322
+ self._buttonGrp.addButton(self._fullImgButton)
323
+ self.layout().addWidget(self._fullImgButton)
324
+ self._roiButton = qt.QRadioButton("ROI", parent=self._roiWidget)
325
+ self._roiWidget.layout().addWidget(self._roiButton)
326
+ self._buttonGrp.addButton(self._roiButton)
327
+ self._roiDefinition = _ROIDefinition(parent=self)
328
+ self._roiWidget.layout().addWidget(self._roiDefinition)
329
+ self.layout().addWidget(self._roiWidget)
330
+
331
+ # connect signal / Slot
332
+ self._roiButton.toggled.connect(self._roiDefinition.setEnabled)
333
+ self._fullImgButton.toggled.connect(self.sigResetZoomRequested)
334
+ self._roiButton.toggled.connect(self.sigResetZoomRequested)
335
+ self._roiDefinition.sigRoiChanged.connect(self.sigRoiChanged)
336
+
337
+ # setup for full image
338
+ self._fullImgButton.setChecked(True)
339
+
340
+ def getROIDims(self):
341
+ if self._roiButton.isChecked():
342
+ return self._roiDefinition.getROIDims()
343
+ else:
344
+ return None
345
+
346
+ def manual_uses_full_image(self, activate):
347
+ if activate:
348
+ self._fullImgButton.setChecked(True)
349
+ else:
350
+ self._roiButton.setChecked(True)
351
+
352
+ # expose API
353
+ def getROIOrigin(self):
354
+ return self._roiDefinition.getROIOrigin()
355
+
356
+ def setLimits(self, width, height):
357
+ self._roiDefinition.setLimits(width=width, height=height)
358
+
359
+ def setScan(self, scan):
360
+ self._roiDefinition.setScan(scan=scan)
361
+
362
+
363
+ class _ROIDefinition(qt.QWidget):
364
+ """
365
+ Widget used to define ROI width and height.
366
+
367
+ :note: emit ROI == None if setDisabled
368
+ """
369
+
370
+ sigRoiChanged = qt.Signal(object)
371
+ """Signal emitted when the ROI changed"""
372
+
373
+ def __init__(self, parent):
374
+ qt.QWidget.__init__(self, parent)
375
+ self.setLayout(qt.QGridLayout())
376
+ self._already_set = False
377
+
378
+ # width & height
379
+ self.layout().addWidget(qt.QLabel("dims", self), 0, 0)
380
+ self._widthSB = qt.QSpinBox(parent=self)
381
+ self._widthSB.setSingleStep(2)
382
+ self._widthSB.setMaximum(10000)
383
+ self._widthSB.setSuffix(" px")
384
+ self._widthSB.setPrefix("w: ")
385
+ self._widthSB.setToolTip("ROI width")
386
+ self.layout().addWidget(self._widthSB, 0, 1)
387
+ self._heightSB = qt.QSpinBox(parent=self)
388
+ self._heightSB.setSingleStep(2)
389
+ self._heightSB.setSuffix(" px")
390
+ self._heightSB.setPrefix("h: ")
391
+ self._heightSB.setToolTip("ROI height")
392
+ self._heightSB.setMaximum(10000)
393
+ self.layout().addWidget(self._heightSB, 0, 2)
394
+
395
+ # origin x and y position
396
+ self.layout().addWidget(qt.QLabel("origin", self), 1, 0)
397
+ self._xOriginSB = qt.QSpinBox(parent=self)
398
+ self._xOriginSB.setSingleStep(10)
399
+ self._xOriginSB.setMaximum(10000)
400
+ self._xOriginSB.setPrefix("x: ")
401
+ self.layout().addWidget(self._xOriginSB, 1, 1)
402
+ self._yOriginSB = qt.QSpinBox(parent=self)
403
+ self._yOriginSB.setSingleStep(10)
404
+ self._yOriginSB.setPrefix("y: ")
405
+ self._yOriginSB.setMaximum(10000)
406
+ self.layout().addWidget(self._yOriginSB, 1, 2)
407
+
408
+ # Signal / Slot connection
409
+ self._widthSB.editingFinished.connect(self.__roiChanged)
410
+ self._heightSB.editingFinished.connect(self.__roiChanged)
411
+ self._xOriginSB.editingFinished.connect(self.__roiChanged)
412
+ self._yOriginSB.editingFinished.connect(self.__roiChanged)
413
+
414
+ def __roiChanged(self, *args, **kwargs):
415
+ self.sigRoiChanged.emit((self.getROIDims(), self.getROIOrigin()))
416
+
417
+ def setLimits(self, width, height):
418
+ """
419
+
420
+ :param x: width maximum value
421
+ :param height: height maximum value
422
+ """
423
+ for spinButton in (self._widthSB, self._heightSB):
424
+ spinButton.blockSignals(True)
425
+ assert type(width) is int
426
+ assert type(height) is int
427
+ valueChanged = False
428
+ if self._widthSB.value() > width:
429
+ self._widthSB.setValue(width)
430
+ valueChanged = True
431
+ if self._heightSB.value() > height:
432
+ self._heightSB.setValue(height)
433
+ valueChanged = True
434
+
435
+ # if this is the first limit definition, propose default width and
436
+ # height
437
+ if self._widthSB.value() == 0:
438
+ self._widthSB.setValue(min(256, width))
439
+ valueChanged = True
440
+ if self._heightSB.value() == 0:
441
+ self._heightSB.setValue(min(256, height))
442
+ valueChanged = True
443
+
444
+ # define minimum / maximum
445
+ self._widthSB.setRange(1, width)
446
+ self._heightSB.setRange(1, height)
447
+ for spinButton in (self._widthSB, self._heightSB):
448
+ spinButton.blockSignals(False)
449
+ if valueChanged is True:
450
+ self.__roiChanged()
451
+
452
+ def getROIDims(self) -> tuple | None:
453
+ """
454
+
455
+ :return: (width, height) or None
456
+ """
457
+ if self.isEnabled():
458
+ return (self._widthSB.value(), self._heightSB.value())
459
+ else:
460
+ return None
461
+
462
+ def getROIOrigin(self):
463
+ return (self._xOriginSB.value(), self._yOriginSB.value())
464
+
465
+ def setEnabled(self, *arg, **kwargs):
466
+ qt.QWidget.setEnabled(self, *arg, **kwargs)
467
+ self.__roiChanged()
468
+
469
+ def setScan(self, scan):
470
+ if not self._already_set:
471
+ self._already_set = True
472
+ try:
473
+ x_origin = scan.dim_1 // 2
474
+ y_origin = scan.dim_2 // 2
475
+ self._xOriginSB.setValue(x_origin)
476
+ self._yOriginSB.setValue(y_origin)
477
+ except Exception:
478
+ _logger.warning(f"unable to determine origin for {scan}")
479
+
480
+
481
+ class AxisSettingsTabWidget(qt.QTabWidget):
482
+ """
483
+ TabWidget containing all the settings of the AxisTask
484
+ """
485
+
486
+ sigLockModeChanged = qt.Signal(bool)
487
+ """signal emitted when the mode lock change"""
488
+
489
+ sigUrlChanged = qt.Signal()
490
+ """Signal emit when frames urls changed"""
491
+
492
+ sigModeChanged = qt.Signal(str)
493
+ """Signal emit when mode (algorithm) is changed"""
494
+
495
+ def __init__(
496
+ self,
497
+ recons_params: QAxisRP | None,
498
+ parent=None,
499
+ ):
500
+ """
501
+
502
+ :param recons_params: reconstruction parameters edited by the widget
503
+ """
504
+ qt.QTabWidget.__init__(self, parent)
505
+ assert recons_params is not None
506
+ # first tab 'calculation widget'
507
+ self._calculationWidget = CalculationWidget(
508
+ parent=self, axis_params=recons_params
509
+ )
510
+
511
+ # second tab: options
512
+ self._optionsWidget = AxisOptionsWidget(parent=self, axis_params=recons_params)
513
+ self._inputWidget = InputWidget(parent=self, axis_params=recons_params)
514
+
515
+ for widget in self._calculationWidget, self._optionsWidget:
516
+ spacer = qt.QWidget(self)
517
+ spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding)
518
+ widget.layout().addWidget(spacer)
519
+
520
+ self._optionsSA = qt.QScrollArea(parent=self)
521
+ self._optionsSA.setWidget(self._optionsWidget)
522
+ self.addTab(self._calculationWidget, "calculation")
523
+ self.addTab(self._optionsSA, "options")
524
+ # simplify set up. Hide options
525
+ self._optionsSA.hide()
526
+ self.addTab(self._inputWidget, "input")
527
+
528
+ # set up
529
+ self.setAxisParams(recons_params)
530
+ self._updatePossibleInput()
531
+
532
+ # connect signal / slot
533
+ self._calculationWidget.sigLockModeChanged.connect(self.sigLockModeChanged)
534
+ self.sigModeChanged.connect(self._updatePossibleInput)
535
+ self._inputWidget._sigUrlChanged.connect(self._urlChanged)
536
+ self._calculationWidget.sigModeChanged.connect(self.sigModeChanged)
537
+ # not very nice but very convenient to have the setting near at the same level
538
+ self._calculationWidget._qleNearPosQLE.textChanged.connect(
539
+ self._inputWidget._changed
540
+ )
541
+
542
+ def _urlChanged(self):
543
+ self.sigUrlChanged.emit()
544
+
545
+ def setScan(self, scan):
546
+ if scan is not None:
547
+ self._inputWidget.setScan(scan)
548
+
549
+ def setAxisParams(self, axis):
550
+ with block_signals(self):
551
+ self._calculationWidget.setAxisParams(axis)
552
+ self._optionsWidget.setAxisParams(axis)
553
+ self._inputWidget.setAxisParams(axis)
554
+
555
+ def _updatePossibleInput(self):
556
+ """Update Input tab according to the current mode"""
557
+ current_mode = self.getMode()
558
+ valid_inputs = axis_mode.AXIS_MODE_METADATAS[current_mode].valid_inputs
559
+ if valid_inputs is None:
560
+ self._inputWidget.setEnabled(False)
561
+ else:
562
+ self._inputWidget.setEnabled(True)
563
+ self._inputWidget.setValidInputs(valid_inputs)
564
+
565
+ # expose API
566
+ def isModeLock(self) -> bool:
567
+ return self._calculationWidget.isModeLock()
568
+
569
+ def setModeLock(self, mode):
570
+ self._calculationWidget.setModeLock(mode=mode)
571
+
572
+ def setEstimatedCorValue(self, value):
573
+ self._calculationWidget.setEstimatedCorValue(value=value)
574
+
575
+ def getEstimatedCor(self):
576
+ return self._calculationWidget.getEstimatedCor()
577
+
578
+ def getMode(self):
579
+ """Return algorithm to use for axis calculation"""
580
+ return self._calculationWidget.getMode()
581
+
582
+ def updateAutomaticallyEstimatedCor(self):
583
+ return self._calculationWidget.updateAutomaticallyEstimatedCor()
584
+
585
+ def setUpdateAutomaticallyEstimatedCor(self, value):
586
+ self._calculationWidget.setUpdateAutomaticallyEstimatedCor(value)
587
+
588
+
589
+ class _ShiftControl(qt.QWidget):
590
+ """
591
+ Widget to control the shift step we want to apply
592
+ """
593
+
594
+ sigShiftLeft = qt.Signal()
595
+ """Signal emitted when the left button is activated"""
596
+ sigShiftRight = qt.Signal()
597
+ """Signal emitted when the right button is activated"""
598
+ sigShiftTop = qt.Signal()
599
+ """Signal emitted when the top button is activated"""
600
+ sigShiftBottom = qt.Signal()
601
+ """Signal emitted when the bottom button is activated"""
602
+ sigReset = qt.Signal()
603
+ """Signal emitted when the reset button is activated"""
604
+ sigAuto = qt.Signal()
605
+ """Signal emitted when the auto button is activated"""
606
+ sigShiftChanged = qt.Signal(float, float)
607
+ """Signal emitted ony when xLE and yLE edition is finished"""
608
+
609
+ def __init__(self, parent, shift_mode: ShiftMode):
610
+ """
611
+
612
+ :param parent: qt.QWidget
613
+ :param shift_mode: what are the shift we want to control
614
+ """
615
+ qt.QWidget.__init__(self, parent)
616
+ self.setLayout(qt.QGridLayout())
617
+ self.layout().setContentsMargins(0, 0, 0, 0)
618
+
619
+ self._leftButton = qt.QPushButton("left", parent=self)
620
+ self.layout().addWidget(self._leftButton, 1, 0)
621
+
622
+ self._rightButton = qt.QPushButton("right", parent=self)
623
+ self.layout().addWidget(self._rightButton, 1, 3)
624
+
625
+ self._shiftInfo = _ShiftInformation(parent=self)
626
+ self.layout().addWidget(self._shiftInfo, 1, 1)
627
+ self._shiftInfo._updateShiftInfo(x=0.0, y=0.0)
628
+
629
+ self._topButton = qt.QPushButton("top", parent=self)
630
+ self.layout().addWidget(self._topButton, 0, 1)
631
+
632
+ self._bottomButton = qt.QPushButton("bottom", parent=self)
633
+ self.layout().addWidget(self._bottomButton, 2, 1)
634
+
635
+ self._resetButton = qt.QPushButton("reset", parent=self)
636
+ self.layout().addWidget(self._resetButton, 3, 2, 3, 4)
637
+
638
+ self._autoButton = qt.QPushButton("auto", parent=self)
639
+ self.layout().addWidget(self._autoButton, 3, 0, 3, 2)
640
+ self._autoButton.hide()
641
+
642
+ # Signal / Slot connection
643
+ self._leftButton.pressed.connect(self.sigShiftLeft.emit)
644
+ self._rightButton.pressed.connect(self.sigShiftRight.emit)
645
+ self._topButton.pressed.connect(self.sigShiftTop.emit)
646
+ self._bottomButton.pressed.connect(self.sigShiftBottom.emit)
647
+ self._resetButton.pressed.connect(self.sigReset.emit)
648
+ self._autoButton.pressed.connect(self.sigAuto.emit)
649
+ self._shiftInfo.sigShiftChanged.connect(self.sigShiftChanged.emit)
650
+
651
+ # expose API
652
+ self._updateShiftInfo = self._shiftInfo._updateShiftInfo
653
+
654
+ self.setShiftMode(shift_mode)
655
+
656
+ def setShiftMode(self, shift_mode):
657
+ show_x_shift = shift_mode in (ShiftMode.x_only, ShiftMode.x_and_y)
658
+ show_y_shift = shift_mode in (ShiftMode.y_only, ShiftMode.x_and_y)
659
+ self._leftButton.setVisible(show_x_shift)
660
+ self._rightButton.setVisible(show_x_shift)
661
+ self._topButton.setVisible(show_y_shift)
662
+ self._bottomButton.setVisible(show_y_shift)
663
+ self._shiftInfo._xLE.setVisible(show_x_shift)
664
+ self._shiftInfo._xLabel.setVisible(show_x_shift)
665
+ self._shiftInfo._yLE.setVisible(show_y_shift)
666
+ self._shiftInfo._yLabel.setVisible(show_y_shift)
667
+
668
+
669
+ class _ImgOpts(qt.QGroupBox):
670
+ sigSubSamplingChanged = qt.Signal()
671
+ """Signal emitted when the sub sampling change"""
672
+
673
+ def __init__(self, parent, title="Image Option"):
674
+ super().__init__(title, parent)
675
+ self.setLayout(qt.QFormLayout())
676
+ self._subSamplingQSpinBox = qt.QSpinBox(self)
677
+ self.layout().addRow("sub-sampling:", self._subSamplingQSpinBox)
678
+ self._subSamplingQSpinBox.setMinimum(1)
679
+
680
+ # set up
681
+ self._subSamplingQSpinBox.setValue(1)
682
+
683
+ # connect signal / slot
684
+ self._subSamplingQSpinBox.valueChanged.connect(self._subSamplingChanged)
685
+
686
+ def _subSamplingChanged(self):
687
+ self.sigSubSamplingChanged.emit()
688
+
689
+ def getSubSampling(self):
690
+ return self._subSamplingQSpinBox.value()
691
+
692
+ def setSubSampling(self, value):
693
+ return self._subSamplingQSpinBox.setValue(int(value))
694
+
695
+
696
+ class _ShiftInformation(qt.QWidget):
697
+ """
698
+ Widget displaying information about the current x and y shift.
699
+ Both x shift and y shift are editable.
700
+ """
701
+
702
+ class _ShiftLineEdit(qt.QLineEdit):
703
+ def __init__(self, *args, **kwargs):
704
+ qt.QLineEdit.__init__(self, *args, **kwargs)
705
+ self._defaultBackgroundColor = None
706
+ # validator
707
+ validator = qt.QDoubleValidator(parent=self, decimals=2)
708
+ self.setValidator(validator)
709
+ self._getDefaultBackgroundColor()
710
+ # connect signal / slot
711
+ self.textEdited.connect(self._userEditing)
712
+ self.editingFinished.connect(self._userEndEditing)
713
+
714
+ def sizeHint(self):
715
+ return qt.QSize(40, 10)
716
+
717
+ def _getDefaultBackgroundColor(self):
718
+ if self._defaultBackgroundColor is None:
719
+ self._defaultBackgroundColor = self.palette().color(
720
+ self.backgroundRole()
721
+ )
722
+ return self._defaultBackgroundColor
723
+
724
+ def _userEditing(self, *args, **kwargs):
725
+ palette = self.palette()
726
+ palette.setColor(self.backgroundRole(), EDITING_BACKGROUND_COLOR)
727
+ self.setPalette(palette)
728
+
729
+ def _userEndEditing(self, *args, **kwargs):
730
+ palette = self.palette()
731
+ palette.setColor(
732
+ self.backgroundRole(),
733
+ self._getDefaultBackgroundColor(),
734
+ )
735
+ self.setPalette(palette)
736
+
737
+ sigShiftChanged = qt.Signal(float, float)
738
+ """Signal emitted ony when xLE and yLE edition is finished"""
739
+
740
+ def __init__(self, parent):
741
+ qt.QWidget.__init__(self, parent)
742
+ self.setLayout(qt.QHBoxLayout())
743
+ self.layout().setContentsMargins(0, 0, 0, 0)
744
+ self.layout().setSpacing(0)
745
+
746
+ self._xLabel = qt.QLabel("x=", parent=self)
747
+ self.layout().addWidget(self._xLabel)
748
+ self._xLE = _ShiftInformation._ShiftLineEdit("", parent=self)
749
+ self.layout().addWidget(self._xLE)
750
+
751
+ self._yLabel = qt.QLabel("y=", parent=self)
752
+ self.layout().addWidget(self._yLabel)
753
+ self._yLE = _ShiftInformation._ShiftLineEdit("", parent=self)
754
+ self.layout().addWidget(self._yLE)
755
+
756
+ # connect Signal / Slot
757
+ self._xLE.editingFinished.connect(self._shiftChanged)
758
+ self._yLE.editingFinished.connect(self._shiftChanged)
759
+
760
+ def _updateShiftInfo(self, x, y):
761
+ with block_signals(self):
762
+ if x is None:
763
+ x = 0.0
764
+ if y is None:
765
+ y = 0.0
766
+ x_text = x
767
+ if x_text != "...":
768
+ x_text = "%.1f" % float(x)
769
+ y_text = y
770
+ if y_text != "...":
771
+ y_text = "%.1f" % float(y)
772
+ self._xLE.setText(x_text)
773
+ self._yLE.setText(y_text)
774
+
775
+ def _shiftChanged(self, *args, **kwargs):
776
+ self.sigShiftChanged.emit(float(self._xLE.text()), float(self._yLE.text()))