tomwer 1.3.0.dev2__py3-none-any.whl → 1.3.0rc10__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/widgets/__init__.py +11 -12
- orangecontrib/tomwer/widgets/control/DataListenerOW.py +6 -6
- orangecontrib/tomwer/widgets/control/DataValidatorOW.py +6 -6
- orangecontrib/tomwer/widgets/control/NXTomomillMixIn.py +3 -3
- orangecontrib/tomwer/widgets/control/NXTomomillOW.py +10 -8
- orangecontrib/tomwer/widgets/control/SingleTomoObjOW.py +6 -6
- orangecontrib/tomwer/widgets/debugtools/DatasetGeneratorOW.py +1 -1
- orangecontrib/tomwer/widgets/icat/RawDataScreenshotCreatorOW.py +98 -98
- orangecontrib/tomwer/widgets/icat/SaveToGalleryAndPublishOW.py +129 -129
- orangecontrib/tomwer/widgets/reconstruction/AxisOW.py +13 -12
- orangecontrib/tomwer/widgets/reconstruction/SAAxisOW.py +11 -9
- orangecontrib/tomwer/widgets/reconstruction/SADeltaBetaOW.py +11 -9
- orangecontrib/tomwer/widgets/reconstruction/SinoNormOW.py +12 -15
- orangecontrib/tomwer/widgets/visualization/DataViewerOW.py +9 -9
- orangecontrib/tomwer/widgets/visualization/DiffViewerOW.py +1 -1
- orangecontrib/tomwer/widgets/visualization/SinogramViewerOW.py +0 -1
- tomwer/__main__.py +0 -10
- tomwer/app/canvas_launcher/config.py +3 -3
- tomwer/app/canvas_launcher/environ.py +1 -0
- tomwer/app/intensitynormalization.py +12 -11
- tomwer/app/nabuapp.py +0 -11
- tomwer/app/zstitching.py +11 -1
- tomwer/core/process/control/datalistener/datalistener.py +15 -10
- tomwer/core/process/control/nxtomomill.py +1 -1
- tomwer/core/process/control/scantransfer.py +8 -32
- tomwer/core/process/edit/darkflatpatch.py +8 -9
- tomwer/core/process/edit/imagekeyeditor.py +20 -22
- tomwer/core/process/icat/screenshots.py +1 -0
- tomwer/core/process/reconstruction/axis/axis.py +263 -59
- tomwer/core/process/reconstruction/axis/mode.py +161 -50
- tomwer/core/process/reconstruction/axis/params.py +23 -20
- tomwer/core/process/reconstruction/darkref/darkrefs.py +12 -13
- tomwer/core/process/reconstruction/nabu/castvolume.py +3 -3
- tomwer/core/process/reconstruction/nabu/nabucommon.py +43 -19
- tomwer/core/process/reconstruction/nabu/nabuscores.py +34 -7
- tomwer/core/process/reconstruction/nabu/nabuslices.py +81 -26
- tomwer/core/process/reconstruction/nabu/nabuvolume.py +31 -26
- tomwer/core/process/reconstruction/nabu/plane.py +9 -0
- tomwer/core/process/reconstruction/nabu/utils.py +32 -9
- tomwer/core/process/reconstruction/saaxis/saaxis.py +4 -1
- tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py +9 -1
- tomwer/core/process/reconstruction/scores/params.py +3 -3
- tomwer/core/process/reconstruction/test/test_darkref_copy.py +4 -4
- tomwer/core/process/stitching/nabustitcher.py +11 -10
- tomwer/core/process/task.py +33 -27
- tomwer/core/process/test/test_axis.py +7 -6
- tomwer/core/process/test/test_data_transfer.py +3 -3
- tomwer/core/process/test/test_nabu.py +10 -2
- tomwer/core/process/test/test_normalization.py +2 -2
- tomwer/core/scan/blissscan.py +3 -3
- tomwer/core/scan/edfscan.py +9 -9
- tomwer/core/scan/nxtomoscan.py +11 -11
- tomwer/core/scan/scanbase.py +31 -24
- tomwer/core/scan/test/test_future_scan.py +1 -1
- tomwer/core/scan/test/test_h5.py +4 -4
- tomwer/core/scan/test/test_process_registration.py +2 -2
- tomwer/core/scan/test/test_scan.py +1 -75
- tomwer/core/settings.py +3 -3
- tomwer/core/test/test_utils.py +2 -2
- tomwer/core/volume/edfvolume.py +6 -6
- tomwer/core/volume/hdf5volume.py +6 -6
- tomwer/core/volume/jp2kvolume.py +6 -6
- tomwer/core/volume/rawvolume.py +6 -6
- tomwer/core/volume/tiffvolume.py +12 -12
- tomwer/gui/cluster/slurm.py +14 -9
- tomwer/gui/cluster/supervisor.py +12 -0
- tomwer/gui/cluster/test/test_cluster.py +1 -2
- tomwer/gui/cluster/test/test_supervisor.py +1 -1
- tomwer/gui/control/datalist.py +5 -0
- tomwer/gui/control/datawatcher/controlwidget.py +2 -4
- tomwer/gui/control/reducedarkflatselector.py +8 -8
- tomwer/gui/control/test/test_single_tomo_obj.py +1 -1
- tomwer/gui/edit/dkrfpatch.py +4 -4
- tomwer/gui/edit/nxtomowarmer.py +2 -2
- tomwer/gui/edit/test/test_dkrf_patch.py +6 -6
- tomwer/gui/imagefromfile.py +2 -2
- tomwer/gui/qfolderdialog.py +5 -0
- tomwer/gui/reconstruction/axis/CompareImages.py +94 -168
- tomwer/gui/reconstruction/axis/radioaxis.py +58 -182
- tomwer/gui/reconstruction/darkref/darkrefwidget.py +2 -1
- tomwer/gui/reconstruction/nabu/castvolume.py +8 -1
- tomwer/gui/reconstruction/nabu/nabuconfig/reconstruction.py +54 -21
- tomwer/gui/reconstruction/normalization/intensity.py +3 -25
- tomwer/gui/reconstruction/saaxis/corrangeselector.py +1 -1
- tomwer/gui/reconstruction/saaxis/saaxis.py +1 -11
- tomwer/gui/reconstruction/sadeltabeta/saadeltabeta.py +0 -10
- tomwer/gui/reconstruction/scores/scoreplot.py +1 -6
- tomwer/gui/reconstruction/test/test_axis.py +18 -4
- tomwer/gui/reconstruction/test/test_nabu.py +3 -0
- tomwer/gui/stitching/stitching.py +2 -2
- tomwer/gui/stitching/stitching_preview.py +7 -53
- tomwer/gui/stitching/stitching_raw.py +3 -3
- tomwer/gui/utils/inputwidget.py +12 -2
- tomwer/gui/utils/lineselector/lineselector.py +1 -1
- tomwer/gui/visualization/dataviewer.py +47 -17
- tomwer/gui/visualization/sinogramviewer.py +19 -26
- tomwer/gui/visualization/test/test_volumeviewer.py +64 -66
- tomwer/gui/visualization/volumeviewer.py +105 -105
- tomwer/io/utils/h5pyutils.py +7 -3
- tomwer/io/utils/utils.py +3 -3
- tomwer/resources/gui/icons/parameters.svg +1 -1
- tomwer/resources/gui/illustrations/no_rot.svg +1 -1
- tomwer/synctools/stacks/edit/darkflatpatch.py +17 -12
- tomwer/tests/test_scripts.py +0 -3
- tomwer/third_part/WaitingOverlay.py +110 -0
- tomwer/third_part/__init__.py +0 -0
- tomwer/version.py +2 -2
- {tomwer-1.3.0.dev2.dist-info → tomwer-1.3.0rc10.dist-info}/METADATA +32 -31
- {tomwer-1.3.0.dev2.dist-info → tomwer-1.3.0rc10.dist-info}/RECORD +115 -153
- {tomwer-1.3.0.dev2.dist-info → tomwer-1.3.0rc10.dist-info}/WHEEL +1 -1
- orangecontrib/tomwer/widgets/reconstruction/TofuOW.py +0 -197
- orangecontrib/tomwer/widgets/reconstruction/icons/XY_lamino.svg +0 -168
- orangecontrib/tomwer/widgets/reconstruction/icons/XZ_lamino.svg +0 -275
- orangecontrib/tomwer/widgets/reconstruction/icons/YZ_lamino.svg +0 -182
- tomwer/app/lamino.py +0 -143
- tomwer/core/process/reconstruction/lamino/__init__.py +0 -1
- tomwer/core/process/reconstruction/lamino/tofu.py +0 -1000
- tomwer/core/process/test/test_lamino.py +0 -76
- tomwer/core/test/test_lamino.py +0 -92
- tomwer/gui/reconstruction/lamino/__init__.py +0 -31
- tomwer/gui/reconstruction/lamino/tofu/TofuOptionLoader.py +0 -107
- tomwer/gui/reconstruction/lamino/tofu/__init__.py +0 -1
- tomwer/gui/reconstruction/lamino/tofu/misc.py +0 -148
- tomwer/gui/reconstruction/lamino/tofu/projections.py +0 -896
- tomwer/gui/reconstruction/lamino/tofu/settings.py +0 -75
- tomwer/gui/reconstruction/lamino/tofu/tofu.py +0 -432
- tomwer/gui/reconstruction/lamino/tofu/tofuexpert.py +0 -567
- tomwer/gui/reconstruction/lamino/tofu/tofuoutput.py +0 -757
- tomwer/gui/reconstruction/test/test_lamino.py +0 -194
- tomwer/resources/gui/icons/lamino_parameters.svg +0 -70
- tomwer/resources/gui/illustrations/lamino_angle.png +0 -0
- tomwer/resources/gui/illustrations/lamino_angle.svg +0 -509
- tomwer/resources/gui/illustrations/lamino_beta_angle.png +0 -0
- tomwer/resources/gui/illustrations/lamino_beta_angle.svg +0 -97
- tomwer/resources/gui/illustrations/lamino_theta_angle.png +0 -0
- tomwer/resources/gui/illustrations/lamino_theta_angle.svg +0 -368
- tomwer/resources/gui/illustrations/manual_slice.png +0 -0
- tomwer/resources/gui/illustrations/manual_slice.svg +0 -221
- tomwer/resources/gui/illustrations/psi_angle.png +0 -0
- tomwer/resources/gui/illustrations/psi_angle.svg +0 -479
- tomwer/resources/gui/illustrations/rotation_center.png +0 -0
- tomwer/resources/gui/illustrations/rotation_center.svg +0 -276
- tomwer/resources/gui/illustrations/slice_stack.png +0 -0
- tomwer/resources/gui/illustrations/slice_stack.svg +0 -266
- tomwer/resources/gui/illustrations/xy_slice.png +0 -0
- tomwer/resources/gui/illustrations/xy_slice.svg +0 -269
- tomwer/resources/gui/illustrations/xz_slice.png +0 -0
- tomwer/resources/gui/illustrations/xz_slice.svg +0 -270
- tomwer/resources/gui/illustrations/yz_slice.png +0 -0
- tomwer/resources/gui/illustrations/yz_slice.svg +0 -270
- tomwer/synctools/stacks/reconstruction/lamino.py +0 -233
- /tomwer-1.3.0.dev2-py3.11-nspkg.pth → /tomwer-1.3.0rc10-py3.11-nspkg.pth +0 -0
- {tomwer-1.3.0.dev2.dist-info → tomwer-1.3.0rc10.dist-info}/LICENSE +0 -0
- {tomwer-1.3.0.dev2.dist-info → tomwer-1.3.0rc10.dist-info}/entry_points.txt +0 -0
- {tomwer-1.3.0.dev2.dist-info → tomwer-1.3.0rc10.dist-info}/namespace_packages.txt +0 -0
- {tomwer-1.3.0.dev2.dist-info → tomwer-1.3.0rc10.dist-info}/top_level.txt +0 -0
tomwer/core/process/task.py
CHANGED
@@ -46,7 +46,8 @@ from ewokscore.task import Task as _EwoksTask
|
|
46
46
|
from ewokscore.taskwithprogress import TaskWithProgress as _EwoksTaskWithProgress
|
47
47
|
from silx.io.dictdump import dicttoh5, h5todict
|
48
48
|
from silx.io.utils import h5py_read_dataset
|
49
|
-
from tomoscan.io import HDF5File
|
49
|
+
from tomoscan.io import HDF5File, get_swmr_mode
|
50
|
+
from tomwer.core.utils.locker import FileLockerManager
|
50
51
|
|
51
52
|
|
52
53
|
_logger = logging.getLogger(__name__)
|
@@ -173,19 +174,20 @@ class BaseProcessInfo:
|
|
173
174
|
:type interpretations: Union[None, dict
|
174
175
|
"""
|
175
176
|
assert process_file is not None
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
177
|
+
with FileLockerManager().get_lock(file_name=process_file):
|
178
|
+
try:
|
179
|
+
self._register_process(
|
180
|
+
process_file=process_file,
|
181
|
+
entry=entry,
|
182
|
+
process=self,
|
183
|
+
configuration=configuration,
|
184
|
+
results=results,
|
185
|
+
process_index=process_index,
|
186
|
+
interpretations=interpretations,
|
187
|
+
overwrite=overwrite,
|
188
|
+
)
|
189
|
+
except IOError as e:
|
190
|
+
_logger.error(e)
|
189
191
|
|
190
192
|
@staticmethod
|
191
193
|
def _register_process(
|
@@ -373,8 +375,8 @@ class BaseProcessInfo:
|
|
373
375
|
:return: list of _process_desc(sequence_index, configuration, results)
|
374
376
|
:rtype: list
|
375
377
|
"""
|
376
|
-
|
377
|
-
with HDF5File(process_file, mode="r", swmr=
|
378
|
+
# retrieve process to load
|
379
|
+
with HDF5File(process_file, mode="r", swmr=get_swmr_mode()) as h5f:
|
378
380
|
if entry is None:
|
379
381
|
if len(h5f.keys()) > 0:
|
380
382
|
root = h5f[list(h5f.keys())[0]]
|
@@ -382,24 +384,28 @@ class BaseProcessInfo:
|
|
382
384
|
_logger.warning("no process find")
|
383
385
|
else:
|
384
386
|
root = h5f[entry]
|
387
|
+
|
388
|
+
processes_to_load = {}
|
385
389
|
for process in root.keys():
|
386
390
|
nx_process = root[process]
|
387
391
|
if (
|
388
392
|
h5py_read_dataset(nx_process["program"])
|
389
393
|
== process_type.program_name()
|
390
394
|
):
|
391
|
-
|
392
|
-
|
393
|
-
process_file, "/".join((nx_process.name, "configuration"))
|
394
|
-
)
|
395
|
-
results = h5todict(
|
396
|
-
process_file, "/".join((nx_process.name, "results"))
|
397
|
-
)
|
398
|
-
processes.append(
|
399
|
-
_process_desc(
|
400
|
-
process_order=p_order, configuration=config, results=results
|
401
|
-
)
|
395
|
+
processes_to_load[nx_process.name] = h5py_read_dataset(
|
396
|
+
nx_process["sequence_index"]
|
402
397
|
)
|
398
|
+
|
399
|
+
# load process
|
400
|
+
processes = []
|
401
|
+
for process_name, p_order in processes_to_load.items():
|
402
|
+
config = h5todict(process_file, "/".join((process_name, "configuration")))
|
403
|
+
results = h5todict(process_file, "/".join((process_name, "results")))
|
404
|
+
processes.append(
|
405
|
+
_process_desc(
|
406
|
+
process_order=p_order, configuration=config, results=results
|
407
|
+
)
|
408
|
+
)
|
403
409
|
return processes
|
404
410
|
|
405
411
|
|
@@ -34,6 +34,7 @@ import tempfile
|
|
34
34
|
import unittest
|
35
35
|
|
36
36
|
import h5py
|
37
|
+
from tomoscan.io import get_swmr_mode
|
37
38
|
import numpy
|
38
39
|
from silx.io.utils import h5py_read_dataset
|
39
40
|
|
@@ -93,9 +94,9 @@ class TestAxisIO(unittest.TestCase):
|
|
93
94
|
)
|
94
95
|
|
95
96
|
# patch the axis process
|
96
|
-
axis_process._CALCULATIONS_METHODS[
|
97
|
-
|
98
|
-
|
97
|
+
axis_process._CALCULATIONS_METHODS[AxisMode.centered] = (
|
98
|
+
TestAxisIO._random_calc
|
99
|
+
)
|
99
100
|
|
100
101
|
axis_process.run()
|
101
102
|
out = axis_process.outputs.data
|
@@ -131,7 +132,7 @@ class TestAxis(unittest.TestCase):
|
|
131
132
|
axis_process.run()
|
132
133
|
self.assertTrue(os.path.exists(scan.process_file))
|
133
134
|
|
134
|
-
with h5py.File(scan.process_file, "r", swmr=
|
135
|
+
with h5py.File(scan.process_file, "r", swmr=get_swmr_mode()) as h5f:
|
135
136
|
self.assertTrue("entry" in h5f)
|
136
137
|
self.assertTrue("tomwer_process_0" in h5f["entry"])
|
137
138
|
group_axis = h5f["entry"]["tomwer_process_0"]
|
@@ -183,7 +184,7 @@ class TestAxis(unittest.TestCase):
|
|
183
184
|
# make sure center of position has been computed
|
184
185
|
self.assertTrue(os.path.exists(scan.process_file))
|
185
186
|
|
186
|
-
with h5py.File(scan.process_file, "r", swmr=
|
187
|
+
with h5py.File(scan.process_file, "r", swmr=get_swmr_mode()) as h5f:
|
187
188
|
self.assertTrue("entry" in h5f)
|
188
189
|
self.assertTrue("tomwer_process_0" in h5f["entry"])
|
189
190
|
group_axis = h5f["entry"]["tomwer_process_0"]
|
@@ -260,7 +261,7 @@ class TestSinogramAlgorithm(unittest.TestCase):
|
|
260
261
|
n_proj=10,
|
261
262
|
n_ini_proj=10,
|
262
263
|
create_ini_dark=True,
|
263
|
-
|
264
|
+
create_final_flat=True,
|
264
265
|
scan_range=360,
|
265
266
|
dim=dim,
|
266
267
|
).scan
|
@@ -42,7 +42,7 @@ from nxtomomill.converter import from_h5_to_nx
|
|
42
42
|
from nxtomomill.io.config.hdf5config import TomoHDF5Config
|
43
43
|
from nxtomo.nxobject.nxdetector import ImageKey
|
44
44
|
|
45
|
-
from tomoscan.io import HDF5File
|
45
|
+
from tomoscan.io import HDF5File, get_swmr_mode
|
46
46
|
from tomoscan.validator import is_valid_for_reconstruction
|
47
47
|
|
48
48
|
from tomwer.core.process.control.datalistener import DataListener
|
@@ -335,9 +335,9 @@ class NXTomoDataTransferBase(unittest.TestCase):
|
|
335
335
|
dst_scan = process.outputs.data
|
336
336
|
assert dst_scan.master_file != self.nexus_file_path
|
337
337
|
assert is_valid_for_reconstruction(dst_scan, check_values=True)
|
338
|
-
with HDF5File(src_scan.master_file, mode="r") as h5s_src:
|
338
|
+
with HDF5File(src_scan.master_file, mode="r", swmr=get_swmr_mode()) as h5s_src:
|
339
339
|
src_dataset = h5s_src["entry0000/detector/data"][...]
|
340
|
-
with HDF5File(dst_scan.master_file, mode="r") as h5s_dst:
|
340
|
+
with HDF5File(dst_scan.master_file, mode="r", swmr=get_swmr_mode()) as h5s_dst:
|
341
341
|
dst_dataset = h5s_dst["entry0000/detector/data"][...]
|
342
342
|
assert numpy.array_equal(src_dataset, dst_dataset)
|
343
343
|
|
@@ -127,7 +127,7 @@ class TestNabuIni(unittest.TestCase):
|
|
127
127
|
# check volume and slice .cfg files for nabu reconstruction are here
|
128
128
|
for file_name in (
|
129
129
|
os.path.basename(self.scan.path) + ".cfg",
|
130
|
-
os.path.basename(self.scan.path) + "
|
130
|
+
os.path.basename(self.scan.path) + "slice_000001_plane_XY" + ".cfg",
|
131
131
|
):
|
132
132
|
with self.subTest(file_name=file_name):
|
133
133
|
self.assertTrue(
|
@@ -151,7 +151,9 @@ class TestNabuIni(unittest.TestCase):
|
|
151
151
|
# check volume and slice .cfg files for nabu reconstruction are here
|
152
152
|
for file_name in (
|
153
153
|
os.path.basename(self.scan.path) + "pag_db0100.cfg",
|
154
|
-
os.path.basename(self.scan.path)
|
154
|
+
os.path.basename(self.scan.path)
|
155
|
+
+ "slice_pag_000001_db0100_plane_XY"
|
156
|
+
+ ".cfg",
|
155
157
|
):
|
156
158
|
with self.subTest(file_name=file_name):
|
157
159
|
self.assertTrue(
|
@@ -179,10 +181,13 @@ class TestNabuIni(unittest.TestCase):
|
|
179
181
|
os.path.basename(self.scan.path)
|
180
182
|
+ "slice_"
|
181
183
|
+ str(slice_index).zfill(6)
|
184
|
+
+ "_plane_XY"
|
182
185
|
+ ".cfg"
|
183
186
|
)
|
184
187
|
|
188
|
+
print("nabu_files are", nabu_files)
|
185
189
|
for ini_file in ini_files:
|
190
|
+
print("check ini_file", ini_file)
|
186
191
|
with self.subTest(file_name=ini_file):
|
187
192
|
self.assertTrue(
|
188
193
|
os.path.join(self._nabu_cfg_folder, ini_file) in nabu_files
|
@@ -220,10 +225,12 @@ class TestNabuIni(unittest.TestCase):
|
|
220
225
|
+ ".cfg"
|
221
226
|
)
|
222
227
|
# add slice ini file
|
228
|
+
# note: plane is only specify for slice.
|
223
229
|
ini_files.append(
|
224
230
|
os.path.basename(self.scan.path)
|
225
231
|
+ "slice_pag_000001_db"
|
226
232
|
+ str(int(pag_db)).zfill(4)
|
233
|
+
+ "_plane_XY"
|
227
234
|
+ ".cfg"
|
228
235
|
)
|
229
236
|
|
@@ -268,6 +275,7 @@ class TestNabuIni(unittest.TestCase):
|
|
268
275
|
+ str(slice_index).zfill(6)
|
269
276
|
+ "_db"
|
270
277
|
+ str(pag_db).zfill(4)
|
278
|
+
+ "_plane_XY"
|
271
279
|
+ ".cfg"
|
272
280
|
)
|
273
281
|
|
tomwer/core/scan/blissscan.py
CHANGED
@@ -54,7 +54,7 @@ import logging
|
|
54
54
|
from typing import Optional
|
55
55
|
|
56
56
|
from silx.io.utils import h5py_read_dataset
|
57
|
-
from tomoscan.io import HDF5File
|
57
|
+
from tomoscan.io import HDF5File, get_swmr_mode
|
58
58
|
|
59
59
|
_logger = logging.getLogger(__name__)
|
60
60
|
|
@@ -203,7 +203,7 @@ class BlissScan:
|
|
203
203
|
return True
|
204
204
|
return False
|
205
205
|
|
206
|
-
with HDF5File(file_path, mode="r", swmr=
|
206
|
+
with HDF5File(file_path, mode="r", swmr=get_swmr_mode()) as h5s:
|
207
207
|
if not isinstance(h5s, h5py.Group) or not isinstance(
|
208
208
|
h5s[entry], h5py.Group
|
209
209
|
):
|
@@ -227,7 +227,7 @@ class BlissScan:
|
|
227
227
|
return tuple()
|
228
228
|
else:
|
229
229
|
res = []
|
230
|
-
with HDF5File(file_path, mode="r", swmr=
|
230
|
+
with HDF5File(file_path, mode="r", swmr=get_swmr_mode()) as h5s:
|
231
231
|
for entry in h5s:
|
232
232
|
if BlissScan.is_bliss_valid_entry(file_path=file_path, entry=entry):
|
233
233
|
res.append(entry)
|
tomwer/core/scan/edfscan.py
CHANGED
@@ -281,9 +281,9 @@ class EDFTomoScan(_tsEDFTomoScan, TomwerScanBase):
|
|
281
281
|
files.append(gfile)
|
282
282
|
if f.endswith(".vol"):
|
283
283
|
if withIndex is True:
|
284
|
-
files[
|
285
|
-
|
286
|
-
|
284
|
+
files[EDFTomoScan.get_index_reconstructed(f, scanID)] = (
|
285
|
+
os.path.join(scanID, f)
|
286
|
+
)
|
287
287
|
else:
|
288
288
|
files.append(os.path.join(scanID, f))
|
289
289
|
return files
|
@@ -552,12 +552,12 @@ class EDFTomoScan(_tsEDFTomoScan, TomwerScanBase):
|
|
552
552
|
file_prefix=self.dataset_basename,
|
553
553
|
metadata={
|
554
554
|
"name": self.path,
|
555
|
-
"creation_time":
|
556
|
-
|
557
|
-
|
558
|
-
"modification_time":
|
559
|
-
|
560
|
-
|
555
|
+
"creation_time": (
|
556
|
+
datetime.fromtimestamp(stat.st_ctime) if stat else None
|
557
|
+
),
|
558
|
+
"modification_time": (
|
559
|
+
datetime.fromtimestamp(stat.st_ctime) if stat else None
|
560
|
+
),
|
561
561
|
},
|
562
562
|
)
|
563
563
|
|
tomwer/core/scan/nxtomoscan.py
CHANGED
@@ -45,7 +45,7 @@ from tomoscan.esrf.identifier.hdf5Identifier import (
|
|
45
45
|
)
|
46
46
|
from tomoscan.esrf.identifier.url_utils import UrlSettings, split_path, split_query
|
47
47
|
from tomoscan.esrf.scan.nxtomoscan import NXtomoScan as _tsNXtomoScan
|
48
|
-
from tomoscan.io import HDF5File
|
48
|
+
from tomoscan.io import HDF5File, get_swmr_mode
|
49
49
|
from nxtomo.nxobject.nxdetector import ImageKey
|
50
50
|
|
51
51
|
from tomwer.utils import docstring
|
@@ -169,12 +169,12 @@ class NXtomoScan(_tsNXtomoScan, TomwerScanBase):
|
|
169
169
|
entry=self.entry,
|
170
170
|
metadata={
|
171
171
|
"name": self.master_file,
|
172
|
-
"creation_time":
|
173
|
-
|
174
|
-
|
175
|
-
"modification_time":
|
176
|
-
|
177
|
-
|
172
|
+
"creation_time": (
|
173
|
+
datetime.fromtimestamp(stat.st_ctime) if stat else None
|
174
|
+
),
|
175
|
+
"modification_time": (
|
176
|
+
datetime.fromtimestamp(stat.st_ctime) if stat else None
|
177
|
+
),
|
178
178
|
},
|
179
179
|
)
|
180
180
|
|
@@ -406,9 +406,9 @@ class NXtomoScan(_tsNXtomoScan, TomwerScanBase):
|
|
406
406
|
)
|
407
407
|
self._projections_with_angles = {}
|
408
408
|
for proj_frame in proj_frames:
|
409
|
-
self._projections_with_angles[
|
410
|
-
proj_frame.
|
411
|
-
|
409
|
+
self._projections_with_angles[proj_frame.rotation_angle] = (
|
410
|
+
proj_frame.url
|
411
|
+
)
|
412
412
|
return self._projections_with_angles
|
413
413
|
|
414
414
|
@staticmethod
|
@@ -422,7 +422,7 @@ class NXtomoScan(_tsNXtomoScan, TomwerScanBase):
|
|
422
422
|
return tuple()
|
423
423
|
else:
|
424
424
|
res = []
|
425
|
-
with HDF5File(file_path, mode="r", swmr=
|
425
|
+
with HDF5File(file_path, mode="r", swmr=get_swmr_mode()) as h5s:
|
426
426
|
for entry_name, node in h5s.items():
|
427
427
|
if isinstance(node, h5py.Group):
|
428
428
|
if NXtomoScan.entry_is_nx_tomo(node):
|
tomwer/core/scan/scanbase.py
CHANGED
@@ -41,7 +41,7 @@ import numpy
|
|
41
41
|
from silx.io.url import DataUrl
|
42
42
|
from silx.utils.enum import Enum as _Enum
|
43
43
|
from tomoscan.identifier import VolumeIdentifier
|
44
|
-
from tomoscan.io import HDF5File
|
44
|
+
from tomoscan.io import HDF5File, get_swmr_mode
|
45
45
|
from tomoscan.normalization import IntensityNormalization
|
46
46
|
from tomoscan.volumebase import VolumeBase
|
47
47
|
from tomoscan.identifier import BaseIdentifier
|
@@ -65,8 +65,6 @@ class TomwerScanBase(TomwerObject):
|
|
65
65
|
|
66
66
|
_DICT_DARK_REF_KEYS = "dark_ref_params"
|
67
67
|
|
68
|
-
_DICT_LAMINO_RP_KEY = "lamino_params"
|
69
|
-
|
70
68
|
_DICT_NABU_RP_KEY = "nabu_params"
|
71
69
|
|
72
70
|
_DICT_AXIS_KEYS = "axis_params"
|
@@ -88,8 +86,6 @@ class TomwerScanBase(TomwerObject):
|
|
88
86
|
|
89
87
|
self._nabu_params = None
|
90
88
|
"""nabu reconstruction parameters"""
|
91
|
-
self._lamino_params = None
|
92
|
-
"""Set of reconstructions parameters for laminography"""
|
93
89
|
self._axis_params = None
|
94
90
|
"""Axis parameters"""
|
95
91
|
self._saaxis_params = None
|
@@ -135,7 +131,7 @@ class TomwerScanBase(TomwerObject):
|
|
135
131
|
and self.process_file is not None
|
136
132
|
and os.path.exists(self.process_file)
|
137
133
|
):
|
138
|
-
with HDF5File(self.process_file, mode="r", swmr=
|
134
|
+
with HDF5File(self.process_file, mode="r", swmr=get_swmr_mode()) as h5s:
|
139
135
|
self._process_index = len(h5s.items())
|
140
136
|
else:
|
141
137
|
self._process_index = 0
|
@@ -253,14 +249,6 @@ class TomwerScanBase(TomwerObject):
|
|
253
249
|
def nabu_recons_params(self, recons_params):
|
254
250
|
self._nabu_params = recons_params
|
255
251
|
|
256
|
-
@property
|
257
|
-
def lamino_recons_params(self):
|
258
|
-
return self._lamino_params
|
259
|
-
|
260
|
-
@lamino_recons_params.setter
|
261
|
-
def lamino_recons_params(self, recons_params):
|
262
|
-
self._lamino_params = recons_params
|
263
|
-
|
264
252
|
@property
|
265
253
|
def axis_params(self):
|
266
254
|
return self._axis_params
|
@@ -448,8 +436,6 @@ class TomwerScanBase(TomwerObject):
|
|
448
436
|
# process index
|
449
437
|
res[self._DICT_PROCESS_INDEX_KEY] = self._process_index
|
450
438
|
|
451
|
-
# lamino reconstruction parameters
|
452
|
-
res[self._DICT_LAMINO_RP_KEY] = self.lamino_recons_params
|
453
439
|
return res
|
454
440
|
|
455
441
|
def load_from_dict(self, desc):
|
@@ -468,8 +454,6 @@ class TomwerScanBase(TomwerObject):
|
|
468
454
|
raise ValueError("Description is not an EDFScan json description")
|
469
455
|
|
470
456
|
assert self.DICT_PATH_KEY in data # pylint: disable=E1101
|
471
|
-
assert self._DICT_LAMINO_RP_KEY in data
|
472
|
-
self.lamino_recons_params = data[self._DICT_LAMINO_RP_KEY]
|
473
457
|
# load axis reconstruction parameters
|
474
458
|
axis_params = data.get(self._DICT_AXIS_KEYS, None)
|
475
459
|
if axis_params is not None:
|
@@ -520,7 +504,6 @@ class TomwerScanBase(TomwerObject):
|
|
520
504
|
isinstance(other, self.__class__)
|
521
505
|
or isinstance(self, other.__class__)
|
522
506
|
and self.type == other.type # pylint: disable=E1101
|
523
|
-
and self.lamino_recons_params == other.lamino_recons_params
|
524
507
|
and self.nabu_recons_params == other.nabu_recons_params
|
525
508
|
and self.path == other.path # pylint: disable=E1101
|
526
509
|
)
|
@@ -602,8 +585,19 @@ class TomwerScanBase(TomwerObject):
|
|
602
585
|
:return: list of urls that contains reconstruction from nabu
|
603
586
|
:rtype: list
|
604
587
|
"""
|
588
|
+
from tomwer.core.process.reconstruction.output import (
|
589
|
+
PROCESS_FOLDER_NAME,
|
590
|
+
) # avoid cyclic import
|
591
|
+
|
605
592
|
all_recons_urls = set()
|
606
593
|
recons_paths = self.reconstruction_paths
|
594
|
+
if self.working_directory:
|
595
|
+
recons_paths.add(
|
596
|
+
os.path.join(
|
597
|
+
self.working_directory,
|
598
|
+
PROCESS_FOLDER_NAME,
|
599
|
+
)
|
600
|
+
)
|
607
601
|
for path in recons_paths:
|
608
602
|
all_recons_urls.update(self.get_reconstructions_urls_from_path(path))
|
609
603
|
return all_recons_urls
|
@@ -612,6 +606,17 @@ class TomwerScanBase(TomwerObject):
|
|
612
606
|
if path is None or not os.path.isdir(path):
|
613
607
|
return []
|
614
608
|
else:
|
609
|
+
|
610
|
+
from tomwer.core.process.reconstruction.saaxis.saaxis import (
|
611
|
+
DEFAULT_RECONS_FOLDER as MULTI_COR_DEFAULT_FOLDER,
|
612
|
+
)
|
613
|
+
from tomwer.core.process.reconstruction.sadeltabeta.sadeltabeta import (
|
614
|
+
DEFAULT_RECONS_FOLDER as MULTI_DB_DEFAULT_FOLDER,
|
615
|
+
)
|
616
|
+
from tomwer.core.process.reconstruction.nabu.settings import (
|
617
|
+
NABU_CFG_FILE_FOLDER,
|
618
|
+
)
|
619
|
+
|
615
620
|
res = set()
|
616
621
|
for f in os.listdir(path):
|
617
622
|
current_path = os.path.join(path, f)
|
@@ -626,10 +631,10 @@ class TomwerScanBase(TomwerObject):
|
|
626
631
|
f
|
627
632
|
in (
|
628
633
|
"matlab",
|
629
|
-
"saaxis_results",
|
630
|
-
"sadeltabeta_results",
|
631
634
|
"steps_file_basename_nabu_sinogram_save_step",
|
632
|
-
|
635
|
+
MULTI_COR_DEFAULT_FOLDER,
|
636
|
+
MULTI_DB_DEFAULT_FOLDER,
|
637
|
+
NABU_CFG_FILE_FOLDER,
|
633
638
|
)
|
634
639
|
or f.endswith("_vol")
|
635
640
|
or "slice" not in f
|
@@ -751,7 +756,7 @@ class TomwerScanBase(TomwerObject):
|
|
751
756
|
from tomwer.core.process.task import Task
|
752
757
|
|
753
758
|
if os.path.exists(self.process_file):
|
754
|
-
with HDF5File(self.process_file, mode="r") as h5s:
|
759
|
+
with HDF5File(self.process_file, mode="r", swmr=get_swmr_mode()) as h5s:
|
755
760
|
if not hasattr(self, "entry"):
|
756
761
|
entry = "entry"
|
757
762
|
else:
|
@@ -859,7 +864,9 @@ def _get_reconstructed_single_file_volume(
|
|
859
864
|
|
860
865
|
if check_url is True:
|
861
866
|
try:
|
862
|
-
with HDF5File(
|
867
|
+
with HDF5File(
|
868
|
+
os.path.abspath(file_), "r", swmr=get_swmr_mode()
|
869
|
+
) as h5f:
|
863
870
|
if entry not in h5f:
|
864
871
|
logger.info("{volume} does not exists")
|
865
872
|
return None
|
tomwer/core/scan/test/test_h5.py
CHANGED
@@ -65,9 +65,9 @@ class TestHDF5Scan(unittest.TestCase):
|
|
65
65
|
n_ini_proj=20,
|
66
66
|
n_proj=20,
|
67
67
|
n_alignement_proj=2,
|
68
|
-
|
68
|
+
create_final_flat=True,
|
69
69
|
create_ini_dark=True,
|
70
|
-
|
70
|
+
create_ini_flat=True,
|
71
71
|
n_refs=5,
|
72
72
|
).scan
|
73
73
|
self.assertEqual(scan_1.ff_interval, 20)
|
@@ -78,9 +78,9 @@ class TestHDF5Scan(unittest.TestCase):
|
|
78
78
|
n_ini_proj=10,
|
79
79
|
n_proj=10,
|
80
80
|
n_alignement_proj=2,
|
81
|
-
|
81
|
+
create_final_flat=False,
|
82
82
|
create_ini_dark=True,
|
83
|
-
|
83
|
+
create_ini_flat=True,
|
84
84
|
n_refs=1,
|
85
85
|
).scan
|
86
86
|
self.assertEqual(scan_2.ff_interval, 0)
|
@@ -32,7 +32,7 @@ import shutil
|
|
32
32
|
import tempfile
|
33
33
|
import unittest
|
34
34
|
|
35
|
-
from tomoscan.io import HDF5File
|
35
|
+
from tomoscan.io import HDF5File, get_swmr_mode
|
36
36
|
|
37
37
|
from tomwer.core.process.task import Task
|
38
38
|
from tomwer.core.utils.scanutils import MockNXtomo
|
@@ -98,7 +98,7 @@ class TestProcessRegistration(unittest.TestCase):
|
|
98
98
|
process_index=i,
|
99
99
|
)
|
100
100
|
|
101
|
-
with HDF5File(self.scan.process_file, "r", swmr=
|
101
|
+
with HDF5File(self.scan.process_file, "r", swmr=get_swmr_mode()) as h5f:
|
102
102
|
nodes = Task._get_process_nodes(
|
103
103
|
root_node=h5f[self.scan.entry], process=self.DummyProcess
|
104
104
|
)
|
@@ -1,45 +1,14 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
# /*##########################################################################
|
3
|
-
#
|
4
|
-
# Copyright (c) 2016-2017 European Synchrotron Radiation Facility
|
5
|
-
#
|
6
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
-
# of this software and associated documentation files (the "Software"), to deal
|
8
|
-
# in the Software without restriction, including without limitation the rights
|
9
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
-
# copies of the Software, and to permit persons to whom the Software is
|
11
|
-
# furnished to do so, subject to the following conditions:
|
12
|
-
#
|
13
|
-
# The above copyright notice and this permission notice shall be included in
|
14
|
-
# all copies or substantial portions of the Software.
|
15
|
-
#
|
16
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22
|
-
# THE SOFTWARE.
|
23
|
-
#
|
24
|
-
# ###########################################################################*/
|
25
|
-
|
26
|
-
__authors__ = ["H. Payno"]
|
27
|
-
__license__ = "MIT"
|
28
|
-
__date__ = "24/01/2017"
|
29
|
-
|
30
1
|
import contextlib
|
31
2
|
import logging
|
32
3
|
import os
|
33
4
|
import shutil
|
34
5
|
import tempfile
|
35
6
|
import unittest
|
36
|
-
from multiprocessing import Process
|
37
7
|
|
38
8
|
import fabio.edfimage
|
39
9
|
import numpy
|
40
10
|
|
41
11
|
from tomwer.core.process.reconstruction.nabu import nabuslices
|
42
|
-
from tomwer.core.process.task import Task
|
43
12
|
from tomwer.core.scan.edfscan import EDFTomoScan
|
44
13
|
from tomwer.core.scan.scanfactory import ScanFactory
|
45
14
|
from tomwer.core.utils.scanutils import MockEDF
|
@@ -103,6 +72,7 @@ class TestScanValidatorFindNabuFiles(unittest.TestCase):
|
|
103
72
|
pag=pag if delta_beta is not None else False,
|
104
73
|
ctf=ctf if delta_beta is not None else False,
|
105
74
|
db=delta_beta,
|
75
|
+
axis="XY",
|
106
76
|
)
|
107
77
|
with self.subTest(
|
108
78
|
slice_index=slice_index,
|
@@ -401,47 +371,3 @@ def test_get_sinogram(tmp_path):
|
|
401
371
|
sinogram_1,
|
402
372
|
numpy.array([[2, 3], [6, 7], [10, 11], [14, 15]]),
|
403
373
|
)
|
404
|
-
|
405
|
-
|
406
|
-
class TestSeveralWriteWithThreading(unittest.TestCase):
|
407
|
-
class DummyProcess(Task):
|
408
|
-
@staticmethod
|
409
|
-
def program_name():
|
410
|
-
"""Name of the program used for this processing"""
|
411
|
-
return "dummy program"
|
412
|
-
|
413
|
-
@staticmethod
|
414
|
-
def program_version():
|
415
|
-
"""version of the program used for this processing"""
|
416
|
-
return "0.0.0"
|
417
|
-
|
418
|
-
@staticmethod
|
419
|
-
def definition():
|
420
|
-
"""definition of the process"""
|
421
|
-
return "no definition"
|
422
|
-
|
423
|
-
def setUp(self):
|
424
|
-
self.tmp_dir = tempfile.mkdtemp()
|
425
|
-
self._file = os.path.join(self.tmp_dir, "XXXtomwer_processes.h5")
|
426
|
-
|
427
|
-
def tearDown(self):
|
428
|
-
shutil.rmtree(self.tmp_dir)
|
429
|
-
|
430
|
-
def testSeveralWrite(self):
|
431
|
-
processes = []
|
432
|
-
for i in range(20):
|
433
|
-
args = (
|
434
|
-
self._file,
|
435
|
-
TestSeveralWriteWithThreading.DummyProcess,
|
436
|
-
"entry0000",
|
437
|
-
{"info": "no configuration"},
|
438
|
-
{"data": numpy.random.random(2000)},
|
439
|
-
i,
|
440
|
-
None,
|
441
|
-
True,
|
442
|
-
)
|
443
|
-
processes.append(Process(target=Task._register_process, args=args))
|
444
|
-
for process in processes:
|
445
|
-
process.start()
|
446
|
-
for process in processes:
|
447
|
-
process.join()
|
tomwer/core/settings.py
CHANGED
@@ -125,7 +125,7 @@ class SlurmSettings:
|
|
125
125
|
N_JOBS = 1
|
126
126
|
"""on how many job we want to split the EwoksTask"""
|
127
127
|
|
128
|
-
MEMORY_PER_WORKER =
|
128
|
+
MEMORY_PER_WORKER = 128 # memory in GB
|
129
129
|
"""Amount of memory per worker"""
|
130
130
|
|
131
131
|
PARTITION = "p9gpu"
|
@@ -136,7 +136,7 @@ class SlurmSettings:
|
|
136
136
|
N_GPUS_PER_WORKER = 1
|
137
137
|
"""number of gpu per worker"""
|
138
138
|
|
139
|
-
PYTHON_VENV =
|
139
|
+
PYTHON_VENV = None
|
140
140
|
"""Python executable to take. Useful if compute nodes have a different environment from the front end.
|
141
141
|
"""
|
142
142
|
|
@@ -144,7 +144,7 @@ class SlurmSettings:
|
|
144
144
|
"""Slurm cluster project name. `scan`, `process` and `info` will be format.
|
145
145
|
"""
|
146
146
|
|
147
|
-
MODULES_TO_LOAD =
|
147
|
+
MODULES_TO_LOAD = ("tomotools/stable", )
|
148
148
|
|
149
149
|
SBATCH_EXTRA_PARAMS = {
|
150
150
|
"export": "NONE", # value to provide to sbatch --export={}
|