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
@@ -1,47 +1,22 @@
1
- # coding: utf-8
2
- # /*##########################################################################
3
- #
4
- # Copyright (c) 2016-2017 European Synchrotron Radiation Facility
5
- #
6
- # Permission is hereby granted, free of charge, to any person obtaining a copy
7
- # of this software and associated documentation files (the "Software"), to deal
8
- # in the Software without restriction, including without limitation the rights
9
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
- # copies of the Software, and to permit persons to whom the Software is
11
- # furnished to do so, subject to the following conditions:
12
- #
13
- # The above copyright notice and this permission notice shall be included in
14
- # all copies or substantial portions of the Software.
15
- #
16
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
- # THE SOFTWARE.
23
- #
24
- # ###########################################################################*/
25
-
26
- __authors__ = ["H. Payno"]
27
- __license__ = "MIT"
28
- __date__ = "11/10/2021"
29
-
1
+ from __future__ import annotations
30
2
 
3
+ import os
4
+ import re
31
5
  import logging
32
- from typing import Optional
33
6
  from functools import lru_cache as cache
34
7
 
35
8
  from silx.gui import qt
36
- from sluurp.utils import get_partitions, get_partition_gpus
9
+ from sluurp.utils import get_partitions, get_partition_gpus, get_partition_walltime
37
10
 
38
11
  from tomwer.core.settings import SlurmSettings, SlurmSettingsMode
12
+ from tomwer.gui import icons
39
13
  from tomwer.gui.utils.qt_utils import block_signals
40
14
  from tomwer.gui.configuration.action import (
41
15
  BasicConfigurationAction,
42
16
  ExpertConfigurationAction,
43
17
  )
44
18
  from tomwer.gui.configuration.level import ConfigurationLevel
19
+
45
20
  from nxtomomill.io.utils import convert_str_to_tuple
46
21
 
47
22
  _logger = logging.getLogger(__name__)
@@ -89,7 +64,7 @@ class SlurmSettingsWindow(qt.QMainWindow):
89
64
  sigConfigChanged = qt.Signal()
90
65
  """Signal emit when the SlurmSetting changed"""
91
66
 
92
- def __init__(self, parent: Optional[qt.QWidget] = None) -> None:
67
+ def __init__(self, parent: qt.QWidget | None = None) -> None:
93
68
  super().__init__(parent)
94
69
 
95
70
  # define toolbar
@@ -166,6 +141,7 @@ class SlurmSettingsWindow(qt.QMainWindow):
166
141
  "partition": settingsClass.PARTITION,
167
142
  "n_gpus": settingsClass.N_GPUS_PER_WORKER,
168
143
  "job_name": settingsClass.PROJECT_NAME,
144
+ "walltime": settingsClass.DEFAULT_WALLTIME,
169
145
  "python_venv": settingsClass.PYTHON_VENV,
170
146
  "modules": settingsClass.MODULES_TO_LOAD,
171
147
  }
@@ -204,122 +180,175 @@ class SlurmSettingsWidget(qt.QWidget):
204
180
  sigConfigChanged = qt.Signal()
205
181
  """Signal emit when the SlurmSetting changed"""
206
182
 
183
+ WALL_TIME_INVALID_COLOR = qt.QColor("#FF0000")
184
+
207
185
  def __init__(
208
186
  self,
209
187
  parent=None,
210
188
  n_gpu=SlurmSettings.N_GPUS_PER_WORKER,
211
- jobLimitation: Optional[int] = 1,
189
+ jobLimitation: int | None = 1,
212
190
  ) -> None:
213
191
  """
214
- :param int n_gpu: if provided will set the value to the number of gpu requested
192
+ :param n_gpu: if provided will set the value to the number of gpu requested
215
193
  (default is one as most of the job are nabu reconstruction)
216
- :param Optional[int] jobLimitation: if set then will hide the option to define the number of job
194
+ :param jobLimitation: if set then will hide the option to define the number of job
217
195
  """
218
196
  super().__init__(parent=parent)
