tomwer 1.4.3__py3-none-any.whl → 1.4.5__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.
@@ -181,21 +181,8 @@ class _StitcherThread(qt.QThread):
181
181
  },
182
182
  )
183
183
 
184
- if self._cluster_config in (None, {}):
185
- self._runLocally(task)
186
- else:
187
- self._runRemotely(task)
188
-
189
- def _runLocally(self, task):
190
- task.run()
191
-
192
- def _runRemotely(self, task):
193
184
  task.run()
194
- # wait for processing to be finished
195
- for future in task.outputs.future_tomo_obj.futures:
196
- future.result()
197
- # note: there is also a callback to aggregate result once all are finished.
198
- # so at this stage the final "nxtomo" or "volume" might not exists yet
185
+ print("stitching finished")
199
186
 
200
187
 
201
188
  class MainWindow(qt.QDialog):
@@ -15,6 +15,8 @@ import sys
15
15
  import numpy
16
16
  from silx.io.url import DataUrl
17
17
  from silx.io.utils import open as open_hdf5
18
+ from silx.gui.utils import concurrent
19
+
18
20
  from sluurp.executor import submit as submit_to_slurm_cluster
19
21
  from sluurp.job import SBatchScriptJob
20
22
  from tomoscan.io import HDF5File
@@ -41,6 +43,8 @@ from tomwer.core.scan.nxtomoscan import NXtomoScan
41
43
  from tomwer.core.scan.scanbase import TomwerScanBase
42
44
  from tomwer.core.utils.slurm import get_slurm_script_name, is_slurm_available
43
45
  from tomwer.core.volume.volumefactory import VolumeFactory
46
+ from tomwer.core.resourcemanager import HDF5VolumeManager
47
+ from tomwer.core.volume.hdf5volume import HDF5VolumeIdentifier
44
48
 
45
49
  from . import settings, utils
46
50
 
@@ -279,25 +283,43 @@ class _NabuBaseReconstructor:
279
283
  success=True,
280
284
  config=config_to_dump,
281
285
  )
282
- elif self.target is Target.LOCAL:
283
- _logger.info(f"run {info} for {self.scan} with {config_to_dump}")
284
- return self._run_nabu_locally(
285
- conf_file=config_file,
286
- file_format=file_format,
287
- config_to_dump=config_to_dump,
288
- axis=config_to_dump["reconstruction"].get("slice_plane", "XY"),
289
- )
290
- elif self.target is Target.SLURM:
291
- _logger.info(
292
- f"run {info} on slurm for {self.scan.path} with {config_to_dump}"
293
- )
294
- return self._run_nabu_on_slurm(
295
- conf_file=config_file,
296
- config_to_dump=config_to_dump,
297
- cluster_config=self.cluster_config.to_dict(),
298
- process_name=process_name,
299
- info=info,
300
- )
286
+ elif self.target in (Target.LOCAL, Target.SLURM):
287
+ axis = config_to_dump["reconstruction"].get("slice_plane", "XY")
288
+ if file_format in ("hdf5", "h5", "hdf"):
289
+ vol_identifiers = utils.get_recons_volume_identifier(
290
+ file_prefix=config_to_dump["output"]["file_prefix"],
291
+ location=config_to_dump["output"]["location"],
292
+ slice_index=None,
293
+ scan=self.scan,
294
+ file_format=file_format,
295
+ axis=axis,
296
+ )
297
+ # release potential resource lockers (like the HDF5 volume viewer)
298
+ for vol_identifier in vol_identifiers:
299
+ if isinstance(vol_identifier, HDF5VolumeIdentifier):
300
+ concurrent.submitToQtMainThread(
301
+ HDF5VolumeManager.release_resource,
302
+ vol_identifier.file_path,
303
+ )
304
+ if self.target is Target.LOCAL:
305
+ _logger.info(f"run {info} for {self.scan} with {config_to_dump}")
306
+ return self._run_nabu_locally(
307
+ conf_file=config_file,
308
+ file_format=file_format,
309
+ config_to_dump=config_to_dump,
310
+ axis=axis,
311
+ )
312
+ elif self.target is Target.SLURM:
313
+ _logger.info(
314
+ f"run {info} on slurm for {self.scan.path} with {config_to_dump}"
315
+ )
316
+ return self._run_nabu_on_slurm(
317
+ conf_file=config_file,
318
+ config_to_dump=config_to_dump,
319
+ cluster_config=self.cluster_config.to_dict(),
320
+ process_name=process_name,
321
+ info=info,
322
+ )
301
323
  else:
