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.
Files changed (61) hide show
  1. orangecontrib/tomwer/orange/managedprocess.py +7 -0
  2. orangecontrib/tomwer/tutorials/simple_volume_to_slurm_reconstruction.ows +2 -2
  3. orangecontrib/tomwer/widgets/edit/ImageKeyUpgraderOW.py +5 -4
  4. orangecontrib/tomwer/widgets/reconstruction/AxisOW.py +19 -47
  5. orangecontrib/tomwer/widgets/reconstruction/DarkRefAndCopyOW.py +0 -2
  6. orangecontrib/tomwer/widgets/reconstruction/NabuOW.py +8 -3
  7. orangecontrib/tomwer/widgets/reconstruction/NabuVolumeOW.py +4 -6
  8. orangecontrib/tomwer/widgets/reconstruction/SAAxisOW.py +8 -4
  9. orangecontrib/tomwer/widgets/reconstruction/SADeltaBetaOW.py +0 -4
  10. orangecontrib/tomwer/widgets/reconstruction/SinoNormOW.py +1 -13
  11. tomwer/app/axis.py +0 -1
  12. tomwer/app/intensitynormalization.py +0 -14
  13. tomwer/app/multicor.py +1 -33
  14. tomwer/app/multipag.py +1 -31
  15. tomwer/app/nabuapp.py +0 -1
  16. tomwer/app/patchrawdarkflat.py +0 -3
  17. tomwer/app/reducedarkflat.py +0 -1
  18. tomwer/core/process/control/datalistener/datalistener.py +0 -232
  19. tomwer/core/process/control/datawatcher/datawatcher.py +0 -5
  20. tomwer/core/process/control/scantransfer.py +3 -60
  21. tomwer/core/process/edit/darkflatpatch.py +0 -8
  22. tomwer/core/process/edit/imagekeyeditor.py +2 -19
  23. tomwer/core/process/reconstruction/axis/axis.py +7 -18
  24. tomwer/core/process/reconstruction/darkref/darkrefs.py +0 -59
  25. tomwer/core/process/reconstruction/nabu/nabuslices.py +0 -88
  26. tomwer/core/process/reconstruction/nabu/nabuvolume.py +0 -10
  27. tomwer/core/process/reconstruction/params_cache.py +36 -0
  28. tomwer/core/process/reconstruction/saaxis/saaxis.py +80 -88
  29. tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py +78 -86
  30. tomwer/core/process/reconstruction/tests/test_params_cache.py +37 -0
  31. tomwer/core/process/script/python.py +0 -19
  32. tomwer/core/process/task.py +0 -290
  33. tomwer/core/process/tests/test_dark_and_flat.py +0 -6
  34. tomwer/core/process/tests/test_data_transfer.py +0 -1
  35. tomwer/core/process/tests/test_data_watcher.py +6 -23
  36. tomwer/core/scan/edfscan.py +0 -11
  37. tomwer/core/scan/nxtomoscan.py +0 -12
  38. tomwer/core/scan/scanbase.py +0 -81
  39. tomwer/gui/reconstruction/axis/CalculationWidget.py +3 -5
  40. tomwer/gui/reconstruction/tests/test_saaxis.py +2 -2
  41. tomwer/gui/reconstruction/tests/test_sadeltabeta.py +2 -2
  42. tomwer/gui/stitching/config/axisparams.py +2 -0
  43. tomwer/synctools/stacks/reconstruction/axis.py +0 -18
  44. tomwer/synctools/tests/test_foldertransfer.py +2 -19
  45. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_i_norm.py +110 -153
  46. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_sa_delta_beta.py +103 -153
  47. tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_saaxis.py +117 -152
  48. tomwer/tests/orangecontrib/tomwer/widgets/{tests/test_darkref.py → test_darkref.py} +0 -9
  49. tomwer/tests/orangecontrib/tomwer/widgets/{tests/test_foldertransfert.py → test_foldertransfert.py} +1 -1
  50. tomwer/tests/test_ewoks/test_workflows.py +0 -4
  51. tomwer/version.py +3 -3
  52. {tomwer-1.4.0rc6.dist-info → tomwer-1.4.2.dist-info}/METADATA +2 -3
  53. {tomwer-1.4.0rc6.dist-info → tomwer-1.4.2.dist-info}/RECORD +58 -59
  54. tomwer/core/scan/tests/test_process_registration.py +0 -64
  55. tomwer/core/utils/Singleton.py +0 -36
  56. tomwer/core/utils/locker.py +0 -58
  57. /tomwer/tests/orangecontrib/tomwer/widgets/{tests/test_conditions.py → test_conditions.py} +0 -0
  58. {tomwer-1.4.0rc6.dist-info → tomwer-1.4.2.dist-info}/LICENSE +0 -0
  59. {tomwer-1.4.0rc6.dist-info → tomwer-1.4.2.dist-info}/WHEEL +0 -0
  60. {tomwer-1.4.0rc6.dist-info → tomwer-1.4.2.dist-info}/entry_points.txt +0 -0
  61. {tomwer-1.4.0rc6.dist-info → tomwer-1.4.2.dist-info}/top_level.txt +0 -0
