tomwer 1.2.0a1__py3-none-any.whl → 1.2.0a3__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 (219) hide show
  1. orangecontrib/tomwer/tutorials/append_raw_darks_and_flats_frames_to_NXtomos.ows +44 -0
  2. orangecontrib/tomwer/tutorials/copy_reduced_darks_and_flats_meth1.ows +55 -0
  3. orangecontrib/tomwer/tutorials/copy_reduced_darks_and_flats_meth2.ows +48 -0
  4. orangecontrib/tomwer/tutorials/default_cor_search.ows +40 -0
  5. orangecontrib/tomwer/tutorials/hello_world_python_script.ows +50 -0
  6. orangecontrib/tomwer/tutorials/simple_slice_reconstruction_on_slurm.ows +50 -0
  7. orangecontrib/tomwer/tutorials/simple_volume_to_slurm_reconstruction.ows +8 -8
  8. orangecontrib/tomwer/widgets/__init__.py +1 -1
  9. orangecontrib/tomwer/widgets/cluster/FutureSupervisorOW.py +0 -1
  10. orangecontrib/tomwer/widgets/cluster/SlurmClusterOW.py +8 -6
  11. orangecontrib/tomwer/widgets/control/AdvancementOW.py +0 -1
  12. orangecontrib/tomwer/widgets/control/DataDiscoveryOW.py +1 -6
  13. orangecontrib/tomwer/widgets/control/DataListOW.py +0 -1
  14. orangecontrib/tomwer/widgets/control/DataListenerOW.py +4 -4
  15. orangecontrib/tomwer/widgets/control/DataSelectorOW.py +0 -1
  16. orangecontrib/tomwer/widgets/control/DataTransfertOW.py +7 -7
  17. orangecontrib/tomwer/widgets/control/DataValidatorOW.py +0 -1
  18. orangecontrib/tomwer/widgets/control/DataWatcherOW.py +0 -3
  19. orangecontrib/tomwer/widgets/control/EDF2NXTomomillOW.py +3 -2
  20. orangecontrib/tomwer/widgets/control/EmailOW.py +82 -0
  21. orangecontrib/tomwer/widgets/control/FilterOW.py +3 -3
  22. orangecontrib/tomwer/widgets/control/NXTomomillOW.py +1 -1
  23. orangecontrib/tomwer/widgets/control/NotifierOW.py +0 -1
  24. orangecontrib/tomwer/widgets/control/ReduceDarkFlatSelectorOW.py +93 -0
  25. orangecontrib/tomwer/widgets/control/SingleTomoObjOW.py +29 -5
  26. orangecontrib/tomwer/widgets/control/TimerOW.py +1 -2
  27. orangecontrib/tomwer/widgets/control/TomoObjSerieOW.py +0 -1
  28. orangecontrib/tomwer/widgets/control/VolumeSelector.py +0 -1
  29. orangecontrib/tomwer/widgets/control/VolumeSymLinkOW.py +4 -10
  30. orangecontrib/tomwer/widgets/control/icons/email.png +0 -0
  31. orangecontrib/tomwer/widgets/control/icons/email.svg +58 -0
  32. orangecontrib/tomwer/widgets/control/icons/reduced_darkflat_selector.png +0 -0
  33. orangecontrib/tomwer/widgets/control/icons/reduced_darkflat_selector.svg +199 -0
  34. orangecontrib/tomwer/widgets/debugtools/DatasetGeneratorOW.py +0 -1
  35. orangecontrib/tomwer/widgets/debugtools/ObjectInspectorOW.py +0 -1
  36. orangecontrib/tomwer/widgets/edit/DarkFlatPatchOW.py +1 -2
  37. orangecontrib/tomwer/widgets/edit/ImageKeyEditorOW.py +1 -2
  38. orangecontrib/tomwer/widgets/edit/ImageKeyUpgraderOW.py +0 -1
  39. orangecontrib/tomwer/widgets/edit/NXtomoEditorOW.py +0 -1
  40. orangecontrib/tomwer/widgets/other/PythonScriptOW.py +29 -1
  41. orangecontrib/tomwer/widgets/other/TomoObjsHub.py +28 -0
  42. orangecontrib/tomwer/widgets/other/icons/hub.png +0 -0
  43. orangecontrib/tomwer/widgets/other/icons/hub.svg +113 -0
  44. orangecontrib/tomwer/widgets/reconstruction/AxisOW.py +18 -12
  45. orangecontrib/tomwer/widgets/reconstruction/CastNabuVolumeOW.py +0 -2
  46. orangecontrib/tomwer/widgets/reconstruction/DarkRefAndCopyOW.py +21 -6
  47. orangecontrib/tomwer/widgets/reconstruction/NabuOW.py +29 -7
  48. orangecontrib/tomwer/widgets/reconstruction/NabuVolumeOW.py +18 -5
  49. orangecontrib/tomwer/widgets/reconstruction/SAAxisOW.py +40 -13
  50. orangecontrib/tomwer/widgets/reconstruction/SADeltaBetaOW.py +37 -10
  51. orangecontrib/tomwer/widgets/reconstruction/SinoNormOW.py +2 -3
  52. orangecontrib/tomwer/widgets/reconstruction/TofuOW.py +5 -4
  53. orangecontrib/tomwer/widgets/stitching/StitcherOW.py +0 -1
  54. orangecontrib/tomwer/widgets/stitching/ZStitchingConfigOW.py +0 -1
  55. orangecontrib/tomwer/widgets/visualization/DataViewerOW.py +10 -4
  56. orangecontrib/tomwer/widgets/visualization/DiffViewerOW.py +1 -1
  57. orangecontrib/tomwer/widgets/visualization/LivesliceOW.py +0 -1
  58. orangecontrib/tomwer/widgets/visualization/NXtomoMetadataViewerOW.py +0 -1
  59. orangecontrib/tomwer/widgets/visualization/RadioStackOW.py +7 -5
  60. orangecontrib/tomwer/widgets/visualization/SampleMovedOW.py +1 -1
  61. orangecontrib/tomwer/widgets/visualization/SinogramViewerOW.py +0 -3
  62. orangecontrib/tomwer/widgets/visualization/SliceStackOW.py +7 -5
  63. orangecontrib/tomwer/widgets/visualization/VolumeViewerOW.py +4 -4
  64. tomwer/__main__.py +139 -5
  65. tomwer/app/axis.py +16 -5
  66. tomwer/app/canvas_launcher/config.py +1 -1
  67. tomwer/app/canvas_launcher/mainwindow.py +164 -6
  68. tomwer/app/darkref.py +10 -181
  69. tomwer/app/darkrefpatch.py +10 -131
  70. tomwer/app/diffframe.py +11 -0
  71. tomwer/app/imagekeyeditor.py +12 -19
  72. tomwer/app/intensitynormalization.py +1 -0
  73. tomwer/app/lamino.py +7 -2
  74. tomwer/app/patchrawdarkflat.py +131 -0
  75. tomwer/app/radiostack.py +10 -0
  76. tomwer/app/reducedarkflat.py +205 -0
  77. tomwer/app/saaxis.py +27 -8
  78. tomwer/app/sadeltabeta.py +29 -8
  79. tomwer/app/samplemoved.py +11 -0
  80. tomwer/app/scanviewer.py +12 -0
  81. tomwer/app/sinogramviewer.py +11 -0
  82. tomwer/app/slicestack.py +11 -0
  83. tomwer/app/zstitching.py +12 -0
  84. tomwer/core/futureobject.py +4 -2
  85. tomwer/core/process/conditions/filters.py +26 -4
  86. tomwer/core/process/control/datadiscovery.py +4 -0
  87. tomwer/core/process/control/datawatcher/datawatcher.py +5 -1
  88. tomwer/core/process/control/email.py +148 -0
  89. tomwer/core/process/control/nxtomoconcatenate.py +9 -2
  90. tomwer/core/process/control/nxtomomill.py +58 -16
  91. tomwer/core/process/control/scanselector.py +4 -0
  92. tomwer/core/process/control/scantransfer.py +52 -23
  93. tomwer/core/process/control/test/test_concatenate_nxtomos.py +1 -0
  94. tomwer/core/process/control/test/test_email.py +52 -0
  95. tomwer/core/process/control/test/test_h52nx_process.py +106 -0
  96. tomwer/core/process/control/test/test_volume_link.py +5 -4
  97. tomwer/core/process/control/timer.py +27 -6
  98. tomwer/core/process/control/tomoobjserie.py +4 -0
  99. tomwer/core/process/control/volumeselector.py +4 -0
  100. tomwer/core/process/control/volumesymlink.py +47 -8
  101. tomwer/core/process/edit/darkflatpatch.py +49 -8
  102. tomwer/core/process/edit/imagekeyeditor.py +63 -13
  103. tomwer/core/process/reconstruction/axis/__init__.py +1 -1
  104. tomwer/core/process/reconstruction/axis/axis.py +61 -41
  105. tomwer/core/process/reconstruction/axis/params.py +4 -6
  106. tomwer/core/process/reconstruction/darkref/darkrefs.py +53 -16
  107. tomwer/core/process/reconstruction/darkref/darkrefscopy.py +12 -2
  108. tomwer/core/process/reconstruction/lamino/__init__.py +1 -1
  109. tomwer/core/process/reconstruction/lamino/tofu.py +22 -2
  110. tomwer/core/process/reconstruction/nabu/nabucommon.py +93 -14
  111. tomwer/core/process/reconstruction/nabu/nabuscores.py +70 -33
  112. tomwer/core/process/reconstruction/nabu/nabuslices.py +219 -41
  113. tomwer/core/process/reconstruction/nabu/nabuvolume.py +240 -108
  114. tomwer/core/process/reconstruction/nabu/utils.py +10 -36
  115. tomwer/core/process/reconstruction/normalization/normalization.py +10 -3
  116. tomwer/core/process/reconstruction/saaxis/__init__.py +1 -0
  117. tomwer/core/process/reconstruction/saaxis/saaxis.py +564 -376
  118. tomwer/core/process/reconstruction/sadeltabeta/__init__.py +1 -0
  119. tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py +481 -268
  120. tomwer/core/process/reconstruction/scores/params.py +21 -8
  121. tomwer/core/process/reconstruction/test/test_darkref_copy.py +2 -0
  122. tomwer/core/process/reconstruction/test/test_saaxis.py +21 -8
  123. tomwer/core/process/reconstruction/test/test_sadeltabeta.py +8 -5
  124. tomwer/core/process/script/python.py +7 -2
  125. tomwer/core/process/stitching/nabustitcher.py +10 -3
  126. tomwer/core/process/task.py +2 -9
  127. tomwer/core/process/test/test_axis.py +25 -15
  128. tomwer/core/process/test/test_conditions.py +6 -6
  129. tomwer/core/process/test/test_dark_and_flat.py +20 -15
  130. tomwer/core/process/test/test_data_transfer.py +8 -8
  131. tomwer/core/process/test/test_data_watcher.py +1 -1
  132. tomwer/core/process/test/test_lamino.py +6 -6
  133. tomwer/core/process/test/test_nabu.py +13 -8
  134. tomwer/core/process/test/test_normalization.py +1 -0
  135. tomwer/core/process/test/test_timer.py +6 -6
  136. tomwer/core/process/visualization/dataviewer.py +4 -0
  137. tomwer/core/process/visualization/diffviewer.py +4 -0
  138. tomwer/core/process/visualization/imagestackviewer.py +4 -0
  139. tomwer/core/process/visualization/radiostack.py +4 -0
  140. tomwer/core/process/visualization/samplemoved.py +4 -0
  141. tomwer/core/process/visualization/sinogramviewer.py +4 -0
  142. tomwer/core/process/visualization/slicestack.py +4 -0
  143. tomwer/core/process/visualization/volumeviewer.py +4 -0
  144. tomwer/core/scan/hdf5scan.py +4 -4
  145. tomwer/core/scan/scanbase.py +5 -1
  146. tomwer/core/scan/test/test_process_registration.py +9 -9
  147. tomwer/core/settings.py +59 -1
  148. tomwer/core/test/test_lamino.py +2 -1
  149. tomwer/core/utils/__init__.py +16 -0
  150. tomwer/core/utils/locker.py +0 -1
  151. tomwer/core/utils/resource.py +6 -11
  152. tomwer/core/utils/scanutils.py +2 -0
  153. tomwer/gui/cluster/slurm.py +91 -7
  154. tomwer/gui/cluster/supervisor.py +16 -11
  155. tomwer/gui/cluster/test/test_cluster.py +16 -1
  156. tomwer/gui/conditions/filter.py +3 -3
  157. tomwer/gui/control/datalist.py +24 -11
  158. tomwer/gui/control/email.py +183 -0
  159. tomwer/gui/control/reducedarkflatselector.py +545 -0
  160. tomwer/gui/control/singletomoobj.py +23 -1
  161. tomwer/gui/control/test/test_email.py +35 -0
  162. tomwer/gui/control/test/test_reducedarkflat_selector.py +280 -0
  163. tomwer/gui/reconstruction/axis/CompareImages.py +1 -1
  164. tomwer/gui/reconstruction/axis/axis.py +10 -6
  165. tomwer/gui/reconstruction/axis/radioaxis.py +14 -6
  166. tomwer/gui/reconstruction/darkref/darkrefcopywidget.py +2 -0
  167. tomwer/gui/reconstruction/darkref/darkrefwidget.py +4 -4
  168. tomwer/gui/reconstruction/nabu/nabuconfig/phase.py +3 -1
  169. tomwer/gui/reconstruction/nabu/nabuconfig/preprocessing.py +34 -33
  170. tomwer/gui/reconstruction/nabu/nabuconfig/reconstruction.py +1 -1
  171. tomwer/gui/reconstruction/normalization/intensity.py +5 -5
  172. tomwer/gui/reconstruction/saaxis/corrangeselector.py +1 -0
  173. tomwer/gui/reconstruction/saaxis/saaxis.py +6 -6
  174. tomwer/gui/reconstruction/sadeltabeta/saadeltabeta.py +6 -6
  175. tomwer/gui/reconstruction/scores/scoreplot.py +6 -4
  176. tomwer/gui/samplemoved/__init__.py +2 -2
  177. tomwer/gui/stackplot.py +18 -7
  178. tomwer/gui/stacks.py +2 -2
  179. tomwer/gui/stitching/stitchandbackground.py +2 -2
  180. tomwer/gui/stitching/stitching.py +1 -1
  181. tomwer/gui/stitching/stitching_raw.py +1 -1
  182. tomwer/gui/utils/__init__.py +1 -85
  183. tomwer/gui/utils/illustrations.py +1 -1
  184. tomwer/gui/utils/inputwidget.py +41 -36
  185. tomwer/gui/utils/slider.py +2 -2
  186. tomwer/gui/utils/utils.py +93 -0
  187. tomwer/gui/visualization/dataviewer.py +8 -5
  188. tomwer/gui/visualization/diffviewer/diffviewer.py +4 -4
  189. tomwer/gui/visualization/reconstructionparameters.py +26 -6
  190. tomwer/gui/visualization/sinogramviewer.py +7 -1
  191. tomwer/gui/visualization/test/test_reconstruction_parameters.py +2 -4
  192. tomwer/gui/visualization/volumeviewer.py +2 -0
  193. tomwer/resources/__init__.py +55 -43
  194. tomwer/resources/gui/icons/compose.png +0 -0
  195. tomwer/resources/gui/icons/compose.svg +75 -0
  196. tomwer/synctools/datatransfert.py +3 -1
  197. tomwer/synctools/stacks/edit/darkflatpatch.py +39 -34
  198. tomwer/synctools/stacks/edit/imagekeyeditor.py +8 -27
  199. tomwer/synctools/stacks/processingstack.py +45 -9
  200. tomwer/synctools/stacks/reconstruction/axis.py +6 -5
  201. tomwer/synctools/stacks/reconstruction/dkrefcopy.py +1 -0
  202. tomwer/synctools/stacks/reconstruction/lamino.py +3 -3
  203. tomwer/synctools/stacks/reconstruction/nabu.py +49 -140
  204. tomwer/synctools/stacks/reconstruction/normalization.py +1 -0
  205. tomwer/synctools/stacks/reconstruction/saaxis.py +19 -33
  206. tomwer/synctools/stacks/reconstruction/sadeltabeta.py +16 -32
  207. tomwer/synctools/test/test_darkRefs.py +19 -10
  208. tomwer/synctools/test/test_foldertransfer.py +7 -7
  209. tomwer/third_party/nabu/preproc/phase.py +6 -8
  210. tomwer/third_party/nabu/utils.py +2 -3
  211. tomwer/version.py +1 -1
  212. {tomwer-1.2.0a1.dist-info → tomwer-1.2.0a3.dist-info}/METADATA +15 -54
  213. {tomwer-1.2.0a1.dist-info → tomwer-1.2.0a3.dist-info}/RECORD +219 -192
  214. {tomwer-1.2.0a1.dist-info → tomwer-1.2.0a3.dist-info}/WHEEL +1 -1
  215. {tomwer-1.2.0a1.dist-info → tomwer-1.2.0a3.dist-info}/entry_points.txt +3 -3
  216. /tomwer-1.2.0a1-py3.9-nspkg.pth → /tomwer-1.2.0a3-py3.11-nspkg.pth +0 -0
  217. {tomwer-1.2.0a1.dist-info → tomwer-1.2.0a3.dist-info}/LICENSE +0 -0
  218. {tomwer-1.2.0a1.dist-info → tomwer-1.2.0a3.dist-info}/namespace_packages.txt +0 -0
  219. {tomwer-1.2.0a1.dist-info → tomwer-1.2.0a3.dist-info}/top_level.txt +0 -0
