tomwer 1.0.4__py3-none-any.whl → 1.1.0__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 (256) hide show
  1. orangecontrib/tomwer/tutorials/EBS_tomo_listener.ows +39 -0
  2. orangecontrib/tomwer/tutorials/cast_volume.ows +34 -0
  3. orangecontrib/tomwer/tutorials/simple_slice_reconstruction.ows +39 -0
  4. orangecontrib/tomwer/tutorials/simple_volume_local_reconstruction.ows +49 -0
  5. orangecontrib/tomwer/tutorials/simple_volume_to_slurm_reconstruction.ows +59 -0
  6. orangecontrib/tomwer/tutorials/using_saaxis_to_find_cor.ows +44 -0
  7. orangecontrib/tomwer/widgets/cluster/FutureSupervisorOW.py +1 -1
  8. orangecontrib/tomwer/widgets/cluster/SlurmClusterOW.py +14 -4
  9. orangecontrib/tomwer/widgets/cluster/__init__.py +1 -1
  10. orangecontrib/tomwer/widgets/control/DataListOW.py +12 -5
  11. orangecontrib/tomwer/widgets/control/DataListenerOW.py +18 -9
  12. orangecontrib/tomwer/widgets/control/DataSelectorOW.py +13 -6
  13. orangecontrib/tomwer/widgets/control/DataTransfertOW.py +4 -5
  14. orangecontrib/tomwer/widgets/control/DataValidatorOW.py +8 -4
  15. orangecontrib/tomwer/widgets/control/DataWatcherOW.py +4 -6
  16. orangecontrib/tomwer/widgets/control/EDF2NXTomomillOW.py +49 -62
  17. orangecontrib/tomwer/widgets/control/FilterOW.py +2 -4
  18. orangecontrib/tomwer/widgets/control/NXTomomillMixIn.py +93 -0
  19. orangecontrib/tomwer/widgets/control/NXTomomillOW.py +135 -128
  20. orangecontrib/tomwer/widgets/control/NotifierOW.py +31 -7
  21. orangecontrib/tomwer/widgets/control/SingleTomoObjOW.py +3 -5
  22. orangecontrib/tomwer/widgets/control/TomoObjSerieOW.py +85 -0
  23. orangecontrib/tomwer/widgets/control/VolumeSelector.py +12 -4
  24. orangecontrib/tomwer/widgets/control/VolumeSymLinkOW.py +11 -7
  25. orangecontrib/tomwer/widgets/control/icons/notification.svg +4 -4
  26. orangecontrib/tomwer/widgets/control/icons/nxtomomill.png +0 -0
  27. orangecontrib/tomwer/widgets/control/icons/nxtomomill.svg +8 -5
  28. orangecontrib/tomwer/widgets/control/icons/tomoobjserie.png +0 -0
  29. orangecontrib/tomwer/widgets/control/icons/tomoobjserie.svg +138 -0
  30. orangecontrib/tomwer/widgets/edit/DarkFlatPatchOW.py +16 -4
  31. orangecontrib/tomwer/widgets/edit/NXtomoEditorOW.py +100 -0
  32. orangecontrib/tomwer/widgets/edit/icons/image_key_editor.png +0 -0
  33. orangecontrib/tomwer/widgets/edit/icons/image_key_upgrader.png +0 -0
  34. orangecontrib/tomwer/widgets/edit/icons/nx_tomo_editor.png +0 -0
  35. orangecontrib/tomwer/widgets/edit/icons/nx_tomo_editor.svg +123 -0
  36. orangecontrib/tomwer/widgets/edit/test/test_dark_flat_patch.py +21 -1
  37. orangecontrib/tomwer/widgets/edit/test/test_image_key_editor.py +1 -1
  38. orangecontrib/tomwer/widgets/edit/test/test_image_key_upgrader.py +1 -1
  39. orangecontrib/tomwer/widgets/edit/test/test_nxtomo_editor.py +25 -0
  40. orangecontrib/tomwer/widgets/other/PythonScriptOW.py +19 -10
  41. orangecontrib/tomwer/widgets/reconstruction/AxisOW.py +20 -14
  42. orangecontrib/tomwer/widgets/reconstruction/CastNabuVolumeOW.py +24 -10
  43. orangecontrib/tomwer/widgets/reconstruction/DarkRefAndCopyOW.py +26 -21
  44. orangecontrib/tomwer/widgets/reconstruction/NabuOW.py +29 -12
  45. orangecontrib/tomwer/widgets/reconstruction/NabuVolumeOW.py +44 -17
  46. orangecontrib/tomwer/widgets/reconstruction/SAAxisOW.py +28 -18
  47. orangecontrib/tomwer/widgets/reconstruction/SADeltaBetaOW.py +24 -17
  48. orangecontrib/tomwer/widgets/reconstruction/SinoNormOW.py +6 -6
  49. orangecontrib/tomwer/widgets/reconstruction/TofuOW.py +4 -2
  50. orangecontrib/tomwer/widgets/reconstruction/icons/nabu_2d.png +0 -0
  51. orangecontrib/tomwer/widgets/reconstruction/icons/nabu_2d.svg +11 -8
  52. orangecontrib/tomwer/widgets/visualization/DataViewerOW.py +10 -4
  53. orangecontrib/tomwer/widgets/visualization/DiffViewerOW.py +1 -1
  54. orangecontrib/tomwer/widgets/visualization/NXtomoMetadataViewerOW.py +69 -0
  55. orangecontrib/tomwer/widgets/visualization/SampleMovedOW.py +2 -4
  56. orangecontrib/tomwer/widgets/visualization/icons/nx_tomo_metadata_viewer.png +0 -0
  57. orangecontrib/tomwer/widgets/visualization/icons/nx_tomo_metadata_viewer.svg +105 -0
  58. tomwer/__main__.py +10 -5
  59. tomwer/app/canvas_launcher/config.py +10 -10
  60. tomwer/app/canvas_launcher/mainwindow.py +68 -6
  61. tomwer/app/canvas_launcher/widgetsscheme.py +1 -3
  62. tomwer/app/darkref.py +16 -12
  63. tomwer/app/imagekeyeditor.py +2 -2
  64. tomwer/app/imagekeyupgrader.py +104 -0
  65. tomwer/app/nxtomoeditor.py +103 -0
  66. tomwer/app/rsync.py +1 -1
  67. tomwer/core/cluster/cluster.py +1 -1
  68. tomwer/core/futureobject.py +1 -0
  69. tomwer/core/process/control/datalistener/datalistener.py +7 -1
  70. tomwer/core/process/control/datalistener/rpcserver.py +3 -3
  71. tomwer/core/process/control/datawatcher/datawatcher.py +18 -18
  72. tomwer/core/process/control/datawatcher/datawatcherobserver.py +5 -8
  73. tomwer/core/process/control/datawatcher/datawatcherprocess.py +2 -3
  74. tomwer/core/process/control/datawatcher/edfdwprocess.py +2 -2
  75. tomwer/core/process/control/nxtomomill.py +33 -58
  76. tomwer/core/process/control/scanlist.py +2 -1
  77. tomwer/core/process/control/scanselector.py +7 -0
  78. tomwer/core/process/control/scantransfer.py +9 -18
  79. tomwer/core/process/control/scanvalidator.py +6 -5
  80. tomwer/core/process/control/singletomoobj.py +2 -1
  81. tomwer/core/process/control/timer.py +2 -1
  82. tomwer/core/process/control/tomoobjserie.py +8 -0
  83. tomwer/core/process/control/volumeselector.py +2 -1
  84. tomwer/core/process/control/volumesymlink.py +2 -1
  85. tomwer/core/process/edit/darkflatpatch.py +2 -1
  86. tomwer/core/process/edit/imagekeyeditor.py +4 -3
  87. tomwer/core/process/reconstruction/axis/axis.py +29 -32
  88. tomwer/core/process/reconstruction/axis/mode.py +3 -2
  89. tomwer/core/process/reconstruction/axis/params.py +35 -16
  90. tomwer/core/process/reconstruction/darkref/darkrefs.py +90 -707
  91. tomwer/core/process/reconstruction/darkref/darkrefscopy.py +44 -16
  92. tomwer/core/process/reconstruction/darkref/params.py +62 -67
  93. tomwer/core/process/reconstruction/lamino/tofu.py +1 -1
  94. tomwer/core/process/reconstruction/nabu/castvolume.py +21 -26
  95. tomwer/core/process/reconstruction/nabu/nabucommon.py +36 -38
  96. tomwer/core/process/reconstruction/nabu/nabuscores.py +28 -13
  97. tomwer/core/process/reconstruction/nabu/nabuslices.py +41 -14
  98. tomwer/core/process/reconstruction/nabu/nabuvolume.py +21 -12
  99. tomwer/core/process/reconstruction/nabu/utils.py +12 -1
  100. tomwer/core/process/reconstruction/normalization/normalization.py +9 -8
  101. tomwer/core/process/reconstruction/saaxis/saaxis.py +46 -20
  102. tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py +38 -12
  103. tomwer/core/process/reconstruction/test/__init__.py +0 -39
  104. tomwer/core/process/reconstruction/test/test_axis_params.py +25 -3
  105. tomwer/core/process/reconstruction/test/test_darkref_copy.py +117 -1
  106. tomwer/core/process/script/python.py +16 -12
  107. tomwer/core/process/task.py +3 -7
  108. tomwer/core/process/test/test_axis.py +1 -1
  109. tomwer/core/process/test/test_dark_and_flat.py +41 -111
  110. tomwer/core/process/test/test_data_listener.py +0 -29
  111. tomwer/core/process/test/test_data_transfer.py +10 -14
  112. tomwer/core/process/test/test_nabu.py +1 -1
  113. tomwer/core/process/test/test_normalization.py +1 -1
  114. tomwer/core/process/visualization/liveslice.py +6 -0
  115. tomwer/core/scan/blissscan.py +37 -2
  116. tomwer/core/scan/edfscan.py +14 -4
  117. tomwer/core/scan/hdf5scan.py +10 -4
  118. tomwer/core/scan/scanbase.py +35 -29
  119. tomwer/core/scan/scanfactory.py +3 -17
  120. tomwer/core/scan/test/test_h5.py +1 -1
  121. tomwer/core/scan/test/test_process_registration.py +0 -11
  122. tomwer/core/scan/test/test_scan.py +32 -30
  123. tomwer/core/settings.py +2 -2
  124. tomwer/core/test/test_utils.py +1 -1
  125. tomwer/core/tomwer_object.py +19 -0
  126. tomwer/core/utils/__init__.py +0 -45
  127. tomwer/core/utils/char.py +2 -0
  128. tomwer/core/utils/gpu.py +5 -5
  129. tomwer/core/utils/nxtomoutils.py +2 -2
  130. tomwer/core/utils/scanutils.py +50 -0
  131. tomwer/core/utils/volumeutils.py +13 -0
  132. tomwer/core/volume/edfvolume.py +4 -0
  133. tomwer/core/volume/hdf5volume.py +4 -0
  134. tomwer/core/volume/jp2kvolume.py +4 -0
  135. tomwer/core/volume/rawvolume.py +4 -0
  136. tomwer/core/volume/tiffvolume.py +4 -0
  137. tomwer/core/volume/volumebase.py +19 -12
  138. tomwer/core/volume/volumefactory.py +20 -1
  139. tomwer/gui/cluster/slurm.py +1 -1
  140. tomwer/gui/cluster/test/test_cluster.py +2 -2
  141. tomwer/gui/control/datalist.py +109 -34
  142. tomwer/gui/control/datatransfert.py +1 -1
  143. tomwer/gui/control/datawatcher/datawatcher.py +23 -13
  144. tomwer/gui/control/datawatcher/datawatcherobserver.py +1 -1
  145. tomwer/gui/control/observations.py +0 -3
  146. tomwer/gui/control/selectorwidgetbase.py +42 -11
  147. tomwer/gui/control/serie/seriecreator.py +967 -0
  148. tomwer/{web/__init__.py → gui/control/serie/seriewaiter.py} +5 -7
  149. tomwer/gui/control/singletomoobj.py +15 -3
  150. tomwer/gui/control/test/test_datalist.py +1 -1
  151. tomwer/gui/control/test/test_datalistener.py +1 -1
  152. tomwer/gui/control/test/test_inputwidget.py +1 -1
  153. tomwer/gui/control/test/test_process_manager.py +1 -13
  154. tomwer/gui/control/test/test_scanselector.py +1 -1
  155. tomwer/gui/control/test/test_scanvalidator.py +1 -1
  156. tomwer/gui/control/test/test_single_tomo_obj.py +1 -1
  157. tomwer/gui/control/test/test_volume_dialog.py +19 -7
  158. tomwer/gui/control/test/test_volumeselector.py +4 -4
  159. tomwer/gui/debugtools/datasetgenerator.py +1 -8
  160. tomwer/gui/edit/dkrfpatch.py +2 -2
  161. tomwer/gui/edit/imagekeyeditor.py +12 -9
  162. tomwer/gui/edit/nxtomoeditor.py +475 -0
  163. tomwer/gui/edit/test/test_dkrf_patch.py +2 -14
  164. tomwer/gui/edit/test/test_image_key_editor.py +2 -2
  165. tomwer/gui/edit/test/test_nx_editor.py +155 -0
  166. tomwer/gui/qfolderdialog.py +11 -0
  167. tomwer/gui/reconstruction/axis/CompareImages.py +27 -29
  168. tomwer/gui/reconstruction/axis/axis.py +2 -0
  169. tomwer/gui/reconstruction/axis/radioaxis.py +67 -11
  170. tomwer/gui/reconstruction/darkref/darkrefcopywidget.py +7 -9
  171. tomwer/gui/reconstruction/darkref/darkrefwidget.py +22 -24
  172. tomwer/gui/reconstruction/lamino/tofu/projections.py +1 -1
  173. tomwer/gui/reconstruction/lamino/tofu/tofu.py +3 -3
  174. tomwer/gui/reconstruction/lamino/tofu/tofuexpert.py +4 -4
  175. tomwer/gui/reconstruction/lamino/tofu/tofuoutput.py +10 -4
  176. tomwer/gui/reconstruction/nabu/castvolume.py +80 -11
  177. tomwer/gui/reconstruction/nabu/check.py +1 -1
  178. tomwer/gui/reconstruction/nabu/nabuconfig/ctf.py +352 -0
  179. tomwer/gui/reconstruction/nabu/nabuconfig/nabuconfig.py +0 -9
  180. tomwer/gui/reconstruction/nabu/nabuconfig/output.py +1 -1
  181. tomwer/gui/reconstruction/nabu/nabuconfig/phase.py +18 -19
  182. tomwer/gui/reconstruction/nabu/nabuconfig/preprocessing.py +30 -7
  183. tomwer/gui/reconstruction/nabu/nabuconfig/reconstruction.py +26 -13
  184. tomwer/gui/reconstruction/nabu/slices.py +10 -2
  185. tomwer/gui/reconstruction/nabu/slurm.py +1 -1
  186. tomwer/gui/reconstruction/nabu/volume.py +13 -7
  187. tomwer/gui/reconstruction/normalization/intensity.py +1 -1
  188. tomwer/gui/reconstruction/saaxis/corrangeselector.py +10 -34
  189. tomwer/gui/reconstruction/saaxis/saaxis.py +11 -6
  190. tomwer/gui/reconstruction/saaxis/sliceselector.py +11 -26
  191. tomwer/gui/reconstruction/sadeltabeta/saadeltabeta.py +13 -8
  192. tomwer/gui/reconstruction/scores/scoreplot.py +67 -61
  193. tomwer/gui/reconstruction/test/test_axis.py +2 -2
  194. tomwer/gui/reconstruction/test/test_lamino.py +2 -2
  195. tomwer/gui/reconstruction/test/test_nabu.py +14 -1
  196. tomwer/gui/reconstruction/test/test_saaxis.py +8 -17
  197. tomwer/gui/reconstruction/test/test_sadeltabeta.py +7 -13
  198. tomwer/gui/stackplot.py +11 -28
  199. tomwer/gui/test/test_axis_gui.py +4 -4
  200. tomwer/gui/test/test_qfolder_dialog.py +12 -0
  201. tomwer/gui/utils/inputwidget.py +42 -21
  202. tomwer/gui/utils/lineselector/lineselector.py +13 -21
  203. tomwer/gui/utils/scandescription.py +2 -4
  204. tomwer/gui/utils/slider.py +1 -102
  205. tomwer/gui/utils/unitsystem.py +48 -11
  206. tomwer/gui/visualization/dataviewer.py +24 -17
  207. tomwer/gui/visualization/diffviewer/diffviewer.py +2 -11
  208. tomwer/gui/visualization/nxtomometadata.py +21 -0
  209. tomwer/gui/visualization/scanoverview.py +0 -1
  210. tomwer/gui/visualization/test/test_nx_tomo_metadata_viewer.py +72 -0
  211. tomwer/gui/visualization/test/test_stacks.py +1 -1
  212. tomwer/gui/visualization/tomoobjoverview.py +49 -0
  213. tomwer/gui/visualization/volumeoverview.py +64 -0
  214. tomwer/gui/visualization/volumeviewer.py +1 -1
  215. tomwer/resources/gui/icons/multi-document-save.png +0 -0
  216. tomwer/resources/gui/icons/multi-document-save.svg +101 -0
  217. tomwer/resources/gui/illustrations/ctf_z1.png +0 -0
  218. tomwer/resources/gui/illustrations/ctf_z1.svg +471 -0
  219. tomwer/synctools/datalistener.py +5 -1
  220. tomwer/synctools/imageloaderthread.py +2 -2
  221. tomwer/synctools/stacks/edit/imagekeyeditor.py +1 -1
  222. tomwer/synctools/stacks/processingstack.py +2 -2
  223. tomwer/synctools/stacks/reconstruction/castvolume.py +1 -0
  224. tomwer/synctools/stacks/reconstruction/lamino.py +1 -3
  225. tomwer/synctools/stacks/reconstruction/sadeltabeta.py +0 -2
  226. tomwer/synctools/test/test_darkRefs.py +32 -149
  227. tomwer/synctools/test/test_foldertransfer.py +1 -1
  228. tomwer/synctools/test/test_scanstages.py +2 -2
  229. tomwer/tests/__init__.py +0 -0
  230. tomwer/tests/conftest.py +51 -0
  231. tomwer/{test → tests}/test_scripts.py +1 -1
  232. tomwer/tests/test_utils.py +10 -0
  233. tomwer/{test → tests}/utils/utilstest.py +0 -11
  234. tomwer/version.py +3 -3
  235. {tomwer-1.0.4.dist-info → tomwer-1.1.0.dist-info}/METADATA +14 -16
  236. {tomwer-1.0.4.dist-info → tomwer-1.1.0.dist-info}/RECORD +245 -217
  237. {tomwer-1.0.4.dist-info → tomwer-1.1.0.dist-info}/WHEEL +1 -1
  238. {tomwer-1.0.4.dist-info → tomwer-1.1.0.dist-info}/entry_points.txt +6 -0
  239. orangecontrib/tomwer/setup.py +0 -45
  240. orangecontrib/tomwer/widgets/setup.py +0 -49
  241. tomwer/app/process.py +0 -153
  242. tomwer/core/process/reconstruction/nabu/slurm.py +0 -36
  243. tomwer/core/process/reconstruction/utils/nabu_slice_exec.py +0 -10
  244. tomwer/core/utils/laminoutils.py +0 -80
  245. tomwer/gui/utils/lineselector/lineselection.py +0 -76
  246. tomwer/setup.py +0 -52
  247. tomwer/web/client.py +0 -43
  248. tomwer/web/config.py +0 -36
  249. tomwer/web/test/test_graylog_connection.py +0 -59
  250. {tomwer/test → orangecontrib/tomwer/tutorials}/__init__.py +0 -0
  251. /tomwer/{web/test → gui/control/serie}/__init__.py +0 -0
  252. /tomwer/{test → tests}/utils/__init__.py +0 -0
  253. /tomwer-1.0.4-py3.8-nspkg.pth → /tomwer-1.1.0-py3.9-nspkg.pth +0 -0
  254. {tomwer-1.0.4.dist-info → tomwer-1.1.0.dist-info}/LICENSE +0 -0
  255. {tomwer-1.0.4.dist-info → tomwer-1.1.0.dist-info}/namespace_packages.txt +0 -0
  256. {tomwer-1.0.4.dist-info → tomwer-1.1.0.dist-info}/top_level.txt +0 -0