302
324
  raise ValueError(f"{self.target} is not recognized as a valid target")
303
325
 
@@ -362,7 +384,7 @@ class _NabuBaseReconstructor:
362
384
  self._process.kill()
363
385
  outs, errs = self._process.communicate()
364
386
 
365
- recons_urls = utils.get_recons_volume_identifier(
387
+ recons_vol_identifiers = utils.get_recons_volume_identifier(
366
388
  file_prefix=config_to_dump["output"]["file_prefix"],
367
389
  location=config_to_dump["output"]["location"],
368
390
  slice_index=None,
@@ -372,7 +394,7 @@ class _NabuBaseReconstructor:
372
394
  )
373
395
  return ResultsLocalRun(
374
396
  success=not nabu_std_err_has_error(errs),
375
- results_identifiers=recons_urls,
397
+ results_identifiers=recons_vol_identifiers,
376
398
  std_out=outs,
377
399
  std_err=errs,
378
400
  config=config_to_dump, # config_slices,
@@ -12,6 +12,7 @@ from nabu.pipeline.fullfield.nabu_config import (
12
12
  )
13
13
  from silx.utils.enum import Enum as _Enum
14
14
 
15
+ from tomoscan.identifier import VolumeIdentifier
15
16
  import tomwer.version
16
17
  from tomwer.core.process.reconstruction.nabu.plane import NabuPlane
17
18
  from tomwer.core.scan.edfscan import EDFTomoScan
@@ -100,7 +101,7 @@ def get_recons_volume_identifier(
100
101
  scan: TomwerScanBase,
101
102
  slice_index: int | None,
102
103
  axis: NabuPlane,
103
- ) -> tuple:
104
+ ) -> tuple[VolumeIdentifier]:
104
105
  """
105
106
  return tuple of DataUrl for existings slices
106
107
  """
@@ -160,19 +161,6 @@ def get_recons_volume_identifier(
160
161
  ),
161
162
  )
162
163
 
163
- # case of the multitiff. Not handled by tomwer
164
- # elif file_format == "tiff":
165
- # # for single frame tiff nabu uses another convention by saving it 'directly'.
166
- # volumes = (
167
- # MultiTIFFVolume(
168
- # file_path=os.path.join(
169
- # location,
170
- # file_prefix,
171
- # ".".join([file_prefix, file_format]),
172
- # ),
173
- # ),
174
- # )
175
-
176
164
  else:
177
165
  raise ValueError(f"file format not managed: {file_format}")
178
166
 
@@ -26,7 +26,6 @@ from processview.core.superviseprocess import SuperviseProcess
26
26
  from tomwer.core.process.task import Task
27
27
  from tomwer.core.scan.nxtomoscan import NXtomoScan
28
28
  from tomwer.core.scan.scanfactory import ScanFactory
29
- from tomwer.core.futureobject import FutureTomwerObject
30
29
  from tomwer.core.volume.volumefactory import VolumeFactory
31
30
 
32
31
 
@@ -135,32 +134,24 @@ class StitcherTask(
135
134
  stitching_config=config,
136
135
  progress_bars=slurm_job_progress_bars,
137
136
  )
138
- for future in futures.values():
139
- # TODO: do we ned to make sure the processing is not finished yet ?
140
- future.add_done_callback(data_aggregation.onePartFinished)
137
+ # will wait and provide feedback until the stitching is completed.
138
+ data_aggregation.process()
141
139
 
142
140
  if config.stitching_type is StitchingType.Z_PREPROC:
143
141
  output_nx_tomo_file = config.output_file_path
144
142
  output_nx_tomo_entry = config.output_data_path
