Beispiel #1
0
class TestScalarFieldView(TestCaseQt, ParametricTestCase):
    """Tests of ScalarFieldView widget."""

    def setUp(self):
        super(TestScalarFieldView, self).setUp()
        self.widget = ScalarFieldView()
        self.widget.show()

        # Commented as it slows down the tests
        # self.qWaitForWindowExposed(self.widget)

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

    @staticmethod
    def _buildData(size):
        """Make a 3D dataset"""
        coords = numpy.linspace(-10, 10, size)
        z = coords.reshape(-1, 1, 1)
        y = coords.reshape(1, -1, 1)
        x = coords.reshape(1, 1, -1)
        return numpy.sin(x * y * z) / (x * y * z)

    def testSimple(self):
        """Set the data and an isosurface"""
        data = self._buildData(size=32)

        self.widget.setData(data)
        self.widget.addIsosurface(0.5, (1., 0., 0., 0.5))
        self.widget.addIsosurface(0.7, qt.QColor('green'))
        self.qapp.processEvents()

    def testNotFinite(self):
        """Test with NaN and inf in data set"""

        # Some NaNs and inf
        data = self._buildData(size=32)
        data[8, :, :] = numpy.nan
        data[16, :, :] = numpy.inf
        data[24, :, :] = - numpy.inf

        self.widget.addIsosurface(0.5, 'red')
        self.widget.setData(data, copy=True)
        self.qapp.processEvents()
        self.widget.setData(None)

        # All NaNs or inf
        data = numpy.empty((4, 4, 4), dtype=numpy.float32)
        for value in (numpy.nan, numpy.inf):
            with self.subTest(value=str(value)):
                data[:] = value
                self.widget.setData(data, copy=True)
                self.qapp.processEvents()
class TestScalarFieldView(TestCaseQt, ParametricTestCase):
    """Tests of ScalarFieldView widget."""
    def setUp(self):
        super(TestScalarFieldView, self).setUp()
        self.widget = ScalarFieldView()
        self.widget.show()

        # Commented as it slows down the tests
        # self.qWaitForWindowExposed(self.widget)

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

    @staticmethod
    def _buildData(size):
        """Make a 3D dataset"""
        coords = numpy.linspace(-10, 10, size)
        z = coords.reshape(-1, 1, 1)
        y = coords.reshape(1, -1, 1)
        x = coords.reshape(1, 1, -1)
        return numpy.sin(x * y * z) / (x * y * z)

    def testSimple(self):
        """Set the data and an isosurface"""
        data = self._buildData(size=32)

        self.widget.setData(data)
        self.widget.addIsosurface(0.5, (1., 0., 0., 0.5))
        self.widget.addIsosurface(0.7, qt.QColor('green'))
        self.qapp.processEvents()

    def testNotFinite(self):
        """Test with NaN and inf in data set"""

        # Some NaNs and inf
        data = self._buildData(size=32)
        data[8, :, :] = numpy.nan
        data[16, :, :] = numpy.inf
        data[24, :, :] = -numpy.inf

        self.widget.addIsosurface(0.5, 'red')
        self.widget.setData(data, copy=True)
        self.qapp.processEvents()
        self.widget.setData(None)

        # All NaNs or inf
        data = numpy.empty((4, 4, 4), dtype=numpy.float32)
        for value in (numpy.nan, numpy.inf):
            with self.subTest(value=str(value)):
                data[:] = value
                self.widget.setData(data, copy=True)
                self.qapp.processEvents()
Beispiel #3
0
class TestScalarFieldView(TestCaseQt):
    """Tests StatsWidget combined with ScalarFieldView"""
    def setUp(self):
        super(TestScalarFieldView, self).setUp()
        self.scalarFieldView = ScalarFieldView()
        self.scalarFieldView.resize(300, 300)
        self.scalarFieldView.show()
        self.statsWidget = BasicStatsWidget()
        self.statsWidget.setPlot(self.scalarFieldView)
        # self.qWaitForWindowExposed(self.sceneWidget)

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

    def _getTextFor(self, row, name):
        """Returns text in table at given row for column name

        :param int row: Row number in the table
        :param str name: Column id
        :rtype: Union[str,None]
        """
        statsTable = self.statsWidget._getStatsTable()

        for column in range(statsTable.columnCount()):
            headerItem = statsTable.horizontalHeaderItem(column)
            if headerItem.data(qt.Qt.UserRole) == name:
                tableItem = statsTable.item(row, column)
                return tableItem.text()

        return None

    def test(self):
        """Test StatsWidget with ScalarFieldView"""
        data = numpy.arange(64**3, dtype=numpy.float64).reshape(64, 64, 64)
        self.scalarFieldView.setData(data)

        statsTable = self.statsWidget._getStatsTable()

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

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

        for column in range(statsTable.columnCount()):
            self.assertEqual(float(self._getTextFor(0, 'min')),
                             numpy.min(data))
            self.assertEqual(float(self._getTextFor(0, 'max')),
                             numpy.max(data))
            sum_ = numpy.sum(data)
            comz = numpy.sum(
                numpy.arange(data.shape[0]) *
                numpy.sum(data, axis=(1, 2))) / sum_
            comy = numpy.sum(
                numpy.arange(data.shape[1]) *
                numpy.sum(data, axis=(0, 2))) / sum_
            comx = numpy.sum(
                numpy.arange(data.shape[2]) *
                numpy.sum(data, axis=(0, 1))) / sum_
            self.assertEqual(self._getTextFor(0, 'COM'), str(
                (comx, comy, comz)))
