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.
- orangecontrib/tomwer/tutorials/icat_publication.ows +58 -0
- orangecontrib/tomwer/widgets/__init__.py +11 -11
- orangecontrib/tomwer/widgets/control/DataDiscoveryOW.py +2 -2
- orangecontrib/tomwer/widgets/control/DataListOW.py +9 -7
- orangecontrib/tomwer/widgets/control/DataListenerOW.py +6 -6
- orangecontrib/tomwer/widgets/control/DataSelectorOW.py +21 -10
- orangecontrib/tomwer/widgets/control/DataValidatorOW.py +6 -6
- orangecontrib/tomwer/widgets/control/EDF2NXTomomillOW.py +24 -7
- orangecontrib/tomwer/widgets/control/EmailOW.py +4 -4
- orangecontrib/tomwer/widgets/control/NXTomomillMixIn.py +3 -3
- orangecontrib/tomwer/widgets/control/NXTomomillOW.py +64 -23
- orangecontrib/tomwer/widgets/control/NXtomoConcatenate.py +20 -8
- orangecontrib/tomwer/widgets/control/NotifierOW.py +1 -0
- orangecontrib/tomwer/widgets/control/SingleTomoObjOW.py +6 -6
- orangecontrib/tomwer/widgets/control/VolumeSelector.py +7 -4
- orangecontrib/tomwer/widgets/control/VolumeSymLinkOW.py +182 -182
- orangecontrib/tomwer/widgets/debugtools/DatasetGeneratorOW.py +5 -5
- orangecontrib/tomwer/widgets/edit/DarkFlatPatchOW.py +4 -4
- orangecontrib/tomwer/widgets/edit/ImageKeyEditorOW.py +3 -3
- orangecontrib/tomwer/widgets/edit/ImageKeyUpgraderOW.py +8 -1
- orangecontrib/tomwer/widgets/edit/NXtomoEditorOW.py +3 -3
- orangecontrib/tomwer/widgets/edit/test/test_nxtomo_editor.py +3 -3
- orangecontrib/tomwer/widgets/icat/PublishProcessedDataOW.py +115 -0
- orangecontrib/tomwer/widgets/icat/RawDataScreenshotCreatorOW.py +98 -0
- orangecontrib/tomwer/widgets/icat/SaveToGalleryAndPublishOW.py +129 -0
- orangecontrib/tomwer/widgets/icat/__init__.py +13 -0
- orangecontrib/tomwer/widgets/icat/icons/add_gallery.png +0 -0
- orangecontrib/tomwer/widgets/icat/icons/add_gallery.svg +82 -0
- orangecontrib/tomwer/widgets/icat/icons/publish_processed_data.png +0 -0
- orangecontrib/tomwer/widgets/icat/icons/publish_processed_data.svg +95 -0
- orangecontrib/tomwer/widgets/icat/icons/raw_screenshots.png +0 -0
- orangecontrib/tomwer/widgets/icat/icons/raw_screenshots.svg +143 -0
- orangecontrib/tomwer/widgets/icons/tomwer_data_portal.png +0 -0
- orangecontrib/tomwer/widgets/icons/tomwer_data_portal.svg +76 -0
- orangecontrib/tomwer/widgets/reconstruction/AxisOW.py +22 -20
- orangecontrib/tomwer/widgets/reconstruction/CastNabuVolumeOW.py +19 -3
- orangecontrib/tomwer/widgets/reconstruction/NabuHelicalPrepareWeightsDoubleOW.py +184 -169
- orangecontrib/tomwer/widgets/reconstruction/NabuOW.py +23 -0
- orangecontrib/tomwer/widgets/reconstruction/NabuVolumeOW.py +39 -5
- orangecontrib/tomwer/widgets/reconstruction/SAAxisOW.py +18 -22
- orangecontrib/tomwer/widgets/reconstruction/SADeltaBetaOW.py +18 -26
- orangecontrib/tomwer/widgets/reconstruction/SinoNormOW.py +15 -19
- orangecontrib/tomwer/widgets/visualization/DataViewerOW.py +9 -9
- orangecontrib/tomwer/widgets/visualization/DiffViewerOW.py +1 -1
- orangecontrib/tomwer/widgets/visualization/LivesliceOW.py +1 -1
- orangecontrib/tomwer/widgets/visualization/NXtomoMetadataViewerOW.py +3 -3
- orangecontrib/tomwer/widgets/visualization/SinogramViewerOW.py +0 -1
- orangecontrib/tomwer/widgets/visualization/VolumeViewerOW.py +3 -29
- tomwer/__main__.py +7 -64
- tomwer/app/axis.py +3 -3
- tomwer/app/canvas.py +8 -0
- tomwer/app/canvas_launcher/config.py +16 -14
- tomwer/app/canvas_launcher/environ.py +1 -0
- tomwer/app/canvas_launcher/mainwindow.py +4 -1
- tomwer/app/darkref.py +1 -1
- tomwer/app/darkrefpatch.py +1 -1
- tomwer/app/diffframe.py +3 -3
- tomwer/app/imagekeyeditor.py +5 -5
- tomwer/app/imagekeyupgrader.py +5 -5
- tomwer/app/intensitynormalization.py +14 -13
- tomwer/app/{saaxis.py → multicor.py} +3 -3
- tomwer/app/{sadeltabeta.py → multipag.py} +3 -3
- tomwer/app/nabuapp.py +0 -11
- tomwer/app/radiostack.py +6 -4
- tomwer/app/samplemoved.py +3 -2
- tomwer/app/scanviewer.py +4 -2
- tomwer/app/sinogramviewer.py +3 -2
- tomwer/app/slicestack.py +3 -2
- tomwer/app/zstitching.py +88 -6
- tomwer/core/cluster/cluster.py +26 -0
- tomwer/core/log/logger.py +7 -5
- tomwer/core/process/conditions/filters.py +1 -1
- tomwer/core/process/control/datalistener/datalistener.py +19 -14
- tomwer/core/process/control/datawatcher/edfdwprocess.py +0 -9
- tomwer/core/process/control/nxtomoconcatenate.py +13 -13
- tomwer/core/process/control/nxtomomill.py +92 -34
- tomwer/core/process/control/scantransfer.py +20 -43
- tomwer/core/process/control/scanvalidator.py +3 -2
- tomwer/core/process/control/test/test_concatenate_nxtomos.py +9 -9
- tomwer/core/process/control/test/test_email.py +4 -4
- tomwer/core/process/control/test/test_h52nx_process.py +59 -7
- tomwer/core/process/control/test/test_volume_link.py +64 -64
- tomwer/core/process/control/timer.py +1 -1
- tomwer/core/process/control/volumesymlink.py +200 -200
- tomwer/core/process/edit/darkflatpatch.py +14 -15
- tomwer/core/process/edit/imagekeyeditor.py +41 -39
- tomwer/core/process/icat/__init__.py +0 -0
- tomwer/core/process/icat/createscreenshots.py +100 -0
- tomwer/core/process/icat/gallery.py +377 -0
- tomwer/core/process/icat/icatbase.py +36 -0
- tomwer/core/process/icat/publish.py +228 -0
- tomwer/core/process/icat/screenshots.py +27 -0
- tomwer/core/process/output.py +52 -0
- tomwer/core/process/reconstruction/axis/axis.py +280 -69
- tomwer/core/process/reconstruction/axis/mode.py +163 -48
- tomwer/core/process/reconstruction/axis/params.py +29 -21
- tomwer/core/process/reconstruction/darkref/darkrefs.py +41 -127
- tomwer/core/process/reconstruction/darkref/darkrefscopy.py +4 -3
- tomwer/core/process/reconstruction/darkref/params.py +1 -1
- tomwer/core/process/reconstruction/nabu/castvolume.py +4 -4
- tomwer/core/process/reconstruction/nabu/helical.py +9 -5
- tomwer/core/process/reconstruction/nabu/nabucommon.py +71 -78
- tomwer/core/process/reconstruction/nabu/nabuscores.py +425 -53
- tomwer/core/process/reconstruction/nabu/nabuslices.py +114 -93
- tomwer/core/process/reconstruction/nabu/nabuvolume.py +54 -27
- tomwer/core/process/reconstruction/nabu/plane.py +9 -0
- tomwer/core/process/reconstruction/nabu/settings.py +2 -2
- tomwer/core/process/reconstruction/nabu/utils.py +164 -26
- tomwer/core/process/reconstruction/output.py +108 -0
- tomwer/core/process/reconstruction/saaxis/saaxis.py +238 -264
- tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py +151 -87
- tomwer/core/process/reconstruction/scores/params.py +7 -4
- tomwer/core/process/reconstruction/scores/scores.py +13 -0
- tomwer/core/process/reconstruction/test/test_axis_params.py +2 -2
- tomwer/core/process/reconstruction/test/test_darkref.py +3 -3
- tomwer/core/process/reconstruction/test/test_darkref_copy.py +7 -7
- tomwer/core/process/reconstruction/test/test_saaxis.py +3 -4
- tomwer/core/process/reconstruction/test/test_sadeltabeta.py +2 -2
- tomwer/core/process/stitching/nabustitcher.py +13 -12
- tomwer/core/process/task.py +34 -26
- tomwer/core/process/test/test_axis.py +13 -12
- tomwer/core/process/test/test_dark_and_flat.py +10 -7
- tomwer/core/process/test/test_data_transfer.py +10 -8
- tomwer/core/process/test/test_nabu.py +14 -6
- tomwer/core/process/test/test_normalization.py +4 -4
- tomwer/core/scan/blissscan.py +3 -3
- tomwer/core/scan/edfscan.py +13 -10
- tomwer/core/scan/hdf5scan.py +19 -530
- tomwer/core/scan/nxtomoscan.py +534 -0
- tomwer/core/scan/scanbase.py +72 -44
- tomwer/core/scan/scanfactory.py +13 -13
- tomwer/core/scan/test/test_edf.py +2 -2
- tomwer/core/scan/test/test_future_scan.py +3 -3
- tomwer/core/scan/test/test_h5.py +18 -16
- tomwer/core/scan/test/test_process_registration.py +4 -40
- tomwer/core/scan/test/test_scan.py +5 -78
- tomwer/core/settings.py +22 -2
- tomwer/core/test/test_scanutils.py +8 -7
- tomwer/core/test/test_utils.py +35 -28
- tomwer/core/tomwer_object.py +1 -1
- tomwer/core/utils/__init__.py +0 -466
- tomwer/core/utils/deprecation.py +1 -1
- tomwer/core/utils/dictutils.py +14 -0
- tomwer/core/utils/lbsram.py +35 -0
- tomwer/core/utils/nxtomoutils.py +1 -1
- tomwer/core/utils/scanutils.py +6 -6
- tomwer/core/utils/spec.py +263 -0
- tomwer/core/volume/edfvolume.py +6 -6
- tomwer/core/volume/hdf5volume.py +6 -6
- tomwer/core/volume/jp2kvolume.py +6 -6
- tomwer/core/volume/rawvolume.py +6 -6
- tomwer/core/volume/tiffvolume.py +12 -12
- tomwer/core/volume/volumefactory.py +2 -2
- tomwer/gui/cluster/slurm.py +274 -65
- tomwer/gui/cluster/supervisor.py +12 -0
- tomwer/gui/cluster/test/test_cluster.py +14 -2
- tomwer/gui/cluster/test/test_supervisor.py +3 -3
- tomwer/gui/configuration/__init__.py +0 -0
- tomwer/gui/{reconstruction/nabu → configuration}/action.py +1 -32
- tomwer/gui/configuration/level.py +22 -0
- tomwer/gui/control/actions.py +54 -0
- tomwer/gui/control/datalist.py +83 -16
- tomwer/gui/control/datalistener.py +4 -16
- tomwer/gui/control/datawatcher/controlwidget.py +2 -4
- tomwer/gui/control/datawatcher/datawatcher.py +1 -24
- tomwer/gui/control/{email.py → emailnotifier.py} +9 -18
- tomwer/gui/control/history.py +2 -2
- tomwer/gui/control/observations.py +2 -2
- tomwer/gui/control/reducedarkflatselector.py +9 -9
- tomwer/gui/control/selectorwidgetbase.py +36 -9
- tomwer/gui/control/serie/seriecreator.py +5 -22
- tomwer/gui/control/test/test_email.py +1 -1
- tomwer/gui/control/test/test_scanvalidator.py +6 -5
- tomwer/gui/control/test/test_single_tomo_obj.py +3 -3
- tomwer/gui/control/tomoobjdisplaymode.py +8 -0
- tomwer/gui/debugtools/datasetgenerator.py +3 -3
- tomwer/gui/edit/dkrfpatch.py +20 -26
- tomwer/gui/edit/imagekeyeditor.py +11 -12
- tomwer/gui/edit/nxtomoeditor.py +111 -44
- tomwer/gui/edit/nxtomowarmer.py +7 -6
- tomwer/gui/edit/test/test_dkrf_patch.py +13 -13
- tomwer/gui/edit/test/test_image_key_editor.py +3 -3
- tomwer/gui/edit/test/test_nx_editor.py +40 -16
- tomwer/gui/icat/__init__.py +0 -0
- tomwer/gui/icat/createscreenshots.py +80 -0
- tomwer/gui/icat/gallery.py +214 -0
- tomwer/gui/icat/publish.py +187 -0
- tomwer/gui/imagefromfile.py +2 -2
- tomwer/gui/qfolderdialog.py +24 -1
- tomwer/gui/reconstruction/axis/CompareImages.py +88 -168
- tomwer/gui/reconstruction/axis/axis.py +171 -57
- tomwer/gui/reconstruction/axis/radioaxis.py +122 -257
- tomwer/gui/reconstruction/darkref/darkrefcopywidget.py +3 -2
- tomwer/gui/reconstruction/darkref/darkrefwidget.py +2 -1
- tomwer/gui/reconstruction/nabu/castvolume.py +14 -3
- tomwer/gui/reconstruction/nabu/check.py +9 -9
- tomwer/gui/reconstruction/nabu/helical.py +29 -12
- tomwer/gui/reconstruction/nabu/nabuconfig/base.py +2 -4
- tomwer/gui/reconstruction/nabu/nabuconfig/nabuconfig.py +2 -1
- tomwer/gui/reconstruction/nabu/nabuconfig/output.py +126 -35
- tomwer/gui/reconstruction/nabu/nabuconfig/phase.py +39 -32
- tomwer/gui/reconstruction/nabu/nabuconfig/preprocessing.py +222 -31
- tomwer/gui/reconstruction/nabu/nabuconfig/reconstruction.py +57 -27
- tomwer/gui/reconstruction/nabu/nabuflow.py +12 -20
- tomwer/gui/reconstruction/nabu/slices.py +10 -11
- tomwer/gui/reconstruction/nabu/volume.py +22 -10
- tomwer/gui/reconstruction/normalization/intensity.py +18 -48
- tomwer/gui/reconstruction/saaxis/corrangeselector.py +8 -24
- tomwer/gui/reconstruction/saaxis/dimensionwidget.py +1 -1
- tomwer/gui/reconstruction/saaxis/saaxis.py +9 -21
- tomwer/gui/reconstruction/sadeltabeta/saadeltabeta.py +45 -12
- tomwer/gui/reconstruction/scores/control.py +2 -9
- tomwer/gui/reconstruction/scores/scoreplot.py +13 -11
- tomwer/gui/reconstruction/test/test_axis.py +41 -16
- tomwer/gui/reconstruction/test/test_nabu.py +31 -9
- tomwer/gui/reconstruction/test/test_saaxis.py +3 -3
- tomwer/gui/reconstruction/test/test_sadeltabeta.py +12 -2
- tomwer/gui/settings.py +5 -28
- tomwer/gui/stackplot.py +2 -5
- tomwer/gui/stitching/action.py +49 -0
- tomwer/gui/stitching/config/axisparams.py +7 -24
- tomwer/gui/stitching/config/output.py +10 -8
- tomwer/gui/stitching/config/positionoveraxis.py +22 -23
- tomwer/gui/stitching/normalization.py +117 -0
- tomwer/gui/stitching/stitchandbackground.py +4 -6
- tomwer/gui/stitching/stitching.py +267 -45
- tomwer/gui/stitching/stitching_preview.py +62 -55
- tomwer/gui/stitching/stitching_raw.py +13 -12
- tomwer/gui/stitching/z_stitching/fineestimation.py +0 -60
- tomwer/gui/utils/buttons.py +112 -29
- tomwer/gui/utils/inputwidget.py +43 -25
- tomwer/gui/utils/lineselector/lineselector.py +1 -1
- tomwer/gui/utils/scandescription.py +4 -0
- tomwer/gui/utils/step.py +144 -0
- tomwer/gui/utils/unitsystem.py +2 -5
- tomwer/gui/utils/vignettes.py +176 -15
- tomwer/gui/visualization/dataviewer.py +48 -35
- tomwer/gui/visualization/diffviewer/diffviewer.py +7 -16
- tomwer/gui/visualization/diffviewer/shiftwidget.py +2 -5
- tomwer/gui/visualization/scanoverview.py +1 -1
- tomwer/gui/visualization/sinogramviewer.py +20 -36
- tomwer/gui/visualization/test/test_diffviewer.py +3 -3
- tomwer/gui/visualization/test/test_nx_tomo_metadata_viewer.py +4 -4
- tomwer/gui/visualization/test/test_sinogramviewer.py +2 -2
- tomwer/gui/visualization/test/test_stacks.py +3 -3
- tomwer/gui/visualization/test/test_volumeviewer.py +65 -67
- tomwer/gui/visualization/volumeviewer.py +114 -113
- tomwer/io/utils/h5pyutils.py +3 -3
- tomwer/io/utils/raw_and_processed_data.py +84 -0
- tomwer/io/utils/tomoobj.py +4 -6
- tomwer/io/utils/utils.py +7 -7
- tomwer/resources/gui/icons/parameters.svg +1 -1
- tomwer/resources/gui/icons/ruler.png +0 -0
- tomwer/resources/gui/icons/ruler.svg +273 -0
- tomwer/resources/gui/icons/short_description.png +0 -0
- tomwer/resources/gui/icons/short_description.svg +58 -0
- tomwer/resources/gui/icons/url.png +0 -0
- tomwer/resources/gui/icons/url.svg +58 -0
- tomwer/resources/gui/illustrations/no_rot.svg +1 -1
- tomwer/synctools/stacks/edit/darkflatpatch.py +19 -14
- tomwer/synctools/stacks/edit/imagekeyeditor.py +2 -2
- tomwer/synctools/stacks/reconstruction/axis.py +4 -4
- tomwer/synctools/stacks/reconstruction/castvolume.py +22 -7
- tomwer/synctools/stacks/reconstruction/dkrefcopy.py +25 -20
- tomwer/synctools/stacks/reconstruction/nabu.py +2 -2
- tomwer/synctools/stacks/reconstruction/normalization.py +2 -2
- tomwer/synctools/stacks/reconstruction/saaxis.py +2 -2
- tomwer/synctools/stacks/reconstruction/sadeltabeta.py +2 -2
- tomwer/synctools/test/test_darkRefs.py +7 -58
- tomwer/synctools/test/test_foldertransfer.py +6 -6
- tomwer/synctools/utils/scanstages.py +6 -6
- tomwer/tests/conftest.py +34 -0
- tomwer/tests/datasets.py +13 -0
- tomwer/tests/test_scripts.py +91 -41
- tomwer/tests/utils.py +5 -0
- tomwer/third_part/WaitingOverlay.py +110 -0
- tomwer/third_part/__init__.py +0 -0
- tomwer/version.py +2 -2
- tomwer-1.3.12-py3.11-nspkg.pth +1 -0
- {tomwer-1.2.1.dist-info → tomwer-1.3.12.dist-info}/METADATA +73 -58
- {tomwer-1.2.1.dist-info → tomwer-1.3.12.dist-info}/RECORD +287 -286
- {tomwer-1.2.1.dist-info → tomwer-1.3.12.dist-info}/WHEEL +1 -1
- orangecontrib/tomwer/widgets/reconstruction/TofuOW.py +0 -197
- orangecontrib/tomwer/widgets/reconstruction/icons/XY_lamino.svg +0 -168
- orangecontrib/tomwer/widgets/reconstruction/icons/XZ_lamino.svg +0 -275
- orangecontrib/tomwer/widgets/reconstruction/icons/YZ_lamino.svg +0 -182
- tomwer/app/lamino.py +0 -143
- tomwer/core/process/reconstruction/lamino/__init__.py +0 -1
- tomwer/core/process/reconstruction/lamino/tofu.py +0 -1000
- tomwer/core/process/test/test_lamino.py +0 -76
- tomwer/core/test/test_lamino.py +0 -92
- tomwer/gui/reconstruction/lamino/__init__.py +0 -31
- tomwer/gui/reconstruction/lamino/tofu/TofuOptionLoader.py +0 -107
- tomwer/gui/reconstruction/lamino/tofu/__init__.py +0 -1
- tomwer/gui/reconstruction/lamino/tofu/misc.py +0 -148
- tomwer/gui/reconstruction/lamino/tofu/projections.py +0 -896
- tomwer/gui/reconstruction/lamino/tofu/settings.py +0 -75
- tomwer/gui/reconstruction/lamino/tofu/tofu.py +0 -432
- tomwer/gui/reconstruction/lamino/tofu/tofuexpert.py +0 -567
- tomwer/gui/reconstruction/lamino/tofu/tofuoutput.py +0 -760
- tomwer/gui/reconstruction/test/test_lamino.py +0 -189
- tomwer/resources/gui/icons/esrf_1.svg +0 -307
- tomwer/resources/gui/icons/lamino_parameters.svg +0 -70
- tomwer/resources/gui/icons/triangle.svg +0 -80
- tomwer/resources/gui/illustrations/lamino_angle.png +0 -0
- tomwer/resources/gui/illustrations/lamino_angle.svg +0 -509
- tomwer/resources/gui/illustrations/lamino_beta_angle.png +0 -0
- tomwer/resources/gui/illustrations/lamino_beta_angle.svg +0 -97
- tomwer/resources/gui/illustrations/lamino_theta_angle.png +0 -0
- tomwer/resources/gui/illustrations/lamino_theta_angle.svg +0 -368
- tomwer/resources/gui/illustrations/manual_slice.png +0 -0
- tomwer/resources/gui/illustrations/manual_slice.svg +0 -221
- tomwer/resources/gui/illustrations/psi_angle.png +0 -0
- tomwer/resources/gui/illustrations/psi_angle.svg +0 -479
- tomwer/resources/gui/illustrations/rotation_center.png +0 -0
- tomwer/resources/gui/illustrations/rotation_center.svg +0 -276
- tomwer/resources/gui/illustrations/slice_stack.png +0 -0
- tomwer/resources/gui/illustrations/slice_stack.svg +0 -266
- tomwer/resources/gui/illustrations/xy_slice.png +0 -0
- tomwer/resources/gui/illustrations/xy_slice.svg +0 -269
- tomwer/resources/gui/illustrations/xz_slice.png +0 -0
- tomwer/resources/gui/illustrations/xz_slice.svg +0 -270
- tomwer/resources/gui/illustrations/yz_slice.png +0 -0
- tomwer/resources/gui/illustrations/yz_slice.svg +0 -270
- tomwer/synctools/stacks/reconstruction/lamino.py +0 -233
- tomwer/synctools/test/test_scanstages.py +0 -162
- tomwer/tests/utils/__init__.py +0 -247
- tomwer/tests/utils/utilstest.py +0 -220
- tomwer-1.2.1-py3.11-nspkg.pth +0 -1
- /tomwer/core/process/control/{email.py → emailnotifier.py} +0 -0
- {tomwer-1.2.1.dist-info → tomwer-1.3.12.dist-info}/LICENSE +0 -0
- {tomwer-1.2.1.dist-info → tomwer-1.3.12.dist-info}/entry_points.txt +0 -0
- {tomwer-1.2.1.dist-info → tomwer-1.3.12.dist-info}/namespace_packages.txt +0 -0
- {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.
|
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
|
-
|
211
|
-
|
212
|
-
|
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
|
-
|
316
|
-
|
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
|
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
|