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
@@ -1,537 +1,26 @@
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
- #############################################################################*/
1
+ from tomwer.core.scan.nxtomoscan import NXtomoScanIdentifier, NXtomoScan
2
+ from tomwer.core.utils.deprecation import deprecated_warning
24
3
 
25
4
 
26
- __authors__ = ["H.Payno"]
27
- __license__ = "MIT"
28
- __date__ = "09/08/2018"
29
-
30
-
31
- import functools
32
- import io
33
- import json
34
- import logging
35
- import os
36
- import pathlib
37
- from datetime import datetime
38
- from typing import Optional
39
- from urllib.parse import urlparse
40
-
41
- import h5py
42
- from processview.core.dataset import DatasetIdentifier
43
- from tomoscan.esrf.identifier.hdf5Identifier import (
44
- HDF5TomoScanIdentifier as _HDF5TomoScanIdentifier,
45
- )
46
- from tomoscan.esrf.identifier.url_utils import UrlSettings, split_path, split_query
47
- from tomoscan.esrf.scan.hdf5scan import HDF5TomoScan as _tsHDF5TomoScan
48
- from tomoscan.esrf.scan.hdf5scan import ImageKey
49
- from tomoscan.io import HDF5File
50
-
51
- from tomwer.utils import docstring
52
- from tomwer.core.scan.helicalmetadata import HelicalMetadata
53
-
54
- from .scanbase import TomwerScanBase
55
-
56
- _logger = logging.getLogger(__name__)
57
-
58
-
59
- class HDF5TomoScanIdentifier(_HDF5TomoScanIdentifier, DatasetIdentifier):
5
+ class HDF5TomoScanIdentifier(NXtomoScanIdentifier):
60
6
  def __init__(self, metadata=None, *args, **kwargs):
