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
@@ -12,6 +12,7 @@ from nabu.stitching.z_stitching import (
12
12
  PreProcessZStitcher,
13
13
  )
14
14
  from nabu.pipeline.config import generate_nabu_configfile, parse_nabu_config_file
15
+ from nabu.stitching.alignment import AlignmentAxis1, AlignmentAxis2
15
16
  from nabu.stitching.config import (
16
17
  get_default_stitching_config,
17
18
  identifiers_as_str_to_instances,
@@ -27,19 +28,18 @@ from nxtomomill.io.utils import (
27
28
  convert_str_to_tuple as _convert_str_to_tuple,
28
29
  convert_str_to_bool as _convert_str_to_bool,
29
30
  )
30
- from silx.gui import icons as silx_icons
31
31
  from silx.gui import qt
32
32
  from tomoscan.serie import Serie
33
33
  from tomoscan.scanbase import TomoScanBase as _TomoScanBase
34
34
  from tomoscan.volumebase import VolumeBase as _VolumeBase
35
35
 
36
- from tomwer.core.scan.hdf5scan import HDF5TomoScan, HDF5TomoScanIdentifier
36
+ from tomwer.core.scan.nxtomoscan import NXtomoScan, NXtomoScanIdentifier
37
37
  from tomwer.core.scan.scanfactory import ScanFactory
38
38
  from tomwer.core.volume.volumefactory import VolumeFactory
39
+ from tomwer.core.volume.volumebase import TomwerVolumeBase
39
40
  from tomwer.core.tomwer_object import TomwerObject
40
41
  from tomwer.core.volume.hdf5volume import HDF5Volume, HDF5VolumeIdentifier
41
42
  from tomwer.io.utils.utils import str_to_dict
42
- from tomwer.gui import icons as tomwer_icons
43
43
  from tomwer.gui.qconfigfile import QConfigFileDialog
44
44
  from tomwer.gui.stitching.config.axisparams import StitcherAxisParams
45
45
  from tomwer.gui.stitching.config.positionoveraxis import PosEditorOverOneAxis
@@ -49,6 +49,15 @@ from tomwer.gui.stitching.stitching_preview import PreviewStitchingPlot
49
49
  from tomwer.gui.stitching.stitching_raw import RawStitchingPlot
50
50
  from tomwer.gui.stitching.axisorderedlist import EditableZOrderedTomoObjWidget
51
51
  from tomwer.gui.stitching.z_stitching.fineestimation import _SliceGetter
52
+ from tomwer.gui.configuration.action import (
53
+ BasicConfigurationAction,
54
+ ExpertConfigurationAction,
55
+ MinimalisticConfigurationAction,
56
+ )
57
+ from tomwer.gui.configuration.level import ConfigurationLevel
58
+ from tomwer.gui.stitching import action as stitching_action
59
+ from tomwer.gui.stitching.normalization import NormalizationBySampleGroupBox
60
+
52
61
 
53
62
  _logger = logging.getLogger(__name__)
54
63
 
@@ -104,6 +113,8 @@ class ZStitchingCentralWidget(qt.QWidget):
104
113
  raw_display_idx,
105
114
  "If toggled will keep the raw display up to date from axis 0 modifications",
106
115
  )
116
+ # set up: turn overlay one by default
117
+ self._previewPlot._backGroundAction.setChecked(True)
107
118
 
108
119
  def _handleRawDisplayconnection(self, toggled: bool):
109
120
  if toggled:
@@ -192,9 +203,33 @@ class ZStitchingCentralWidget(qt.QWidget):
192
203
 
193
204
  def addTomoObj(self, tomo_obj: TomwerObject):
194
205
  self._mainWidget.addTomoObj(tomo_obj)
206
+ self._updatePreviewPixelSize()
195
207
 
196
208
  def removeTomoObj(self, tomo_obj: TomwerObject):
197
209
  self._mainWidget.removeTomoObj(tomo_obj)
