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
@@ -43,21 +43,27 @@ from processview.core.manager.manager import ProcessManager, DatasetState
|
|
43
43
|
from processview.core.superviseprocess import SuperviseProcess
|
44
44
|
|
45
45
|
from silx.io.utils import h5py_read_dataset
|
46
|
-
from
|
46
|
+
from tomwer.core.utils.deprecation import deprecated_warning
|
47
47
|
|
48
48
|
from tomoscan.io import HDF5File
|
49
49
|
|
50
50
|
from tomwer.core.cluster.cluster import SlurmClusterConfiguration
|
51
51
|
from tomwer.core.futureobject import FutureTomwerObject
|
52
52
|
from tomwer.core.process.task import Task
|
53
|
+
from tomwer.core.process.icat.gallery import (
|
54
|
+
IcatScreenshots,
|
55
|
+
deduce_dataset_gallery_location,
|
56
|
+
select_screenshot_from_volume,
|
57
|
+
)
|
53
58
|
from tomwer.core.scan.edfscan import EDFTomoScan
|
54
|
-
from tomwer.core.scan.
|
59
|
+
from tomwer.core.scan.nxtomoscan import NXtomoScan
|
55
60
|
from tomwer.core.scan.scanbase import TomwerScanBase
|
56
61
|
from tomwer.core.scan.scanfactory import ScanFactory
|
62
|
+
from tomwer.core.utils.dictutils import concatenate_dict
|
57
63
|
from tomwer.core.utils.scanutils import data_identifier_to_scan
|
64
|
+
from tomwer.core.volume.volumefactory import VolumeFactory
|
58
65
|
from tomwer.io.utils.h5pyutils import EntryReader
|
59
66
|
from tomwer.utils import docstring
|
60
|
-
from tomwer.core.utils import concatenate_dict
|
61
67
|
from tomwer.io.utils import format_stderr_stdout
|
62
68
|
|
63
69
|
from . import settings, utils
|
@@ -143,8 +149,8 @@ def run_volume_reconstruction(
|
|
143
149
|
assert len(results) == 1, "only one volume should be reconstructed"
|
144
150
|
res = results[0]
|
145
151
|
# tag latest reconstructions
|
146
|
-
if isinstance(res, ResultsLocalRun) and res.
|
147
|
-
scan.set_latest_vol_reconstructions(res.
|
152
|
+
if isinstance(res, ResultsLocalRun) and res.results_identifiers is not None:
|
153
|
+
scan.set_latest_vol_reconstructions(res.results_identifiers)
|
148
154
|
# create future if needed
|
149
155
|
if isinstance(res, ResultSlurmRun):
|
150
156
|
future_tomo_obj = FutureTomwerObject(
|
@@ -292,8 +298,8 @@ class VolumeRunner(_NabuBaseReconstructor):
|
|
292
298
|
def process(self, fn):
|
293
299
|
if fn.done() and not (fn.cancelled() or fn.exception()):
|
294
300
|
# update reconstruction urls only if processing succeed.
|
295
|
-
|
296
|
-
self.scan.add_latest_vol_reconstructions(
|
301
|
+
recons_identifiers = self.f_partial()
|
302
|
+
self.scan.add_latest_vol_reconstructions(recons_identifiers)
|
297
303
|
|
298
304
|
file_format = config_to_dump["output"]["file_format"]
|
299
305
|
callback = functools.partial(
|
@@ -303,9 +309,6 @@ class VolumeRunner(_NabuBaseReconstructor):
|
|
303
309
|
file_format=file_format,
|
304
310
|
scan=self.scan,
|
305
311
|
slice_index=None,
|
306
|
-
start_z=config_to_dump["reconstruction"]["start_z"],
|
307
|
-
end_z=config_to_dump["reconstruction"]["end_z"],
|
308
|
-
expects_single_slice=False,
|
309
312
|
)
|
310
313
|
|
311
314
|
return (CallBack(callback, self.scan),)
|
@@ -346,7 +349,7 @@ class VolumeRunner(_NabuBaseReconstructor):
|
|
346
349
|
"""
|
347
350
|
assert type(db) in (int, type(None))
|
348
351
|
assert not pag == ctf == True, "cannot ask for both pag and ctf active"
|
349
|
-
if isinstance(self.scan,
|
352
|
+
if isinstance(self.scan, NXtomoScan):
|
350
353
|
basename, _ = os.path.splitext(self.scan.master_file)
|
351
354
|
basename = os.path.basename(basename)
|
352
355
|
try:
|
@@ -371,7 +374,7 @@ class NabuVolumeTask(
|
|
371
374
|
Task,
|
372
375
|
SuperviseProcess,
|
373
376
|
input_names=("data", "nabu_params"),
|
374
|
-
output_names=("data", "volumes", "future_tomo_obj"),
|
377
|
+
output_names=("data", "volumes", "future_tomo_obj", "screenshots"),
|
375
378
|
optional_input_names=(
|
376
379
|
"dry_run",
|
377
380
|
"nabu_extra_params", # some parameter that must update 'nabu_params' before launching the reconstruction. Such as z range...
|
@@ -462,8 +465,8 @@ class NabuVolumeTask(
|
|
462
465
|
future_tomo_obj = None
|
463
466
|
else:
|
464
467
|
# tag latest reconstructions
|
465
|
-
if isinstance(res, ResultsLocalRun) and res.
|
466
|
-
scan.set_latest_vol_reconstructions(res.
|
468
|
+
if isinstance(res, ResultsLocalRun) and res.results_identifiers is not None:
|
469
|
+
scan.set_latest_vol_reconstructions(res.results_identifiers)
|
467
470
|
# create future if needed
|
468
471
|
if isinstance(res, ResultSlurmRun):
|
469
472
|
future_tomo_obj = FutureTomwerObject(
|
@@ -527,6 +530,26 @@ class NabuVolumeTask(
|
|
527
530
|
self.outputs.volumes = scan.latest_vol_reconstructions
|
528
531
|
self.outputs.future_tomo_obj = future_tomo_obj
|
529
532
|
|
533
|
+
# build screenshots
|
534
|
+
try:
|
535
|
+
screenshots = {}
|
536
|
+
[
|
537
|
+
screenshots.update(
|
538
|
+
select_screenshot_from_volume(
|
539
|
+
VolumeFactory.create_tomo_object_from_identifier(rec_identifier)
|
540
|
+
)
|
541
|
+
)
|
542
|
+
for rec_identifier in scan.latest_vol_reconstructions
|
543
|
+
]
|
544
|
+
except Exception as e:
|
545
|
+
_logger.error(f"screenshot creation failed. Error is {e}")
|
546
|
+
else:
|
547
|
+
self.outputs.screenshots = IcatScreenshots(
|
548
|
+
data_dir=deduce_dataset_gallery_location(scan),
|
549
|
+
screenshots=screenshots,
|
550
|
+
scan=scan,
|
551
|
+
)
|
552
|
+
|
530
553
|
def set_configuration(self, configuration: dict) -> None:
|
531
554
|
Task.set_configuration(self, configuration=configuration)
|
532
555
|
if "dry_run" in configuration:
|
@@ -33,8 +33,6 @@ import logging
|
|
33
33
|
_logger = logging.getLogger(__name__)
|
34
34
|
|
35
35
|
|
36
|
-
NABU_FILE_PER_GROUP = 100
|
37
|
-
|
38
36
|
NABU_CONFIG_FILE_EXTENSION = ".cfg"
|
39
37
|
|
40
38
|
NABU_CFG_FILE_FOLDER = "nabu_cfg_files"
|
@@ -60,3 +58,5 @@ else:
|
|
60
58
|
|
61
59
|
|
62
60
|
NABU_CAST_APP_PATH = "nabu.app.cast_volume"
|
61
|
+
|
62
|
+
NABU_MULTICOR_PATH = "nabu.app.multicor"
|
@@ -42,7 +42,7 @@ from silx.utils.enum import Enum as _Enum
|
|
42
42
|
|
43
43
|
import tomwer.version
|
44
44
|
from tomwer.core.scan.edfscan import EDFTomoScan
|
45
|
-
from tomwer.core.scan.
|
45
|
+
from tomwer.core.scan.nxtomoscan import NXtomoScan
|
46
46
|
from tomwer.core.scan.scanbase import TomwerScanBase
|
47
47
|
from tomwer.core.volume.edfvolume import EDFVolume
|
48
48
|
from tomwer.core.volume.hdf5volume import HDF5Volume
|
@@ -148,9 +148,6 @@ def get_recons_volume_identifier(
|
|
148
148
|
file_format: str,
|
149
149
|
scan: TomwerScanBase,
|
150
150
|
slice_index: typing.Union[int, None],
|
151
|
-
start_z: typing.Union[int, None],
|
152
|
-
end_z: typing.Union[int, None],
|
153
|
-
expects_single_slice: bool,
|
154
151
|
) -> tuple:
|
155
152
|
"""
|
156
153
|
return tuple of DataUrl for existings slices
|
@@ -165,7 +162,7 @@ def get_recons_volume_identifier(
|
|
165
162
|
file_name = ".".join((file_name, file_format))
|
166
163
|
file_path = os.path.join(location, file_name)
|
167
164
|
|
168
|
-
if isinstance(scan,
|
165
|
+
if isinstance(scan, NXtomoScan):
|
169
166
|
entry = scan.entry
|
170
167
|
elif isinstance(scan, EDFTomoScan):
|
171
168
|
entry = "entry"
|
@@ -223,6 +220,75 @@ def get_recons_volume_identifier(
|
|
223
220
|
return tuple([volume.get_identifier() for volume in volumes])
|
224
221
|
|
225
222
|
|
223
|
+
def get_multi_cor_recons_volume_identifiers(
|
224
|
+
scan: TomwerScanBase,
|
225
|
+
slice_index: int,
|
226
|
+
location: str,
|
227
|
+
file_prefix: str,
|
228
|
+
cors: tuple,
|
229
|
+
file_format: str,
|
230
|
+
) -> dict:
|
231
|
+
"""
|
232
|
+
util to retrieve Volumes (identifier) reconstructed by nabu-multicor
|
233
|
+
|
234
|
+
:param TomwerScanBase scan: scam processed by the nabu-multicor
|
235
|
+
:param str location: location of the files
|
236
|
+
:param tuple cors: cors for which we want the reconstructed slices. As this extension is created by nabu
|
237
|
+
the cor reference is in absolute.
|
238
|
+
:param str file_format: file format of the reconstruction
|
239
|
+
|
240
|
+
:return: a dict with absolute cor value as key and the Volume identifier as value
|
241
|
+
"""
|
242
|
+
_logger.info("Deduce volume identifiers for nabu-multicor")
|
243
|
+
if isinstance(slice_index, str):
|
244
|
+
slice_index = slice_index_to_int(slice_index=slice_index, scan=scan)
|
245
|
+
assert isinstance(
|
246
|
+
slice_index, int
|
247
|
+
), "slice_index is expected to be an int or to be converted to it"
|
248
|
+
res = {}
|
249
|
+
if isinstance(scan, EDFTomoScan):
|
250
|
+
entry = "entry"
|
251
|
+
else:
|
252
|
+
entry = scan.entry
|
253
|
+
|
254
|
+
for cor in cors:
|
255
|
+
file_path = os.path.join(
|
256
|
+
location,
|
257
|
+
f"{file_prefix}_{cor:.3f}_{str(slice_index).zfill(5)}.{file_format}",
|
258
|
+
)
|
259
|
+
|
260
|
+
if file_format in ("hdf5", "h5", "hdf"):
|
261
|
+
file_path = os.path.join(
|
262
|
+
location,
|
263
|
+
f"{file_prefix}_{cor:.3f}", # this level is expected to be removed on the future nabu versions
|
264
|
+
f"{file_prefix}_{cor:.3f}_{str(slice_index).zfill(5)}.{file_format}",
|
265
|
+
)
|
266
|
+
volume = HDF5Volume(
|
267
|
+
file_path=file_path,
|
268
|
+
data_path="/".join([entry, "reconstruction"]),
|
269
|
+
)
|
270
|
+
elif file_format in ("vol", "raw"):
|
271
|
+
volume = (RawVolume(file_path=file_path),)
|
272
|
+
elif file_format in ("jp2", "jp2k", "edf", "tiff"):
|
273
|
+
if file_format in ("jp2k", "jp2"):
|
274
|
+
constructor = JP2KVolume
|
275
|
+
elif file_format == "edf":
|
276
|
+
constructor = EDFVolume
|
277
|
+
elif file_format == "tiff":
|
278
|
+
constructor = TIFFVolume
|
279
|
+
else:
|
280
|
+
raise NotImplementedError
|
281
|
+
file_path = location
|
282
|
+
volume = constructor(
|
283
|
+
folder=os.path.dirname(file_path),
|
284
|
+
volume_basename=os.path.basename(file_path),
|
285
|
+
)
|
286
|
+
else:
|
287
|
+
raise ValueError(f"file_format {file_format} is not handled for now")
|
288
|
+
res[cor] = volume.get_identifier()
|
289
|
+
return res
|
290
|
+
|
291
|
+
|
226
292
|
class _NabuMode(_Enum):
|
227
293
|
FULL_FIELD = "standard acquisition"
|
228
294
|
HALF_ACQ = "half acquisition"
|
@@ -302,24 +368,6 @@ class _NabuProcessing(_Enum):
|
|
302
368
|
return (_NabuProcessing.RECONSTRUCTION,)
|
303
369
|
|
304
370
|
|
305
|
-
class ConfigurationLevel(_Enum):
|
306
|
-
REQUIRED = "required"
|
307
|
-
OPTIONAL = "optional"
|
308
|
-
ADVANCED = "advanced"
|
309
|
-
|
310
|
-
def _get_num_value(self) -> int:
|
311
|
-
if self is self.REQUIRED:
|
312
|
-
return 0
|
313
|
-
elif self is self.OPTIONAL:
|
314
|
-
return 1
|
315
|
-
elif self is self.ADVANCED:
|
316
|
-
return 2
|
317
|
-
|
318
|
-
def __le__(self, other):
|
319
|
-
assert isinstance(other, ConfigurationLevel)
|
320
|
-
return self._get_num_value() <= other._get_num_value()
|
321
|
-
|
322
|
-
|
323
371
|
class _NabuPostProcessing(_Enum):
|
324
372
|
"""Define all the post processing action available"""
|
325
373
|
|
@@ -374,9 +422,12 @@ class _NabuPaddingType(_Enum):
|
|
374
422
|
EDGES = "edges"
|
375
423
|
|
376
424
|
|
377
|
-
class
|
425
|
+
class RingCorrectionMethod(_Enum):
|
378
426
|
NONE = "None"
|
379
427
|
MUNCH = "munch"
|
428
|
+
VO = "vo"
|
429
|
+
MEAN_SUBTRACTION = "mean-subtraction"
|
430
|
+
MEAN_DIVISION = "mean-division"
|
380
431
|
|
381
432
|
|
382
433
|
def nabu_std_err_has_error(errs: typing.Optional[bytes]):
|
@@ -397,6 +448,7 @@ def nabu_std_err_has_error(errs: typing.Optional[bytes]):
|
|
397
448
|
or "self.module = SourceModule(self.src, **self.sourcemodule_kwargs)"
|
398
449
|
in line
|
399
450
|
or "return SourceModule(" in line
|
451
|
+
or "CUBLAS" in line
|
400
452
|
)
|
401
453
|
|
402
454
|
if errs is None:
|
@@ -438,3 +490,56 @@ def update_cfg_file_after_transfer(config_file_path, old_path, new_path):
|
|
438
490
|
config=config_as_dict,
|
439
491
|
options_level="advanced",
|
440
492
|
)
|
493
|
+
|
494
|
+
|
495
|
+
def slice_index_to_int(
|
496
|
+
slice_index: typing.Union[int, str], scan: TomwerScanBase
|
497
|
+
) -> int:
|
498
|
+
"""
|
499
|
+
cast a slice to an index. The slice can be a string in ['first', 'last', 'middle']
|
500
|
+
"""
|
501
|
+
if slice_index == "fisrt":
|
502
|
+
return 0
|
503
|
+
elif slice_index == "last":
|
504
|
+
if scan is None:
|
505
|
+
# backward compatibility in the case the scan is not provided. Should not happen anymore
|
506
|
+
_logger.warning("Scan not provided. Consider the 2048 width detector")
|
507
|
+
return 2047
|
508
|
+
elif scan.dim_2 is not None:
|
509
|
+
return scan.dim_2 - 1
|
510
|
+
else:
|
511
|
+
# this could happen on some EDF scans. Not expected to happen for HDF5
|
512
|
+
_logger.warning("unable to get dim size, guess this is 2048 width")
|
513
|
+
# in this
|
514
|
+
return 2047
|
515
|
+
elif slice_index == "middle":
|
516
|
+
if scan is None:
|
517
|
+
# backward compatibility in the case the scan is not provided. Should not happen anymore
|
518
|
+
_logger.warning("Scan not provided. Consider the 1024 width detector")
|
519
|
+
# default middle.
|
520
|
+
return 1024
|
521
|
+
elif scan.dim_2 is None:
|
522
|
+
_logger.warning("unable to get dim size, guess this is 2048 width")
|
523
|
+
return 1024
|
524
|
+
else:
|
525
|
+
return scan.dim_2 // 2
|
526
|
+
else:
|
527
|
+
return int(slice_index)
|
528
|
+
|
529
|
+
|
530
|
+
def get_nabu_multicor_file_prefix(scan):
|
531
|
+
if isinstance(scan, EDFTomoScan):
|
532
|
+
dataset_path = scan.path
|
533
|
+
elif isinstance(scan, NXtomoScan):
|
534
|
+
dataset_path = scan.master_file
|
535
|
+
else:
|
536
|
+
raise TypeError(f"{type(scan)} is not handled")
|
537
|
+
|
538
|
+
if os.path.isfile(dataset_path): # hdf5
|
539
|
+
file_prefix = os.path.basename(dataset_path).split(".")[0]
|
540
|
+
elif os.path.isdir(dataset_path):
|
541
|
+
file_prefix = os.path.basename(dataset_path)
|
542
|
+
else:
|
543
|
+
raise ValueError(f"dataset location {scan.path} is neither a file or directory")
|
544
|
+
file_prefix += "_rec" # avoid overwriting dataset
|
545
|
+
return file_prefix
|
@@ -0,0 +1,108 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
import os
|
3
|
+
import logging
|
4
|
+
from silx.utils.enum import Enum as _Enum
|
5
|
+
from tomwer.io.utils.raw_and_processed_data import (
|
6
|
+
to_processed_data_path,
|
7
|
+
to_raw_data_path,
|
8
|
+
)
|
9
|
+
from tomwer.core.scan.scanbase import TomwerScanBase
|
10
|
+
from tomwer.core.utils.scanutils import format_output_location
|
11
|
+
|
12
|
+
_logger = logging.getLogger(__name__)
|
13
|
+
|
14
|
+
|
15
|
+
PROCESS_FOLDER_NAME = "reconstructed_volumes"
|
16
|
+
|
17
|
+
|
18
|
+
class ProcessDataOutputDirMode(_Enum):
|
19
|
+
IN_SCAN_FOLDER = "same folder as scan"
|
20
|
+
PROCESSED_DATA_FOLDER = "PROCESSED_DATA folder"
|
21
|
+
RAW_DATA_FOLDER = "RAW_DATA folder"
|
22
|
+
OTHER = "other"
|
23
|
+
|
24
|
+
|
25
|
+
class NabuOutputFileFormat(_Enum):
|
26
|
+
TIFF = "tiff"
|
27
|
+
HDF5 = "hdf5"
|
28
|
+
JP2K = "jp2"
|
29
|
+
EDF = "edf"
|
30
|
+
RAW = "vol"
|
31
|
+
|
32
|
+
@classmethod
|
33
|
+
def from_value(cls, value):
|
34
|
+
if isinstance(value, str):
|
35
|
+
value = value.lstrip(".")
|
36
|
+
return super().from_value(value)
|
37
|
+
|
38
|
+
|
39
|
+
def get_file_format(file_str):
|
40
|
+
extension = os.path.splitext(file_str.lower())[-1]
|
41
|
+
extension = extension.lstrip(".")
|
42
|
+
if extension in ("tiff", "tif"):
|
43
|
+
return NabuOutputFileFormat.TIFF
|
44
|
+
elif extension in ("hdf5", "hdf", "h5"):
|
45
|
+
return NabuOutputFileFormat.HDF5
|
46
|
+
elif extension in ("jp2", "jp2k", "jpg2k"):
|
47
|
+
return NabuOutputFileFormat.JP2K
|
48
|
+
elif extension in ("edf",):
|
49
|
+
return NabuOutputFileFormat.EDF
|
50
|
+
elif extension in ("vol", "raw"):
|
51
|
+
return NabuOutputFileFormat.RAW
|
52
|
+
else:
|
53
|
+
raise ValueError(f"Unrecognized file extension {extension} from {file_str}")
|
54
|
+
|
55
|
+
|
56
|
+
def get_output_folder_from_scan(
|
57
|
+
mode: ProcessDataOutputDirMode,
|
58
|
+
scan: TomwerScanBase,
|
59
|
+
nabu_location: str | None,
|
60
|
+
file_basename: str,
|
61
|
+
file_format: NabuOutputFileFormat,
|
62
|
+
) -> tuple[str, str]:
|
63
|
+
"""
|
64
|
+
:return: (location, location_cfg_files). Location is the nabu configuration field 'output/location' 'location_cfg_files' is the information on where to save the nabu configuration file
|
65
|
+
|
66
|
+
"""
|
67
|
+
output_mode = ProcessDataOutputDirMode.from_value(mode)
|
68
|
+
file_format = NabuOutputFileFormat.from_value(file_format)
|
69
|
+
|
70
|
+
if output_mode is ProcessDataOutputDirMode.OTHER and nabu_location in ("", None):
|
71
|
+
_logger.info(
|
72
|
+
"output dir requested is other bit no path provided. Fall back on the output dir to the scan folder"
|
73
|
+
)
|
74
|
+
# note: this is only an info because we expect to pass by this one for all .ows configuration (before 1.3 version)
|
75
|
+
# as there was no different option by the time
|
76
|
+
output_mode = ProcessDataOutputDirMode.IN_SCAN_FOLDER
|
77
|
+
|
78
|
+
if output_mode is ProcessDataOutputDirMode.OTHER:
|
79
|
+
assert nabu_location not in (
|
80
|
+
"",
|
81
|
+
None,
|
82
|
+
), "nabu_location not provided when expected"
|
83
|
+
location = format_output_location(nabu_location, scan=scan)
|
84
|
+
location_cfg_files = location
|
85
|
+
elif output_mode in (
|
86
|
+
ProcessDataOutputDirMode.IN_SCAN_FOLDER,
|
87
|
+
ProcessDataOutputDirMode.PROCESSED_DATA_FOLDER,
|
88
|
+
ProcessDataOutputDirMode.RAW_DATA_FOLDER,
|
89
|
+
):
|
90
|
+
# otherwise default location will be the data root level
|
91
|
+
location = os.path.join(scan.path, PROCESS_FOLDER_NAME)
|
92
|
+
location_cfg_files = location
|
93
|
+
if file_format in (
|
94
|
+
NabuOutputFileFormat.EDF.value,
|
95
|
+
NabuOutputFileFormat.TIFF.value,
|
96
|
+
NabuOutputFileFormat.JP2K.value,
|
97
|
+
): # if user specify the location
|
98
|
+
location = "/".join([location, file_basename])
|
99
|
+
if output_mode is ProcessDataOutputDirMode.PROCESSED_DATA_FOLDER:
|
100
|
+
location = to_processed_data_path(location)
|
101
|
+
location_cfg_files = to_processed_data_path(location_cfg_files)
|
102
|
+
if output_mode is ProcessDataOutputDirMode.RAW_DATA_FOLDER:
|
103
|
+
location = to_raw_data_path(location)
|
104
|
+
location_cfg_files = to_raw_data_path(location_cfg_files)
|
105
|
+
else:
|
106
|
+
raise NotImplementedError(f"mode {output_mode.value} is not implemented yet")
|
107
|
+
|
108
|
+
return location, location_cfg_files
|