Пример #1
0
 def setUp(self):
     super(TestSceneWidget, self).setUp()
     self.sceneWidget = SceneWidget()
     self.sceneWidget.resize(300, 300)
     self.sceneWidget.show()
     self.statsWidget = BasicStatsWidget()
     self.statsWidget.setPlot(self.sceneWidget)
Пример #2
0
    def setUp(self):
        super(TestPositionInfoWidget, self).setUp()
        self.sceneWidget = SceneWidget()
        self.sceneWidget.resize(300, 300)
        self.sceneWidget.show()

        self.positionInfoWidget = PositionInfoWidget()
        self.positionInfoWidget.setSceneWidget(self.sceneWidget)
        self.positionInfoWidget.show()
        self.qWaitForWindowExposed(self.positionInfoWidget)
Пример #3
0
 def setUp(self):
     super(TestSceneWidget, self).setUp()
     self.sceneWidget = SceneWidget()
     self.sceneWidget.resize(300, 300)
     self.sceneWidget.show()
     self.statsWidget = BasicStatsWidget()
     self.statsWidget.setPlot(self.sceneWidget)
Пример #4
0
    def setUp(self):
        super(TestPositionInfoWidget, self).setUp()
        self.sceneWidget = SceneWidget()
        self.sceneWidget.resize(300, 300)
        self.sceneWidget.show()

        self.positionInfoWidget = PositionInfoWidget()
        self.positionInfoWidget.setSceneWidget(self.sceneWidget)
        self.positionInfoWidget.show()
        self.qWaitForWindowExposed(self.positionInfoWidget)
Пример #5
0
 def setUp(self):
     super(TestSceneWidgetPicking, self).setUp()
     self.widget = SceneWidget()
     self.widget.resize(300, 300)
     self.widget.show()