210
+ self._updatePreviewPixelSize()
211
+
212
+ def _updatePreviewPixelSize(self):
213
+ """update the pixel size of the preview from existing tomo obj"""
214
+
215
+ def get_pixel_size():
216
+ tomo_objs = self._mainWidget.getTomoObjs()
217
+ for tomo_obj in tomo_objs:
218
+ if (
219
+ isinstance(tomo_obj, NXtomoScan)
220
+ and tomo_obj.x_pixel_size is not None
221
+ and tomo_obj.y_pixel_size is not None
222
+ ):
223
+ return tomo_obj.x_pixel_size, tomo_obj.y_pixel_size
224
+ elif (
225
+ isinstance(tomo_obj, TomwerVolumeBase)
226
+ and tomo_obj.voxel_size is not None
227
+ ):
228
+ return tomo_obj.voxel_size[1], tomo_obj.voxel_size[2]
229
+ return None, None
230
+
231
+ pixel_size = get_pixel_size()
232
+ self._mainWidget._previewPlot.setPixelSize(pixel_size=pixel_size)
198
233
 
199
234
  def getConfiguration(self) -> dict:
200
235
  # missing parameters:
@@ -303,12 +338,15 @@ class ZStitchingCentralWidget(qt.QWidget):
303
338
  class ZStitchingWindow(qt.QMainWindow):
304
339
  """
305
340
  Main widget containing all the options to define the stitching to be done
341
+
342
+ :param bool with_configuration_action: if True append the load and save stitching configuration tool button.
343
+ In some cases those can also be part of Menu so we want to avoid having those twice
306
344
  """
307
345
 
308
346
  sigChanged = qt.Signal()
309
347
  """Signal emit each time the configuration is modified"""
310
348
 
311
- def __init__(self, parent=None) -> None:
349
+ def __init__(self, parent=None, with_configuration_action=True) -> None:
312
350
  super().__init__(parent)
313
351
  self._previewFolder = None
314
352
  # folder to store files (volume or NXtomo) for previews
@@ -335,42 +373,56 @@ class ZStitchingWindow(qt.QMainWindow):
335
373
  # separator
336
374
  toolbar.addSeparator()
337
375
 
338
- # load action
339
- self.__loadAction = qt.QAction(self)
340
- self.__loadAction.setToolTip("load nabu-stitching configuration")
341
- load_icon = silx_icons.getQIcon("document-open")
342
- self.__loadAction.setIcon(load_icon)
343
- toolbar.addAction(self.__loadAction)
344
- self.__loadAction.triggered.connect(
345
- functools.partial(self._loadSettings, file_path=None)
346
- )
376
+ if with_configuration_action:
377
+ # load action
378
+ self.__loadAction = stitching_action.LoadConfigurationAction(self)
379
+ toolbar.addAction(self.__loadAction)
380
+ self.__loadAction.triggered.connect(
381
+ functools.partial(self._loadSettings, file_path=None)
382
+ )
347
383
 
348
- # save action
349
- self.__saveAction = qt.QAction(self)
350
- self.__saveAction.setToolTip("save nabu-stitching configuration")
351
- save_icon = silx_icons.getQIcon("document-save")
352
- self.__saveAction.setIcon(save_icon)
353
- toolbar.addAction(self.__saveAction)
354
- self.__saveAction.triggered.connect(
355
- functools.partial(self._saveSettings, file_path=None)
356
- )
384
+ # save action
385
+ self.__saveAction = stitching_action.SaveConfigurationAction(self)
386
+ toolbar.addAction(self.__saveAction)
387
+ self.__saveAction.triggered.connect(
388
+ functools.partial(self._saveSettings, file_path=None)
389
+ )
357
390
 
358
- # separator
359
- toolbar.addSeparator()
391
+ # separator
392
+ toolbar.addSeparator()
360
393
 
361
394
  # update preview action
362
- self.__updatePreviewAction = qt.QAction(self)
363
- self.__updatePreviewAction.setToolTip(
364
- "Compute preview with current settings (shortcut: F5)"
365
- )
366
- update_preview_icon = tomwer_icons.getQIcon("update_stitching_preview")
367
- self.__updatePreviewAction.setIcon(update_preview_icon)
395
+ self.__updatePreviewAction = stitching_action.PreviewAction(self)
368
396
  toolbar.addAction(self.__updatePreviewAction)
369
397
  self.__updatePreviewAction.triggered.connect(self._trigger_update_preview)
370
398
 
371
399
  # separator
372
400
  toolbar.addSeparator()
