tomwer 1.2.1__py3-none-any.whl → 1.3.12__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (334) hide show
  1. orangecontrib/tomwer/tutorials/icat_publication.ows +58 -0
  2. orangecontrib/tomwer/widgets/__init__.py +11 -11
  3. orangecontrib/tomwer/widgets/control/DataDiscoveryOW.py +2 -2
  4. orangecontrib/tomwer/widgets/control/DataListOW.py +9 -7
  5. orangecontrib/tomwer/widgets/control/DataListenerOW.py +6 -6
  6. orangecontrib/tomwer/widgets/control/DataSelectorOW.py +21 -10
  7. orangecontrib/tomwer/widgets/control/DataValidatorOW.py +6 -6
  8. orangecontrib/tomwer/widgets/control/EDF2NXTomomillOW.py +24 -7
  9. orangecontrib/tomwer/widgets/control/EmailOW.py +4 -4
  10. orangecontrib/tomwer/widgets/control/NXTomomillMixIn.py +3 -3
  11. orangecontrib/tomwer/widgets/control/NXTomomillOW.py +64 -23
  12. orangecontrib/tomwer/widgets/control/NXtomoConcatenate.py +20 -8
  13. orangecontrib/tomwer/widgets/control/NotifierOW.py +1 -0
  14. orangecontrib/tomwer/widgets/control/SingleTomoObjOW.py +6 -6
  15. orangecontrib/tomwer/widgets/control/VolumeSelector.py +7 -4
  16. orangecontrib/tomwer/widgets/control/VolumeSymLinkOW.py +182 -182
  17. orangecontrib/tomwer/widgets/debugtools/DatasetGeneratorOW.py +5 -5
  18. orangecontrib/tomwer/widgets/edit/DarkFlatPatchOW.py +4 -4
  19. orangecontrib/tomwer/widgets/edit/ImageKeyEditorOW.py +3 -3
  20. orangecontrib/tomwer/widgets/edit/ImageKeyUpgraderOW.py +8 -1
  21. orangecontrib/tomwer/widgets/edit/NXtomoEditorOW.py +3 -3
  22. orangecontrib/tomwer/widgets/edit/test/test_nxtomo_editor.py +3 -3
  23. orangecontrib/tomwer/widgets/icat/PublishProcessedDataOW.py +115 -0
  24. orangecontrib/tomwer/widgets/icat/RawDataScreenshotCreatorOW.py +98 -0
  25. orangecontrib/tomwer/widgets/icat/SaveToGalleryAndPublishOW.py +129 -0
  26. orangecontrib/tomwer/widgets/icat/__init__.py +13 -0
  27. orangecontrib/tomwer/widgets/icat/icons/add_gallery.png +0 -0
  28. orangecontrib/tomwer/widgets/icat/icons/add_gallery.svg +82 -0
  29. orangecontrib/tomwer/widgets/icat/icons/publish_processed_data.png +0 -0
  30. orangecontrib/tomwer/widgets/icat/icons/publish_processed_data.svg +95 -0
  31. orangecontrib/tomwer/widgets/icat/icons/raw_screenshots.png +0 -0
  32. orangecontrib/tomwer/widgets/icat/icons/raw_screenshots.svg +143 -0
  33. orangecontrib/tomwer/widgets/icons/tomwer_data_portal.png +0 -0
  34. orangecontrib/tomwer/widgets/icons/tomwer_data_portal.svg +76 -0
  35. orangecontrib/tomwer/widgets/reconstruction/AxisOW.py +22 -20
  36. orangecontrib/tomwer/widgets/reconstruction/CastNabuVolumeOW.py +19 -3
  37. orangecontrib/tomwer/widgets/reconstruction/NabuHelicalPrepareWeightsDoubleOW.py +184 -169
  38. orangecontrib/tomwer/widgets/reconstruction/NabuOW.py +23 -0
  39. orangecontrib/tomwer/widgets/reconstruction/NabuVolumeOW.py +39 -5
  40. orangecontrib/tomwer/widgets/reconstruction/SAAxisOW.py +18 -22
  41. orangecontrib/tomwer/widgets/reconstruction/SADeltaBetaOW.py +18 -26
  42. orangecontrib/tomwer/widgets/reconstruction/SinoNormOW.py +15 -19
  43. orangecontrib/tomwer/widgets/visualization/DataViewerOW.py +9 -9
  44. orangecontrib/tomwer/widgets/visualization/DiffViewerOW.py +1 -1
  45. orangecontrib/tomwer/widgets/visualization/LivesliceOW.py +1 -1
  46. orangecontrib/tomwer/widgets/visualization/NXtomoMetadataViewerOW.py +3 -3
  47. orangecontrib/tomwer/widgets/visualization/SinogramViewerOW.py +0 -1
  48. orangecontrib/tomwer/widgets/visualization/VolumeViewerOW.py +3 -29
  49. tomwer/__main__.py +7 -64
  50. tomwer/app/axis.py +3 -3
  51. tomwer/app/canvas.py +8 -0
  52. tomwer/app/canvas_launcher/config.py +16 -14
  53. tomwer/app/canvas_launcher/environ.py +1 -0
  54. tomwer/app/canvas_launcher/mainwindow.py +4 -1
  55. tomwer/app/darkref.py +1 -1
  56. tomwer/app/darkrefpatch.py +1 -1
  57. tomwer/app/diffframe.py +3 -3
  58. tomwer/app/imagekeyeditor.py +5 -5
  59. tomwer/app/imagekeyupgrader.py +5 -5
  60. tomwer/app/intensitynormalization.py +14 -13
  61. tomwer/app/{saaxis.py → multicor.py} +3 -3
  62. tomwer/app/{sadeltabeta.py → multipag.py} +3 -3
  63. tomwer/app/nabuapp.py +0 -11
  64. tomwer/app/radiostack.py +6 -4
  65. tomwer/app/samplemoved.py +3 -2
  66. tomwer/app/scanviewer.py +4 -2
  67. tomwer/app/sinogramviewer.py +3 -2
  68. tomwer/app/slicestack.py +3 -2
  69. tomwer/app/zstitching.py +88 -6
  70. tomwer/core/cluster/cluster.py +26 -0
  71. tomwer/core/log/logger.py +7 -5
  72. tomwer/core/process/conditions/filters.py +1 -1
  73. tomwer/core/process/control/datalistener/datalistener.py +19 -14
  74. tomwer/core/process/control/datawatcher/edfdwprocess.py +0 -9
  75. tomwer/core/process/control/nxtomoconcatenate.py +13 -13
  76. tomwer/core/process/control/nxtomomill.py +92 -34
  77. tomwer/core/process/control/scantransfer.py +20 -43
  78. tomwer/core/process/control/scanvalidator.py +3 -2
  79. tomwer/core/process/control/test/test_concatenate_nxtomos.py +9 -9
  80. tomwer/core/process/control/test/test_email.py +4 -4
  81. tomwer/core/process/control/test/test_h52nx_process.py +59 -7
  82. tomwer/core/process/control/test/test_volume_link.py +64 -64
  83. tomwer/core/process/control/timer.py +1 -1
  84. tomwer/core/process/control/volumesymlink.py +200 -200
  85. tomwer/core/process/edit/darkflatpatch.py +14 -15
  86. tomwer/core/process/edit/imagekeyeditor.py +41 -39
  87. tomwer/core/process/icat/__init__.py +0 -0
  88. tomwer/core/process/icat/createscreenshots.py +100 -0
  89. tomwer/core/process/icat/gallery.py +377 -0
  90. tomwer/core/process/icat/icatbase.py +36 -0
  91. tomwer/core/process/icat/publish.py +228 -0
  92. tomwer/core/process/icat/screenshots.py +27 -0
  93. tomwer/core/process/output.py +52 -0
  94. tomwer/core/process/reconstruction/axis/axis.py +280 -69
  95. tomwer/core/process/reconstruction/axis/mode.py +163 -48
  96. tomwer/core/process/reconstruction/axis/params.py +29 -21
  97. tomwer/core/process/reconstruction/darkref/darkrefs.py +41 -127
  98. tomwer/core/process/reconstruction/darkref/darkrefscopy.py +4 -3
  99. tomwer/core/process/reconstruction/darkref/params.py +1 -1
  100. tomwer/core/process/reconstruction/nabu/castvolume.py +4 -4
  101. tomwer/core/process/reconstruction/nabu/helical.py +9 -5
  102. tomwer/core/process/reconstruction/nabu/nabucommon.py +71 -78
  103. tomwer/core/process/reconstruction/nabu/nabuscores.py +425 -53
  104. tomwer/core/process/reconstruction/nabu/nabuslices.py +114 -93
  105. tomwer/core/process/reconstruction/nabu/nabuvolume.py +54 -27
  106. tomwer/core/process/reconstruction/nabu/plane.py +9 -0
  107. tomwer/core/process/reconstruction/nabu/settings.py +2 -2
  108. tomwer/core/process/reconstruction/nabu/utils.py +164 -26
  109. tomwer/core/process/reconstruction/output.py +108 -0
  110. tomwer/core/process/reconstruction/saaxis/saaxis.py +238 -264
  111. tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py +151 -87
  112. tomwer/core/process/reconstruction/scores/params.py +7 -4
  113. tomwer/core/process/reconstruction/scores/scores.py +13 -0
  114. tomwer/core/process/reconstruction/test/test_axis_params.py +2 -2
  115. tomwer/core/process/reconstruction/test/test_darkref.py +3 -3
  116. tomwer/core/process/reconstruction/test/test_darkref_copy.py +7 -7
  117. tomwer/core/process/reconstruction/test/test_saaxis.py +3 -4
  118. tomwer/core/process/reconstruction/test/test_sadeltabeta.py +2 -2
  119. tomwer/core/process/stitching/nabustitcher.py +13 -12
  120. tomwer/core/process/task.py +34 -26
  121. tomwer/core/process/test/test_axis.py +13 -12
  122. tomwer/core/process/test/test_dark_and_flat.py +10 -7
  123. tomwer/core/process/test/test_data_transfer.py +10 -8
  124. tomwer/core/process/test/test_nabu.py +14 -6
  125. tomwer/core/process/test/test_normalization.py +4 -4
  126. tomwer/core/scan/blissscan.py +3 -3
  127. tomwer/core/scan/edfscan.py +13 -10
  128. tomwer/core/scan/hdf5scan.py +19 -530
  129. tomwer/core/scan/nxtomoscan.py +534 -0
  130. tomwer/core/scan/scanbase.py +72 -44
  131. tomwer/core/scan/scanfactory.py +13 -13
  132. tomwer/core/scan/test/test_edf.py +2 -2
  133. tomwer/core/scan/test/test_future_scan.py +3 -3
  134. tomwer/core/scan/test/test_h5.py +18 -16
  135. tomwer/core/scan/test/test_process_registration.py +4 -40
  136. tomwer/core/scan/test/test_scan.py +5 -78
  137. tomwer/core/settings.py +22 -2
  138. tomwer/core/test/test_scanutils.py +8 -7
  139. tomwer/core/test/test_utils.py +35 -28
  140. tomwer/core/tomwer_object.py +1 -1
  141. tomwer/core/utils/__init__.py +0 -466
  142. tomwer/core/utils/deprecation.py +1 -1
  143. tomwer/core/utils/dictutils.py +14 -0
  144. tomwer/core/utils/lbsram.py +35 -0
  145. tomwer/core/utils/nxtomoutils.py +1 -1
  146. tomwer/core/utils/scanutils.py +6 -6
  147. tomwer/core/utils/spec.py +263 -0
  148. tomwer/core/volume/edfvolume.py +6 -6
  149. tomwer/core/volume/hdf5volume.py +6 -6
  150. tomwer/core/volume/jp2kvolume.py +6 -6
  151. tomwer/core/volume/rawvolume.py +6 -6
  152. tomwer/core/volume/tiffvolume.py +12 -12
  153. tomwer/core/volume/volumefactory.py +2 -2
  154. tomwer/gui/cluster/slurm.py +274 -65
  155. tomwer/gui/cluster/supervisor.py +12 -0
  156. tomwer/gui/cluster/test/test_cluster.py +14 -2
  157. tomwer/gui/cluster/test/test_supervisor.py +3 -3
  158. tomwer/gui/configuration/__init__.py +0 -0
  159. tomwer/gui/{reconstruction/nabu → configuration}/action.py +1 -32
  160. tomwer/gui/configuration/level.py +22 -0
  161. tomwer/gui/control/actions.py +54 -0
  162. tomwer/gui/control/datalist.py +83 -16
  163. tomwer/gui/control/datalistener.py +4 -16
  164. tomwer/gui/control/datawatcher/controlwidget.py +2 -4
  165. tomwer/gui/control/datawatcher/datawatcher.py +1 -24
  166. tomwer/gui/control/{email.py → emailnotifier.py} +9 -18
  167. tomwer/gui/control/history.py +2 -2
  168. tomwer/gui/control/observations.py +2 -2
  169. tomwer/gui/control/reducedarkflatselector.py +9 -9
  170. tomwer/gui/control/selectorwidgetbase.py +36 -9
  171. tomwer/gui/control/serie/seriecreator.py +5 -22
  172. tomwer/gui/control/test/test_email.py +1 -1
  173. tomwer/gui/control/test/test_scanvalidator.py +6 -5
  174. tomwer/gui/control/test/test_single_tomo_obj.py +3 -3
  175. tomwer/gui/control/tomoobjdisplaymode.py +8 -0
  176. tomwer/gui/debugtools/datasetgenerator.py +3 -3
  177. tomwer/gui/edit/dkrfpatch.py +20 -26
  178. tomwer/gui/edit/imagekeyeditor.py +11 -12
  179. tomwer/gui/edit/nxtomoeditor.py +111 -44
  180. tomwer/gui/edit/nxtomowarmer.py +7 -6
  181. tomwer/gui/edit/test/test_dkrf_patch.py +13 -13
  182. tomwer/gui/edit/test/test_image_key_editor.py +3 -3
  183. tomwer/gui/edit/test/test_nx_editor.py +40 -16
  184. tomwer/gui/icat/__init__.py +0 -0
  185. tomwer/gui/icat/createscreenshots.py +80 -0
  186. tomwer/gui/icat/gallery.py +214 -0
  187. tomwer/gui/icat/publish.py +187 -0
  188. tomwer/gui/imagefromfile.py +2 -2
  189. tomwer/gui/qfolderdialog.py +24 -1
  190. tomwer/gui/reconstruction/axis/CompareImages.py +88 -168
  191. tomwer/gui/reconstruction/axis/axis.py +171 -57
  192. tomwer/gui/reconstruction/axis/radioaxis.py +122 -257
  193. tomwer/gui/reconstruction/darkref/darkrefcopywidget.py +3 -2
  194. tomwer/gui/reconstruction/darkref/darkrefwidget.py +2 -1
  195. tomwer/gui/reconstruction/nabu/castvolume.py +14 -3
  196. tomwer/gui/reconstruction/nabu/check.py +9 -9
  197. tomwer/gui/reconstruction/nabu/helical.py +29 -12
  198. tomwer/gui/reconstruction/nabu/nabuconfig/base.py +2 -4
  199. tomwer/gui/reconstruction/nabu/nabuconfig/nabuconfig.py +2 -1
  200. tomwer/gui/reconstruction/nabu/nabuconfig/output.py +126 -35
  201. tomwer/gui/reconstruction/nabu/nabuconfig/phase.py +39 -32
  202. tomwer/gui/reconstruction/nabu/nabuconfig/preprocessing.py +222 -31
  203. tomwer/gui/reconstruction/nabu/nabuconfig/reconstruction.py +57 -27
  204. tomwer/gui/reconstruction/nabu/nabuflow.py +12 -20
  205. tomwer/gui/reconstruction/nabu/slices.py +10 -11
  206. tomwer/gui/reconstruction/nabu/volume.py +22 -10
  207. tomwer/gui/reconstruction/normalization/intensity.py +18 -48
  208. tomwer/gui/reconstruction/saaxis/corrangeselector.py +8 -24
  209. tomwer/gui/reconstruction/saaxis/dimensionwidget.py +1 -1
  210. tomwer/gui/reconstruction/saaxis/saaxis.py +9 -21
  211. tomwer/gui/reconstruction/sadeltabeta/saadeltabeta.py +45 -12
  212. tomwer/gui/reconstruction/scores/control.py +2 -9
  213. tomwer/gui/reconstruction/scores/scoreplot.py +13 -11
  214. tomwer/gui/reconstruction/test/test_axis.py +41 -16
  215. tomwer/gui/reconstruction/test/test_nabu.py +31 -9
  216. tomwer/gui/reconstruction/test/test_saaxis.py +3 -3
  217. tomwer/gui/reconstruction/test/test_sadeltabeta.py +12 -2
  218. tomwer/gui/settings.py +5 -28
  219. tomwer/gui/stackplot.py +2 -5
  220. tomwer/gui/stitching/action.py +49 -0
  221. tomwer/gui/stitching/config/axisparams.py +7 -24
  222. tomwer/gui/stitching/config/output.py +10 -8
  223. tomwer/gui/stitching/config/positionoveraxis.py +22 -23
  224. tomwer/gui/stitching/normalization.py +117 -0
  225. tomwer/gui/stitching/stitchandbackground.py +4 -6
  226. tomwer/gui/stitching/stitching.py +267 -45
  227. tomwer/gui/stitching/stitching_preview.py +62 -55
  228. tomwer/gui/stitching/stitching_raw.py +13 -12
  229. tomwer/gui/stitching/z_stitching/fineestimation.py +0 -60
  230. tomwer/gui/utils/buttons.py +112 -29
  231. tomwer/gui/utils/inputwidget.py +43 -25
  232. tomwer/gui/utils/lineselector/lineselector.py +1 -1
  233. tomwer/gui/utils/scandescription.py +4 -0
  234. tomwer/gui/utils/step.py +144 -0
  235. tomwer/gui/utils/unitsystem.py +2 -5
  236. tomwer/gui/utils/vignettes.py +176 -15
  237. tomwer/gui/visualization/dataviewer.py +48 -35
  238. tomwer/gui/visualization/diffviewer/diffviewer.py +7 -16
  239. tomwer/gui/visualization/diffviewer/shiftwidget.py +2 -5
  240. tomwer/gui/visualization/scanoverview.py +1 -1
  241. tomwer/gui/visualization/sinogramviewer.py +20 -36
  242. tomwer/gui/visualization/test/test_diffviewer.py +3 -3
  243. tomwer/gui/visualization/test/test_nx_tomo_metadata_viewer.py +4 -4
  244. tomwer/gui/visualization/test/test_sinogramviewer.py +2 -2
  245. tomwer/gui/visualization/test/test_stacks.py +3 -3
  246. tomwer/gui/visualization/test/test_volumeviewer.py +65 -67
  247. tomwer/gui/visualization/volumeviewer.py +114 -113
  248. tomwer/io/utils/h5pyutils.py +3 -3
  249. tomwer/io/utils/raw_and_processed_data.py +84 -0
  250. tomwer/io/utils/tomoobj.py +4 -6
  251. tomwer/io/utils/utils.py +7 -7
  252. tomwer/resources/gui/icons/parameters.svg +1 -1
  253. tomwer/resources/gui/icons/ruler.png +0 -0
  254. tomwer/resources/gui/icons/ruler.svg +273 -0
  255. tomwer/resources/gui/icons/short_description.png +0 -0
  256. tomwer/resources/gui/icons/short_description.svg +58 -0
  257. tomwer/resources/gui/icons/url.png +0 -0
  258. tomwer/resources/gui/icons/url.svg +58 -0
  259. tomwer/resources/gui/illustrations/no_rot.svg +1 -1
  260. tomwer/synctools/stacks/edit/darkflatpatch.py +19 -14
  261. tomwer/synctools/stacks/edit/imagekeyeditor.py +2 -2
  262. tomwer/synctools/stacks/reconstruction/axis.py +4 -4
  263. tomwer/synctools/stacks/reconstruction/castvolume.py +22 -7
  264. tomwer/synctools/stacks/reconstruction/dkrefcopy.py +25 -20
  265. tomwer/synctools/stacks/reconstruction/nabu.py +2 -2
  266. tomwer/synctools/stacks/reconstruction/normalization.py +2 -2
  267. tomwer/synctools/stacks/reconstruction/saaxis.py +2 -2
  268. tomwer/synctools/stacks/reconstruction/sadeltabeta.py +2 -2
  269. tomwer/synctools/test/test_darkRefs.py +7 -58
  270. tomwer/synctools/test/test_foldertransfer.py +6 -6
  271. tomwer/synctools/utils/scanstages.py +6 -6
  272. tomwer/tests/conftest.py +34 -0
  273. tomwer/tests/datasets.py +13 -0
  274. tomwer/tests/test_scripts.py +91 -41
  275. tomwer/tests/utils.py +5 -0
  276. tomwer/third_part/WaitingOverlay.py +110 -0
  277. tomwer/third_part/__init__.py +0 -0
  278. tomwer/version.py +2 -2
  279. tomwer-1.3.12-py3.11-nspkg.pth +1 -0
  280. {tomwer-1.2.1.dist-info → tomwer-1.3.12.dist-info}/METADATA +73 -58
  281. {tomwer-1.2.1.dist-info → tomwer-1.3.12.dist-info}/RECORD +287 -286
  282. {tomwer-1.2.1.dist-info → tomwer-1.3.12.dist-info}/WHEEL +1 -1
  283. orangecontrib/tomwer/widgets/reconstruction/TofuOW.py +0 -197
  284. orangecontrib/tomwer/widgets/reconstruction/icons/XY_lamino.svg +0 -168
  285. orangecontrib/tomwer/widgets/reconstruction/icons/XZ_lamino.svg +0 -275
  286. orangecontrib/tomwer/widgets/reconstruction/icons/YZ_lamino.svg +0 -182
  287. tomwer/app/lamino.py +0 -143
  288. tomwer/core/process/reconstruction/lamino/__init__.py +0 -1
  289. tomwer/core/process/reconstruction/lamino/tofu.py +0 -1000
  290. tomwer/core/process/test/test_lamino.py +0 -76
  291. tomwer/core/test/test_lamino.py +0 -92
  292. tomwer/gui/reconstruction/lamino/__init__.py +0 -31
  293. tomwer/gui/reconstruction/lamino/tofu/TofuOptionLoader.py +0 -107
  294. tomwer/gui/reconstruction/lamino/tofu/__init__.py +0 -1
  295. tomwer/gui/reconstruction/lamino/tofu/misc.py +0 -148
  296. tomwer/gui/reconstruction/lamino/tofu/projections.py +0 -896
  297. tomwer/gui/reconstruction/lamino/tofu/settings.py +0 -75
  298. tomwer/gui/reconstruction/lamino/tofu/tofu.py +0 -432
  299. tomwer/gui/reconstruction/lamino/tofu/tofuexpert.py +0 -567
  300. tomwer/gui/reconstruction/lamino/tofu/tofuoutput.py +0 -760
  301. tomwer/gui/reconstruction/test/test_lamino.py +0 -189
  302. tomwer/resources/gui/icons/esrf_1.svg +0 -307
  303. tomwer/resources/gui/icons/lamino_parameters.svg +0 -70
  304. tomwer/resources/gui/icons/triangle.svg +0 -80
  305. tomwer/resources/gui/illustrations/lamino_angle.png +0 -0
  306. tomwer/resources/gui/illustrations/lamino_angle.svg +0 -509
  307. tomwer/resources/gui/illustrations/lamino_beta_angle.png +0 -0
  308. tomwer/resources/gui/illustrations/lamino_beta_angle.svg +0 -97
  309. tomwer/resources/gui/illustrations/lamino_theta_angle.png +0 -0
  310. tomwer/resources/gui/illustrations/lamino_theta_angle.svg +0 -368
  311. tomwer/resources/gui/illustrations/manual_slice.png +0 -0
  312. tomwer/resources/gui/illustrations/manual_slice.svg +0 -221
  313. tomwer/resources/gui/illustrations/psi_angle.png +0 -0
  314. tomwer/resources/gui/illustrations/psi_angle.svg +0 -479
  315. tomwer/resources/gui/illustrations/rotation_center.png +0 -0
  316. tomwer/resources/gui/illustrations/rotation_center.svg +0 -276
  317. tomwer/resources/gui/illustrations/slice_stack.png +0 -0
  318. tomwer/resources/gui/illustrations/slice_stack.svg +0 -266
  319. tomwer/resources/gui/illustrations/xy_slice.png +0 -0
  320. tomwer/resources/gui/illustrations/xy_slice.svg +0 -269
  321. tomwer/resources/gui/illustrations/xz_slice.png +0 -0
  322. tomwer/resources/gui/illustrations/xz_slice.svg +0 -270
  323. tomwer/resources/gui/illustrations/yz_slice.png +0 -0
  324. tomwer/resources/gui/illustrations/yz_slice.svg +0 -270
  325. tomwer/synctools/stacks/reconstruction/lamino.py +0 -233
  326. tomwer/synctools/test/test_scanstages.py +0 -162
  327. tomwer/tests/utils/__init__.py +0 -247
  328. tomwer/tests/utils/utilstest.py +0 -220
  329. tomwer-1.2.1-py3.11-nspkg.pth +0 -1
  330. /tomwer/core/process/control/{email.py → emailnotifier.py} +0 -0
  331. {tomwer-1.2.1.dist-info → tomwer-1.3.12.dist-info}/LICENSE +0 -0
  332. {tomwer-1.2.1.dist-info → tomwer-1.3.12.dist-info}/entry_points.txt +0 -0
  333. {tomwer-1.2.1.dist-info → tomwer-1.3.12.dist-info}/namespace_packages.txt +0 -0
  334. {tomwer-1.2.1.dist-info → tomwer-1.3.12.dist-info}/top_level.txt +0 -0