Пример #6
0
class TestSceneWidgetPicking(TestCaseQt, ParametricTestCase):
    """Tests SceneWidget picking feature"""
    def setUp(self):
        super(TestSceneWidgetPicking, self).setUp()
        self.widget = SceneWidget()
        self.widget.resize(300, 300)
        self.widget.show()
        # self.qWaitForWindowExposed(self.widget)

    def tearDown(self):
        self.qapp.processEvents()
        self.widget.setAttribute(qt.Qt.WA_DeleteOnClose)
        self.widget.close()
        del self.widget
        super(TestSceneWidgetPicking, self).tearDown()

    def _widgetCenter(self):
        """Returns widget center"""
        size = self.widget.size()
        return size.width() // 2, size.height() // 2

    def testPickImage(self):
        """Test picking of ImageData and ImageRgba items"""
        imageData = items.ImageData()
        imageData.setData(numpy.arange(100).reshape(10, 10))

        imageRgba = items.ImageRgba()
        imageRgba.setData(
            numpy.arange(300, dtype=numpy.uint8).reshape(10, 10, 3))

        for item in (imageData, imageRgba):
            with self.subTest(item=item.__class__.__name__):
                # Add item
                self.widget.clearItems()
                self.widget.addItem(item)
                self.widget.resetZoom('front')
                self.qapp.processEvents()

                # Picking on data (at widget center)
                picking = list(self.widget.pickItems(*self._widgetCenter()))

                self.assertEqual(len(picking), 1)
                self.assertIs(picking[0].getItem(), item)
                self.assertEqual(picking[0].getPositions('ndc').shape, (1, 3))
                data = picking[0].getData()
                self.assertEqual(len(data), 1)
                self.assertTrue(
                    numpy.array_equal(data,
                                      item.getData()[picking[0].getIndices()]))

                # Picking outside data
                picking = list(self.widget.pickItems(1, 1))
                self.assertEqual(len(picking), 0)

    def testPickScatter(self):
        """Test picking of Scatter2D and Scatter3D items"""
        data = numpy.arange(100)

        scatter2d = items.Scatter2D()
        scatter2d.setData(x=data, y=data, value=data)

        scatter3d = items.Scatter3D()
        scatter3d.setData(x=data, y=data, z=data, value=data)

        for item in (scatter2d, scatter3d):
            with self.subTest(item=item.__class__.__name__):
                # Add item
                self.widget.clearItems()
                self.widget.addItem(item)
                self.widget.resetZoom('front')
                self.qapp.processEvents()

                # Picking on data (at widget center)
                picking = list(self.widget.pickItems(*self._widgetCenter()))

                self.assertEqual(len(picking), 1)
                self.assertIs(picking[0].getItem(), item)
                nbPos = len(picking[0].getPositions('ndc'))
                data = picking[0].getData()
                self.assertEqual(nbPos, len(data))
                self.assertTrue(
                    numpy.array_equal(
                        data,
                        item.getValueData()[picking[0].getIndices()]))

                # Picking outside data
                picking = list(self.widget.pickItems(1, 1))
                self.assertEqual(len(picking), 0)

    def testPickVolume(self):
        """Test picking of volume CutPlane and Isosurface items"""
        for dtype in (numpy.float32, numpy.complex64):
            with self.subTest(dtype=dtype):
                refData = numpy.arange(10**3, dtype=dtype).reshape(10, 10, 10)
                volume = self.widget.addVolume(refData)
                if dtype == numpy.complex64:
                    volume.setComplexMode(volume.Mode.REAL)
                    refData = numpy.real(refData)
                self.widget.resetZoom('front')

                cutplane = volume.getCutPlanes()[0]
                if dtype == numpy.complex64:
                    cutplane.setComplexMode(volume.Mode.REAL)
                cutplane.getColormap().setVRange(0, 100)
                cutplane.setNormal((0, 0, 1))

                # Picking on data without anything displayed
                cutplane.setVisible(False)
                picking = list(self.widget.pickItems(*self._widgetCenter()))
                self.assertEqual(len(picking), 0)

                # Picking on data with the cut plane
                cutplane.setVisible(True)
                picking = list(self.widget.pickItems(*self._widgetCenter()))

                self.assertEqual(len(picking), 1)
                self.assertIs(picking[0].getItem(), cutplane)
                data = picking[0].getData()
                self.assertEqual(len(data), 1)
                self.assertEqual(picking[0].getPositions().shape, (1, 3))
                self.assertTrue(
                    numpy.array_equal(data, refData[picking[0].getIndices()]))

                # Picking on data with an isosurface
                isosurface = volume.addIsosurface(level=500,
                                                  color=(1., 0., 0., .5))
                picking = list(self.widget.pickItems(*self._widgetCenter()))
                self.assertEqual(len(picking), 2)
                self.assertIs(picking[0].getItem(), cutplane)
                self.assertIs(picking[1].getItem(), isosurface)
                self.assertEqual(picking[1].getPositions().shape, (1, 3))
                data = picking[1].getData()
                self.assertEqual(len(data), 1)
                self.assertTrue(
                    numpy.array_equal(data, refData[picking[1].getIndices()]))

                # Picking outside data
                picking = list(self.widget.pickItems(1, 1))
                self.assertEqual(len(picking), 0)

                self.widget.clearItems()

    def testPickMesh(self):
        """Test picking of Mesh items"""

        triangles = items.Mesh()
        triangles.setData(position=((0, 0, 0), (1, 0, 0), (1, 1, 0), (0, 0, 0),
                                    (1, 1, 0), (0, 1, 0)),
                          color=(1, 0, 0, 1),
                          mode='triangles')
        triangleStrip = items.Mesh()
        triangleStrip.setData(position=(((1, 0, 0), (0, 0, 0), (1, 1, 0),
                                         (0, 1, 0))),
                              color=(0, 1, 0, 1),
                              mode='triangle_strip')
        triangleFan = items.Mesh()
        triangleFan.setData(position=((0, 0, 0), (1, 0, 0), (1, 1, 0), (0, 1,
                                                                        0)),
                            color=(0, 0, 1, 1),
                            mode='fan')

        for item in (triangles, triangleStrip, triangleFan):
            with self.subTest(mode=item.getDrawMode()):
                # Add item
                self.widget.clearItems()
                self.widget.addItem(item)
                self.widget.resetZoom('front')
                self.qapp.processEvents()

                # Picking on data (at widget center)
                picking = list(self.widget.pickItems(*self._widgetCenter()))

                self.assertEqual(len(picking), 1)
                self.assertIs(picking[0].getItem(), item)
                nbPos = len(picking[0].getPositions())
                data = picking[0].getData()
                self.assertEqual(nbPos, len(data))
                self.assertTrue(
                    numpy.array_equal(
                        data,
                        item.getPositionData()[picking[0].getIndices()]))

                # Picking outside data
                picking = list(self.widget.pickItems(1, 1))
                self.assertEqual(len(picking), 0)

    def testPickMeshWithIndices(self):
        """Test picking of Mesh items defined by indices"""

        triangles = items.Mesh()
        triangles.setData(
            position=((0, 0, 0), (1, 0, 0), (0, 1, 0), (1, 1, 0)),
            color=(1, 0, 0, 1),
            indices=numpy.array(  # dummy triangles and square
                (0, 0, 1, 0, 1, 2, 1, 2, 3),
                dtype=numpy.uint8),
            mode='triangles')
        triangleStrip = items.Mesh()
        triangleStrip.setData(
            position=((0, 0, 0), (1, 0, 0), (0, 1, 0), (1, 1, 0)),
            color=(0, 1, 0, 1),
            indices=numpy.array(  # dummy triangles and square
                (1, 0, 0, 1, 2, 3),
                dtype=numpy.uint8),
            mode='triangle_strip')
        triangleFan = items.Mesh()
        triangleFan.setData(
            position=((0, 0, 0), (1, 0, 0), (0, 1, 0), (1, 1, 0)),
            color=(0, 0, 1, 1),
            indices=numpy.array(  # dummy triangle, square, dummy
                (1, 1, 0, 2, 3, 3),
                dtype=numpy.uint8),
            mode='fan')

        for item in (triangles, triangleStrip, triangleFan):
            with self.subTest(mode=item.getDrawMode()):
                # Add item
                self.widget.clearItems()
                self.widget.addItem(item)
                self.widget.resetZoom('front')
                self.qapp.processEvents()

                # Picking on data (at widget center)
                picking = list(self.widget.pickItems(*self._widgetCenter()))

                self.assertEqual(len(picking), 1)
                self.assertIs(picking[0].getItem(), item)
                nbPos = len(picking[0].getPositions())
                data = picking[0].getData()
                self.assertEqual(nbPos, len(data))
                self.assertTrue(
                    numpy.array_equal(
                        data,
                        item.getPositionData()[picking[0].getIndices()]))

                # Picking outside data
                picking = list(self.widget.pickItems(1, 1))
                self.assertEqual(len(picking), 0)

    def testPickCylindricalMesh(self):
        """Test picking of Box, Cylinder and Hexagon items"""

        positions = numpy.array(((0., 0., 0.), (1., 1., 0.), (2., 2., 0.)))
        box = items.Box()
        box.setData(position=positions)
        cylinder = items.Cylinder()
        cylinder.setData(position=positions)
        hexagon = items.Hexagon()
        hexagon.setData(position=positions)

        for item in (box, cylinder, hexagon):
            with self.subTest(item=item.__class__.__name__):
                # Add item
                self.widget.clearItems()
                self.widget.addItem(item)
                self.widget.resetZoom('front')
                self.qapp.processEvents()

                # Picking on data (at widget center)
                picking = list(self.widget.pickItems(*self._widgetCenter()))

                self.assertEqual(len(picking), 1)
                self.assertIs(picking[0].getItem(), item)
                nbPos = len(picking[0].getPositions())
                data = picking[0].getData()
                print(item.__class__.__name__, [positions[1]], data)
                self.assertTrue(numpy.all(numpy.equal(positions[1], data)))
                self.assertEqual(nbPos, len(data))
                self.assertTrue(
                    numpy.array_equal(
                        data,
                        item.getPosition()[picking[0].getIndices()]))

                # Picking outside data
                picking = list(self.widget.pickItems(1, 1))
                self.assertEqual(len(picking), 0)