@@ -8,17 +8,9 @@ from __future__ import annotations
8
8
 
9
9
  import logging
10
10
  from collections import namedtuple
11
- from datetime import datetime
12
11
 
13
- import h5py
14
- import numpy
15
12
  from ewokscore.task import Task as _EwoksTask
16
13
  from ewokscore.taskwithprogress import TaskWithProgress as _EwoksTaskWithProgress
17
- from silx.io.dictdump import dicttoh5, h5todict
18
- from silx.io.utils import h5py_read_dataset
19
- from silx.io.utils import open as open_hdf5
20
- from tomoscan.io import HDF5File
21
- from tomwer.core.utils.locker import FileLockerManager
22
14
 
23
15
 
24
16
  _logger = logging.getLogger(__name__)
@@ -31,15 +23,10 @@ _process_desc = namedtuple(
31
23
  class BaseProcessInfo:
32
24
  """Tomwer base process class"""
33
25
 
34
- _output_values = {}
35
- # TODO: look at this: not sure this is needed anymore
36
-
37
26
  def __init__(self, inputs=None):
38
27
  """
39
28
  :param return_dict: if True serialize (to_dict / from_dict functions) between each task
40
29
  """
41
- if inputs is None:
42
- inputs = {}
43
30
 
44
31
  self._scheme_title = (
45
32
  "scheme_title" # TODO: have a look, this must be get somewhere and reused ?
@@ -60,29 +47,6 @@ class BaseProcessInfo:
60
47
  # TODO: use argsparse instead of this dict ?
61
48
  raise NotImplementedError("BaseProcess is an abstract class")
62
49
 
63
- def get_output_value(self, key):
64
- """
65
-
66
- :param key:
67
- :return:
68
- """
69
- assert type(key) is str
70
- if key in self._output_values:
71
- return self._output_values[key]
72
- else:
73
- return None
74
-
75
- def clear_output_values(self):
76
- self._output_values.clear()
77
-
78
- def register_output(self, key, value):
79
- """
80
-
81
- :param key: name of the output
82
- :param value: value of the output
83
- """
84
- self._output_values[key] = value
85
-
86
50
  @staticmethod
87
51
  def program_name():
88
52
  """Name of the program used for this processing"""
@@ -113,260 +77,6 @@ class BaseProcessInfo:
113
77
  def set_configuration(self, configuration: dict) -> None:
114
78
  self._settings = configuration
115
79
 
116
- def register_process(
117
- self,
118
- process_file: str,
119
- entry: str,
120
- configuration: dict | None,
121
- results: dict | None,
122
- process_index: int,
123
- interpretations: dict | None = None,
124
- overwrite: bool = True,
125
- ) -> None:
126
- """
127
- Store the current process in the linked h5 file if any,
128
- output data stored will be the one defined by the data_keys
129
-
130
- :param process_file: where to store the processing information
131
- :param entry: entry process
132
- :param configuration: configuration of the process
133
- :param results: result of the processing
134
- :param process_index: index of the process
135
- :param overwrite: if True then overwrite the process if already
136
- exists
137
- :paramerpretations: for each result we can add a flag
138
- 'interpretation'
139
- """
140
- assert process_file is not None
141
- with FileLockerManager().get_lock(file_name=process_file):
142
- try:
143
- self._register_process(
144
- process_file=process_file,
145
- entry=entry,
146
- process=self,
147
- configuration=configuration,
148
- results=results,
149
- process_index=process_index,
150
- interpretations=interpretations,
151
- overwrite=overwrite,
152
- )
153
- except IOError as e:
154
- _logger.error(e)
155
-
156
- @staticmethod
157
- def _register_process(
158
- process_file: str,
159
- process,
160
- entry: str | None,
161
- configuration: dict | None,
162
- results: dict | None,
163
- process_index: int,
164
- interpretations: dict | None = None,
165
- overwrite: bool = True,
166
- ) -> None:
167
- """
168
- Store the current process in the linked h5 file if any,
169
- output data stored will be the one defined by the data_keys
170
-
171
- :param process: process to record
172
- :param process_file: where to store the processing information
173
- :param entry: entry process
174
- :param configuration: configuration of the process
175
- :param results: result of the processing
176
- :param process_index: index of the process
177
- :param overwrite: if True then overwrite the process if already
178
- exists
179
- :paramerpretations: for each result we can add a flag
180
- 'interpretation'
181
- """
182
- assert process_file is not None, "The process file should be defined"
183
- if interpretations is None:
184
- interpretations = {}
185
- process_name = "tomwer_process_" + str(process_index)
186
-
187
- def get_process_path():
188
- return "/".join((entry or "entry", process_name))
189
-
190
- # save it to the file (lock should be handled upper)
191
- with HDF5File(process_file, mode="a") as h5f:
192
- nx_process = h5f.require_group(get_process_path())
193
- if "NX_class" not in nx_process.attrs:
194
- nx_process.attrs["NX_class"] = "NXprocess"
195
- if overwrite:
196
- for key in (
197
- "program",
198
- "results",
199
- "version",
200
- "date",
201
- "sequence_index",
202
- "class_instance",
203
- "configuration",
204
- ):
205
- if key in nx_process:
206
- del nx_process[key]
207
-
208
- # write process information
209
- nx_process["program"] = process.program_name()
210
- nx_process["version"] = process.program_version()
211
- nx_process["date"] = datetime.now().replace(microsecond=0).isoformat()
212
- nx_process["sequence_index"] = numpy.int32(process_index)
213
- _class = process.__class__
214
- nx_process["class_instance"] = ".".join(
215
- (_class.__module__, _class.__name__)
216
- )
217
-
218
- # dump result
219
- if results is not None:
220
- h5path = "/".join((get_process_path(), "results"))
221
- dicttoh5(
222
- results,
223
- h5file=process_file,
224
- h5path=h5path,
225
- update_mode="modify",
226
- mode="a",
227
- )
228
- for interpretation_key, interpretation in interpretations.items():
229
- try:
230
- with HDF5File(process_file, mode="a") as h5f:
231
- node = h5f["/".join((get_process_path(), "results"))]
232
- node[interpretation_key].attrs[
233
- "interpretation"
234
- ] = interpretation
235
- except KeyError:
236
- _logger.warning(
237
- "Invalid interpretation - no result store"
238
- " for %s" % interpretation_key
239
- )
240
-
241
- # dump configuration
242
- if configuration is not None:
243
- h5path = "/".join((get_process_path(), "configuration"))
244
- dicttoh5(
245
- configuration,
246
- h5file=process_file,
247
- h5path=h5path,
248
- update_mode="modify",
249
- mode="a",
250
- )
251
-
252
- with HDF5File(process_file, mode="a") as h5f:
253
- nx_process = h5f.require_group(get_process_path())
254
- nx_process["configuration"].attrs["NX_class"] = "NXcollection"
255
-
256
- @staticmethod
257
- def _get_process_nodes(
258
- root_node: h5py.Group, process, version: str = None, depth: int = 2
259
- ) -> dict:
260
- """
261
-
262
- :param root_node:
263
- :param version: version to look for (ignored for now)
264
- :return: list of process nodes [as h5py.Group]. Key is node name,
265
- value is the process index
266
- """
267
-
268
- def is_process_node(node):
269
- if node is None:
270
- return False
271
- return (
272
- node.name.split("/")[-1].startswith("tomwer_process_")
273
- and "NX_class" in node.attrs
274
- and node.attrs["NX_class"] == "NXprocess"
275
- and "program" in node
276
- and (
277
- process is None
278
- or h5py_read_dataset(node["program"]) == process.program_name()
279
- )
280
- and "version" in node
281
- and "sequence_index" in node
282
- )
283
-
284
- if isinstance(root_node, h5py.Dataset):
285
- return {}
286
- res = {}
287
- if is_process_node(root_node):
288
- res[root_node.name] = int(h5py_read_dataset(root_node["sequence_index"]))
289
-
290
- if root_node is not None:
291
- for _, node in root_node.items():
292
- if depth >= 1:
293
- res.update(
294
- Task._get_process_nodes(
295
- process=process,
296
- root_node=node,
297
- depth=depth,
298
- version=version,
299
- )
300
- )
301
- return res
302
-
303
- @staticmethod
304
- def get_most_recent_process(
305
- root_node: h5py.Group, process, version: str = None
306
- ) -> h5py.Group | None:
307
- nodes = Task._get_process_nodes(
308
- root_node=root_node, process=process, version=version, depth=1
309
- )
310
- nodes_with_time = []
311
- nodes_time = []
312
- import datetime
313
-
314
- for node_name in nodes:
315
- node = root_node[node_name]
316
- assert isinstance(node, h5py.Group), "node should be a h5py.Group"
317
- if "date" in node:
318
- nodes_with_time.append(node)
319
- nodes_time.append(
320
- datetime.datetime.fromisoformat(h5py_read_dataset(node["date"]))
321
- )
322
- if len(nodes_with_time) == 0:
323
- return None
324
- else:
325
- st = numpy.argmax(nodes_time)
326
- return nodes_with_time[st]
327
-
328
- @staticmethod
329
- def get_processes_frm_type(process_file: str, process_type, entry=None) -> list:
330
- """
331
-
332
- :param process_file: file to read
333
- :param process_type: process type we are looking for
334
- :return: list of _process_desc(sequence_index, configuration, results)
335
- """
336
- # retrieve process to load
337
- with open_hdf5(process_file) as h5f:
338
- if entry is None:
339
- if len(h5f.keys()) > 0:
340
- root = h5f[list(h5f.keys())[0]]
341
- else:
342
- _logger.warning("no process find")
343
- return []
344
- else:
345
- root = h5f[entry]
346
-
347
- processes_to_load = {}
348
- for process in root.keys():
349
- nx_process = root[process]
350
- if (
351
- h5py_read_dataset(nx_process["program"])
352
- == process_type.program_name()
353
- ):
354
- processes_to_load[nx_process.name] = h5py_read_dataset(
355
- nx_process["sequence_index"]
356
- )
357
-
358
- # load process
359
- processes = []
360
- for process_name, p_order in processes_to_load.items():
361
- config = h5todict(process_file, "/".join((process_name, "configuration")))
362
- results = h5todict(process_file, "/".join((process_name, "results")))
363
- processes.append(
364
- _process_desc(
365
- process_order=p_order, configuration=config, results=results
366
- )
367
- )
368
- return processes
369
-
370
80
 
371
81
  class TaskWithProgress(_EwoksTaskWithProgress, BaseProcessInfo):
372
82
  """Class from which all tomwer process should inherit
@@ -146,7 +146,6 @@ class TestDarkRefEdf(unittest.TestCase):
146
146
  self.recons_params = DKRFRP()
147
147
  self.recons_params.overwrite_dark = True
148
148
  self.recons_params.overwrite_ref = True
149
- self.assertFalse(os.path.exists(self.scan.process_file))
150
149
 
151
150
  def tearDown(self) -> None:
152
151
  shutil.rmtree(self.scan_folder)
@@ -169,8 +168,6 @@ class TestDarkRefEdf(unittest.TestCase):
169
168
  )
170
169
  for method, th_res in zip(method_to_test, th_results):
171
170
  with self.subTest(method=method):
172
- if os.path.exists(self.scan.process_file):
173
- os.remove(self.scan.process_file)
174
171
  process = DarkRefsTask(
175
172
  inputs={
176
173
  "dark_ref_params": self.recons_params,
@@ -204,8 +201,6 @@ class TestDarkRefEdf(unittest.TestCase):
204
201
  )
205
202
  for method, th_res in zip(method_to_test, th_results):
206
203
  with self.subTest(method=method):
207
- if os.path.exists(self.scan.process_file):
208
- os.remove(self.scan.process_file)
209
204
  self.recons_params.dark_calc_method = cMethod.NONE
210
205
  self.recons_params.flat_calc_method = method
211
206
  process = DarkRefsTask(
@@ -236,7 +231,6 @@ class TestDarkRefNx(unittest.TestCase):
236
231
  dst=self._file_path,
237
232
  )
238
233
  self.scan = NXtomoScan(scan=self._file_path, entry="entry0000")
239
- self.assertFalse(os.path.exists(self.scan.process_file))
240
234
  self.recons_params = DKRFRP()
241
235
  self.recons_params.overwrite_dark = True
242
236
  self.recons_params.overwrite_ref = True
@@ -119,7 +119,6 @@ class TestBlissDataTransfer(unittest.TestCase):
119
119
  master_sample_file=None,
120
120
  )
121
121
  self.scan = scans[0]
122
- self.assertTrue(os.path.exists(self.scan.process_file))
123
122
 
124
123
  def tearDown(self):
125
124
  shutil.rmtree(self.input_dir)
@@ -26,31 +26,14 @@ def test_data_watcher_io(tmp_path, det_method):
26
26
  scanID=str(scan_folder), nRadio=10, nRecons=1, nPagRecons=4, dim=10
27
27
  )
28
28
  data_watcher_process.setFolderObserved(str(tmp_path / "folder"))
29
- data_watcher_process.clear_output_values()
30
29
  data_watcher_process.set_serialize_output_data(True)
31
30
  LoopThread.quitEvent.clear()
32
31
  data_watcher_process.start()
32
+ time.sleep(0.5)
33
33
 
34
- # note: this quitEvent is nasty. But we don't want to spend time on the (EDF) data watcher which is not the future
34
+ data_watcher_process.stop()
35
+ data_watcher_process.waitForObservationFinished()
36
+ import gc
35
37
 
36
- timeout = 8
37
- while data_watcher_process.get_output_value("data") is None and timeout > 0:
38
- _delta = 0.5
39
- time.sleep(_delta)
40
- timeout -= _delta
41
-
42
- def quit_test():
43
- data_watcher_process.stop()
44
- data_watcher_process.waitForObservationFinished()
45
- import gc
46
-
47
- gc.collect()
48
- LoopThread.quitEvent.clear()
49
-
50
- if timeout <= 0:
51
- quit_test()
52
- raise TimeoutError("timeout expire")
53
-
54
- out = data_watcher_process.get_output_value("data")
55
- assert isinstance(out, dict)
56
- quit_test()
38
+ gc.collect()
39
+ LoopThread.quitEvent.clear()
@@ -75,8 +75,6 @@ class EDFTomoScan(_tsEDFTomoScan, TomwerScanBase):
75
75
  self.add_reconstruction_path(self.path)
76
76
 
77
77
  self._dark = None
78
- self._process_file = self.get_process_file_name(self)
79
- self._init_index_process_file(overwrite_proc_file=overwrite_proc_file)
80
78
 
81
79
  if scan is not None and update:
82
80
  try:
@@ -129,15 +127,6 @@ class EDFTomoScan(_tsEDFTomoScan, TomwerScanBase):
129
127
  )
130
128
  return EDFTomoScan(scan=identifier.folder)
131
129
 
132
- @staticmethod
133
- def get_process_file_name(scan):
134
- if scan.path is not None:
135
- basename = os.path.basename(scan.path)
136
- basename = "_".join((basename, "tomwer_processes.h5"))
137
- return os.path.join(scan.path, basename)
138
- else:
139
- return None
140
-
141
130
  def clear_caches(self):
142
131
  _tsEDFTomoScan.clear_caches(self)
143
132
  TomwerScanBase.clear_caches(self)
@@ -101,8 +101,6 @@ class NXtomoScan(_tsNXtomoScan, TomwerScanBase):
101
101
 
102
102
  self._reconstruction_urls = None
103
103
  self._projections_with_angles = None
104
- self._process_file = self.get_process_file_name(self)
105
- self._init_index_process_file(overwrite_proc_file=overwrite_proc_file)
106
104
  try:
107
105
  reduced_darks, metadata = self.load_reduced_darks(return_info=True)
108
106
  except (KeyError, OSError, ValueError):
@@ -159,16 +157,6 @@ class NXtomoScan(_tsNXtomoScan, TomwerScanBase):
159
157
  },
160
158
  )
161
159
 
162
- @staticmethod
163
- def get_process_file_name(scan):
164
- if scan.path is not None:
165
- basename, _ = os.path.splitext(scan.master_file)
166
- basename = os.path.basename(basename)
167
- basename = "_".join((basename, "tomwer_processes.h5"))
168
- return os.path.join(scan.path, basename)
169
- else:
170
- return None
171
-
172
160
  @staticmethod
173
161
  def directory_contains_scan(directory, src_pattern=None, dest_pattern=None):
174
162
  """
@@ -11,7 +11,6 @@ from typing import Iterable
11
11
  import numpy
12
12
  from silx.io.url import DataUrl
13
13
  from silx.utils.enum import Enum as _Enum
14
- from silx.io.utils import open as open_hdf5
15
14
 
16
15
  from tomoscan.identifier import VolumeIdentifier
17
16
  from tomoscan.normalization import IntensityNormalization
@@ -21,7 +20,6 @@ from tomoscan.esrf.volume.utils import guess_volumes
21
20
 
22
21
  from tomwer.core.tomwer_object import TomwerObject
23
22
  from tomwer.core.utils.ftseriesutils import orderFileByLastLastModification
24
- from tomwer.core.utils.locker import FileLockerManager
25
23
  from tomwer.io.utils.raw_and_processed_data import (
26
24
  to_raw_data_path,
27
25
  to_processed_data_path,
@@ -46,8 +44,6 @@ class TomwerScanBase(TomwerObject):
46
44
 
47
45
  _DICT_SA_DELTA_BETA_KEYS = "sa_delta_beta_params"
48
46
 
49
- _DICT_PROCESS_INDEX_KEY = "next_process_index"
50
-
51
47
  _DICT_NORMALIZATION_KEY = "norm_params"
52
48
 
53
49
  VALID_RECONS_EXTENSION = ".edf", ".npy", ".npz", ".hdf5", ".tiff", ".jp2", ".vol"
@@ -67,9 +63,6 @@ class TomwerScanBase(TomwerObject):
67
63
  """Information regarding sa_delta_beta_params"""
68
64
  self._dark_ref_params = None
69
65
  """Information regarding dark - ref reconstruction"""
70
- self._process_file = None
71
- """file storing processes applied on the scan, with their configuration
72
- and result"""
73
66
  self._cache_proj_urls = None
74
67
  """cache for the projection urls"""
75
68
  self._cache_radio_axis = {}
@@ -99,26 +92,11 @@ class TomwerScanBase(TomwerObject):
99
92
  """
100
93
  raise NotImplementedError("Base class")
101
94
 
102
- def _init_index_process_file(self, overwrite_proc_file=False):
103
- if (
104
- not overwrite_proc_file
105
- and self.process_file is not None
106
- and os.path.exists(self.process_file)
107
- ):
108
- with open_hdf5(self.process_file) as h5s:
109
- self._process_index = len(h5s.items())
110
- else:
111
- self._process_index = 0
112
-
113
95
  def clear_caches(self):
114
96
  self._cache_proj_urls = None
115
97
  self._notify_ffc_rsc_missing = True
116
98
  super().clear_caches()
117
99
 
118
- @staticmethod
119
- def get_process_file_name(scan):
120
- raise NotImplementedError("Base class")
121
-
122
100
  def _flat_field_correction(
123
101
  self,
124
102
  data,
@@ -195,13 +173,6 @@ class TomwerScanBase(TomwerObject):
195
173
  div[div == 0] = 1
196
174
  return (data - dark) / div
197
175
 
198
- def acquire_process_file_lock(self):
199
- """create a FileLocker context manager to insure safe write to the
200
- process file"""
201
- if self.process_file is None:
202
- raise ValueError("No processing file defined")
203
- return FileLockerManager().get_lock(file_name=self.process_file)
204
-
205
176
  @property
206
177
  def reconstructions(self):
207
178
  """list of reconstruction files"""
@@ -269,12 +240,6 @@ class TomwerScanBase(TomwerObject):
269
240
  """return parent basename of the directory containing the acquisition"""
270
241
  raise NotImplementedError("Base class")
271
242
 
272
- def pop_process_index(self) -> int:
273
- """Return and lock the next free process index"""
274
- process_index = self._process_index
275
- self._process_index += 1
276
- return process_index
277
-
278
243
  @functools.lru_cache(maxsize=3)
279
244
  def get_opposite_projections(self, mode) -> tuple:
280
245
  """
@@ -340,23 +305,6 @@ class TomwerScanBase(TomwerObject):
340
305
  """
341
306
  raise NotImplementedError("Base class")
342
307
 
343
- @property
344
- def process_file(self) -> str:
345
- """
346
-
347
- :return: file used to store the processes launch by tomwer
348
- """
349
- return self._process_file
350
-
351
- @property
352
- def process_file_url(self) -> DataUrl:
353
- """
354
-
355
- :return: DataUrl of the process file
356
- """
357
- entry = self.entry if hasattr(self, "entry") else "entry"
358
- return DataUrl(file_path=self._process_file, data_path=entry, scheme="silx")
359
-
360
308
  def to_dict(self):
361
309
  res = {}
362
310
  # nabu reconstruction parameters
@@ -393,8 +341,6 @@ class TomwerScanBase(TomwerObject):
393
341
  res[self._DICT_NORMALIZATION_KEY] = None
394
342
  else:
395
343
  res[self._DICT_NORMALIZATION_KEY] = self.intensity_normalization.to_dict()
396
- # process index
397
- res[self._DICT_PROCESS_INDEX_KEY] = self._process_index
398
344
 
399
345
  return res
400
346
 
@@ -450,8 +396,6 @@ class TomwerScanBase(TomwerObject):
450
396
  sa_delta_beta_params
451
397
  )
452
398
 
453
- self._process_index = data[self._DICT_PROCESS_INDEX_KEY]
454
-
455
399
  def equal(self, other):
456
400
  """
457
401
 
@@ -720,31 +664,6 @@ class TomwerScanBase(TomwerObject):
720
664
  else:
721
665
  return None
722
666
 
723
- def set_process_index_frm_tomwer_process_file(self):
724
- """
725
- Set the process_index to the last index find in the tomwer_process_file
726
- + 1
727
- """
728
- from tomwer.core.process.task import Task
729
-
730
- if os.path.exists(self.process_file):
731
- with open_hdf5(self.process_file) as h5s:
732
- if not hasattr(self, "entry"):
733
- entry = "entry"
734
- else:
735
- entry = self.entry
736
- if entry in h5s:
737
- node = h5s[entry]
738
- pn = Task._get_process_nodes(
739
- root_node=node, process=None, version=None
740
- )
741
- indexes = pn.values()
742
- if len(indexes) > 0:
743
- self._process_index = max(indexes) + 1
744
- logger.debug(
745
- f"set process_index from tomwer process file to {self._process_index}"
746
- )
747
-
748
667
  def get_nabu_dataset_info(self, binning=1, binning_z=1, proj_subsampling=1) -> dict:
749
668
  """
750
669
 
@@ -180,10 +180,6 @@ class CalculationWidget(qt.QWidget):
180
180
  return axis_mode.AxisMode.from_value(self._qcbPosition.currentText())
181
181
 
182
182
  def setMode(self, mode: axis_mode.AxisMode):
183
- if mode == self.getMode():
184
- # when set mode the estimated cor might changed.
185
- # that we want to avoid.
186
- return
187
183
  with block_signals(self._qcbPosition):
188
184
  index = self._qcbPosition.findText(mode.value)
189
185
  if index >= 0:
@@ -211,7 +207,9 @@ class CalculationWidget(qt.QWidget):
211
207
  self._axis_params_changed()
212
208
 
213
209
  def _axis_params_changed(self, *args, **kwargs):
214
- self.setMode(self._axis_params.mode)
210
+ if self._axis_params.mode != self.getMode():
211
+ # setMode will force to update visible side. So avoid to reset it if not necessary
212
+ self.setMode(self._axis_params.mode)
215
213
 
216
214
  def setScan(self, scan: TomwerScanBase | None):
217
215
  self._estimatedCorWidget.setPixelSize(pixel_size_m=scan.x_pixel_size)
@@ -140,7 +140,7 @@ class TestSAAxisWindow(TestCaseQt):
140
140
  conf = SAAxisParams.from_dict(conf)
141
141
  self.assertEqual(conf.slice_indexes, "middle")
142
142
  self.assertEqual(conf.file_format, "hdf5")
143
- self.assertTrue(isinstance(conf.nabu_params, dict))
143
+ self.assertTrue(isinstance(conf.nabu_recons_params, dict))
144
144
  for key in (
145
145
  "preproc",
146
146
  "reconstruction",
@@ -150,7 +150,7 @@ class TestSAAxisWindow(TestCaseQt):
150
150
  "phase",
151
151
  ):
152
152
  with self.subTest(key=key):
153
- self.assertTrue(key in conf.nabu_params)
153
+ self.assertTrue(key in conf.nabu_recons_params)
154
154
  self.assertEqual(conf._dry_run, False)
155
155
  self.assertEqual(conf.mode, ReconstructionMode.VERTICAL)
156
156
  self.assertEqual(conf.score_method, ScoreMethod.TV_INVERSE)
@@ -72,7 +72,7 @@ class TestSADeltaBetaWindow(TestCaseQt):
72
72
  # the configuration should be convertible to
73
73
  conf = SADeltaBetaParams.from_dict(conf)
74
74
  self.assertEqual(conf.slice_indexes, "middle")
75
- self.assertTrue(isinstance(conf.nabu_params, dict))
75
+ self.assertTrue(isinstance(conf.nabu_recons_params, dict))
76
76
  for key in (
77
77
  "preproc",
78
78
  "reconstruction",
@@ -82,7 +82,7 @@ class TestSADeltaBetaWindow(TestCaseQt):
82
82
  "phase",
83
83
  ):
84
84
  with self.subTest(key=key):
85
- self.assertTrue(key in conf.nabu_params)
85
+ self.assertTrue(key in conf.nabu_recons_params)
86
86
  self.assertEqual(conf._dry_run, False)
87
87
  self.assertEqual(conf.score_method, ScoreMethod.TV_INVERSE)
88
88
  self.assertEqual(conf.output_dir, None)
@@ -119,6 +119,8 @@ class StitcherAxisParams(qt.QWidget):
119
119
  for option in options:
120
120
  clean_option = option.rstrip(" ").lstrip(" ")
121
121
  opt_name, opt_value = clean_option.split("=")
122
+ if opt_value == "":
123
+ continue
122
124
  if opt_name == stitching_config.KEY_IMG_REG_METHOD:
123
125
  self.setShiftSearchMethod(opt_value)
124
126
  elif opt_name == stitching_config.KEY_WINDOW_SIZE: