tomwer 1.3.26__py3-none-any.whl → 1.4.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.
- orangecontrib/tomwer/orange/managedprocess.py +1 -29
- orangecontrib/tomwer/orange/settings.py +2 -28
- orangecontrib/tomwer/tests/TestAcquisition.py +220 -0
- orangecontrib/tomwer/tutorials/append_raw_darks_and_flats_frames_to_NXtomos.ows +2 -2
- orangecontrib/tomwer/tutorials/copy_reduced_darks_and_flats_meth1.ows +1 -1
- orangecontrib/tomwer/tutorials/{icat_publication.ows → drac_publication.ows} +7 -21
- orangecontrib/tomwer/tutorials/id16b/ID16b_full_volume.ows +22 -0
- orangecontrib/tomwer/tutorials/id16b/ID16b_insitu.ows +302 -0
- orangecontrib/tomwer/tutorials/id16b/ID16b_normalization.ows +218 -0
- orangecontrib/tomwer/tutorials/simple_volume_to_slurm_reconstruction.ows +29 -24
- orangecontrib/tomwer/tutorials/test_cor.ows +19 -0
- orangecontrib/tomwer/tutorials/volume_casting_on_slurm.ows +54 -0
- orangecontrib/tomwer/widgets/__init__.py +3 -5
- orangecontrib/tomwer/widgets/cluster/FutureSupervisorOW.py +35 -54
- orangecontrib/tomwer/widgets/cluster/SlurmClusterOW.py +1 -31
- orangecontrib/tomwer/widgets/control/AdvancementOW.py +1 -29
- orangecontrib/tomwer/widgets/control/DataDiscoveryOW.py +5 -4
- orangecontrib/tomwer/widgets/control/DataListenerOW.py +1 -29
- orangecontrib/tomwer/widgets/control/DataSelectorOW.py +11 -30
- orangecontrib/tomwer/widgets/control/DataTransfertOW.py +2 -28
- orangecontrib/tomwer/widgets/control/DataValidatorOW.py +1 -28
- orangecontrib/tomwer/widgets/control/DataWatcherOW.py +1 -28
- orangecontrib/tomwer/widgets/control/EDF2NXTomomillOW.py +48 -51
- orangecontrib/tomwer/widgets/control/EmailOW.py +12 -2
- orangecontrib/tomwer/widgets/control/FilterOW.py +1 -28
- orangecontrib/tomwer/widgets/control/NXTomomillOW.py +37 -53
- orangecontrib/tomwer/widgets/control/NXtomoConcatenate.py +21 -20
- orangecontrib/tomwer/widgets/control/NotifierOW.py +9 -28
- orangecontrib/tomwer/widgets/control/ReduceDarkFlatSelectorOW.py +3 -2
- orangecontrib/tomwer/widgets/control/SingleTomoObjOW.py +1 -27
- orangecontrib/tomwer/widgets/control/TimerOW.py +9 -28
- orangecontrib/tomwer/widgets/control/TomoObjSeriesOW.py +58 -0
- orangecontrib/tomwer/widgets/control/VolumeSelector.py +8 -30
- orangecontrib/tomwer/widgets/control/icons/nxtomomill.svg +173 -119
- orangecontrib/tomwer/widgets/control/icons/reduced_darkflat_selector.png +0 -0
- orangecontrib/tomwer/widgets/control/icons/reduced_darkflat_selector.svg +55 -195
- orangecontrib/tomwer/widgets/control/icons/{tomoobjserie.svg → tomoobjseries.svg} +2 -2
- orangecontrib/tomwer/widgets/dataportal/PublishProcessedDataOW.py +172 -0
- orangecontrib/tomwer/widgets/{icat → dataportal}/__init__.py +2 -2
- orangecontrib/tomwer/widgets/debugtools/DatasetGeneratorOW.py +2 -29
- orangecontrib/tomwer/widgets/debugtools/ObjectInspectorOW.py +1 -29
- orangecontrib/tomwer/widgets/edit/DarkFlatPatchOW.py +48 -73
- orangecontrib/tomwer/widgets/edit/ImageKeyEditorOW.py +48 -75
- orangecontrib/tomwer/widgets/edit/ImageKeyUpgraderOW.py +5 -30
- orangecontrib/tomwer/widgets/edit/NXtomoEditorOW.py +51 -52
- orangecontrib/tomwer/widgets/other/PythonScriptOW.py +22 -10
- orangecontrib/tomwer/widgets/reconstruction/AxisOW.py +51 -60
- orangecontrib/tomwer/widgets/reconstruction/CastNabuVolumeOW.py +22 -68
- orangecontrib/tomwer/widgets/reconstruction/DarkRefAndCopyOW.py +3 -30
- orangecontrib/tomwer/widgets/reconstruction/NabuHelicalPrepareWeightsDoubleOW.py +21 -19
- orangecontrib/tomwer/widgets/reconstruction/NabuOW.py +7 -70
- orangecontrib/tomwer/widgets/reconstruction/NabuVolumeOW.py +41 -84
- orangecontrib/tomwer/widgets/reconstruction/SAAxisOW.py +15 -40
- orangecontrib/tomwer/widgets/reconstruction/SADeltaBetaOW.py +13 -35
- orangecontrib/tomwer/widgets/reconstruction/SinoNormOW.py +2 -30
- orangecontrib/tomwer/widgets/stitching/ZStitchingConfigOW.py +11 -11
- orangecontrib/tomwer/widgets/utils.py +2 -29
- orangecontrib/tomwer/widgets/visualization/DataViewerOW.py +1 -27
- orangecontrib/tomwer/widgets/visualization/DiffViewerOW.py +1 -27
- orangecontrib/tomwer/widgets/visualization/NXtomoMetadataViewerOW.py +1 -1
- orangecontrib/tomwer/widgets/visualization/RadioStackOW.py +2 -28
- orangecontrib/tomwer/widgets/visualization/SampleMovedOW.py +1 -27
- orangecontrib/tomwer/widgets/visualization/SinogramViewerOW.py +1 -27
- orangecontrib/tomwer/widgets/visualization/SliceStackOW.py +2 -28
- tomwer/__init__.py +3 -28
- tomwer/__main__.py +8 -4
- tomwer/app/__init__.py +2 -0
- tomwer/app/axis.py +8 -10
- tomwer/app/canvas.py +23 -29
- tomwer/app/canvas_launcher/config.py +14 -102
- tomwer/app/canvas_launcher/environ.py +5 -8
- tomwer/app/canvas_launcher/mainwindow.py +175 -69
- tomwer/app/canvas_launcher/splash.py +1 -3
- tomwer/app/canvas_launcher/utils.py +47 -0
- tomwer/app/canvas_launcher/widgetsscheme.py +3 -10
- tomwer/app/diffframe.py +2 -0
- tomwer/app/imagekeyeditor.py +2 -1
- tomwer/app/imagekeyupgrader.py +2 -0
- tomwer/app/multicor.py +5 -2
- tomwer/app/multipag.py +16 -5
- tomwer/app/nabuapp.py +2 -1
- tomwer/app/nxtomoeditor.py +17 -12
- tomwer/app/patchrawdarkflat.py +2 -0
- tomwer/app/radiostack.py +3 -2
- tomwer/app/reducedarkflat.py +3 -0
- tomwer/app/samplemoved.py +2 -0
- tomwer/app/scanviewer.py +2 -0
- tomwer/app/sinogramviewer.py +2 -0
- tomwer/app/slicestack.py +11 -13
- tomwer/app/stitching/common.py +431 -0
- tomwer/app/stopdatalistener.py +3 -0
- tomwer/app/ystitching.py +26 -0
- tomwer/app/zstitching.py +8 -363
- tomwer/core/__init__.py +2 -28
- tomwer/core/cluster/__init__.py +3 -0
- tomwer/core/cluster/cluster.py +10 -26
- tomwer/core/futureobject.py +17 -43
- tomwer/core/log/__init__.py +2 -0
- tomwer/core/log/processlog.py +0 -28
- tomwer/core/process/cluster/supervisor.py +52 -34
- tomwer/core/process/conditions/filters.py +3 -28
- tomwer/core/process/control/datalistener/datalistener.py +7 -75
- tomwer/core/process/control/datalistener/rpcserver.py +8 -38
- tomwer/core/process/control/datawatcher/datawatcher.py +11 -40
- tomwer/core/process/control/datawatcher/datawatcherobserver.py +30 -64
- tomwer/core/process/control/datawatcher/datawatcherprocess.py +11 -32
- tomwer/core/process/control/datawatcher/edfdwprocess.py +2 -27
- tomwer/core/process/control/datawatcher/hdf5dwprocess.py +1 -26
- tomwer/core/process/control/datawatcher/status.py +1 -26
- tomwer/core/process/control/emailnotifier.py +11 -23
- tomwer/core/process/control/nxtomoconcatenate.py +20 -18
- tomwer/core/process/control/nxtomomill.py +9 -44
- tomwer/core/process/control/scanlist.py +0 -27
- tomwer/core/process/control/scantransfer.py +15 -13
- tomwer/core/process/control/scanvalidator.py +4 -30
- tomwer/core/process/control/{test → tests}/test_concatenate_nxtomos.py +5 -5
- tomwer/core/process/control/timer.py +1 -27
- tomwer/core/process/control/tomoobjseries.py +12 -0
- tomwer/core/process/drac/binning.py +37 -0
- tomwer/core/process/drac/dracbase.py +170 -0
- tomwer/core/process/drac/gallery.py +109 -0
- tomwer/core/process/drac/output.py +12 -0
- tomwer/core/process/drac/processeddataset.py +147 -0
- tomwer/core/process/drac/publish.py +118 -0
- tomwer/core/process/drac/rawdataset.py +142 -0
- tomwer/core/process/drac/tests/test_gallery.py +71 -0
- tomwer/core/process/drac/tests/test_icat_processed_dataset.py +80 -0
- tomwer/core/process/drac/tests/test_icat_raw_dataset.py +90 -0
- tomwer/core/process/edit/darkflatpatch.py +1 -28
- tomwer/core/process/edit/imagekeyeditor.py +4 -32
- tomwer/core/process/edit/nxtomoeditor.py +307 -0
- tomwer/core/process/edit/tests/test_darkflatpatch.py +243 -0
- tomwer/core/process/edit/tests/test_imagekey_editor.py +99 -0
- tomwer/core/process/output.py +9 -2
- tomwer/core/process/reconstruction/__init__.py +0 -26
- tomwer/core/process/reconstruction/axis/anglemode.py +1 -29
- tomwer/core/process/reconstruction/axis/axis.py +47 -804
- tomwer/core/process/reconstruction/axis/mode.py +89 -25
- tomwer/core/process/reconstruction/axis/params.py +131 -283
- tomwer/core/process/reconstruction/axis/projectiontype.py +0 -28
- tomwer/core/process/reconstruction/axis/side.py +8 -0
- tomwer/core/process/reconstruction/darkref/darkrefs.py +14 -39
- tomwer/core/process/reconstruction/darkref/darkrefscopy.py +7 -39
- tomwer/core/process/reconstruction/darkref/params.py +1 -28
- tomwer/core/process/reconstruction/nabu/castvolume.py +19 -34
- tomwer/core/process/reconstruction/nabu/nabucommon.py +18 -43
- tomwer/core/process/reconstruction/nabu/nabuscores.py +64 -68
- tomwer/core/process/reconstruction/nabu/nabuslices.py +63 -105
- tomwer/core/process/reconstruction/nabu/nabuvolume.py +44 -70
- tomwer/core/process/reconstruction/nabu/plane.py +10 -0
- tomwer/core/process/reconstruction/nabu/settings.py +1 -28
- tomwer/core/process/reconstruction/nabu/target.py +0 -28
- tomwer/core/process/reconstruction/nabu/test/test_castvolume.py +116 -0
- tomwer/core/process/reconstruction/nabu/test/test_nabu_utils.py +277 -0
- tomwer/core/process/reconstruction/nabu/test/test_nabunormalization.py +199 -0
- tomwer/core/process/reconstruction/nabu/utils.py +11 -60
- tomwer/core/process/reconstruction/normalization/normalization.py +2 -32
- tomwer/core/process/reconstruction/normalization/params.py +3 -35
- tomwer/core/process/reconstruction/output.py +14 -19
- tomwer/core/process/reconstruction/paramsbase.py +4 -33
- tomwer/core/process/reconstruction/saaxis/params.py +5 -33
- tomwer/core/process/reconstruction/saaxis/saaxis.py +22 -51
- tomwer/core/process/reconstruction/sadeltabeta/params.py +2 -31
- tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py +18 -46
- tomwer/core/process/reconstruction/scores/params.py +9 -39
- tomwer/core/process/reconstruction/scores/scores.py +10 -42
- tomwer/core/process/reconstruction/tests/__init__.py +0 -0
- tomwer/core/process/reconstruction/tests/test_axis.py +46 -0
- tomwer/core/process/reconstruction/tests/test_darkref.py +33 -0
- tomwer/core/process/reconstruction/{test → tests}/test_saaxis.py +1 -27
- tomwer/core/process/reconstruction/tests/test_sadeltabeta.py +48 -0
- tomwer/core/process/reconstruction/{test → tests}/test_utils.py +4 -4
- tomwer/core/process/reconstruction/utils/cor.py +8 -4
- tomwer/core/process/script/python.py +1 -27
- tomwer/core/process/script/tests/test_script.py +41 -0
- tomwer/core/process/stitching/metadataholder.py +5 -4
- tomwer/core/process/stitching/nabustitcher.py +35 -5
- tomwer/core/process/stitching/tests/test_metadataholder.py +17 -0
- tomwer/core/process/task.py +20 -63
- tomwer/core/process/tests/__init__.py +0 -0
- tomwer/core/process/{test → tests}/test_conditions.py +1 -28
- tomwer/core/process/{test → tests}/test_dark_and_flat.py +1 -27
- tomwer/core/process/{test → tests}/test_data_listener.py +1 -27
- tomwer/core/process/{test → tests}/test_data_transfer.py +2 -28
- tomwer/core/process/{test → tests}/test_data_watcher.py +1 -27
- tomwer/core/process/{test → tests}/test_nabu.py +2 -33
- tomwer/core/process/{test → tests}/test_normalization.py +1 -26
- tomwer/core/process/{test → tests}/test_timer.py +1 -27
- tomwer/core/process/utils.py +2 -31
- tomwer/core/process/visualization/dataviewer.py +1 -26
- tomwer/core/process/visualization/diffviewer.py +1 -26
- tomwer/core/process/visualization/imagestackviewer.py +0 -26
- tomwer/core/process/visualization/radiostack.py +0 -26
- tomwer/core/process/visualization/samplemoved.py +0 -28
- tomwer/core/process/visualization/sinogramviewer.py +0 -27
- tomwer/core/process/visualization/slicestack.py +0 -28
- tomwer/core/process/visualization/tests/test_data_viewer.py +12 -0
- tomwer/core/process/visualization/tests/test_diff_viewer.py +12 -0
- tomwer/core/process/visualization/tests/test_image_stack_viewer.py +14 -0
- tomwer/core/process/visualization/tests/test_radio_stack.py +12 -0
- tomwer/core/process/visualization/tests/test_sample_moved.py +14 -0
- tomwer/core/process/visualization/tests/test_sinogram_viewer.py +13 -0
- tomwer/core/process/visualization/tests/test_slice_stack.py +13 -0
- tomwer/core/process/visualization/tests/test_volume_viewer.py +12 -0
- tomwer/core/process/visualization/volumeviewer.py +0 -29
- tomwer/core/scan/__init__.py +3 -27
- tomwer/core/scan/blissscan.py +5 -34
- tomwer/core/scan/edfscan.py +19 -53
- tomwer/core/scan/hdf5scan.py +2 -2
- tomwer/core/scan/nxtomoscan.py +48 -54
- tomwer/core/scan/scanbase.py +107 -203
- tomwer/core/scan/scanfactory.py +11 -41
- tomwer/core/scan/tests/__init__.py +0 -0
- tomwer/core/scan/tests/test_edf.py +25 -0
- tomwer/core/scan/tests/test_future_scan.py +35 -0
- tomwer/core/scan/tests/test_nxtomoscan.py +143 -0
- tomwer/core/scan/tests/test_process_registration.py +64 -0
- tomwer/core/settings.py +18 -40
- tomwer/core/tests/__init__.py +0 -0
- tomwer/core/tests/test_scanutils.py +26 -0
- tomwer/core/{test → tests}/test_utils.py +1 -28
- tomwer/core/tomwer_object.py +4 -0
- tomwer/core/utils/__init__.py +2 -0
- tomwer/core/utils/char.py +0 -28
- tomwer/core/utils/deprecation.py +12 -38
- tomwer/core/utils/dictutils.py +1 -3
- tomwer/core/utils/ftseriesutils.py +1 -27
- tomwer/core/utils/gpu.py +0 -28
- tomwer/core/utils/image.py +8 -39
- tomwer/core/utils/locker.py +1 -28
- tomwer/core/utils/logconfig.py +0 -27
- tomwer/core/utils/normalization.py +4 -31
- tomwer/core/utils/nxtomoutils.py +8 -38
- tomwer/core/utils/resource.py +0 -26
- tomwer/core/utils/scanutils.py +23 -52
- tomwer/core/utils/slurm.py +7 -30
- tomwer/core/utils/spec.py +6 -6
- tomwer/core/utils/tests/__init__.py +0 -0
- tomwer/core/utils/tests/test_image.py +30 -0
- tomwer/core/utils/tests/test_nxtomo.py +38 -0
- tomwer/core/utils/tests/test_scan_utils.py +46 -0
- tomwer/core/utils/tests/test_time.py +6 -0
- tomwer/core/utils/threads.py +0 -26
- tomwer/core/utils/time.py +0 -27
- tomwer/core/volume/__init__.py +4 -0
- tomwer/core/volume/edfvolume.py +1 -28
- tomwer/core/volume/hdf5volume.py +1 -28
- tomwer/core/volume/jp2kvolume.py +1 -27
- tomwer/core/volume/rawvolume.py +1 -28
- tomwer/core/volume/tests/test_volumes.py +21 -0
- tomwer/core/volume/tiffvolume.py +1 -28
- tomwer/core/volume/volumebase.py +5 -0
- tomwer/core/volume/volumefactory.py +7 -33
- tomwer/gui/__init__.py +0 -28
- tomwer/gui/cluster/__init__.py +2 -0
- tomwer/gui/cluster/slurm.py +297 -95
- tomwer/gui/cluster/supervisor.py +1 -27
- tomwer/gui/cluster/tests/__init__.py +0 -0
- tomwer/gui/cluster/{test → tests}/test_cluster.py +21 -26
- tomwer/gui/cluster/{test → tests}/test_supervisor.py +1 -27
- tomwer/gui/conditions/__init__.py +2 -0
- tomwer/gui/conditions/filter.py +1 -26
- tomwer/gui/configuration/__init__.py +2 -0
- tomwer/gui/control/__init__.py +2 -0
- tomwer/gui/control/actions.py +2 -28
- tomwer/gui/control/datadiscovery.py +4 -3
- tomwer/gui/control/datalist.py +64 -69
- tomwer/gui/control/datalistener.py +1 -39
- tomwer/gui/control/datareacheractions.py +1 -28
- tomwer/gui/control/datatransfert.py +2 -29
- tomwer/gui/control/datavalidator.py +3 -37
- tomwer/gui/control/datawatcher/__init__.py +0 -28
- tomwer/gui/control/datawatcher/configuration.py +1 -28
- tomwer/gui/control/datawatcher/datawatcher.py +3 -32
- tomwer/gui/control/datawatcher/datawatcherobserver.py +2 -28
- tomwer/gui/control/history.py +5 -35
- tomwer/gui/control/nxtomomill.py +3 -30
- tomwer/gui/control/observations.py +61 -55
- tomwer/gui/control/reducedarkflatselector.py +24 -20
- tomwer/gui/control/scanselectorwidget.py +2 -28
- tomwer/gui/control/selectorwidgetbase.py +17 -17
- tomwer/gui/control/series/__init__.py +0 -0
- tomwer/gui/control/{serie/seriecreator.py → series/seriescreator.py} +214 -235
- tomwer/gui/control/series/serieswaiter.py +0 -0
- tomwer/gui/control/series/test/test_creator.py +424 -0
- tomwer/gui/control/series/test/test_nxtomo_concatenate.py +21 -0
- tomwer/gui/control/singletomoobj.py +1 -1
- tomwer/gui/control/tests/__init__.py +0 -0
- tomwer/gui/control/tests/test_datalist.py +47 -0
- tomwer/gui/control/{test → tests}/test_datalistener.py +1 -28
- tomwer/gui/control/tests/test_datavalidator.py +27 -0
- tomwer/gui/control/{test → tests}/test_inputwidget.py +1 -27
- tomwer/gui/control/tests/test_process_manager.py +38 -0
- tomwer/gui/control/tests/test_scan_observations.py +23 -0
- tomwer/gui/control/tests/test_scanselector.py +42 -0
- tomwer/gui/control/{test → tests}/test_scanvalidator.py +1 -27
- tomwer/gui/control/{test → tests}/test_volume_dialog.py +2 -30
- tomwer/gui/control/{test → tests}/test_volumeselector.py +1 -27
- tomwer/gui/control/volumeselectorwidget.py +2 -30
- tomwer/gui/dataportal/__init__.py +2 -0
- tomwer/gui/{icat → dataportal}/createscreenshots.py +3 -2
- tomwer/gui/dataportal/gallery.py +133 -0
- tomwer/gui/dataportal/outputformat.py +0 -0
- tomwer/gui/dataportal/publish.py +96 -0
- tomwer/gui/dataportal/tests/test_create_screenshots_gui.py +23 -0
- tomwer/gui/dataportal/tests/test_gallery_gui.py +21 -0
- tomwer/gui/debugtools/__init__.py +2 -0
- tomwer/gui/debugtools/datasetgenerator.py +1 -30
- tomwer/gui/debugtools/objectinspector.py +1 -29
- tomwer/gui/dialog/QDataDialog.py +89 -0
- tomwer/gui/{qfolderdialog.py → dialog/QVolumeDialog.py} +8 -107
- tomwer/gui/dialog/__init__.py +1 -0
- tomwer/gui/edit/__init__.py +2 -0
- tomwer/gui/edit/dkrfpatch.py +52 -87
- tomwer/gui/edit/imagekeyeditor.py +18 -54
- tomwer/gui/edit/nxtomoeditor.py +113 -300
- tomwer/gui/edit/nxtomowarmer.py +3 -2
- tomwer/gui/edit/tests/__init__.py +0 -0
- tomwer/gui/edit/{test → tests}/test_dkrf_patch.py +3 -29
- tomwer/gui/edit/{test → tests}/test_image_key_editor.py +1 -27
- tomwer/gui/edit/{test → tests}/test_nx_editor.py +45 -23
- tomwer/gui/fonts.py +5 -0
- tomwer/gui/icons.py +28 -66
- tomwer/gui/illustrations.py +4 -34
- tomwer/gui/imagefromfile.py +5 -30
- tomwer/gui/metadataloader.py +36 -0
- tomwer/gui/qconfigfile.py +3 -0
- tomwer/gui/qlefilesystem.py +3 -0
- tomwer/gui/reconstruction/__init__.py +2 -0
- tomwer/gui/reconstruction/axis/AxisMainWindow.py +275 -0
- tomwer/gui/reconstruction/axis/AxisOptionsWidget.py +313 -0
- tomwer/gui/reconstruction/axis/AxisSettingsWidget.py +797 -0
- tomwer/gui/reconstruction/axis/AxisWidget.py +534 -0
- tomwer/gui/reconstruction/axis/CalculationWidget.py +218 -0
- tomwer/gui/reconstruction/axis/CompareImages.py +11 -44
- tomwer/gui/reconstruction/axis/ControlWidget.py +285 -0
- tomwer/gui/reconstruction/axis/EstimatedCORWidget.py +394 -0
- tomwer/gui/reconstruction/axis/EstimatedCorComboBox.py +118 -0
- tomwer/gui/reconstruction/axis/InputWidget.py +347 -0
- tomwer/gui/reconstruction/axis/ManualFramesSelection.py +168 -0
- tomwer/gui/reconstruction/axis/__init__.py +2 -2
- tomwer/gui/reconstruction/darkref/__init__.py +0 -27
- tomwer/gui/reconstruction/darkref/darkrefcopywidget.py +5 -34
- tomwer/gui/reconstruction/darkref/darkrefwidget.py +1 -27
- tomwer/gui/reconstruction/nabu/castvolume.py +40 -59
- tomwer/gui/reconstruction/nabu/check.py +7 -33
- tomwer/gui/reconstruction/nabu/nabuconfig/base.py +7 -34
- tomwer/gui/reconstruction/nabu/nabuconfig/ctf.py +6 -5
- tomwer/gui/reconstruction/nabu/nabuconfig/nabuconfig.py +10 -69
- tomwer/gui/reconstruction/nabu/nabuconfig/output.py +3 -47
- tomwer/gui/reconstruction/nabu/nabuconfig/phase.py +54 -36
- tomwer/gui/reconstruction/nabu/nabuconfig/preprocessing.py +103 -54
- tomwer/gui/reconstruction/nabu/nabuconfig/reconstruction.py +116 -65
- tomwer/gui/reconstruction/nabu/nabuflow.py +31 -61
- tomwer/gui/reconstruction/nabu/platform.py +94 -0
- tomwer/gui/reconstruction/nabu/slices.py +81 -45
- tomwer/gui/reconstruction/nabu/slurm.py +1 -27
- tomwer/gui/reconstruction/nabu/test/test_cast_volume.py +82 -0
- tomwer/gui/reconstruction/nabu/test/test_check.py +66 -0
- tomwer/gui/reconstruction/nabu/test/test_ctf.py +46 -0
- tomwer/gui/reconstruction/nabu/test/test_helical.py +21 -0
- tomwer/gui/reconstruction/nabu/test/test_nabu_preprocessing.py +81 -0
- tomwer/gui/reconstruction/nabu/volume.py +62 -90
- tomwer/gui/reconstruction/normalization/intensity.py +5 -32
- tomwer/gui/reconstruction/normalization/test/test_intensity.py +89 -0
- tomwer/gui/reconstruction/saaxis/corrangeselector.py +32 -56
- tomwer/gui/reconstruction/saaxis/dimensionwidget.py +56 -96
- tomwer/gui/reconstruction/saaxis/saaxis.py +17 -38
- tomwer/gui/reconstruction/saaxis/sliceselector.py +8 -39
- tomwer/gui/reconstruction/sadeltabeta/saadeltabeta.py +19 -37
- tomwer/gui/reconstruction/scores/control.py +2 -30
- tomwer/gui/reconstruction/scores/scoreplot.py +23 -49
- tomwer/gui/reconstruction/tests/__init__.py +0 -0
- tomwer/gui/reconstruction/{test → tests}/test_axis.py +23 -49
- tomwer/gui/reconstruction/{test → tests}/test_nabu.py +16 -31
- tomwer/gui/reconstruction/{test → tests}/test_saaxis.py +10 -37
- tomwer/gui/reconstruction/{test → tests}/test_sadeltabeta.py +1 -26
- tomwer/gui/samplemoved/__init__.py +2 -30
- tomwer/gui/samplemoved/selectiontable.py +3 -33
- tomwer/gui/settings.py +7 -0
- tomwer/gui/stackplot.py +33 -661
- tomwer/gui/stacks.py +261 -135
- tomwer/gui/stitching/SingleAxisStitchingWidget.py +326 -0
- tomwer/gui/stitching/StitchingOptionsWidget.py +438 -0
- tomwer/gui/stitching/StitchingWindow.py +586 -0
- tomwer/gui/stitching/__init__.py +2 -0
- tomwer/gui/stitching/alignment.py +90 -0
- tomwer/gui/stitching/axisorderedlist.py +44 -34
- tomwer/gui/stitching/config/axisparams.py +25 -11
- tomwer/gui/stitching/config/output.py +6 -5
- tomwer/gui/stitching/config/positionoveraxis.py +313 -51
- tomwer/gui/stitching/config/stitchingstrategies.py +22 -16
- tomwer/gui/stitching/config/tests/test_axisparams.py +25 -0
- tomwer/gui/stitching/config/tomoobjdetails.py +3 -5
- tomwer/gui/stitching/normalization.py +1 -0
- tomwer/gui/stitching/preview.py +59 -0
- tomwer/gui/stitching/singleaxis.py +57 -0
- tomwer/gui/stitching/stitchandbackground.py +3 -2
- tomwer/gui/stitching/stitching_preview.py +44 -36
- tomwer/gui/stitching/stitching_raw.py +5 -3
- tomwer/gui/stitching/tests/test_ZStitchingWindow.py +88 -0
- tomwer/gui/stitching/tests/test_axis_ordered_list.py +21 -0
- tomwer/gui/stitching/tests/test_normalization.py +27 -0
- tomwer/gui/stitching/tests/test_preview.py +68 -0
- tomwer/gui/stitching/tests/test_stitching_raw.py +110 -0
- tomwer/gui/stitching/tests/utils.py +92 -0
- tomwer/gui/stitching/utils.py +14 -0
- tomwer/gui/stitching/z_stitching/fineestimation.py +5 -33
- tomwer/gui/stitching/z_stitching/tests/test_fine_estimation.py +35 -0
- tomwer/gui/stitching/z_stitching/tests/test_raw_estimation.py +215 -0
- tomwer/gui/stitching/z_stitching/tests/test_stitching_window.py +51 -0
- tomwer/gui/tests/__init__.py +0 -0
- tomwer/gui/tests/test_axis_gui.py +43 -0
- tomwer/gui/{test → tests}/test_qfolder_dialog.py +1 -1
- tomwer/gui/utils/RangeWidget.py +44 -0
- tomwer/gui/utils/buttons.py +4 -3
- tomwer/gui/utils/completer.py +2 -33
- tomwer/gui/utils/flow.py +11 -40
- tomwer/gui/utils/gpu.py +60 -0
- tomwer/gui/utils/illustrations.py +1 -26
- tomwer/gui/utils/inputwidget.py +35 -73
- tomwer/gui/utils/lineselector/lineselector.py +9 -46
- tomwer/gui/utils/loadingmode.py +81 -0
- tomwer/gui/utils/qt_utils.py +9 -0
- tomwer/gui/utils/sandboxes.py +1 -26
- tomwer/gui/utils/scandescription.py +2 -31
- tomwer/gui/utils/scrollarea.py +6 -55
- tomwer/gui/utils/slider.py +4 -28
- tomwer/gui/utils/splashscreen.py +0 -28
- tomwer/gui/utils/step.py +14 -13
- tomwer/gui/utils/tests/test_completer.py +41 -0
- tomwer/gui/utils/tests/test_line_selector.py +21 -0
- tomwer/gui/utils/tests/test_splashscreen.py +8 -0
- tomwer/gui/utils/tests/test_vignettes.py +68 -0
- tomwer/gui/utils/unitsystem.py +15 -69
- tomwer/gui/utils/utils.py +4 -5
- tomwer/gui/utils/vignettes.py +10 -41
- tomwer/gui/utils/waiterthread.py +0 -26
- tomwer/gui/visualization/__init__.py +2 -0
- tomwer/gui/visualization/dataviewer.py +68 -421
- tomwer/gui/visualization/diffviewer/diffviewer.py +2 -30
- tomwer/gui/visualization/diffviewer/shiftwidget.py +4 -29
- tomwer/gui/visualization/fullscreenplot.py +5 -5
- tomwer/gui/visualization/imagestack.py +403 -0
- tomwer/gui/visualization/nxtomometadata.py +0 -4
- tomwer/gui/visualization/reconstructionparameters.py +14 -32
- tomwer/gui/visualization/scanoverview.py +33 -66
- tomwer/gui/visualization/sinogramviewer.py +2 -28
- tomwer/gui/visualization/test/__init__.py +0 -28
- tomwer/gui/visualization/test/test_dataviewer.py +1 -28
- tomwer/gui/visualization/test/test_diffviewer.py +1 -28
- tomwer/gui/visualization/test/test_nx_tomo_metadata_viewer.py +0 -5
- tomwer/gui/visualization/test/test_reconstruction_parameters.py +1 -27
- tomwer/gui/visualization/test/test_sinogramviewer.py +1 -28
- tomwer/gui/visualization/test/test_stacks.py +184 -115
- tomwer/gui/visualization/test/test_volumeviewer.py +3 -2
- tomwer/gui/visualization/tomoobjoverview.py +2 -2
- tomwer/gui/visualization/volumeoverview.py +3 -2
- tomwer/gui/visualization/volumeviewer.py +47 -43
- tomwer/io/__init__.py +2 -0
- tomwer/io/utils/h5pyutils.py +1 -27
- tomwer/io/utils/test/test_raw_and_processed_data.py +10 -0
- tomwer/io/utils/test/test_utils.py +67 -0
- tomwer/io/utils/utils.py +2 -31
- tomwer/resources/__init__.py +13 -33
- tomwer/resources/gui/icons/edit_downstream.svg +114 -0
- tomwer/resources/gui/icons/edit_upstream.svg +112 -0
- tomwer/resources/gui/icons/free_edition.svg +23 -0
- tomwer/resources/gui/icons/icat_gallery_opts.png +0 -0
- tomwer/resources/gui/icons/icat_gallery_opts.svg +80 -0
- tomwer/resources/gui/icons/search.png +0 -0
- tomwer/resources/gui/icons/search.svg +23 -0
- tomwer/resources/gui/icons/warning.png +0 -0
- tomwer/synctools/__init__.py +2 -0
- tomwer/synctools/axis.py +1 -27
- tomwer/synctools/darkref.py +1 -26
- tomwer/synctools/datalistener.py +1 -27
- tomwer/synctools/datatransfert.py +2 -27
- tomwer/synctools/imageloaderthread.py +1 -28
- tomwer/synctools/rsyncmanager.py +1 -25
- tomwer/synctools/saaxis.py +1 -26
- tomwer/synctools/sadeltabeta.py +1 -26
- tomwer/synctools/stacks/control/datalistener.py +1 -26
- tomwer/synctools/stacks/processingstack.py +4 -33
- tomwer/synctools/stacks/reconstruction/axis.py +6 -53
- tomwer/synctools/stacks/reconstruction/castvolume.py +12 -43
- tomwer/synctools/stacks/reconstruction/dkrefcopy.py +4 -27
- tomwer/synctools/stacks/reconstruction/nabu.py +3 -28
- tomwer/synctools/stacks/reconstruction/normalization.py +2 -27
- tomwer/synctools/stacks/reconstruction/saaxis.py +2 -27
- tomwer/synctools/stacks/reconstruction/sadeltabeta.py +2 -27
- tomwer/synctools/tests/__init__.py +0 -0
- tomwer/synctools/{test → tests}/test_darkRefs.py +16 -40
- tomwer/synctools/{test → tests}/test_foldertransfer.py +2 -33
- tomwer/synctools/utils/scanstages.py +2 -31
- tomwer/tests/__init__.py +1 -0
- tomwer/tests/app/test_stitching.py +95 -0
- tomwer/tests/datasets.py +1 -5
- tomwer/tests/orangecontrib/tomwer/widgets/cluster/tests/test_future_supervisorow.py +48 -0
- tomwer/tests/orangecontrib/tomwer/widgets/cluster/tests/test_slurm_clusterow.py +40 -0
- tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_advancement.py +8 -0
- tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_data_validator.py +55 -0
- tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_datadiscovery.py +129 -0
- tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_datalistener.py +111 -0
- tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_dataselector.py +69 -0
- tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_datawatcher.py +411 -0
- tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_emailow.py +29 -0
- tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_notifier.py +24 -0
- tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_nxtomo_concatenate_ow.py +64 -0
- tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_nxtomomill.py +133 -0
- tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_reduce_dark_flat_selector.py +40 -0
- tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_singletomoobj.py +40 -0
- tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_timerow.py +25 -0
- tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_tomoobj_series.py +96 -0
- tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_volume_selector.py +69 -0
- orangecontrib/tomwer/widgets/edit/test/test_image_key_editor.py → tomwer/tests/orangecontrib/tomwer/widgets/debugtools/tests/test_dataset_generator.py +17 -16
- tomwer/tests/orangecontrib/tomwer/widgets/debugtools/tests/test_object_inspector.py +36 -0
- {orangecontrib/tomwer/widgets/edit/test → tomwer/tests/orangecontrib/tomwer/widgets/edit/tests}/test_dark_flat_patch.py +1 -27
- tomwer/tests/orangecontrib/tomwer/widgets/edit/tests/test_image_key_editor.py +30 -0
- tomwer/tests/orangecontrib/tomwer/widgets/edit/tests/test_nxtomo_editor.py +138 -0
- tomwer/tests/orangecontrib/tomwer/widgets/other/tests/test_pythonscript.py +31 -0
- tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_axis.py +199 -0
- tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_cast_volumeow.py +58 -0
- tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_dark_refs_widget.py +136 -0
- tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_delta_beta_selector.py +15 -0
- tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_i_norm.py +200 -0
- tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_nabu_helical_prepare_weights_double.py +20 -0
- tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_nabu_volume.py +74 -0
- tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_nabu_widget.py +107 -0
- tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_sa_delta_beta.py +194 -0
- tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_saaxis.py +194 -0
- tomwer/tests/orangecontrib/tomwer/widgets/stitching/tests/test_zstitching.py +313 -0
- tomwer/tests/orangecontrib/tomwer/widgets/tests/test_conditions.py +85 -0
- tomwer/tests/orangecontrib/tomwer/widgets/tests/test_darkref.py +225 -0
- tomwer/tests/orangecontrib/tomwer/widgets/tests/test_foldertransfert.py +105 -0
- tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_dataviewerow.py +57 -0
- tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_diffviewerow.py +39 -0
- tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_nxtomo_metadata_viewer.py +29 -0
- tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_radio_stackow.py +31 -0
- tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_sample_movedow.py +46 -0
- tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_sinogram_viewerow.py +31 -0
- tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_slice_stackow.py +31 -0
- tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_volume_viewerow.py +32 -0
- tomwer/tests/test_ewoks/test_conversion.py +104 -0
- tomwer/tests/test_ewoks/test_single_node_execution.py +87 -0
- tomwer/tests/test_ewoks/test_workflows.py +138 -0
- tomwer/utils.py +11 -39
- tomwer/version.py +2 -2
- {tomwer-1.3.26.dist-info → tomwer-1.4.0.dist-info}/LICENSE +3 -3
- tomwer-1.4.0.dist-info/METADATA +337 -0
- tomwer-1.4.0.dist-info/RECORD +912 -0
- {tomwer-1.3.26.dist-info → tomwer-1.4.0.dist-info}/WHEEL +1 -1
- {tomwer-1.3.26.dist-info → tomwer-1.4.0.dist-info}/entry_points.txt +1 -0
- orangecontrib/tomwer/widgets/control/DataListOW.py +0 -129
- orangecontrib/tomwer/widgets/control/TomoObjSerieOW.py +0 -86
- orangecontrib/tomwer/widgets/control/VolumeSymLinkOW.py +0 -182
- orangecontrib/tomwer/widgets/edit/test/test_nxtomo_editor.py +0 -141
- orangecontrib/tomwer/widgets/icat/PublishProcessedDataOW.py +0 -115
- orangecontrib/tomwer/widgets/icat/RawDataScreenshotCreatorOW.py +0 -98
- orangecontrib/tomwer/widgets/icat/SaveToGalleryAndPublishOW.py +0 -129
- orangecontrib/tomwer/widgets/icat/icons/add_gallery.png +0 -0
- orangecontrib/tomwer/widgets/icat/icons/add_gallery.svg +0 -82
- orangecontrib/tomwer/widgets/icat/icons/raw_screenshots.png +0 -0
- orangecontrib/tomwer/widgets/icat/icons/raw_screenshots.svg +0 -143
- orangecontrib/tomwer/widgets/visualization/LivesliceOW.py +0 -87
- orangecontrib/tomwer/widgets/visualization/icons/liveslice.png +0 -0
- orangecontrib/tomwer/widgets/visualization/icons/liveslice.svg +0 -110
- tomwer/core/log/logger.py +0 -130
- tomwer/core/process/control/test/test_volume_link.py +0 -74
- tomwer/core/process/control/tomoobjserie.py +0 -12
- tomwer/core/process/control/volumesymlink.py +0 -200
- tomwer/core/process/icat/createscreenshots.py +0 -100
- tomwer/core/process/icat/gallery.py +0 -377
- tomwer/core/process/icat/icatbase.py +0 -36
- tomwer/core/process/icat/publish.py +0 -228
- tomwer/core/process/icat/screenshots.py +0 -27
- tomwer/core/process/reconstruction/test/test_darkref.py +0 -60
- tomwer/core/process/reconstruction/test/test_sadeltabeta.py +0 -74
- tomwer/core/process/test/test_axis.py +0 -309
- tomwer/core/process/visualization/liveslice.py +0 -6
- tomwer/core/progress.py +0 -100
- tomwer/core/scan/test/test_edf.py +0 -53
- tomwer/core/scan/test/test_future_scan.py +0 -61
- tomwer/core/scan/test/test_h5.py +0 -96
- tomwer/core/scan/test/test_process_registration.py +0 -109
- tomwer/core/test/test_scanutils.py +0 -53
- tomwer/gui/control/emailnotifier.py +0 -174
- tomwer/gui/control/serie/seriewaiter.py +0 -28
- tomwer/gui/control/test/__init__.py +0 -28
- tomwer/gui/control/test/test_datalist.py +0 -96
- tomwer/gui/control/test/test_datavalidator.py +0 -54
- tomwer/gui/control/test/test_email.py +0 -35
- tomwer/gui/control/test/test_process_manager.py +0 -65
- tomwer/gui/control/test/test_scanselector.py +0 -67
- tomwer/gui/edit/test/__init__.py +0 -28
- tomwer/gui/icat/gallery.py +0 -214
- tomwer/gui/icat/publish.py +0 -187
- tomwer/gui/reconstruction/axis/axis.py +0 -733
- tomwer/gui/reconstruction/axis/radioaxis.py +0 -2467
- tomwer/gui/stitching/stitching.py +0 -1392
- tomwer/gui/test/__init__.py +0 -28
- tomwer/gui/test/test_axis_gui.py +0 -34
- tomwer/synctools/stacks/edit/darkflatpatch.py +0 -169
- tomwer/synctools/stacks/edit/imagekeyeditor.py +0 -135
- tomwer/third_part/WaitingOverlay.py +0 -110
- tomwer-1.3.26-py3.11-nspkg.pth +0 -1
- tomwer-1.3.26.dist-info/METADATA +0 -292
- tomwer-1.3.26.dist-info/RECORD +0 -785
- tomwer-1.3.26.dist-info/namespace_packages.txt +0 -1
- /orangecontrib/tomwer/{widgets/edit/test → tests}/__init__.py +0 -0
- {tomwer/core/process/control/test → orangecontrib/tomwer/tutorials/id16b}/__init__.py +0 -0
- {tomwer/core/process/icat → orangecontrib/tomwer/widgets/cluster/tests}/__init__.py +0 -0
- /orangecontrib/tomwer/widgets/control/icons/{tomoobjserie.png → tomoobjseries.png} +0 -0
- {tomwer/core/process/reconstruction/test → orangecontrib/tomwer/widgets/control/tests}/__init__.py +0 -0
- /orangecontrib/tomwer/widgets/{icat → dataportal}/icons/publish_processed_data.png +0 -0
- /orangecontrib/tomwer/widgets/{icat → dataportal}/icons/publish_processed_data.svg +0 -0
- {tomwer/core/process/test → orangecontrib/tomwer/widgets/debugtools/tests}/__init__.py +0 -0
- {tomwer/core/scan/test → orangecontrib/tomwer/widgets/edit/tests}/__init__.py +0 -0
- {tomwer/core/test → orangecontrib/tomwer/widgets/other/tests}/__init__.py +0 -0
- {tomwer/gui/cluster/test → orangecontrib/tomwer/widgets/reconstruction/tests}/__init__.py +0 -0
- {tomwer/gui/control/serie → orangecontrib/tomwer/widgets/stitching/tests}/__init__.py +0 -0
- {tomwer/gui/icat → orangecontrib/tomwer/widgets/tests}/__init__.py +0 -0
- {tomwer/gui/reconstruction/test → orangecontrib/tomwer/widgets/visualization/tests}/__init__.py +0 -0
- /tomwer/{synctools/stacks/edit → app/stitching}/__init__.py +0 -0
- /tomwer/{synctools/test → core/process/control/tests}/__init__.py +0 -0
- /tomwer/core/process/control/{test → tests}/test_email.py +0 -0
- /tomwer/core/process/control/{test → tests}/test_h52nx_process.py +0 -0
- /tomwer/{third_part → core/process/drac}/__init__.py +0 -0
- /tomwer/core/process/reconstruction/{test → tests}/test_axis_params.py +0 -0
- /tomwer/core/process/reconstruction/{test → tests}/test_darkref_copy.py +0 -0
- /tomwer/core/process/reconstruction/{test → tests}/test_paramsbase.py +0 -0
- /tomwer/core/scan/{test → tests}/test_scan.py +0 -0
- /tomwer/gui/control/{serie → series}/nxtomoconcatenate.py +0 -0
- /tomwer/gui/control/{test → tests}/test_datadiscovery.py +0 -0
- /tomwer/gui/control/{test → tests}/test_reducedarkflat_selector.py +0 -0
- /tomwer/gui/control/{test → tests}/test_single_tomo_obj.py +0 -0
- {orangecontrib/tomwer/widgets/edit/test → tomwer/tests/orangecontrib/tomwer/widgets/edit/tests}/test_image_key_upgrader.py +0 -0
- {tomwer-1.3.26.dist-info → tomwer-1.4.0.dist-info}/top_level.txt +0 -0
tomwer/gui/cluster/slurm.py
CHANGED
@@ -1,47 +1,22 @@
|
|
1
|
-
|
2
|
-
# /*##########################################################################
|
3
|
-
#
|
4
|
-
# Copyright (c) 2016-2017 European Synchrotron Radiation Facility
|
5
|
-
#
|
6
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
-
# of this software and associated documentation files (the "Software"), to deal
|
8
|
-
# in the Software without restriction, including without limitation the rights
|
9
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
-
# copies of the Software, and to permit persons to whom the Software is
|
11
|
-
# furnished to do so, subject to the following conditions:
|
12
|
-
#
|
13
|
-
# The above copyright notice and this permission notice shall be included in
|
14
|
-
# all copies or substantial portions of the Software.
|
15
|
-
#
|
16
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22
|
-
# THE SOFTWARE.
|
23
|
-
#
|
24
|
-
# ###########################################################################*/
|
25
|
-
|
26
|
-
__authors__ = ["H. Payno"]
|
27
|
-
__license__ = "MIT"
|
28
|
-
__date__ = "11/10/2021"
|
29
|
-
|
1
|
+
from __future__ import annotations
|
30
2
|
|
3
|
+
import os
|
4
|
+
import re
|
31
5
|
import logging
|
32
|
-
from typing import Optional
|
33
6
|
from functools import lru_cache as cache
|
34
7
|
|
35
8
|
from silx.gui import qt
|
36
|
-
from sluurp.utils import get_partitions, get_partition_gpus
|
9
|
+
from sluurp.utils import get_partitions, get_partition_gpus, get_partition_walltime
|
37
10
|
|
38
11
|
from tomwer.core.settings import SlurmSettings, SlurmSettingsMode
|
12
|
+
from tomwer.gui import icons
|
39
13
|
from tomwer.gui.utils.qt_utils import block_signals
|
40
14
|
from tomwer.gui.configuration.action import (
|
41
15
|
BasicConfigurationAction,
|
42
16
|
ExpertConfigurationAction,
|
43
17
|
)
|
44
18
|
from tomwer.gui.configuration.level import ConfigurationLevel
|
19
|
+
|
45
20
|
from nxtomomill.io.utils import convert_str_to_tuple
|
46
21
|
|
47
22
|
_logger = logging.getLogger(__name__)
|
@@ -89,7 +64,7 @@ class SlurmSettingsWindow(qt.QMainWindow):
|
|
89
64
|
sigConfigChanged = qt.Signal()
|
90
65
|
"""Signal emit when the SlurmSetting changed"""
|
91
66
|
|
92
|
-
def __init__(self, parent:
|
67
|
+
def __init__(self, parent: qt.QWidget | None = None) -> None:
|
93
68
|
super().__init__(parent)
|
94
69
|
|
95
70
|
# define toolbar
|
@@ -166,6 +141,7 @@ class SlurmSettingsWindow(qt.QMainWindow):
|
|
166
141
|
"partition": settingsClass.PARTITION,
|
167
142
|
"n_gpus": settingsClass.N_GPUS_PER_WORKER,
|
168
143
|
"job_name": settingsClass.PROJECT_NAME,
|
144
|
+
"walltime": settingsClass.DEFAULT_WALLTIME,
|
169
145
|
"python_venv": settingsClass.PYTHON_VENV,
|
170
146
|
"modules": settingsClass.MODULES_TO_LOAD,
|
171
147
|
}
|
@@ -204,122 +180,175 @@ class SlurmSettingsWidget(qt.QWidget):
|
|
204
180
|
sigConfigChanged = qt.Signal()
|
205
181
|
"""Signal emit when the SlurmSetting changed"""
|
206
182
|
|
183
|
+
WALL_TIME_INVALID_COLOR = qt.QColor("#FF0000")
|
184
|
+
|
207
185
|
def __init__(
|
208
186
|
self,
|
209
187
|
parent=None,
|
210
188
|
n_gpu=SlurmSettings.N_GPUS_PER_WORKER,
|
211
|
-
jobLimitation:
|
189
|
+
jobLimitation: int | None = 1,
|
212
190
|
) -> None:
|
213
191
|
"""
|
214
|
-
:param
|
192
|
+
:param n_gpu: if provided will set the value to the number of gpu requested
|
215
193
|
(default is one as most of the job are nabu reconstruction)
|
216
|
-
:param
|
194
|
+
:param jobLimitation: if set then will hide the option to define the number of job
|
217
195
|
"""
|
218
196
|
super().__init__(parent=parent)
|
219
|
-
self.setLayout(qt.
|
197
|
+
self.setLayout(qt.QGridLayout())
|
198
|
+
"""Action to display warning in case of possible 'wrong' setting"""
|
199
|
+
# define some optional warning
|
200
|
+
warning_icon = icons.getQIcon("warning")
|
201
|
+
self._warning_opd_p9 = qt.QLabel("")
|
202
|
+
self._warning_opd_p9.setPixmap(warning_icon.pixmap(20, state=qt.QIcon.On))
|
203
|
+
self._warning_opd_p9.setToolTip(
|
204
|
+
f"'{get_login()}' account cannot submit job on p9 architecture"
|
205
|
+
)
|
206
|
+
self._warning_opd_export_opts = qt.QLabel("")
|
207
|
+
self._warning_opd_export_opts.setPixmap(
|
208
|
+
warning_icon.pixmap(20, state=qt.QIcon.On)
|
209
|
+
)
|
210
|
+
self._warning_opd_export_opts.setToolTip(
|
211
|
+
f"'{get_login()}' account needs to export job with ALL option (advanced settings)"
|
212
|
+
)
|
220
213
|
|
221
214
|
# queues
|
222
|
-
self.
|
223
|
-
self.
|
215
|
+
self._queueLabel = qt.QLabel("queue / partition")
|
216
|
+
self.layout().addWidget(self._queueLabel, 0, 0, 1, 1)
|
217
|
+
self._queueCB = qt.QComboBox(self)
|
218
|
+
self._queueCB.setEditable(True)
|
224
219
|
for partition in get_partitions():
|
225
220
|
if partition in ("nice*",):
|
226
221
|
# filter some node that we cannot access in fact
|
227
222
|
continue
|
228
|
-
self.
|
229
|
-
self.layout().
|
223
|
+
self._queueCB.addItem(partition)
|
224
|
+
self.layout().addWidget(self._queueCB, 0, 1, 1, 1)
|
225
|
+
self.layout().addWidget(self._warning_opd_p9, 0, 2, 1, 1)
|
230
226
|
|
231
227
|
# n workers
|
232
|
-
self._nWorkers = qt.QSpinBox(self)
|
233
|
-
self._nWorkers.setRange(1, 100)
|
234
228
|
self._nWorkersLabel = qt.QLabel("number of task", self)
|
235
|
-
self.layout().
|
229
|
+
self.layout().addWidget(self._nWorkersLabel, 1, 0, 1, 1)
|
230
|
+
self._nWorkersSP = qt.QSpinBox(self)
|
231
|
+
self._nWorkersSP.setRange(1, 100)
|
232
|
+
self.layout().addWidget(self._nWorkersSP, 1, 1, 1, 1)
|
236
233
|
|
237
234
|
# ncores active
|
238
|
-
self.
|
239
|
-
self.
|
240
|
-
self.
|
235
|
+
self._nCoresLabel = qt.QLabel("number of cores per task")
|
236
|
+
self.layout().addWidget(self._nCoresLabel, 2, 0, 1, 1)
|
237
|
+
self._nCoresSB = qt.QSpinBox(self)
|
238
|
+
self._nCoresSB.setRange(1, 500)
|
239
|
+
self.layout().addWidget(self._nCoresSB, 2, 1, 1, 1)
|
241
240
|
|
242
241
|
# memory
|
243
|
-
self.
|
244
|
-
self.
|
245
|
-
self.
|
246
|
-
self.
|
242
|
+
self._memoryLabel = qt.QLabel("memory per task")
|
243
|
+
self.layout().addWidget(self._memoryLabel, 3, 0, 1, 1)
|
244
|
+
self._memorySB = qt.QSpinBox(self)
|
245
|
+
self._memorySB.setRange(1, 10000)
|
246
|
+
self._memorySB.setSuffix("GB")
|
247
|
+
self.layout().addWidget(self._memorySB, 3, 1, 1, 1)
|
247
248
|
|
248
249
|
# gpu
|
249
|
-
self.
|
250
|
-
self.
|
251
|
-
self.
|
250
|
+
self._nGpuLabel = qt.QLabel("number of GPUs per task")
|
251
|
+
self.layout().addWidget(self._nGpuLabel, 4, 0, 1, 1)
|
252
|
+
self._nGpuSB = qt.QSpinBox(self)
|
253
|
+
self._nGpuSB.setRange(0, 12)
|
254
|
+
self.layout().addWidget(self._nGpuSB, 4, 1, 1, 1)
|
252
255
|
|
253
256
|
# n jobs
|
257
|
+
self._nJobsLabel = qt.QLabel("number of job", self)
|
258
|
+
self.layout().addWidget(self._nJobsLabel, 5, 0, 1, 1)
|
259
|
+
|
254
260
|
self._nJobs = qt.QSpinBox(self)
|
255
261
|
self._nJobs.setRange(1, 100000)
|
256
262
|
self._nJobs.setValue(1)
|
257
|
-
self._nJobsLabel = qt.QLabel("number of job", self)
|
258
|
-
self.layout().addRow(self._nJobsLabel, self._nJobs)
|
259
263
|
self._nJobs.setToolTip("Define on how many part the job should be split in")
|
260
264
|
self._nJobsLabel.setVisible(jobLimitation is None)
|
261
265
|
self._nJobs.setVisible(jobLimitation is None)
|
266
|
+
self.layout().addWidget(self._nJobs, 5, 1, 1, 1)
|
267
|
+
|
268
|
+
# wall time
|
269
|
+
self._wallTimeLabel = qt.QLabel("wall time", self)
|
270
|
+
self.layout().addWidget(self._wallTimeLabel, 6, 0, 1, 1)
|
271
|
+
self._wallTimeQLE = qt.QLineEdit("", self)
|
272
|
+
self.__reWallTime = qt.QRegularExpression(
|
273
|
+
r"[0-9]?[0-9]:[0-9]?[0-9]:[0-9]?[0-9]"
|
274
|
+
)
|
275
|
+
self._wallTimeQLE.setPlaceholderText("HH:MM:SS")
|
276
|
+
self._wallTimeValidator = qt.QRegularExpressionValidator(
|
277
|
+
self.__reWallTime, self
|
278
|
+
)
|
279
|
+
self._wallTimeQLE.setValidator(self._wallTimeValidator)
|
280
|
+
self.layout().addWidget(self._wallTimeQLE, 6, 1, 1, 1)
|
281
|
+
self.__defaultWallTimeBackgroundColor = self.palette().color(
|
282
|
+
self._wallTimeQLE.backgroundRole()
|
283
|
+
)
|
284
|
+
self._warningWallTime = qt.QLabel("")
|
285
|
+
self._warningWallTime.setPixmap(warning_icon.pixmap(20, state=qt.QIcon.On))
|
286
|
+
self.layout().addWidget(self._warningWallTime, 6, 2, 1, 1)
|
262
287
|
|
263
288
|
# python exe / modules
|
264
289
|
self._preProcessingGroup = qt.QGroupBox("pre-processing", self)
|
265
290
|
self._preProcessingGroup.setLayout(qt.QFormLayout())
|
266
291
|
self._preProcessingButtonGroup = qt.QButtonGroup(self)
|
267
292
|
self._preProcessingButtonGroup.setExclusive(True)
|
268
|
-
self.layout().
|
293
|
+
self.layout().addWidget(self._preProcessingGroup, 10, 0, 1, 2)
|
269
294
|
|
270
295
|
# python venv
|
271
|
-
self._pythonVenv = qt.QLineEdit("/scisoft/tomotools/activate stable", self)
|
272
296
|
self._sourceScriptCB = qt.QRadioButton("source script (python venv)", self)
|
297
|
+
self._pythonVenv = qt.QLineEdit("/scisoft/tomotools/activate stable", self)
|
273
298
|
self._preProcessingButtonGroup.addButton(self._sourceScriptCB)
|
274
|
-
self._preProcessingGroup.layout().addRow(self._sourceScriptCB, self._pythonVenv)
|
275
299
|
self._pythonVenv.setToolTip(
|
276
300
|
"""
|
277
301
|
Optional path to a bash script to source before executing the script.
|
278
302
|
"""
|
279
303
|
)
|
280
|
-
|
304
|
+
self._preProcessingGroup.layout().addRow(self._sourceScriptCB, self._pythonVenv)
|
305
|
+
# module
|
281
306
|
self._modulesQLE = qt.QLineEdit(", ".join(SlurmSettings.MODULES_TO_LOAD), self)
|
282
307
|
self._modulesCB = qt.QRadioButton("module(s) to load", self)
|
283
308
|
self._preProcessingButtonGroup.addButton(self._modulesCB)
|
284
|
-
self._preProcessingGroup.layout().addRow(self._modulesCB, self._modulesQLE)
|
285
309
|
self._preProcessingGroup.setToolTip(
|
286
310
|
"""
|
287
311
|
Optional list of modules to load before executing the script. each module must be separated by a coma
|
288
312
|
"""
|
289
313
|
)
|
314
|
+
self._preProcessingGroup.layout().addRow(self._modulesCB, self._modulesQLE)
|
290
315
|
|
291
316
|
# job name
|
317
|
+
self._job_nameQLabel = qt.QLabel("job name", self)
|
318
|
+
self.layout().addWidget(self._job_nameQLabel, 13, 0, 1, 1)
|
319
|
+
|
292
320
|
self._jobName = qt.QLineEdit("", self)
|
293
321
|
self._jobName.setToolTip(
|
294
322
|
"""Job name. Can contains several keyword that will be formatted:
|
295
323
|
- scan: will be replaced by the scan name
|
296
324
|
- process: will be replaced by the process name (nabu slices, nabu volume...)
|
297
325
|
- info: some extra information that can be provided by the process to `specify` the processing
|
298
|
-
note: those key word have to be
|
326
|
+
note: those key word have to be surrounding by surrounded `{` and `}` in order to be formatted.
|
299
327
|
"""
|
300
328
|
)
|
301
|
-
self.
|
302
|
-
self.layout().addRow(self._job_nameQLabel, self._jobName)
|
329
|
+
self.layout().addWidget(self._jobName, 13, 1, 1, 1)
|
303
330
|
|
304
331
|
# port
|
305
332
|
# fixme: replace by a dedicated widget / validator for TCP adress
|
333
|
+
self._portLabel = qt.QLabel("port", self)
|
334
|
+
self.layout().addWidget(self._portLabel, 14, 0, 1, 1)
|
306
335
|
self._port = _PortRangeSelection(self)
|
307
336
|
self._port.setRange(0, 99999)
|
308
337
|
self._port.setToolTip("TCP Port for the dask-distributed scheduler")
|
309
|
-
self.
|
310
|
-
self.layout().addRow(self._portLabel, self._port)
|
338
|
+
self.layout().addWidget(self._port, 14, 1, 1, 1)
|
311
339
|
|
312
340
|
# dashboard port
|
313
341
|
self._dashboardPort = qt.QSpinBox(self)
|
342
|
+
self.layout().addWidget(self._dashboardPort, 15, 0, 1, 1)
|
314
343
|
self._dashboardPort.setRange(0, 99999)
|
315
344
|
self._dashboardPort.setToolTip("TCP Port for the dashboard")
|
316
345
|
self._dashboardPortLabel = qt.QLabel("dashboard port", self)
|
317
|
-
self.layout().
|
346
|
+
self.layout().addWidget(self._dashboardPort, 15, 1, 1, 1)
|
318
347
|
|
319
348
|
# sbatch advance parameters
|
320
349
|
self._sbatchAdvancedParameters = qt.QGroupBox("sbatch advanced settings", self)
|
321
350
|
self._sbatchAdvancedParameters.setLayout(qt.QFormLayout())
|
322
|
-
self.layout().
|
351
|
+
self.layout().addWidget(self._sbatchAdvancedParameters, 16, 0, 1, 2)
|
323
352
|
|
324
353
|
## export parameter
|
325
354
|
self._exportValueCM = qt.QComboBox(self)
|
@@ -338,6 +367,7 @@ class SlurmSettingsWidget(qt.QWidget):
|
|
338
367
|
)
|
339
368
|
self._exportValueCM.setCurrentText("NONE")
|
340
369
|
self._sbatchAdvancedParameters.layout().addRow("--export", self._exportValueCM)
|
370
|
+
self.layout().addWidget(self._warning_opd_export_opts, 16, 2, 1, 1)
|
341
371
|
|
342
372
|
## gpu card
|
343
373
|
self._gpuCardCB = qt.QComboBox(self)
|
@@ -357,29 +387,39 @@ class SlurmSettingsWidget(qt.QWidget):
|
|
357
387
|
self._portLabel.hide() # for now we don't use the port. This can be done automatically
|
358
388
|
self._port.hide() # for now we don't use the port. This can be done automatically
|
359
389
|
# for now nworker == ntask is not used
|
360
|
-
self.
|
390
|
+
self._nWorkersSP.setVisible(False)
|
361
391
|
self._nWorkersLabel.setVisible(False)
|
362
392
|
|
363
393
|
# set up the gui
|
364
|
-
self.
|
365
|
-
self.
|
366
|
-
self.
|
367
|
-
if self.
|
368
|
-
self.
|
369
|
-
self.
|
394
|
+
self._nCoresSB.setValue(SlurmSettings.N_CORES_PER_TASK)
|
395
|
+
self._nWorkersSP.setValue(SlurmSettings.N_TASKS)
|
396
|
+
self._memorySB.setValue(SlurmSettings.MEMORY_PER_WORKER)
|
397
|
+
if self._queueCB.findText(SlurmSettings.PARTITION) >= 0:
|
398
|
+
self._queueCB.setCurrentText(SlurmSettings.PARTITION)
|
399
|
+
self._nGpuSB.setValue(n_gpu)
|
370
400
|
self._jobName.setText(SlurmSettings.PROJECT_NAME)
|
401
|
+
self._wallTimeQLE.setText(SlurmSettings.DEFAULT_WALLTIME)
|
371
402
|
self._modulesCB.setChecked(True) # by default we go for modules
|
403
|
+
self._warning_opd_p9.setVisible(False)
|
404
|
+
self._warning_opd_export_opts.setVisible(False)
|
405
|
+
self._warningWallTime.setVisible(False)
|
372
406
|
self._preProcessingModeChanged()
|
373
407
|
self._partitionChanged()
|
408
|
+
self._sbatchAdvancedSettingsChanged()
|
374
409
|
self._nGpuChanged()
|
375
410
|
|
376
411
|
# connect signal / slot
|
377
|
-
self.
|
378
|
-
self.
|
379
|
-
self.
|
380
|
-
self.
|
381
|
-
self.
|
412
|
+
self._nCoresSB.valueChanged.connect(self._configurationChanged)
|
413
|
+
self._nWorkersSP.valueChanged.connect(self._configurationChanged)
|
414
|
+
self._memorySB.valueChanged.connect(self._configurationChanged)
|
415
|
+
self._queueCB.currentTextChanged.connect(self._configurationChanged)
|
416
|
+
self._queueCB.currentTextChanged.connect(self._updateWallTimeWarnings)
|
417
|
+
self._queueCB.currentTextChanged.connect(self._updateWallTimeTooltip)
|
418
|
+
self._nGpuSB.valueChanged.connect(self._configurationChanged)
|
382
419
|
self._jobName.editingFinished.connect(self._configurationChanged)
|
420
|
+
self._wallTimeQLE.editingFinished.connect(self._configurationChanged)
|
421
|
+
self._wallTimeQLE.editingFinished.connect(self._updateWallTimeWarnings)
|
422
|
+
self._wallTimeQLE.editingFinished.connect(self._updateWallTimeTooltip)
|
383
423
|
self._pythonVenv.editingFinished.connect(self._configurationChanged)
|
384
424
|
self._modulesQLE.editingFinished.connect(self._configurationChanged)
|
385
425
|
self._preProcessingButtonGroup.buttonClicked.connect(self._configurationChanged)
|
@@ -388,10 +428,44 @@ class SlurmSettingsWidget(qt.QWidget):
|
|
388
428
|
self._preProcessingButtonGroup.buttonClicked.connect(
|
389
429
|
self._preProcessingModeChanged
|
390
430
|
)
|
391
|
-
self.
|
392
|
-
self.
|
431
|
+
self._queueCB.currentTextChanged.connect(self._partitionChanged)
|
432
|
+
self._nGpuSB.valueChanged.connect(self._nGpuChanged)
|
393
433
|
self._gpuCardCB.currentTextChanged.connect(self._configurationChanged)
|
394
434
|
self._exportValueCM.currentIndexChanged.connect(self._configurationChanged)
|
435
|
+
self._exportValueCM.currentIndexChanged.connect(
|
436
|
+
self._sbatchAdvancedSettingsChanged
|
437
|
+
)
|
438
|
+
|
439
|
+
def _updateWallTimeWarnings(self):
|
440
|
+
time_limit, _ = self._getPartitionWallTime(partition=self.getQueue())
|
441
|
+
palette = self._wallTimeQLE.palette()
|
442
|
+
wall_time_limit_exceed = time_limit is not None and _WallTime(
|
443
|
+
self.getWallTime()
|
444
|
+
) > _WallTime(time_limit)
|
445
|
+
if wall_time_limit_exceed:
|
446
|
+
palette.setColor(self.backgroundRole(), self.WALL_TIME_INVALID_COLOR)
|
447
|
+
else:
|
448
|
+
palette.setColor(
|
449
|
+
self.backgroundRole(), self.__defaultWallTimeBackgroundColor
|
450
|
+
)
|
451
|
+
self._warningWallTime.setVisible(wall_time_limit_exceed)
|
452
|
+
self._wallTimeQLE.setPalette(palette)
|
453
|
+
|
454
|
+
def _updateWallTimeTooltip(self):
|
455
|
+
partition = self.getQueue()
|
456
|
+
time_limit, default_wall_time = self._getPartitionWallTime(partition=partition)
|
457
|
+
if time_limit is not None and default_wall_time is not None:
|
458
|
+
tooltip = "\n".join(
|
459
|
+
(
|
460
|
+
f"for partition {partition}:",
|
461
|
+
f"time limit: {time_limit}",
|
462
|
+
f"default limit: {default_wall_time}",
|
463
|
+
)
|
464
|
+
)
|
465
|
+
else:
|
466
|
+
tooltip = f"no wall time found for {partition}"
|
467
|
+
self._wallTimeQLE.setToolTip(tooltip)
|
468
|
+
self._warningWallTime.setToolTip(tooltip)
|
395
469
|
|
396
470
|
def _nGpuChanged(self, *args, **kwargs):
|
397
471
|
nGpu = self.getNGPU()
|
@@ -401,34 +475,34 @@ class SlurmSettingsWidget(qt.QWidget):
|
|
401
475
|
self.sigConfigChanged.emit()
|
402
476
|
|
403
477
|
def getNCores(self) -> int:
|
404
|
-
return self.
|
478
|
+
return self._nCoresSB.value()
|
405
479
|
|
406
480
|
def setNCores(self, n: int) -> None:
|
407
|
-
self.
|
481
|
+
self._nCoresSB.setValue(int(n))
|
408
482
|
|
409
483
|
def getNWorkers(self) -> int:
|
410
|
-
return self.
|
484
|
+
return self._nWorkersSP.value()
|
411
485
|
|
412
486
|
def setNWorkers(self, n) -> None:
|
413
|
-
self.
|
487
|
+
self._nWorkersSP.setValue(int(n))
|
414
488
|
|
415
489
|
def getMemory(self) -> int:
|
416
|
-
return self.
|
490
|
+
return self._memorySB.value()
|
417
491
|
|
418
492
|
def setMemory(self, memory: int) -> None:
|
419
|
-
self.
|
493
|
+
self._memorySB.setValue(int(memory))
|
420
494
|
|
421
495
|
def getQueue(self) -> str:
|
422
|
-
return self.
|
496
|
+
return self._queueCB.currentText()
|
423
497
|
|
424
498
|
def setQueue(self, text: str) -> None:
|
425
|
-
self.
|
499
|
+
self._queueCB.setCurrentText(text)
|
426
500
|
|
427
501
|
def getNGPU(self) -> int:
|
428
|
-
return self.
|
502
|
+
return self._nGpuSB.value()
|
429
503
|
|
430
504
|
def setNGPU(self, n: int) -> None:
|
431
|
-
self.
|
505
|
+
self._nGpuSB.setValue(int(n))
|
432
506
|
|
433
507
|
def getNJobs(self) -> int:
|
434
508
|
return self._nJobs.value()
|
@@ -442,6 +516,31 @@ class SlurmSettingsWidget(qt.QWidget):
|
|
442
516
|
def setProjectName(self, name):
|
443
517
|
self._jobName.setText(name)
|
444
518
|
|
519
|
+
def getWallTime(self):
|
520
|
+
parts = self._wallTimeQLE.text().split(":")
|
521
|
+
hours = parts[0]
|
522
|
+
if len(parts) > 1:
|
523
|
+
minutes = parts[1]
|
524
|
+
else:
|
525
|
+
minutes = ""
|
526
|
+
if len(parts) > 2:
|
527
|
+
seconds = parts[2]
|
528
|
+
else:
|
529
|
+
seconds = ""
|
530
|
+
|
531
|
+
return ":".join(
|
532
|
+
[
|
533
|
+
hours.zfill(2),
|
534
|
+
minutes.zfill(2),
|
535
|
+
seconds.zfill(2),
|
536
|
+
]
|
537
|
+
)
|
538
|
+
|
539
|
+
def setWallTime(self, walltime):
|
540
|
+
self._wallTimeQLE.setText(walltime)
|
541
|
+
self._updateWallTimeWarnings()
|
542
|
+
self._updateWallTimeTooltip()
|
543
|
+
|
445
544
|
def getPythonExe(self):
|
446
545
|
if self._sourceScriptCB.isChecked():
|
447
546
|
return self._pythonVenv.text()
|
@@ -468,9 +567,9 @@ class SlurmSettingsWidget(qt.QWidget):
|
|
468
567
|
if len(modules) > 0:
|
469
568
|
self._modulesCB.setChecked(True)
|
470
569
|
|
471
|
-
def getGpuCard(self) ->
|
570
|
+
def getGpuCard(self) -> str | None:
|
472
571
|
card = self._gpuCardCB.currentText()
|
473
|
-
if card == "any" or self.
|
572
|
+
if card == "any" or self._nGpuSB == 0:
|
474
573
|
return None
|
475
574
|
else:
|
476
575
|
return card
|
@@ -532,6 +631,10 @@ class SlurmSettingsWidget(qt.QWidget):
|
|
532
631
|
if project_name is not None:
|
533
632
|
self.setProjectName(project_name)
|
534
633
|
|
634
|
+
wall_time = config.get("walltime", None)
|
635
|
+
if wall_time is not None:
|
636
|
+
self.setWallTime(wall_time)
|
637
|
+
|
535
638
|
python_venv = config.get("python_venv", None)
|
536
639
|
if python_venv is not None:
|
537
640
|
python_venv = python_venv.rstrip("'").rstrip('"')
|
@@ -562,6 +665,7 @@ class SlurmSettingsWidget(qt.QWidget):
|
|
562
665
|
"partition": self.getQueue(),
|
563
666
|
"n_gpus": self.getNGPU(),
|
564
667
|
"job_name": self.getProjectName(),
|
668
|
+
"walltime": self.getWallTime(),
|
565
669
|
"sbatch_extra_params": self.getSBatchExtraParams(),
|
566
670
|
}
|
567
671
|
if self._modulesCB.isChecked():
|
@@ -569,7 +673,7 @@ class SlurmSettingsWidget(qt.QWidget):
|
|
569
673
|
elif self._sourceScriptCB.isChecked():
|
570
674
|
config["python_venv"] = self.getPythonExe()
|
571
675
|
else:
|
572
|
-
raise ValueError("'modules' or python
|
676
|
+
raise ValueError("'modules' or python environment should be enable")
|
573
677
|
return config
|
574
678
|
|
575
679
|
def getSlurmClusterConfiguration(self):
|
@@ -583,14 +687,29 @@ class SlurmSettingsWidget(qt.QWidget):
|
|
583
687
|
|
584
688
|
def setConfigurationLevel(self, level: ConfigurationLevel):
|
585
689
|
self._sbatchAdvancedParameters.setVisible(level >= ConfigurationLevel.ADVANCED)
|
690
|
+
self._wallTimeLabel.setVisible(level >= ConfigurationLevel.ADVANCED)
|
691
|
+
self._wallTimeQLE.setVisible(level >= ConfigurationLevel.ADVANCED)
|
586
692
|
|
587
693
|
def _partitionChanged(self, *args, **kwargs):
|
588
694
|
partition = self.getQueue()
|
695
|
+
# op(erator) accounts (from icc computers) cannot export to p9. they don't have home directories
|
696
|
+
self._warning_opd_p9.setVisible(
|
697
|
+
current_login_is_op_account() and partition.lower().startswith("p9")
|
698
|
+
)
|
589
699
|
gpus = self._getGpus(partition=partition)
|
590
700
|
self._gpuCardCB.clear()
|
591
701
|
self._gpuCardCB.addItems(gpus)
|
592
702
|
self._gpuCardCB.setCurrentText("any")
|
593
703
|
|
704
|
+
def _sbatchAdvancedSettingsChanged(self, *args, **kwargs):
|
705
|
+
# op(erator) accounts (from icc computers) must export ALL environment variable. Else job fails
|
706
|
+
# warning: we want to display the warning no matter if we are in 'advance options' or not.
|
707
|
+
# this way the user always see the warning when necessary
|
708
|
+
self._warning_opd_export_opts.setVisible(
|
709
|
+
current_login_is_op_account()
|
710
|
+
and self._exportValueCM.currentText() == "NONE"
|
711
|
+
)
|
712
|
+
|
594
713
|
@cache(maxsize=None)
|
595
714
|
def _getGpus(self, partition) -> tuple:
|
596
715
|
try:
|
@@ -604,6 +723,15 @@ class SlurmSettingsWidget(qt.QWidget):
|
|
604
723
|
]
|
605
724
|
return gpus
|
606
725
|
|
726
|
+
@cache(maxsize=None)
|
727
|
+
def _getPartitionWallTime(self, partition: str) -> tuple[str | None, str | None]:
|
728
|
+
try:
|
729
|
+
times = get_partition_walltime(partition=partition)
|
730
|
+
except Exception:
|
731
|
+
return None, None
|
732
|
+
else:
|
733
|
+
return times["time"], times["default_time"]
|
734
|
+
|
607
735
|
|
608
736
|
class _PortRangeSelection(qt.QWidget):
|
609
737
|
sigRangeChanged = qt.Signal()
|
@@ -647,8 +775,82 @@ class _PortRangeSelection(qt.QWidget):
|
|
647
775
|
self._stepQSpinBox.value(),
|
648
776
|
)
|
649
777
|
|
650
|
-
def setRange(self, min_: int, max_: int, step:
|
778
|
+
def setRange(self, min_: int, max_: int, step: int | None = None) -> None:
|
651
779
|
self._fromQSpinBox.setValue(min(min_, max_))
|
652
780
|
self._toQSpinBox.setValue(max(min_, max_))
|
653
781
|
if step is not None:
|
654
782
|
self._stepQSpinBox.setValue(step)
|
783
|
+
|
784
|
+
|
785
|
+
def get_login() -> str | None:
|
786
|
+
try:
|
787
|
+
return os.getlogin()
|
788
|
+
except OSError:
|
789
|
+
"""In CI computer this raises the following error
|
790
|
+
OSError: [Errno 6] No such device or address
|
791
|
+
"""
|
792
|
+
return None
|
793
|
+
|
794
|
+
|
795
|
+
def current_login_is_op_account() -> bool:
|
796
|
+
"""
|
797
|
+
return True if the current login is a op[i]dXX login.
|
798
|
+
"""
|
799
|
+
return is_op_account(get_login())
|
800
|
+
|
801
|
+
|
802
|
+
def is_op_account(user: str | None) -> bool:
|
803
|
+
"""
|
804
|
+
Determines if a given username follows the 'op' account format,
|
805
|
+
specifically 'opdXX' or 'opidXX', where 'XX' are numeric digits.
|
806
|
+
|
807
|
+
Args:
|
808
|
+
user (Optional[str]): The username to check.
|
809
|
+
|
810
|
+
Returns:
|
811
|
+
bool: True if the username matches the pattern, False otherwise.
|
812
|
+
"""
|
813
|
+
|
814
|
+
if user is None:
|
815
|
+
return False
|
816
|
+
|
817
|
+
op_account_pattern = r"^opi?d\d{2}$"
|
818
|
+
return bool(re.match(op_account_pattern, user))
|
819
|
+
|
820
|
+
|
821
|
+
class _WallTime:
|
822
|
+
"""Util class to compare two walltime provided as D-HH:MM:SS or as HH:MM:SS"""
|
823
|
+
|
824
|
+
def __init__(self, walltime: str):
|
825
|
+
parts = walltime.split("-")
|
826
|
+
if len(parts) > 1:
|
827
|
+
assert len(parts) == 2, f"unexpected walltime format ({walltime})"
|
828
|
+
days = int(parts[0])
|
829
|
+
else:
|
830
|
+
days = 0
|
831
|
+
|
832
|
+
def minutes_to_seconds(value):
|
833
|
+
return value * 60
|
834
|
+
|
835
|
+
def hours_to_seconds(value):
|
836
|
+
return minutes_to_seconds(value * 60)
|
837
|
+
|
838
|
+
def days_to_seconds(value):
|
839
|
+
return hours_to_seconds(value * 24)
|
840
|
+
|
841
|
+
hours, minutes, seconds = map(int, parts[-1].split(":"))
|
842
|
+
self.value = (
|
843
|
+
seconds
|
844
|
+
+ minutes_to_seconds(minutes)
|
845
|
+
+ hours_to_seconds(hours)
|
846
|
+
+ days_to_seconds(days)
|
847
|
+
)
|
848
|
+
|
849
|
+
def __lt__(self, other):
|
850
|
+
return self.value < other.value
|
851
|
+
|
852
|
+
def __gt__(self, other):
|
853
|
+
return self.value > other.value
|
854
|
+
|
855
|
+
def __eq__(self, other):
|
856
|
+
return self.value == other.value
|
tomwer/gui/cluster/supervisor.py
CHANGED
@@ -1,31 +1,5 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
|
3
|
-
#
|
4
|
-
# Copyright (c) 2016-2017 European Synchrotron Radiation Facility
|
5
|
-
#
|
6
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
-
# of this software and associated documentation files (the "Software"), to deal
|
8
|
-
# in the Software without restriction, including without limitation the rights
|
9
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
-
# copies of the Software, and to permit persons to whom the Software is
|
11
|
-
# furnished to do so, subject to the following conditions:
|
12
|
-
#
|
13
|
-
# The above copyright notice and this permission notice shall be included in
|
14
|
-
# all copies or substantial portions of the Software.
|
15
|
-
#
|
16
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22
|
-
# THE SOFTWARE.
|
23
|
-
#
|
24
|
-
# ###########################################################################*/
|
25
|
-
|
26
|
-
__authors__ = ["H. Payno"]
|
27
|
-
__license__ = "MIT"
|
28
|
-
__date__ = "14/10/2021"
|
2
|
+
from __future__ import annotations
|
29
3
|
|
30
4
|
|
31
5
|
import functools
|
File without changes
|