tomwer 1.2.1__py3-none-any.whl → 1.3.12__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 (334) hide show
  1. orangecontrib/tomwer/tutorials/icat_publication.ows +58 -0
  2. orangecontrib/tomwer/widgets/__init__.py +11 -11
  3. orangecontrib/tomwer/widgets/control/DataDiscoveryOW.py +2 -2
  4. orangecontrib/tomwer/widgets/control/DataListOW.py +9 -7
  5. orangecontrib/tomwer/widgets/control/DataListenerOW.py +6 -6
  6. orangecontrib/tomwer/widgets/control/DataSelectorOW.py +21 -10
  7. orangecontrib/tomwer/widgets/control/DataValidatorOW.py +6 -6
  8. orangecontrib/tomwer/widgets/control/EDF2NXTomomillOW.py +24 -7
  9. orangecontrib/tomwer/widgets/control/EmailOW.py +4 -4
  10. orangecontrib/tomwer/widgets/control/NXTomomillMixIn.py +3 -3
  11. orangecontrib/tomwer/widgets/control/NXTomomillOW.py +64 -23
  12. orangecontrib/tomwer/widgets/control/NXtomoConcatenate.py +20 -8
  13. orangecontrib/tomwer/widgets/control/NotifierOW.py +1 -0
  14. orangecontrib/tomwer/widgets/control/SingleTomoObjOW.py +6 -6
  15. orangecontrib/tomwer/widgets/control/VolumeSelector.py +7 -4
  16. orangecontrib/tomwer/widgets/control/VolumeSymLinkOW.py +182 -182
  17. orangecontrib/tomwer/widgets/debugtools/DatasetGeneratorOW.py +5 -5
  18. orangecontrib/tomwer/widgets/edit/DarkFlatPatchOW.py +4 -4
  19. orangecontrib/tomwer/widgets/edit/ImageKeyEditorOW.py +3 -3
  20. orangecontrib/tomwer/widgets/edit/ImageKeyUpgraderOW.py +8 -1
  21. orangecontrib/tomwer/widgets/edit/NXtomoEditorOW.py +3 -3
  22. orangecontrib/tomwer/widgets/edit/test/test_nxtomo_editor.py +3 -3
  23. orangecontrib/tomwer/widgets/icat/PublishProcessedDataOW.py +115 -0
  24. orangecontrib/tomwer/widgets/icat/RawDataScreenshotCreatorOW.py +98 -0
  25. orangecontrib/tomwer/widgets/icat/SaveToGalleryAndPublishOW.py +129 -0
  26. orangecontrib/tomwer/widgets/icat/__init__.py +13 -0
  27. orangecontrib/tomwer/widgets/icat/icons/add_gallery.png +0 -0
  28. orangecontrib/tomwer/widgets/icat/icons/add_gallery.svg +82 -0
  29. orangecontrib/tomwer/widgets/icat/icons/publish_processed_data.png +0 -0
  30. orangecontrib/tomwer/widgets/icat/icons/publish_processed_data.svg +95 -0
  31. orangecontrib/tomwer/widgets/icat/icons/raw_screenshots.png +0 -0
  32. orangecontrib/tomwer/widgets/icat/icons/raw_screenshots.svg +143 -0
  33. orangecontrib/tomwer/widgets/icons/tomwer_data_portal.png +0 -0
  34. orangecontrib/tomwer/widgets/icons/tomwer_data_portal.svg +76 -0
  35. orangecontrib/tomwer/widgets/reconstruction/AxisOW.py +22 -20
  36. orangecontrib/tomwer/widgets/reconstruction/CastNabuVolumeOW.py +19 -3
  37. orangecontrib/tomwer/widgets/reconstruction/NabuHelicalPrepareWeightsDoubleOW.py +184 -169
  38. orangecontrib/tomwer/widgets/reconstruction/NabuOW.py +23 -0
  39. orangecontrib/tomwer/widgets/reconstruction/NabuVolumeOW.py +39 -5
  40. orangecontrib/tomwer/widgets/reconstruction/SAAxisOW.py +18 -22
  41. orangecontrib/tomwer/widgets/reconstruction/SADeltaBetaOW.py +18 -26
  42. orangecontrib/tomwer/widgets/reconstruction/SinoNormOW.py +15 -19
  43. orangecontrib/tomwer/widgets/visualization/DataViewerOW.py +9 -9
  44. orangecontrib/tomwer/widgets/visualization/DiffViewerOW.py +1 -1
  45. orangecontrib/tomwer/widgets/visualization/LivesliceOW.py +1 -1
  46. orangecontrib/tomwer/widgets/visualization/NXtomoMetadataViewerOW.py +3 -3
  47. orangecontrib/tomwer/widgets/visualization/SinogramViewerOW.py +0 -1
  48. orangecontrib/tomwer/widgets/visualization/VolumeViewerOW.py +3 -29
  49. tomwer/__main__.py +7 -64
  50. tomwer/app/axis.py +3 -3
  51. tomwer/app/canvas.py +8 -0
  52. tomwer/app/canvas_launcher/config.py +16 -14
  53. tomwer/app/canvas_launcher/environ.py +1 -0
  54. tomwer/app/canvas_launcher/mainwindow.py +4 -1
  55. tomwer/app/darkref.py +1 -1
  56. tomwer/app/darkrefpatch.py +1 -1
  57. tomwer/app/diffframe.py +3 -3
  58. tomwer/app/imagekeyeditor.py +5 -5
  59. tomwer/app/imagekeyupgrader.py +5 -5
  60. tomwer/app/intensitynormalization.py +14 -13
  61. tomwer/app/{saaxis.py → multicor.py} +3 -3
  62. tomwer/app/{sadeltabeta.py → multipag.py} +3 -3
  63. tomwer/app/nabuapp.py +0 -11
  64. tomwer/app/radiostack.py +6 -4
  65. tomwer/app/samplemoved.py +3 -2
  66. tomwer/app/scanviewer.py +4 -2
  67. tomwer/app/sinogramviewer.py +3 -2
  68. tomwer/app/slicestack.py +3 -2
  69. tomwer/app/zstitching.py +88 -6
  70. tomwer/core/cluster/cluster.py +26 -0
  71. tomwer/core/log/logger.py +7 -5
  72. tomwer/core/process/conditions/filters.py +1 -1
  73. tomwer/core/process/control/datalistener/datalistener.py +19 -14
  74. tomwer/core/process/control/datawatcher/edfdwprocess.py +0 -9
  75. tomwer/core/process/control/nxtomoconcatenate.py +13 -13
  76. tomwer/core/process/control/nxtomomill.py +92 -34
  77. tomwer/core/process/control/scantransfer.py +20 -43
  78. tomwer/core/process/control/scanvalidator.py +3 -2
  79. tomwer/core/process/control/test/test_concatenate_nxtomos.py +9 -9
  80. tomwer/core/process/control/test/test_email.py +4 -4
  81. tomwer/core/process/control/test/test_h52nx_process.py +59 -7
  82. tomwer/core/process/control/test/test_volume_link.py +64 -64
  83. tomwer/core/process/control/timer.py +1 -1
  84. tomwer/core/process/control/volumesymlink.py +200 -200
  85. tomwer/core/process/edit/darkflatpatch.py +14 -15
  86. tomwer/core/process/edit/imagekeyeditor.py +41 -39
  87. tomwer/core/process/icat/__init__.py +0 -0
  88. tomwer/core/process/icat/createscreenshots.py +100 -0
  89. tomwer/core/process/icat/gallery.py +377 -0
  90. tomwer/core/process/icat/icatbase.py +36 -0
  91. tomwer/core/process/icat/publish.py +228 -0
  92. tomwer/core/process/icat/screenshots.py +27 -0
  93. tomwer/core/process/output.py +52 -0
  94. tomwer/core/process/reconstruction/axis/axis.py +280 -69
  95. tomwer/core/process/reconstruction/axis/mode.py +163 -48
  96. tomwer/core/process/reconstruction/axis/params.py +29 -21
  97. tomwer/core/process/reconstruction/darkref/darkrefs.py +41 -127
  98. tomwer/core/process/reconstruction/darkref/darkrefscopy.py +4 -3
  99. tomwer/core/process/reconstruction/darkref/params.py +1 -1
  100. tomwer/core/process/reconstruction/nabu/castvolume.py +4 -4
  101. tomwer/core/process/reconstruction/nabu/helical.py +9 -5
  102. tomwer/core/process/reconstruction/nabu/nabucommon.py +71 -78
  103. tomwer/core/process/reconstruction/nabu/nabuscores.py +425 -53
  104. tomwer/core/process/reconstruction/nabu/nabuslices.py +114 -93
  105. tomwer/core/process/reconstruction/nabu/nabuvolume.py +54 -27
  106. tomwer/core/process/reconstruction/nabu/plane.py +9 -0
  107. tomwer/core/process/reconstruction/nabu/settings.py +2 -2
  108. tomwer/core/process/reconstruction/nabu/utils.py +164 -26
  109. tomwer/core/process/reconstruction/output.py +108 -0
  110. tomwer/core/process/reconstruction/saaxis/saaxis.py +238 -264
  111. tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py +151 -87
  112. tomwer/core/process/reconstruction/scores/params.py +7 -4
  113. tomwer/core/process/reconstruction/scores/scores.py +13 -0
  114. tomwer/core/process/reconstruction/test/test_axis_params.py +2 -2
  115. tomwer/core/process/reconstruction/test/test_darkref.py +3 -3
  116. tomwer/core/process/reconstruction/test/test_darkref_copy.py +7 -7
  117. tomwer/core/process/reconstruction/test/test_saaxis.py +3 -4
  118. tomwer/core/process/reconstruction/test/test_sadeltabeta.py +2 -2
  119. tomwer/core/process/stitching/nabustitcher.py +13 -12
  120. tomwer/core/process/task.py +34 -26
  121. tomwer/core/process/test/test_axis.py +13 -12
  122. tomwer/core/process/test/test_dark_and_flat.py +10 -7
  123. tomwer/core/process/test/test_data_transfer.py +10 -8
  124. tomwer/core/process/test/test_nabu.py +14 -6
  125. tomwer/core/process/test/test_normalization.py +4 -4
  126. tomwer/core/scan/blissscan.py +3 -3
  127. tomwer/core/scan/edfscan.py +13 -10
  128. tomwer/core/scan/hdf5scan.py +19 -530
  129. tomwer/core/scan/nxtomoscan.py +534 -0
  130. tomwer/core/scan/scanbase.py +72 -44
  131. tomwer/core/scan/scanfactory.py +13 -13
  132. tomwer/core/scan/test/test_edf.py +2 -2
  133. tomwer/core/scan/test/test_future_scan.py +3 -3
  134. tomwer/core/scan/test/test_h5.py +18 -16
  135. tomwer/core/scan/test/test_process_registration.py +4 -40
  136. tomwer/core/scan/test/test_scan.py +5 -78
  137. tomwer/core/settings.py +22 -2
  138. tomwer/core/test/test_scanutils.py +8 -7
  139. tomwer/core/test/test_utils.py +35 -28
  140. tomwer/core/tomwer_object.py +1 -1
  141. tomwer/core/utils/__init__.py +0 -466
  142. tomwer/core/utils/deprecation.py +1 -1
  143. tomwer/core/utils/dictutils.py +14 -0
  144. tomwer/core/utils/lbsram.py +35 -0
  145. tomwer/core/utils/nxtomoutils.py +1 -1
  146. tomwer/core/utils/scanutils.py +6 -6
  147. tomwer/core/utils/spec.py +263 -0
  148. tomwer/core/volume/edfvolume.py +6 -6
  149. tomwer/core/volume/hdf5volume.py +6 -6
  150. tomwer/core/volume/jp2kvolume.py +6 -6
  151. tomwer/core/volume/rawvolume.py +6 -6
  152. tomwer/core/volume/tiffvolume.py +12 -12
  153. tomwer/core/volume/volumefactory.py +2 -2
  154. tomwer/gui/cluster/slurm.py +274 -65
  155. tomwer/gui/cluster/supervisor.py +12 -0
  156. tomwer/gui/cluster/test/test_cluster.py +14 -2
  157. tomwer/gui/cluster/test/test_supervisor.py +3 -3
  158. tomwer/gui/configuration/__init__.py +0 -0
  159. tomwer/gui/{reconstruction/nabu → configuration}/action.py +1 -32
  160. tomwer/gui/configuration/level.py +22 -0
  161. tomwer/gui/control/actions.py +54 -0
  162. tomwer/gui/control/datalist.py +83 -16
  163. tomwer/gui/control/datalistener.py +4 -16
  164. tomwer/gui/control/datawatcher/controlwidget.py +2 -4
  165. tomwer/gui/control/datawatcher/datawatcher.py +1 -24
  166. tomwer/gui/control/{email.py → emailnotifier.py} +9 -18
  167. tomwer/gui/control/history.py +2 -2
  168. tomwer/gui/control/observations.py +2 -2
  169. tomwer/gui/control/reducedarkflatselector.py +9 -9
  170. tomwer/gui/control/selectorwidgetbase.py +36 -9
  171. tomwer/gui/control/serie/seriecreator.py +5 -22
  172. tomwer/gui/control/test/test_email.py +1 -1
  173. tomwer/gui/control/test/test_scanvalidator.py +6 -5
  174. tomwer/gui/control/test/test_single_tomo_obj.py +3 -3
  175. tomwer/gui/control/tomoobjdisplaymode.py +8 -0
  176. tomwer/gui/debugtools/datasetgenerator.py +3 -3
  177. tomwer/gui/edit/dkrfpatch.py +20 -26
  178. tomwer/gui/edit/imagekeyeditor.py +11 -12
  179. tomwer/gui/edit/nxtomoeditor.py +111 -44
  180. tomwer/gui/edit/nxtomowarmer.py +7 -6
  181. tomwer/gui/edit/test/test_dkrf_patch.py +13 -13
  182. tomwer/gui/edit/test/test_image_key_editor.py +3 -3
  183. tomwer/gui/edit/test/test_nx_editor.py +40 -16
  184. tomwer/gui/icat/__init__.py +0 -0
  185. tomwer/gui/icat/createscreenshots.py +80 -0
  186. tomwer/gui/icat/gallery.py +214 -0
  187. tomwer/gui/icat/publish.py +187 -0
  188. tomwer/gui/imagefromfile.py +2 -2
  189. tomwer/gui/qfolderdialog.py +24 -1
  190. tomwer/gui/reconstruction/axis/CompareImages.py +88 -168
  191. tomwer/gui/reconstruction/axis/axis.py +171 -57
  192. tomwer/gui/reconstruction/axis/radioaxis.py +122 -257
  193. tomwer/gui/reconstruction/darkref/darkrefcopywidget.py +3 -2
  194. tomwer/gui/reconstruction/darkref/darkrefwidget.py +2 -1
  195. tomwer/gui/reconstruction/nabu/castvolume.py +14 -3
  196. tomwer/gui/reconstruction/nabu/check.py +9 -9
  197. tomwer/gui/reconstruction/nabu/helical.py +29 -12
  198. tomwer/gui/reconstruction/nabu/nabuconfig/base.py +2 -4
  199. tomwer/gui/reconstruction/nabu/nabuconfig/nabuconfig.py +2 -1
  200. tomwer/gui/reconstruction/nabu/nabuconfig/output.py +126 -35
  201. tomwer/gui/reconstruction/nabu/nabuconfig/phase.py +39 -32
  202. tomwer/gui/reconstruction/nabu/nabuconfig/preprocessing.py +222 -31
  203. tomwer/gui/reconstruction/nabu/nabuconfig/reconstruction.py +57 -27
  204. tomwer/gui/reconstruction/nabu/nabuflow.py +12 -20
  205. tomwer/gui/reconstruction/nabu/slices.py +10 -11
  206. tomwer/gui/reconstruction/nabu/volume.py +22 -10
  207. tomwer/gui/reconstruction/normalization/intensity.py +18 -48
  208. tomwer/gui/reconstruction/saaxis/corrangeselector.py +8 -24
  209. tomwer/gui/reconstruction/saaxis/dimensionwidget.py +1 -1
  210. tomwer/gui/reconstruction/saaxis/saaxis.py +9 -21
  211. tomwer/gui/reconstruction/sadeltabeta/saadeltabeta.py +45 -12
  212. tomwer/gui/reconstruction/scores/control.py +2 -9
  213. tomwer/gui/reconstruction/scores/scoreplot.py +13 -11
  214. tomwer/gui/reconstruction/test/test_axis.py +41 -16
  215. tomwer/gui/reconstruction/test/test_nabu.py +31 -9
  216. tomwer/gui/reconstruction/test/test_saaxis.py +3 -3
  217. tomwer/gui/reconstruction/test/test_sadeltabeta.py +12 -2
  218. tomwer/gui/settings.py +5 -28
  219. tomwer/gui/stackplot.py +2 -5
  220. tomwer/gui/stitching/action.py +49 -0
  221. tomwer/gui/stitching/config/axisparams.py +7 -24
  222. tomwer/gui/stitching/config/output.py +10 -8
  223. tomwer/gui/stitching/config/positionoveraxis.py +22 -23
  224. tomwer/gui/stitching/normalization.py +117 -0
  225. tomwer/gui/stitching/stitchandbackground.py +4 -6
  226. tomwer/gui/stitching/stitching.py +267 -45
  227. tomwer/gui/stitching/stitching_preview.py +62 -55
  228. tomwer/gui/stitching/stitching_raw.py +13 -12
  229. tomwer/gui/stitching/z_stitching/fineestimation.py +0 -60
  230. tomwer/gui/utils/buttons.py +112 -29
  231. tomwer/gui/utils/inputwidget.py +43 -25
  232. tomwer/gui/utils/lineselector/lineselector.py +1 -1
  233. tomwer/gui/utils/scandescription.py +4 -0
  234. tomwer/gui/utils/step.py +144 -0
  235. tomwer/gui/utils/unitsystem.py +2 -5
  236. tomwer/gui/utils/vignettes.py +176 -15
  237. tomwer/gui/visualization/dataviewer.py +48 -35
  238. tomwer/gui/visualization/diffviewer/diffviewer.py +7 -16
  239. tomwer/gui/visualization/diffviewer/shiftwidget.py +2 -5
  240. tomwer/gui/visualization/scanoverview.py +1 -1
  241. tomwer/gui/visualization/sinogramviewer.py +20 -36
  242. tomwer/gui/visualization/test/test_diffviewer.py +3 -3
  243. tomwer/gui/visualization/test/test_nx_tomo_metadata_viewer.py +4 -4
  244. tomwer/gui/visualization/test/test_sinogramviewer.py +2 -2
  245. tomwer/gui/visualization/test/test_stacks.py +3 -3
  246. tomwer/gui/visualization/test/test_volumeviewer.py +65 -67
  247. tomwer/gui/visualization/volumeviewer.py +114 -113
  248. tomwer/io/utils/h5pyutils.py +3 -3
  249. tomwer/io/utils/raw_and_processed_data.py +84 -0
  250. tomwer/io/utils/tomoobj.py +4 -6
  251. tomwer/io/utils/utils.py +7 -7
  252. tomwer/resources/gui/icons/parameters.svg +1 -1
  253. tomwer/resources/gui/icons/ruler.png +0 -0
  254. tomwer/resources/gui/icons/ruler.svg +273 -0
  255. tomwer/resources/gui/icons/short_description.png +0 -0
  256. tomwer/resources/gui/icons/short_description.svg +58 -0
  257. tomwer/resources/gui/icons/url.png +0 -0
  258. tomwer/resources/gui/icons/url.svg +58 -0
  259. tomwer/resources/gui/illustrations/no_rot.svg +1 -1
  260. tomwer/synctools/stacks/edit/darkflatpatch.py +19 -14
  261. tomwer/synctools/stacks/edit/imagekeyeditor.py +2 -2
  262. tomwer/synctools/stacks/reconstruction/axis.py +4 -4
  263. tomwer/synctools/stacks/reconstruction/castvolume.py +22 -7
  264. tomwer/synctools/stacks/reconstruction/dkrefcopy.py +25 -20
  265. tomwer/synctools/stacks/reconstruction/nabu.py +2 -2
  266. tomwer/synctools/stacks/reconstruction/normalization.py +2 -2
  267. tomwer/synctools/stacks/reconstruction/saaxis.py +2 -2
  268. tomwer/synctools/stacks/reconstruction/sadeltabeta.py +2 -2
  269. tomwer/synctools/test/test_darkRefs.py +7 -58
  270. tomwer/synctools/test/test_foldertransfer.py +6 -6
  271. tomwer/synctools/utils/scanstages.py +6 -6
  272. tomwer/tests/conftest.py +34 -0
  273. tomwer/tests/datasets.py +13 -0
  274. tomwer/tests/test_scripts.py +91 -41
  275. tomwer/tests/utils.py +5 -0
  276. tomwer/third_part/WaitingOverlay.py +110 -0
  277. tomwer/third_part/__init__.py +0 -0
  278. tomwer/version.py +2 -2
  279. tomwer-1.3.12-py3.11-nspkg.pth +1 -0
  280. {tomwer-1.2.1.dist-info → tomwer-1.3.12.dist-info}/METADATA +73 -58
  281. {tomwer-1.2.1.dist-info → tomwer-1.3.12.dist-info}/RECORD +287 -286
  282. {tomwer-1.2.1.dist-info → tomwer-1.3.12.dist-info}/WHEEL +1 -1
  283. orangecontrib/tomwer/widgets/reconstruction/TofuOW.py +0 -197
  284. orangecontrib/tomwer/widgets/reconstruction/icons/XY_lamino.svg +0 -168
  285. orangecontrib/tomwer/widgets/reconstruction/icons/XZ_lamino.svg +0 -275
  286. orangecontrib/tomwer/widgets/reconstruction/icons/YZ_lamino.svg +0 -182
  287. tomwer/app/lamino.py +0 -143
  288. tomwer/core/process/reconstruction/lamino/__init__.py +0 -1
  289. tomwer/core/process/reconstruction/lamino/tofu.py +0 -1000
  290. tomwer/core/process/test/test_lamino.py +0 -76
  291. tomwer/core/test/test_lamino.py +0 -92
  292. tomwer/gui/reconstruction/lamino/__init__.py +0 -31
  293. tomwer/gui/reconstruction/lamino/tofu/TofuOptionLoader.py +0 -107
  294. tomwer/gui/reconstruction/lamino/tofu/__init__.py +0 -1
  295. tomwer/gui/reconstruction/lamino/tofu/misc.py +0 -148
  296. tomwer/gui/reconstruction/lamino/tofu/projections.py +0 -896
  297. tomwer/gui/reconstruction/lamino/tofu/settings.py +0 -75
  298. tomwer/gui/reconstruction/lamino/tofu/tofu.py +0 -432
  299. tomwer/gui/reconstruction/lamino/tofu/tofuexpert.py +0 -567
  300. tomwer/gui/reconstruction/lamino/tofu/tofuoutput.py +0 -760
  301. tomwer/gui/reconstruction/test/test_lamino.py +0 -189
  302. tomwer/resources/gui/icons/esrf_1.svg +0 -307
  303. tomwer/resources/gui/icons/lamino_parameters.svg +0 -70
  304. tomwer/resources/gui/icons/triangle.svg +0 -80
  305. tomwer/resources/gui/illustrations/lamino_angle.png +0 -0
  306. tomwer/resources/gui/illustrations/lamino_angle.svg +0 -509
  307. tomwer/resources/gui/illustrations/lamino_beta_angle.png +0 -0
  308. tomwer/resources/gui/illustrations/lamino_beta_angle.svg +0 -97
  309. tomwer/resources/gui/illustrations/lamino_theta_angle.png +0 -0
  310. tomwer/resources/gui/illustrations/lamino_theta_angle.svg +0 -368
  311. tomwer/resources/gui/illustrations/manual_slice.png +0 -0
  312. tomwer/resources/gui/illustrations/manual_slice.svg +0 -221
  313. tomwer/resources/gui/illustrations/psi_angle.png +0 -0
  314. tomwer/resources/gui/illustrations/psi_angle.svg +0 -479
  315. tomwer/resources/gui/illustrations/rotation_center.png +0 -0
  316. tomwer/resources/gui/illustrations/rotation_center.svg +0 -276
  317. tomwer/resources/gui/illustrations/slice_stack.png +0 -0
  318. tomwer/resources/gui/illustrations/slice_stack.svg +0 -266
  319. tomwer/resources/gui/illustrations/xy_slice.png +0 -0
  320. tomwer/resources/gui/illustrations/xy_slice.svg +0 -269
  321. tomwer/resources/gui/illustrations/xz_slice.png +0 -0
  322. tomwer/resources/gui/illustrations/xz_slice.svg +0 -270
  323. tomwer/resources/gui/illustrations/yz_slice.png +0 -0
  324. tomwer/resources/gui/illustrations/yz_slice.svg +0 -270
  325. tomwer/synctools/stacks/reconstruction/lamino.py +0 -233
  326. tomwer/synctools/test/test_scanstages.py +0 -162
  327. tomwer/tests/utils/__init__.py +0 -247
  328. tomwer/tests/utils/utilstest.py +0 -220
  329. tomwer-1.2.1-py3.11-nspkg.pth +0 -1
  330. /tomwer/core/process/control/{email.py → emailnotifier.py} +0 -0
  331. {tomwer-1.2.1.dist-info → tomwer-1.3.12.dist-info}/LICENSE +0 -0
  332. {tomwer-1.2.1.dist-info → tomwer-1.3.12.dist-info}/entry_points.txt +0 -0
  333. {tomwer-1.2.1.dist-info → tomwer-1.3.12.dist-info}/namespace_packages.txt +0 -0
  334. {tomwer-1.2.1.dist-info → tomwer-1.3.12.dist-info}/top_level.txt +0 -0