@@ -35,20 +35,25 @@ __license__ = "MIT"
35
35
  __date__ = "25/02/2021"
36
36
 
37
37
 
38
+ import os
39
+ import weakref
40
+ import numpy
41
+ import logging
42
+ from typing import Union
43
+ from contextlib import AbstractContextManager
44
+ from matplotlib import image as _matplotlib_image
38
45
  from silx.gui import qt
39
46
  from silx.gui.plot import PlotWidget
47
+ from tomwer.io.utils.utils import get_slice_data
40
48
  from tomwer.gui.reconstruction.saaxis.dimensionwidget import DimensionWidget
41
49
  from tomwer.gui.visualization.dataviewer import ImageStack
42
50
  from tomwer.gui.utils.vignettes import VignettesQDialog
43
- from contextlib import AbstractContextManager
44
51
  from tomwer.gui.utils.buttons import PadlockButton
45
52
  from tomwer.gui import icons
53
+ from tomwer.gui import settings
46
54
  from tomwer.io.utils.h5pyutils import DatasetReader
47
55
  from tomwer.core.process.reconstruction.scores.params import ScoreMethod
48
- from typing import Union
49
- import weakref
50
- import numpy
51
- import logging
56
+ from tomwer.io.utils import get_default_directory
52
57
 
53
58
  _logger = logging.getLogger(__name__)