Пример #7
0
class TestSceneWidget(TestCaseQt, ParametricTestCase):
    """Tests StatsWidget combined with SceneWidget"""
    def setUp(self):
        super(TestSceneWidget, self).setUp()
        self.sceneWidget = SceneWidget()
        self.sceneWidget.resize(300, 300)
        self.sceneWidget.show()
        self.statsWidget = BasicStatsWidget()
        self.statsWidget.setPlot(self.sceneWidget)
        # self.qWaitForWindowExposed(self.sceneWidget)

    def tearDown(self):
        Stats._getContext.cache_clear()
        self.qapp.processEvents()
        self.sceneWidget.setAttribute(qt.Qt.WA_DeleteOnClose)
        self.sceneWidget.close()
        del self.sceneWidget
        self.statsWidget.setAttribute(qt.Qt.WA_DeleteOnClose)
        self.statsWidget.close()
        del self.statsWidget
        super(TestSceneWidget, self).tearDown()

    def test(self):
        """Test StatsWidget with SceneWidget"""
        # Prepare scene

        # Data image
        image = self.sceneWidget.addImage(numpy.arange(100).reshape(10, 10))
        image.setLabel('Image')
        # RGB image
        imageRGB = self.sceneWidget.addImage(
            numpy.arange(300, dtype=numpy.uint8).reshape(10, 10, 3))
        imageRGB.setLabel('RGB Image')
        # 2D scatter
        data = numpy.arange(100)
        scatter2D = self.sceneWidget.add2DScatter(x=data, y=data, value=data)
        scatter2D.setLabel('2D Scatter')
        # 3D scatter
        scatter3D = self.sceneWidget.add3DScatter(x=data,
                                                  y=data,
                                                  z=data,
                                                  value=data)
        scatter3D.setLabel('3D Scatter')
        # Add a group
        group = items.GroupItem()
        self.sceneWidget.addItem(group)
        # 3D scalar field
        data = numpy.arange(64**3).reshape(64, 64, 64)
        scalarField = items.ScalarField3D()
        scalarField.setData(data, copy=False)
        scalarField.setLabel('3D Scalar field')
        group.addItem(scalarField)

        statsTable = self.statsWidget._getStatsTable()

        # Test selection only
        self.statsWidget.setDisplayOnlyActiveItem(True)
        self.assertEqual(statsTable.rowCount(), 0)

        self.sceneWidget.selection().setCurrentItem(group)
        self.assertEqual(statsTable.rowCount(), 0)

        for item in (image, scatter2D, scatter3D, scalarField):
            with self.subTest('selection only', item=item.getLabel()):
                self.sceneWidget.selection().setCurrentItem(item)
                self.assertEqual(statsTable.rowCount(), 1)
                self._checkItem(item)

        # Test all data
        self.statsWidget.setDisplayOnlyActiveItem(False)
        self.assertEqual(statsTable.rowCount(), 4)

        for item in (image, scatter2D, scatter3D, scalarField):
            with self.subTest('all items', item=item.getLabel()):
                self._checkItem(item)

    def _checkItem(self, item):
        """Check that item is in StatsTable and that stats are OK

        :param silx.gui.plot3d.items.Item3D item:
        """
        if isinstance(item, (items.Scatter2D, items.Scatter3D)):
            data = item.getValueData(copy=False)
        else:
            data = item.getData(copy=False)

        statsTable = self.statsWidget._getStatsTable()
        tableItems = statsTable._itemToTableItems(item)
        self.assertTrue(len(tableItems) > 0)
        self.assertEqual(tableItems['legend'].text(), item.getLabel())
        self.assertEqual(float(tableItems['min'].text()), numpy.min(data))
        self.assertEqual(float(tableItems['max'].text()), numpy.max(data))