@@ -32,6 +32,7 @@ import logging
32
32
 
33
33
  from orangewidget import gui, widget
34
34
  from orangewidget.widget import Input
35
+
35
36
  from silx.gui import qt
36
37
 
37
38
  import tomwer.core.process.visualization.slicestack
@@ -75,15 +76,16 @@ class SlicesStackOW(widget.OWBaseWidget, openclass=True):
75
76
 
76
77
  ewokstaskclass = tomwer.core.process.visualization.slicestack._SliceStackPlaceHolder
77
78
 
78
- allows_cycle = True
79
- compress_signal = False
80
-
81
79
  want_main_area = True
82
80
  want_control_area = False
83
81
  resizing_enabled = True
84
82
 
85
83
  class Inputs:
86
- data = Input(name="data", type=TomwerScanBase)
84
+ data = Input(
85
+ name="data",
86
+ type=TomwerScanBase,
87
+ multiple=True,
88
+ )
87
89
 
88
90
  def __init__(self, parent=None):
89
91
  widget.OWBaseWidget.__init__(self, parent)
@@ -92,7 +94,7 @@ class SlicesStackOW(widget.OWBaseWidget, openclass=True):
92
94
  self._box.layout().addWidget(self._viewer)
93
95
 
94
96
  @Inputs.data