219
- self.setLayout(qt.QFormLayout())
197
+ self.setLayout(qt.QGridLayout())
198
+ """Action to display warning in case of possible 'wrong' setting"""
199
+ # define some optional warning
200
+ warning_icon = icons.getQIcon("warning")
201
+ self._warning_opd_p9 = qt.QLabel("")
202
+ self._warning_opd_p9.setPixmap(warning_icon.pixmap(20, state=qt.QIcon.On))
203
+ self._warning_opd_p9.setToolTip(
204
+ f"'{get_login()}' account cannot submit job on p9 architecture"
205
+ )
206
+ self._warning_opd_export_opts = qt.QLabel("")
207
+ self._warning_opd_export_opts.setPixmap(
208
+ warning_icon.pixmap(20, state=qt.QIcon.On)
209
+ )
210
+ self._warning_opd_export_opts.setToolTip(
211
+ f"'{get_login()}' account needs to export job with ALL option (advanced settings)"
212
+ )
220
213
 
221
214
  # queues
222
- self._queue = qt.QComboBox(self)
223
- self._queue.setEditable(True)
215
+ self._queueLabel = qt.QLabel("queue / partition")
216
+ self.layout().addWidget(self._queueLabel, 0, 0, 1, 1)
217
+ self._queueCB = qt.QComboBox(self)
218
+ self._queueCB.setEditable(True)
224
219
  for partition in get_partitions():
225
220
  if partition in ("nice*",):
226
221
  # filter some node that we cannot access in fact
227
222
  continue
228
- self._queue.addItem(partition)
229
- self.layout().addRow("queue / partition", self._queue)
223
+ self._queueCB.addItem(partition)
224
+ self.layout().addWidget(self._queueCB, 0, 1, 1, 1)
225
+ self.layout().addWidget(self._warning_opd_p9, 0, 2, 1, 1)
230
226
 
231
227
  # n workers
232
- self._nWorkers = qt.QSpinBox(self)
233
- self._nWorkers.setRange(1, 100)
234
228
  self._nWorkersLabel = qt.QLabel("number of task", self)
235
- self.layout().addRow(self._nWorkersLabel, self._nWorkers)
229
+ self.layout().addWidget(self._nWorkersLabel, 1, 0, 1, 1)
230
+ self._nWorkersSP = qt.QSpinBox(self)
231
+ self._nWorkersSP.setRange(1, 100)
232
+ self.layout().addWidget(self._nWorkersSP, 1, 1, 1, 1)
236
233
 
237
234
  # ncores active
238
- self._nCores = qt.QSpinBox(self)
239
- self._nCores.setRange(1, 500)
240
- self.layout().addRow("number of cores per task", self._nCores)
235
+ self._nCoresLabel = qt.QLabel("number of cores per task")
236
+ self.layout().addWidget(self._nCoresLabel, 2, 0, 1, 1)
237
+ self._nCoresSB = qt.QSpinBox(self)
238
+ self._nCoresSB.setRange(1, 500)
239
+ self.layout().addWidget(self._nCoresSB, 2, 1, 1, 1)
241
240
 
242
241
  # memory
243
- self._memory = qt.QSpinBox(self)
244
- self._memory.setRange(1, 10000)
245
- self._memory.setSuffix("GB")
246
- self.layout().addRow("memory per task", self._memory)
242
+ self._memoryLabel = qt.QLabel("memory per task")
243
+ self.layout().addWidget(self._memoryLabel, 3, 0, 1, 1)
244
+ self._memorySB = qt.QSpinBox(self)
245
+ self._memorySB.setRange(1, 10000)
246
+ self._memorySB.setSuffix("GB")
247
+ self.layout().addWidget(self._memorySB, 3, 1, 1, 1)
247
248
 
248
249
  # gpu
249
- self._nGpu = qt.QSpinBox(self)
250
- self._nGpu.setRange(0, 12)
251
- self.layout().addRow("number of GPUs per task", self._nGpu)
250
+ self._nGpuLabel = qt.QLabel("number of GPUs per task")
251
+ self.layout().addWidget(self._nGpuLabel, 4, 0, 1, 1)
252
+ self._nGpuSB = qt.QSpinBox(self)
253
+ self._nGpuSB.setRange(0, 12)
254
+ self.layout().addWidget(self._nGpuSB, 4, 1, 1, 1)
252
255
 