Пример #8
0
 def setUp(self):
     super(TestSceneWidget, self).setUp()
     self.widget = SceneWidget()
     self.widget.show()
     self.qWaitForWindowExposed(self.widget)
Пример #9
0
class TestSceneWidget(TestCaseQt, ParametricTestCase):
    """Tests SceneWidget picking feature"""
    def setUp(self):
        super(TestSceneWidget, self).setUp()
        self.widget = SceneWidget()
        self.widget.show()
        self.qWaitForWindowExposed(self.widget)

    def tearDown(self):
        self.qapp.processEvents()
        self.widget.setAttribute(qt.Qt.WA_DeleteOnClose)
        self.widget.close()
        del self.widget
        super(TestSceneWidget, self).tearDown()

    def testFogEffect(self):
        """Test fog effect on scene primitive"""
        image = self.widget.addImage(numpy.arange(100).reshape(10, 10))
        scatter = self.widget.add3DScatter(
            *numpy.random.random(4000).reshape(4, -1))
        scatter.setTranslation(10, 10)
        scatter.setScale(10, 10, 10)

        self.widget.resetZoom('front')
        self.qapp.processEvents()

        self.widget.setFogMode(self.widget.FogMode.LINEAR)
        self.qapp.processEvents()

        self.widget.setFogMode(self.widget.FogMode.NONE)
        self.qapp.processEvents()