Beispiel #4
0
def main(argv=None):
    # Parse input arguments
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('-l',
                        '--level',
                        nargs='?',
                        type=float,
                        default=float('nan'),
                        help="The value at which to generate the iso-surface")
    parser.add_argument('-sx',
                        '--xscale',
                        nargs='?',
                        type=float,
                        default=1.,
                        help="The scale of the data on the X axis")
    parser.add_argument('-sy',
                        '--yscale',
                        nargs='?',
                        type=float,
                        default=1.,
                        help="The scale of the data on the Y axis")
    parser.add_argument('-sz',
                        '--zscale',
                        nargs='?',
                        type=float,
                        default=1.,
                        help="The scale of the data on the Z axis")
    parser.add_argument('-ox',
                        '--xoffset',
                        nargs='?',
                        type=float,
                        default=0.,
                        help="The offset of the data on the X axis")
    parser.add_argument('-oy',
                        '--yoffset',
                        nargs='?',
                        type=float,
                        default=0.,
                        help="The offset of the data on the Y axis")
    parser.add_argument('-oz',
                        '--zoffset',
                        nargs='?',
                        type=float,
                        default=0.,
                        help="The offset of the data on the Z axis")
    parser.add_argument('filename',
                        nargs='?',
                        default=None,
                        help="""Filename to open.

        It supports 3D volume saved as .npy or in .h5 files.

        It also support nD data set (n>=3) stored in a HDF5 file.
        For HDF5, provide the filename and path as: <filename>::<path_in_file>.
        If the data set has more than 3 dimensions, it is possible to choose a
        3D data set as a subset by providing the indices along the first n-3
        dimensions with '#':
        <filename>::<path_in_file>#<1st_dim_index>...#<n-3th_dim_index>

        E.g.: data.h5::/data_5D#1#1
        """)
    args = parser.parse_args(args=argv)

    # Start GUI
    global app  # QApplication must be global to avoid seg fault on quit
    app = qt.QApplication([])

    # Create the viewer main window
    window = ScalarFieldView()
    window.setAttribute(qt.Qt.WA_DeleteOnClose)

    # Create a parameter tree for the scalar field view
    treeView = SFViewParamTree.TreeView(window)
    treeView.setSfView(window)  # Attach the parameter tree to the view

    # Add the parameter tree to the main window in a dock widget
    dock = qt.QDockWidget()
    dock.setWindowTitle('Parameters')
    dock.setWidget(treeView)
    window.addDockWidget(qt.Qt.RightDockWidgetArea, dock)

    # Load data from file
    if args.filename is not None:
        data = load(args.filename)
        _logger.info('Data:\n\tShape: %s\n\tRange: [%f, %f]', str(data.shape),
                     data.min(), data.max())
    else:
        # Create dummy data
        _logger.warning('Not data file provided, creating dummy data')
        coords = numpy.linspace(-10, 10, 64)
        z = coords.reshape(-1, 1, 1)
        y = coords.reshape(1, -1, 1)
        x = coords.reshape(1, 1, -1)
        data = numpy.sin(x * y * z) / (x * y * z)

    # Set ScalarFieldView data
    window.setData(data)

    # Set scale of the data
    window.setScale(args.xscale, args.yscale, args.zscale)

    # Set offset of the data
    window.setTranslation(args.xoffset, args.yoffset, args.zoffset)

    # Set axes labels
    window.setAxesLabels('X', 'Y', 'Z')

    # Add an iso-surface
    if not numpy.isnan(args.level):
        # Add an iso-surface at the given iso-level
        window.addIsosurface(args.level, '#FF0000FF')
    else:
        # Add an iso-surface from a function
        window.addIsosurface(default_isolevel, '#FF0000FF')

    window.show()
    return app.exec_()
Beispiel #5
0
class TestScalarFieldView(TestCaseQt):
    """Tests StatsWidget combined with ScalarFieldView"""

    def setUp(self):
        super(TestScalarFieldView, self).setUp()
        self.scalarFieldView = ScalarFieldView()
        self.scalarFieldView.resize(300, 300)
        self.scalarFieldView.show()
        self.statsWidget = BasicStatsWidget()
        self.statsWidget.setPlot(self.scalarFieldView)
        # self.qWaitForWindowExposed(self.sceneWidget)

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

    def _getTextFor(self, row, name):
        """Returns text in table at given row for column name

        :param int row: Row number in the table
        :param str name: Column id
        :rtype: Union[str,None]
        """
        statsTable = self.statsWidget._getStatsTable()

        for column in range(statsTable.columnCount()):
            headerItem = statsTable.horizontalHeaderItem(column)
            if headerItem.data(qt.Qt.UserRole) == name:
                tableItem = statsTable.item(row, column)
                return tableItem.text()

        return None

    def test(self):
        """Test StatsWidget with ScalarFieldView"""
        data = numpy.arange(64**3, dtype=numpy.float64).reshape(64, 64, 64)
        self.scalarFieldView.setData(data)

        statsTable = self.statsWidget._getStatsTable()

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

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

        for column in range(statsTable.columnCount()):
            self.assertEqual(float(self._getTextFor(0, 'min')), numpy.min(data))
            self.assertEqual(float(self._getTextFor(0, 'max')), numpy.max(data))
            sum_ = numpy.sum(data)
            comz = numpy.sum(numpy.arange(data.shape[0]) * numpy.sum(data, axis=(1, 2))) / sum_
            comy = numpy.sum(numpy.arange(data.shape[1]) * numpy.sum(data, axis=(0, 2))) / sum_
            comx = numpy.sum(numpy.arange(data.shape[2]) * numpy.sum(data, axis=(0, 1))) / sum_
            self.assertEqual(self._getTextFor(0, 'COM'), str((comx, comy, comz)))