253
256
  # n jobs
257
+ self._nJobsLabel = qt.QLabel("number of job", self)
258
+ self.layout().addWidget(self._nJobsLabel, 5, 0, 1, 1)
259
+
254
260
  self._nJobs = qt.QSpinBox(self)
255
261
  self._nJobs.setRange(1, 100000)
256
262
  self._nJobs.setValue(1)
257
- self._nJobsLabel = qt.QLabel("number of job", self)
258
- self.layout().addRow(self._nJobsLabel, self._nJobs)
259
263
  self._nJobs.setToolTip("Define on how many part the job should be split in")
260
264
  self._nJobsLabel.setVisible(jobLimitation is None)
261
265
  self._nJobs.setVisible(jobLimitation is None)
266
+ self.layout().addWidget(self._nJobs, 5, 1, 1, 1)
267
+
268
+ # wall time
269
+ self._wallTimeLabel = qt.QLabel("wall time", self)
270
+ self.layout().addWidget(self._wallTimeLabel, 6, 0, 1, 1)
271
+ self._wallTimeQLE = qt.QLineEdit("", self)
272
+ self.__reWallTime = qt.QRegularExpression(
273
+ r"[0-9]?[0-9]:[0-9]?[0-9]:[0-9]?[0-9]"
274
+ )
275
+ self._wallTimeQLE.setPlaceholderText("HH:MM:SS")
276
+ self._wallTimeValidator = qt.QRegularExpressionValidator(
277
+ self.__reWallTime, self
278
+ )
279
+ self._wallTimeQLE.setValidator(self._wallTimeValidator)
280
+ self.layout().addWidget(self._wallTimeQLE, 6, 1, 1, 1)
281
+ self.__defaultWallTimeBackgroundColor = self.palette().color(
282
+ self._wallTimeQLE.backgroundRole()
283
+ )
284
+ self._warningWallTime = qt.QLabel("")
285
+ self._warningWallTime.setPixmap(warning_icon.pixmap(20, state=qt.QIcon.On))
286
+ self.layout().addWidget(self._warningWallTime, 6, 2, 1, 1)
262
287
 
263
288
  # python exe / modules
264
289
  self._preProcessingGroup = qt.QGroupBox("pre-processing", self)
265
290
  self._preProcessingGroup.setLayout(qt.QFormLayout())
266
291
  self._preProcessingButtonGroup = qt.QButtonGroup(self)
267
292
  self._preProcessingButtonGroup.setExclusive(True)
268
- self.layout().addRow(self._preProcessingGroup)
293
+ self.layout().addWidget(self._preProcessingGroup, 10, 0, 1, 2)
269
294
 
270
295
  # python venv
271
- self._pythonVenv = qt.QLineEdit("/scisoft/tomotools/activate stable", self)
272
296
  self._sourceScriptCB = qt.QRadioButton("source script (python venv)", self)
297
+ self._pythonVenv = qt.QLineEdit("/scisoft/tomotools/activate stable", self)
273
298
  self._preProcessingButtonGroup.addButton(self._sourceScriptCB)
274
- self._preProcessingGroup.layout().addRow(self._sourceScriptCB, self._pythonVenv)
275
299
  self._pythonVenv.setToolTip(
276
300
  """
277
301
  Optional path to a bash script to source before executing the script.
278
302
  """
279
303
  )
280
-
304
+ self._preProcessingGroup.layout().addRow(self._sourceScriptCB, self._pythonVenv)
305
+ # module
281
306
  self._modulesQLE = qt.QLineEdit(", ".join(SlurmSettings.MODULES_TO_LOAD), self)
282
307
  self._modulesCB = qt.QRadioButton("module(s) to load", self)
283
308
  self._preProcessingButtonGroup.addButton(self._modulesCB)
284
- self._preProcessingGroup.layout().addRow(self._modulesCB, self._modulesQLE)
285
309
  self._preProcessingGroup.setToolTip(
286
310
  """
287
311
  Optional list of modules to load before executing the script. each module must be separated by a coma
288
312
  """
289
313
  )