Пример #10
0
class TestPositionInfoWidget(TestCaseQt):
    """Tests PositionInfoWidget"""

    def setUp(self):
        super(TestPositionInfoWidget, self).setUp()
        self.sceneWidget = SceneWidget()
        self.sceneWidget.resize(300, 300)
        self.sceneWidget.show()

        self.positionInfoWidget = PositionInfoWidget()
        self.positionInfoWidget.setSceneWidget(self.sceneWidget)
        self.positionInfoWidget.show()
        self.qWaitForWindowExposed(self.positionInfoWidget)

        # self.qWaitForWindowExposed(self.widget)

    def tearDown(self):
        self.qapp.processEvents()

        self.sceneWidget.setAttribute(qt.Qt.WA_DeleteOnClose)
        self.sceneWidget.close()
        del self.sceneWidget

        self.positionInfoWidget.setAttribute(qt.Qt.WA_DeleteOnClose)
        self.positionInfoWidget.close()
        del self.positionInfoWidget
        super(TestPositionInfoWidget, self).tearDown()

    def test(self):
        """Test PositionInfoWidget"""
        self.assertIs(self.positionInfoWidget.getSceneWidget(),
                      self.sceneWidget)

        data = numpy.arange(100)
        self.sceneWidget.add2DScatter(x=data, y=data, value=data)
        self.sceneWidget.resetZoom('front')

        # Double click at the center
        self.mouseDClick(self.sceneWidget, button=qt.Qt.LeftButton)

        # Clear displayed value
        self.positionInfoWidget.clear()

        # Update info from API
        self.positionInfoWidget.pick(x=10, y=10)

        # Remove SceneWidget
        self.positionInfoWidget.setSceneWidget(None)
Пример #11
0
class TestSceneWidget(TestCaseQt, ParametricTestCase):
    """Tests StatsWidget combined with SceneWidget"""

    def setUp(self):
        super(TestSceneWidget, self).setUp()
        self.sceneWidget = SceneWidget()
        self.sceneWidget.resize(300, 300)
        self.sceneWidget.show()
        self.statsWidget = BasicStatsWidget()
        self.statsWidget.setPlot(self.sceneWidget)
        # self.qWaitForWindowExposed(self.sceneWidget)

    def tearDown(self):
        self.qapp.processEvents()
        self.sceneWidget.setAttribute(qt.Qt.WA_DeleteOnClose)
        self.sceneWidget.close()
        del self.sceneWidget
        self.statsWidget.setAttribute(qt.Qt.WA_DeleteOnClose)
        self.statsWidget.close()
        del self.statsWidget
        super(TestSceneWidget, self).tearDown()

    def test(self):
        """Test StatsWidget with SceneWidget"""
        # Prepare scene

        # Data image
        image = self.sceneWidget.addImage(numpy.arange(100).reshape(10, 10))
        image.setLabel('Image')
        # RGB image
        imageRGB = self.sceneWidget.addImage(
            numpy.arange(300, dtype=numpy.uint8).reshape(10, 10, 3))
        imageRGB.setLabel('RGB Image')
        # 2D scatter
        data = numpy.arange(100)
        scatter2D = self.sceneWidget.add2DScatter(x=data, y=data, value=data)
        scatter2D.setLabel('2D Scatter')
        # 3D scatter
        scatter3D = self.sceneWidget.add3DScatter(x=data, y=data, z=data, value=data)
        scatter3D.setLabel('3D Scatter')
        # Add a group
        group = items.GroupItem()
        self.sceneWidget.addItem(group)
        # 3D scalar field
        data = numpy.arange(64**3).reshape(64, 64, 64)
        scalarField = items.ScalarField3D()
        scalarField.setData(data, copy=False)
        scalarField.setLabel('3D Scalar field')
        group.addItem(scalarField)

        statsTable = self.statsWidget._getStatsTable()

        # Test selection only
        self.statsWidget.setDisplayOnlyActiveItem(True)
        self.assertEqual(statsTable.rowCount(), 0)

        self.sceneWidget.selection().setCurrentItem(group)
        self.assertEqual(statsTable.rowCount(), 0)

        for item in (image, scatter2D, scatter3D, scalarField):
            with self.subTest('selection only', item=item.getLabel()):
                self.sceneWidget.selection().setCurrentItem(item)
                self.assertEqual(statsTable.rowCount(), 1)
                self._checkItem(item)

        # Test all data
        self.statsWidget.setDisplayOnlyActiveItem(False)
        self.assertEqual(statsTable.rowCount(), 4)

        for item in (image, scatter2D, scatter3D, scalarField):
            with self.subTest('all items', item=item.getLabel()):
                self._checkItem(item)

    def _checkItem(self, item):
        """Check that item is in StatsTable and that stats are OK

        :param silx.gui.plot3d.items.Item3D item:
        """
        if isinstance(item, (items.Scatter2D, items.Scatter3D)):
            data = item.getValueData(copy=False)
        else:
            data = item.getData(copy=False)

        statsTable = self.statsWidget._getStatsTable()
        tableItems = statsTable._itemToTableItems(item)
        self.assertTrue(len(tableItems) > 0)
        self.assertEqual(tableItems['legend'].text(), item.getLabel())
        self.assertEqual(float(tableItems['min'].text()), numpy.min(data))
        self.assertEqual(float(tableItems['max'].text()), numpy.max(data))