54
59
 
@@ -310,7 +315,7 @@ class CorSelection(VariableSelection):
310
315
  self._absoluteVarValueLE,
311
316
  )
312
317
  try:
313
- import pyopencl # noqa F401
318
+ import pyopencl # noqa F401 pylint: disable=E0401
314
319
  except Exception:
315
320
  idx = self._scoreMethodCB.findText(ScoreMethod.TOMO_CONSISTENCY.value)
316
321
  if idx >= 0:
@@ -495,10 +500,20 @@ class ScorePlot(qt.QWidget):
495
500
  self.setLayout(qt.QGridLayout())
496
501
  # main plot
497
502
  self._plot = ImageStack(self, show_overview=False)
503
+ self._plot.getPlotWidget().setYAxisInverted(settings.Y_AXIS_DOWNWARD)
504
+
498
505
  self._plot.getPlotWidget().setKeepDataAspectRatio(True)
499
506
  self._plot._sliderDockWidget.hide()
500
507
  self._plot.getPlotWidget().getColorBarWidget().hide()
501
508
  self._plot.getPlotWidget().getPositionInfoWidget().hide()
509
+ # add save all action
510
+ save_all_icon = icons.getQIcon("multi-document-save")
511
+ self._saveAllSnapshot = qt.QAction(
512
+ save_all_icon, "save all screenshot as png", self
513
+ )
514
+ toolbar = self._plot.getPlotWidget().toolBar()
515
+ toolbar.addSeparator()
516
+ toolbar.addAction(self._saveAllSnapshot)
502
517
  # hide dock widget