95
- def addLeafScan(self, scanID):
97
+ def addLeafScan(self, scanID, *args, **kwargs):
96
98
  if scanID is None:
97
99
  return
98
100
  self._viewer.addLeafScan(scanID)
@@ -30,6 +30,7 @@ __date__ = "21/07/2020"
30
30
  import pytest
31
31
  from orangewidget import gui, widget
32
32
  from orangewidget.widget import Input
33
+
33
34
  from silx.gui import qt
34
35
 
35
36
  import tomwer.core.process.visualization.volumeviewer
@@ -60,20 +61,19 @@ class VolumeViewerOW(widget.OWBaseWidget, openclass=True):
60
61
  want_main_area = True
61
62
  want_control_area = False
62
63
  resizing_enabled = True
63
- compress_signal = False
64
64
 
65
65
  class Inputs:
66
66
  data = Input(name="data", type=TomwerScanBase)
67
- volume = Input(name="volume", type=TomwerVolumeBase)
67
+ volume = Input(name="volume", type=TomwerVolumeBase, multiple=True)
68
68
 
69
69
  def __init__(self, parent=None):
70
- widget.OWBaseWidget.__init__(self, parent)
70
+ super().__init__(parent)
71
71
  self._layout = gui.vBox(self.mainArea, self.name).layout()