61
- super().__init__(*args, **kwargs)
62
- DatasetIdentifier.__init__(
63
- self, data_builder=HDF5TomoScan.from_identifier, metadata=metadata
7
+ deprecated_warning(
8
+ name="tomwer.core.scan.nxtomoscan.NXtomoScanIdentifier",
9
+ type_="class",
10
+ reason="improve readibility",
11
+ since_version="1.3",
12
+ replacement="VolumeSymbolicLinkTask",
64
13
  )
14
+ super().__init__(metadata, *args, **kwargs)
65
15
 
66
- @staticmethod
67
- def from_str(identifier):
68
- info = urlparse(identifier)
69
- paths = split_path(info.path)
70
- if len(paths) == 1:
71
- hdf5_file = paths[0]
72
- tomo_type = None
73
- elif len(paths) == 2:
74
- tomo_type, hdf5_file = paths
75
- else:
76
- raise ValueError("Failed to parse path string:", info.path)
77
- if tomo_type is not None and tomo_type != HDF5TomoScanIdentifier.TOMO_TYPE:
78
- raise TypeError(
79
- f"provided identifier fits {tomo_type} and not {HDF5TomoScanIdentifier.TOMO_TYPE}"
80
- )
81
-
82
- queries = split_query(info.query)
83
- entry = queries.get(UrlSettings.DATA_PATH_KEY, None)
84
- if entry is None:
85
- raise ValueError(f"expects to get {UrlSettings.DATA_PATH_KEY} query")
86
-
87
- return HDF5TomoScanIdentifier(
88
- object=HDF5TomoScan, hdf5_file=hdf5_file, entry=entry
89
- )
90
-
91
- def long_description(self) -> str:
92
- """used for processview header tooltip for now"""
93
- return self.to_str()
94
-
95
-
96
- class HDF5TomoScan(_tsHDF5TomoScan, TomwerScanBase):
97
- """
98
- This is the implementation of a TomoBase class for an acquisition stored
99
- in a HDF5 file.
100
-
101
- For now several property of the acquisition is accessible thought a getter
102
- (like get_scan_range) and a property (scan_range).
103
-
104
- This is done to be compliant with TomoBase instanciation. But his will be
105
- replace progressively by properties at the 'TomoBase' level
106
-
107
- :param scan: scan directory or scan masterfile.h5
108
- :type: Union[str,None]
109
- """
110
-
111
- _TYPE = "hdf5"
112
16
 
17
+ class HDF5TomoScan(NXtomoScan):
113
18
  def __init__(self, scan, entry, index=None, overwrite_proc_file=False):
114
- TomwerScanBase.__init__(self)
115
- _tsHDF5TomoScan.__init__(self, scan=scan, entry=entry, index=index)
116
- # register at least the 'default' working directory as a possible reconstruction path
117
- self.add_reconstruction_path(self.path)
118
- self._helical = HelicalMetadata()
119
-
120
- self._reconstruction_urls = None
121
- self._projections_with_angles = None
122
- self._process_file = self.get_process_file_name(self)
123
- self._init_index_process_file(overwrite_proc_file=overwrite_proc_file)
124
- try:
125
- reduced_darks, metadata = self.load_reduced_darks(return_info=True)
126
- except (KeyError, OSError, ValueError):
127
- # file or key does not exists
128
- pass
129
- else:
130
- self.set_reduced_darks(reduced_darks, darks_infos=metadata)
131
-
132
- try:
133
- reduced_flats, metadata = self.load_reduced_flats(return_info=True)
134
- except (KeyError, OSError, ValueError):
135
- pass
136
- else:
137
- self.set_reduced_flats(reduced_flats, flats_infos=metadata)
138
-
139
- @property
140
- def working_directory(self):
141
- if self.master_file is None:
142
- return None
143
- else:
144
- return os.path.realpath(os.path.dirname(self.master_file))
145
-
146
- @property
147
- def helical(self):
148
- return self._helical
149
-
150
- @staticmethod
151
- def from_identifier(identifier):
152
- """Return the Dataset from a identifier"""
153
- if not isinstance(identifier, HDF5TomoScanIdentifier):
154
- raise TypeError(
155
- f"identifier should be an instance of {HDF5TomoScanIdentifier}. Not {type(identifier)}"
156
- )
157
- return HDF5TomoScan(scan=identifier.file_path, entry=identifier.data_path)
158
-
159
- def get_identifier(self):
160
- try:
161
- stat = pathlib.Path(self.master_file).stat()
162
- except Exception:
163
- stat = None
164
-
165
- return HDF5TomoScanIdentifier(
166
- object=self,
167
- hdf5_file=self.master_file,
168
- entry=self.entry,
169
- metadata={
170
- "name": self.master_file,
171
- "creation_time": datetime.fromtimestamp(stat.st_ctime)
172
- if stat
173
- else None,
174
- "modification_time": datetime.fromtimestamp(stat.st_ctime)
175
- if stat
176
- else None,
177
- },
178
- )
179
-
180
- @staticmethod
181
- def get_process_file_name(scan):
182
- if scan.path is not None:
183
- basename, _ = os.path.splitext(scan.master_file)
184
- basename = os.path.basename(basename)
185
- basename = "_".join((basename, "tomwer_processes.h5"))
186
- return os.path.join(scan.path, basename)
187
- else:
188
- return None
189
-
190
- @staticmethod
191
- def directory_contains_scan(directory, src_pattern=None, dest_pattern=None):
192
- """
193
-
194
- Check if the given directory is holding an acquisition
195
-
196
- :param str directory: directory we want to check
197
- :param str src_pattern: buffer name pattern ('lbsram')
198
- :param dest_pattern: output pattern (''). Needed because some
199
- acquisition can split the file produce between
200
- two directories. This is the case for edf,
201
- where .info file are generated in /data/dir
202
- instead of /lbsram/data/dir
203
- :type: str
204
- :return: does the given directory contains any acquisition
205
- :rtype: bool
206
- """
207
- master_file = os.path.join(directory, os.path.basename(directory))
208
- if os.path.exists("master_file.hdf5"):
209
- return True
210
- else:
211
- return os.path.exists(master_file + ".h5")
212
-
213
- def clear_caches(self):
214
- _tsHDF5TomoScan.clear_caches(self)
215
- TomwerScanBase.clear_caches(self)
216
-
217
- def is_abort(self, src_pattern, dest_pattern):
218
- """
219
- Check if the acquisition have been aborted. In this case the directory
220
- should contain a [scan].abo file
221
-
222
- :param str src_pattern: buffer name pattern ('lbsram')
223
- :param dest_pattern: output pattern (''). Needed because some
224
- acquisition can split the file produce between
225
- two directories. This is the case for edf,
226
- where .info file are generated in /data/dir
227
- instead of /lbsram/data/dir
228
- :return: True if the acquisition have been abort and the directory
229
- should be abort
230
- """
231
- # for now there is no abort definition in .hdf5
232
- return False
233
-
234
- @staticmethod
235
- def from_dict(_dict):
236
- path = _dict[HDF5TomoScan.DICT_PATH_KEY]
237
- entry = _dict[HDF5TomoScan._DICT_ENTRY_KEY]
238
-
239
- scan = HDF5TomoScan(scan=path, entry=entry)
240
- scan.load_from_dict(_dict=_dict)
241
- return scan
242
-
243
- @docstring(TomwerScanBase)
244
- def load_from_dict(self, _dict):
245
- """
246
-
247
- :param _dict:
248
- :return:
249
- """
250
- if isinstance(_dict, io.TextIOWrapper):
251
- data = json.load(_dict)
252
- else:
253
- data = _dict
254
- if not (self.DICT_TYPE_KEY in data and data[self.DICT_TYPE_KEY] == self._TYPE):
255
- raise ValueError("Description is not an EDFScan json description")
256
-
257
- _tsHDF5TomoScan.load_from_dict(self, _dict)
258
- TomwerScanBase.load_from_dict(self, _dict)
259
- return self
260
-
261
- @docstring(TomwerScanBase)
262
- def to_dict(self) -> dict:
263
- ddict = _tsHDF5TomoScan.to_dict(self)
264
- ddict.update(TomwerScanBase.to_dict(self))
265
- return ddict
266
-
267
- def update(self):
268
- """update list of radio and reconstruction by parsing the scan folder"""
269
- if self.master_file is None:
270
- return
271
- if not os.path.exists(self.master_file):
272
- return
273
- _tsHDF5TomoScan.update(self)
274
- self.reconstructions = self.get_reconstructions_urls()
275
-
276
- def _get_scheme(self):
277
- """
278
-
279
- :return: scheme to read url
280
- :rtype: str
281
- """
282
- return "silx"
283
-
284
- def is_finish(self):
285
- return len(self.projections) >= self.tomo_n
286
-
287
- @docstring(TomwerScanBase.get_sinogram)
288
- @functools.lru_cache(maxsize=16, typed=True)
289
- def get_sinogram(self, line, subsampling=1, norm_method=None, **kwargs):
290
- """
291
-
292
- extract the sinogram from projections
293
-
294
- :param line: which sinogram we want
295
- :type: int
296
- :param subsampling: subsampling to apply if any. Allows to skip some io
297
- :type: int
298
- :return: sinogram from the radio lines
299
- :rtype: numpy.array
300
- """
301
- return _tsHDF5TomoScan.get_sinogram(
302
- self,
303
- line=line,
304
- subsampling=subsampling,
305
- norm_method=norm_method,
306
- **kwargs,
307
- )
308
-
309
- @property
310
- def reduced_darks(self):
311
- if self._reduced_darks is None:
312
- if self.process_file is not None and os.path.exists(self.process_file):
313
- from tomwer.core.process.reconstruction.darkref.darkrefs import (
314
- DarkRefsTask,
315
- ) # avoid cyclic import
316
-
317
- reduced_darks = DarkRefsTask.get_darks_frm_process_file(
318
- process_file=self.process_file, entry=self.entry
319
- )
320
- if reduced_darks is not None:
321
- self.set_reduced_darks(darks=reduced_darks)
322
- return self._reduced_darks
323
-
324
- @property
325
- def reduced_flats(self):
326
- if self._reduced_flats is None:
327
- if self.process_file is not None and os.path.exists(self.process_file):
328
- from tomwer.core.process.reconstruction.darkref.darkrefs import (
329
- DarkRefsTask,
330
- ) # avoid cyclic import
331
-
332
- reduced_flats = DarkRefsTask.get_flats_frm_process_file(
333
- process_file=self.process_file, entry=self.entry
334
- )
335
- if reduced_flats is not None:
336
- self.set_reduced_flats(flats=reduced_flats)
337
- return self._reduced_flats
338
-
339
- @docstring(TomwerScanBase.get_proj_angle_url)
340
- def get_proj_angle_url(self, use_cache: bool = True, with_alignment=True):
341
- if not use_cache:
342
- self._cache_proj_urls = None
343
-
344
- if self._cache_proj_urls is None:
345
- frames = self.frames
346
- if frames is None:
347
- return {}
348
-
349
- self._cache_proj_urls = {}
350
- for frame in frames:
351
- if frame.image_key is ImageKey.PROJECTION:
352
- if frame.is_control and with_alignment:
353
- self._cache_proj_urls[f"{frame.rotation_angle} (1)"] = frame.url
354
- elif frame.is_control:
355
- continue
356
- else:
357
- self._cache_proj_urls[str(frame.rotation_angle)] = frame.url
358
- return self._cache_proj_urls
359
-
360
- @docstring(TomwerScanBase._deduce_transfert_scan)
361
- def _deduce_transfert_scan(self, output_dir):
362
- new_master_file_path = os.path.join(
363
- output_dir, os.path.basename(self.master_file)
364
- )
365
- return HDF5TomoScan(scan=new_master_file_path, entry=self.entry)
366
-
367
- def data_flat_field_correction(self, data, index=None):
368
- flats = self.reduced_flats
369
- flat1 = flat2 = None
370
- index_flat1 = index_flat2 = None
371
- if flats is not None:
372
- flat_indexes = sorted(list(flats.keys()))
373
- if len(flats) > 0:
374
- index_flat1 = flat_indexes[0]
375
- flat1 = flats[index_flat1]
376
- if len(flats) > 1:
377
- index_flat2 = flat_indexes[-1]
378
- flat2 = flats[index_flat2]
379
- darks = self.reduced_darks
380
- dark = None
381
- if darks is not None and len(darks) > 0:
382
- # take only one dark into account for now
383
- dark = list(darks.values())[0]
384
- return self._flat_field_correction(
385
- data=data,
386
- dark=dark,
387
- flat1=flat1,
388
- flat2=flat2,
389
- index_flat1=index_flat1,
390
- index_flat2=index_flat2,
391
- index_proj=index,
392
- )
393
-
394
- @docstring(_tsHDF5TomoScan.ff_interval)
395
- @property
396
- def ff_interval(self):
397
- """
398
- Make some assumption to compute the flat field interval:
399
- """
400
-
401
- def get_first_two_ff_indexes():
402
- if self.flats is None:
403
- return None, None
404
- else:
405
- self._last_flat_index = None
406
- self._first_serie_flat_index = None
407
- for flat_index in self.flats:
408
- if self._last_flat_index is None:
409
- self._last_flat_index = flat_index
410
- elif flat_index == self._last_flat_index + 1:
411
- self._last_flat_index = flat_index
412
- continue
413
- else:
414
- return self._last_flat_index, flat_index
415
- return None, None
416
-
417
- first_serie_index, second_serie_index = get_first_two_ff_indexes()
418
- if first_serie_index is None:
419
- return 0
420
- elif second_serie_index is not None:
421
- return second_serie_index - first_serie_index - 1
422
- else:
423
- return 0
424
-
425
- def projections_with_angle(self):
426
- """projections / radio, does not include the return projections"""
427
- if self._projections_with_angles is None:
428
- if self.frames:
429
- proj_frames = tuple(
430
- filter(
431
- lambda x: x.image_key == ImageKey.PROJECTION
432
- and x.is_control is False,
433
- self.frames,
434
- )
435
- )
436
- self._projections_with_angles = {}
437
- for proj_frame in proj_frames:
438
- self._projections_with_angles[
439
- proj_frame.rotation_angle
440
- ] = proj_frame.url
441
- return self._projections_with_angles
442
-
443
- @staticmethod
444
- def is_nexus_nxtomo_file(file_path: str) -> bool:
445
- if h5py.is_hdf5(file_path):
446
- return len(HDF5TomoScan.get_nxtomo_entries(file_path)) > 0
447
-
448
- @staticmethod
449
- def get_nxtomo_entries(file_path: str) -> tuple:
450
- if not h5py.is_hdf5(file_path):
451
- return tuple()
452
- else:
453
- res = []
454
- with HDF5File(file_path, mode="r", swmr=True, libver="latest") as h5s:
455
- for entry_name, node in h5s.items():
456
- if isinstance(node, h5py.Group):
457
- if HDF5TomoScan.entry_is_nx_tomo(node):
458
- res.append(entry_name)
459
- return tuple(res)
460
-
461
- @staticmethod
462
- def entry_is_nx_tomo(entry: h5py.Group):
463
- return ("beam" in entry and "instrument" in entry and "sample" in entry) or (
464
- hasattr(entry, "attrs")
465
- and "definition" in entry.attrs
466
- and entry.attrs["definition"] == "NXtomo"
467
- )
468
-
469
- @staticmethod
470
- def is_nxdetector(grp: h5py.Group):
471
- """
472
- Check if the grp is an nx detector
473
-
474
- :param h5py.Group grp:
475
- :return: True if this is the definition of a group
476
- :rtype: bool
477
- """
478
- if hasattr(grp, "attrs"):
479
- if "NX_class" in grp.attrs and grp.attrs["NX_class"] == "NXdetector":
480
- return True
481
- return False
482
-
483
- # Dataset implementation
484
-
485
- @docstring(TomwerScanBase)
486
- def get_nabu_dataset_info(self, binning=1, binning_z=1, proj_subsampling=1):
487
- if not isinstance(binning, int):
488
- raise TypeError(f"binning should be an int. Not {type(binning)}")
489
- if not isinstance(binning_z, int):
490
- raise TypeError(f"binning_z should be an int. Not {type(binning_z)}")
491
- if not isinstance(proj_subsampling, int):
492
- raise TypeError(
493
- f"proj_subsampling should be an int. Not {type(proj_subsampling)}"
494
- )
495
- return {
496
- "hdf5_entry": self.entry,
497
- "location": os.path.basename(self.master_file),
498
- "binning": binning,
499
- "binning_z": binning_z,
500
- "projections_subsampling": proj_subsampling,
501
- }
502
-
503
- @docstring(TomwerScanBase)
504
- def to_nabu_dataset_analyser(self):
505
- from nabu.resources.dataset_analyzer import HDF5DatasetAnalyzer
506
-
507
- return HDF5DatasetAnalyzer(
508
- location=self.master_file, extra_options={"hdf5_entry": self.entry}
509
- )
510
-
511
- @docstring(TomwerScanBase)
512
- def scan_dir_name(self) -> Optional[str]:
513
- """for 'this/is/my/file.h5' returns 'my'"""
514
- if self.master_file is not None:
515
- return os.path.dirname(self.master_file).split(os.sep)[-1]
516
- else:
517
- return None
518
-
519
- @docstring(TomwerScanBase)
520
- def scan_basename(self):
521
- if self.master_file is not None:
522
- try:
523
- return os.path.dirname(self.master_file)
524
- except Exception:
525
- return None
526
- else:
527
- return None
528
-
529
- @docstring(TomwerScanBase)
530
- def scan_parent_dir_basename(self):
531
- if self.master_file is not None:
532
- try:
533
- return os.path.dirname(os.path.dirname(self.master_file))
534
- except Exception:
535
- return None
536
- else:
537
- return None
19
+ deprecated_warning(
20
+ name="tomwer.core.scan.nxtomoscan.NXtomoScan",
21
+ type_="class",
22
+ reason="improve readibility",
23
+ since_version="1.3",
24
+ replacement="VolumeSymbolicLinkTask",
25
+ )
26
+ super().__init__(scan, entry, index, overwrite_proc_file)