@@ -37,7 +37,7 @@ from silx.gui import qt
37
37
  from tomwer.core.process.reconstruction.normalization import SinoNormalizationTask
38
38
  from tomwer.core.scan.scanbase import TomwerScanBase
39
39
  from tomwer.core.settings import get_lbsram_path, isOnLbsram
40
- from tomwer.core.utils import isLowOnMemory
40
+ from tomwer.core.utils.lbsram import is_low_on_memory
41
41
 
42
42
  from ..processingstack import FIFO, ProcessingThread
43
43
 
@@ -60,7 +60,7 @@ class INormalizationProcessStack(FIFO, qt.QObject):
60
60
  )
61
61
  _logger.processStarted(f"start intensity normalization {data}")
62
62
  assert isinstance(data, TomwerScanBase)
63
- if isOnLbsram(data) and isLowOnMemory(get_lbsram_path()) is True:
63
+ if isOnLbsram(data) and is_low_on_memory(get_lbsram_path()) is True:
64
64
  # if computer is running into low memory on lbsram skip it
65
65
  mess = "low memory, skip intensity normalization", data.path
66
66
  ProcessManager().notify_dataset_state(
@@ -37,7 +37,7 @@ from silx.gui import qt
37
37
  from tomwer.core.process.reconstruction.saaxis import SAAxisTask
38
38
  from tomwer.core.scan.scanbase import TomwerScanBase
39
39
  from tomwer.core.settings import get_lbsram_path, isOnLbsram
40
- from tomwer.core.utils import isLowOnMemory
40
+ from tomwer.core.utils.lbsram import is_low_on_memory
41
41
  from tomwer.synctools.axis import QAxisRP
42
42
  from tomwer.synctools.saaxis import QSAAxisParams
43
43
 
@@ -78,7 +78,7 @@ class SAAxisProcessStack(FIFO, qt.QObject):
78
78
  self._data_currently_computed = data
79
79
  saaxis_params = QSAAxisParams.from_dict(configuration)
80
80
  saaxis_params.frame_width = data.dim_1
81
- if isOnLbsram(data) and isLowOnMemory(get_lbsram_path()) is True:
81
+ if isOnLbsram(data) and is_low_on_memory(get_lbsram_path()) is True:
82
82
  # if computer is running into low memory on lbsram skip it
83
83
  mess = f"low memory, skip saaxis calculation {data.path}"
84
84
  ProcessManager().notify_dataset_state(
@@ -39,7 +39,7 @@ from tomwer.core.process.reconstruction.sadeltabeta.sadeltabeta import (
39
39
  )
40
40
  from tomwer.core.scan.scanbase import TomwerScanBase
41
41
  from tomwer.core.settings import get_lbsram_path, isOnLbsram
42
- from tomwer.core.utils import isLowOnMemory
42
+ from tomwer.core.utils.lbsram import is_low_on_memory
43
43
  from tomwer.synctools.axis import QAxisRP
44
44
  from tomwer.synctools.sadeltabeta import QSADeltaBetaParams
45
45
 
@@ -79,7 +79,7 @@ class SADeltaBetaProcessStack(FIFO, qt.QObject):
79
79
  data.sa_delta_beta_params = QSADeltaBetaParams()
80
80
  self._data_currently_computed = data
81
81
  sa_delta_beta_params = QSADeltaBetaParams.from_dict(configuration)
82
- if isOnLbsram(data) and isLowOnMemory(get_lbsram_path()) is True:
82
+ if isOnLbsram(data) and is_low_on_memory(get_lbsram_path()) is True:
83
83
  # if computer is running into low memory on lbsram skip it
84
84
  mess = f"low memory, skip sa-delta-beta-axis calculation {data.path}"
85
85
  ProcessManager().notify_dataset_state(
@@ -38,9 +38,8 @@ from silx.gui.utils.testutils import TestCaseQt
38
38
 
39
39
  from tomwer.core.process.reconstruction.darkref.darkrefs import DarkRefsTask
40
40
  from tomwer.core.process.reconstruction.darkref.params import DKRFRP, ReduceMethod
41
- from tomwer.core.scan.scanfactory import ScanFactory
42
41
  from tomwer.core.utils.scanutils import MockEDF
43
- from tomwer.tests.utils import UtilsTest
42
+ from tomwer.tests.datasets import TomwerCIDatasets
44
43
 
45
44
 
46
45
  class TestDarkRefsBehavior(TestCaseQt):
@@ -58,7 +57,9 @@ class TestDarkRefsBehavior(TestCaseQt):
58
57
  """number of theoretical dark file the algorithm should create"""
59
58
  self.dataset_folder = os.path.join(self.tmpDir, self.datasetsID)
60
59
 
61
- dataDir = UtilsTest.getEDFDataset(self.datasetsID)
60
+ dataDir = TomwerCIDatasets.get_dataset(
61
+ f"edf_datasets/{self.datasetsID}",
62
+ )
62
63
  shutil.copytree(dataDir, self.dataset_folder)
63
64
  files = os.listdir(self.dataset_folder)
64
65
  for _f in files:
@@ -380,7 +381,9 @@ class TestDarkAccumulation(TestCaseQt):
380
381
  def setUp(self):
381
382
  super().setUp()
382
383
  self.dataset = "bone8_1_"
383
- dataDir = UtilsTest.getEDFDataset(self.dataset)
384
+ dataDir = TomwerCIDatasets.get_dataset(
385
+ f"edf_datasets/{self.dataset}",
386
+ )
384
387
  self.outputdir = tempfile.mkdtemp()
385
388
  shutil.copytree(src=dataDir, dst=os.path.join(self.outputdir, self.dataset))
386
389
  self.darkFile = os.path.join(self.outputdir, self.dataset, "dark.edf")
@@ -418,57 +421,3 @@ class TestDarkAccumulation(TestCaseQt):
418
421
  with fabio.open(self.darkFile) as dsc:
419
422
  self.computed_dark = dsc.data
420
423
  self.assertTrue(numpy.array_equal(self.computed_dark, self.dark_reference))
421
-
422
-
423
- class TestPCOTomo(TestCaseQt):
424
- """Test processing of DKRF are correct"""
425
-
426
- def setUp(self):
427
- TestCaseQt.setUp(self)
428
- self.tmp_dir = tempfile.mkdtemp()
429
- MockEDF.fastMockAcquisition(self.tmp_dir)
430
-
431
- self.recons_params = DKRFRP()
432
- self.recons_params.flat_calc_method = ReduceMethod.NONE
433
- self.recons_params.dark_calc_method = ReduceMethod.NONE
434
- self.recons_params.dark_pattern = ".*_dark_.*"
435
- self.recons_params.flat_pattern = ".*_ref_.*"
436
- self.recons_params._set_remove_opt(True)
437
-
438
- def copyDataset(self, dataset):
439
- folder = os.path.join(self.tmp_dir, dataset)
440
- shutil.copytree(os.path.join(UtilsTest.getEDFDataset(dataset)), folder)
441
- self.scan = ScanFactory.create_scan_object(scan_path=folder)
442
-
443
- def tearDown(self):
444
- shutil.rmtree(self.tmp_dir)
445
-
446
- def testDark2x2Scan(self):
447
- self.dataset = "pcotomo_2x2scan_refdarkbeg_end_conti"
448
- self.copyDataset(self.dataset)
449
- self.recons_params.dark_calc_method = ReduceMethod.MEDIAN
450
- dar_ref_process = DarkRefsTask(
451
- inputs={
452
- "dark_ref_params": self.recons_params,
453
- "data": self.scan,
454
- "darkhst_prefix": "darkHST",
455
- "force_sync": True,
456
- "serialize_output_data": False,
457
- }
458
- )
459
- dar_ref_process.run()
460
-
461
- def testRef2x2Scan(self):
462
- self.dataset = "pcotomo_2x2scan_refdarkbeg_end_conti"
463
- self.copyDataset(self.dataset)
464
- self.recons_params.flat_calc_method = ReduceMethod.MEDIAN
465
- dar_ref_process = DarkRefsTask(
466
- inputs={
467
- "dark_ref_params": self.recons_params,
468
- "data": self.scan,
469
- "darkhst_prefix": "darkHST",
470
- "force_sync": True,
471
- "serialize_output_data": False,
472
- }
473
- )
474
- dar_ref_process.run()
@@ -40,12 +40,12 @@ from nxtomomill.converter import from_h5_to_nx
40
40
  from nxtomomill.io.config.hdf5config import TomoHDF5Config
41
41
  from silx.gui.utils.testutils import TestCaseQt
42
42
 
43
- from tomwer.core.scan.hdf5scan import HDF5TomoScan
43
+ from tomwer.core.scan.nxtomoscan import NXtomoScan
44
44
  from tomwer.core.scan.scanfactory import ScanFactory
45
- from tomwer.core.utils import rebaseParFile
45
+ from tomwer.core.utils.spec import rebaseParFile
46
46
  from tomwer.core.utils.scanutils import MockEDF
47
47
  from tomwer.synctools.datatransfert import ScanTransfer
48
- from tomwer.tests.utils import UtilsTest
48
+ from tomwer.tests.datasets import TomwerCIDatasets
49
49
 
50
50
  try:
51
51
  from tomwer.synctools.rsyncmanager import RSyncManager
@@ -239,7 +239,7 @@ class TestHDFDataTransfert(TestCaseQt):
239
239
  self.input_dir = tempfile.mkdtemp()
240
240
  self.output_dir = tempfile.mkdtemp()
241
241
  shutil.copytree(
242
- UtilsTest.getBlissDataset(folderID="sample"),
242
+ TomwerCIDatasets.get_dataset("bliss/sample"),
243
243
  os.path.join(self.input_dir, "sample"),
244
244
  )
245
245
 
@@ -272,7 +272,7 @@ class TestHDFDataTransfert(TestCaseQt):
272
272
  output_file_path, entry = results[0]
273
273
  assert os.path.exists(output_file_path)
274
274
  assert os.path.isfile(output_file_path)
275
- self.scan = HDF5TomoScan(scan=output_file_path, entry=entry)
275
+ self.scan = NXtomoScan(scan=output_file_path, entry=entry)
276
276
 
277
277
  # register information regarding origin of the file
278
278
  from tomwer.core.process.control.datalistener import DataListener
@@ -333,7 +333,7 @@ class TestPreTransfert(unittest.TestCase):
333
333
 
334
334
  def setUp(self):
335
335
  unittest.TestCase.setUp(self)
336
- folderDataset = UtilsTest.getEDFDataset("scan_3_")
336
+ folderDataset = TomwerCIDatasets.get_dataset("edf_datasets/scan_3_")
337
337
  self.tmpdir = tempfile.mkdtemp()
338
338
  self.outputfolder = tempfile.mkdtemp()
339
339
  scan_path = os.path.join(self.tmpdir, "scan_3_")
@@ -38,7 +38,7 @@ from silx.io.url import DataUrl
38
38
  from silx.utils.enum import Enum as _Enum
39
39
 
40
40
  from tomwer.core.scan.edfscan import EDFTomoScan
41
- from tomwer.core.scan.hdf5scan import HDF5TomoScan
41
+ from tomwer.core.scan.nxtomoscan import NXtomoScan
42
42
  from tomwer.core.scan.scanbase import TomwerScanBase
43
43
  from tomwer.synctools.rsyncmanager import RSyncManager
44
44
 
@@ -117,7 +117,7 @@ class ScanStages:
117
117
  RSyncManager().sync_file(
118
118
  source=info_file, target=file_info_dest, wait=True
119
119
  )
120
- elif isinstance(self.scan, HDF5TomoScan):
120
+ elif isinstance(self.scan, NXtomoScan):
121
121
  raise NotImplementedError()
122
122
  elif stage is ScanStages.AcquisitionStage.ACQUI_ON_GOING:
123
123
  # copy half of the acquisition file
@@ -129,7 +129,7 @@ class ScanStages:
129
129
  n_url -= 1
130
130
  self._copy_url_file(url=urls[keys[n_url]], dest_dir=dest_dir)
131
131
 
132
- elif isinstance(self.scan, HDF5TomoScan):
132
+ elif isinstance(self.scan, NXtomoScan):
133
133
  raise NotImplementedError()
134
134
  elif stage is ScanStages.AcquisitionStage.ACQUI_ENDED:
135
135
  if isinstance(self.scan, EDFTomoScan):
@@ -142,7 +142,7 @@ class ScanStages:
142
142
  )
143
143
  xml_dest = os.path.join(dest_dir, os.path.basename(xml_file))
144
144
  RSyncManager().sync_file(source=xml_file, target=xml_dest, wait=True)
145
- elif isinstance(self.scan, HDF5TomoScan):
145
+ elif isinstance(self.scan, NXtomoScan):
146
146
  raise NotImplementedError()
147
147
  elif stage is ScanStages.AcquisitionStage.RECONSTRUCTION_ADDED:
148
148
  # copy reconstruction
@@ -188,14 +188,14 @@ class ScanStages:
188
188
  RSyncManager().sync_file(
189
189
  source=_xml_file, target=xml_dest, wait=True
190
190
  )
191
- elif isinstance(self.scan, HDF5TomoScan):
191
+ elif isinstance(self.scan, NXtomoScan):
192
192
  raise NotImplementedError()
193
193
  elif stage is ScanStages.AcquisitionStage.COMPLETE:
194
194
  if isinstance(self.scan, EDFTomoScan):
195
195
  for file_ in os.listdir(self.scan.path):
196
196
  file_fp = os.path.join(self.scan.path, file_)
197
197
  RSyncManager().sync_file(source=file_fp, target=dest_dir, wait=True)
198
- elif isinstance(self.scan, HDF5TomoScan):
198
+ elif isinstance(self.scan, NXtomoScan):
199
199
  raise NotImplementedError()
200
200
  else:
201
201
  raise ValueError("given stage is not recognized", stage)
tomwer/tests/conftest.py CHANGED
@@ -1,4 +1,5 @@
1
1
  import gc
2
+ import os
2
3
  import logging
3
4
 
4
5
  import pytest
@@ -49,3 +50,36 @@ def warn_qtwidgets_alive():
49
50
  len(widgets),
50
51
  "\n ".join(map(str, widgets)),
51
52
  )
53
+
54
+
55
+ @pytest.fixture(scope="function")
56
+ def nxtomo_scan_180(tmp_path):
57
+ test_path = tmp_path / "test"
58
+ test_path.mkdir()
59
+ yield create_default_scan(
60
+ scan_path=os.path.join(test_path, "scan_180"),
61
+ scan_range=180,
62
+ )
63
+
64
+
65
+ @pytest.fixture(scope="function")
66
+ def nxtomo_scan_360(tmp_path):
67
+ test_path = tmp_path / "test"
68
+ test_path.mkdir()
69
+ yield create_default_scan(
70
+ scan_path=os.path.join(test_path, "scan_360"),
71
+ scan_range=360,
72
+ )
73
+
74
+
75
+ def create_default_scan(scan_path: str, scan_range: int):
76
+ from tomwer.core.utils.scanutils import MockNXtomo
77
+
78
+ return MockNXtomo(
79
+ scan_path=scan_path,
80
+ n_proj=10,
81
+ n_ini_proj=10,
82
+ scan_range=scan_range,
83
+ dim=20,
84
+ energy=12.3,
85
+ ).scan
@@ -0,0 +1,13 @@
1
+ import os
2
+ from tomoscan.test.datasets import GitlabProject
3
+
4
+ TomwerCIDatasets = GitlabProject(
5
+ branch_name="tomwer",
6
+ host="https://gitlab.esrf.fr",
7
+ cache_dir=os.path.join(
8
+ os.path.dirname(__file__),
9
+ "__archive__",
10
+ ),
11
+ token=None,
12
+ project_id=4299, # https://gitlab.esrf.fr/tomotools/ci_datasets
13
+ )
@@ -1,44 +1,10 @@
1
- # coding: utf-8
2
- # /*##########################################################################
3
- # Copyright (C) 2016 European Synchrotron Radiation Facility
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
22
- #
23
- #############################################################################*/
24
-
25
-
26
- from __future__ import absolute_import, division, print_function
27
-
28
1
  """Test suite to scripts"""
29
2
 
30
- __authors__ = ["V.Valls", "H.Payno"]
31
- __license__ = "MIT"
32
- __copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
33
- __date__ = "21/02/2018"
34
-
35
-
36
3
  import logging
37
4
  import subprocess
38
5
  import sys
39
6
  import unittest
40
-
41
- from tomwer.tests.utils.utilstest import UtilsTest
7
+ import os
42
8
 
43
9
  _logger = logging.getLogger(__name__)
44
10
 
@@ -77,8 +43,9 @@ class TestScriptsHelp(unittest.TestCase):
77
43
  self.assertEqual(p.returncode, 0)
78
44
 
79
45
  def executeAppHelp(self, script_name, module_name):
80
- script = UtilsTest.script_path(script_name, module_name)
81
- env = UtilsTest.get_test_env()
46
+ test_script = ScriptTest()
47
+ script = test_script.script_path(script_name, module_name)
48
+ env = test_script.get_test_env()
82
49
  if script.endswith(".exe"):
83
50
  command_line = [script]
84
51
  else:
@@ -89,23 +56,106 @@ class TestScriptsHelp(unittest.TestCase):
89
56
  def testAxis(self):
90
57
  self.executeAppHelp("axis", "tomwer.app.axis")
91
58
 
59
+ def testCanvas(self):
60
+ self.executeAppHelp("axis", "tomwer.app.canvas")
61
+
92
62
  def testDarkRef(self):
93
63
  self.executeAppHelp("darkref", "tomwer.app.darkref")
94
64
 
95
- def testLamino(self):
96
- self.executeAppHelp("lamino", "tomwer.app.lamino")
65
+ def testDarkRefPath(self):
66
+ self.executeAppHelp("darkrefpatch", "tomwer.app.darkrefpatch")
67
+
68
+ def testDiffFrame(self):
69
+ self.executeAppHelp("diffFrame", "tomwer.app.diffframe")
70
+
71
+ def testImageKeyEditor(self):
72
+ self.executeAppHelp("image-key-editor", "tomwer.app.imagekeyeditor")
73
+
74
+ def testImageKeyUpgrader(self):
75
+ self.executeAppHelp("image-key-upgrader", "tomwer.app.imagekeyupgrader")
76
+
77
+ def testIntensityNormalization(self):
78
+ self.executeAppHelp(
79
+ "intensity-normalization", "tomwer.app.intensitynormalization"
80
+ )
81
+
82
+ def testMulticor(self):
83
+ self.executeAppHelp("multicor", "tomwer.app.multicor")
84
+
85
+ def testMultiPag(self):
86
+ self.executeAppHelp("multipag", "tomwer.app.multipag")
97
87
 
98
88
  def testNabu(self):
99
89
  self.executeAppHelp("nabu", "tomwer.app.nabuapp")
100
90
 
91
+ def testNxTomoEditor(self):
92
+ self.executeAppHelp("nxtomo-editor", "tomwer.app.nxtomoeditor")
93
+
94
+ def testPatchRawDarkflat(self):
95
+ self.executeAppHelp("patch-raw-dark-flat", "tomwer.app.patchrawdarkflat")
96
+
101
97
  def testRadioStack(self):
102
98
  self.executeAppHelp("radiostack", "tomwer.app.radiostack")
103
99
 
100
+ def testReduceDarkFlat(self):
101
+ self.executeAppHelp("reduce-dark-flat", "tomwer.app.reducedarkflat")
102
+
103
+ def testRSync(self):
104
+ self.executeAppHelp("rsync", "tomwer.app.rsync")
105
+
104
106
  def testSampleMoved(self):
105
107
  self.executeAppHelp("samplemoved", "tomwer.app.samplemoved")
106
108
 
109
+ def testScanviewer(self):
110
+ self.executeAppHelp("scanviewer", "tomwer.app.scanviewer")
111
+
112
+ def testSinogramViewer(self):
113
+ self.executeAppHelp("sinogramviewer", "tomwer.app.sinogramviewer")
114
+
107
115
  def testSliceStack(self):
108
116
  self.executeAppHelp("slicestack", "tomwer.app.slicestack")
109
117
 
110
- def testRSync(self):
111
- self.executeAppHelp("rsync", "tomwer.app.rsync")
118
+ def testStopDataListener(self):
119
+ self.executeAppHelp("stop-data-listener", "tomwer.app.stopdatalistener")
120
+
121
+ def testZStitching(self):
122
+ self.executeAppHelp("zstitching", "tomwer.app.zstitching")
123
+
124
+
125
+ class ScriptTest:
126
+ """
127
+ Class providing useful stuff for preparing script tests.
128
+ """
129
+
130
+ def get_test_env(self):
131
+ """
132
+ Returns an associated environment with a working project.
133
+ """
134
+ env = dict((str(k), str(v)) for k, v in os.environ.items())
135
+ env["PYTHONPATH"] = os.pathsep.join(sys.path)
136
+ return env
137
+
138
+ def script_path(self, script_name, module_name):
139
+ """Returns the script path according to it's location"""
140
+ import importlib
141
+
142
+ module = importlib.import_module(module_name)
143
+ script = module.__file__
144
+ return script
145
+
146
+ def get_installed_script_path(self, script):
147
+ """
148
+ Returns the path of the executable and the associated environment
149
+
150
+ In Windows, it checks availability of script using .py .bat, and .exe
151
+ file extensions.
152
+ """
153
+ paths = os.environ.get("PATH", "").split(os.pathsep)
154
+ for base in paths:
155
+ # clean up extra quotes from paths
156
+ if base.startswith('"') and base.endswith('"'):
157
+ base = base[1:-1]
158
+ # script not found
159
+ _logger.warning("Script '%s' not found in paths: %s", script, ":".join(paths))
160
+ script_path = script
161
+ return script_path
tomwer/tests/utils.py ADDED
@@ -0,0 +1,5 @@
1
+ import os
2
+
3
+
4
+ def skip_gui_test():
5
+ return os.environ.get("_TOMWER_NO_GUI_UNIT_TESTS", "False") == "True"
@@ -0,0 +1,110 @@
1
+ from typing import Optional
2
+ from silx.gui.widgets.WaitingPushButton import WaitingPushButton
3
+ from silx.gui import qt
4
+ from silx.gui.qt import inspect as qt_inspect
5
+ from silx.gui.plot import PlotWidget
6
+
7
+
8
+ class WaitingOverlay(qt.QWidget):
9
+ """Widget overlaying another widget with a processing wheel icon.
10
+
11
+ :param parent: widget on top of which to display the "processing/waiting wheel"
12
+ """
13
+
14
+ def __init__(self, parent: qt.QWidget) -> None:
15
+ super().__init__(parent)
16
+ self.setContentsMargins(0, 0, 0, 0)
17
+
18
+ self._waitingButton = WaitingPushButton(self)
19
+ self._waitingButton.setDown(True)
20
+ self._waitingButton.setWaiting(True)
21
+ self._waitingButton.setStyleSheet(
22
+ "QPushButton { background-color: rgba(150, 150, 150, 40); border: 0px; border-radius: 10px; }"
23
+ )
24
+ self._registerParent(parent)
25
+
26
+ def text(self) -> str:
27
+ """Returns displayed text"""
28
+ return self._waitingButton.text()
29
+
30
+ def setText(self, text: str):
31
+ """Set displayed text"""
32
+ self._waitingButton.setText(text)
33
+ self._resize()
34
+
35
+ def _listenedWidget(self, parent: qt.QWidget) -> qt.QWidget:
36
+ """Returns widget to register event filter to according to parent"""
37
+ if isinstance(parent, PlotWidget):
38
+ return parent.getWidgetHandle()
39
+ return parent
40
+
41
+ def _backendChanged(self):
42
+ self._listenedWidget(self.parent()).installEventFilter(self)
43
+ self._resizeLater()
44
+
45
+ def _registerParent(self, parent: Optional[qt.QWidget]):
46
+ if parent is None:
47
+ return
48
+ self._listenedWidget(parent).installEventFilter(self)
49
+ if isinstance(parent, PlotWidget):
50
+ parent.sigBackendChanged.connect(self._backendChanged)
51
+ self._resize()
52
+
53
+ def _unregisterParent(self, parent: Optional[qt.QWidget]):
54
+ if parent is None:
55
+ return
56
+ if isinstance(parent, PlotWidget):
57
+ parent.sigBackendChanged.disconnect(self._backendChanged)
58
+ self._listenedWidget(parent).removeEventFilter(self)
59
+
60
+ def setParent(self, parent: qt.QWidget):
61
+ self._unregisterParent(self.parent())
62
+ super().setParent(parent)
63
+ self._registerParent(parent)
64
+
65
+ def showEvent(self, event: qt.QShowEvent):
66
+ super().showEvent(event)
67
+ self._waitingButton.setVisible(True)
68
+
69
+ def hideEvent(self, event: qt.QHideEvent):
70
+ super().hideEvent(event)
71
+ self._waitingButton.setVisible(False)
72
+
73
+ def _resize(self):
74
+ if not qt_inspect.isValid(self):
75
+ return # For _resizeLater in case the widget has been deleted
76
+
77
+ parent = self.parent()
78
+ if parent is None:
79
+ return
80
+
81
+ size = self._waitingButton.sizeHint()
82
+ if isinstance(parent, PlotWidget):
83
+ offset = parent.getWidgetHandle().mapTo(parent, qt.QPoint(0, 0))
84
+ left, top, width, height = parent.getPlotBoundsInPixels()
85
+ rect = qt.QRect(
86
+ qt.QPoint(
87
+ int(offset.x() + left + width / 2 - size.width() / 2),
88
+ int(offset.y() + top + height / 2 - size.height() / 2),
89
+ ),
90
+ size,
91
+ )
92
+ else:
93
+ position = parent.size()
94
+ position = (position - size) / 2
95
+ rect = qt.QRect(qt.QPoint(position.width(), position.height()), size)
96
+ self.setGeometry(rect)
97
+ self.raise_()
98
+
99
+ def _resizeLater(self):
100
+ qt.QTimer.singleShot(0, self._resize)
101
+
102
+ def eventFilter(self, watched: qt.QWidget, event: qt.QEvent):
103
+ if event.type() == qt.QEvent.Resize:
104
+ self._resize()
105
+ self._resizeLater() # Defer resize for the receiver to have handled it
106
+ return super().eventFilter(watched, event)
107
+
108
+ # expose Waiting push button API
109
+ def setIconSize(self, size):
110
+ self._waitingButton.setIconSize(size)
File without changes
tomwer/version.py CHANGED
@@ -76,8 +76,8 @@ RELEASE_LEVEL_VALUE = {
76
76
  }
77
77
 
78
78
  MAJOR = 1
79
- MINOR = 2
80
- MICRO = 1
79
+ MINOR = 3
80
+ MICRO = 12
81
81
  RELEV = "final" # <16
82
82
  SERIAL = 0 # <16
83
83
 
@@ -0,0 +1 @@
1
+ import sys, types, os;p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('orangecontrib',));importlib = __import__('importlib.util');__import__('importlib.machinery');m = sys.modules.setdefault('orangecontrib', importlib.util.module_from_spec(importlib.machinery.PathFinder.find_spec('orangecontrib', [os.path.dirname(p)])));m = m or sys.modules.setdefault('orangecontrib', types.ModuleType('orangecontrib'));mp = (m or []) and m.__dict__.setdefault('__path__',[]);(p not in mp) and mp.append(p)