72
72
  self.viewer = VolumeViewer(parent=self)
73
73
  self._layout.addWidget(self.viewer)
74
74
 
75
75
  @Inputs.data
76
- def addScan(self, scan):
76
+ def addScan(self, scan, *args, **kwargs):
77
77
  if scan is None:
78
78
  return
79
79
  self.viewer.setScan(scan)
tomwer/__main__.py CHANGED
@@ -36,9 +36,125 @@ __date__ = "10/11/2020"
36
36
 
37
37
 
38
38
  import sys
39
-
39
+ import logging
40
+ import traceback
41
+ from collections import namedtuple
40
42
  import tomwer.version
41
- from tomwer.utils import Launcher
43
+ from tomwer.utils import Launcher as _Launcher
44
+
45
+
46
+ DeprecationWarning = namedtuple(
47
+ "DeprecationWarning", ["since", "reason", "replacement"]
48
+ )
49
+
50
+
51
+ depreclog = logging.getLogger("nxtomomill.DEPRECATION")
52
+
53
+
54
+ class Launcher(_Launcher):
55
+ """
56
+ Manage launch of module.
57
+
58
+ Provides an API to describe available commands and feature to display help
59
+ and execute the commands.
60
+ """
61
+
62
+ def __init__(
63
+ self, prog=None, usage=None, description=None, epilog=None, version=None
64
+ ):
65
+ super().__init__(
66
+ prog=prog,
67
+ usage=usage,
68
+ description=description,
69
+ epilog=epilog,
70
+ version=version,
71
+ )
72
+ self._deprecations = {}
73
+ "deprecations with prog names as key and deprecation info as values"
74
+
75
+ def add_command(
76
+ self,
77
+ name=None,
78
+ module_name=None,
79
+ description=None,
80
+ command=None,
81
+ deprecated=False,
82
+ deprecated_since_version=None,
83
+ deprecated_reason=None,
84
+ deprecated_replacement=None,
85
+ ):
86
+ super().add_command(
87
+ name=name, module_name=module_name, description=description, command=command
88
+ )
89
+ if deprecated:
90
+ self._deprecations[name] = DeprecationWarning(
91
+ since=deprecated_since_version,
92
+ reason=deprecated_reason,
93
+ replacement=deprecated_replacement,
94
+ )
95
+
96
+ def execute(self, argv=None):
97
+ if argv is None:
98
+ argv = sys.argv
99
+
100
+ if len(argv) <= 1:
101
+ self.print_help()
102
+ return 0
103
+
104
+ command_name = argv[1]
105
+
106
+ if command_name in self._deprecations:
107
+ deprecation_info = self._deprecations[command_name]
108
+ deprecated_warning(
109
+ type_="application",
110
+ name=command_name,
111
+ reason=deprecation_info.reason,
112
+ replacement=deprecation_info.replacement,
113
+ since_version=deprecation_info.since,
114
+ )
115
+ super().execute(argv=argv)
116
+
117
+
118
+ def deprecated_warning(
119
+ type_,
120
+ name,
121
+ reason=None,
122
+ replacement=None,
123
+ since_version=None,
124
+ skip_backtrace_count=0,
125
+ ):
126
+ """
127
+ Function to log a deprecation warning
128
+
129
+ :param str type_: Nature of the object to be deprecated:
130
+ "Module", "Function", "Class" ...
131
+ :param name: Object name.
132
+ :param str reason: Reason for deprecating this function
133
+ (e.g. "feature no longer provided",
134
+ :param str replacement: Name of replacement function (if the reason for
135
+ deprecating was to rename the function)
136
+ :param str since_version: First *silx* version for which the function was
137
+ deprecated (e.g. "0.5.0").
138
+ :param int skip_backtrace_count: Amount of last backtrace to ignore when
139
+ logging the backtrace
140
+ """
141
+ if not depreclog.isEnabledFor(logging.WARNING):
142
+ # Avoid computation when it is not logged
143
+ return
144
+
145
+ msg = "%s %s is deprecated"
146
+ if since_version is not None:
147
+ msg += " since silx version %s" % since_version
148
+ msg += "."
149
+ if reason is not None:
150
+ msg += " Reason: %s." % reason
151
+ if replacement is not None:
152
+ msg += " Use '%s' instead." % replacement
153
+ msg += "\n%s"
154
+ limit = 2 + skip_backtrace_count
155
+ backtrace = "".join(traceback.format_stack(limit=limit)[0])
156
+ backtrace = backtrace.rstrip()
157
+ depreclog.warning(msg, type_, name, backtrace)
42
158
 