503
518
  self._plot._reconsInfoDockWidget.hide()
504
519
  self._plot._tableDockWidget.hide()
@@ -563,6 +578,7 @@ class ScorePlot(qt.QWidget):
563
578
  self._varSelectedFromVignettes
564
579
  )
565
580
  self._varValueWidget.sigScoreMethodChanged.connect(self._updateScores)
581
+ self._saveAllSnapshot.triggered.connect(self._saveAllReconstructedSlices)
566
582
 
567
583
  # set up
568
584
  # for now we don't want to use the volume and voxel size
@@ -570,8 +586,8 @@ class ScorePlot(qt.QWidget):
570
586
  self._voxelSizeW.hide()
571
587
  self._axisLabel.hide()
572
588
 
573
- def __init_subclass__(cls, constructor, **kwargs):
574
- super().__init_subclass__(**kwargs)
589
+ def __init_subclass__(cls, constructor, **kwargs): # pylint: disable=E0302
590
+ super().__init_subclass__()
575
591
  cls._CorSlectionBuilder = constructor
576
592
 
577
593
  def getScoreMethod(self):
@@ -711,7 +727,8 @@ class ScorePlot(qt.QWidget):
711
727
  self._plot.setUrls(urls=self._urls)
712
728
  self._varSlider.setVarValues(self._var_values)
713
729
  old = self._varSlider.blockSignals(True)
714
- self._varSlider.setVarValue(self._var_values[0])
730
+ if len(self._var_values) > 0:
731
+ self._varSlider.setVarValue(self._var_values[0])
715
732
  self._varSlider.blockSignals(old)
716
733
 
717
734
  old = self._varValueWidget.blockSignals(True)
@@ -790,6 +807,47 @@ class ScorePlot(qt.QWidget):
790
807
  )
791
808
  )
792
809
 