314
+ self._preProcessingGroup.layout().addRow(self._modulesCB, self._modulesQLE)
290
315
 
291
316
  # job name
317
+ self._job_nameQLabel = qt.QLabel("job name", self)
318
+ self.layout().addWidget(self._job_nameQLabel, 13, 0, 1, 1)
319
+
292
320
  self._jobName = qt.QLineEdit("", self)
293
321
  self._jobName.setToolTip(
294
322
  """Job name. Can contains several keyword that will be formatted:
295
323
  - scan: will be replaced by the scan name
296
324
  - process: will be replaced by the process name (nabu slices, nabu volume...)
297
325
  - info: some extra information that can be provided by the process to `specify` the processing
298
- note: those key word have to be surronding by surrounded `{` and `}` in order to be formatted.
326
+ note: those key word have to be surrounding by surrounded `{` and `}` in order to be formatted.
299
327
  """
300
328
  )
301
- self._job_nameQLabel = qt.QLabel("job name", self)
302
- self.layout().addRow(self._job_nameQLabel, self._jobName)
329
+ self.layout().addWidget(self._jobName, 13, 1, 1, 1)
303
330
 
304
331
  # port
305
332
  # fixme: replace by a dedicated widget / validator for TCP adress
333
+ self._portLabel = qt.QLabel("port", self)
334
+ self.layout().addWidget(self._portLabel, 14, 0, 1, 1)
306
335
  self._port = _PortRangeSelection(self)
307
336
  self._port.setRange(0, 99999)
308
337
  self._port.setToolTip("TCP Port for the dask-distributed scheduler")
309
- self._portLabel = qt.QLabel("port", self)
310
- self.layout().addRow(self._portLabel, self._port)
338
+ self.layout().addWidget(self._port, 14, 1, 1, 1)
311
339
 
312
340
  # dashboard port
313
341
  self._dashboardPort = qt.QSpinBox(self)
342
+ self.layout().addWidget(self._dashboardPort, 15, 0, 1, 1)
314
343
  self._dashboardPort.setRange(0, 99999)
315
344
  self._dashboardPort.setToolTip("TCP Port for the dashboard")
316
345
  self._dashboardPortLabel = qt.QLabel("dashboard port", self)
317
- self.layout().addRow(self._dashboardPortLabel, self._dashboardPort)
346
+ self.layout().addWidget(self._dashboardPort, 15, 1, 1, 1)
318
347
 
319
348
  # sbatch advance parameters
320
349
  self._sbatchAdvancedParameters = qt.QGroupBox("sbatch advanced settings", self)
321
350
  self._sbatchAdvancedParameters.setLayout(qt.QFormLayout())
322
- self.layout().addRow(self._sbatchAdvancedParameters)
351
+ self.layout().addWidget(self._sbatchAdvancedParameters, 16, 0, 1, 2)
323
352
 
324
353
  ## export parameter
325
354
  self._exportValueCM = qt.QComboBox(self)
@@ -338,6 +367,7 @@ class SlurmSettingsWidget(qt.QWidget):
338
367
  )
339
368
  self._exportValueCM.setCurrentText("NONE")
340
369
  self._sbatchAdvancedParameters.layout().addRow("--export", self._exportValueCM)
370
+ self.layout().addWidget(self._warning_opd_export_opts, 16, 2, 1, 1)
341
371
 
342
372
  ## gpu card
343
373
  self._gpuCardCB = qt.QComboBox(self)
@@ -357,29 +387,39 @@ class SlurmSettingsWidget(qt.QWidget):
357
387
  self._portLabel.hide() # for now we don't use the port. This can be done automatically
358
388
  self._port.hide() # for now we don't use the port. This can be done automatically
359
389
  # for now nworker == ntask is not used
360
- self._nWorkers.setVisible(False)
390
+ self._nWorkersSP.setVisible(False)
361
391
  self._nWorkersLabel.setVisible(False)
362
392
 
363
393
  # set up the gui