Пример #12
0
class TestPositionInfoWidget(TestCaseQt):
    """Tests PositionInfoWidget"""
    def setUp(self):
        super(TestPositionInfoWidget, self).setUp()
        self.sceneWidget = SceneWidget()
        self.sceneWidget.resize(300, 300)
        self.sceneWidget.show()

        self.positionInfoWidget = PositionInfoWidget()
        self.positionInfoWidget.setSceneWidget(self.sceneWidget)
        self.positionInfoWidget.show()
        self.qWaitForWindowExposed(self.positionInfoWidget)

        # self.qWaitForWindowExposed(self.widget)

    def tearDown(self):
        self.qapp.processEvents()

        self.sceneWidget.setAttribute(qt.Qt.WA_DeleteOnClose)
        self.sceneWidget.close()
        del self.sceneWidget

        self.positionInfoWidget.setAttribute(qt.Qt.WA_DeleteOnClose)
        self.positionInfoWidget.close()
        del self.positionInfoWidget
        super(TestPositionInfoWidget, self).tearDown()

    def test(self):
        """Test PositionInfoWidget"""
        self.assertIs(self.positionInfoWidget.getSceneWidget(),
                      self.sceneWidget)

        data = numpy.arange(100)
        self.sceneWidget.add2DScatter(x=data, y=data, value=data)
        self.sceneWidget.resetZoom('front')

        # Double click at the center
        self.mouseDClick(self.sceneWidget, button=qt.Qt.LeftButton)

        # Clear displayed value
        self.positionInfoWidget.clear()

        # Update info from API
        self.positionInfoWidget.pick(x=10, y=10)

        # Remove SceneWidget
        self.positionInfoWidget.setSceneWidget(None)
Пример #13
0
 def setUp(self):
     super(TestSceneWidgetPicking, self).setUp()
     self.widget = SceneWidget()
     self.widget.resize(300, 300)
     self.widget.show()