43
159
 
44
160
  def main():
@@ -63,13 +179,21 @@ def main():
63
179
  )
64
180
  launcher.add_command(
65
181
  "dark-ref",
66
- module_name="tomwer.app.darkref",
182
+ module_name="tomwer.app.reducedarkflat",
67
183
  description="Compute mean / median darks and flat fields",
184
+ deprecated=True,
185
+ deprecated_reason="improve name",
186
+ deprecated_replacement="reduce-dark-flat",
187
+ deprecated_since_version=1.2,
68
188
  )
69
189
  launcher.add_command(
70
190
  "dark-ref-patch",
71
- module_name="tomwer.app.darkrefpatch",
72
- description="patch dark and / or flat to an NXTomo entry",
191
+ module_name="tomwer.app.patchrawdarkflat",
192
+ description="patch raw dark and / or flat to an NXTomo entry",
193
+ deprecated=True,
194
+ deprecated_reason="improve name",
195
+ deprecated_replacement="patch-raw-dark-flat",
196
+ deprecated_since_version=1.2,
73
197
  )
74
198
  launcher.add_command(
75
199
  "diff-frame",
@@ -116,6 +240,16 @@ def main():
116
240
  module_name="tomwer.app.ows_to_script",
117
241
  description="Convert a .ows file to python script",
118
242
  )