364
- self._nCores.setValue(SlurmSettings.N_CORES_PER_TASK)
365
- self._nWorkers.setValue(SlurmSettings.N_TASKS)
366
- self._memory.setValue(SlurmSettings.MEMORY_PER_WORKER)
367
- if self._queue.findText(SlurmSettings.PARTITION) >= 0:
368
- self._queue.setCurrentText(SlurmSettings.PARTITION)
369
- self._nGpu.setValue(n_gpu)
394
+ self._nCoresSB.setValue(SlurmSettings.N_CORES_PER_TASK)
395
+ self._nWorkersSP.setValue(SlurmSettings.N_TASKS)
396
+ self._memorySB.setValue(SlurmSettings.MEMORY_PER_WORKER)
397
+ if self._queueCB.findText(SlurmSettings.PARTITION) >= 0:
398
+ self._queueCB.setCurrentText(SlurmSettings.PARTITION)
399
+ self._nGpuSB.setValue(n_gpu)
370
400
  self._jobName.setText(SlurmSettings.PROJECT_NAME)
401
+ self._wallTimeQLE.setText(SlurmSettings.DEFAULT_WALLTIME)
371
402
  self._modulesCB.setChecked(True) # by default we go for modules
403
+ self._warning_opd_p9.setVisible(False)
404
+ self._warning_opd_export_opts.setVisible(False)
405
+ self._warningWallTime.setVisible(False)
372
406
  self._preProcessingModeChanged()
373
407
  self._partitionChanged()
408
+ self._sbatchAdvancedSettingsChanged()
374
409
  self._nGpuChanged()
375
410
 
376
411
  # connect signal / slot
377
- self._nCores.valueChanged.connect(self._configurationChanged)
378
- self._nWorkers.valueChanged.connect(self._configurationChanged)
379
- self._memory.valueChanged.connect(self._configurationChanged)
380
- self._queue.currentTextChanged.connect(self._configurationChanged)
381
- self._nGpu.valueChanged.connect(self._configurationChanged)
412
+ self._nCoresSB.valueChanged.connect(self._configurationChanged)
413
+ self._nWorkersSP.valueChanged.connect(self._configurationChanged)
414
+ self._memorySB.valueChanged.connect(self._configurationChanged)
415
+ self._queueCB.currentTextChanged.connect(self._configurationChanged)
416
+ self._queueCB.currentTextChanged.connect(self._updateWallTimeWarnings)
417
+ self._queueCB.currentTextChanged.connect(self._updateWallTimeTooltip)
418
+ self._nGpuSB.valueChanged.connect(self._configurationChanged)
382
419
  self._jobName.editingFinished.connect(self._configurationChanged)
420
+ self._wallTimeQLE.editingFinished.connect(self._configurationChanged)
421
+ self._wallTimeQLE.editingFinished.connect(self._updateWallTimeWarnings)
422
+ self._wallTimeQLE.editingFinished.connect(self._updateWallTimeTooltip)
383
423
  self._pythonVenv.editingFinished.connect(self._configurationChanged)
384
424
  self._modulesQLE.editingFinished.connect(self._configurationChanged)
385
425
  self._preProcessingButtonGroup.buttonClicked.connect(self._configurationChanged)
@@ -388,10 +428,44 @@ class SlurmSettingsWidget(qt.QWidget):
388
428
  self._preProcessingButtonGroup.buttonClicked.connect(
389
429
  self._preProcessingModeChanged
390
430
  )
391
- self._queue.currentTextChanged.connect(self._partitionChanged)
392
- self._nGpu.valueChanged.connect(self._nGpuChanged)
431
+ self._queueCB.currentTextChanged.connect(self._partitionChanged)
432
+ self._nGpuSB.valueChanged.connect(self._nGpuChanged)
393
433
  self._gpuCardCB.currentTextChanged.connect(self._configurationChanged)
394
434
  self._exportValueCM.currentIndexChanged.connect(self._configurationChanged)