@@ -1,36 +1,3 @@
1
- # coding: utf-8
2
- ###########################################################################
3
- # Copyright (C) 2016 European Synchrotron Radiation Facility
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
22
- #
23
- #############################################################################
24
-
25
- """contain utils for score process
26
- """
27
-
28
- __authors__ = [
29
- "H.Payno",
30
- ]
31
- __license__ = "MIT"
32
- __date__ = "28/10/2021"
33
-
34
1
  try:
35
2
  from nabu.pipeline.fullfield.reconstruction import ( # noqa F401
36
3
  FullFieldReconstructor,
@@ -49,13 +16,18 @@ else:
49
16
  has_nabu = True
50
17
  import logging
51
18
  import os
19
+ import sys
52
20
  from copy import deepcopy
21
+ import subprocess
53
22
  from typing import Iterable, Optional, Union
23
+ import numpy
54
24
 
55
25
  from nabu.pipeline.fullfield.nabu_config import (
56
26
  nabu_config as nabu_fullfield_default_config,
57
27
  )
58
28
  from processview.core.manager.manager import ProcessManager
29
+ from sluurp.job import SBatchScriptJob
30
+ from sluurp.executor import submit as submit_to_slurm_cluster
59
31
 
60
32
  from tomwer.core.futureobject import FutureTomwerObject
61
33
  from tomwer.core.process.reconstruction.nabu.nabuslices import (
@@ -63,15 +35,21 @@ from tomwer.core.process.reconstruction.nabu.nabuslices import (
63
35
  _NabuBaseReconstructor,
64
36
  generate_nabu_configfile,
65
37
  )
38
+ from tomwer.core.process.reconstruction.nabu.utils import (
39
+ slice_index_to_int,
40
+ get_nabu_multicor_file_prefix,
41
+ )
66
42
  from tomwer.core.process.reconstruction.nabu.target import Target
67
43
  from tomwer.core.progress import Progress
68
44
  from tomwer.core.scan.scanbase import TomwerScanBase
69
- from tomwer.core.utils.slurm import is_slurm_available
45
+ from tomwer.core.utils.slurm import get_slurm_script_name, is_slurm_available
70
46
  from tomwer.utils import docstring
47
+ from tomwer.core.process.reconstruction.nabu.utils import nabu_std_err_has_error
48
+ from tomwer.core.process.reconstruction.nabu.plane import NabuPlane
71
49
 
72
50
  from ..nabu import settings as nabu_settings
73
- from . import utils
74
- from .nabucommon import ResultsLocalRun, ResultSlurmRun, ResultsWithStd
51
+ from . import utils, settings
52
+ from .nabucommon import ResultsLocalRun, ResultSlurmRun, ResultsWithStd, ResultsRun
75
53
 
76
54
  _logger = logging.getLogger(__name__)
77
55
 
@@ -83,6 +61,7 @@ def run_nabu_one_slice_several_config(
83
61
  dry_run: bool,
84
62
  slice_index: Union[int, str],
85
63
  file_format: str,
64
+ axis: NabuPlane,
86
65
  advancement: Optional[Progress] = None,
87
66
  process_id: Optional[int] = None,
88
67
  instanciate_classes_only: bool = False,
@@ -132,6 +111,7 @@ def run_nabu_one_slice_several_config(
132
111
  cluster_config=cluster_config,
133
112
  process_name=process_name,
134
113
  output_file_prefix_pattern=output_file_prefix_pattern,
114
+ axis=axis,
135
115
  )
136
116
  if instanciate_classes_only:
137
117
  return (reconstructor,)
@@ -156,7 +136,7 @@ def run_nabu_one_slice_several_config(
156
136
  std_outs.append(res.std_out)
157
137
  std_errs.append(res.std_err)
158
138
  if isinstance(res, ResultsLocalRun):
159
- recons_urls[var_value] = res.results_urls
139
+ recons_urls[var_value] = res.results_identifiers
160
140
  if isinstance(res, ResultSlurmRun):
161
141
  future_tomo_obj = FutureTomwerObject(
162
142
  tomo_obj=scan,
@@ -167,6 +147,87 @@ def run_nabu_one_slice_several_config(
167
147
  return success, recons_urls, std_outs, std_errs, future_tomo_objs
168
148
 
169
149
 
150
+ def run_nabu_multicor(
151
+ scan: TomwerScanBase,
152
+ nabu_config: dict,
153
+ cors: tuple,
154
+ cluster_config: Optional[dict],
155
+ dry_run: bool,
156
+ slice_index: Union[int, str],
157
+ file_format: str,
158
+ process_id: Optional[int] = None,
159
+ instanciate_classes_only: bool = False,
160
+ output_file_prefix_pattern=None,
161
+ ):
162
+ if cluster_config in (None, {}):
163
+ target = Target.LOCAL
164
+ elif isinstance(cluster_config, dict):
165
+ if not is_slurm_available():
166
+ raise RuntimeError("Slurm computation requested but unvailable")
167
+ target = Target.SLURM
168
+ else:
169
+ raise TypeError(
170
+ f"cluster_config should be None or a dict not {type(cluster_config)}"
171
+ )
172
+
173
+ if process_id is not None:
174
+ try:
175
+ process_name = ProcessManager().get_process(process_id=process_id).name
176
+ except KeyError:
177
+ process_name = "unknow"
178
+ else:
179
+ process_name = ""
180
+
181
+ # TODO: FIXME small hack to make sure the configuration will be accepted when valie
182
+ # for now even if the cor values are given from a dedicated parameter nabu is still
183
+ # checking the value provided in the config file. If this value is invalid for
184
+ # half acquisition it will be refused
185
+ nabu_config["reconstruction"]["rotation_axis_position"] = numpy.mean(cors)
186
+
187
+ axis = nabu_config["reconstruction"].get("slice_plane", "XY")
188
+
189
+ reconstructor = _ReconstructorMultiCor(
190
+ scan=scan,
191
+ nabu_config=nabu_config,
192
+ cors=cors,
193
+ slice_index=slice_index,
194
+ target=target,
195
+ dry_run=dry_run,
196
+ file_format=file_format,
197
+ cluster_config=cluster_config,
198
+ process_name=process_name,
199
+ axis=axis,
200
+ output_file_prefix_pattern=output_file_prefix_pattern,
201
+ )
202
+ if instanciate_classes_only:
203
+ return reconstructor
204
+
205
+ try:
206
+ result = reconstructor.run()
207
+ except TimeoutError as e:
208
+ _logger.error(e)
209
+ return None
210
+ else:
211
+ recons_urls = {}
212
+ std_outs = []
213
+ std_errs = []
214
+ future_tomo_obj = None
215
+
216
+ success = result.success
217
+ if isinstance(result, ResultsWithStd):
218
+ std_outs.append(result.std_out)
219
+ std_errs.append(result.std_err)
220
+ if isinstance(result, ResultsLocalRun):
221
+ recons_urls = result.results_identifiers
222
+ if isinstance(result, ResultSlurmRun):
223
+ future_tomo_obj = FutureTomwerObject(
224
+ tomo_obj=scan,
225
+ process_requester_id=process_id,
226
+ futures=result.future_slurm_jobs,
227
+ )
228
+ return success, recons_urls, (future_tomo_obj,), std_outs, std_errs
229
+
230
+
170
231
  class _Reconstructor(_NabuBaseReconstructor):
171
232
  def __init__(
172
233
  self,
@@ -174,6 +235,7 @@ class _Reconstructor(_NabuBaseReconstructor):
174
235
  nabu_configs: Iterable,
175
236
  advancement: Optional[Progress],
176
237
  slice_index: Union[int, str],
238
+ axis: Union[str, NabuPlane],
177
239
  target: Target,
178
240
  dry_run: bool,
179
241
  file_format: str,
@@ -182,6 +244,14 @@ class _Reconstructor(_NabuBaseReconstructor):
182
244
  output_file_prefix_pattern=None,
183
245
  ) -> None:
184
246
  """
247
+ :param scan: scan to reconstruct
248
+ :param nabu_configs: all the configuration to run
249
+ :param advancement: Progress object to notify advancement
250
+ :param slice_index: index of the slice to reconstruct.
251
+ :param axis: axis over which we want to do the reconstruction
252
+ :param target: is the reconstruction is to made locally or remotly
253
+ :param file_format: reconstructed volume file format
254
+ :param cluster_config: cluster configuration in the case of a remote execution
185
255
  :param str extra_output_file_pattern: possible extra file name pattern like for cor we want to add 'cor_' as prefix and cor value as suffix.
186
256
  To make the file name unique. For delta/beta it is already forseen to be unique. For now keywords are:
187
257
  * file_name: default file name according to db values and dataset name
@@ -193,12 +263,12 @@ class _Reconstructor(_NabuBaseReconstructor):
193
263
  target=target,
194
264
  cluster_config=cluster_config,
195
265
  process_name=process_name,
266
+ axis=axis,
196
267
  )
197
268
  if not isinstance(slice_index, (int, str)):
198
269
  raise TypeError(
199
270
  f"slice_index should be an int or a string not {type(slice_index)}"
200
271
  )
201
-
202
272
  self.advancement = advancement
203
273
  self.slice_index = slice_index
204
274
  self.nabu_configs = nabu_configs
@@ -207,14 +277,9 @@ class _Reconstructor(_NabuBaseReconstructor):
207
277
 
208
278
  @docstring(_NabuBaseReconstructor)
209
279
  def run(self) -> Iterable:
210
- if self.slice_index == "middle":
211
- if self.scan.dim_2 is not None:
212
- self.slice_index = self.scan.dim_2 // 2
213
- else:
214
- _logger.warning(
215
- "scan.dim_2 returns None, unable to deduce middle " "pick 1024"
216
- )
217
- self.slice_index = 1024
280
+ self.slice_index = slice_index_to_int(
281
+ slice_index=self.slice_index, scan=self.scan
282
+ )
218
283
 
219
284
  results = {}
220
285
  if self.advancement:
@@ -223,8 +288,6 @@ class _Reconstructor(_NabuBaseReconstructor):
223
288
  if self._cancelled:
224
289
  break
225
290
  config, conf_file = self.preprocess_config(deepcopy(config), var_value)
226
- print("conf file is", conf_file)
227
- print("confif output is", config.get("output"))
228
291
 
229
292
  # add some tomwer metadata and save the configuration
230
293
  # note: for now the section is ignored by nabu but shouldn't stay that way
@@ -240,8 +303,6 @@ class _Reconstructor(_NabuBaseReconstructor):
240
303
  config_to_dump=config_to_dump,
241
304
  config_file=conf_file,
242
305
  file_format=self.file_format,
243
- start_z=None,
244
- end_z=None,
245
306
  info="nabu slice reconstruction",
246
307
  process_name=self.process_name,
247
308
  )
@@ -303,6 +364,7 @@ class _Reconstructor(_NabuBaseReconstructor):
303
364
  pag=pag,
304
365
  db=db,
305
366
  ctf=ctf,
367
+ axis=self.axis,
306
368
  )
307
369
  file_prefix = self._format_file_prefix(file_prefix=file_prefix, value=value)
308
370
  _config["output"]["file_prefix"] = file_prefix
@@ -312,11 +374,22 @@ class _Reconstructor(_NabuBaseReconstructor):
312
374
 
313
375
  if "reconstruction" not in _config:
314
376
  _config["reconstruction"] = {}
315
- _config["reconstruction"]["start_z"] = self.slice_index
316
- _config["reconstruction"]["end_z"] = self.slice_index
377
+ if self.axis is NabuPlane.YZ:
378
+ _config["reconstruction"]["start_x"] = self.slice_index
379
+ _config["reconstruction"]["end_x"] = self.slice_index
380
+ elif self.axis is NabuPlane.XZ:
381
+ _config["reconstruction"]["start_y"] = self.slice_index
382
+ _config["reconstruction"]["end_y"] = self.slice_index
383
+ elif self.axis is NabuPlane.XY:
384
+ _config["reconstruction"]["start_z"] = self.slice_index
385
+ _config["reconstruction"]["end_z"] = self.slice_index
386
+ else:
387
+ raise ValueError(
388
+ f"self.axis has an invalid value: {self.axis} when expected to be in {NabuPlane.values()}"
389
+ )
317
390
  return _config, file_prefix
318
391
 
319
- def preprocess_config(self, config, value: float):
392
+ def preprocess_config(self, config, value) -> tuple:
320
393
  dataset_params = self.scan.get_nabu_dataset_info()
321
394
  if "dataset" in config:
322
395
  dataset_params.update(config["dataset"])
@@ -344,3 +417,302 @@ class _Reconstructor(_NabuBaseReconstructor):
344
417
  cfg_folder, file_prefix + nabu_settings.NABU_CONFIG_FILE_EXTENSION
345
418
  )
346
419
  return config, conf_file
420
+
421
+
422
+ class _ReconstructorMultiCor(_NabuBaseReconstructor):
423
+ def __init__(
424
+ self,
425
+ nabu_config: dict,
426
+ axis: Union[str, NabuPlane],
427
+ cors: tuple,
428
+ file_format,
429
+ slice_index: Union[int, str] = "middle",
430
+ output_file_prefix_pattern=None,
431
+ *args,
432
+ **kwargs,
433
+ ):
434
+ if not isinstance(cors, tuple):
435
+ raise TypeError(
436
+ f"cors are expected to be an instance of tuple. Get {type(cors)} instead"
437
+ )
438
+ self.__cors = cors
439
+ self.__slice_index = slice_index
440
+ self.__nabu_config = nabu_config
441
+ self.file_format = file_format
442
+ self._output_file_prefix_pattern = output_file_prefix_pattern
443
+
444
+ super().__init__(*args, **kwargs)
445
+
446
+ @property
447
+ def cors(self) -> tuple:
448
+ return self.__cors
449
+
450
+ @property
451
+ def slice_index(self) -> Union[int, str]:
452
+ return self.__slice_index
453
+
454
+ @property
455
+ def nabu_config(self) -> dict:
456
+ return self.__nabu_config
457
+
458
+ def _process_config(
459
+ self,
460
+ config_to_dump: dict,
461
+ config_file: str,
462
+ file_format: str,
463
+ info: Optional[str],
464
+ process_name: str,
465
+ ):
466
+ """
467
+ process provided configuration
468
+
469
+ :param str info:
470
+ """
471
+ if self.dry_run is True or self.only_create_config_file():
472
+ return ResultsRun(
473
+ success=True,
474
+ config=config_to_dump,
475
+ )
476
+ elif self.target is Target.LOCAL:
477
+ _logger.info(f"run {info} for {self.scan} with {config_to_dump}")
478
+ return self._run_nabu_multicor_locally(
479
+ conf_file=config_file,
480
+ file_format=file_format,
481
+ config_to_dump=config_to_dump,
482
+ )
483
+ elif self.target is Target.SLURM:
484
+ _logger.info(
485
+ f"run {info} on slurm for {self.scan.path} with {config_to_dump}"
486
+ )
487
+ return self._run_nabu_multicor_on_slurm(
488
+ conf_file=config_file,
489
+ config_to_dump=config_to_dump,
490
+ cluster_config=self.cluster_config.to_dict(),
491
+ process_name=process_name,
492
+ info=info,
493
+ )
494
+ else:
495
+ raise ValueError(f"{self.target} is not recognized as a valid target")
496
+
497
+ @staticmethod
498
+ def convert_cor_from_rel_to_abs(scan, cor):
499
+ if scan.dim_1 is not None:
500
+ return cor + scan.dim_1 / 2.0
501
+ else:
502
+ _logger.warning("enable to get image half width. Set it to 1024")
503
+ return cor + 1024
504
+
505
+ @staticmethod
506
+ def convert_cor_from_abs_to_rel(scan, cor):
507
+ if scan.dim_1 is not None:
508
+ return cor - scan.dim_1 / 2.0
509
+ else:
510
+ _logger.warning("enable to get image half width. Set it to 1024")
511
+ return cor - 1024
512
+
513
+ def _run_nabu_multicor_locally(
514
+ self,
515
+ conf_file: str,
516
+ file_format: str,
517
+ config_to_dump: dict,
518
+ ) -> ResultsLocalRun:
519
+ """
520
+ run locally nabu for a single configuration file.
521
+
522
+ :param str conf_file: path to the nabu .cfg file
523
+ :param str file_format: format of the generated file
524
+ :param dict config_to_dump: configuration saved in the .cfg as a dictionary
525
+ :return: results of the local run
526
+ :rtype: ResultsLocalRun
527
+ """
528
+ if not has_nabu:
529
+ raise ImportError("Fail to import nabu")
530
+ slice_index = slice_index_to_int(self.slice_index, scan=self.scan)
531
+
532
+ cor_in_nabu_ref = tuple(
533
+ [self.convert_cor_from_rel_to_abs(self.scan, cor) for cor in self.cors]
534
+ )
535
+ cor_in_nabu_ref = ",".join([str(cor) for cor in cor_in_nabu_ref])
536
+ command = " ".join(
537
+ (
538
+ sys.executable,
539
+ "-m",
540
+ settings.NABU_MULTICOR_PATH,
541
+ conf_file, # input file
542
+ f"{slice_index}", # slice
543
+ f"{cor_in_nabu_ref}", # cor
544
+ )
545
+ )
546
+ _logger.info(f'call nabu from "{command}"')
547
+
548
+ self._process = subprocess.Popen(
549
+ command,
550
+ shell=True,
551
+ cwd=self.scan.path,
552
+ stdout=subprocess.PIPE,
553
+ stderr=subprocess.PIPE,
554
+ )
555
+ try:
556
+ outs, errs = self._process.communicate()
557
+ except (TimeoutError, KeyboardInterrupt):
558
+ self._process.kill()
559
+ outs, errs = self._process.communicate()
560
+
561
+ file_prefix = get_nabu_multicor_file_prefix(self.scan)
562
+
563
+ recons_vol_identifiers = utils.get_multi_cor_recons_volume_identifiers(
564
+ slice_index=slice_index,
565
+ location=config_to_dump["output"]["location"],
566
+ file_prefix=file_prefix,
567
+ scan=self.scan,
568
+ file_format=file_format,
569
+ cors=[
570
+ self.convert_cor_from_rel_to_abs(self.scan, cor) for cor in self.cors
571
+ ],
572
+ )
573
+ # convert back from abs ref to rel ref
574
+ recons_vol_identifiers = {
575
+ self.convert_cor_from_abs_to_rel(self.scan, cor): identifiers
576
+ for cor, identifiers in recons_vol_identifiers.items()
577
+ }
578
+ return ResultsLocalRun(
579
+ success=not nabu_std_err_has_error(errs),
580
+ results_identifiers=recons_vol_identifiers.values(),
581
+ std_out=outs,
582
+ std_err=errs,
583
+ config=config_to_dump, # config_slices,
584
+ )
585
+
586
+ def _run_nabu_multicor_on_slurm(
587
+ self,
588
+ conf_file: str,
589
+ config_to_dump: dict,
590
+ cluster_config: dict,
591
+ process_name: str,
592
+ info: str,
593
+ ) -> ResultSlurmRun:
594
+ """
595
+ Run a nabu reconstruction on slurm of a single configuration
596
+
597
+ :return: results of the slurm run
598
+ :rtype: ResultSlurmRun
599
+ """
600
+ if not isinstance(conf_file, str):
601
+ raise TypeError(f"conf_file is expected to be a strg not {type(conf_file)}")
602
+ if not isinstance(config_to_dump, dict):
603
+ raise TypeError(
604
+ f"config_to_dump is expected to be a strg not {type(config_to_dump)}"
605
+ )
606
+ if not is_slurm_available():
607
+ raise RuntimeError("slurm not available")
608
+ if not isinstance(cluster_config, dict):
609
+ raise ValueError(
610
+ f"cluster config is expected to be a dict not {type(cluster_config)}"
611
+ )
612
+
613
+ # create slurm cluster
614
+ project_name = cluster_config.get(
615
+ "job_name", "tomwer_{scan}_-_{process}_-_{info}"
616
+ )
617
+ project_name = project_name.format(
618
+ scan=str(self.scan), process=process_name, info=info
619
+ )
620
+ # project name should not contain any spaces as it will be integrated in a script and interpreted.
621
+ project_name = project_name.replace(" ", "_")
622
+ cluster_config["job_name"] = project_name
623
+
624
+ slice_index = slice_index_to_int(self.slice_index, scan=self.scan)
625
+ cor_in_nabu_ref = tuple(
626
+ [self.convert_cor_from_rel_to_abs(self.scan, cor) for cor in self.cors]
627
+ )
628
+ cor_in_nabu_ref = ",".join([str(cor) for cor in cor_in_nabu_ref])
629
+
630
+ # submit job
631
+ script_name = get_slurm_script_name(prefix="nabu")
632
+ # for now force job name
633
+ cluster_config["job_name"] = f"tomwer-nabu {conf_file}"
634
+ job = SBatchScriptJob(
635
+ slurm_config=cluster_config,
636
+ script=(
637
+ f"python3 -m {settings.NABU_MULTICOR_PATH} {conf_file} {slice_index} {cor_in_nabu_ref}",
638
+ ),
639
+ script_path=os.path.join(self.scan.path, "slurm_scripts", script_name),
640
+ clean_script=False,
641
+ working_directory=self.scan.working_directory,
642
+ )
643
+ future_slurm_job = submit_to_slurm_cluster(job)
644
+
645
+ callbacks = self._get_futures_slurm_callback(config_to_dump)
646
+ assert isinstance(
647
+ callbacks, tuple
648
+ ), f"callbacks is expected to an instance of tuple and not {type(callbacks)}"
649
+ for callback in callbacks:
650
+ future_slurm_job.add_done_callback(callback.process)
651
+
652
+ return ResultSlurmRun(
653
+ success=True,
654
+ config=config_to_dump,
655
+ future_slurm_jobs=(future_slurm_job,),
656
+ std_out=None,
657
+ std_err=None,
658
+ job_id=job.job_id,
659
+ )
660
+
661
+ def preprocess_config(self, config):
662
+ dataset_params = self.scan.get_nabu_dataset_info()
663
+ if "dataset" in config:
664
+ dataset_params.update(config["dataset"])
665
+ config["dataset"] = dataset_params
666
+
667
+ config["resources"] = utils.get_nabu_resources_desc(
668
+ scan=self.scan, workers=1, method="local"
669
+ )
670
+ # force overwrite results
671
+ if "output" not in config:
672
+ config["output"] = {}
673
+ config["output"].update({"overwrite_results": 1})
674
+
675
+ cfg_folder = os.path.join(
676
+ config["output"]["location"],
677
+ nabu_settings.NABU_CFG_FILE_FOLDER,
678
+ )
679
+ os.makedirs(cfg_folder, exist_ok=True)
680
+
681
+ cfg_folder = os.path.join(
682
+ self.nabu_config["output"]["location"],
683
+ nabu_settings.NABU_CFG_FILE_FOLDER,
684
+ )
685
+ os.makedirs(cfg_folder, exist_ok=True)
686
+
687
+ conf_file = os.path.join(
688
+ cfg_folder,
689
+ f"{self.scan.get_dataset_basename()}_multi_cor"
690
+ + nabu_settings.NABU_CONFIG_FILE_EXTENSION,
691
+ )
692
+ return config, conf_file
693
+
694
+ def run(self) -> Iterable:
695
+ nabu_config, conf_file = self.preprocess_config(deepcopy(self.nabu_config))
696
+
697
+ # the policy is to save nabu .cfg file at the same location as the
698
+ # force overwrite results
699
+
700
+ # add some tomwer metadata and save the configuration
701
+ # note: for now the section is ignored by nabu but shouldn't stay that way
702
+ with utils.TomwerInfo(nabu_config) as config_to_dump:
703
+ generate_nabu_configfile(
704
+ conf_file,
705
+ nabu_fullfield_default_config,
706
+ config=config_to_dump,
707
+ options_level="advanced",
708
+ )
709
+
710
+ results = self._process_config(
711
+ config_to_dump=nabu_config,
712
+ config_file=conf_file,
713
+ file_format=self.file_format,
714
+ info="nabu sa-axis reconstruction",
715
+ process_name=self.process_name,
716
+ )
717
+
718
+ return results