tomwer 1.4.0rc6__py3-none-any.whl → 1.4.2__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/orange/managedprocess.py +7 -0
- orangecontrib/tomwer/tutorials/simple_volume_to_slurm_reconstruction.ows +2 -2
- orangecontrib/tomwer/widgets/edit/ImageKeyUpgraderOW.py +5 -4
- orangecontrib/tomwer/widgets/reconstruction/AxisOW.py +19 -47
- orangecontrib/tomwer/widgets/reconstruction/DarkRefAndCopyOW.py +0 -2
- orangecontrib/tomwer/widgets/reconstruction/NabuOW.py +8 -3
- orangecontrib/tomwer/widgets/reconstruction/NabuVolumeOW.py +4 -6
- orangecontrib/tomwer/widgets/reconstruction/SAAxisOW.py +8 -4
- orangecontrib/tomwer/widgets/reconstruction/SADeltaBetaOW.py +0 -4
- orangecontrib/tomwer/widgets/reconstruction/SinoNormOW.py +1 -13
- tomwer/app/axis.py +0 -1
- tomwer/app/intensitynormalization.py +0 -14
- tomwer/app/multicor.py +1 -33
- tomwer/app/multipag.py +1 -31
- tomwer/app/nabuapp.py +0 -1
- tomwer/app/patchrawdarkflat.py +0 -3
- tomwer/app/reducedarkflat.py +0 -1
- tomwer/core/process/control/datalistener/datalistener.py +0 -232
- tomwer/core/process/control/datawatcher/datawatcher.py +0 -5
- tomwer/core/process/control/scantransfer.py +3 -60
- tomwer/core/process/edit/darkflatpatch.py +0 -8
- tomwer/core/process/edit/imagekeyeditor.py +2 -19
- tomwer/core/process/reconstruction/axis/axis.py +7 -18
- tomwer/core/process/reconstruction/darkref/darkrefs.py +0 -59
- tomwer/core/process/reconstruction/nabu/nabuslices.py +0 -88
- tomwer/core/process/reconstruction/nabu/nabuvolume.py +0 -10
- tomwer/core/process/reconstruction/params_cache.py +36 -0
- tomwer/core/process/reconstruction/saaxis/saaxis.py +80 -88
- tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py +78 -86
- tomwer/core/process/reconstruction/tests/test_params_cache.py +37 -0
- tomwer/core/process/script/python.py +0 -19
- tomwer/core/process/task.py +0 -290
- tomwer/core/process/tests/test_dark_and_flat.py +0 -6
- tomwer/core/process/tests/test_data_transfer.py +0 -1
- tomwer/core/process/tests/test_data_watcher.py +6 -23
- tomwer/core/scan/edfscan.py +0 -11
- tomwer/core/scan/nxtomoscan.py +0 -12
- tomwer/core/scan/scanbase.py +0 -81
- tomwer/gui/reconstruction/axis/CalculationWidget.py +3 -5
- tomwer/gui/reconstruction/tests/test_saaxis.py +2 -2
- tomwer/gui/reconstruction/tests/test_sadeltabeta.py +2 -2
- tomwer/gui/stitching/config/axisparams.py +2 -0
- tomwer/synctools/stacks/reconstruction/axis.py +0 -18
- tomwer/synctools/tests/test_foldertransfer.py +2 -19
- tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_i_norm.py +110 -153
- tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_sa_delta_beta.py +103 -153
- tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_saaxis.py +117 -152
- tomwer/tests/orangecontrib/tomwer/widgets/{tests/test_darkref.py → test_darkref.py} +0 -9
- tomwer/tests/orangecontrib/tomwer/widgets/{tests/test_foldertransfert.py → test_foldertransfert.py} +1 -1
- tomwer/tests/test_ewoks/test_workflows.py +0 -4
- tomwer/version.py +3 -3
- {tomwer-1.4.0rc6.dist-info → tomwer-1.4.2.dist-info}/METADATA +2 -3
- {tomwer-1.4.0rc6.dist-info → tomwer-1.4.2.dist-info}/RECORD +58 -59
- tomwer/core/scan/tests/test_process_registration.py +0 -64
- tomwer/core/utils/Singleton.py +0 -36
- tomwer/core/utils/locker.py +0 -58
- /tomwer/tests/orangecontrib/tomwer/widgets/{tests/test_conditions.py → test_conditions.py} +0 -0
- {tomwer-1.4.0rc6.dist-info → tomwer-1.4.2.dist-info}/LICENSE +0 -0
- {tomwer-1.4.0rc6.dist-info → tomwer-1.4.2.dist-info}/WHEEL +0 -0
- {tomwer-1.4.0rc6.dist-info → tomwer-1.4.2.dist-info}/entry_points.txt +0 -0
- {tomwer-1.4.0rc6.dist-info → tomwer-1.4.2.dist-info}/top_level.txt +0 -0
@@ -14,7 +14,6 @@ from nabu.pipeline.fullfield.nabu_config import (
|
|
14
14
|
from processview.core.manager.manager import ProcessManager, DatasetState
|
15
15
|
from processview.core.superviseprocess import SuperviseProcess
|
16
16
|
|
17
|
-
from silx.io.utils import h5py_read_dataset
|
18
17
|
from silx.io.utils import open as open_hdf5
|
19
18
|
from tomwer.core.utils.deprecation import deprecated_warning
|
20
19
|
|
@@ -30,7 +29,6 @@ from tomwer.core.scan.scanfactory import ScanFactory
|
|
30
29
|
from tomwer.core.utils.dictutils import concatenate_dict
|
31
30
|
from tomwer.core.utils.scanutils import data_identifier_to_scan
|
32
31
|
from tomwer.core.volume.volumefactory import VolumeFactory
|
33
|
-
from tomwer.io.utils.h5pyutils import EntryReader
|
34
32
|
from tomwer.utils import docstring
|
35
33
|
from tomwer.io.utils import format_stderr_stdout
|
36
34
|
from tomwer.core.process.reconstruction.output import (
|
@@ -548,14 +546,6 @@ class NabuVolumeTask(
|
|
548
546
|
def dry_run(self):
|
549
547
|
return self._dry_run
|
550
548
|
|
551
|
-
@staticmethod
|
552
|
-
def retrieve_last_relative_cor(scan):
|
553
|
-
with EntryReader(scan.process_file_url) as h5f:
|
554
|
-
latest_nabu_node = Task.get_most_recent_process(h5f, NabuVolumeTask)
|
555
|
-
path = "configuration/reconstruction/rotation_axis_position"
|
556
|
-
if latest_nabu_node is not None and path in latest_nabu_node:
|
557
|
-
return h5py_read_dataset(latest_nabu_node[path])
|
558
|
-
|
559
549
|
def cancel(self):
|
560
550
|
"""
|
561
551
|
stop current processing
|
@@ -0,0 +1,36 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from tomwer.core.scan.scanbase import TomwerScanBase
|
4
|
+
from collections import OrderedDict
|
5
|
+
|
6
|
+
_CACHE: {str, tuple[float | None, dict | None]} = OrderedDict()
|
7
|
+
"""
|
8
|
+
In the case we want to reprocess a scan we (might) need to know the cor and the nabu reconstruction parameters (for nabu slice and volume reconstructions)
|
9
|
+
But we are not keeping all those object during the full 'orange canvas' lifecycle, it would be too heavy.
|
10
|
+
As a consequence we cache those (small) values (and only those) of the last n scans (n==30) in case users want to reprocess some of those.
|
11
|
+
n value is an arbitrary value.
|
12
|
+
"""
|
13
|
+
_CACHE_SIZE = 30
|
14
|
+
|
15
|
+
|
16
|
+
def save_reconstruction_parameters_to_cache(scan: TomwerScanBase):
|
17
|
+
# pop if exists. Will move this item as 'last-in'
|
18
|
+
_CACHE.pop(scan.get_identifier().to_str(), None)
|
19
|
+
_CACHE[scan.get_identifier().to_str()] = (
|
20
|
+
None if scan.axis_params is None else scan.axis_params.relative_cor_value,
|
21
|
+
None if scan.nabu_recons_params is None else scan.nabu_recons_params,
|
22
|
+
)
|
23
|
+
if len(_CACHE) > _CACHE_SIZE:
|
24
|
+
_CACHE.popitem(last=False)
|
25
|
+
|
26
|
+
|
27
|
+
def load_reconstruction_parameters_from_cache(scan: TomwerScanBase):
|
28
|
+
cor, nabu_recons_params = _CACHE.get(scan.get_identifier().to_str(), (None, None))
|
29
|
+
if cor is not None and scan.axis_params is not None:
|
30
|
+
scan.axis_params.set_relative_value(cor)
|
31
|
+
if nabu_recons_params is not None:
|
32
|
+
scan.nabu_recons_params = nabu_recons_params
|
33
|
+
|
34
|
+
|
35
|
+
def clear_reconstruction_parameters_cache():
|
36
|
+
_CACHE.clear()
|
@@ -5,15 +5,16 @@ from __future__ import annotations
|
|
5
5
|
|
6
6
|
import logging
|
7
7
|
import os
|
8
|
-
|
9
8
|
import h5py
|
9
|
+
|
10
10
|
import numpy
|
11
11
|
from multiprocessing import Pool
|
12
12
|
from processview.core.manager import DatasetState, ProcessManager
|
13
13
|
from processview.core.superviseprocess import SuperviseProcess
|
14
14
|
from silx.io.url import DataUrl
|
15
|
-
from
|
15
|
+
from silx.io.utils import h5py_read_dataset
|
16
16
|
|
17
|
+
from tomwer.core.utils.deprecation import deprecated_warning
|
17
18
|
from tomoscan.io import HDF5File
|
18
19
|
|
19
20
|
import tomwer.version
|
@@ -33,13 +34,14 @@ from tomwer.core.process.reconstruction.scores import (
|
|
33
34
|
from tomwer.core.process.reconstruction.scores.params import ScoreMethod
|
34
35
|
from tomwer.core.process.reconstruction.utils.cor import relative_pos_to_absolute
|
35
36
|
from tomwer.core.process.task import Task
|
36
|
-
from tomwer.core.
|
37
|
+
from tomwer.core.process import utils as core_utils
|
37
38
|
from tomwer.core.scan.scanbase import TomwerScanBase
|
38
39
|
from tomwer.core.scan.scanfactory import ScanFactory
|
39
40
|
from tomwer.core.utils import logconfig
|
40
|
-
from tomwer.core.utils.locker import FileLockerManager
|
41
41
|
from tomwer.core.utils.scanutils import data_identifier_to_scan
|
42
42
|
from tomwer.core.utils.slurm import is_slurm_available
|
43
|
+
|
44
|
+
from tomwer.io.utils.h5pyutils import EntryReader
|
43
45
|
from tomwer.core.volume.volumefactory import VolumeFactory
|
44
46
|
from tomwer.io.utils.utils import get_slice_data
|
45
47
|
from tomwer.io.utils import format_stderr_stdout
|
@@ -378,7 +380,8 @@ class SAAxisTask(
|
|
378
380
|
output_dir = params.output_dir or None
|
379
381
|
if output_dir is None:
|
380
382
|
output_dir = (
|
381
|
-
params.
|
383
|
+
params.nabu_recons_params.get("output", {}).get("location", None)
|
384
|
+
or None
|
382
385
|
)
|
383
386
|
if output_dir is None:
|
384
387
|
output_dir = os.path.join(scan.path, DEFAULT_RECONS_FOLDER)
|
@@ -576,35 +579,23 @@ class SAAxisTask(
|
|
576
579
|
_logger.error(e)
|
577
580
|
else:
|
578
581
|
if self._dump_process:
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
if self.dump_roi and process_idx is not None:
|
583
|
-
self.dump_rois(
|
584
|
-
scan, score_rois=score_rois, process_index=process_idx
|
585
|
-
)
|
582
|
+
self.save_results_to_disk(scan=scan)
|
583
|
+
if self.dump_roi:
|
584
|
+
self.dump_rois(scan, score_rois=score_rois)
|
586
585
|
|
587
586
|
@staticmethod
|
588
|
-
def dump_rois(scan, score_rois
|
589
|
-
process_file = scan.process_file
|
590
|
-
process_name = "tomwer_process_" + str(process_index)
|
591
|
-
|
587
|
+
def dump_rois(scan, score_rois):
|
592
588
|
if scan.saaxis_params.scores in (None, {}):
|
593
589
|
return
|
594
590
|
|
595
|
-
|
596
|
-
return "/".join((scan.entry or "entry", process_name))
|
591
|
+
process_url = SAAxisTask.get_results_url(scan=scan)
|
597
592
|
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
score_roi_grp = nx_process.require_group("score_roi")
|
605
|
-
for cor, roi in score_rois.items():
|
606
|
-
score_roi_grp[str(cor)] = roi
|
607
|
-
score_roi_grp[str(cor)].attrs["interpretation"] = "image"
|
593
|
+
with HDF5File(process_url.file_path(), mode="w") as h5f:
|
594
|
+
nx_process = h5f.require_group(process_url.data_path())
|
595
|
+
score_roi_grp = nx_process.require_group("score_roi")
|
596
|
+
for cor, roi in score_rois.items():
|
597
|
+
score_roi_grp[str(cor)] = roi
|
598
|
+
score_roi_grp[str(cor)].attrs["interpretation"] = "image"
|
608
599
|
|
609
600
|
@staticmethod
|
610
601
|
def program_name():
|
@@ -622,74 +613,75 @@ class SAAxisTask(
|
|
622
613
|
return "Semi automatic center of rotation / axis calculation"
|
623
614
|
|
624
615
|
@staticmethod
|
625
|
-
def
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
cor = scan.axis_params.relative_cor_value
|
634
|
-
|
635
|
-
process_index = scan.pop_process_index()
|
636
|
-
try:
|
637
|
-
with scan.acquire_process_file_lock():
|
638
|
-
Task._register_process(
|
639
|
-
process_file=scan.process_file,
|
640
|
-
entry=entry,
|
641
|
-
results={"center_of_rotation": cor if cor is not None else "-"},
|
642
|
-
configuration=scan.saaxis_params.to_dict(),
|
643
|
-
process_index=process_index,
|
644
|
-
overwrite=True,
|
645
|
-
process=SAAxisTask,
|
646
|
-
)
|
647
|
-
SAAxisTask._extends_results(
|
648
|
-
scan=scan, entry=entry, process_index=process_index
|
649
|
-
)
|
650
|
-
except Exception as e:
|
651
|
-
_logger.warning(
|
652
|
-
f"Fail to register process of with index {process_index}. Reason is {e}"
|
653
|
-
)
|
654
|
-
return process_index
|
616
|
+
def get_results_url(scan):
|
617
|
+
return DataUrl(
|
618
|
+
file_path=scan.get_relative_file(
|
619
|
+
os.path.join(DEFAULT_RECONS_FOLDER, "tomwer_saaxis.h5")
|
620
|
+
),
|
621
|
+
data_path=scan.entry or "entry",
|
622
|
+
scheme="silx",
|
623
|
+
)
|
655
624
|
|
656
625
|
@staticmethod
|
657
|
-
def
|
658
|
-
process_file = scan.process_file
|
659
|
-
process_name = "tomwer_process_" + str(process_index)
|
660
|
-
|
626
|
+
def save_results_to_disk(scan):
|
661
627
|
if scan.saaxis_params.scores in (None, {}):
|
662
628
|
return
|
663
629
|
|
664
|
-
|
665
|
-
return "/".join((entry or "entry", process_name))
|
630
|
+
saaxis_results_url = SAAxisTask.get_results_url(scan=scan)
|
666
631
|
|
667
632
|
# save it to the file
|
668
|
-
with
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
633
|
+
with HDF5File(saaxis_results_url.file_path(), mode="a") as h5f:
|
634
|
+
nx_process = h5f.require_group(saaxis_results_url.data_path())
|
635
|
+
if "NX_class" not in nx_process.attrs:
|
636
|
+
nx_process.attrs["NX_class"] = "NXprocess"
|
637
|
+
|
638
|
+
results = nx_process.require_group("results")
|
639
|
+
for cor, (url, score) in scan.saaxis_params.scores.items():
|
640
|
+
results_cor = results.require_group(str(cor))
|
641
|
+
for method in ScoreMethod:
|
642
|
+
method_score = score.get(method)
|
643
|
+
if method_score is None:
|
644
|
+
results_cor[method.value] = "None"
|
645
|
+
else:
|
646
|
+
results_cor[method.value] = method_score
|
647
|
+
|
648
|
+
link_path = os.path.relpath(
|
649
|
+
url.file_path(),
|
650
|
+
os.path.dirname(saaxis_results_url.file_path()),
|
651
|
+
)
|
652
|
+
results_cor["reconstructed_slice"] = h5py.ExternalLink(
|
653
|
+
link_path, url.data_path()
|
654
|
+
)
|
655
|
+
|
656
|
+
@staticmethod
|
657
|
+
def load_results_from_disk(scan):
|
658
|
+
saaxis_results_url = SAAxisTask.get_results_url(scan=scan)
|
659
|
+
|
660
|
+
if saaxis_results_url.file_path() is None or not os.path.exists(
|
661
|
+
saaxis_results_url.file_path()
|
662
|
+
):
|
663
|
+
_logger.warning(
|
664
|
+
"Unable to find process file. Unable to read " "existing processing"
|
665
|
+
)
|
666
|
+
return None, None
|
667
|
+
|
668
|
+
try:
|
669
|
+
with EntryReader(saaxis_results_url) as h5f_entry_node:
|
670
|
+
scores = core_utils.get_scores(h5f_entry_node)
|
671
|
+
if (
|
672
|
+
"results" in h5f_entry_node
|
673
|
+
and "center_of_rotation" in h5f_entry_node["results"]
|
674
|
+
):
|
675
|
+
selected = h5py_read_dataset(
|
676
|
+
h5f_entry_node["results"]["center_of_rotation"]
|
692
677
|
)
|
678
|
+
else:
|
679
|
+
_logger.warning(f"no results found for {scan}")
|
680
|
+
selected = None
|
681
|
+
return scores, selected
|
682
|
+
except ValueError:
|
683
|
+
_logger.warning(f"Data path ({saaxis_results_url.data_path()}) not found")
|
684
|
+
return None, None
|
693
685
|
|
694
686
|
def cancel(self):
|
695
687
|
"""
|
@@ -20,6 +20,7 @@ from processview.core.manager import DatasetState, ProcessManager
|
|
20
20
|
from processview.core.superviseprocess import SuperviseProcess
|
21
21
|
from tomoscan.esrf.scan.utils import get_data
|
22
22
|
from tomoscan.io import HDF5File
|
23
|
+
from silx.io.utils import h5py_read_dataset
|
23
24
|
|
24
25
|
import tomwer.version
|
25
26
|
from tomwer.core.process.reconstruction.nabu.nabucommon import (
|
@@ -36,21 +37,21 @@ from tomwer.core.process.reconstruction.scores import (
|
|
36
37
|
compute_score,
|
37
38
|
get_disk_mask_radius,
|
38
39
|
)
|
39
|
-
from tomwer.core.utils.locker import FileLockerManager
|
40
40
|
from tomwer.core.process.task import Task
|
41
|
-
from tomwer.core.
|
41
|
+
from tomwer.core.process import utils as core_utils
|
42
42
|
from tomwer.core.scan.scanbase import TomwerScanBase
|
43
43
|
from tomwer.core.scan.scanfactory import ScanFactory
|
44
44
|
from tomwer.core.utils import logconfig
|
45
45
|
from tomwer.core.utils.scanutils import data_identifier_to_scan
|
46
46
|
from tomwer.core.volume.volumefactory import VolumeFactory
|
47
47
|
from tomwer.io.utils import format_stderr_stdout
|
48
|
+
from tomwer.io.utils.h5pyutils import EntryReader
|
48
49
|
from tomwer.core.process.reconstruction.nabu.nabuscores import (
|
49
50
|
run_nabu_one_slice_several_config,
|
50
51
|
)
|
51
52
|
from tomwer.core.futureobject import FutureTomwerObject
|
52
53
|
|
53
|
-
|
54
|
+
from silx.io.url import DataUrl
|
54
55
|
from silx.utils.deprecation import deprecated, deprecated_warning
|
55
56
|
|
56
57
|
from ..nabu import utils as nabu_utils
|
@@ -202,7 +203,8 @@ class SADeltaBetaTask(
|
|
202
203
|
|
203
204
|
if params.output_dir is None:
|
204
205
|
output_dir = (
|
205
|
-
params.
|
206
|
+
params.nabu_recons_params.get("output", {}).get("location", None)
|
207
|
+
or None
|
206
208
|
)
|
207
209
|
if output_dir is None:
|
208
210
|
output_dir = os.path.join(scan.path, DEFAULT_RECONS_FOLDER)
|
@@ -587,39 +589,30 @@ class SADeltaBetaTask(
|
|
587
589
|
_logger.error(e)
|
588
590
|
else:
|
589
591
|
if self._dump_process:
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
if self.dump_roi and process_idx is not None:
|
594
|
-
self.dump_rois(
|
595
|
-
scan, score_rois=score_rois, process_index=process_idx
|
596
|
-
)
|
592
|
+
self.save_results_to_disk(scan=scan)
|
593
|
+
if self.dump_roi:
|
594
|
+
self.dump_rois(scan, score_rois=score_rois)
|
597
595
|
|
598
596
|
@staticmethod
|
599
|
-
def dump_rois(scan, score_rois: dict
|
600
|
-
if score_rois is None or len(score_rois) == 0:
|
601
|
-
return
|
597
|
+
def dump_rois(scan, score_rois: dict):
|
602
598
|
if not isinstance(score_rois, dict):
|
603
599
|
raise TypeError("score_rois is expected to be a dict")
|
604
|
-
|
605
|
-
|
600
|
+
|
601
|
+
if score_rois is None or len(score_rois) == 0:
|
602
|
+
return
|
606
603
|
|
607
604
|
if scan.saaxis_params.scores in (None, {}):
|
608
605
|
return
|
609
606
|
|
610
|
-
|
611
|
-
return "/".join((scan.entry or "entry", process_name))
|
607
|
+
sa_delta_beta_results_url = SADeltaBetaTask.get_results_url(scan=scan)
|
612
608
|
|
613
609
|
# save it to the file
|
614
|
-
with
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
score_roi_grp =
|
620
|
-
for db, roi in score_rois.items():
|
621
|
-
score_roi_grp[str(db)] = roi
|
622
|
-
score_roi_grp[str(db)].attrs["interpretation"] = "image"
|
610
|
+
with HDF5File(sa_delta_beta_results_url.file_path(), mode="a") as h5f:
|
611
|
+
nx_process = h5f.require_group(sa_delta_beta_results_url.data_path())
|
612
|
+
score_roi_grp = nx_process.require_group("score_roi")
|
613
|
+
for db, roi in score_rois.items():
|
614
|
+
score_roi_grp[str(db)] = roi
|
615
|
+
score_roi_grp[str(db)].attrs["interpretation"] = "image"
|
623
616
|
|
624
617
|
@staticmethod
|
625
618
|
def program_name():
|
@@ -637,73 +630,72 @@ class SADeltaBetaTask(
|
|
637
630
|
return "Semi automatic center of rotation / axis calculation"
|
638
631
|
|
639
632
|
@staticmethod
|
640
|
-
def
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
633
|
+
def get_results_url(scan):
|
634
|
+
return DataUrl(
|
635
|
+
file_path=scan.get_relative_file(
|
636
|
+
os.path.join(DEFAULT_RECONS_FOLDER, "tomwer_sadelta_beta.h5")
|
637
|
+
),
|
638
|
+
data_path=scan.entry or "entry",
|
639
|
+
scheme="silx",
|
640
|
+
)
|
645
641
|
|
646
|
-
|
647
|
-
|
648
|
-
|
642
|
+
@staticmethod
|
643
|
+
def save_results_to_disk(scan):
|
644
|
+
if scan.saaxis_params.scores in (None, {}):
|
645
|
+
return
|
649
646
|
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
)
|
665
|
-
|
666
|
-
|
667
|
-
|
647
|
+
results_url = SADeltaBetaTask.get_results_url(scan=scan)
|
648
|
+
# save it to the file
|
649
|
+
with HDF5File(results_url.file_path(), mode="w") as h5f:
|
650
|
+
nx_process = h5f.require_group(results_url.data_path())
|
651
|
+
if "NX_class" not in nx_process.attrs:
|
652
|
+
nx_process.attrs["NX_class"] = "NXprocess"
|
653
|
+
|
654
|
+
results = nx_process.require_group("results")
|
655
|
+
|
656
|
+
for cor, (url, score) in scan.sa_delta_beta_params.scores.items():
|
657
|
+
results_db = results.require_group(str(cor))
|
658
|
+
for method in ScoreMethod:
|
659
|
+
if method is ScoreMethod.TOMO_CONSISTENCY:
|
660
|
+
continue
|
661
|
+
results_db[method.value] = score.get(method)
|
662
|
+
|
663
|
+
link_path = os.path.relpath(
|
664
|
+
url.file_path(),
|
665
|
+
os.path.dirname(results_url.file_path()),
|
666
|
+
)
|
667
|
+
results_db["reconstructed_slice"] = h5py.ExternalLink(
|
668
|
+
link_path, url.data_path()
|
668
669
|
)
|
669
|
-
|
670
|
-
return process_index
|
671
670
|
|
672
671
|
@staticmethod
|
673
|
-
def
|
674
|
-
|
675
|
-
|
672
|
+
def load_results_from_disk(scan):
|
673
|
+
results_url = SADeltaBetaTask.get_results_url(scan=scan)
|
674
|
+
process_file = results_url.file_path()
|
676
675
|
|
677
|
-
if
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
return
|
676
|
+
if process_file is None or not os.path.exists(process_file):
|
677
|
+
_logger.warning(
|
678
|
+
"Unable to find process file. Unable to read " "existing processing"
|
679
|
+
)
|
680
|
+
return None, None
|
682
681
|
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
results = nx_process.require_group("results")
|
693
|
-
for cor, (url, score) in scan.sa_delta_beta_params.scores.items():
|
694
|
-
results_db = results.require_group(str(cor))
|
695
|
-
for method in ScoreMethod:
|
696
|
-
if method is ScoreMethod.TOMO_CONSISTENCY:
|
697
|
-
continue
|
698
|
-
results_db[method.value] = score.get(method)
|
699
|
-
|
700
|
-
link_path = os.path.relpath(
|
701
|
-
url.file_path(),
|
702
|
-
os.path.dirname(process_file),
|
703
|
-
)
|
704
|
-
results_db["reconstructed_slice"] = h5py.ExternalLink(
|
705
|
-
link_path, url.data_path()
|
682
|
+
try:
|
683
|
+
with EntryReader(results_url) as h5f_entry_node:
|
684
|
+
scores = core_utils.get_scores(h5f_entry_node)
|
685
|
+
if (
|
686
|
+
"results" in h5f_entry_node
|
687
|
+
and "delta_beta" in h5f_entry_node["results"]
|
688
|
+
):
|
689
|
+
selected = h5py_read_dataset(
|
690
|
+
h5f_entry_node["results"]["delta_beta"]
|
706
691
|
)
|
692
|
+
else:
|
693
|
+
_logger.warning(f"no results found for {scan}")
|
694
|
+
selected = None
|
695
|
+
return scores, selected
|
696
|
+
except ValueError:
|
697
|
+
_logger.warning(f"Data path ({results_url.data_path()}) not found")
|
698
|
+
return None, None
|
707
699
|
|
708
700
|
def cancel(self):
|
709
701
|
"""
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import os
|
2
|
+
from tomwer.core.process.reconstruction.params_cache import (
|
3
|
+
_CACHE,
|
4
|
+
_CACHE_SIZE,
|
5
|
+
save_reconstruction_parameters_to_cache,
|
6
|
+
clear_reconstruction_parameters_cache,
|
7
|
+
)
|
8
|
+
from tomwer.core.utils.scanutils import MockNXtomo
|
9
|
+
|
10
|
+
|
11
|
+
def test_cache(tmp_path):
|
12
|
+
nxtomos = [
|
13
|
+
MockNXtomo(
|
14
|
+
scan_path=os.path.join(tmp_path, f"my_nxtomo_{i_scan}"),
|
15
|
+
n_proj=10,
|
16
|
+
).scan
|
17
|
+
for i_scan in range(31)
|
18
|
+
]
|
19
|
+
new_nxtomo = MockNXtomo(
|
20
|
+
scan_path=os.path.join(tmp_path, "my_nxtomo_99"),
|
21
|
+
n_proj=10,
|
22
|
+
).scan
|
23
|
+
|
24
|
+
clear_reconstruction_parameters_cache()
|
25
|
+
# test saving it in the original order
|
26
|
+
[save_reconstruction_parameters_to_cache(scan=scan) for scan in nxtomos]
|
27
|
+
assert len(_CACHE) == _CACHE_SIZE
|
28
|
+
assert _CACHE == {
|
29
|
+
nxtomo.get_identifier().to_str(): (None, None) for nxtomo in nxtomos[1:]
|
30
|
+
}
|
31
|
+
|
32
|
+
# try updating the next last one to make sure it won't be removed
|
33
|
+
save_reconstruction_parameters_to_cache(scan=nxtomos[1])
|
34
|
+
save_reconstruction_parameters_to_cache(scan=new_nxtomo)
|
35
|
+
assert nxtomos[1].get_identifier().to_str() in _CACHE
|
36
|
+
assert nxtomos[2].get_identifier().to_str() not in _CACHE
|
37
|
+
clear_reconstruction_parameters_cache()
|
@@ -7,7 +7,6 @@ import logging
|
|
7
7
|
|
8
8
|
import tomwer.version
|
9
9
|
from tomwer.core.process.task import Task
|
10
|
-
from tomwer.core.scan.edfscan import EDFTomoScan
|
11
10
|
from tomwer.core.scan.scanbase import TomwerScanBase
|
12
11
|
from tomwer.core.scan.scanfactory import ScanFactory
|
13
12
|
from tomwer.core.utils.scanutils import data_identifier_to_scan
|
@@ -40,24 +39,6 @@ class PythonScript(
|
|
40
39
|
out_data = data_identifier_to_scan(interpreter.locals.get("out_data"))
|
41
40
|
out_volume = data_identifier_to_scan(interpreter.locals.get("out_volume"))
|
42
41
|
|
43
|
-
# register process
|
44
|
-
if isinstance(scan, EDFTomoScan):
|
45
|
-
entry = None
|
46
|
-
else:
|
47
|
-
entry = scan.entry
|
48
|
-
|
49
|
-
try:
|
50
|
-
self.register_process(
|
51
|
-
process_file=scan.process_file,
|
52
|
-
entry=entry,
|
53
|
-
configuration={"scriptText": self.get_configuration()["scriptText"]},
|
54
|
-
results=None,
|
55
|
-
process_index=scan.pop_process_index(),
|
56
|
-
overwrite=True,
|
57
|
-
)
|
58
|
-
except Exception as e:
|
59
|
-
_logger.error("Fail to register process. Error is " + str(e))
|
60
|
-
|
61
42
|
if out_data is not None and self.get_input_value("serialize_output_data", True):
|
62
43
|
self.outputs.data = out_data.to_dict()
|
63
44
|
else:
|