435
+ self._exportValueCM.currentIndexChanged.connect(
436
+ self._sbatchAdvancedSettingsChanged
437
+ )
438
+
439
+ def _updateWallTimeWarnings(self):
440
+ time_limit, _ = self._getPartitionWallTime(partition=self.getQueue())
441
+ palette = self._wallTimeQLE.palette()
442
+ wall_time_limit_exceed = time_limit is not None and _WallTime(
443
+ self.getWallTime()
444
+ ) > _WallTime(time_limit)
445
+ if wall_time_limit_exceed:
446
+ palette.setColor(self.backgroundRole(), self.WALL_TIME_INVALID_COLOR)
447
+ else:
448
+ palette.setColor(
449
+ self.backgroundRole(), self.__defaultWallTimeBackgroundColor
450
+ )
451
+ self._warningWallTime.setVisible(wall_time_limit_exceed)
452
+ self._wallTimeQLE.setPalette(palette)
453
+
454
+ def _updateWallTimeTooltip(self):
455
+ partition = self.getQueue()
456
+ time_limit, default_wall_time = self._getPartitionWallTime(partition=partition)
457
+ if time_limit is not None and default_wall_time is not None:
458
+ tooltip = "\n".join(
459
+ (
460
+ f"for partition {partition}:",
461
+ f"time limit: {time_limit}",
462
+ f"default limit: {default_wall_time}",
463
+ )
464
+ )
465
+ else:
466
+ tooltip = f"no wall time found for {partition}"
467
+ self._wallTimeQLE.setToolTip(tooltip)
468
+ self._warningWallTime.setToolTip(tooltip)
395
469
 
396
470
  def _nGpuChanged(self, *args, **kwargs):
397
471
  nGpu = self.getNGPU()
@@ -401,34 +475,34 @@ class SlurmSettingsWidget(qt.QWidget):
401
475
  self.sigConfigChanged.emit()
402
476
 
403
477
  def getNCores(self) -> int:
404
- return self._nCores.value()
478
+ return self._nCoresSB.value()
405
479
 
406
480
  def setNCores(self, n: int) -> None:
407
- self._nCores.setValue(int(n))
481
+ self._nCoresSB.setValue(int(n))
408
482
 
409
483
  def getNWorkers(self) -> int:
410
- return self._nWorkers.value()
484
+ return self._nWorkersSP.value()
411
485
 
412
486
  def setNWorkers(self, n) -> None:
413
- self._nWorkers.setValue(int(n))
487
+ self._nWorkersSP.setValue(int(n))
414
488
 
415
489
  def getMemory(self) -> int:
416
- return self._memory.value()
490
+ return self._memorySB.value()
417
491
 
418
492
  def setMemory(self, memory: int) -> None:
419
- self._memory.setValue(int(memory))
493
+ self._memorySB.setValue(int(memory))
420
494
 
421
495
  def getQueue(self) -> str:
422
- return self._queue.currentText()
496
+ return self._queueCB.currentText()
423
497
 
424
498
  def setQueue(self, text: str) -> None:
425
- self._queue.setCurrentText(text)
499
+ self._queueCB.setCurrentText(text)
426
500
 
427
501
  def getNGPU(self) -> int:
428
- return self._nGpu.value()
502
+ return self._nGpuSB.value()
429
503
 
430
504
  def setNGPU(self, n: int) -> None:
431
- self._nGpu.setValue(int(n))
505
+ self._nGpuSB.setValue(int(n))
432
506
 
433
507
  def getNJobs(self) -> int:
434
508
  return self._nJobs.value()
@@ -442,6 +516,31 @@ class SlurmSettingsWidget(qt.QWidget):
442
516
  def setProjectName(self, name):
443
517
  self._jobName.setText(name)
444
518
 
519
+ def getWallTime(self):
520
+ parts = self._wallTimeQLE.text().split(":")
521
+ hours = parts[0]
522
+ if len(parts) > 1:
523
+ minutes = parts[1]
524
+ else:
525
+ minutes = ""
526
+ if len(parts) > 2:
527
+ seconds = parts[2]
528
+ else:
529
+ seconds = ""
530
+
531
+ return ":".join(
532
+ [
533
+ hours.zfill(2),
534
+ minutes.zfill(2),
535
+ seconds.zfill(2),
536
+ ]
537
+ )
538
+
539
+ def setWallTime(self, walltime):
540
+ self._wallTimeQLE.setText(walltime)
541
+ self._updateWallTimeWarnings()
542
+ self._updateWallTimeTooltip()
543
+
445
544
  def getPythonExe(self):
