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
@@ -137,6 +137,11 @@ class VariableSelection(qt.QWidget):
137
137
  self._scoreMethodCB = qt.QComboBox(self)
138
138
  self.layout().addWidget(self._scoreMethodCB, 0, 1, 1, 1)
139
139
  for method in ScoreMethod:
140
+ if method is ScoreMethod.TOMO_CONSISTENCY:
141
+ # for now we avoid this method. Does not provide great results and is very time consuming
142
+ # I guess when we will add it we will need to first display slices
143
+ # and then only compute the score. It might be an "on demand" score but not computed by default.
144
+ continue
140
145
  self._scoreMethodCB.addItem(method.value)
141
146
  # default score method is 1 / tv
142
147
  idx = self._scoreMethodCB.findText(ScoreMethod.TV_INVERSE.value)
@@ -210,7 +215,7 @@ class VariableSelection(qt.QWidget):
210
215
  colormap = None
211
216
  if self.parent() and hasattr(self.parent(), "getPlotWidget"):
212
217
  master_plot = self.parent().getPlotWidget()
213
- colormap = master_plot.getColorBarWidget().getColormap()
218
+ colormap = master_plot.getPlotWidget().getColorBarWidget().getColormap()
214
219
  dialog = VignettesQDialog(
215
220
  value_name=f"{self._variable_name} position",
216
221
  score_name="score",
@@ -571,7 +576,7 @@ class ScorePlot(qt.QWidget):
571
576
  self._varSlider.valueChanged.connect(self._plot.setCurrentUrlIndex)
572
577
  self._varSlider.valueChanged.connect(self._sliderReleased)
573
578
  self._varSlider.valueChanged.connect(self._updateVarValue)
574
- self._varScore.sigMouseWheelActive.connect(self._propagateSPWheelEvent)
579
+ self._varScore.sigMouseWheelActive.connect(self._varSlider.wheelEvent)
575
580
  self._varValueWidget.sigAutoFocusLocked.connect(self._autoFocusLockChanged)
576
581
  self._varValueWidget.sigAutoFocusUnLocked.connect(self._autoFocusLockChanged)
577
582
  self._varValueWidget.sigSelectionModeChanged.connect(
@@ -588,6 +593,11 @@ class ScorePlot(qt.QWidget):
588
593
  self._volumeSizeW.hide()
589
594
  self._voxelSizeW.hide()
590
595
  self._axisLabel.hide()
596
+ # use mean mean+/-3std for the cor
597
+ plotWidget = self._plot.getPlotWidget()
598
+ colormap = plotWidget.getDefaultColormap()
599
+ colormap.setAutoscaleMode(colormap.STDDEV3)
600
+ plotWidget.setDefaultColormap(colormap=colormap)
591
601
 
592
602
  def __init_subclass__(cls, constructor, **kwargs): # pylint: disable=E0302
593
603
  super().__init_subclass__()
@@ -603,12 +613,7 @@ class ScorePlot(qt.QWidget):
603
613
  self.sigConfigurationChanged.emit()
604
614
 
605
615
  def getPlotWidget(self):
606
- return self._plot.getPlotWidget()
607
-
608
- def _stopAnimationThread(self):
609
- self._plot._freeLoadingThreads()
610
- if self._plot._plot.updateThread.is_alive():
611
- self._plot._plot.updateThread.stop()
616
+ return self._plot
612
617
 
613
618
  def close(self):
614
619
  self._plot.close()
@@ -657,9 +662,6 @@ class ScorePlot(qt.QWidget):
657
662
  def _varSelectedFromVignettes(self, value):
658
663
  self._varSlider.setVarValue(value)
659
664
 
660
- def _propagateSPWheelEvent(self, event):
661
- self._varSlider.wheelEvent(event)
662
-
663
665
  def _get_closest_var(self, value):
664
666
  """return the closest cor value to value or None if no cor value
665
667
  defined"""
@@ -38,12 +38,13 @@ from silx.gui import qt
38
38
  from silx.gui.utils.testutils import TestCaseQt
39
39
 
40
40
  from tomwer.core.process.reconstruction.axis.mode import AxisMode
41
- from tomwer.core.scan.edfscan import EDFTomoScan
42
- from tomwer.core.scan.hdf5scan import HDF5TomoScan
41
+ from tomwer.core.scan.nxtomoscan import NXtomoScan
43
42
  from tomwer.gui.reconstruction.axis import AxisWindow
44
43
  from tomwer.gui.reconstruction.axis.radioaxis import _ManualFramesSelection
45
44
  from tomwer.synctools.axis import QAxisRP
46
- from tomwer.tests.utils import UtilsTest, skip_gui_test
45
+ from tomwer.tests.datasets import TomwerCIDatasets
46
+ from tomwer.tests.utils import skip_gui_test
47
+ from tomwer.core.utils.scanutils import MockNXtomo
47
48
 
48
49
 
49
50
  @pytest.mark.skipif(skip_gui_test(), reason="skip gui test")
@@ -51,33 +52,55 @@ class TestWindowAxis(TestCaseQt):
51
52
  """Test that the axis widget work correctly"""
52
53
 
53
54
  def setUp(self):
55
+ self.tempdir = tempfile.mkdtemp()
54
56
  self.recons_params = QAxisRP()
55
57
  self._window = AxisWindow(axis_params=self.recons_params)
56
- self.scan_path = UtilsTest.getEDFDataset("D2_H2_T2_h_")
57
- self.scan = EDFTomoScan(self.scan_path)
58
+ self.scan = MockNXtomo(
59
+ scan_path=os.path.join(self.tempdir, "nx_tomo.nx"),
60
+ n_proj=10,
61
+ n_ini_proj=10,
62
+ scan_range=180,
63
+ dim=20,
64
+ energy=12.3,
65
+ ).scan
58
66
  self._window.show()
59
67
  self.qWaitForWindowExposed(self._window)
60
68
 
61
69
  def tearDown(self):
70
+ shutil.rmtree(self.tempdir)
62
71
  self._window.setAttribute(qt.Qt.WA_DeleteOnClose)
63
72
  self._window.close()
64
73
 
65
74
  def testSetImagesNumpyArray(self):
66
75
  """Test the setImages function"""
67
76
  radio_axis = self._window._axisWidget._radioAxis
68
- self.assertEqual(radio_axis.getPlot().getPlot().getActiveImage(), None)
77
+ radio_axis_plot = self._window._axisWidget._radioAxis.getPlot()
78
+ numpy.testing.assert_array_equal(
79
+ radio_axis_plot.getPlot().getActiveImage().getData(), numpy.empty((0, 0, 4))
80
+ )
69
81
  imgA = numpy.random.random((100, 100))
70
82
  imgB = numpy.random.random((100, 100))
71
83
  radio_axis.setImages(imgA=imgA, imgB=imgB, flipB=True)
72
84
  self.qapp.processEvents()
73
- self.assertNotEqual(radio_axis.getPlot().getPlot().getActiveImage(), None)
85
+ # make sur the image has been set
86
+ assert radio_axis_plot.getPlot().getImage(legend="image1").getData().shape == (
87
+ 100,
88
+ 100,
89
+ )
74
90
 
75
91
  def testSetScan(self):
76
92
  """Test the setScan function"""
77
93
  radio_axis_plot = self._window._axisWidget._radioAxis.getPlot()
78
- self.assertEqual(radio_axis_plot.getPlot().getActiveImage(), None)
94
+ numpy.testing.assert_array_equal(
95
+ radio_axis_plot.getPlot().getActiveImage().getData(), numpy.empty((0, 0, 4))
96
+ )
79
97
  self._window.setScan(self.scan)
80
- self.assertNotEqual(radio_axis_plot.getPlot().getActiveImage(), None)
98
+ self.qapp.processEvents()
99
+ # make sur the image has been set
100
+ assert radio_axis_plot.getPlot().getImage(legend="image1").getData().shape == (
101
+ 20,
102
+ 20,
103
+ )
81
104
 
82
105
  def testShiftButtons(self):
83
106
  """Test that the 'left', 'right', ... buttons and the shift steps are
@@ -89,7 +112,10 @@ class TestWindowAxis(TestCaseQt):
89
112
  self.qapp.processEvents()
90
113
  self.assertTrue(radio_axis.getXShift() == 0)
91
114
  self.assertTrue(radio_axis.getYShift() == 0)
92
- self.assertTrue(radio_axis.getShiftStep() == 1.0)
115
+ self.assertTrue(
116
+ radio_axis.getShiftStep() == 1.0,
117
+ f"shift is {radio_axis.getShiftStep()} when 1.0 expected",
118
+ )
93
119
  radio_axis._controlWidget._shiftControl._leftButton.click()
94
120
  self.qapp.processEvents()
95
121
  self.assertTrue(radio_axis.getXShift() == -1)
@@ -98,7 +124,7 @@ class TestWindowAxis(TestCaseQt):
98
124
  self.qapp.processEvents()
99
125
  self.assertTrue(radio_axis.getXShift() == 0)
100
126
  self.assertTrue(radio_axis.getYShift() == 0)
101
- radio_axis._controlWidget._displacementSelector._fineButton.toggle()
127
+ radio_axis._controlWidget._displacementSelector._fineButton.click()
102
128
  self.qapp.processEvents()
103
129
  self.assertTrue(radio_axis.getShiftStep() == 0.1)
104
130
  radio_axis._controlWidget._shiftControl._topButton.click()
@@ -131,9 +157,6 @@ class TestWindowAxis(TestCaseQt):
131
157
  self.assertEqual(radio_axis.getXShift(), -6.0)
132
158
  self.assertEqual(radio_axis.getYShift(), 0.0)
133
159
 
134
- def testAxisCalculationSaveLoad(self):
135
- pass
136
-
137
160
 
138
161
  @pytest.mark.skipif(skip_gui_test(), reason="skip gui test")
139
162
  class TestWindowsAxisSetScan(TestCaseQt):
@@ -148,10 +171,12 @@ class TestWindowsAxisSetScan(TestCaseQt):
148
171
  # create dataset
149
172
  self.master_file = os.path.join(self.scan_dir, "frm_edftomomill_twoentries.nx")
150
173
  shutil.copyfile(
151
- UtilsTest.getH5Dataset(folderID="frm_edftomomill_twoentries.nx"),
174
+ TomwerCIDatasets.get_dataset(
175
+ "h5_datasets/frm_edftomomill_twoentries.nx",
176
+ ),
152
177
  self.master_file,
153
178
  )
154
- self.scan = HDF5TomoScan(scan=self.master_file, entry="entry0000")
179
+ self.scan = NXtomoScan(scan=self.master_file, entry="entry0000")
155
180
 
156
181
  def tearDown(self):
157
182
  self.widget.setAttribute(qt.Qt.WA_DeleteOnClose)
@@ -37,7 +37,7 @@ from tomwer.gui.reconstruction.nabu.nabuconfig.output import _NabuOutputConfig
37
37
  from tomwer.gui.reconstruction.nabu.nabuconfig.phase import _NabuPhaseConfig
38
38
  from tomwer.gui.reconstruction.nabu.nabuconfig.preprocessing import (
39
39
  _NabuPreProcessingConfig,
40
- _RingCorrectionMethod,
40
+ RingCorrectionMethod,
41
41
  )
42
42
  from tomwer.gui.reconstruction.nabu.nabuconfig.reconstruction import (
43
43
  _NabuReconstructionConfig,
@@ -45,6 +45,7 @@ from tomwer.gui.reconstruction.nabu.nabuconfig.reconstruction import (
45
45
  from tomwer.gui.reconstruction.nabu.nabuflow import NabuFlowControl
46
46
  from tomwer.gui.reconstruction.nabu.volume import NabuVolumeWidget
47
47
  from tomwer.tests.utils import skip_gui_test
48
+ from tomwer.core.process.output import ProcessDataOutputDirMode
48
49
 
49
50
 
50
51
  class ProcessClass:
@@ -119,8 +120,8 @@ class TestNabuPreProcConfig(TestCaseQt):
119
120
  "log_max_clip": 10.0,
120
121
  "take_logarithm": True,
121
122
  "normalize_srcurrent": 0,
122
- "sino_rings_correction": _RingCorrectionMethod.NONE.value,
123
- "sino_rings_options": "sigma=1.0 ; levels=10",
123
+ "sino_rings_correction": RingCorrectionMethod.NONE.value,
124
+ "sino_rings_options": "sigma=1.0 ; levels=10 ; padding=False",
124
125
  "tilt_correction": "",
125
126
  "autotilt_options": "",
126
127
  }
@@ -138,8 +139,8 @@ class TestNabuPreProcConfig(TestCaseQt):
138
139
  "log_max_clip": 250.0,
139
140
  "take_logarithm": False,
140
141
  "normalize_srcurrent": 1,
141
- "sino_rings_correction": _RingCorrectionMethod.MUNCH.value,
142
- "sino_rings_options": "sigma=1.4 ; levels=11",
142
+ "sino_rings_correction": RingCorrectionMethod.MUNCH.value,
143
+ "sino_rings_options": "sigma=1.4 ; levels=11 ; padding=True",
143
144
  "tilt_correction": "1d-correlation",
144
145
  "autotilt_options": "low_pass=1; high_pass=20",
145
146
  }
@@ -218,6 +219,7 @@ class TestNabuReconstructionConfig(TestCaseQt):
218
219
  """Test that the get configuration is working"""
219
220
  ini_conf = {
220
221
  "method": "FBP",
222
+ "slice_plane": "XY",
221
223
  "angles_file": "",
222
224
  "axis_correction_file": "",
223
225
  "angle_offset": 0.0,
@@ -245,6 +247,7 @@ class TestNabuReconstructionConfig(TestCaseQt):
245
247
  """Test that the set configuration is working"""
246
248
  ini_conf = {
247
249
  "method": "FBP",
250
+ "slice_plane": "XZ",
248
251
  "angles_file": "",
249
252
  "axis_correction_file": "",
250
253
  "angle_offset": 12.5,
@@ -283,6 +286,7 @@ class TestNabuReconstructionConfig(TestCaseQt):
283
286
  self.assertFalse(self.nabuWidget._preconditioningFilter.isChecked())
284
287
  self.assertTrue(self.nabuWidget._clipOuterCircleCB.isChecked())
285
288
  self.assertTrue(self.nabuWidget._centeredAxisCB.isChecked())
289
+ assert self.nabuWidget._axisQCB.currentText() == ini_conf["slice_plane"]
286
290
 
287
291
  # check the generated configuration
288
292
  self.assertEqual(self.nabuWidget.getConfiguration(), ini_conf)
@@ -303,17 +307,25 @@ class TestNabuOutputConfig(TestCaseQt):
303
307
  self.qapp.processEvents()
304
308
 
305
309
  def testGetConfiguration(self):
306
- ini_conf = {"file_format": "hdf5", "location": ""}
310
+ ini_conf = {
311
+ "file_format": "hdf5",
312
+ "location": "",
313
+ "output_dir_mode": "same folder as scan",
314
+ }
307
315
  self.assertEqual(self.nabuWidget.getConfiguration(), ini_conf)
308
316
 
309
317
  def testSetConfiguration(self):
310
- conf = {"file_format": "tiff", "location": os.sep.join(("tmp", "my_output"))}
318
+ conf = {
319
+ "file_format": "tiff",
320
+ "location": os.sep.join(("tmp", "my_output")),
321
+ "output_dir_mode": "other",
322
+ }
311
323
  self.nabuWidget.setConfiguration(conf)
312
324
  self.nabuWidget.show()
313
325
  self.qapp.processEvents()
314
326
  # check some widget visibility
315
327
  self.assertTrue(self.nabuWidget._output_dir_widget._outputDirQLE.isVisible())
316
- self.assertFalse(self.nabuWidget._output_dir_widget._defaultOutput.isChecked())
328
+ self.assertTrue(self.nabuWidget._output_dir_widget._otherDirRB.isChecked())
317
329
 
318
330
  self.assertEqual(self.nabuWidget.getConfiguration(), conf)
319
331
 
@@ -323,6 +335,7 @@ class TestNabuVolumeWidget(TestCaseQt):
323
335
  def setUp(self):
324
336
  TestCaseQt.setUp(self)
325
337
  self.nabuWidget = NabuVolumeWidget(parent=None)
338
+ self.nabuWidget.setConfigurationLevel("advanced")
326
339
 
327
340
  def tearDown(self):
328
341
  self.nabuWidget.setAttribute(qt.Qt.WA_DeleteOnClose)
@@ -334,6 +347,8 @@ class TestNabuVolumeWidget(TestCaseQt):
334
347
  "start_z": 0,
335
348
  "end_z": -1,
336
349
  "gpu_mem_fraction": 0.9,
350
+ "output_dir_mode": ProcessDataOutputDirMode.IN_SCAN_FOLDER.value,
351
+ "overwrite_output_location": False,
337
352
  "postproc": {"output_histogram": 1},
338
353
  "cpu_mem_fraction": 0.9,
339
354
  "use_phase_margin": True,
@@ -354,6 +369,13 @@ class TestNabuVolumeWidget(TestCaseQt):
354
369
  "new_output_location": "/new/location",
355
370
  }
356
371
  self.nabuWidget.setConfiguration(conf)
357
- self.nabuWidget.show()
358
372
  self.qapp.processEvents()
373
+
374
+ # update the config dict has setting an other custom output directory update some items
375
+ conf.update(
376
+ {
377
+ "overwrite_output_location": True,
378
+ "output_dir_mode": ProcessDataOutputDirMode.OTHER.value,
379
+ }
380
+ )
359
381
  self.assertEqual(self.nabuWidget.getConfiguration(), conf)
@@ -37,7 +37,7 @@ import pytest
37
37
  from silx.gui import qt
38
38
  from silx.gui.utils.testutils import TestCaseQt
39
39
  from silx.io.url import DataUrl
40
- from tomoscan.unitsystem import metricsystem
40
+ from pyunitsystem import metricsystem
41
41
 
42
42
  from tomwer.core.process.reconstruction.saaxis.params import (
43
43
  ReconstructionMode,
@@ -45,7 +45,7 @@ from tomwer.core.process.reconstruction.saaxis.params import (
45
45
  )
46
46
  from tomwer.core.process.reconstruction.scores import ComputedScore
47
47
  from tomwer.core.process.reconstruction.scores.params import ScoreMethod
48
- from tomwer.core.utils.scanutils import MockHDF5
48
+ from tomwer.core.utils.scanutils import MockNXtomo
49
49
  from tomwer.gui.reconstruction.saaxis.dimensionwidget import DimensionWidget
50
50
  from tomwer.gui.reconstruction.saaxis.saaxis import SAAxisWindow
51
51
  from tomwer.tests.utils import skip_gui_test
@@ -144,7 +144,7 @@ class TestSAAxisWindow(TestCaseQt):
144
144
  # create a scan
145
145
  self.folder = tempfile.mkdtemp()
146
146
  dim = 10
147
- mock = MockHDF5(
147
+ mock = MockNXtomo(
148
148
  scan_path=self.folder, n_proj=10, n_ini_proj=10, scan_range=180, dim=dim
149
149
  )
150
150
  mock.add_alignment_radio(index=10, angle=90)
@@ -41,7 +41,7 @@ from silx.io.url import DataUrl
41
41
  from tomwer.core.process.reconstruction.sadeltabeta.params import SADeltaBetaParams
42
42
  from tomwer.core.process.reconstruction.scores import ComputedScore
43
43
  from tomwer.core.process.reconstruction.scores.params import ScoreMethod
44
- from tomwer.core.utils.scanutils import MockHDF5
44
+ from tomwer.core.utils.scanutils import MockNXtomo
45
45
  from tomwer.gui.reconstruction.sadeltabeta import SADeltaBetaWindow
46
46
  from tomwer.tests.utils import skip_gui_test
47
47
 
@@ -75,7 +75,7 @@ class TestSADeltaBetaWindow(TestCaseQt):
75
75
  # create a scan
76
76
  self.folder = tempfile.mkdtemp()
77
77
  dim = 10
78
- mock = MockHDF5(
78
+ mock = MockNXtomo(
79
79
  scan_path=self.folder, n_proj=10, n_ini_proj=10, scan_range=180, dim=dim
80
80
  )
81
81
  mock.add_alignment_radio(index=10, angle=90)
@@ -115,11 +115,19 @@ class TestSADeltaBetaWindow(TestCaseQt):
115
115
 
116
116
  def testSetConfiguration(self):
117
117
  """Insure configuration setter works"""
118
+ nabu_specific_params = {
119
+ "phase": {
120
+ "padding_type": "zeros",
121
+ "unsharp_coeff": 5.36,
122
+ "unsharp_sigma": 4.1,
123
+ },
124
+ }
118
125
  self._window.setSlicesRange(0, 20)
119
126
  configuration = {
120
127
  "slice_index": {"Slice": 2},
121
128
  "delta_beta_values": (50, 100, 200),
122
129
  "score_method": "standard deviation",
130
+ "nabu_params": nabu_specific_params,
123
131
  }
124
132
  self._window.setConfiguration(configuration)
125
133
  res_conf = self._window.getConfiguration()
@@ -129,6 +137,8 @@ class TestSADeltaBetaWindow(TestCaseQt):
129
137
  "score_method",
130
138
  ):
131
139
  self.assertEqual(configuration[key], res_conf[key])
140
+ for key, value in nabu_specific_params["phase"].items():
141
+ assert value == res_conf["nabu_params"]["phase"][key]
132
142
 
133
143
  def testSetResults(self):
134
144
  """Test setting results"""
tomwer/gui/settings.py CHANGED
@@ -1,31 +1,8 @@
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__ = "05/11/2018"
1
+ from silx.gui import qt
29
2
 
30
3
 
31
4
  Y_AXIS_DOWNWARD = True
5
+ """Default axis direction Y"""
6
+
7
+ EDITING_BACKGROUND_COLOR = qt.QColor("#c3d0d6")
8
+ """Background color used to notify the user that application waits end of edition before taking it into account"""
tomwer/gui/stackplot.py CHANGED
@@ -555,7 +555,7 @@ class _StackImageToLoad(_StackImage, qt.QObject):
555
555
 
556
556
  def clear(self):
557
557
  for img in self._images.values():
558
- img.sigLoaded.disconnect(self._loaded)
558
+ img.sigLoaded.disconnect(self.sigImageLoaded)
559
559
  _StackImage.clear(self)
560
560
  self._url_to_index.clear()
561
561
 
@@ -568,7 +568,7 @@ class _StackImageToLoad(_StackImage, qt.QObject):
568
568
  raise TypeError(f"Unmanaged type: {type(image)}")
569
569
  self._url_to_index[image_.url.path()] = self.nextIndex
570
570
  _StackImage.addImage(self, image_)
571
- image_.sigLoaded.connect(self._loaded)
571
+ image_.sigLoaded.connect(self.sigImageLoaded)
572
572
  if self._mode == ASAP_LOADING:
573
573
  image_.load(self._force_sync)
574
574
 
@@ -615,9 +615,6 @@ class _StackImageToLoad(_StackImage, qt.QObject):
615
615
  except Exception as e:
616
616
  logger.error(e)
617
617
 
618
- def _loaded(self, url_path):
619
- self.sigImageLoaded.emit(url_path)
620
-
621
618
  def setForceSync(self, value):
622
619
  self._force_sync = value
623
620
 
@@ -0,0 +1,49 @@
1
+ from silx.gui import qt
2
+ from silx.gui import icons as silx_icons
3
+ from tomwer.gui import icons as tomwer_icons
4
+
5
+
6
+ class LoadConfigurationAction(qt.QAction):
7
+ """Action to trigger load of a stitching configuration"""
8
+
9
+ def __init__(self, parent=None, text=None):
10
+ super().__init__(parent)
11
+ if text is not None:
12
+ self.setText(text)
13
+ self.setToolTip("load nabu-stitching configuration")
14
+ load_icon = silx_icons.getQIcon("document-open")
15
+ self.setIcon(load_icon)
16
+
17
+
18
+ class SaveConfigurationAction(qt.QAction):
19
+ """Action to trigger save of a stitching configuration"""
20
+
21
+ def __init__(self, parent=None, text=None):
22
+ super().__init__(parent)
23
+ if text is not None:
24
+ self.setText(text)
25
+ self.setToolTip("save nabu-stitching configuration")
26
+ save_icon = silx_icons.getQIcon("document-save")
27
+ self.setIcon(save_icon)
28
+
29
+
30
+ class AddTomoObjectAction(qt.QAction):
31
+ """Action to trigger add a volume to a stitching configuration"""
32
+
33
+ def __init__(self, parent=None, text=None):
34
+ super().__init__(parent)
35
+ if text is not None:
36
+ self.setText(text)
37
+ self.setToolTip(
38
+ "Add a NXtomo or a (nabu) reconstructed volume to the stitching"
39
+ )
40
+ add_icon = tomwer_icons.getQIcon("add")
41
+ self.setIcon(add_icon)
42
+
43
+
44
+ class PreviewAction(qt.QAction):
45
+ def __init__(self, parent=None):
46
+ super().__init__(parent)
47
+ self.setToolTip("Compute preview with current settings (shortcut: F5)")
48
+ update_preview_icon = tomwer_icons.getQIcon("update_stitching_preview")
49
+ self.setIcon(update_preview_icon)
@@ -2,11 +2,11 @@ import logging
2
2
  from typing import Union
3
3
 
4
4
  from nabu.stitching import config as stitching_config
5
- from nabu.stitching.utils import ScoreMethod
6
5
  from nabu.stitching.utils import ShiftAlgorithm as StitchShiftAlgorithm
7
6
  from silx.gui import qt
8
7
 
9
8
  from tomwer.gui.utils.qt_utils import block_signals
9
+ from tomwer.gui.configuration.level import ConfigurationLevel
10
10
 
11
11
  _logger = logging.getLogger(__name__)
12
12
 
@@ -34,7 +34,6 @@ class StitcherAxisParams(qt.QWidget):
34
34
  axis_0_shift_search_method = [
35
35
  StitchShiftAlgorithm.NABU_FFT,
36
36
  StitchShiftAlgorithm.SKIMAGE,
37
- StitchShiftAlgorithm.SHIFT_GRID,
38
37
  StitchShiftAlgorithm.ITK_IMG_REG_V4,
39
38
  StitchShiftAlgorithm.NONE,
40
39
  ]
@@ -54,13 +53,6 @@ class StitcherAxisParams(qt.QWidget):
54
53
  tooltip = "size of the window to try to refine shift"
55
54
  self._windowSizeLabel.setToolTip(tooltip)
56
55
  self._windowSizeSB.setToolTip(tooltip)
57
- # score method
58
- self._scoreMethodLabel = qt.QLabel("score method", self)
59
- self.layout().addWidget(self._scoreMethodLabel, 2, 0, 1, 1)
60
- self._scoreMethodCB = qt.QComboBox(self)
61
- for method in ScoreMethod:
62
- self._scoreMethodCB.addItem(method.value)
63
- self.layout().addWidget(self._scoreMethodCB, 2, 1, 1, 1)
64
56
 
65
57
  # filter options
66
58
  self._filteringGroup = _FilteringGroupBox("filter for shift search", self)
@@ -68,7 +60,7 @@ class StitcherAxisParams(qt.QWidget):
68
60
  self._filteringGroup.setChecked(False)
69
61
  self._filteringGroup.setLowPassValue(1)
70
62
  self._filteringGroup.setHighPassValue(20)
71
- self.layout().addWidget(self._filteringGroup, 3, 0, 2, 3)
63
+ self.layout().addWidget(self._filteringGroup, 2, 0, 2, 3)
72
64
 
73
65
  # set up
74
66
  self._methodChanged()
@@ -76,7 +68,6 @@ class StitcherAxisParams(qt.QWidget):
76
68
  # connect signal / slot
77
69
  self._shiftSearchMethodCB.currentIndexChanged.connect(self._methodChanged)
78
70
  self._windowSizeSB.valueChanged.connect(self._notifyConfigChanged)
79
- self._scoreMethodCB.currentIndexChanged.connect(self._notifyConfigChanged)
80
71
  self._filteringGroup.sigValueChanged.connect(self._notifyConfigChanged)
81
72
 
82
73
  @property
@@ -91,21 +82,12 @@ class StitcherAxisParams(qt.QWidget):
91
82
  idx = self._shiftSearchMethodCB.findText(method.value)
92
83
  self._shiftSearchMethodCB.setCurrentIndex(idx)
93
84
 
94
- def setScoreMethod(self, method: Union[ScoreMethod, str]) -> None:
95
- method = ScoreMethod.from_value(method)
96
- idx = self._scoreMethodCB.findText(method.value)
97
- self._scoreMethodCB.setCurrentIndex(idx)
98
-
99
85
  def getConfiguration(self) -> dict:
100
86
  method = self.getShiftSearchMethod()
101
87
  param_opts = [
102
88
  f"{stitching_config.KEY_IMG_REG_METHOD}={method.value}",
103
89
  f"{stitching_config.KEY_WINDOW_SIZE}={self._windowSizeSB.value()}",
104
90
  ]
105
- if method is StitchShiftAlgorithm.SHIFT_GRID:
106
- param_opts.append(
107
- f"{stitching_config.KEY_SCORE_METHOD}='{self._scoreMethodCB.currentText()}'"
108
- )
109
91
  if self._filteringGroup.isChecked():
110
92
  param_opts.append(
111
93
  f"{stitching_config.KEY_LOW_PASS_FILTER}='{self._filteringGroup.getLowPassValue()}'"
@@ -136,8 +118,6 @@ class StitcherAxisParams(qt.QWidget):
136
118
  self.setShiftSearchMethod(opt_value)
137
119
  elif opt_name == stitching_config.KEY_WINDOW_SIZE:
138
120
  self._windowSizeSB.setValue(int(opt_value))
139
- elif opt_name == stitching_config.KEY_SCORE_METHOD:
140
- self.setScoreMethod(opt_value)
141
121
  elif opt_name == stitching_config.KEY_LOW_PASS_FILTER:
142
122
  self._filteringGroup.setLowPassValue(int(opt_value))
143
123
  self._filteringGroup.setEnabled(True)
@@ -153,8 +133,6 @@ class StitcherAxisParams(qt.QWidget):
153
133
  def _methodChanged(self) -> None:
154
134
  method = self.getShiftSearchMethod()
155
135
  with block_signals(self):
156
- self._scoreMethodCB.setVisible(method is StitchShiftAlgorithm.SHIFT_GRID)
157
- self._scoreMethodLabel.setVisible(method is StitchShiftAlgorithm.SHIFT_GRID)
158
136
  self._windowSizeSB.setVisible(method is not StitchShiftAlgorithm.NONE)
159
137
  self._windowSizeLabel.setVisible(method is not StitchShiftAlgorithm.NONE)
160
138
  self._notifyConfigChanged()
@@ -162,6 +140,11 @@ class StitcherAxisParams(qt.QWidget):
162
140
  def _notifyConfigChanged(self, *args, **kwargs) -> None:
163
141
  self.sigConfigChanged.emit()
164
142
 
143
+ def setConfigurationLevel(self, level: ConfigurationLevel):
144
+ self._windowSizeLabel.setVisible(level >= ConfigurationLevel.OPTIONAL)
145
+ self._windowSizeSB.setVisible(level >= ConfigurationLevel.OPTIONAL)
146
+ self._filteringGroup.setVisible(level >= ConfigurationLevel.ADVANCED)
147
+
165
148
 
166
149
  class _FilteringGroupBox(qt.QGroupBox):
167
150
  sigValueChanged = qt.Signal()
@@ -5,9 +5,10 @@ from nabu.stitching.config import StitchingType
5
5
  from nxtomomill.io.utils import convert_str_to_bool
6
6
  from silx.gui import qt
7
7
 
8
- from tomwer.core.scan.hdf5scan import HDF5TomoScan, HDF5TomoScanIdentifier
8
+ from tomwer.core.scan.nxtomoscan import NXtomoScan, NXtomoScanIdentifier
9
9
  from tomwer.core.scan.scanfactory import ScanFactory
10
10
  from tomwer.gui.utils.inputwidget import OutputVolumeDefinition
11
+ from tomwer.gui.qlefilesystem import QLFileSystem
11
12
 
12
13
  _logger = logging.getLogger(__name__)
13
14
 
@@ -21,21 +22,21 @@ class _PreProcessingOutput(qt.QWidget):
21
22
  super().__init__(parent)
22
23
  self.setLayout(qt.QFormLayout())
23
24
  # TODO: check if the widget with output .nx file exists somewhere
24
- self._outputFile = qt.QLineEdit("stitching/stitched.nx", self)
25
+ self._outputFile = QLFileSystem("stitching/stitched.nx", self)
25
26
  self.layout().addRow("output nexus file", self._outputFile)
26
27
  self._outputDataPath = qt.QLineEdit("entry0000", self)
27
28
  self.layout().addRow("output data path", self._outputDataPath)
28
29
 
29
30
  def getUrl(self) -> str:
30
- return HDF5TomoScanIdentifier(
31
- object=HDF5TomoScan,
31
+ return NXtomoScanIdentifier(
32
+ object=NXtomoScan,
32
33
  hdf5_file=self._outputFile.text(),
33
34
  entry=self._outputDataPath.text(),
34
35
  )
35
36
 
36
37
  def setUrl(self, url: str):
37
38
  try:
38
- identifier = HDF5TomoScanIdentifier.from_str(url)
39
+ identifier = NXtomoScanIdentifier.from_str(url)
39
40
  except Exception as e:
40
41
  _logger.warning(f"Fail to create an identifier from {url}. Error is {e}")
41
42
  else:
@@ -71,6 +72,7 @@ class StitchingOutput(qt.QWidget):
71
72
  self._postProcOutput = _PostProcessingOutput(parent=self)
72
73
  self.layout().addWidget(self._postProcOutput)
73
74
  self._overwritePB = qt.QCheckBox("overwrite", self)
75
+ self._overwritePB.setChecked(True)
74
76
  self.layout().addWidget(self._overwritePB)
75
77
 
76
78
  # add a vertical spacer for display
@@ -110,7 +112,7 @@ class StitchingOutput(qt.QWidget):
110
112
  except Exception:
111
113
  scan = None
112
114
 
113
- if not isinstance(scan, HDF5TomoScan):
115
+ if not isinstance(scan, NXtomoScan):
114
116
  _logger.info("Failed to create an HDFTomoscan from url")
115
117
  return None
116
118
  else:
@@ -146,8 +148,8 @@ class StitchingOutput(qt.QWidget):
146
148
  stitching_config.DATA_PATH_FIELD, None
147
149
  )
148
150
  if location is not None:
149
- identifier = HDF5TomoScanIdentifier(
150
- object=HDF5TomoScan, hdf5_file=location, entry=data_path
151
+ identifier = NXtomoScanIdentifier(
152
+ object=NXtomoScan, hdf5_file=location, entry=data_path
151
153
  )
152
154
  self._preProcOutput.setUrl(identifier.to_str())
153
155