373
401
 
402
+ # configuraiton level / mode
403
+ self.__configurationModesAction = qt.QAction(self)
404
+ self.__configurationModesAction.setCheckable(False)
405
+ menu = qt.QMenu(self)
406
+ self.__configurationModesAction.setMenu(menu)
407
+ toolbar.addAction(self.__configurationModesAction)
408
+
409
+ self.__configurationModesGroup = qt.QActionGroup(self)
410
+ self.__configurationModesGroup.setExclusive(True)
411
+ self.__configurationModesGroup.triggered.connect(self._userModeChanged)
412
+
413
+ self._minimalisticAction = MinimalisticConfigurationAction(toolbar)
414
+ menu.addAction(self._minimalisticAction)
415
+ self.__configurationModesGroup.addAction(self._minimalisticAction)
416
+ self._basicConfigAction = BasicConfigurationAction(toolbar)
417
+ menu.addAction(self._basicConfigAction)
418
+ self.__configurationModesGroup.addAction(self._basicConfigAction)
419
+ self._expertConfiguration = ExpertConfigurationAction(toolbar)
420
+ menu.addAction(self._expertConfiguration)
421
+ self.__configurationModesGroup.addAction(self._expertConfiguration)
422
+
423
+ # separator
424
+ toolbar.addSeparator()
425
+
374
426
  # create central widget
375
427
  self._widget = ZStitchingCentralWidget(parent=self)
376
428
  self.setCentralWidget(self._widget)
@@ -390,11 +442,16 @@ class ZStitchingWindow(qt.QMainWindow):
390
442
  )
391
443
  ## stitching strategies
392
444
  self._stitchingOptsWidget = StitchingOptions(parent=self)
393
- self._stitchingOptsWidget.setObjectName("options")
445
+ self._stitchingOptsScrollArea = qt.QScrollArea(self)
446
+ self._stitchingOptsScrollArea.setWidget(self._stitchingOptsWidget)
447
+ self._stitchingOptsScrollArea.setWidgetResizable(True)
448
+ self._stitchingOptsScrollArea.setHorizontalScrollBarPolicy(
449
+ qt.Qt.ScrollBarAlwaysOff
450
+ )
394
451
  self._stitchingOptsDockWidget = qt.QDockWidget(parent=self)
395
452
  self._stitchingOptsDockWidget.layout().setContentsMargins(0, 0, 0, 0)
396
453
  self._stitchingOptsDockWidget.setFeatures(qt.QDockWidget.DockWidgetMovable)
397
- self._stitchingOptsDockWidget.setWidget(self._stitchingOptsWidget)
454
+ self._stitchingOptsDockWidget.setWidget(self._stitchingOptsScrollArea)
398
455
  self._stitchingOptsDockWidget.setWindowTitle("processing options")
399
456
  self.addDockWidget(qt.Qt.RightDockWidgetArea, self._stitchingOptsDockWidget)
400
457
 
@@ -425,13 +482,13 @@ class ZStitchingWindow(qt.QMainWindow):
425
482
  )
426
483
  ### add a check box to update position from preview if asked by the user
427
484
  self._updateAxis0PosFromPreviewCalc = qt.QCheckBox(
428
- "update position 0 from preview calc"
485
+ "update position 0 from preview calc",
486
+ self,
429
487
  )
430
488
  self._updateAxis0PosFromPreviewCalc.setToolTip(
431
- "When the user trigger a preview, if some shift search refined over axis 0 is done then will update the axis 0 positions"
489
+ "When the user trigger a preview, if some shift search refined over axis 0 is done then will update the axis 0 positions",
432
490
  )
433
- self._updateAxis0PosFromPreviewCalc.setChecked(False)
434
- self._updateAxis0PosFromPreviewCalc.setVisible(False)
491
+ self._updateAxis0PosFromPreviewCalc.setChecked(True)
435
492
  self._editTomoObjAxis0PositionsWidget.layout().insertWidget(
436
493
  0, self._updateAxis0PosFromPreviewCalc
437
494
  )
@@ -463,13 +520,12 @@ class ZStitchingWindow(qt.QMainWindow):
463
520
  )
464
521
  ### add a check box to update position from preview if asked by the user