243
+ launcher.add_command(
244
+ "patch-raw-dark-flat",
245
+ module_name="tomwer.app.patchrawdarkflat",
246
+ description="patch raw dark and / or flat to an NXTomo entry",
247
+ )
248
+ launcher.add_command(
249
+ "reduce-dark-flat",
250
+ module_name="tomwer.app.reducedarkflat",
251
+ description="Compute reduce darks / flats (mean / median of raw darks and flats)",
252
+ )
119
253
  launcher.add_command(
120
254
  "rsync",
121
255
  module_name="tomwer.app.rsync",
tomwer/app/axis.py CHANGED
@@ -11,7 +11,7 @@ from silx.gui import qt
11
11
 
12
12
  from tomwer.core.process.reconstruction.axis.axis import (
13
13
  AxisMode,
14
- AxisProcess,
14
+ AxisTask,
15
15
  NoAxisUrl,
16
16
  )
17
17
  from tomwer.core.process.reconstruction.darkref.darkrefs import (
@@ -29,9 +29,9 @@ _logger = logging.getLogger(__name__)
29
29
 
30
30
 
31
31
  class _AxisProcessGUI(AxisWindow):
32
- def __init__(self, scan, axis_params):
32
+ def __init__(self, scan, axis_params, backend=None):
33
33
  axis_params.frame_width = scan.dim_1
34
- AxisWindow.__init__(self, axis_params=axis_params)
34
+ super().__init__(axis_params=axis_params, backend=backend)
35
35
  self.hideLockButton()
36
36
  self.hideApplyButton()
37
37
  self.setScan(scan=scan)
@@ -46,11 +46,12 @@ class _AxisProcessGUI(AxisWindow):
46
46
  ("start axis calculation with", scan.axis_params.axis_url_1.url.path())
47
47
  )
48
48
  _logger.info(mess)
49
- process = AxisProcess(
49
+ process = AxisTask(
50
50
  inputs={
51
51
  "data": scan,
52
52
  "axis_params": self._axis_params,
53
53
  "wait": wait,
54
+ "serialize_output_data": False,
54
55
  }
55
56
  )
56
57
  try:
@@ -111,12 +112,22 @@ def main(argv):
111
112
  default=False,
112
113
  help="Define the mode 'full' when display shifted images from manual" " mode",
113
114
  )
114
-
115
+ parser.add_argument(
116
+ "--use-opengl-plot",
117
+ help="Use OpenGL for plots (instead of matplotlib)",
118
+ action="store_true",
119
+ default=False,
120
+ )
115
121
  options = parser.parse_args(argv[1:])
116
122
 
117
123
  if options.debug:
118
124
  logging.root.setLevel(logging.DEBUG)
119
125
 
126
+ if options.use_opengl_plot:
127
+ import silx
128
+
129
+ silx.config.DEFAULT_PLOT_BACKEND = "gl"
130
+
120
131
  increase_max_number_file()
121
132
 
122
133
  global app # QApplication must be global to avoid seg fault on quit
@@ -129,7 +129,7 @@ class TomwerConfig(config.Config):
129
129
  "Quick Start": "https://www.youtube.com/playlist?list=PLddRXwP6Z6F9KOu1V5o6H24KPH5Ikuk2f",
130
130
  #: The 'full' documentation, should be something like current /docs/
131
131
  #: but specific for 'Visual Programing' only
132
- "Documentation": "https://tomotools.gitlab-pages.esrf.fr/nxtomomill/index.html",
132
+ "Documentation": "https://tomotools.gitlab-pages.esrf.fr/tomwer/index.html",
133
133
  #: YouTube tutorials
134
134
  "Screencasts": "https://www.youtube.com/@tomotools",
135
135
  }