810
+ def _saveAllReconstructedSlices(self): # pragma: no cover
811
+ """
812
+ save all reconstructed slices to a folder provided by the user
813
+ """
814
+ dialog = qt.QFileDialog(self, directory=get_default_directory())
815
+ dialog.setFileMode(qt.QFileDialog.DirectoryOnly)
816
+ if not dialog.exec_():
817
+ dialog.close()
818
+ return
819
+
820
+ output_folder = dialog.selectedFiles()[0]
821
+ try:
822
+ self.saveReconstructedSlicesTo(output_folder=output_folder)
823
+ except Exception as e:
824
+ _logger.error(f"Fail to save snapshots. Error is {e}")
825
+ else:
826
+ _logger.info(f"snapshots have been saved to {output_folder}")
827
+
828
+ def saveReconstructedSlicesTo(self, output_folder):
829
+ """dump all slices with score as name"""
830
+ # make sure the output dir exists
831
+ os.makedirs(output_folder, exist_ok=True)
832
+
833
+ i_missing_score = 0
834
+ for score, slice_url in zip(self._var_values, self._urls):
835
+ try:
836
+ data = get_slice_data(slice_url)
837
+ if score is None:
838
+ file_name = f"no_score_{i_missing_score}.png"
839
+ i_missing_score += 1
840
+ else:
841
+ file_name = f"{score}.png"
842
+ _matplotlib_image.imsave(
843
+ os.path.join(output_folder, file_name),
844
+ data,
845
+ format="png",
846
+ )
847
+
848
+ except Exception as e:
849
+ _logger.error(f"Failed to dump {slice_url.path()}. Raison is {e}")
850
+
793
851
 
794
852
  class _VarSlider(qt.QWidget):
795
853
  def __init__(self, parent, orientation):
@@ -823,55 +881,3 @@ class _VarSlider(qt.QWidget):
823
881
 
824
882
  def value(self):
825
883
  return self._slider.value()
826
-
827
-
828
- if __name__ == "__main__":
829
- from silx.image.phantomgenerator import PhantomGenerator
830
- from silx.io.url import DataUrl
831
- import tempfile
832
- import os
833
- import h5py
834
- import shutil
835
- from scipy import stats
836
-
837
- app = qt.QApplication([])
838
- img_width = 216
839
- data = PhantomGenerator.get2DPhantomSheppLogan(n=img_width)
840
- nb_cor = 50
841
- urls = []
842
- slices_folder = tempfile.mkdtemp()
843
- for i in range(nb_cor):
844
- noise = (
845
- numpy.random.random(img_width * img_width).reshape(img_width, img_width)
846
- * 100.0
847
- )
848
- file_path = os.path.join(slices_folder, "slice_{}.hdf5".format(i))
849
- with h5py.File(file_path, mode="a") as h5f:
850
- h5f["data"] = noise + data
851
- urls.append(DataUrl(file_path=file_path, data_path="data", scheme="silx"))
852
- variance = 1
853
- mu = 0.5
854
- sigma = numpy.sqrt(variance)
855
- x = numpy.linspace(mu - 3 * sigma, mu + 3 * sigma, nb_cor)
856
- scores = stats.norm.pdf(x, mu, sigma)
857
-
858
- cor_values = numpy.linspace(80, 120, nb_cor)
859
- scores_dict = {}
860
- for cor, url, score in zip(cor_values, urls, scores):
861
- scores_dict[cor] = (url, score)
862
-
863
- window1 = ScorePlot(variable_name="var x")
864
- window1.setVarScores(scores=scores_dict, score_method="std")
865
- window1.show()
866
- from tomwer.core.scan.scanbase import TomwerScanBase
867
- from tomwer.core.process.reconstruction.saaxis.params import SAAxisParams
868
- from tomwer.core.process.reconstruction.saaxis.saaxis import SAAxisProcess
869
-
870
- scan = TomwerScanBase()
871
- scan.saaxis_params = SAAxisParams()
872
- scan.saaxis_params.scores = scores_dict
873
- SAAxisProcess.autofocus(scan)
874
- window1.setScan(scan)
875
- app.exec_()
876
-
877
- shutil.rmtree(slices_folder)
@@ -29,8 +29,8 @@ __date__ = "16/06/2021"
29
29
 
30
30
  from tomwer.gui.reconstruction.axis import AxisWindow
31
31
  from tomwer.gui.reconstruction.axis.radioaxis import _ManualFramesSelection
32
- from tomwer.test.utils import skip_gui_test
33
- from tomwer.test.utils import UtilsTest
32
+ from tomwer.tests.utils import skip_gui_test
33
+ from tomwer.tests.utils import UtilsTest
34
34
  from tomwer.core.process.reconstruction.axis.mode import AxisMode
35
35
  from tomwer.core.scan.edfscan import EDFTomoScan
36
36
  from tomwer.synctools.axis import QAxisRP
@@ -35,8 +35,8 @@ import pytest
35
35
  from silx.gui import qt
36
36
  from tomwer.core import settings
37
37
  from tomwer.gui.reconstruction.lamino.tofu import TofuWindow
38
- from tomwer.test.utils import UtilsTest
39
- from tomwer.test.utils import skip_gui_test
38
+ from tomwer.tests.utils import UtilsTest
39
+ from tomwer.tests.utils import skip_gui_test
40
40
 
41
41
 
42
42
  @pytest.mark.skipif(skip_gui_test(), reason="skip gui test")
@@ -29,7 +29,7 @@ __date__ = "05/02/2020"
29
29
 
30
30
  import os
31
31
  from silx.gui import qt
32
- from tomwer.test.utils import skip_gui_test
32
+ from tomwer.tests.utils import skip_gui_test
33
33
  from tomwer.gui.reconstruction.nabu.nabuflow import NabuFlowControl
34
34
  from tomwer.gui.reconstruction.nabu.nabuconfig.preprocessing import (
35
35
  _NabuPreProcessingConfig,
@@ -116,6 +116,7 @@ class TestNabuPreProcConfig(TestCaseQt):
116
116
  "log_min_clip": 1e-6,
117
117
  "log_max_clip": 10.0,
118
118
  "take_logarithm": True,
119
+ "normalize_srcurrent": 0,
119
120
  "sino_rings_correction": _RingCorrectionMethod.NONE.value,
120
121
  "sino_rings_options": "sigma=1.0 ; levels=10",
121
122
  "tilt_correction": "",
@@ -134,6 +135,7 @@ class TestNabuPreProcConfig(TestCaseQt):
134
135
  "log_min_clip": 1e-3,
135
136
  "log_max_clip": 250.0,
136
137
  "take_logarithm": False,
138
+ "normalize_srcurrent": 1,
137
139
  "sino_rings_correction": _RingCorrectionMethod.MUNCH.value,
138
140
  "sino_rings_options": "sigma=1.4 ; levels=11",
139
141
  "tilt_correction": "1d-correlation",
@@ -162,6 +164,10 @@ class TestNabuPhaseConfig(TestCaseQt):
162
164
  "padding_type": "edge",
163
165
  "unsharp_coeff": 0,
164
166
  "unsharp_sigma": 0,
167
+ "beam_shape": "parallel",
168
+ "ctf_advanced_params": " length_scale=1e-05; lim1=1e-05; lim2=0.2; normalize_by_mean=True",
169
+ "ctf_geometry": " z1_v=None; z1_h=None; detec_pixel_size=None; magnification=True",
170
+ "ctf_translations_file": "",
165
171
  }