446
545
  if self._sourceScriptCB.isChecked():
447
546
  return self._pythonVenv.text()
@@ -468,9 +567,9 @@ class SlurmSettingsWidget(qt.QWidget):
468
567
  if len(modules) > 0:
469
568
  self._modulesCB.setChecked(True)
470
569
 
471
- def getGpuCard(self) -> Optional[str]:
570
+ def getGpuCard(self) -> str | None:
472
571
  card = self._gpuCardCB.currentText()
473
- if card == "any" or self._nGpu == 0:
572
+ if card == "any" or self._nGpuSB == 0:
474
573
  return None
475
574
  else:
476
575
  return card
@@ -532,6 +631,10 @@ class SlurmSettingsWidget(qt.QWidget):
532
631
  if project_name is not None:
533
632
  self.setProjectName(project_name)
534
633
 
634
+ wall_time = config.get("walltime", None)
635
+ if wall_time is not None:
636
+ self.setWallTime(wall_time)
637
+
535
638
  python_venv = config.get("python_venv", None)
536
639
  if python_venv is not None:
537
640
  python_venv = python_venv.rstrip("'").rstrip('"')
@@ -562,6 +665,7 @@ class SlurmSettingsWidget(qt.QWidget):
562
665
  "partition": self.getQueue(),
563
666
  "n_gpus": self.getNGPU(),
564
667
  "job_name": self.getProjectName(),
668
+ "walltime": self.getWallTime(),
565
669
  "sbatch_extra_params": self.getSBatchExtraParams(),
566
670
  }
567
671
  if self._modulesCB.isChecked():
@@ -569,7 +673,7 @@ class SlurmSettingsWidget(qt.QWidget):
569
673
  elif self._sourceScriptCB.isChecked():
570
674
  config["python_venv"] = self.getPythonExe()
571
675
  else:
572
- raise ValueError("'modules' or python environement should be enable")
676
+ raise ValueError("'modules' or python environment should be enable")
573
677
  return config
574
678
 
575
679
  def getSlurmClusterConfiguration(self):
@@ -583,14 +687,29 @@ class SlurmSettingsWidget(qt.QWidget):
583
687
 
584
688
  def setConfigurationLevel(self, level: ConfigurationLevel):
585
689
  self._sbatchAdvancedParameters.setVisible(level >= ConfigurationLevel.ADVANCED)
690
+ self._wallTimeLabel.setVisible(level >= ConfigurationLevel.ADVANCED)
691
+ self._wallTimeQLE.setVisible(level >= ConfigurationLevel.ADVANCED)
586
692
 
587
693
  def _partitionChanged(self, *args, **kwargs):
588
694
  partition = self.getQueue()
695
+ # op(erator) accounts (from icc computers) cannot export to p9. they don't have home directories
696
+ self._warning_opd_p9.setVisible(
697
+ current_login_is_op_account() and partition.lower().startswith("p9")
698
+ )
589
699
  gpus = self._getGpus(partition=partition)
590
700
  self._gpuCardCB.clear()
591
701
  self._gpuCardCB.addItems(gpus)
592
702
  self._gpuCardCB.setCurrentText("any")
593
703
 
704
+ def _sbatchAdvancedSettingsChanged(self, *args, **kwargs):
705
+ # op(erator) accounts (from icc computers) must export ALL environment variable. Else job fails
706
+ # warning: we want to display the warning no matter if we are in 'advance options' or not.
707
+ # this way the user always see the warning when necessary
708
+ self._warning_opd_export_opts.setVisible(
709
+ current_login_is_op_account()
710
+ and self._exportValueCM.currentText() == "NONE"
711
+ )
712
+
594
713
  @cache(maxsize=None)
595
714
  def _getGpus(self, partition) -> tuple:
596
715
  try:
@@ -604,6 +723,15 @@ class SlurmSettingsWidget(qt.QWidget):
604
723
  ]
605
724
  return gpus
606
725
 
726
+ @cache(maxsize=None)
727
+ def _getPartitionWallTime(self, partition: str) -> tuple[str | None, str | None]:
728
+ try:
729
+ times = get_partition_walltime(partition=partition)
730
+ except Exception:
731
+ return None, None
732
+ else:
733
+ return times["time"], times["default_time"]
734
+
607
735
 