465
522
  self._updateAxis2PosFromPreviewCalc = qt.QCheckBox(
466
- "update position 2 from preview calc"
523
+ "update position 2 from preview calc", self
467
524
  )
468
525
  self._updateAxis2PosFromPreviewCalc.setToolTip(
469
526
  "When the user trigger a preview, if some shift search refined over axis 2 is done then will update the axis 2 positions"
470
527
  )
471
- self._updateAxis2PosFromPreviewCalc.setChecked(False)
472
- self._updateAxis2PosFromPreviewCalc.setVisible(False)
528
+ self._updateAxis2PosFromPreviewCalc.setChecked(True)
473
529
  self._editTomoObjAxis2PositionsWidget.layout().insertWidget(
474
530
  0, self._updateAxis2PosFromPreviewCalc
475
531
  )
@@ -511,6 +567,9 @@ class ZStitchingWindow(qt.QMainWindow):
511
567
  self._widget.sigStitchingTypeChanged.connect(
512
568
  self._outputWidget._updateOutputForStitchingType
513
569
  )
570
+ self._widget.sigStitchingTypeChanged.connect(
571
+ self._stitchingOptsWidget._stitchingTypeChanged
572
+ )
514
573
 
515
574
  ## handle raw plot preview
516
575
  self._stitchingOptsWidget.sigFlipLRChanged.connect(
@@ -532,6 +591,10 @@ class ZStitchingWindow(qt.QMainWindow):
532
591
  )
533
592
  self._widget.sigTomoObjsLoaded.connect(self.getRawDisplayPlot().setTomoObjs)
534
593
 
594
+ # set up
595
+ self._basicConfigAction.setChecked(True)
596
+ self._userModeChanged(self._basicConfigAction)
597
+
535
598
  def setCallbackToGetSlurmConfig(self, callback):
536
599
  self._callbackToGetSlurmConfig = callback
537
600
 
@@ -570,8 +633,8 @@ class ZStitchingWindow(qt.QMainWindow):
570
633
 
571
634
  def getNXtomoIdentifierForPreview(self):
572
635
  folder = self.getPreviewFolder()