Пример #14
0
class TestSceneWidgetPicking(TestCaseQt, ParametricTestCase):
    """Tests SceneWidget picking feature"""

    def setUp(self):
        super(TestSceneWidgetPicking, self).setUp()
        self.widget = SceneWidget()
        self.widget.resize(300, 300)
        self.widget.show()
        # self.qWaitForWindowExposed(self.widget)

    def tearDown(self):
        self.qapp.processEvents()
        self.widget.setAttribute(qt.Qt.WA_DeleteOnClose)
        self.widget.close()
        del self.widget
        super(TestSceneWidgetPicking, self).tearDown()

    def _widgetCenter(self):
        """Returns widget center"""
        size = self.widget.size()
        return size.width() // 2, size.height() // 2

    def testPickImage(self):
        """Test picking of ImageData and ImageRgba items"""
        imageData = items.ImageData()
        imageData.setData(numpy.arange(100).reshape(10, 10))

        imageRgba = items.ImageRgba()
        imageRgba.setData(
            numpy.arange(300, dtype=numpy.uint8).reshape(10, 10, 3))

        for item in (imageData, imageRgba):
            with self.subTest(item=item.__class__.__name__):
                # Add item
                self.widget.clearItems()
                self.widget.addItem(item)
                self.widget.resetZoom('front')
                self.qapp.processEvents()

                # Picking on data (at widget center)
                picking = list(self.widget.pickItems(*self._widgetCenter()))

                self.assertEqual(len(picking), 1)
                self.assertIs(picking[0].getItem(), item)
                self.assertEqual(picking[0].getPositions('ndc').shape, (1, 3))
                data = picking[0].getData()
                self.assertEqual(len(data), 1)
                self.assertTrue(numpy.array_equal(
                    data,
                    item.getData()[picking[0].getIndices()]))

                # Picking outside data
                picking = list(self.widget.pickItems(1, 1))
                self.assertEqual(len(picking), 0)

    def testPickScatter(self):
        """Test picking of Scatter2D and Scatter3D items"""
        data = numpy.arange(100)

        scatter2d = items.Scatter2D()
        scatter2d.setData(x=data, y=data, value=data)

        scatter3d = items.Scatter3D()
        scatter3d.setData(x=data, y=data, z=data, value=data)

        for item in (scatter2d, scatter3d):
            with self.subTest(item=item.__class__.__name__):
                # Add item
                self.widget.clearItems()
                self.widget.addItem(item)
                self.widget.resetZoom('front')
                self.qapp.processEvents()

                # Picking on data (at widget center)
                picking = list(self.widget.pickItems(*self._widgetCenter()))

                self.assertEqual(len(picking), 1)
                self.assertIs(picking[0].getItem(), item)
                nbPos = len(picking[0].getPositions('ndc'))
                data = picking[0].getData()
                self.assertEqual(nbPos, len(data))
                self.assertTrue(numpy.array_equal(
                    data,
                    item.getValueData()[picking[0].getIndices()]))

                # Picking outside data
                picking = list(self.widget.pickItems(1, 1))
                self.assertEqual(len(picking), 0)

    def testPickVolume(self):
        """Test picking of volume CutPlane and Isosurface items"""
        for dtype in (numpy.float32, numpy.complex64):
            with self.subTest(dtype=dtype):
                refData = numpy.arange(10**3, dtype=dtype).reshape(10, 10, 10)
                volume = self.widget.addVolume(refData)
                if dtype == numpy.complex64:
                    volume.setComplexMode(volume.Mode.REAL)
                    refData = numpy.real(refData)
                self.widget.resetZoom('front')

                cutplane = volume.getCutPlanes()[0]
                if dtype == numpy.complex64:
                    cutplane.setComplexMode(volume.Mode.REAL)
                cutplane.getColormap().setVRange(0, 100)
                cutplane.setNormal((0, 0, 1))

                # Picking on data without anything displayed
                cutplane.setVisible(False)
                picking = list(self.widget.pickItems(*self._widgetCenter()))
                self.assertEqual(len(picking), 0)

                # Picking on data with the cut plane
                cutplane.setVisible(True)
                picking = list(self.widget.pickItems(*self._widgetCenter()))

                self.assertEqual(len(picking), 1)
                self.assertIs(picking[0].getItem(), cutplane)
                data = picking[0].getData()
                self.assertEqual(len(data), 1)
                self.assertEqual(picking[0].getPositions().shape, (1, 3))
                self.assertTrue(numpy.array_equal(
                    data,
                    refData[picking[0].getIndices()]))

                # Picking on data with an isosurface
                isosurface = volume.addIsosurface(
                    level=500, color=(1., 0., 0., .5))
                picking = list(self.widget.pickItems(*self._widgetCenter()))
                self.assertEqual(len(picking), 2)
                self.assertIs(picking[0].getItem(), cutplane)
                self.assertIs(picking[1].getItem(), isosurface)
                self.assertEqual(picking[1].getPositions().shape, (1, 3))
                data = picking[1].getData()
                self.assertEqual(len(data), 1)
                self.assertTrue(numpy.array_equal(
                    data,
                    refData[picking[1].getIndices()]))

                # Picking outside data
                picking = list(self.widget.pickItems(1, 1))
                self.assertEqual(len(picking), 0)

                self.widget.clearItems()

    def testPickMesh(self):
        """Test picking of Mesh items"""

        triangles = items.Mesh()
        triangles.setData(
            position=((0, 0, 0), (1, 0, 0), (1, 1, 0),
                      (0, 0, 0), (1, 1, 0), (0, 1, 0)),
            color=(1, 0, 0, 1),
            mode='triangles')
        triangleStrip = items.Mesh()
        triangleStrip.setData(
            position=(((1, 0, 0), (0, 0, 0), (1, 1, 0), (0, 1, 0))),
            color=(0, 1, 0, 1),
            mode='triangle_strip')
        triangleFan = items.Mesh()
        triangleFan.setData(
            position=((0, 0, 0), (1, 0, 0), (1, 1, 0), (0, 1, 0)),
            color=(0, 0, 1, 1),
            mode='fan')

        for item in (triangles, triangleStrip, triangleFan):
            with self.subTest(mode=item.getDrawMode()):
                # Add item
                self.widget.clearItems()
                self.widget.addItem(item)
                self.widget.resetZoom('front')
                self.qapp.processEvents()

                # Picking on data (at widget center)
                picking = list(self.widget.pickItems(*self._widgetCenter()))

                self.assertEqual(len(picking), 1)
                self.assertIs(picking[0].getItem(), item)
                nbPos = len(picking[0].getPositions())
                data = picking[0].getData()
                self.assertEqual(nbPos, len(data))
                self.assertTrue(numpy.array_equal(
                    data,
                    item.getPositionData()[picking[0].getIndices()]))

                # Picking outside data
                picking = list(self.widget.pickItems(1, 1))
                self.assertEqual(len(picking), 0)

    def testPickMeshWithIndices(self):
        """Test picking of Mesh items defined by indices"""

        triangles = items.Mesh()
        triangles.setData(
            position=((0, 0, 0), (1, 0, 0), (0, 1, 0), (1, 1, 0)),
            color=(1, 0, 0, 1),
            indices=numpy.array(  # dummy triangles and square
                (0, 0, 1, 0, 1, 2, 1, 2, 3), dtype=numpy.uint8),
            mode='triangles')
        triangleStrip = items.Mesh()
        triangleStrip.setData(
            position=((0, 0, 0), (1, 0, 0), (0, 1, 0), (1, 1, 0)),
            color=(0, 1, 0, 1),
            indices=numpy.array(  # dummy triangles and square
                (1, 0, 0, 1, 2, 3), dtype=numpy.uint8),
            mode='triangle_strip')
        triangleFan = items.Mesh()
        triangleFan.setData(
            position=((0, 0, 0), (1, 0, 0), (0, 1, 0), (1, 1, 0)),
            color=(0, 0, 1, 1),
            indices=numpy.array(  # dummy triangle, square, dummy
                (1, 1, 0, 2, 3, 3), dtype=numpy.uint8),
            mode='fan')

        for item in (triangles, triangleStrip, triangleFan):
            with self.subTest(mode=item.getDrawMode()):
                # Add item
                self.widget.clearItems()
                self.widget.addItem(item)
                self.widget.resetZoom('front')
                self.qapp.processEvents()

                # Picking on data (at widget center)
                picking = list(self.widget.pickItems(*self._widgetCenter()))

                self.assertEqual(len(picking), 1)
                self.assertIs(picking[0].getItem(), item)
                nbPos = len(picking[0].getPositions())
                data = picking[0].getData()
                self.assertEqual(nbPos, len(data))
                self.assertTrue(numpy.array_equal(
                    data,
                    item.getPositionData()[picking[0].getIndices()]))

                # Picking outside data
                picking = list(self.widget.pickItems(1, 1))
                self.assertEqual(len(picking), 0)

    def testPickCylindricalMesh(self):
        """Test picking of Box, Cylinder and Hexagon items"""

        positions = numpy.array(((0., 0., 0.), (1., 1., 0.), (2., 2., 0.)))
        box = items.Box()
        box.setData(position=positions)
        cylinder = items.Cylinder()
        cylinder.setData(position=positions)
        hexagon = items.Hexagon()
        hexagon.setData(position=positions)

        for item in (box, cylinder, hexagon):
            with self.subTest(item=item.__class__.__name__):
                # Add item
                self.widget.clearItems()
                self.widget.addItem(item)
                self.widget.resetZoom('front')
                self.qapp.processEvents()

                # Picking on data (at widget center)
                picking = list(self.widget.pickItems(*self._widgetCenter()))

                self.assertEqual(len(picking), 1)
                self.assertIs(picking[0].getItem(), item)
                nbPos = len(picking[0].getPositions())
                data = picking[0].getData()
                print(item.__class__.__name__, [positions[1]], data)
                self.assertTrue(numpy.all(numpy.equal(positions[1], data)))
                self.assertEqual(nbPos, len(data))
                self.assertTrue(numpy.array_equal(
                    data,
                    item.getPosition()[picking[0].getIndices()]))

                # Picking outside data
                picking = list(self.widget.pickItems(1, 1))
                self.assertEqual(len(picking), 0)