166
172
  self.assertEqual(self.nabuWidget.getConfiguration(), ini_conf)
167
173
 
@@ -173,6 +179,10 @@ class TestNabuPhaseConfig(TestCaseQt):
173
179
  "padding_type": "zeros",
174
180
  "unsharp_coeff": 3.6,
175
181
  "unsharp_sigma": 2.1,
182
+ "beam_shape": "cone",
183
+ "ctf_advanced_params": " length_scale=1e-05; lim1=1e-05; lim2=0.2; normalize_by_mean=True",
184
+ "ctf_geometry": " z1_v=0.0; z1_h=0.0; detec_pixel_size=None; magnification=True",
185
+ "ctf_translations_file": "",
176
186
  }
177
187
  self.nabuWidget.setConfiguration(conf)
178
188
  self.nabuWidget.show()
@@ -225,6 +235,7 @@ class TestNabuReconstructionConfig(TestCaseQt):
225
235
  "positivity_constraint": 1,
226
236
  "translation_movements_file": "",
227
237
  "clip_outer_circle": 0,
238
+ "centered_axis": 0,
228
239
  }
229
240
  self.assertEqual(self.nabuWidget.getConfiguration(), ini_conf)
230
241
 
@@ -251,6 +262,7 @@ class TestNabuReconstructionConfig(TestCaseQt):
251
262
  "positivity_constraint": 0,
252
263
  "translation_movements_file": "my_file.csv",
253
264
  "clip_outer_circle": 1,
265
+ "centered_axis": 1,
254
266
  }
255
267
  self.nabuWidget.setConfiguration(ini_conf)
256
268
  self.qapp.processEvents()
@@ -268,6 +280,7 @@ class TestNabuReconstructionConfig(TestCaseQt):
268
280
  self.assertFalse(subRegionWidget._zSubRegion._maxQLE.isEnabled())
269
281
  self.assertFalse(self.nabuWidget._preconditioningFilter.isChecked())
270
282
  self.assertTrue(self.nabuWidget._clipOuterCircleCB.isChecked())
283
+ self.assertTrue(self.nabuWidget._centeredAxisCB.isChecked())
271
284
 
272
285
  # check the generated configuration
273
286
  self.assertEqual(self.nabuWidget.getConfiguration(), ini_conf)
@@ -27,7 +27,7 @@ __license__ = "MIT"
27
27
  __date__ = "03/02/2021"
28
28
 
29
29
 
30
- from tomwer.test.utils import skip_gui_test
30
+ from tomwer.tests.utils import skip_gui_test
31
31
  from tomwer.gui.reconstruction.saaxis.dimensionwidget import DimensionWidget
32
32
  from tomoscan.unitsystem import metricsystem
33
33
  from silx.gui.utils.testutils import TestCaseQt
@@ -41,7 +41,6 @@ from tomwer.core.process.reconstruction.scores import ComputedScore
41
41
  from tomwer.core.process.reconstruction.scores.params import ScoreMethod
42
42
  from silx.io.url import DataUrl
43
43
  from silx.gui import qt
44
- import unittest
45
44
  import pytest
46
45
  import numpy
47
46
  import shutil
@@ -203,19 +202,11 @@ class TestSAAxisWindow(TestCaseQt):
203
202
  self.assertEqual(configuration[key], res_conf[key])
204
203
 
205
204
  def testSetResults(self):
206
- """Test setting results"""
205
+ """Test setting results and saving result to a folder"""
207
206
  self._window.setCorScores(self._cor_scores, score_method="standard deviation")
208
-
209
-
210
- def suite():
211
- test_suite = unittest.TestSuite()
212
- for ui in (
213
- TestDimensionWidget,
214
- TestSAAxisWindow,
215
- ):
216
- test_suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(ui))
217
- return test_suite
218
-
219
-
220
- if __name__ == "__main__":
221
- unittest.main(defaultTest="suite")
207
+ # test saving snapshots
208
+ with tempfile.TemporaryDirectory() as output_png_imgs:
209
+ final_dir = os.path.join(output_png_imgs, "test/create/it")
210
+ self._window.saveReconstructedSlicesTo(final_dir)
211
+ assert os.path.exists(final_dir)
212
+ assert len(os.listdir(final_dir)) == len(self._cor_scores)
@@ -27,7 +27,7 @@ __license__ = "MIT"
27
27
  __date__ = "09/06/2021"
28
28
 
29
29
 
30
- from tomwer.test.utils import skip_gui_test
30
+ from tomwer.tests.utils import skip_gui_test
31
31
  from silx.gui.utils.testutils import TestCaseQt
32
32
  from tomwer.core.utils.scanutils import MockHDF5
33
33
  from tomwer.gui.reconstruction.sadeltabeta import SADeltaBetaWindow
@@ -36,7 +36,6 @@ from tomwer.core.process.reconstruction.scores.params import ScoreMethod
36
36
  from tomwer.core.process.reconstruction.scores import ComputedScore
37
37
  from silx.io.url import DataUrl
38
38
  from silx.gui import qt
39
- import unittest
40
39
  import pytest
41
40
  import numpy
42
41
  import shutil
@@ -132,14 +131,9 @@ class TestSADeltaBetaWindow(TestCaseQt):
132
131
  def testSetResults(self):
133
132
  """Test setting results"""
134
133
  self._window.setDBScores(self._cor_scores, score_method="total variation")
135
-
136
-
137
- def suite():
138
- test_suite = unittest.TestSuite()
139
- for ui in (TestSADeltaBetaWindow,):
140
- test_suite.addTest(unittest.defaultTestLoader.loadTestsFromTestCase(ui))
141
- return test_suite
142
-
143
-
144
- if __name__ == "__main__":
145
- unittest.main(defaultTest="suite")
134
+ # test saving snapshots
135
+ with tempfile.TemporaryDirectory() as output_png_imgs:
136
+ final_dir = os.path.join(output_png_imgs, "test/create/it")
137
+ self._window.saveReconstructedSlicesTo(final_dir)
138
+ assert os.path.exists(final_dir)
139
+ assert len(os.listdir(final_dir)) == len(self._cor_scores)
tomwer/gui/stackplot.py CHANGED
@@ -44,7 +44,8 @@ import logging
44
44
  from tomwer.gui import icons