145
- tomwer_scan = NXtomoScan(
143
+ self.outputs.data = NXtomoScan(
146
144
  scan=output_nx_tomo_file, entry=output_nx_tomo_entry
147
145
  )
148
- self.outputs.future_tomo_obj = FutureTomwerObject(
149
- tomo_obj=tomwer_scan,
150
- futures=tuple(futures.values()),
151
- )
152
- self.outputs.data = None
146
+ self.outputs.future_tomo_obj = None
153
147
  self.outputs.volume = None
154
148
 
155
149
  elif config.stitching_type is StitchingType.Z_POSTPROC:
156
150
  tomwer_volume = VolumeFactory.create_tomo_object_from_identifier(
157
151
  config.output_volume.get_identifier().to_str()
158
152
  )
159
- self.outputs.future_tomo_obj = FutureTomwerObject(
160
- tomo_obj=tomwer_volume,
161
- futures=tuple(futures.values()),
162
- )
163
- self.outputs.volume = None
153
+ self.outputs.future_tomo_obj = None
154
+ self.outputs.volume = tomwer_volume
164
155
  self.outputs.data = None
165
156
 
166
157
 
@@ -171,7 +162,7 @@ class StitchingPostProcAggregation(_StitchingPostProcAggregation):
171
162
 
172
163
  def __init__(self, *args, **kwargs) -> None:
173
164
  super().__init__(*args, **kwargs)
174
- self._n_finished = 0
165
+ print("creates StitchingPostProcAggregation")
175
166
 
176
167
  if isinstance(self.stitching_config, dict):
177
168
  stitching_type = StitchingType.from_value(
@@ -192,10 +183,6 @@ class StitchingPostProcAggregation(_StitchingPostProcAggregation):
192
183
  f"stitching_config is expected to be an instance of {StitchingConfiguration}. {type(self.stitching_config)} provided instead"
193
184
  )
194
185
 
195
- def onePartFinished(self, *args, **kwargs):
196
- self._n_finished += 1
197
- # note: for now we only consider the user of the futures.
198
- # if users want to only run post-processing agregation then they will use the nabu CLI for it.
199
- if self._n_finished == len(self._futures):
200
- _logger.info("All slurm job finished. Will aggregate results")
201
- self.process()
186
+ def process(self):
187
+ super().process()
188
+ _logger.info("Stitching finished.")
@@ -0,0 +1,33 @@
1
+ class BaseResourceObserver:
2
+ """base class of the resource observer"""
3
+
4
+ def release_resource(self, resource):
5
+ raise NotImplementedError("Base class")
6
+
7
+
8
+ class _DummyResourceManager:
9
+ """
10
+ Simple resource manager. It holds a set of observer tha must release a resource when requested
11
+ Observers must implement the 'BaseResourceObserver'
12
+ """
13
+
14
+ def __init__(self):
15
+ self._observers = set()
16
+
17
+ def register(self, observer):
18
+ """Register a process to be notified when the resource should be released."""
19
+ if observer not in self._observers:
20
+ self._observers.add(observer)
21
+
22
+ def unregister(self, observer):
23
+ """Unregister a process so it won't be notified anymore."""
24
+ if observer in self._observers:
25
+ self._observers.remove(observer)
26
+
27
+ def release_resource(self, resource: str):
28
+ """Force all observer to release the given resource"""
29
+ for observer in self._observers:
30
+ observer.release_resource(resource)
31
+
32
+
33
+ HDF5VolumeManager = _DummyResourceManager()
@@ -211,7 +211,7 @@ class _PositionInfoWidget(qt.QWidget):
211
211
  else:
212
212
  value = float(self._relativePositionQLE.text())
213
213
  # make sure we only emit the signal if the value changed (and when the Qline has been edited).
214
- if self._axis_params.relative_cor_value is None or (
214
+ if isinstance(self._axis_params.relative_cor_value, (type(None), str)) or (
215
215
  self._axis_params is not None
216
216
  and not numpy.isclose(
217
217
  value, self._axis_params.relative_cor_value, atol=1e-3
@@ -95,6 +95,7 @@ class _NabuPhaseConfig(qt.QWidget, base._NabuStageConfigBase):
95
95
  self._unsharpOpts.setDiscourageUnsharpMask(
96
96
  self.getMethod() is _NabuPhaseMethod.NONE
97
97
  )
98
+ self._unsharpOpts._updateUnsharpMaskWarning()
98
99
  self.sigConfChanged.emit("method")
99
100
 
100
101
  def _signalConfChanged(self, param):
@@ -6,6 +6,8 @@ import h5py
6
6
 
7
7
  import numpy
8
8
  import numpy.lib.npyio
9
+
10
+ import os
9
11
  import silx
10
12
  from silx.gui import qt
11
13
  from silx.gui.colors import Colormap
@@ -18,6 +20,7 @@ from tomwer.core.volume.volumefactory import VolumeFactory
18
20
  from tomwer.core.scan.scanbase import TomwerScanBase
19
21
  from tomwer.gui.visualization.reconstructionparameters import ReconstructionParameters
20
22
  from tomwer.core.volume.hdf5volume import HDF5Volume
23
+ from tomwer.core.resourcemanager import BaseResourceObserver, HDF5VolumeManager
21
24
  from tomoscan.identifier import VolumeIdentifier
22
25
 
23
26
  from silx.gui.widgets.WaitingOverlay import WaitingOverlay
@@ -215,9 +218,9 @@ class _TomoApplicationContext(DataViewHooks):
215
218
  return self.__defaultColormapDialog
216
219
 
217
220
 
218
- class VolumeViewer(qt.QMainWindow):
221
+ class VolumeViewer(qt.QMainWindow, BaseResourceObserver):
219
222
  def __init__(self, parent):
220
- qt.QMainWindow.__init__(self, parent)
223
+ super().__init__(parent)
221
224
 
222
225
  self._volume_loaded_in_background = (None, None)
223
226
  # store the volume loaded in the background and the thread used for it as (volume_identifier, thread)
@@ -259,6 +262,8 @@ class VolumeViewer(qt.QMainWindow):
259
262
  loading data on the fly and avoid loading everything into memory for
260
263
  hdf5."""
261
264
  self.__last_mode = None
265
+ # register the viewer as observer of the HDF5 volume (handle resource conflict)
266
+ HDF5VolumeManager.register(self)
262
267
 
263
268
  def _close_h5_file(self):
264
269
  if self._h5_file is not None:
@@ -266,9 +271,21 @@ class VolumeViewer(qt.QMainWindow):
266
271
  self._h5_file = None
267
272
 
268
273
  def close(self):
274
+ HDF5VolumeManager.unregister(self)
269
275
  self._close_h5_file()
270
276
  super().close()
271
277
 
278
+ def release_resource(self, resource: str):
279
+ if self._h5_file is not None and resource in (
280
+ self._h5_file.filename,
281
+ os.path.abspath(self._h5_file.filename),
282
+ ):
283
+ _logger.warning(
284
+ f"{resource} about to be overwrite. Closing resource and cleaning plot."
285
+ )
286
+ self._close_h5_file()
287
+ self.clear()
288
+
272
289
  def setScan(self, scan):
273
290
  self.clear()
274
291
  if scan is None:
@@ -276,7 +293,6 @@ class VolumeViewer(qt.QMainWindow):
276
293
 
277
294
  elif len(scan.latest_vol_reconstructions) == 0:
278
295
  _logger.warning(f"No reconstructed volume for {scan}")
279
- self.clear()
280
296
  self._infoWidget.setScan(scan)
281
297
  else:
282
298
  self._set_volumes(volumes=scan.latest_vol_reconstructions)
tomwer/version.py CHANGED
@@ -77,7 +77,7 @@ RELEASE_LEVEL_VALUE = {
77
77
 
78
78
  MAJOR = 1
79
79
  MINOR = 4
80
- MICRO = 3
80
+ MICRO = 5
81
81
  RELEV = "final" # <16
82
82
  SERIAL = 0 # <16
83
83
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tomwer
3
- Version: 1.4.3
3
+ Version: 1.4.5
4
4
  Summary: "tomography workflow tools"
5
5
  Home-page: https://gitlab.esrf.fr/tomotools/tomwer
6
6
  Author: Henri Payno, Pierre Paleo, Pierre-Olivier Autran, Jérôme Lesaint, Alessandro Mirone
@@ -220,7 +220,7 @@ orangecontrib/tomwer/widgets/visualization/tests/__init__.py,sha256=47DEQpj8HBSa
220
220
  tomwer/__init__.py,sha256=GeLSeY4__z-HQZu1y4ptZ5Y1OeXFvG8kuEwWXhkeaMA,360
221
221
  tomwer/__main__.py,sha256=7tCADiS4u7k1PCxFhlRAcYSIOpxQTGUTx8sCEQ-hi1E,8707
222
222
  tomwer/utils.py,sha256=7h7dEgKAEUmQ43jkULvC1B9Adl55nkCty-SEKUKCl4U,7008
223
- tomwer/version.py,sha256=a1loEqEj9NVb3IVtlWL8YHxJkt3I_gA4e_oclG0NANo,4386
223
+ tomwer/version.py,sha256=YCgU5UeQQFVVtrqoIyPtoYMjDfnF7xbfD1Fop0kLlSA,4386
224
224
  tomwer/app/__init__.py,sha256=RYMB2YhbQaoMXC8W-oOyfZ_Y1vmHD7L13YkKeAMuShM,85
225
225
  tomwer/app/axis.py,sha256=OhDgMj_gS-45PnjKBTyOCOkmZ1Iy-Tb6Dj66mzQg0sU,5827
226
226
  tomwer/app/canvas.py,sha256=sM368nniUwbQXLA-oNCg1iNwMMol_ZGTKbiw8WsC4yw,1539
@@ -253,9 +253,10 @@ tomwer/app/canvas_launcher/splash.py,sha256=cpUuZVKwlQbeAWfAqjpjP4q1v1MmkfxU6WWl
253
253
  tomwer/app/canvas_launcher/utils.py,sha256=4zWaao2EW5OcKomAw38YUIUgOLfkUPGdPCqLsfD1NMI,1031
254
254
  tomwer/app/canvas_launcher/widgetsscheme.py,sha256=9Or1KMmSxIs_dJmJGV0Xhjg9HH4m8aPGbtiEuK2i6q0,2744
255
255
  tomwer/app/stitching/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
256
- tomwer/app/stitching/common.py,sha256=-CztPRSwIAHocNIDksBdbRWALsy9G5aRFiG9b78vtlg,15203
256
+ tomwer/app/stitching/common.py,sha256=TCXNnAz2MSJrrogB5iWptktxq-g5ED2FUt_jMnDXpnQ,14723
257
257
  tomwer/core/__init__.py,sha256=ry3BZxaZzsbjymW1wqPcKROzJO9ePkiiqWp1JRVOrS8,72
258
258
  tomwer/core/futureobject.py,sha256=YQE6zROyDFu2PYBI7hxZKpn-K_FqZQ9xGSIyqMErK5U,5114
259
+ tomwer/core/resourcemanager.py,sha256=VLNnVodMa-HOMZhN2qpUR_L6phJ8IHPUEPYMxuW6VHg,1067
259
260
  tomwer/core/settings.py,sha256=57qD44LU_3eB50rD7RHdg5nBweiHerzWbXHcBUna6gY,4089
260
261
  tomwer/core/signal.py,sha256=I5TUcyeBZzrEh1SFGs-ylJSL1aBs41ZFb3IJo3O_55c,6115
261
262
  tomwer/core/tomwer_object.py,sha256=rIaD1QlN3Q0cR5h9Sap1Whn4lawu5z9zZ1KspdhYbg0,2023
@@ -334,14 +335,14 @@ tomwer/core/process/reconstruction/darkref/settings.py,sha256=35jliuOIjMKTOJjgn4
334
335
  tomwer/core/process/reconstruction/nabu/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
335
336
  tomwer/core/process/reconstruction/nabu/castvolume.py,sha256=4VEVnJxWfG8_Ku2uhUSQAgGfvP_08mXswmC3bHU7E4M,9317
336
337
  tomwer/core/process/reconstruction/nabu/helical.py,sha256=gauUkoPiShvnvMQrCQXv28g0yLe-GceML5kYMSXmNIg,1997
337
- tomwer/core/process/reconstruction/nabu/nabucommon.py,sha256=s1KxEzHQJ09JEWP3_EvKFe51k1boi_a8YRlbs3TppdE,23338
338
+ tomwer/core/process/reconstruction/nabu/nabucommon.py,sha256=-rXMJmLL3e7BCF4keT7JcKmC5SuJQsCrvIDCYcbum48,24519
338
339
  tomwer/core/process/reconstruction/nabu/nabuscores.py,sha256=e5tRG1QtmVAdXb8KHMTMtBXA3KQXqKKcqipY2HzMURg,25275
339
340
  tomwer/core/process/reconstruction/nabu/nabuslices.py,sha256=WAmNlfyRWL0zhEE8jMjMg7WyzPM4BcBA6bWpaH8O53A,32101
340
341
  tomwer/core/process/reconstruction/nabu/nabuvolume.py,sha256=Fn0tkPDTDJQaMEJA4LzpPp0ZtG4MIu9YN82-jesxRKo,20052
341
342
  tomwer/core/process/reconstruction/nabu/plane.py,sha256=366gWprWw8Rlob8jsMn753CqgudruvvVauU0ihH2lU4,400
342
343
  tomwer/core/process/reconstruction/nabu/settings.py,sha256=3AJpxVQbJziw4v6F26Ppz8Q9vc9ZNepTWygqpCAbIEM,955
343
344
  tomwer/core/process/reconstruction/nabu/target.py,sha256=59BbpzpBRVKEpZowcZVgdAj1GLKZGVJ52s3XA7ouLPs,122
344
- tomwer/core/process/reconstruction/nabu/utils.py,sha256=MvGMeAKrpSzScvRowe2ZbyQyNLj80vxm3jk-ldMMPEU,16519
345
+ tomwer/core/process/reconstruction/nabu/utils.py,sha256=ymORZjJR7YkQ0VBujDyptF0xXzkj1dCwo29NjXvhA2E,16140
345
346
  tomwer/core/process/reconstruction/nabu/test/test_castvolume.py,sha256=v7USCU3z0zeW4TPs-slNJJei6t6B_UeqeJG5MV9qRII,3881
346
347
  tomwer/core/process/reconstruction/nabu/test/test_nabu_utils.py,sha256=8HpR_1iLkE32GYYaOyS84SR7_5nh1e48E3W4N34666g,15347
347
348
  tomwer/core/process/reconstruction/nabu/test/test_nabunormalization.py,sha256=5rHDwUROEBlsEFsZoy8mmcdRpziEetF9g_oFyxlvS6k,6010
@@ -374,7 +375,7 @@ tomwer/core/process/script/python.py,sha256=NScx6DtRA6m71jciiN6a7QIr3ICWmo3rXJY1
374
375
  tomwer/core/process/script/tests/test_script.py,sha256=1uku23G5_6JEjohI53FZyLpTjkmfsdGrwX__5Mr3DBg,1024
375
376
  tomwer/core/process/stitching/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
376
377
  tomwer/core/process/stitching/metadataholder.py,sha256=QWo04TRsGFg1MdydLvuuK1C2ICRXNwL1oK32JXB1dE8,6530
377
- tomwer/core/process/stitching/nabustitcher.py,sha256=DQTmCqOvcei9S9eu-H9NoVXBcBQf6DRxYOJO2Nn50QY,8129
378
+ tomwer/core/process/stitching/nabustitcher.py,sha256=wJGCpPIcBQXv-g6F6kxchEtcMEiqMGsq-r0Nq36aKmo,7422
378
379
  tomwer/core/process/stitching/tests/test_metadataholder.py,sha256=E9jgvtwdbcF9tgWS3uqHppHf8ff0aCvjROrLAFVZSpQ,631
379
380
  tomwer/core/process/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
380
381
  tomwer/core/process/tests/test_conditions.py,sha256=FBmBn3fvMW2H27ZLVnyYyS1bnfCb9v86WnWDw46WbMo,2140
@@ -545,7 +546,7 @@ tomwer/gui/reconstruction/axis/AxisSettingsWidget.py,sha256=7GpHteE2j9RUo-jUQoJd
545
546
  tomwer/gui/reconstruction/axis/AxisWidget.py,sha256=nkORZHLo8D3Sk8j-8QVr9l3Qse66s-Nv-tB6kCkSMTY,19794
546
547
  tomwer/gui/reconstruction/axis/CalculationWidget.py,sha256=E9zwJ2dNnc7KGH1QHRZE2eElIzj_r4GbPCIG_hn2yhw,8628
547
548
  tomwer/gui/reconstruction/axis/CompareImages.py,sha256=jqzlMBU_tfIdR1yHuZa8Avt8Te0EPBkjI6R4TY6kIlw,11425
548
- tomwer/gui/reconstruction/axis/ControlWidget.py,sha256=DsBPFIEZCva-JPUFxORjkAnoYfgb5udfJ71W-fCwgRY,10686
549
+ tomwer/gui/reconstruction/axis/ControlWidget.py,sha256=w2kNLuIhQhGT3KpEYWWq4XJks3Kr7R2aOPCTKz4je4U,10709
549
550
  tomwer/gui/reconstruction/axis/EstimatedCORWidget.py,sha256=dL9SCjPEZ7MQLGZP0gZARb-rxD8YYSl-gcFyuN14jwg,17081
550
551
  tomwer/gui/reconstruction/axis/EstimatedCorComboBox.py,sha256=Hq8o6X5-iVMqltGcpy2E5OpCP5nNV353Mepsf_R7zVY,4434
551
552
  tomwer/gui/reconstruction/axis/InputWidget.py,sha256=UhEWL3aJG56PfkI7DKw-sBd6hDsRJ2NnQ0XN0nBmM6g,13052
@@ -568,7 +569,7 @@ tomwer/gui/reconstruction/nabu/nabuconfig/base.py,sha256=ZsfZORtztbZRIGmcX5bJGlV
568
569
  tomwer/gui/reconstruction/nabu/nabuconfig/ctf.py,sha256=z7mqBt77Y81gO7GO1OsXG3iGxcgSKNYLAjxlG-uC0K8,13142
569
570
  tomwer/gui/reconstruction/nabu/nabuconfig/nabuconfig.py,sha256=rJXFMr_dlTekd0mCbzzg7b7L2QJrLthDHX6JK1zkZTc,9059
570
571
  tomwer/gui/reconstruction/nabu/nabuconfig/output.py,sha256=0SShYqvFj-motxTw20e3I1Z0WiierSqgOsN15qwe-TY,11907
571
- tomwer/gui/reconstruction/nabu/nabuconfig/phase.py,sha256=3SPSokMuE4wvoKTn-aFStln__sjewcpG7H9oJY4x5qs,16239
572
+ tomwer/gui/reconstruction/nabu/nabuconfig/phase.py,sha256=h4F0qtKXOeligVuqKa-pBAvP2ol2EgfSRHjxvsQkvAQ,16293
572
573
  tomwer/gui/reconstruction/nabu/nabuconfig/preprocessing.py,sha256=lmL2UTL7gt20nbDv921SFIAnVoJkumafSCjqTE4zGlY,32608
573
574
  tomwer/gui/reconstruction/nabu/nabuconfig/reconstruction.py,sha256=bGCF7bJBfnh0xh4zcWpqhLrzqHuG32F-Tn4xHVQny3M,41151
574
575
  tomwer/gui/reconstruction/nabu/test/test_cast_volume.py,sha256=kup5JVKNN4QZOXYGco1ZRb_4TWrXAQOtfuQcqTpraA0,2764
@@ -668,7 +669,7 @@ tomwer/gui/visualization/scanoverview.py,sha256=boXasH759jc8p9v43nFqq6oxFGDMn8gg
668
669
  tomwer/gui/visualization/sinogramviewer.py,sha256=M91xw63ptfG1erPt6jvFH5uqmV6KUm1B4xreco6Ixto,8380
669
670
  tomwer/gui/visualization/tomoobjoverview.py,sha256=8tsVhTZw0upDSYzE1W8VXCWMBmSFcEP7SlcGA6Nl6ig,1995
670
671
  tomwer/gui/visualization/volumeoverview.py,sha256=k0OLdw5dvbDlWFnk6I8TlrJu03dmKToCZVEtmAh_U9M,2496
671
- tomwer/gui/visualization/volumeviewer.py,sha256=nT9GXMFZ86Hy6ppCJB_HnE8jFgIyvEmUnPPY1JZau1A,17007
672
+ tomwer/gui/visualization/volumeviewer.py,sha256=CVfRj_azmrfoSztjX3l6nnQ9Yoyk9yhNbREoXRRq7eY,17648
672
673
  tomwer/gui/visualization/diffviewer/__init__.py,sha256=rZ7qOTfAChU3FouCdkZllXT9ZZqTdo1XhLZMfmOqUAE,39
673
674
  tomwer/gui/visualization/diffviewer/diffviewer.py,sha256=_MOApAnImO7cYg0-Oz8EKfJt0hWeDqusYLZ_gBrRRdk,20556
674
675
  tomwer/gui/visualization/diffviewer/shiftwidget.py,sha256=7gD_mo9P7HXklD416BScUnrQNDDqXkItgkzehqBam00,19608
@@ -903,9 +904,9 @@ tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_volume_viewer
903
904
  tomwer/tests/test_ewoks/test_conversion.py,sha256=a8cEWbErXiFCAkaapi0jeEoRKYxcFQCoa-Jr_u77_OM,3656
904
905
  tomwer/tests/test_ewoks/test_single_node_execution.py,sha256=YBUHfiAnkciv_kjj7biC5fOs7c7ofNImM_azGMn4LZM,2813
905
906
  tomwer/tests/test_ewoks/test_workflows.py,sha256=Eq80eexf5NVL7SzvwctLOaUeuQ8V3vDiFiHgbJA4Yb8,4871
906
- tomwer-1.4.3.dist-info/LICENSE,sha256=62p1wL0n9WMTu8x2YDv0odYgTqeSvTd9mQ0v6Mq7lzE,1876
907
- tomwer-1.4.3.dist-info/METADATA,sha256=Ld2sbq0AQqYvZRs3bw6o5BjDIzkFYxLOMzOXiANnUiY,13377
908
- tomwer-1.4.3.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
909
- tomwer-1.4.3.dist-info/entry_points.txt,sha256=py3ZUWvGnWGc5c7Yhw_uBTm8Fmew0BDw3aQZnWMBNZI,500
910
- tomwer-1.4.3.dist-info/top_level.txt,sha256=Yz5zKh0FPiImtzHYcPuztG1AO8-6KEpUWgoChGbA0Ys,21
911
- tomwer-1.4.3.dist-info/RECORD,,
907
+ tomwer-1.4.5.dist-info/LICENSE,sha256=62p1wL0n9WMTu8x2YDv0odYgTqeSvTd9mQ0v6Mq7lzE,1876
908
+ tomwer-1.4.5.dist-info/METADATA,sha256=0NdM0A0KYCcrCLxW5E546hD9VL2otACgkkf8UvJH6ao,13377
909
+ tomwer-1.4.5.dist-info/WHEEL,sha256=A3WOREP4zgxI0fKrHUG8DC8013e3dK3n7a6HDbcEIwE,91
910
+ tomwer-1.4.5.dist-info/entry_points.txt,sha256=py3ZUWvGnWGc5c7Yhw_uBTm8Fmew0BDw3aQZnWMBNZI,500
911
+ tomwer-1.4.5.dist-info/top_level.txt,sha256=Yz5zKh0FPiImtzHYcPuztG1AO8-6KEpUWgoChGbA0Ys,21
912
+ tomwer-1.4.5.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.6.0)
2
+ Generator: setuptools (75.7.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5