diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/silx.egg-info/PKG-INFO | 2 | ||||
-rw-r--r-- | src/silx.egg-info/SOURCES.txt | 2 | ||||
-rw-r--r-- | src/silx.egg-info/requires.txt | 3 | ||||
-rw-r--r-- | src/silx/_version.py | 2 | ||||
-rw-r--r-- | src/silx/gui/_glutils/gl.py | 20 | ||||
-rw-r--r-- | src/silx/gui/_glutils/test/__init__.py | 23 | ||||
-rw-r--r-- | src/silx/gui/_glutils/test/test_gl.py | 36 | ||||
-rw-r--r-- | src/silx/gui/plot/MaskToolsWidget.py | 10 | ||||
-rw-r--r-- | src/silx/gui/plot/ScatterMaskToolsWidget.py | 8 | ||||
-rw-r--r-- | src/silx/gui/plot/_BaseMaskToolsWidget.py | 4 | ||||
-rw-r--r-- | src/silx/gui/plot/actions/io.py | 12 | ||||
-rwxr-xr-x | src/silx/gui/plot/backends/BackendMatplotlib.py | 3 | ||||
-rw-r--r-- | src/silx/gui/plot/backends/glutils/GLPlotCurve.py | 4 | ||||
-rw-r--r-- | src/silx/gui/plot3d/actions/io.py | 6 | ||||
-rw-r--r-- | src/silx/io/dictdump.py | 11 |
15 files changed, 116 insertions, 30 deletions
diff --git a/src/silx.egg-info/PKG-INFO b/src/silx.egg-info/PKG-INFO index f953bc6..905be0f 100644 --- a/src/silx.egg-info/PKG-INFO +++ b/src/silx.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: silx -Version: 1.1.0 +Version: 1.1.2 Summary: Software library for X-ray data analysis Home-page: http://www.silx.org/ Author: data analysis unit diff --git a/src/silx.egg-info/SOURCES.txt b/src/silx.egg-info/SOURCES.txt index 6d81290..55da403 100644 --- a/src/silx.egg-info/SOURCES.txt +++ b/src/silx.egg-info/SOURCES.txt @@ -454,6 +454,8 @@ src/silx/gui/_glutils/__init__.py src/silx/gui/_glutils/font.py src/silx/gui/_glutils/gl.py src/silx/gui/_glutils/utils.py +src/silx/gui/_glutils/test/__init__.py +src/silx/gui/_glutils/test/test_gl.py src/silx/gui/data/ArrayTableModel.py src/silx/gui/data/ArrayTableWidget.py src/silx/gui/data/DataViewer.py diff --git a/src/silx.egg-info/requires.txt b/src/silx.egg-info/requires.txt index 11d2418..5a2c2e0 100644 --- a/src/silx.egg-info/requires.txt +++ b/src/silx.egg-info/requires.txt @@ -1,4 +1,4 @@ -numpy>=1.12.0 +numpy>=1.21.3 setuptools h5py fabio>=0.9 @@ -18,3 +18,4 @@ Pillow [test] pytest pytest-xvfb +pytest-mock diff --git a/src/silx/_version.py b/src/silx/_version.py index 511e823..5688237 100644 --- a/src/silx/_version.py +++ b/src/silx/_version.py @@ -70,7 +70,7 @@ PRERELEASE_NORMALIZED_NAME = {"dev": "a", MAJOR = 1 MINOR = 1 -MICRO = 0 +MICRO = 2 RELEV = "final" # <16 SERIAL = 0 # <16 diff --git a/src/silx/gui/_glutils/gl.py b/src/silx/gui/_glutils/gl.py index d33cf49..fb0a3fa 100644 --- a/src/silx/gui/_glutils/gl.py +++ b/src/silx/gui/_glutils/gl.py @@ -63,13 +63,29 @@ except NameError: GLchar = c_char +def getVersion() -> tuple: + """Returns the GL version as tuple of integers. + + Raises: + ValueError: If the version returned by the driver is not supported + """ + try: + desc = glGetString(GL_VERSION) + if isinstance(desc, bytes): + desc = desc.decode("ascii") + version = desc.split(" ", 1)[0] + return tuple([int(i) for i in version.split('.')]) + except Exception as e: + raise ValueError("GL version not properly formatted") from e + + def testGL() -> bool: """Test if required OpenGL version and extensions are available. This MUST be run with an active OpenGL context. """ - version = glGetString(GL_VERSION).split()[0] # get version number - major, minor = int(version[0]), int(version[2]) + version = getVersion() + major, minor = version[0], version[1] if major < 2 or (major == 2 and minor < 1): _logger.error("OpenGL version >=2.1 required, running with %s" % version) return False diff --git a/src/silx/gui/_glutils/test/__init__.py b/src/silx/gui/_glutils/test/__init__.py new file mode 100644 index 0000000..5ad4c28 --- /dev/null +++ b/src/silx/gui/_glutils/test/__init__.py @@ -0,0 +1,23 @@ +# /*########################################################################## +# +# Copyright (c) 2015-2022 European Synchrotron Radiation Facility +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# +# ###########################################################################*/ diff --git a/src/silx/gui/_glutils/test/test_gl.py b/src/silx/gui/_glutils/test/test_gl.py new file mode 100644 index 0000000..be9332b --- /dev/null +++ b/src/silx/gui/_glutils/test/test_gl.py @@ -0,0 +1,36 @@ +# /*########################################################################## +# +# Copyright (c) 2015-2022 European Synchrotron Radiation Facility +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# +# ###########################################################################*/ + +from .. import gl + + +def test_version_bytes(mocker): + mocker.patch('silx.gui._glutils.gl.glGetString', return_value=b"3.0 Mock") + assert gl.getVersion() == (3, 0) + + +def test_version_str(mocker): + """In case glGetString returns str""" + mocker.patch('silx.gui._glutils.gl.glGetString', return_value="3.0 Mock") + assert gl.getVersion() == (3, 0) diff --git a/src/silx/gui/plot/MaskToolsWidget.py b/src/silx/gui/plot/MaskToolsWidget.py index 46b532c..327cdd6 100644 --- a/src/silx/gui/plot/MaskToolsWidget.py +++ b/src/silx/gui/plot/MaskToolsWidget.py @@ -1,6 +1,6 @@ # /*########################################################################## # -# Copyright (c) 2017-2021 European Synchrotron Radiation Facility +# Copyright (c) 2017-2022 European Synchrotron Radiation Facility # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -416,7 +416,7 @@ class MaskToolsWidget(BaseMaskToolsWidget): if self.isMaskInteractionActivated(): # Disable drawing tool - self.browseAction.trigger() + self.plot.resetInteractiveMode() if self.isItemMaskUpdated(): # No "after-care" self._data = numpy.zeros((0, 0), dtype=numpy.uint8) @@ -712,7 +712,7 @@ class MaskToolsWidget(BaseMaskToolsWidget): """Open Save mask dialog""" dialog = qt.QFileDialog(self) dialog.setWindowTitle("Save Mask") - dialog.setOption(dialog.DontUseNativeDialog) + dialog.setOption(qt.QFileDialog.DontUseNativeDialog) dialog.setModal(1) hdf5Filter = 'HDF5 (%s)' % _HDF5_EXT_STR filters = [ @@ -733,9 +733,9 @@ class MaskToolsWidget(BaseMaskToolsWidget): # disable overwrite confirmation for HDF5, # because we append the data to existing files if filt_ == hdf5Filter: - dialog.setOption(dialog.DontConfirmOverwrite) + dialog.setOption(qt.QFileDialog.DontConfirmOverwrite) else: - dialog.setOption(dialog.DontConfirmOverwrite, False) + dialog.setOption(qt.QFileDialog.DontConfirmOverwrite, False) dialog.filterSelected.connect(onFilterSelection) if not dialog.exec(): diff --git a/src/silx/gui/plot/ScatterMaskToolsWidget.py b/src/silx/gui/plot/ScatterMaskToolsWidget.py index 3f8c28b..5c82fcf 100644 --- a/src/silx/gui/plot/ScatterMaskToolsWidget.py +++ b/src/silx/gui/plot/ScatterMaskToolsWidget.py @@ -1,6 +1,6 @@ # /*########################################################################## # -# Copyright (c) 2018-2021 European Synchrotron Radiation Facility +# Copyright (c) 2018-2022 European Synchrotron Radiation Facility # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -287,8 +287,10 @@ class ScatterMaskToolsWidget(BaseMaskToolsWidget): self.plot.sigActiveScatterChanged.disconnect(self._activeScatterChanged) except (RuntimeError, TypeError): _logger.info(sys.exc_info()[1]) - if not self.browseAction.isChecked(): - self.browseAction.trigger() # Disable drawing tool + + if self.isMaskInteractionActivated(): + # Disable drawing tool + self.plot.resetInteractiveMode() if self.getSelectionMask(copy=False) is not None: self.plot.sigActiveScatterChanged.connect( diff --git a/src/silx/gui/plot/_BaseMaskToolsWidget.py b/src/silx/gui/plot/_BaseMaskToolsWidget.py index dda75e1..1673137 100644 --- a/src/silx/gui/plot/_BaseMaskToolsWidget.py +++ b/src/silx/gui/plot/_BaseMaskToolsWidget.py @@ -918,8 +918,8 @@ class BaseMaskToolsWidget(qt.QWidget): if (event.type() == qt.QEvent.EnabledChange and not self.isEnabled() and self.drawActionGroup.checkedAction()): - # Disable drawing tool by setting interaction to zoom - self.browseAction.trigger() + # Disable drawing tool by reseting interaction to pan or zoom + self.plot.resetInteractiveMode() def save(self, filename, kind): """Save current mask in a file diff --git a/src/silx/gui/plot/actions/io.py b/src/silx/gui/plot/actions/io.py index 6cdd4d0..1ed9649 100644 --- a/src/silx/gui/plot/actions/io.py +++ b/src/silx/gui/plot/actions/io.py @@ -1,6 +1,6 @@ # /*########################################################################## # -# Copyright (c) 2004-2021 European Synchrotron Radiation Facility +# Copyright (c) 2004-2022 European Synchrotron Radiation Facility # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -628,21 +628,21 @@ class SaveAction(PlotAction): # Create and run File dialog dialog = qt.QFileDialog(self.plot) - dialog.setOption(dialog.DontUseNativeDialog) + dialog.setOption(qt.QFileDialog.DontUseNativeDialog) dialog.setWindowTitle("Output File Selection") dialog.setModal(1) dialog.setNameFilters(list(filters.keys())) - dialog.setFileMode(dialog.AnyFile) - dialog.setAcceptMode(dialog.AcceptSave) + dialog.setFileMode(qt.QFileDialog.AnyFile) + dialog.setAcceptMode(qt.QFileDialog.AcceptSave) def onFilterSelection(filt_): # disable overwrite confirmation for NXdata types, # because we append the data to existing files if filt_ in self._appendFilters: - dialog.setOption(dialog.DontConfirmOverwrite) + dialog.setOption(qt.QFileDialog.DontConfirmOverwrite) else: - dialog.setOption(dialog.DontConfirmOverwrite, False) + dialog.setOption(qt.QFileDialog.DontConfirmOverwrite, False) dialog.filterSelected.connect(onFilterSelection) diff --git a/src/silx/gui/plot/backends/BackendMatplotlib.py b/src/silx/gui/plot/backends/BackendMatplotlib.py index 8610ed1..1b31582 100755 --- a/src/silx/gui/plot/backends/BackendMatplotlib.py +++ b/src/silx/gui/plot/backends/BackendMatplotlib.py @@ -1485,6 +1485,9 @@ class BackendMatplotlibQt(BackendMatplotlib, FigureCanvasQTAgg): This is directly called by matplotlib for widget resize. """ + if self.size().isEmpty(): + return # Skip rendering of 0-sized canvas + self.updateZOrder() # Starting with mpl 2.1.0, toggling autoscale raises a ValueError diff --git a/src/silx/gui/plot/backends/glutils/GLPlotCurve.py b/src/silx/gui/plot/backends/glutils/GLPlotCurve.py index 65bb6f0..4825479 100644 --- a/src/silx/gui/plot/backends/glutils/GLPlotCurve.py +++ b/src/silx/gui/plot/backends/glutils/GLPlotCurve.py @@ -854,8 +854,8 @@ class Points2D(object): @classmethod def init(cls): """OpenGL context initialization""" - version = gl.glGetString(gl.GL_VERSION) - majorVersion = int(version[0]) + version = gl.getVersion() + majorVersion = version[0] assert majorVersion >= 2 gl.glEnable(gl.GL_VERTEX_PROGRAM_POINT_SIZE) # OpenGL 2 gl.glEnable(gl.GL_POINT_SPRITE) # OpenGL 2 diff --git a/src/silx/gui/plot3d/actions/io.py b/src/silx/gui/plot3d/actions/io.py index f8a1d86..47b0ce5 100644 --- a/src/silx/gui/plot3d/actions/io.py +++ b/src/silx/gui/plot3d/actions/io.py @@ -1,6 +1,6 @@ # /*########################################################################## # -# Copyright (c) 2016-2021 European Synchrotron Radiation Facility +# Copyright (c) 2016-2022 European Synchrotron Radiation Facility # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -226,8 +226,8 @@ class VideoAction(Plot3DAction): dialog.setModal(True) dialog.setNameFilters([self.PNG_SERIE_FILTER, self.MNG_FILTER]) - dialog.setFileMode(dialog.AnyFile) - dialog.setAcceptMode(dialog.AcceptSave) + dialog.setFileMode(qt.QFileDialog.AnyFile) + dialog.setAcceptMode(qt.QFileDialog.AcceptSave) if not dialog.exec(): return diff --git a/src/silx/io/dictdump.py b/src/silx/io/dictdump.py index d1bf8c4..094a51f 100644 --- a/src/silx/io/dictdump.py +++ b/src/silx/io/dictdump.py @@ -32,9 +32,12 @@ import numpy import os.path import h5py try: - import pint + from pint import Quantity as PintQuantity except ImportError: - pint = None + try: + from pint.quantity import Quantity as PintQuantity + except ImportError: + PintQuantity = None from .configdict import ConfigDict from .utils import is_group @@ -67,7 +70,7 @@ def _prepare_hdf5_write_value(array_like): ``numpy.array()`` (`str`, `list`, `numpy.ndarray`…) :return: ``numpy.ndarray`` ready to be written as an HDF5 dataset """ - if pint is not None and isinstance(array_like, pint.quantity.Quantity): + if PintQuantity is not None and isinstance(array_like, PintQuantity): return numpy.array(array_like.magnitude) array = numpy.asarray(array_like) if numpy.issubdtype(array.dtype, numpy.bytes_): @@ -470,7 +473,7 @@ def nexus_to_h5_dict( add_nx_class=add_nx_class, has_nx_class=key_has_nx_class) - elif pint is not None and isinstance(value, pint.quantity.Quantity): + elif PintQuantity is not None and isinstance(value, PintQuantity): copy[key] = value.magnitude copy[(key, "units")] = f"{value.units:~C}" |