45
45
  import functools
46
46
  import time
47
- from collections import namedtuple, Iterable
47
+ from collections import namedtuple
48
+ from typing import Iterable, Optional
48
49
 
49
50
  logger = logging.getLogger(__name__)
50
51
 
@@ -204,7 +205,7 @@ class _QImageStackPlot(qt.QWidget):
204
205
  self._qspinbox.blockSignals(False)
205
206
 
206
207
  def createStackImageInstance(self):
207
- return _StackImage()
208
+ return _StackImage(images=None)
208
209
 
209
210
  def showImage(self, index):
210
211
  """
@@ -232,25 +233,6 @@ class _QImageStackPlot(qt.QWidget):
232
233
  self._qspinbox.blockSignals(False)
233
234
  self._qslider.blockSignals(False)
234
235
 
235
- def setImage(self, index, data):
236
- """
237
- Set the given data as the image for the given index
238
-
239
- :param int index: the index of the image to set
240
- :param numpy.ndarray data: the image
241
- """
242
- _data = data
243
- if data is None:
244
- _data = self.IMG_NOT_FOUND
245
- self.images[index] = _data
246
-
247
- def isEmpty(self):
248
- """
249
-
250
- :return bool: True if no reconstruction has been set yet
251
- """
252
- return self.images.empty()
253
-
254
236
  def clear(self):
255
237
  self.setImages(None)
256
238
 
@@ -388,10 +370,6 @@ class _QImageFileStackPlot(_QImageStackPlot):
388
370
  self._qslider.valueChanged.connect(self.changeActiveImageFrmQSlider)
389
371
  self._qspinbox.valueChanged.connect(self.changeActiveImageFrmQSpinBox)
390
372
 
391
- def setLoadingImage(self, sliceNb):
392
- """Set the status of the image to not loaded"""
393
- self.setImage(sliceNb, _QImageFileStackPlot.IMG_LOADING)
394
-
395
373
  def setImages(self, imagesFiles):
396
374
  """
397
375
  Set the stack of images files
@@ -497,7 +475,7 @@ class _QImageFileStackPlot(_QImageStackPlot):
497
475
 
498
476
 
499
477
  class _StackImage(object):
500
- def __init__(self, images):
478
+ def __init__(self, images: Optional[Iterable]):
501
479
  _images = images
502
480
  if _images is None:
503
481
  _images = {}
@@ -516,6 +494,11 @@ class _StackImage(object):
516
494
  else:
517
495
  return self._images[index]
518
496
 
497
+ def setImages(self, images: Iterable):
498
+ self.clear()
499
+ for image in images:
500
+ self.addImage(image)
501
+
519
502
  def size(self):
520
503
  return len(self._images)
521
504
 
@@ -543,9 +526,9 @@ class _StackImageToLoad(_StackImage, qt.QObject):
543
526
  """Signal emitted when the loading mode is changed. Parameter are new mode,
544
527
  old mode"""
545
528
 
546
- def __init__(self, loadingMode=LAZY_LOADING):
529
+ def __init__(self, loadingMode=LAZY_LOADING, images: Optional[Iterable] = None):
547
530
  assert loadingMode in (LAZY_LOADING, ASAP_LOADING, ON_SHOW_LOADING)
548
- _StackImage.__init__(self, images=None)
531
+ _StackImage.__init__(self, images=images)
549
532
  qt.QObject.__init__(self)
550
533
  self._mode = loadingMode
551
534
  self._url_to_index = {}
@@ -1,7 +1,7 @@
1
1
  from tomwer.gui.reconstruction.axis.radioaxis import AxisTabWidget
2
2
  from tomwer.synctools.axis import QAxisRP
3
3
  from silx.gui.utils.testutils import TestCaseQt
4
- from tomwer.test.utils import skip_gui_test
4
+ from tomwer.tests.utils import skip_gui_test
5
5
  import pytest
6
6
 
7
7
 
