tomwer 1.3.27__py3-none-any.whl → 1.4.0rc0__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 +48 -49
- 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 +40 -85
- 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 -7
- 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 +7 -4
- 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 +63 -111
- tomwer/core/process/reconstruction/axis/mode.py +5 -3
- tomwer/core/process/reconstruction/axis/params.py +5 -146
- tomwer/core/process/reconstruction/axis/projectiontype.py +0 -28
- 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 +47 -48
- tomwer/core/process/reconstruction/nabu/nabuslices.py +59 -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 +18 -47
- tomwer/core/process/reconstruction/sadeltabeta/params.py +2 -31
- tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py +16 -44
- 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/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_axis.py +1 -79
- 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 +4 -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 +46 -54
- tomwer/core/scan/scanbase.py +104 -200
- 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/{test → tests}/test_process_registration.py +1 -28
- 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/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 +264 -0
- tomwer/gui/reconstruction/axis/AxisOptionsWidget.py +153 -0
- tomwer/gui/reconstruction/axis/AxisSettingsWidget.py +776 -0
- tomwer/gui/reconstruction/axis/AxisWidget.py +526 -0
- tomwer/gui/reconstruction/axis/CalculationWidget.py +374 -0
- tomwer/gui/reconstruction/axis/CompareImages.py +11 -44
- tomwer/gui/reconstruction/axis/ControlWidget.py +277 -0
- tomwer/gui/reconstruction/axis/InputWidget.py +491 -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 +16 -49
- 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 +19 -48
- 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 +8 -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 +23 -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 +4 -32
- 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 +27 -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 +2 -31
- tomwer/synctools/stacks/reconstruction/castvolume.py +12 -43
- tomwer/synctools/stacks/reconstruction/dkrefcopy.py +3 -26
- tomwer/synctools/stacks/reconstruction/nabu.py +1 -26
- tomwer/synctools/stacks/reconstruction/normalization.py +1 -26
- tomwer/synctools/stacks/reconstruction/saaxis.py +1 -26
- tomwer/synctools/stacks/reconstruction/sadeltabeta.py +1 -26
- 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 +215 -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 +3 -3
- {tomwer-1.3.27.dist-info → tomwer-1.4.0rc0.dist-info}/LICENSE +3 -3
- tomwer-1.4.0rc0.dist-info/METADATA +337 -0
- tomwer-1.4.0rc0.dist-info/RECORD +909 -0
- {tomwer-1.3.27.dist-info → tomwer-1.4.0rc0.dist-info}/WHEEL +1 -1
- {tomwer-1.3.27.dist-info → tomwer-1.4.0rc0.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/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/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 -1388
- 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.27-py3.11-nspkg.pth +0 -1
- tomwer-1.3.27.dist-info/METADATA +0 -292
- tomwer-1.3.27.dist-info/RECORD +0 -785
- tomwer-1.3.27.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/process/reconstruction/{test → tests}/test_utils.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.27.dist-info → tomwer-1.4.0rc0.dist-info}/top_level.txt +0 -0
tomwer/gui/stackplot.py
CHANGED
@@ -1,324 +1,50 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
#
|
4
|
-
# This file is part of the PyMca X-ray Fluorescence Toolkit developed at
|
5
|
-
# the ESRF by the Software group.
|
6
|
-
#
|
7
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
-
# of this software and associated documentation files (the "Software"), to deal
|
9
|
-
# in the Software without restriction, including without limitation the rights
|
10
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
-
# copies of the Software, and to permit persons to whom the Software is
|
12
|
-
# furnished to do so, subject to the following conditions:
|
13
|
-
#
|
14
|
-
# The above copyright notice and this permission notice shall be included in
|
15
|
-
# all copies or substantial portions of the Software.
|
16
|
-
#
|
17
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23
|
-
# THE SOFTWARE.
|
24
|
-
#
|
25
|
-
#############################################################################*/
|
1
|
+
"""Contains the QImageFileStackPlot. Widget to display a set of files with metadata (either scan or volume metadata)
|
2
|
+
"""
|
26
3
|
|
27
|
-
|
28
|
-
__license__ = "MIT"
|
29
|
-
__date__ = "24/05/2016"
|
4
|
+
from __future__ import annotations
|
30
5
|
|
31
|
-
import functools
|
32
6
|
import logging
|
33
7
|
import os
|
34
8
|
import time
|
35
|
-
from collections import OrderedDict, namedtuple
|
36
|
-
from typing import Iterable, Optional
|
37
9
|
|
38
|
-
import numpy
|
39
10
|
from silx.gui import qt
|
40
|
-
from
|
41
|
-
from silx.gui.plot.actions import PlotAction
|
42
|
-
from silx.gui.plot.actions.control import YAxisInvertedAction
|
43
|
-
from silx.io.url import DataUrl
|
11
|
+
from tomwer.gui.visualization.imagestack import ImageStack
|
44
12
|
|
45
|
-
import tomwer.resources
|
46
|
-
from tomwer.gui import icons, settings
|
47
13
|
|
48
14
|
from . import utils
|
49
|
-
from .imagefromfile import FileWithImage, ImageFromFile, _Image
|
50
15
|
|
51
16
|
logger = logging.getLogger(__name__)
|
52
17
|
|
53
18
|
|
54
|
-
class
|
19
|
+
class QImageFileStackPlot(ImageStack):
|
55
20
|
"""
|
56
|
-
Widget to display
|
57
|
-
|
58
|
-
:param parent: the Qt parent widget
|
21
|
+
Widget based on ImageStack and adding some widget to display metadata associated with urls.
|
22
|
+
Like Paganin delta / beta values...
|
59
23
|
"""
|
60
24
|
|
61
|
-
|
62
|
-
|
63
|
-
IMG_LOADING = numpy.load(
|
64
|
-
tomwer.resources._resource_filename(
|
65
|
-
"%s.%s" % ("hourglass", "npy"),
|
66
|
-
default_directory=os.path.join("gui", "icons"),
|
67
|
-
)
|
68
|
-
)
|
69
|
-
|
70
|
-
def __init__(self, parent, sliderVertical=False, backend=None):
|
71
|
-
qt.QWidget.__init__(self, parent)
|
72
|
-
self._transpose = False
|
73
|
-
"""If we want to transpose the image like imagj by default"""
|
74
|
-
|
75
|
-
self.images = self.createStackImageInstance()
|
76
|
-
layout = qt.QVBoxLayout()
|
77
|
-
layout.setContentsMargins(0, 0, 0, 0)
|
78
|
-
|
79
|
-
mainwidget = qt.QWidget(self)
|
80
|
-
mainLayout = qt.QHBoxLayout() if sliderVertical else qt.QVBoxLayout()
|
81
|
-
mainLayout.setContentsMargins(0, 0, 0, 0)
|
82
|
-
mainwidget.setLayout(mainLayout)
|
83
|
-
layout.addWidget(mainwidget)
|
84
|
-
|
85
|
-
self._plot = Plot2D(self, backend=backend)
|
86
|
-
|
87
|
-
def find_y_inverted(actions):
|
88
|
-
for act in actions:
|
89
|
-
if isinstance(act, YAxisInvertedAction):
|
90
|
-
return act
|
91
|
-
return None
|
92
|
-
|
93
|
-
y_inverted = find_y_inverted(self._plot.toolBar().actions())
|
94
|
-
if y_inverted is None:
|
95
|
-
# temporary, XAxisInverted should be embed into silx.
|
96
|
-
pos = min(8, len(self._plot.toolBar().actions()))
|
97
|
-
y_inverted = self._plot.toolBar().actions()[-pos]
|
98
|
-
self.axis_invert = XAxisInvertedAction(plot=self._plot)
|
99
|
-
self._plot.toolBar().insertAction(y_inverted, self.axis_invert)
|
100
|
-
|
101
|
-
self._plot.setYAxisInverted(settings.Y_AXIS_DOWNWARD)
|
102
|
-
if hasattr(self._plot, "setAxesDisplayed"):
|
103
|
-
# by default we want to have a full screen display
|
104
|
-
self._plot.setAxesDisplayed(False)
|
105
|
-
|
106
|
-
colormap = self._plot.getDefaultColormap()
|
107
|
-
if type(colormap) is dict:
|
108
|
-
colormap["autoscale"] = True
|
109
|
-
else:
|
110
|
-
assert hasattr(colormap, "setVRange")
|
111
|
-
colormap.setVRange(None, None)
|
112
|
-
self._plot.setDefaultColormap(colormap)
|
113
|
-
self._plot.setKeepDataAspectRatio(True)
|
114
|
-
|
115
|
-
# removing some plot action to clear toolbar
|
116
|
-
self._plot.getMaskAction().setVisible(False)
|
117
|
-
self._plot.getCopyAction().setVisible(False)
|
118
|
-
# if has the option medianFilter, active it
|
119
|
-
if hasattr(self._plot, "getMedianFilter2DAction"):
|
120
|
-
self._plot.getMedianFilter2DAction().setVisible(True)
|
121
|
-
|
122
|
-
mainLayout.addWidget(self._plot)
|
123
|
-
|
124
|
-
if sliderVertical is True:
|
125
|
-
lLayout = qt.QVBoxLayout()
|
126
|
-
else:
|
127
|
-
lLayout = qt.QHBoxLayout()
|
128
|
-
|
129
|
-
self._controlWidget = qt.QWidget(self)
|
130
|
-
self._controlWidget.setLayout(lLayout)
|
131
|
-
lLayout.setContentsMargins(0, 0, 0, 0)
|
132
|
-
mainLayout.addWidget(self._controlWidget)
|
133
|
-
|
134
|
-
self._qspinbox = qt.QSpinBox(parent=self._controlWidget)
|
135
|
-
self._qslider = qt.QSlider(
|
136
|
-
qt.Qt.Vertical if sliderVertical is True else qt.Qt.Horizontal,
|
137
|
-
parent=self._controlWidget,
|
138
|
-
)
|
139
|
-
self.setRange(0, 0)
|
140
|
-
self._qslider.setTickPosition(qt.QSlider.TickPosition(0))
|
141
|
-
if sliderVertical:
|
142
|
-
lLayout.addWidget(self._qspinbox)
|
143
|
-
lLayout.addWidget(self._qslider)
|
144
|
-
else:
|
145
|
-
lLayout.addWidget(self._qslider)
|
146
|
-
lLayout.addWidget(self._qspinbox)
|
147
|
-
self._connectControls()
|
148
|
-
self.setLayout(layout)
|
149
|
-
|
150
|
-
self.setImages(None)
|
151
|
-
self.getActiveImage = self._plot.getActiveImage
|
152
|
-
|
153
|
-
def _disconnectControls(self):
|
154
|
-
self._qspinbox.valueChanged.disconnect(self.showImage)
|
155
|
-
self._qslider.valueChanged.disconnect(self.showImage)
|
156
|
-
|
157
|
-
def setTranspose(self, value):
|
158
|
-
if self._transpose != value:
|
159
|
-
self._transpose = value
|
160
|
-
img = self._plot.getActiveImage()
|
161
|
-
if img is not None:
|
162
|
-
data = numpy.transpose(img.getData())
|
163
|
-
img.setData(data)
|
164
|
-
|
165
|
-
def _connectControls(self):
|
166
|
-
self._qspinbox.valueChanged.connect(self.showImage)
|
167
|
-
self._qslider.valueChanged.connect(self.showImage)
|
168
|
-
|
169
|
-
def sizeHint(self):
|
170
|
-
"""Return a reasonable default size for usage in :class:`PlotWindow`"""
|
171
|
-
return self._sizeHint
|
172
|
-
|
173
|
-
def setImages(self, images):
|
174
|
-
"""
|
175
|
-
Set the images to display
|
176
|
-
"""
|
177
|
-
self._qslider.blockSignals(True)
|
178
|
-
self._qspinbox.blockSignals(True)
|
179
|
-
|
180
|
-
self.images.clear()
|
181
|
-
if images is None:
|
182
|
-
self._plot.clear()
|
183
|
-
if self._qslider:
|
184
|
-
self._qslider.setRange(0, 0)
|
185
|
-
self._qspinbox.setRange(0, 0)
|
186
|
-
return
|
187
|
-
else:
|
188
|
-
if isinstance(images, (list, tuple)):
|
189
|
-
self.images.setImages(images)
|
190
|
-
else:
|
191
|
-
assert isinstance(images, (dict, OrderedDict))
|
192
|
-
_images = OrderedDict(sorted(images.items(), key=lambda t: t[0]))
|
193
|
-
self.images.setImages(_images.values())
|
194
|
-
if self.images.size() > 0:
|
195
|
-
self.showImage(0)
|
196
|
-
|
197
|
-
if self._qslider:
|
198
|
-
if self.images.size() > 0:
|
199
|
-
self.setRange(0, self.images.size())
|
200
|
-
else:
|
201
|
-
self.setRange(0, 0)
|
202
|
-
if self.images.size() > 0:
|
203
|
-
self.showImage(self._qspinbox.value())
|
204
|
-
|
205
|
-
self._qslider.blockSignals(False)
|
206
|
-
self._qspinbox.blockSignals(False)
|
207
|
-
|
208
|
-
def createStackImageInstance(self):
|
209
|
-
return _StackImage(images=None)
|
210
|
-
|
211
|
-
def showImage(self, index):
|
212
|
-
"""
|
213
|
-
Show the image of index 'index' as the current image displayed
|
214
|
-
|
215
|
-
:param int index: the index of the image to display.
|
216
|
-
"""
|
217
|
-
self._qspinbox.blockSignals(True)
|
218
|
-
self._qslider.blockSignals(True)
|
219
|
-
# update gui
|
220
|
-
self._qspinbox.setValue(index)
|
221
|
-
self._qslider.setValue(index)
|
222
|
-
image = self.images.getImage(index)
|
223
|
-
if image is not None:
|
224
|
-
if image.data is not None:
|
225
|
-
data = image.data
|
226
|
-
if self._transpose is True:
|
227
|
-
data = numpy.transpose(data)
|
228
|
-
if self.axis_invert.isInverted() is True:
|
229
|
-
data = numpy.fliplr(data)
|
230
|
-
self._plot.addImage(data=data, legend=str(index), replace=True)
|
231
|
-
self._updateImageInfo()
|
232
|
-
else:
|
233
|
-
image.load()
|
234
|
-
self._qspinbox.blockSignals(False)
|
235
|
-
self._qslider.blockSignals(False)
|
236
|
-
|
237
|
-
def clear(self):
|
238
|
-
self.setImages(None)
|
239
|
-
|
240
|
-
def setRange(self, _min, _max):
|
241
|
-
"""Set the range of the spin box
|
242
|
-
|
243
|
-
:param _min: the minimal value of the slice. If equal None, not set
|
244
|
-
:param _max: the maximal value of the slice. If equal None, not set
|
245
|
-
"""
|
246
|
-
self._qslider.setRange(_min, _max)
|
247
|
-
self._qspinbox.setRange(_min, _max)
|
248
|
-
|
249
|
-
def getControlWidget(self):
|
250
|
-
return self._controlWidget
|
251
|
-
|
252
|
-
def _updateImageInfo(self):
|
253
|
-
pass
|
254
|
-
|
255
|
-
|
256
|
-
class _QImageFileStackPlot(_QImageStackPlot):
|
257
|
-
"""
|
258
|
-
Widget based on QImageStackPlot but managing images from a stack of path to
|
259
|
-
file
|
260
|
-
"""
|
261
|
-
|
262
|
-
def __init__(self, parent, backend=None):
|
25
|
+
def __init__(self, parent, show_overview=True, backend=None):
|
263
26
|
"""
|
264
27
|
Constructor
|
265
28
|
|
266
29
|
:param parent: the Qt parent widget
|
267
30
|
"""
|
268
|
-
|
269
|
-
self._imagejThreads = []
|
270
|
-
# threads used to open frames with image j
|
271
|
-
|
272
|
-
self._loadingMode = _LoadingModeToolButton(parent=self)
|
273
|
-
self.getControlWidget().layout().addWidget(self._loadingMode)
|
274
|
-
self.addFolderName(False)
|
275
|
-
self.clear()
|
276
|
-
|
277
|
-
# connect the qslider with the GUI
|
278
|
-
self._sliderConnected = False
|
279
|
-
|
280
|
-
style = qt.QApplication.style()
|
281
|
-
self.waitingIcon = style.standardIcon(qt.QStyle.SP_BrowserReload)
|
282
|
-
|
283
|
-
# add some toolbar information
|
284
|
-
self._qslider.setToolTip(
|
285
|
-
"The loading of the image will start when the \
|
286
|
-
slider will be released"
|
287
|
-
)
|
288
|
-
self._qspinbox.setToolTip(
|
289
|
-
"To start the loading press enter on the spin\
|
290
|
-
box or release the slider"
|
291
|
-
)
|
31
|
+
super().__init__(parent, show_overview=show_overview)
|
292
32
|
|
293
|
-
self.
|
33
|
+
self._plot.setBackend(backend=backend)
|
294
34
|
|
295
|
-
self.
|
296
|
-
self.setImages(None)
|
35
|
+
self._imagejThreads = []
|
297
36
|
|
298
|
-
#
|
299
|
-
self.
|
37
|
+
# dock widget: qslider
|
38
|
+
self._plot.layout()
|
39
|
+
self._fileInfoDockWidget = qt.QDockWidget(parent=self)
|
40
|
+
self._fileInfoWidget = self.__buildFileInfo()
|
41
|
+
self._fileInfoDockWidget.setWidget(self._fileInfoWidget)
|
42
|
+
self.addDockWidget(qt.Qt.BottomDockWidgetArea, self._fileInfoDockWidget)
|
43
|
+
self._fileInfoDockWidget.setFeatures(qt.QDockWidget.DockWidgetMovable)
|
300
44
|
|
301
45
|
# connect signal / slot
|
302
|
-
self.images.sigImageLoaded.connect(self._updateIfCurrent)
|
303
|
-
self.images.sigLoadingModeChanged.connect(self._loadingModeChanged)
|
304
46
|
self._openWithImjButton.released.connect(self._openCurrentInImagej)
|
305
|
-
|
306
|
-
def getLoadingMode(self):
|
307
|
-
return self.images.getLoadingMode()
|
308
|
-
|
309
|
-
def setLoadingMode(self, mode):
|
310
|
-
self._loadingMode.blockSignals(True)
|
311
|
-
self._loadingMode.setLoadingMode(mode)
|
312
|
-
self.images.setLoadingMode(mode)
|
313
|
-
self.showImage(self._qslider.value())
|
314
|
-
self._loadingMode.blockSignals(False)
|
315
|
-
|
316
|
-
def _loadingModeChanged(self, mode, old_mode):
|
317
|
-
self._loadingMode.blockSignals(True)
|
318
|
-
self._disconnectModeControl(old_mode)
|
319
|
-
self._loadingMode.setLoadingMode(mode)
|
320
|
-
self._connectModeControl(mode)
|
321
|
-
self._loadingMode.blockSignals(False)
|
47
|
+
self.sigCurrentUrlChanged.connect(self._updateUrlInfos)
|
322
48
|
|
323
49
|
def __buildFileInfo(self):
|
324
50
|
self._fileInfoWidget = qt.QWidget(parent=self)
|
@@ -351,53 +77,13 @@ class _QImageFileStackPlot(_QImageStackPlot):
|
|
351
77
|
|
352
78
|
return self._fileInfoWidget
|
353
79
|
|
354
|
-
def _disconnectControls(self):
|
355
|
-
self._disconnectModeControl(self.getLoadingMode())
|
356
|
-
|
357
|
-
def _connectControls(self):
|
358
|
-
self._connectModeControl(self.getLoadingMode())
|
359
|
-
|
360
|
-
def _disconnectModeControl(self, mode):
|
361
|
-
if mode == LAZY_LOADING:
|
362
|
-
self._qslider.sliderReleased.disconnect(self.changeActiveImageFrmQSlider)
|
363
|
-
self._qspinbox.editingFinished.disconnect(self.changeActiveImageFrmQSpinBox)
|
364
|
-
else:
|
365
|
-
self._qslider.valueChanged.disconnect(self.changeActiveImageFrmQSlider)
|
366
|
-
self._qspinbox.valueChanged.disconnect(self.changeActiveImageFrmQSpinBox)
|
367
|
-
|
368
|
-
def _connectModeControl(self, mode):
|
369
|
-
if mode == LAZY_LOADING:
|
370
|
-
self._qslider.sliderReleased.connect(self.changeActiveImageFrmQSlider)
|
371
|
-
self._qspinbox.editingFinished.connect(self.changeActiveImageFrmQSpinBox)
|
372
|
-
elif mode in (ON_SHOW_LOADING, ASAP_LOADING):
|
373
|
-
self._qslider.valueChanged.connect(self.changeActiveImageFrmQSlider)
|
374
|
-
self._qspinbox.valueChanged.connect(self.changeActiveImageFrmQSpinBox)
|
375
|
-
|
376
|
-
def setImages(self, imagesFiles):
|
377
|
-
"""
|
378
|
-
Set the stack of images files
|
379
|
-
|
380
|
-
:param _imagesFiles: the list of images path to be displayed
|
381
|
-
"""
|
382
|
-
self._qslider.blockSignals(True)
|
383
|
-
self._qspinbox.blockSignals(True)
|
384
|
-
_QImageStackPlot.setImages(self, imagesFiles)
|
385
|
-
|
386
|
-
self._qslider.setRange(0, self.images.size() - 1)
|
387
|
-
self._qspinbox.setMaximum(self.images.size() - 1)
|
388
|
-
|
389
|
-
self._qslider.blockSignals(False)
|
390
|
-
self._qspinbox.blockSignals(False)
|
391
|
-
|
392
80
|
def _openCurrentInImagej(self):
|
393
|
-
|
394
|
-
if
|
81
|
+
current_url = self.getCurrentUrl()
|
82
|
+
if current_url is None:
|
395
83
|
logger.warning("No active image defined")
|
396
84
|
else:
|
397
85
|
try:
|
398
|
-
self._imagejThreads.append(
|
399
|
-
utils.open_url_with_image_j(active_image.url)
|
400
|
-
)
|
86
|
+
self._imagejThreads.append(utils.open_url_with_image_j(current_url))
|
401
87
|
except OSError as e:
|
402
88
|
msg = qt.QMessageBox(self)
|
403
89
|
msg.setIcon(qt.QMessageBox.Warning)
|
@@ -405,328 +91,14 @@ class _QImageFileStackPlot(_QImageStackPlot):
|
|
405
91
|
msg.setText(str(e))
|
406
92
|
msg.exec_()
|
407
93
|
|
408
|
-
def
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
return str(data_slice)
|
420
|
-
else:
|
421
|
-
raise TypeError("Unexpected slicing type. Found %s" % type(data_slice))
|
422
|
-
|
423
|
-
image = self._getActiveImageInfo()
|
424
|
-
if image is not None:
|
425
|
-
imageName = image.url.file_path()
|
426
|
-
if self._joinFolderName is True:
|
427
|
-
firstFolder = os.path.split(os.path.dirname(imageName))[-1]
|
428
|
-
imageName = os.path.join(firstFolder, os.path.basename(imageName))
|
429
|
-
else:
|
430
|
-
imageName = os.path.basename(imageName)
|
431
|
-
if image.url.data_path() is not None:
|
432
|
-
imageName = imageName + "&path=" + image.url.data_path()
|
433
|
-
if image.url.data_slice() is not None:
|
434
|
-
if isinstance(image.url.data_slice(), Iterable):
|
435
|
-
data_slice = [slice_to_string(s) for s in image.url.data_slice()]
|
436
|
-
else:
|
437
|
-
data_slice = slice_to_string(image.url.data_slice())
|
438
|
-
imageName = imageName + "&slice=" + ",".join(data_slice)
|
439
|
-
|
440
|
-
self._qlFileName.setText(imageName)
|
441
|
-
self._qlFileName.setToolTip(image.url.path())
|
442
|
-
try:
|
443
|
-
last_mod = time.ctime(os.path.getmtime(image.url.file_path()))
|
444
|
-
except Exception:
|
445
|
-
last_mod = ""
|
446
|
-
self._qlLastModifications.setText(last_mod)
|
447
|
-
|
448
|
-
def addFolderName(self, b):
|
449
|
-
"""
|
450
|
-
|
451
|
-
:param bool val: If true then will join the folder name of the file in
|
452
|
-
addition of the file name.
|
453
|
-
"""
|
454
|
-
self._joinFolderName = b
|
455
|
-
|
456
|
-
def _updateIfCurrent(self, url):
|
457
|
-
indexFile = self._qslider.value()
|
458
|
-
index = self.images.getUrlIndex(url)
|
459
|
-
if index == indexFile:
|
460
|
-
self.changeActiveImageFrmQSlider()
|
461
|
-
|
462
|
-
def changeActiveImageFrmQSlider(self):
|
463
|
-
indexFile = self._qslider.value()
|
464
|
-
self.showImage(indexFile)
|
465
|
-
|
466
|
-
def changeActiveImageFrmQSpinBox(self):
|
467
|
-
indexFile = self._qspinbox.value()
|
468
|
-
self.showImage(indexFile)
|
469
|
-
|
470
|
-
def getImage(self, index):
|
471
|
-
return self._imagesFiles[index]
|
472
|
-
|
473
|
-
def createStackImageInstance(self):
|
474
|
-
return _StackImageToLoad()
|
475
|
-
|
476
|
-
def clear(self):
|
477
|
-
if hasattr(self, "_qlFileName"):
|
478
|
-
self._qlFileName.setText("")
|
479
|
-
super(_QImageFileStackPlot, self).clear()
|
480
|
-
|
481
|
-
def close(self):
|
482
|
-
[thread.quit() for thread in self._imagejThreads]
|
483
|
-
super.close()
|
484
|
-
|
485
|
-
|
486
|
-
class _StackImage(object):
|
487
|
-
def __init__(self, images: Optional[Iterable]):
|
488
|
-
_images = images
|
489
|
-
if _images is None:
|
490
|
-
_images = {}
|
491
|
-
self._images = OrderedDict(_images)
|
492
|
-
"""Key: unique index or label or path, Value: _Image"""
|
493
|
-
self.nextIndex = 0
|
494
|
-
|
495
|
-
def addImage(self, image):
|
496
|
-
assert isinstance(image, _Image)
|
497
|
-
self._images[self.nextIndex] = image
|
498
|
-
self.nextIndex = self.nextIndex + 1
|
499
|
-
|
500
|
-
def getImage(self, index):
|
501
|
-
if index not in self._images:
|
502
|
-
return None
|
503
|
-
else:
|
504
|
-
return self._images[index]
|
505
|
-
|
506
|
-
def setImages(self, images: Iterable):
|
507
|
-
self.clear()
|
508
|
-
for image in images:
|
509
|
-
self.addImage(image)
|
510
|
-
|
511
|
-
def size(self):
|
512
|
-
return len(self._images)
|
513
|
-
|
514
|
-
def clear(self):
|
515
|
-
self._images.clear()
|
516
|
-
self.nextIndex = 0
|
517
|
-
|
518
|
-
|
519
|
-
LAZY_LOADING = "lazy loading"
|
520
|
-
ASAP_LOADING = "load ASAP"
|
521
|
-
ON_SHOW_LOADING = "load when show requested"
|
522
|
-
|
523
|
-
LOADING_MODES = (LAZY_LOADING, ASAP_LOADING, ON_SHOW_LOADING)
|
524
|
-
|
525
|
-
|
526
|
-
class _StackImageToLoad(_StackImage, qt.QObject):
|
527
|
-
"""
|
528
|
-
Define a set of images that can be already loaded or that can be loaded on
|
529
|
-
demand
|
530
|
-
"""
|
531
|
-
|
532
|
-
sigImageLoaded = qt.Signal(str)
|
533
|
-
"""Signal emitted when an image is loaded. Param is url_path"""
|
534
|
-
sigLoadingModeChanged = qt.Signal(str, str)
|
535
|
-
"""Signal emitted when the loading mode is changed. Parameter are new mode,
|
536
|
-
old mode"""
|
537
|
-
|
538
|
-
def __init__(self, loadingMode=LAZY_LOADING, images: Optional[Iterable] = None):
|
539
|
-
assert loadingMode in (LAZY_LOADING, ASAP_LOADING, ON_SHOW_LOADING)
|
540
|
-
_StackImage.__init__(self, images=images)
|
541
|
-
qt.QObject.__init__(self)
|
542
|
-
self._mode = loadingMode
|
543
|
-
self._url_to_index = {}
|
544
|
-
self._force_sync = False
|
545
|
-
|
546
|
-
def getUrlIndex(self, _url):
|
547
|
-
"""return the url position on the stack if registred"""
|
548
|
-
_url_path = _url
|
549
|
-
if isinstance(_url_path, DataUrl):
|
550
|
-
_url_path = _url_path.path()
|
551
|
-
if _url_path in self._url_to_index:
|
552
|
-
return self._url_to_index[_url_path]
|
553
|
-
else:
|
554
|
-
return None
|
555
|
-
|
556
|
-
def clear(self):
|
557
|
-
for img in self._images.values():
|
558
|
-
img.sigLoaded.disconnect(self.sigImageLoaded)
|
559
|
-
_StackImage.clear(self)
|
560
|
-
self._url_to_index.clear()
|
561
|
-
|
562
|
-
def addImage(self, image):
|
563
|
-
if isinstance(image, ImageFromFile):
|
564
|
-
image_ = image
|
565
|
-
elif isinstance(image, DataUrl):
|
566
|
-
image_ = ImageFromFile(url=image)
|
567
|
-
else:
|
568
|
-
raise TypeError(f"Unmanaged type: {type(image)}")
|
569
|
-
self._url_to_index[image_.url.path()] = self.nextIndex
|
570
|
-
_StackImage.addImage(self, image_)
|
571
|
-
image_.sigLoaded.connect(self.sigImageLoaded)
|
572
|
-
if self._mode == ASAP_LOADING:
|
573
|
-
image_.load(self._force_sync)
|
574
|
-
|
575
|
-
def setImages(self, images):
|
576
|
-
"""
|
577
|
-
|
578
|
-
:param list or tuple images: manage ImageFromFile or file pats (as str)
|
579
|
-
"""
|
580
|
-
self.clear()
|
581
|
-
for img in images:
|
582
|
-
if type(img) is str:
|
583
|
-
self.addFile(_file=img)
|
584
|
-
else:
|
585
|
-
self.addImage(img)
|
586
|
-
|
587
|
-
def setFiles(self, files):
|
588
|
-
self.clear()
|
589
|
-
for _file in files:
|
590
|
-
self.addFile(_file=_file)
|
591
|
-
|
592
|
-
def addFile(self, _file):
|
593
|
-
_fileWithImage = FileWithImage(_file)
|
594
|
-
_imagesFiles = _fileWithImage.getImages(_load=self._mode == ASAP_LOADING)
|
595
|
-
if _imagesFiles is None:
|
596
|
-
return
|
597
|
-
for imgFile in _imagesFiles:
|
598
|
-
self.addImage(imgFile)
|
599
|
-
|
600
|
-
def setLoadingMode(self, mode):
|
601
|
-
assert mode in LOADING_MODES
|
602
|
-
old = self._mode
|
603
|
-
self._mode = mode
|
604
|
-
self.sigLoadingModeChanged.emit(mode, old)
|
605
|
-
if self._mode == ASAP_LOADING:
|
606
|
-
self._loadAllImages()
|
607
|
-
|
608
|
-
def getLoadingMode(self):
|
609
|
-
return self._mode
|
610
|
-
|
611
|
-
def _loadAllImages(self):
|
612
|
-
for _, img in self._images.items():
|
613
|
-
try:
|
614
|
-
img.load(sync=self._force_sync)
|
615
|
-
except Exception as e:
|
616
|
-
logger.error(e)
|
617
|
-
|
618
|
-
def setForceSync(self, value):
|
619
|
-
self._force_sync = value
|
620
|
-
|
621
|
-
|
622
|
-
_loadingModeState = namedtuple("_loadingModeState", ["icon", "state", "action"])
|
623
|
-
|
624
|
-
|
625
|
-
class _LoadingModeToolButton(qt.QToolButton):
|
626
|
-
"""Tool button to switch keep aspect ratio of a plot"""
|
627
|
-
|
628
|
-
sigLoadModeChanged = qt.Signal(str)
|
629
|
-
|
630
|
-
def __init__(self, parent=None):
|
631
|
-
super(_LoadingModeToolButton, self).__init__(parent=parent)
|
632
|
-
|
633
|
-
self._states = {
|
634
|
-
ON_SHOW_LOADING: _loadingModeState(
|
635
|
-
icon=icons.getQIcon("low_speed"),
|
636
|
-
state="load data only when requiring",
|
637
|
-
action="will load data only when requiring",
|
638
|
-
),
|
639
|
-
LAZY_LOADING: _loadingModeState(
|
640
|
-
icon=icons.getQIcon("medium_low_speed"),
|
641
|
-
state="load data when seems convenient",
|
642
|
-
action="will load data when seems convenient",
|
643
|
-
),
|
644
|
-
ASAP_LOADING: _loadingModeState(
|
645
|
-
icon=icons.getQIcon("high_speed"),
|
646
|
-
state="load data as soon as possible",
|
647
|
-
action="will load data as soon as possible",
|
648
|
-
),
|
649
|
-
}
|
650
|
-
|
651
|
-
onShowLoadingMode = self._createAction(ON_SHOW_LOADING)
|
652
|
-
fctOSL = functools.partial(self.setLoadingMode, ON_SHOW_LOADING)
|
653
|
-
onShowLoadingMode.triggered.connect(fctOSL)
|
654
|
-
|
655
|
-
lazyLoadingMode = self._createAction(LAZY_LOADING)
|
656
|
-
fctLL = functools.partial(self.setLoadingMode, LAZY_LOADING)
|
657
|
-
lazyLoadingMode.triggered.connect(fctLL)
|
658
|
-
|
659
|
-
asapLoadingMode = self._createAction(ASAP_LOADING)
|
660
|
-
fctAL = functools.partial(self.setLoadingMode, ASAP_LOADING)
|
661
|
-
asapLoadingMode.triggered.connect(fctAL)
|
662
|
-
|
663
|
-
menu = qt.QMenu(self)
|
664
|
-
menu.addAction(onShowLoadingMode)
|
665
|
-
menu.addAction(lazyLoadingMode)
|
666
|
-
menu.addAction(asapLoadingMode)
|
667
|
-
self.setMenu(menu)
|
668
|
-
self.setPopupMode(qt.QToolButton.InstantPopup)
|
669
|
-
|
670
|
-
self.setLoadingMode(ON_SHOW_LOADING)
|
671
|
-
|
672
|
-
def _createAction(self, loadingMode):
|
673
|
-
icon = self._states[loadingMode].icon
|
674
|
-
text = self._states[loadingMode].action
|
675
|
-
return qt.QAction(icon, text, self)
|
676
|
-
|
677
|
-
def setLoadingMode(self, loadingMode):
|
678
|
-
assert loadingMode in LOADING_MODES
|
679
|
-
icon = self._states[loadingMode].icon
|
680
|
-
toolTip = self._states[loadingMode].state
|
681
|
-
self.setIcon(icon)
|
682
|
-
self.setToolTip(toolTip)
|
683
|
-
self.sigLoadModeChanged.emit(loadingMode)
|
684
|
-
|
685
|
-
|
686
|
-
class XAxisInvertedAction(PlotAction):
|
687
|
-
"""QAction controlling X orientation on a :class:`.PlotWidget`.
|
688
|
-
|
689
|
-
:param plot: :class:`.PlotWidget` instance on which to operate
|
690
|
-
:param parent: See :class:`QAction`
|
691
|
-
"""
|
692
|
-
|
693
|
-
def __init__(self, plot, parent=None):
|
694
|
-
# Uses two images for checked/unchecked states
|
695
|
-
self._states = {
|
696
|
-
False: (icons.getQIcon("plot-xleft"), "Orient X axis left"),
|
697
|
-
True: (icons.getQIcon("plot-xright"), "Orient X axis right"),
|
698
|
-
}
|
699
|
-
|
700
|
-
self._inverted = False
|
701
|
-
icon, tooltip = self._states[self.isInverted()]
|
702
|
-
super(XAxisInvertedAction, self).__init__(
|
703
|
-
plot,
|
704
|
-
icon=icon,
|
705
|
-
text="Invert X Axis",
|
706
|
-
tooltip=tooltip,
|
707
|
-
triggered=self._actionTriggered,
|
708
|
-
checkable=False,
|
709
|
-
parent=parent,
|
710
|
-
)
|
711
|
-
|
712
|
-
def _xAxisInvertedChanged(self, inverted):
|
713
|
-
"""Handle Plot set y axis inverted signal"""
|
714
|
-
icon, tooltip = self._states[inverted]
|
715
|
-
self.setIcon(icon)
|
716
|
-
self.setToolTip(tooltip)
|
717
|
-
|
718
|
-
def _actionTriggered(self, checked=False):
|
719
|
-
self._inverted = not self._inverted
|
720
|
-
icon, tooltip = self._states[self.isInverted()]
|
721
|
-
# this only work for images
|
722
|
-
self.setIcon(icon)
|
723
|
-
self.setToolTip(tooltip)
|
724
|
-
|
725
|
-
# flip the current data
|
726
|
-
data = self.plot.getActiveImage()
|
727
|
-
if data:
|
728
|
-
data_array = numpy.fliplr(data.getData())
|
729
|
-
data.setData(data_array)
|
730
|
-
|
731
|
-
def isInverted(self):
|
732
|
-
return self._inverted
|
94
|
+
def _updateUrlInfos(self):
|
95
|
+
url = self.getCurrentUrl()
|
96
|
+
name = url.file_path().split(os.path.sep)[-1]
|
97
|
+
|
98
|
+
self._qlFileName.setText(name)
|
99
|
+
self._qlFileName.setToolTip(url.path())
|
100
|
+
try:
|
101
|
+
last_mod = time.ctime(os.path.getmtime(url.file_path()))
|
102
|
+
except Exception:
|
103
|
+
last_mod = ""
|
104
|
+
self._qlLastModifications.setText(last_mod)
|