@@ -4,6 +4,7 @@ import os
4
4
  import shutil
5
5
  import signal
6
6
  import sys
7
+ from typing import List
7
8
  from contextlib import closing
8
9
  from logging.handlers import RotatingFileHandler
9
10
  from urllib.request import urlopen
@@ -27,6 +28,9 @@ from silx.gui import qt
27
28
 
28
29
  import tomwer.version
29
30
  from tomwer.core.log.logger import TomwerLogger
31
+ from orangecanvas.preview import previewdialog, previewmodel
32
+ from orangecanvas.application import examples as orange_examples
33
+
30
34
 
31
35
  from .config import TomwerConfig, TomwerSplashScreen
32
36
 
@@ -54,6 +58,8 @@ LOG_FOLDER = "/var/log/tomwer"
54
58
 
55
59
 
56
60
  class MainWindow(_MainWindow):
61
+ HELPDESK_URL = "https://requests.esrf.fr/plugins/servlet/desk/portal/41"
62
+
57
63
  def __init__(self, *args, **kwargs):
58
64
  super().__init__(*args, **kwargs)
59
65
  self.process_supervisor_dock = DockWidget(
@@ -85,12 +91,143 @@ class MainWindow(_MainWindow):
85
91
  super().setup_menu()
86
92
  self.view_menu.addAction(self.show_processes_manager_action)
87
93
 
88
- def open_about(self):
89
- # type: () -> None
90
- """Open the about dialog."""
91
- dlg = AboutDialog(self)
92
- dlg.setAttribute(qt.Qt.WA_DeleteOnClose)
93
- dlg.exec()
94
+ self.simple_example_action = qt.QAction(
95
+ self.tr("simple use cases"),
96
+ self,
97
+ objectName="simple-use-cases",
98
+ toolTip=self.tr("Some simple examples."),
99
+ triggered=self.open_simple_examples,
100
+ menuRole=qt.QAction.AboutRole,
101
+ )
102
+
103
+ self.dark_flat_example_action = qt.QAction(
104
+ self.tr("darks and flats manipulations"),
105
+ self,
106
+ objectName="dark-flat-manipulation",
107
+ toolTip=self.tr("Examples around dark and flat."),
108
+ triggered=self.open_dark_flat_examples,
109
+ menuRole=qt.QAction.AboutRole,
110
+ )
111
+ self.slurm_execution_example_action = qt.QAction(
112
+ self.tr("remote processing with slurm"),
113
+ self,
114
+ objectName="execution-on-slurm",
115
+ toolTip=self.tr("Examples of some execution over slurm."),
116
+ triggered=self.open_slurm_execution_example,
117
+ menuRole=qt.QAction.AboutRole,
118
+ )
119
+ self.cor_search_example_action = qt.QAction(
120
+ self.tr("cor search advance example"),
121
+ self,
122
+ objectName="cor-search-example",
123
+ toolTip=self.tr("Examples of ways to search for the Center of rotation."),
124
+ triggered=self.open_cor_search_example,
125
+ menuRole=qt.QAction.AboutRole,
126
+ )
127
+ self.python_script_example_action = qt.QAction(
128
+ self.tr("python script examples"),
129
+ self,
130
+ objectName="python-script-example",
131
+ toolTip=self.tr("Examples of some python script usage."),
132
+ triggered=self.open_python_script_example,
133
+ menuRole=qt.QAction.AboutRole,
134
+ )
135
+ # Predefined workflows menu.
136
+ self.predefined_workflows_menu = qt.QMenu(
137
+ self.tr("&Examples"),
138
+ self.menuBar(),
139
+ objectName="examples-menu",
140
+ )
141
+ self.predefined_workflows_menu.addActions(
142
+ [
143
+ self.simple_example_action,
144
+ self.cor_search_example_action,
145
+ self.dark_flat_example_action,
146
+ self.slurm_execution_example_action,
147
+ self.python_script_example_action,
148
+ ]
149
+ )
150
+
151
+ self.menuBar().addMenu(self.predefined_workflows_menu)
152
+
153
+ self._helpdeskButton = qt.QAction(
154
+ self.tr("&Helpdesk"),
155
+ self,
156
+ objectName="helpdeskButton",
157
+ triggered=self._contactUs,
158
+ toolTip="contact esrf data processing helpdesk if you have some troubles with the application",
159
+ )
160
+ self.menuBar().addAction(self._helpdeskButton)
161
+
162
+ def _contactUs(self, *args, **kwargs):
163
+ try:
164
+ qt.QDesktopServices.openUrl(qt.QUrl(self.HELPDESK_URL))
165
+ except Exception as e:
166
+ _logger.error(
167
+ f"Failed to launch helpdesk web page ({self.HELPDESK_URL}). Error is {e}"
168
+ )
169
+
170
+ def __open_examples(self, examples, filter_names=None):
171
+ """
172
+ filter the existing tutorials by names contained in the file name
173
+ """
174
+ items = [previewmodel.PreviewItem(path=t.abspath()) for t in examples]
175
+
176
+ def my_filter(value):
177
+ for filter_name in filter_names:
178
+ if filter_name in value:
179
+ return True
180
+ return False
181
+
182
+ if filter_names is not None:
183
+ items = filter(
184
+ lambda item: my_filter(os.path.basename(item.path())),
185
+ items,
186
+ )
187
+ dialog = previewdialog.PreviewDialog(self)
188
+ model = previewmodel.PreviewModel(dialog, items=items)
189
+ title = self.tr("Example Workflows")
190
+ dialog.setWindowTitle(title)
191
+ template = '<h3 style="font-size: 26px">\n' "{0}\n" "</h3>"
192
+
193
+ dialog.setHeading(template.format(title))
194
+ dialog.setModel(model)
195
+
196
+ model.delayedScanUpdate()
197
+ status = dialog.exec()
198
+ index = dialog.currentIndex()
199
+
200
+ dialog.deleteLater()
201
+
202
+ if status == qt.QDialog.Accepted:
203
+ selected = model.item(index)
204
+ self.open_example_scheme(selected.path())
205
+ return status # def open_about(self):
206
+
207
+ def open_simple_examples(self):
208
+ return self.__open_examples(
209
+ orange_examples.workflows(), filter_names=("simple", "EBS_tomo_listener")
210
+ )
211
+
212
+ def open_slurm_execution_example(self):
213
+ return self.__open_examples(
214
+ orange_examples.workflows(), filter_names=("slurm",)
215
+ )
216
+
217
+ def open_dark_flat_examples(self):
218
+ return self.__open_examples(
219
+ orange_examples.workflows(), filter_names=("darks",)
220
+ )
221
+
222
+ def open_python_script_example(self):
223
+ return self.__open_examples(
224
+ orange_examples.workflows(), filter_names=("_script",)
225
+ )
226
+
227
+ def open_cor_search_example(self):
228
+ return self.__open_examples(
229
+ orange_examples.workflows(), filter_names=("find_cor", "cor_search")
230
+ )
94
231
 
95
232
 
96
233
  log = logging.getLogger(__name__)
@@ -125,12 +262,33 @@ class _OMain(ocMain):
125
262
  signal.signal(signal.SIGINT, signal.SIG_DFL)
126
263
  # Disable pyqtgraph's atexit and QApplication.aboutToQuit cleanup handlers.
127
264
  pyqtgraph.setConfigOption("exitCleanup", False)
265
+ print("argv are", argv)
128
266
  super().run(argv)
129
267
 
130
268
  def argument_parser(self) -> argparse.ArgumentParser:
131
269
  parser = super().argument_parser()
270
+ parser.add_argument(
271
+ "--use-opengl-plot",
272
+ help="Use OpenGL for plots (instead of matplotlib)",
273
+ action="store_true",
274
+ default=False,
275
+ )
132
276
  return parser
133
277
 
278
+ def parse_arguments(self, argv: List[str]):
279
+ super().parse_arguments(argv)
280
+ # define silx plot backend. For now the si;pler is to
281
+ # define an environment variable.
282
+ # this way we should also be able to let the user define it
283
+ # on it's own later...
284
+ if self.options.use_opengl_plot:
285
+ import silx
286
+
287
+ # other standalones are not passing by the silx.config
288
+ # but for the canvas this is way simpler to use it.
289
+ # then all plot which have backend==None will pick the default plot backend
290
+ silx.config.DEFAULT_PLOT_BACKEND = "gl"
291
+
134
292
  def setup_logging(self):
135
293
  super().setup_logging()
136
294
  make_sql_logger(self.options.log_level)