@@ -13,14 +13,14 @@ class TestGetNabuCorOpts(TestCaseQt):
13
13
  """
14
14
  axis_params = QAxisRP()
15
15
  widget = AxisTabWidget(recons_params=axis_params)
16
- assert axis_params.get_nabu_cor_options() == "side='all'"
16
+ assert axis_params.get_nabu_cor_options_as_str() == "side='all'"
17
17
  widget._calculationWidget._corOpts.setText("low_pass=2")
18
18
  widget._calculationWidget._corOpts.editingFinished.emit()
19
- assert axis_params.get_nabu_cor_options() == "side='all' ; low_pass=2"
19
+ assert axis_params.get_nabu_cor_options_as_str() == "side='all' ; low_pass=2"
20
20
  widget._calculationWidget._corOpts.setText("low_pass=2 ; high_pass=10")
21
21
  widget._calculationWidget._sideCB.setCurrentText("left")
22
22
  widget._calculationWidget._corOpts.editingFinished.emit()
23
23
  assert (
24
- axis_params.get_nabu_cor_options()
24
+ axis_params.get_nabu_cor_options_as_str()
25
25
  == "side='left' ; low_pass=2 ; high_pass=10"
26
26
  )
@@ -0,0 +1,12 @@
1
+ import pytest
2
+ from tomwer.tests.conftest import qtapp # noqa F401
3
+ from tomwer.gui.qfolderdialog import QDataDialog
4
+
5
+
6
+ @pytest.mark.parametrize("multi_selection", (True, False))
7
+ def test_qdata_dialog(
8
+ qtapp, # noqa F401
9
+ multi_selection,
10
+ ):
11
+ dialog = QDataDialog(parent=None, multiSelection=multi_selection)
12
+ dialog.files_selected()
@@ -249,45 +249,57 @@ class NXTomomillOutputDirSelector(qt.QWidget):
249
249
  sigChanged = qt.Signal()
250
250
  """Signal emit when the output directory of the nx file change"""
251
251
 
252
+ DEFAULT_PROCESSED_DIR = (
253
+ "{scan_parent_dir_basename}/../PROCESSED_DATA/{scan_dir_name}"
254
+ )
255
+ """Default pattern to find the 'processed' directory"""
256
+
252
257
  def __init__(self, parent=None):
253
258
  qt.QWidget.__init__(self, parent)
254
259
  self.setLayout(qt.QGridLayout())
255
260
  self.__buttonGroup = qt.QButtonGroup(self)
256
261
  self.__buttonGroup.setExclusive(True)
257
262
 
258
- # automatic
259
- self._automaticRB = qt.QRadioButton("automatic", self)
260
- self._automaticRB.setToolTip(
261
- "Define the output directory of the "
262
- "nexus (.nx) file. Will be created at the"
263
- " same level as the bliss input file "
264
- "(.h5)"
265
- )
266
- self.layout().addWidget(self._automaticRB, 0, 0, 1, 1)
267
- self.__buttonGroup.addButton(self._automaticRB)
263
+ tooltip = f"""Define the output directory of the nexus (.nx) file. Options are:
264
+ \n - next to bliss file: create the NXtomos at the same level as the bliss input file
265
+ \n - 'PROCESSED_DATA' folder: create NXtomos on the default 'PROCESSED_DATA' folder (bliss default folder, nearby the 'raw' folder). Uses {self.DEFAULT_PROCESSED_DIR} pattern
266
+ \n - user defined folder: users can provide their own folders using keywords for string formatting such as 'scan_dir_name', 'scan_basename' or 'scan_parent_dir_basename'
267
+ """
268
+
269
+ # output dir is the folder containing the .nx file
270
+ self._closeToNxRB = qt.QRadioButton("next to bliss file", self)
271
+ self._closeToNxRB.setToolTip(tooltip)
272
+ self.layout().addWidget(self._closeToNxRB, 0, 0, 1, 1)
273
+ self.__buttonGroup.addButton(self._closeToNxRB)
274
+ # output dir is the default 'reduced'folder
275
+ self._processedFolderRB = qt.QRadioButton("'PROCESSED_DATA' folder", self)
276
+ self._processedFolderRB.setToolTip(tooltip)
277
+ self.layout().addWidget(self._processedFolderRB, 1, 0, 1, 1)
278
+ self.__buttonGroup.addButton(self._processedFolderRB)
268
279
  # manual
269
- self._manualRB = qt.QRadioButton("personalized output directory", self)
270
- self._manualRB.setToolTip("Define yourself the output directory")
271
- self.layout().addWidget(self._manualRB, 1, 0, 1, 1)
280
+ self._manualRB = qt.QRadioButton("custom output directory", self)
281
+ self._manualRB.setToolTip(tooltip)
282
+ self.layout().addWidget(self._manualRB, 2, 0, 1, 1)
272
283
  self._outputFolderQLE = qt.QLineEdit("", self)
273
- self.layout().addWidget(self._outputFolderQLE, 1, 1, 1, 1)
284
+ self.layout().addWidget(self._outputFolderQLE, 2, 1, 1, 1)
274
285
  self._selectButton = qt.QPushButton("", self)
275
286
  style = qt.QApplication.style()
276
287
  icon_opendir = style.standardIcon(qt.QStyle.SP_DirOpenIcon)
277
288
  self._selectButton.setIcon(icon_opendir)
278
289
  self._selectButton.setToolTip("select output directory")
279
- self.layout().addWidget(self._selectButton, 1, 2, 1, 1)
290
+ self.layout().addWidget(self._selectButton, 2, 2, 1, 1)
280
291
  self.__buttonGroup.addButton(self._manualRB)
281
292
 
282
293
  # connect signal / slot
283
294
  self._selectButton.released.connect(self._selectOutpuFolder)
284
295
  self.__buttonGroup.buttonReleased.connect(self._updateVisiblity)
285
- self._automaticRB.toggled.connect(self._outputDirChanged)
296
+ self._closeToNxRB.toggled.connect(self._outputDirChanged)
297
+ self._processedFolderRB.toggled.connect(self._outputDirChanged)
286
298
  self._manualRB.toggled.connect(self._outputDirChanged)
287
299
  self._outputFolderQLE.editingFinished.connect(self._outputDirChanged)
288
300
 
289
301
  # set up
290
- self._automaticRB.setChecked(True)
302
+ self._closeToNxRB.setChecked(True)
291
303
  self._updateVisiblity()
292
304
 
293
305
  def _updateVisiblity(self, *args, **kwargs):
@@ -297,7 +309,7 @@ class NXTomomillOutputDirSelector(qt.QWidget):
297
309
  def _outputDirChanged(self):
298
310
  self.sigChanged.emit()
299
311
 
300
- def _selectOutpuFolder(self):
312
+ def _selectOutpuFolder(self): # pragma: no cover
301
313
  defaultDirectory = self._outputFolderQLE.text()
302
314
  if os.path.isdir(defaultDirectory):
303
315
  defaultDirectory = get_default_directory()
@@ -315,14 +327,23 @@ class NXTomomillOutputDirSelector(qt.QWidget):
315
327
  def getOutputFolder(self) -> Union[None, str]:
316
328
  if self._manualRB.isChecked():
317
329
  return self._outputFolderQLE.text()
330
+ elif self._processedFolderRB.isChecked():
331
+ return self.DEFAULT_PROCESSED_DIR
318
332
  else:
319
333
  return None
320
334
 
321
335
  def setOutputFolder(self, output_folder: Optional[str]):
322
336
  old = self.blockSignals(True)
323
337
  self._manualRB.setChecked(output_folder is not None)
324
- if output_folder is not None:
325
- self._outputFolderQLE.setText(output_folder)
338
+ if output_folder is None:
339
+ self._closeToNxRB.setChecked()
340
+ else:
341
+ is_default_processed_folder = output_folder == self.DEFAULT_PROCESSED_DIR
342
+ if is_default_processed_folder:
343
+ self._processedFolderRB.setChecked(True)
344
+ else:
345
+ self._outputFolderQLE.setText(output_folder)
346
+ self._manualRB.setChecked(True)
326
347
  self._updateVisiblity()
327
348
  self.blockSignals(old)
328
349
 
@@ -359,7 +380,7 @@ class _ConfigFileSelector(qt.QWidget):
359
380
  def _clearFilePath(self):
360
381
  self._lineEdit.clear()
361
382
 
362
- def _selectCFGFile(self):
383
+ def _selectCFGFile(self): # pragma: no cover
363
384
  dialog = qt.QFileDialog(self)
364
385
  dialog.setFileMode(qt.QFileDialog.ExistingFile)
365
386