573
- return HDF5TomoScanIdentifier(
574
- object=HDF5TomoScan,
636
+ return NXtomoScanIdentifier(
637
+ object=NXtomoScan,
575
638
  hdf5_file=os.path.join(folder, "nxtomo_stiching_preview.hdf5"),
576
639
  entry="entry0000",
577
640
  )
@@ -664,7 +727,7 @@ class ZStitchingWindow(qt.QMainWindow):
664
727
 
665
728
  # clean current preview to notify some calculation is going on
666
729
  preview_plot = self._widget._mainWidget._previewPlot
667
- preview_plot.setWaiting(True)
730
+ preview_plot._waitingOverlay.show()
668
731
 
669
732
  # start sitching on a thread
670
733
  self._previewThread = PreviewThread(stitching_config=config)
@@ -679,12 +742,14 @@ class ZStitchingWindow(qt.QMainWindow):
679
742
  assert isinstance(sender, PreviewThread)
680
743
  composition = sender.frame_composition
681
744
  tomo_objs_new_axis_positions = sender.final_tomo_objs_positions
682
- assert isinstance(tomo_objs_new_axis_positions, dict)
745
+ assert isinstance(
746
+ tomo_objs_new_axis_positions, dict
747
+ ), "final_tomo_objs_positions is expected to be a dict with obj identifier as key and the tuple of position as value"
683
748
  # expect it to be a dict with tomo obj identifier as key and a tuple of (axis_2_pos, axis_1_pos, axis_0_pos) as value
684
749
  output_obj_identifier = sender.output_identifier
685
750
 
686
751
  preview_plot = self._widget._mainWidget._previewPlot
687
- preview_plot.setWaiting(False)
752
+ preview_plot._waitingOverlay.hide()
688
753
 
689
754
  self._previewThread.finished.disconnect(self._previewCalculationFinished)
690
755
  self._previewThread = None
@@ -780,6 +845,20 @@ class ZStitchingWindow(qt.QMainWindow):
780
845
  def setStitchingType(self, stitching_type: StitchingType):
781
846
  self._widget.setStitchingType(stitching_type)
782
847
 
848
+ def _userModeChanged(self, action):
849
+ self.__configurationModesAction.setIcon(action.icon())
850
+ self.__configurationModesAction.setToolTip(action.tooltip())
851
+ if action is self._basicConfigAction:
852
+ level = ConfigurationLevel.OPTIONAL
853
+ elif action is self._expertConfiguration:
854
+ level = ConfigurationLevel.ADVANCED
855
+ else:
856
+ level = ConfigurationLevel.REQUIRED
857
+ self._stitchingOptsWidget.setConfigurationLevel(level)
858
+ self._editTomoObjAxis2PositionsDockWidget.setVisible(
859
+ level >= ConfigurationLevel.ADVANCED
860
+ )
861
+
783
862
 
784
863
  def concatenate_dict(dict_1, dict_2) -> dict:
785
864
  """update dict which has dict as values. And we want concatenate those values to"""
@@ -921,6 +1000,92 @@ class _SlicesSelector(qt.QGroupBox):
921
1000
  self._stepSliceSB.setValue(int(step))
922
1001
 
923
1002
 
1003
+ class _AlignmentGroupBox(qt.QGroupBox):
1004
+ DEFAULT_PAD_MODE = "constant"
1005
+
1006
+ ALIGNMENT_DOC = (
1007
+ "https://tomotools.gitlab-pages.esrf.fr/nabu/stitching/alignment.html"
1008
+ )
1009
+
1010
+ DEFAULT_ALIGNMENT_AXIS_1 = AlignmentAxis1.CENTER
1011
+ DEFAULT_ALIGNMENT_AXIS_2 = AlignmentAxis2.CENTER
1012
+
1013
+ _PAD_MODES = (
1014
+ "constant", # Pads with a constant value.
1015
+ "edge", # Pads with the edge values of array.
1016
+ "linear_ramp", # Pads with the linear ramp between end_value and the array edge value.
1017
+ "maximum", # Pads with the maximum value of all or part of the vector along each axis.
1018
+ "mean", # Pads with the mean value of all or part of the vector along each axis.
1019
+ "median", # Pads with the median value of all or part of the vector along each axis.
1020
+ "minimum", # Pads with the minimum value of all or part of the vector along each axis.
1021
+ "reflect", # Pads with the reflection of the vector mirrored on the first and last values of the vector along each axis.
1022
+ "symmetric", # Pads with the reflection of the vector mirrored along the edge of the array.
1023
+ "wrap", # Pads with the wrap of the vector along the axis. The first values are used to pad the end and the end values are used to pad the beginning.
1024
+ )
1025
+
1026
+ def __init__(self, parent: qt.QWidget = None, title="alignment") -> None:
1027
+ super().__init__(title, parent)
1028
+ self.setLayout(qt.QFormLayout())
1029
+
1030
+ # alignment axis 1
1031
+ self._alignmentAxis1CB = qt.QComboBox(self)
1032
+ for alignment in AlignmentAxis1.values():
1033
+ self._alignmentAxis1CB.addItem(alignment)
1034
+ self.layout().addRow("Axis 1 alignment", self._alignmentAxis1CB)
1035
+ self._alignmentAxis1CB.setToolTip(
1036
+ f"Alignment to do in case of volumes with different size over axis 1. Only possible for post-processing (reconstructed volume). See {self.ALIGNMENT_DOC} for details."
1037
+ )
1038
+
1039
+ # alignment axis 2
1040
+ self._alignmentAxis2CB = qt.QComboBox(self)
1041
+ for alignment in AlignmentAxis2.values():
1042
+ self._alignmentAxis2CB.addItem(alignment)
1043
+ self.layout().addRow("Axis 2 alignment", self._alignmentAxis2CB)
1044
+ self._alignmentAxis2CB.setToolTip(
1045
+ f"Alignment to do in case of frames with different size over axis 2. See {self.ALIGNMENT_DOC} for details."
1046
+ )
1047
+
1048
+ # pad mode
1049
+ self._padModeCB = qt.QComboBox(self)
1050
+ for pad_mode in self._PAD_MODES:
1051
+ self._padModeCB.addItem(pad_mode)
1052
+ self.layout().addRow("pad mode", self._padModeCB)
1053
+ self._padModeCB.setToolTip("padding mode to apply for alignment")
1054
+
1055
+ # set up
1056
+ self.setAlignmentAxis1(self.DEFAULT_ALIGNMENT_AXIS_1)
1057
+ self.setAlignmentAxis2(self.DEFAULT_ALIGNMENT_AXIS_2)
1058
+
1059
+ def getAlignmentAxis1(self) -> AlignmentAxis1:
1060
+ return AlignmentAxis1.from_value(self._alignmentAxis1CB.currentText())
1061
+
1062
+ def setAlignmentAxis1(self, alignment: AlignmentAxis1):
1063
+ alignment = AlignmentAxis1.from_value(alignment)
1064
+ self._alignmentAxis1CB.setCurrentIndex(
1065
+ self._alignmentAxis1CB.findText(alignment.value)
1066
+ )
1067
+
1068
+ def getAlignmentAxis2(self) -> AlignmentAxis2:
1069
+ return AlignmentAxis2.from_value(self._alignmentAxis2CB.currentText())
1070
+
1071
+ def setAlignmentAxis2(self, alignment: AlignmentAxis2):
1072
+ alignment = AlignmentAxis2.from_value(alignment)
1073
+ self._alignmentAxis2CB.setCurrentIndex(
1074
+ self._alignmentAxis2CB.findText(alignment.value)
1075
+ )
1076
+
1077
+ def getPadMode(self) -> str:
1078
+ return self._padModeCB.currentText()
1079
+
1080
+ def setPadMode(self, pad_mode: str):
1081
+ idx = self._padModeCB.findText(pad_mode)
1082
+ if idx >= 0:
1083
+ self._padModeCB.setCurrentIndex(idx)
1084
+
1085
+ def setAlignmentAxis1Enabled(self, enabled: bool):
1086
+ self._alignmentAxis1CB.setEnabled(enabled)
1087
+
1088
+
924
1089
  class StitchingOptions(qt.QWidget):
925
1090
  """
926
1091
  Widget to let the user define the different options for z-stitching such as which algorithm to search shift,
@@ -968,6 +1133,10 @@ class StitchingOptions(qt.QWidget):
968
1133
  )
969
1134
  self.layout().addRow(self._flipUD_CB)
970
1135
 
1136
+ # alignment options
1137
+ self._alignmentGroup = _AlignmentGroupBox(self)
1138
+ self.layout().addRow(self._alignmentGroup)
1139
+
971
1140
  # slices to be reconstructed
972
1141
  self._slices = _SlicesSelector(parent=self)
973
1142
  self._slices.setToolTip(
@@ -999,6 +1168,11 @@ class StitchingOptions(qt.QWidget):
999
1168
  self._rescalingWidget = RescalingWidget(parent=self)
1000
1169
  self.layout().addRow(self._rescalingWidget)
1001
1170
 
1171
+ # normalization by sample
1172
+ self._normalizationBySampleWidget = NormalizationBySampleGroupBox(parent=self)
1173
+ self._normalizationBySampleWidget.setChecked(False)
1174
+ self.layout().addRow(self._normalizationBySampleWidget)
1175
+
1002
1176
  # connect signal / slot
1003
1177
  self._stitchingStrategiesWidget.sigChanged.connect(self._updated)
1004
1178
  self._previewSlices.editingFinished.connect(self._sliceForPreviewHasChanged)
@@ -1052,10 +1226,14 @@ class StitchingOptions(qt.QWidget):
1052
1226
  stitching_config.STITCHING_SECTION: {
1053
1227
  stitching_config.FLIP_LR: self._flipLR_CB.isChecked(),
1054
1228
  stitching_config.FLIP_UD: self._flipUD_CB.isChecked(),
1229
+ stitching_config.ALIGNMENT_AXIS_1_FIELD: self._alignmentGroup.getAlignmentAxis1().value,
1230
+ stitching_config.ALIGNMENT_AXIS_2_FIELD: self._alignmentGroup.getAlignmentAxis2().value,
1231
+ stitching_config.PAD_MODE_FIELD: self._alignmentGroup.getPadMode(),
1055
1232
  },
1056
1233
  stitching_config.INPUTS_SECTION: {
1057
1234
  stitching_config.STITCHING_SLICES: slices,
1058
1235
  },
1236
+ stitching_config.NORMALIZATION_BY_SAMPLE_SECTION: self._normalizationBySampleWidget.getConfiguration(),
1059
1237
  }
1060
1238
 
1061
1239
  for ddict in (
@@ -1075,21 +1253,65 @@ class StitchingOptions(qt.QWidget):
1075
1253
  slices = config.get(stitching_config.STITCHING_SECTION, {}).get(
1076
1254
  stitching_config.STITCHING_SLICES, ""
1077
1255
  )
1256
+ # slices
1078
1257
  if slices == "":
1079
1258
  slices = None
1080
1259
  if slices is not None:
1081
1260
  self.setSlices(slices)
1261
+ # flip_lr
1082
1262
  flip_lr = config.get(stitching_config.STITCHING_SECTION, {}).get(
1083
1263
  stitching_config.FLIP_LR, None
1084
1264
  )
1085
1265
  if flip_lr is not None:
1086
1266
  self._flipLR_CB.setChecked(flip_lr in (True, "True", 1, "1"))
1087
-
1267
+ # flip_ud
1088
1268
  flip_ud = config.get(stitching_config.STITCHING_SECTION, {}).get(
1089
1269
  stitching_config.FLIP_UD, None
1090
1270
  )
1091
1271
  if flip_ud is not None:
1092
1272
  self._flipUD_CB.setChecked(flip_ud in (True, "True", 1, "1"))
1273
+ # alignment
1274
+ alignment_axis_1 = config.get(stitching_config.STITCHING_SECTION, {}).get(
1275
+ stitching_config.ALIGNMENT_AXIS_1_FIELD, None
1276
+ )
1277
+ if alignment_axis_1 is not None:
1278
+ self._alignmentGroup.setAlignmentAxis1(alignment_axis_1)
1279
+ alignment_axis_2 = config.get(stitching_config.STITCHING_SECTION, {}).get(
1280
+ stitching_config.ALIGNMENT_AXIS_2_FIELD, None
1281
+ )
1282
+ if alignment_axis_2 is not None:
1283
+ self._alignmentGroup.setAlignmentAxis2(alignment_axis_2)
1284
+ # pad_mode
1285
+ pad_mode = config.get(stitching_config.STITCHING_SECTION, {}).get(
1286
+ stitching_config.PAD_MODE_FIELD, None
1287
+ )
1288
+ if pad_mode is not None:
1289
+ self._alignmentGroup.setPadMode(pad_mode=pad_mode)
1290
+
1291
+ # normalization by sample
1292
+ normalization_by_sample = config.get(
1293
+ stitching_config.NORMALIZATION_BY_SAMPLE_SECTION, None
1294
+ )
1295
+ if normalization_by_sample is not None:
1296
+ self._normalizationBySampleWidget.setConfiguration(normalization_by_sample)
1297
+
1298
+ def _stitchingTypeChanged(self, stiching_type: str):
1299
+ stiching_type = StitchingType.from_value(stiching_type)
1300
+ self._alignmentGroup.setAlignmentAxis1Enabled(
1301
+ stiching_type is StitchingType.Z_POSTPROC
1302
+ )
1303
+
1304
+ def setConfigurationLevel(self, level: ConfigurationLevel):
1305
+ self._alignmentGroup.setVisible(level >= ConfigurationLevel.ADVANCED)
1306
+ self._previewSlices.setVisible(level >= ConfigurationLevel.OPTIONAL)
1307
+ self._flipLR_CB.setVisible(level >= ConfigurationLevel.ADVANCED)
1308
+ self._flipUD_CB.setVisible(level >= ConfigurationLevel.ADVANCED)
1309
+ self._rescalingWidget.setVisible(level >= ConfigurationLevel.ADVANCED)
1310
+ self._axis0ShiftSearchParams.setConfigurationLevel(level)
1311
+ self._axis2ShiftSearchParams.setConfigurationLevel(level)
1312
+ self._normalizationBySampleWidget.setVisible(
1313
+ level >= ConfigurationLevel.ADVANCED
1314
+ )
1093
1315
 
1094
1316
 
1095
1317
  class RescalingWidget(qt.QWidget):