tomwer 1.2.9__py3-none-any.whl → 1.3.0a0__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 +1 -0
- orangecontrib/tomwer/widgets/control/DataDiscoveryOW.py +2 -2
- orangecontrib/tomwer/widgets/control/DataListOW.py +9 -7
- orangecontrib/tomwer/widgets/control/DataSelectorOW.py +21 -10
- orangecontrib/tomwer/widgets/control/EDF2NXTomomillOW.py +11 -5
- orangecontrib/tomwer/widgets/control/EmailOW.py +4 -4
- orangecontrib/tomwer/widgets/control/NXTomomillOW.py +31 -18
- orangecontrib/tomwer/widgets/control/NXtomoConcatenate.py +14 -7
- orangecontrib/tomwer/widgets/control/NotifierOW.py +1 -0
- orangecontrib/tomwer/widgets/control/VolumeSelector.py +7 -4
- orangecontrib/tomwer/widgets/control/VolumeSymLinkOW.py +182 -182
- orangecontrib/tomwer/widgets/debugtools/DatasetGeneratorOW.py +4 -4
- orangecontrib/tomwer/widgets/edit/DarkFlatPatchOW.py +4 -4
- orangecontrib/tomwer/widgets/edit/ImageKeyEditorOW.py +3 -3
- orangecontrib/tomwer/widgets/edit/ImageKeyUpgraderOW.py +2 -0
- 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 +9 -8
- orangecontrib/tomwer/widgets/reconstruction/CastNabuVolumeOW.py +3 -3
- orangecontrib/tomwer/widgets/reconstruction/NabuHelicalPrepareWeightsDoubleOW.py +179 -169
- orangecontrib/tomwer/widgets/reconstruction/NabuOW.py +23 -0
- orangecontrib/tomwer/widgets/reconstruction/NabuVolumeOW.py +39 -5
- orangecontrib/tomwer/widgets/reconstruction/SAAxisOW.py +7 -13
- orangecontrib/tomwer/widgets/reconstruction/SADeltaBetaOW.py +7 -17
- orangecontrib/tomwer/widgets/reconstruction/SinoNormOW.py +3 -4
- orangecontrib/tomwer/widgets/visualization/LivesliceOW.py +1 -1
- orangecontrib/tomwer/widgets/visualization/NXtomoMetadataViewerOW.py +3 -3
- orangecontrib/tomwer/widgets/visualization/VolumeViewerOW.py +3 -29
- tomwer/__main__.py +11 -58
- tomwer/app/canvas.py +8 -0
- tomwer/app/canvas_launcher/config.py +13 -11
- tomwer/app/darkref.py +1 -1
- tomwer/app/darkrefpatch.py +1 -1
- tomwer/app/imagekeyeditor.py +5 -5
- tomwer/app/imagekeyupgrader.py +5 -5
- tomwer/app/intensitynormalization.py +2 -2
- tomwer/app/radiostack.py +2 -2
- tomwer/app/zstitching.py +74 -3
- 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 +3 -3
- tomwer/core/process/control/nxtomoconcatenate.py +13 -13
- tomwer/core/process/control/nxtomomill.py +83 -25
- tomwer/core/process/control/scantransfer.py +11 -10
- 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 +6 -6
- tomwer/core/process/edit/imagekeyeditor.py +17 -18
- 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 +26 -0
- tomwer/core/process/output.py +52 -0
- tomwer/core/process/reconstruction/axis/axis.py +17 -10
- tomwer/core/process/reconstruction/axis/mode.py +4 -0
- tomwer/core/process/reconstruction/axis/params.py +9 -4
- tomwer/core/process/reconstruction/darkref/darkrefs.py +8 -6
- tomwer/core/process/reconstruction/darkref/darkrefscopy.py +1 -1
- tomwer/core/process/reconstruction/darkref/params.py +1 -1
- tomwer/core/process/reconstruction/lamino/tofu.py +4 -4
- tomwer/core/process/reconstruction/nabu/castvolume.py +1 -1
- tomwer/core/process/reconstruction/nabu/helical.py +9 -5
- tomwer/core/process/reconstruction/nabu/nabucommon.py +32 -62
- tomwer/core/process/reconstruction/nabu/nabuscores.py +387 -61
- tomwer/core/process/reconstruction/nabu/nabuslices.py +33 -21
- tomwer/core/process/reconstruction/nabu/nabuvolume.py +37 -14
- tomwer/core/process/reconstruction/nabu/settings.py +2 -2
- tomwer/core/process/reconstruction/nabu/utils.py +129 -24
- tomwer/core/process/reconstruction/output.py +108 -0
- tomwer/core/process/reconstruction/saaxis/saaxis.py +233 -263
- tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py +140 -86
- tomwer/core/process/reconstruction/scores/params.py +4 -1
- 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 +3 -3
- 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 +2 -2
- tomwer/core/process/test/test_axis.py +6 -6
- tomwer/core/process/test/test_dark_and_flat.py +10 -7
- tomwer/core/process/test/test_data_transfer.py +7 -6
- tomwer/core/process/test/test_nabu.py +4 -4
- tomwer/core/process/test/test_normalization.py +2 -2
- tomwer/core/scan/edfscan.py +4 -1
- tomwer/core/scan/hdf5scan.py +19 -500
- tomwer/core/scan/nxtomoscan.py +532 -0
- tomwer/core/scan/scanbase.py +42 -20
- tomwer/core/scan/scanfactory.py +13 -13
- tomwer/core/scan/test/test_future_scan.py +2 -2
- tomwer/core/scan/test/test_h5.py +12 -10
- tomwer/core/scan/test/test_process_registration.py +2 -2
- tomwer/core/scan/test/test_scan.py +4 -3
- tomwer/core/settings.py +20 -0
- tomwer/core/test/test_scanutils.py +8 -7
- tomwer/core/test/test_utils.py +33 -26
- 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/volumefactory.py +2 -2
- tomwer/gui/cluster/slurm.py +260 -60
- tomwer/gui/cluster/test/test_cluster.py +13 -0
- tomwer/gui/cluster/test/test_supervisor.py +2 -2
- 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 +78 -16
- tomwer/gui/control/datalistener.py +4 -16
- 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 +1 -1
- 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 +2 -2
- tomwer/gui/control/tomoobjdisplaymode.py +8 -0
- tomwer/gui/debugtools/datasetgenerator.py +3 -3
- tomwer/gui/edit/dkrfpatch.py +16 -22
- tomwer/gui/edit/imagekeyeditor.py +8 -11
- tomwer/gui/edit/nxtomoeditor.py +111 -44
- tomwer/gui/edit/nxtomowarmer.py +4 -4
- tomwer/gui/edit/test/test_dkrf_patch.py +7 -7
- 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/reconstruction/axis/axis.py +171 -57
- tomwer/gui/reconstruction/axis/radioaxis.py +80 -95
- tomwer/gui/reconstruction/darkref/darkrefcopywidget.py +3 -2
- tomwer/gui/reconstruction/lamino/tofu/projections.py +1 -1
- tomwer/gui/reconstruction/lamino/tofu/tofuoutput.py +3 -6
- tomwer/gui/reconstruction/nabu/castvolume.py +1 -1
- 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/output.py +110 -33
- tomwer/gui/reconstruction/nabu/nabuconfig/phase.py +9 -12
- tomwer/gui/reconstruction/nabu/nabuconfig/preprocessing.py +219 -29
- tomwer/gui/reconstruction/nabu/nabuconfig/reconstruction.py +3 -6
- tomwer/gui/reconstruction/nabu/nabuflow.py +12 -20
- tomwer/gui/reconstruction/nabu/slices.py +6 -7
- tomwer/gui/reconstruction/nabu/volume.py +22 -10
- tomwer/gui/reconstruction/normalization/intensity.py +15 -23
- tomwer/gui/reconstruction/saaxis/corrangeselector.py +7 -23
- tomwer/gui/reconstruction/saaxis/dimensionwidget.py +1 -1
- tomwer/gui/reconstruction/saaxis/saaxis.py +7 -9
- tomwer/gui/reconstruction/sadeltabeta/saadeltabeta.py +2 -1
- tomwer/gui/reconstruction/scores/control.py +2 -9
- tomwer/gui/reconstruction/scores/scoreplot.py +11 -5
- tomwer/gui/reconstruction/test/test_axis.py +23 -12
- tomwer/gui/reconstruction/test/test_lamino.py +8 -3
- tomwer/gui/reconstruction/test/test_nabu.py +28 -9
- tomwer/gui/reconstruction/test/test_saaxis.py +3 -3
- tomwer/gui/reconstruction/test/test_sadeltabeta.py +2 -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 +265 -43
- tomwer/gui/stitching/stitching_preview.py +62 -5
- tomwer/gui/stitching/stitching_raw.py +2 -5
- tomwer/gui/stitching/z_stitching/fineestimation.py +0 -60
- tomwer/gui/utils/buttons.py +112 -29
- tomwer/gui/utils/inputwidget.py +33 -25
- 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 +1 -4
- 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 +1 -10
- 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 +2 -2
- tomwer/io/utils/raw_and_processed_data.py +84 -0
- tomwer/io/utils/tomoobj.py +4 -6
- 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/synctools/stacks/edit/darkflatpatch.py +2 -2
- tomwer/synctools/stacks/edit/imagekeyeditor.py +2 -2
- tomwer/synctools/stacks/reconstruction/axis.py +4 -4
- tomwer/synctools/stacks/reconstruction/castvolume.py +2 -2
- tomwer/synctools/stacks/reconstruction/dkrefcopy.py +4 -10
- 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 +92 -39
- tomwer/tests/utils.py +5 -0
- tomwer/version.py +3 -3
- {tomwer-1.2.9.dist-info → tomwer-1.3.0a0.dist-info}/METADATA +39 -39
- {tomwer-1.2.9.dist-info → tomwer-1.3.0a0.dist-info}/RECORD +248 -209
- tomwer/resources/gui/icons/esrf_1.svg +0 -307
- tomwer/resources/gui/icons/triangle.svg +0 -80
- tomwer/synctools/test/test_scanstages.py +0 -162
- tomwer/tests/utils/__init__.py +0 -247
- tomwer/tests/utils/utilstest.py +0 -220
- /tomwer/app/{saaxis.py → multicor.py} +0 -0
- /tomwer/app/{sadeltabeta.py → multipag.py} +0 -0
- /tomwer/core/process/control/{email.py → emailnotifier.py} +0 -0
- /tomwer-1.2.9-py3.11-nspkg.pth → /tomwer-1.3.0a0-py3.11-nspkg.pth +0 -0
- {tomwer-1.2.9.dist-info → tomwer-1.3.0a0.dist-info}/LICENSE +0 -0
- {tomwer-1.2.9.dist-info → tomwer-1.3.0a0.dist-info}/WHEEL +0 -0
- {tomwer-1.2.9.dist-info → tomwer-1.3.0a0.dist-info}/entry_points.txt +0 -0
- {tomwer-1.2.9.dist-info → tomwer-1.3.0a0.dist-info}/namespace_packages.txt +0 -0
- {tomwer-1.2.9.dist-info → tomwer-1.3.0a0.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,
|
@@ -50,12 +17,15 @@ else:
|
|
50
17
|
import logging
|
51
18
|
import os
|
52
19
|
from copy import deepcopy
|
20
|
+
import subprocess
|
53
21
|
from typing import Iterable, Optional, Union
|
54
22
|
|
55
23
|
from nabu.pipeline.fullfield.nabu_config import (
|
56
24
|
nabu_config as nabu_fullfield_default_config,
|
57
25
|
)
|
58
26
|
from processview.core.manager.manager import ProcessManager
|
27
|
+
from sluurp.job import SBatchScriptJob
|
28
|
+
from sluurp.executor import submit as submit_to_slurm_cluster
|
59
29
|
|
60
30
|
from tomwer.core.futureobject import FutureTomwerObject
|
61
31
|
from tomwer.core.process.reconstruction.nabu.nabuslices import (
|
@@ -63,15 +33,20 @@ from tomwer.core.process.reconstruction.nabu.nabuslices import (
|
|
63
33
|
_NabuBaseReconstructor,
|
64
34
|
generate_nabu_configfile,
|
65
35
|
)
|
36
|
+
from tomwer.core.process.reconstruction.nabu.utils import (
|
37
|
+
slice_index_to_int,
|
38
|
+
get_nabu_multicor_file_prefix,
|
39
|
+
)
|
66
40
|
from tomwer.core.process.reconstruction.nabu.target import Target
|
67
41
|
from tomwer.core.progress import Progress
|
68
42
|
from tomwer.core.scan.scanbase import TomwerScanBase
|
69
|
-
from tomwer.core.utils.slurm import is_slurm_available
|
43
|
+
from tomwer.core.utils.slurm import get_slurm_script_name, is_slurm_available
|
70
44
|
from tomwer.utils import docstring
|
45
|
+
from tomwer.core.process.reconstruction.nabu.utils import nabu_std_err_has_error
|
71
46
|
|
72
47
|
from ..nabu import settings as nabu_settings
|
73
|
-
from . import utils
|
74
|
-
from .nabucommon import ResultsLocalRun, ResultSlurmRun, ResultsWithStd
|
48
|
+
from . import utils, settings
|
49
|
+
from .nabucommon import ResultsLocalRun, ResultSlurmRun, ResultsWithStd, ResultsRun
|
75
50
|
|
76
51
|
_logger = logging.getLogger(__name__)
|
77
52
|
|
@@ -156,7 +131,7 @@ def run_nabu_one_slice_several_config(
|
|
156
131
|
std_outs.append(res.std_out)
|
157
132
|
std_errs.append(res.std_err)
|
158
133
|
if isinstance(res, ResultsLocalRun):
|
159
|
-
recons_urls[var_value] = res.
|
134
|
+
recons_urls[var_value] = res.results_identifiers
|
160
135
|
if isinstance(res, ResultSlurmRun):
|
161
136
|
future_tomo_obj = FutureTomwerObject(
|
162
137
|
tomo_obj=scan,
|
@@ -167,6 +142,77 @@ def run_nabu_one_slice_several_config(
|
|
167
142
|
return success, recons_urls, std_outs, std_errs, future_tomo_objs
|
168
143
|
|
169
144
|
|
145
|
+
def run_nabu_multicor(
|
146
|
+
scan: TomwerScanBase,
|
147
|
+
nabu_config: dict,
|
148
|
+
cors: tuple,
|
149
|
+
cluster_config: Optional[dict],
|
150
|
+
dry_run: bool,
|
151
|
+
slice_index: Union[int, str],
|
152
|
+
file_format: str,
|
153
|
+
process_id: Optional[int] = None,
|
154
|
+
instanciate_classes_only: bool = False,
|
155
|
+
output_file_prefix_pattern=None,
|
156
|
+
):
|
157
|
+
if cluster_config in (None, {}):
|
158
|
+
target = Target.LOCAL
|
159
|
+
elif isinstance(cluster_config, dict):
|
160
|
+
if not is_slurm_available():
|
161
|
+
raise RuntimeError("Slurm computation requested but unvailable")
|
162
|
+
target = Target.SLURM
|
163
|
+
else:
|
164
|
+
raise TypeError(
|
165
|
+
f"cluster_config should be None or a dict not {type(cluster_config)}"
|
166
|
+
)
|
167
|
+
|
168
|
+
if process_id is not None:
|
169
|
+
try:
|
170
|
+
process_name = ProcessManager().get_process(process_id=process_id).name
|
171
|
+
except KeyError:
|
172
|
+
process_name = "unknow"
|
173
|
+
else:
|
174
|
+
process_name = ""
|
175
|
+
|
176
|
+
reconstructor = _ReconstructorMultiCor(
|
177
|
+
scan=scan,
|
178
|
+
nabu_config=nabu_config,
|
179
|
+
cors=cors,
|
180
|
+
slice_index=slice_index,
|
181
|
+
target=target,
|
182
|
+
dry_run=dry_run,
|
183
|
+
file_format=file_format,
|
184
|
+
cluster_config=cluster_config,
|
185
|
+
process_name=process_name,
|
186
|
+
output_file_prefix_pattern=output_file_prefix_pattern,
|
187
|
+
)
|
188
|
+
if instanciate_classes_only:
|
189
|
+
return reconstructor
|
190
|
+
|
191
|
+
try:
|
192
|
+
result = reconstructor.run()
|
193
|
+
except TimeoutError as e:
|
194
|
+
_logger.error(e)
|
195
|
+
return None
|
196
|
+
else:
|
197
|
+
recons_urls = {}
|
198
|
+
std_outs = []
|
199
|
+
std_errs = []
|
200
|
+
|
201
|
+
success = result.success
|
202
|
+
if isinstance(result, ResultsWithStd):
|
203
|
+
std_outs.append(result.std_out)
|
204
|
+
std_errs.append(result.std_err)
|
205
|
+
if isinstance(result, ResultsLocalRun):
|
206
|
+
recons_urls = result.results_identifiers
|
207
|
+
if isinstance(result, ResultSlurmRun):
|
208
|
+
future_tomo_obj = FutureTomwerObject(
|
209
|
+
tomo_obj=scan,
|
210
|
+
process_requester_id=process_id,
|
211
|
+
futures=result.future_slurm_jobs,
|
212
|
+
)
|
213
|
+
return success, recons_urls, (future_tomo_obj,), std_outs, std_errs
|
214
|
+
|
215
|
+
|
170
216
|
class _Reconstructor(_NabuBaseReconstructor):
|
171
217
|
def __init__(
|
172
218
|
self,
|
@@ -207,14 +253,9 @@ class _Reconstructor(_NabuBaseReconstructor):
|
|
207
253
|
|
208
254
|
@docstring(_NabuBaseReconstructor)
|
209
255
|
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
|
256
|
+
self.slice_index = slice_index_to_int(
|
257
|
+
slice_index=self.slice_index, scan=self.scan
|
258
|
+
)
|
218
259
|
|
219
260
|
results = {}
|
220
261
|
if self.advancement:
|
@@ -222,24 +263,11 @@ class _Reconstructor(_NabuBaseReconstructor):
|
|
222
263
|
for var_value, config in self.nabu_configs.items():
|
223
264
|
if self._cancelled:
|
224
265
|
break
|
225
|
-
|
226
|
-
# in 1.2 there is some strange pipes. But this is rework on the next version so just fixe pipelines in this version
|
227
|
-
if "nabu_params" in config:
|
228
|
-
nabu_config = deepcopy(config["nabu_params"])
|
229
|
-
nabu_config["output"].update(config["output"])
|
230
|
-
if "pipeline" not in nabu_config:
|
231
|
-
nabu_config["pipeline"] = {}
|
232
|
-
nabu_config["pipeline"].update(config.get("pipeline", {}))
|
233
|
-
nabu_config["reconstruction"].update(config.get("reconstruction", {}))
|
234
|
-
# end work around 1.2
|
235
|
-
else:
|
236
|
-
nabu_config = deepcopy(config)
|
237
|
-
|
238
|
-
nabu_config, conf_file = self.preprocess_config(nabu_config, var_value)
|
266
|
+
config, conf_file = self.preprocess_config(deepcopy(config), var_value)
|
239
267
|
|
240
268
|
# add some tomwer metadata and save the configuration
|
241
269
|
# note: for now the section is ignored by nabu but shouldn't stay that way
|
242
|
-
with utils.TomwerInfo(
|
270
|
+
with utils.TomwerInfo(config) as config_to_dump:
|
243
271
|
generate_nabu_configfile(
|
244
272
|
conf_file,
|
245
273
|
nabu_fullfield_default_config,
|
@@ -327,7 +355,7 @@ class _Reconstructor(_NabuBaseReconstructor):
|
|
327
355
|
_config["reconstruction"]["end_z"] = self.slice_index
|
328
356
|
return _config, file_prefix
|
329
357
|
|
330
|
-
def preprocess_config(self, config, value
|
358
|
+
def preprocess_config(self, config, value) -> tuple:
|
331
359
|
dataset_params = self.scan.get_nabu_dataset_info()
|
332
360
|
if "dataset" in config:
|
333
361
|
dataset_params.update(config["dataset"])
|
@@ -355,3 +383,301 @@ class _Reconstructor(_NabuBaseReconstructor):
|
|
355
383
|
cfg_folder, file_prefix + nabu_settings.NABU_CONFIG_FILE_EXTENSION
|
356
384
|
)
|
357
385
|
return config, conf_file
|
386
|
+
|
387
|
+
|
388
|
+
class _ReconstructorMultiCor(_NabuBaseReconstructor):
|
389
|
+
def __init__(
|
390
|
+
self,
|
391
|
+
nabu_config: dict,
|
392
|
+
cors: tuple,
|
393
|
+
file_format,
|
394
|
+
slice_index: Union[int, str] = "middle",
|
395
|
+
output_file_prefix_pattern=None,
|
396
|
+
*args,
|
397
|
+
**kwargs,
|
398
|
+
):
|
399
|
+
if not isinstance(cors, tuple):
|
400
|
+
raise TypeError(
|
401
|
+
f"cors are expected to be an instance of tuple. Get {type(cors)} instead"
|
402
|
+
)
|
403
|
+
self.__cors = cors
|
404
|
+
self.__slice_index = slice_index
|
405
|
+
self.__nabu_config = nabu_config
|
406
|
+
self.file_format = file_format
|
407
|
+
self._output_file_prefix_pattern = output_file_prefix_pattern
|
408
|
+
|
409
|
+
super().__init__(*args, **kwargs)
|
410
|
+
|
411
|
+
@property
|
412
|
+
def cors(self) -> tuple:
|
413
|
+
return self.__cors
|
414
|
+
|
415
|
+
@property
|
416
|
+
def slice_index(self) -> Union[int, str]:
|
417
|
+
return self.__slice_index
|
418
|
+
|
419
|
+
@property
|
420
|
+
def nabu_config(self) -> dict:
|
421
|
+
return self.__nabu_config
|
422
|
+
|
423
|
+
def _process_config(
|
424
|
+
self,
|
425
|
+
config_to_dump: dict,
|
426
|
+
config_file: str,
|
427
|
+
file_format: str,
|
428
|
+
info: Optional[str],
|
429
|
+
process_name: str,
|
430
|
+
):
|
431
|
+
"""
|
432
|
+
process provided configuration
|
433
|
+
|
434
|
+
:param str info:
|
435
|
+
"""
|
436
|
+
if self.dry_run is True or self.only_create_config_file():
|
437
|
+
return ResultsRun(
|
438
|
+
success=True,
|
439
|
+
config=config_to_dump,
|
440
|
+
)
|
441
|
+
elif self.target is Target.LOCAL:
|
442
|
+
_logger.info(f"run {info} for {self.scan} with {config_to_dump}")
|
443
|
+
return self._run_nabu_multicor_locally(
|
444
|
+
conf_file=config_file,
|
445
|
+
file_format=file_format,
|
446
|
+
config_to_dump=config_to_dump,
|
447
|
+
)
|
448
|
+
elif self.target is Target.SLURM:
|
449
|
+
_logger.info(
|
450
|
+
f"run {info} on slurm for {self.scan.path} with {config_to_dump}"
|
451
|
+
)
|
452
|
+
return self._run_nabu_multicor_on_slurm(
|
453
|
+
conf_file=config_file,
|
454
|
+
config_to_dump=config_to_dump,
|
455
|
+
cluster_config=self.cluster_config.to_dict(),
|
456
|
+
process_name=process_name,
|
457
|
+
info=info,
|
458
|
+
)
|
459
|
+
else:
|
460
|
+
raise ValueError(f"{self.target} is not recognized as a valid target")
|
461
|
+
|
462
|
+
@staticmethod
|
463
|
+
def convert_cor_from_rel_to_abs(scan, cor):
|
464
|
+
if scan.dim_1 is not None:
|
465
|
+
return cor + scan.dim_1 / 2.0
|
466
|
+
else:
|
467
|
+
_logger.warning("enable to get image half width. Set it to 1024")
|
468
|
+
return cor + 1024
|
469
|
+
|
470
|
+
@staticmethod
|
471
|
+
def convert_cor_from_abs_to_rel(scan, cor):
|
472
|
+
if scan.dim_1 is not None:
|
473
|
+
return cor - scan.dim_1 / 2.0
|
474
|
+
else:
|
475
|
+
_logger.warning("enable to get image half width. Set it to 1024")
|
476
|
+
return cor - 1024
|
477
|
+
|
478
|
+
def _run_nabu_multicor_locally(
|
479
|
+
self,
|
480
|
+
conf_file: str,
|
481
|
+
file_format: str,
|
482
|
+
config_to_dump: dict,
|
483
|
+
) -> ResultsLocalRun:
|
484
|
+
"""
|
485
|
+
run locally nabu for a single configuration file.
|
486
|
+
|
487
|
+
:param str conf_file: path to the nabu .cfg file
|
488
|
+
:param str file_format: format of the generated file
|
489
|
+
:param dict config_to_dump: configuration saved in the .cfg as a dictionary
|
490
|
+
:return: results of the local run
|
491
|
+
:rtype: ResultsLocalRun
|
492
|
+
"""
|
493
|
+
if not has_nabu:
|
494
|
+
raise ImportError("Fail to import nabu")
|
495
|
+
slice_index = slice_index_to_int(self.slice_index, scan=self.scan)
|
496
|
+
|
497
|
+
cor_in_nabu_ref = tuple(
|
498
|
+
[self.convert_cor_from_rel_to_abs(self.scan, cor) for cor in self.cors]
|
499
|
+
)
|
500
|
+
cor_in_nabu_ref = ",".join([str(cor) for cor in cor_in_nabu_ref])
|
501
|
+
command = " ".join(
|
502
|
+
(
|
503
|
+
"python3",
|
504
|
+
"-m",
|
505
|
+
settings.NABU_MULTICOR_PATH,
|
506
|
+
conf_file, # input file
|
507
|
+
f"{slice_index}", # slice
|
508
|
+
f"{cor_in_nabu_ref}", # cor
|
509
|
+
)
|
510
|
+
)
|
511
|
+
_logger.info(f'call nabu from "{command}"')
|
512
|
+
|
513
|
+
self._process = subprocess.Popen(
|
514
|
+
command,
|
515
|
+
shell=True,
|
516
|
+
cwd=self.scan.path,
|
517
|
+
stdout=subprocess.PIPE,
|
518
|
+
stderr=subprocess.PIPE,
|
519
|
+
)
|
520
|
+
try:
|
521
|
+
outs, errs = self._process.communicate()
|
522
|
+
except (TimeoutError, KeyboardInterrupt):
|
523
|
+
self._process.kill()
|
524
|
+
outs, errs = self._process.communicate()
|
525
|
+
|
526
|
+
file_prefix = get_nabu_multicor_file_prefix(self.scan)
|
527
|
+
|
528
|
+
recons_vol_identifiers = utils.get_multi_cor_recons_volume_identifiers(
|
529
|
+
slice_index=slice_index,
|
530
|
+
location=config_to_dump["output"]["location"],
|
531
|
+
file_prefix=file_prefix,
|
532
|
+
scan=self.scan,
|
533
|
+
file_format=file_format,
|
534
|
+
cors=[
|
535
|
+
self.convert_cor_from_rel_to_abs(self.scan, cor) for cor in self.cors
|
536
|
+
],
|
537
|
+
)
|
538
|
+
# convert back from abs ref to rel ref
|
539
|
+
recons_vol_identifiers = {
|
540
|
+
self.convert_cor_from_abs_to_rel(self.scan, cor): identifiers
|
541
|
+
for cor, identifiers in recons_vol_identifiers.items()
|
542
|
+
}
|
543
|
+
return ResultsLocalRun(
|
544
|
+
success=not nabu_std_err_has_error(errs),
|
545
|
+
results_identifiers=recons_vol_identifiers,
|
546
|
+
std_out=outs,
|
547
|
+
std_err=errs,
|
548
|
+
config=config_to_dump, # config_slices,
|
549
|
+
)
|
550
|
+
|
551
|
+
def _run_nabu_multicor_on_slurm(
|
552
|
+
self,
|
553
|
+
conf_file: str,
|
554
|
+
config_to_dump: dict,
|
555
|
+
cluster_config: dict,
|
556
|
+
process_name: str,
|
557
|
+
info: str,
|
558
|
+
) -> ResultSlurmRun:
|
559
|
+
"""
|
560
|
+
Run a nabu reconstruction on slurm of a single configuration
|
561
|
+
|
562
|
+
:return: results of the slurm run
|
563
|
+
:rtype: ResultSlurmRun
|
564
|
+
"""
|
565
|
+
if not isinstance(conf_file, str):
|
566
|
+
raise TypeError(f"conf_file is expected to be a strg not {type(conf_file)}")
|
567
|
+
if not isinstance(config_to_dump, dict):
|
568
|
+
raise TypeError(
|
569
|
+
f"config_to_dump is expected to be a strg not {type(config_to_dump)}"
|
570
|
+
)
|
571
|
+
if not is_slurm_available():
|
572
|
+
raise RuntimeError("slurm not available")
|
573
|
+
if not isinstance(cluster_config, dict):
|
574
|
+
raise ValueError(
|
575
|
+
f"cluster config is expected to be a dict not {type(cluster_config)}"
|
576
|
+
)
|
577
|
+
|
578
|
+
# create slurm cluster
|
579
|
+
project_name = cluster_config.get(
|
580
|
+
"job_name", "tomwer_{scan}_-_{process}_-_{info}"
|
581
|
+
)
|
582
|
+
project_name = project_name.format(
|
583
|
+
scan=str(self.scan), process=process_name, info=info
|
584
|
+
)
|
585
|
+
# project name should not contain any spaces as it will be integrated in a script and interpreted.
|
586
|
+
project_name = project_name.replace(" ", "_")
|
587
|
+
cluster_config["job_name"] = project_name
|
588
|
+
|
589
|
+
slice_index = slice_index_to_int(self.slice_index, scan=self.scan)
|
590
|
+
cor_in_nabu_ref = tuple(
|
591
|
+
[self.convert_cor_from_rel_to_abs(self.scan, cor) for cor in self.cors]
|
592
|
+
)
|
593
|
+
cor_in_nabu_ref = ",".join([str(cor) for cor in cor_in_nabu_ref])
|
594
|
+
|
595
|
+
# submit job
|
596
|
+
script_name = get_slurm_script_name(prefix="nabu")
|
597
|
+
# for now force job name
|
598
|
+
cluster_config["job_name"] = f"tomwer-nabu {conf_file}"
|
599
|
+
job = SBatchScriptJob(
|
600
|
+
slurm_config=cluster_config,
|
601
|
+
script=(
|
602
|
+
f"python3 -m {settings.NABU_MULTICOR_PATH} {conf_file} {slice_index} {cor_in_nabu_ref}",
|
603
|
+
),
|
604
|
+
script_path=os.path.join(self.scan.path, "slurm_scripts", script_name),
|
605
|
+
clean_script=False,
|
606
|
+
working_directory=self.scan.working_directory,
|
607
|
+
)
|
608
|
+
future_slurm_job = submit_to_slurm_cluster(job)
|
609
|
+
|
610
|
+
callbacks = self._get_futures_slurm_callback(config_to_dump)
|
611
|
+
assert isinstance(
|
612
|
+
callbacks, tuple
|
613
|
+
), f"callbacks is expected to an instance of tuple and not {type(callbacks)}"
|
614
|
+
for callback in callbacks:
|
615
|
+
future_slurm_job.add_done_callback(callback.process)
|
616
|
+
|
617
|
+
return ResultSlurmRun(
|
618
|
+
success=True,
|
619
|
+
config=config_to_dump,
|
620
|
+
future_slurm_jobs=(future_slurm_job,),
|
621
|
+
std_out=None,
|
622
|
+
std_err=None,
|
623
|
+
job_id=job.job_id,
|
624
|
+
)
|
625
|
+
|
626
|
+
def preprocess_config(self, config):
|
627
|
+
dataset_params = self.scan.get_nabu_dataset_info()
|
628
|
+
if "dataset" in config:
|
629
|
+
dataset_params.update(config["dataset"])
|
630
|
+
config["dataset"] = dataset_params
|
631
|
+
|
632
|
+
config["resources"] = utils.get_nabu_resources_desc(
|
633
|
+
scan=self.scan, workers=1, method="local"
|
634
|
+
)
|
635
|
+
# force overwrite results
|
636
|
+
if "output" not in config:
|
637
|
+
config["output"] = {}
|
638
|
+
config["output"].update({"overwrite_results": 1})
|
639
|
+
|
640
|
+
cfg_folder = os.path.join(
|
641
|
+
config["output"]["location"],
|
642
|
+
nabu_settings.NABU_CFG_FILE_FOLDER,
|
643
|
+
)
|
644
|
+
os.makedirs(cfg_folder, exist_ok=True)
|
645
|
+
|
646
|
+
cfg_folder = os.path.join(
|
647
|
+
self.nabu_config["output"]["location"],
|
648
|
+
nabu_settings.NABU_CFG_FILE_FOLDER,
|
649
|
+
)
|
650
|
+
os.makedirs(cfg_folder, exist_ok=True)
|
651
|
+
|
652
|
+
conf_file = os.path.join(
|
653
|
+
cfg_folder,
|
654
|
+
f"{self.scan.get_dataset_basename()}_multi_cor"
|
655
|
+
+ nabu_settings.NABU_CONFIG_FILE_EXTENSION,
|
656
|
+
)
|
657
|
+
return config, conf_file
|
658
|
+
|
659
|
+
def run(self) -> Iterable:
|
660
|
+
nabu_config, conf_file = self.preprocess_config(deepcopy(self.nabu_config))
|
661
|
+
|
662
|
+
# the policy is to save nabu .cfg file at the same location as the
|
663
|
+
# force overwrite results
|
664
|
+
|
665
|
+
# add some tomwer metadata and save the configuration
|
666
|
+
# note: for now the section is ignored by nabu but shouldn't stay that way
|
667
|
+
with utils.TomwerInfo(nabu_config) as config_to_dump:
|
668
|
+
generate_nabu_configfile(
|
669
|
+
conf_file,
|
670
|
+
nabu_fullfield_default_config,
|
671
|
+
config=config_to_dump,
|
672
|
+
options_level="advanced",
|
673
|
+
)
|
674
|
+
|
675
|
+
results = self._process_config(
|
676
|
+
config_to_dump=nabu_config,
|
677
|
+
config_file=conf_file,
|
678
|
+
file_format=self.file_format,
|
679
|
+
info="nabu sa-axis reconstruction",
|
680
|
+
process_name=self.process_name,
|
681
|
+
)
|
682
|
+
|
683
|
+
return results
|
@@ -41,6 +41,12 @@ from processview.core.manager.manager import ProcessManager, DatasetState
|
|
41
41
|
from tomwer.core.futureobject import FutureTomwerObject
|
42
42
|
from tomwer.core.utils.scanutils import data_identifier_to_scan
|
43
43
|
from tomwer.core.utils.slurm import is_slurm_available
|
44
|
+
from tomwer.core.process.reconstruction.nabu.utils import slice_index_to_int
|
45
|
+
from tomwer.core.process.icat.gallery import (
|
46
|
+
IcatScreenshots,
|
47
|
+
deduce_dataset_gallery_location,
|
48
|
+
)
|
49
|
+
from tomwer.core.volume.volumefactory import VolumeFactory
|
44
50
|
|
45
51
|
try:
|
46
52
|
from nabu.pipeline.fullfield.reconstruction import ( # noqa F401
|
@@ -81,7 +87,7 @@ from tomoscan.io import HDF5File
|
|
81
87
|
|
82
88
|
from tomwer.core.process.task import Task
|
83
89
|
from tomwer.core.scan.edfscan import EDFTomoScan
|
84
|
-
from tomwer.core.scan.
|
90
|
+
from tomwer.core.scan.nxtomoscan import NXtomoScan
|
85
91
|
from tomwer.core.scan.scanbase import TomwerScanBase
|
86
92
|
from tomwer.core.scan.scanfactory import ScanFactory
|
87
93
|
from tomwer.io.utils.h5pyutils import EntryReader
|
@@ -210,7 +216,7 @@ def run_slices_reconstruction(
|
|
210
216
|
assert not is_cluster_job, "cluster job should not return ResultsLocalRun"
|
211
217
|
stderrs.append(result.std_err)
|
212
218
|
stdouts.append(result.std_out)
|
213
|
-
output_urls.extend(result.
|
219
|
+
output_urls.extend(result.results_identifiers)
|
214
220
|
# if slice_index is None this mean that we are simply creating the
|
215
221
|
# .cfg file for nabu full volume.
|
216
222
|
elif isinstance(result, ResultSlurmRun):
|
@@ -263,11 +269,7 @@ class NabuSlicesTask(
|
|
263
269
|
"dry_run",
|
264
270
|
"serialize_output_data",
|
265
271
|
),
|
266
|
-
output_names=(
|
267
|
-
"data",
|
268
|
-
"nabu_params",
|
269
|
-
"future_tomo_obj",
|
270
|
-
),
|
272
|
+
output_names=("data", "nabu_params", "future_tomo_obj", "screenshots"),
|
271
273
|
):
|
272
274
|
"""
|
273
275
|
Definition of the nabu reconstruction volume reconstruction process
|
@@ -313,7 +315,7 @@ class NabuSlicesTask(
|
|
313
315
|
assert isinstance(configuration, dict), "configuration is expected to be a dict"
|
314
316
|
|
315
317
|
entry = "entry"
|
316
|
-
if isinstance(scan,
|
318
|
+
if isinstance(scan, NXtomoScan):
|
317
319
|
entry = scan.entry
|
318
320
|
|
319
321
|
output_urls = []
|
@@ -358,7 +360,7 @@ class NabuSlicesTask(
|
|
358
360
|
), "cluster job should not return ResultsLocalRun"
|
359
361
|
stderrs.append(result.std_err)
|
360
362
|
stdouts.append(result.std_out)
|
361
|
-
output_urls.extend(result.
|
363
|
+
output_urls.extend(result.results_identifiers)
|
362
364
|
# if slice_index is None this mean that we are simply creating the
|
363
365
|
# .cfg file for nabu full volume.
|
364
366
|
elif isinstance(result, ResultSlurmRun):
|
@@ -392,6 +394,21 @@ class NabuSlicesTask(
|
|
392
394
|
scan.set_latest_reconstructions(output_urls)
|
393
395
|
future_tomo_obj = None
|
394
396
|
|
397
|
+
volume_urls = []
|
398
|
+
for rec_identifier in scan.latest_reconstructions:
|
399
|
+
volume_urls.extend(
|
400
|
+
VolumeFactory.from_identifier_to_vol_urls(rec_identifier)
|
401
|
+
)
|
402
|
+
|
403
|
+
self.outputs.screenshots = IcatScreenshots(
|
404
|
+
data_dir=deduce_dataset_gallery_location(scan),
|
405
|
+
screenshots={
|
406
|
+
os.path.splitext(os.path.basename(url.file_path()))[0]: url
|
407
|
+
for url in volume_urls
|
408
|
+
},
|
409
|
+
scan=scan,
|
410
|
+
)
|
411
|
+
|
395
412
|
process_index = scan.pop_process_index()
|
396
413
|
# update processes information / registration
|
397
414
|
gc.collect()
|
@@ -668,12 +685,9 @@ class SingleSliceRunner(_NabuBaseReconstructor):
|
|
668
685
|
:raise: TIMEOUT_SLURM_JOB_SUBMISSION if not all workers spwan
|
669
686
|
"""
|
670
687
|
if isinstance(self.slice_index, str):
|
671
|
-
|
672
|
-
self.
|
673
|
-
|
674
|
-
raise ValueError(
|
675
|
-
f"slice index is expected to an int or 'middle' and not {type(self.slice_index)}"
|
676
|
-
)
|
688
|
+
self._slice_index = slice_index_to_int(
|
689
|
+
slice_index=self.slice_index, scan=self.scan
|
690
|
+
)
|
677
691
|
elif (
|
678
692
|
isinstance(self.slice_index, float)
|
679
693
|
and int(self.slice_index) == self.slice_index
|
@@ -784,9 +798,6 @@ class SingleSliceRunner(_NabuBaseReconstructor):
|
|
784
798
|
file_format=file_format,
|
785
799
|
scan=self.scan,
|
786
800
|
slice_index=None,
|
787
|
-
start_z=None,
|
788
|
-
end_z=None,
|
789
|
-
expects_single_slice=True,
|
790
801
|
)
|
791
802
|
|
792
803
|
return (CallBack(callback, self.scan),)
|
@@ -799,10 +810,11 @@ class SingleSliceRunner(_NabuBaseReconstructor):
|
|
799
810
|
):
|
800
811
|
if pag:
|
801
812
|
assert db is not None, "if paganin defined, db should not be None"
|
802
|
-
if slice_index
|
803
|
-
slice_index = scan
|
813
|
+
if slice_index is not None:
|
814
|
+
slice_index = slice_index_to_int(slice_index, scan=scan)
|
815
|
+
|
804
816
|
assert type(db) in (int, type(None))
|
805
|
-
if isinstance(scan,
|
817
|
+
if isinstance(scan, NXtomoScan):
|
806
818
|
basename, _ = os.path.splitext(scan.master_file)
|
807
819
|
basename = os.path.basename(basename)
|
808
820
|
try:
|