608
736
  class _PortRangeSelection(qt.QWidget):
609
737
  sigRangeChanged = qt.Signal()
@@ -647,8 +775,82 @@ class _PortRangeSelection(qt.QWidget):
647
775
  self._stepQSpinBox.value(),
648
776
  )
649
777
 
650
- def setRange(self, min_: int, max_: int, step: Optional[int] = None) -> None:
778
+ def setRange(self, min_: int, max_: int, step: int | None = None) -> None:
651
779
  self._fromQSpinBox.setValue(min(min_, max_))
652
780
  self._toQSpinBox.setValue(max(min_, max_))
653
781
  if step is not None:
654
782
  self._stepQSpinBox.setValue(step)
783
+
784
+
785
+ def get_login() -> str | None:
786
+ try:
787
+ return os.getlogin()
788
+ except OSError:
789
+ """In CI computer this raises the following error
790
+ OSError: [Errno 6] No such device or address
791
+ """
792
+ return None
793
+
794
+
795
+ def current_login_is_op_account() -> bool:
796
+ """
797
+ return True if the current login is a op[i]dXX login.
798
+ """
799
+ return is_op_account(get_login())
800
+
801
+
802
+ def is_op_account(user: str | None) -> bool:
803
+ """
804
+ Determines if a given username follows the 'op' account format,
805
+ specifically 'opdXX' or 'opidXX', where 'XX' are numeric digits.
806
+
807
+ Args:
808
+ user (Optional[str]): The username to check.
809
+
810
+ Returns:
811
+ bool: True if the username matches the pattern, False otherwise.
812
+ """
813
+
814
+ if user is None:
815
+ return False
816
+
817
+ op_account_pattern = r"^opi?d\d{2}$"
818
+ return bool(re.match(op_account_pattern, user))
819
+
820
+
821
+ class _WallTime:
822
+ """Util class to compare two walltime provided as D-HH:MM:SS or as HH:MM:SS"""
823
+
824
+ def __init__(self, walltime: str):
825
+ parts = walltime.split("-")
826
+ if len(parts) > 1:
827
+ assert len(parts) == 2, f"unexpected walltime format ({walltime})"
828
+ days = int(parts[0])
829
+ else:
830
+ days = 0
831
+
832
+ def minutes_to_seconds(value):
833
+ return value * 60
834
+
835
+ def hours_to_seconds(value):
836
+ return minutes_to_seconds(value * 60)
837
+
838
+ def days_to_seconds(value):
839
+ return hours_to_seconds(value * 24)
840
+
841
+ hours, minutes, seconds = map(int, parts[-1].split(":"))
842
+ self.value = (
843
+ seconds
844
+ + minutes_to_seconds(minutes)
845
+ + hours_to_seconds(hours)
846
+ + days_to_seconds(days)
847
+ )
848
+
849
+ def __lt__(self, other):
850
+ return self.value < other.value
851
+
852
+ def __gt__(self, other):
853
+ return self.value > other.value
854
+
855
+ def __eq__(self, other):
856
+ return self.value == other.value
@@ -1,31 +1,5 @@
1
1
  # coding: utf-8
2
- # /*##########################################################################
3
- #
4
- # Copyright (c) 2016-2017 European Synchrotron Radiation Facility
5
- #
6
- # Permission is hereby granted, free of charge, to any person obtaining a copy
7
- # of this software and associated documentation files (the "Software"), to deal
8
- # in the Software without restriction, including without limitation the rights
9
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
- # copies of the Software, and to permit persons to whom the Software is
11
- # furnished to do so, subject to the following conditions:
12
- #
13
- # The above copyright notice and this permission notice shall be included in
14
- # all copies or substantial portions of the Software.
15
- #
16
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
- # THE SOFTWARE.
23
- #
24
- # ###########################################################################*/
25
-
26
- __authors__ = ["H. Payno"]
27
- __license__ = "MIT"
28
- __date__ = "14/10/2021"
2
+ from __future__ import annotations
29
3
 
30
4
 
31
5
  import functools
File without changes