class _TestRoiStatsBase(TestCaseQt):
    """Base class for several unittest relative to ROIStatsWidget"""
    def setUp(self):
        TestCaseQt.setUp(self)
        # define plot
        self.plot = PlotWindow()
        self.plot.addImage(numpy.arange(10000).reshape(100, 100),
                           legend='img1')
        self.img_item = self.plot.getImage('img1')
        self.plot.addCurve(x=numpy.linspace(0, 10, 56),
                           y=numpy.arange(56),
                           legend='curve1')
        self.curve_item = self.plot.getCurve('curve1')
        self.plot.addHistogram(edges=numpy.linspace(0, 10, 56),
                               histogram=numpy.arange(56),
                               legend='histo1')
        self.histogram_item = self.plot.getHistogram(legend='histo1')
        self.plot.addScatter(x=numpy.linspace(0, 10, 56),
                             y=numpy.linspace(0, 10, 56),
                             value=numpy.arange(56),
                             legend='scatter1')
        self.scatter_item = self.plot.getScatter(legend='scatter1')

        # stats widget
        self.statsWidget = ROIStatsWidget(plot=self.plot)

        # define stats
        stats = [
            ('sum', numpy.sum),
            ('mean', numpy.mean),
        ]
        self.statsWidget.setStats(stats=stats)

        # define rois
        self.roi1D = ROI(name='range1', fromdata=0, todata=4, type_='energy')
        self.rectangle_roi = RectangleROI()
        self.rectangle_roi.setGeometry(origin=(0, 0), size=(20, 20))
        self.rectangle_roi.setName('Initial ROI')
        self.polygon_roi = PolygonROI()
        points = numpy.array([[0, 5], [5, 0], [10, 5], [5, 10]])
        self.polygon_roi.setPoints(points)

    def statsTable(self):
        return self.statsWidget._statsROITable

    def tearDown(self):
        Stats._getContext.cache_clear()
        self.statsWidget.setAttribute(qt.Qt.WA_DeleteOnClose, True)
        self.statsWidget.close()
        self.statsWidget = None
        self.plot.setAttribute(qt.Qt.WA_DeleteOnClose, True)
        self.plot.close()
        self.plot = None
        TestCaseQt.tearDown(self)
Example #2
0
def get_2D_rois():
    """return some RectangleROI instance"""
    rectangle_roi = RectangleROI()
    rectangle_roi.setGeometry(origin=(0, 100), size=(20, 20))
    rectangle_roi.setName('Initial ROI')
    polygon_roi = PolygonROI()
    polygon_points = numpy.array([(0, 10), (10, 20), (45, 30), (35, 0)])
    polygon_roi.setPoints(polygon_points)
    polygon_roi.setName('polygon ROI')
    arc_roi = ArcROI()
    arc_roi.setName('arc ROI')
    arc_roi.setFirstShapePoints(numpy.array([[50, 10], [80, 120]]))
    arc_roi.setGeometry(*arc_roi.getGeometry())
    return rectangle_roi, polygon_roi, arc_roi
Example #3
0
 def test(self):
     """Test stats result on an image context with different scale and
     origins"""
     roi_origins = [(0, 0), (2, 10), (14, 20)]
     img_origins = [(0, 0), (14, 20), (2, 10)]
     img_scales = [1.0, 0.5, 2.0]
     _stats = {
         'sum': stats.Stat(name='sum', fct=numpy.sum),
     }
     for roi_origin in roi_origins:
         for img_origin in img_origins:
             for img_scale in img_scales:
                 with self.subTest(roi_origin=roi_origin,
                                   img_origin=img_origin,
                                   img_scale=img_scale):
                     self.plot.addImage(self.data,
                                        legend='img',
                                        origin=img_origin,
                                        scale=img_scale)
                     roi = RectangleROI()
                     roi.setGeometry(origin=roi_origin, size=(20, 20))
                     context = stats._ImageContext(
                         item=self.plot.getImage('img'),
                         plot=self.plot,
                         onlimits=False,
                         roi=roi)
                     x_start = int(
                         (roi_origin[0] - img_origin[0]) / img_scale)
                     x_end = int(x_start + (20 / img_scale)) + 1
                     y_start = int(
                         (roi_origin[1] - img_origin[1]) / img_scale)
                     y_end = int(y_start + (20 / img_scale)) + 1
                     x_start = max(x_start, 0)
                     x_end = min(max(x_end, 0), self.data_dims[1])
                     y_start = max(y_start, 0)
                     y_end = min(max(y_end, 0), self.data_dims[0])
                     th_sum = numpy.sum(self.data[y_start:y_end,
                                                  x_start:x_end])
                     self.assertAlmostEqual(
                         _stats['sum'].calculate(context), th_sum)
Example #4
0
    if roi.getName() == '':
        roi.setName('ROI %d' % len(roiManager.getRois()))
    if isinstance(roi, LineMixIn):
        roi.setLineWidth(1)
        roi.setLineStyle('--')
    if isinstance(roi, SymbolMixIn):
        roi.setSymbolSize(5)
    roi.setSelectable(True)
    roi.setEditable(True)


roiManager.sigRoiAdded.connect(updateAddedRegionOfInterest)

# Add a rectangular region of interest
roi = RectangleROI()
roi.setGeometry(origin=(50, 50), size=(200, 200))
roi.setName('Initial ROI')
roiManager.addRoi(roi)

# Create the table widget displaying
roiTable = RegionOfInterestTableWidget()
roiTable.setRegionOfInterestManager(roiManager)

# Create a toolbar containing buttons for all ROI 'drawing' modes
roiToolbar = qt.QToolBar()  # The layout to store the buttons
roiToolbar.setIconSize(qt.QSize(16, 16))

for roiClass in roiManager.getSupportedRoiClasses():
    # Create a tool button and associate it with the QAction of each mode
    action = roiManager.getInteractionModeAction(roiClass)
    roiToolbar.addAction(action)
Example #5
0
    """Called for each added region of interest: set the name"""
    if roi.getLabel() == '':
        roi.setLabel('ROI %d' % len(roiManager.getRois()))
    if isinstance(roi, LineMixIn):
        roi.setLineWidth(2)
        roi.setLineStyle('--')
    if isinstance(roi, SymbolMixIn):
        roi.setSymbol('o')
        roi.setSymbolSize(5)


roiManager.sigRoiAdded.connect(updateAddedRegionOfInterest)

# Add a rectangular region of interest
roi = RectangleROI()
roi.setGeometry(origin=(50, 50), size=(200, 200))
roi.setLabel('Initial ROI')
roiManager.addRoi(roi)

# Create the table widget displaying
roiTable = RegionOfInterestTableWidget()
roiTable.setRegionOfInterestManager(roiManager)

# Create a toolbar containing buttons for all ROI 'drawing' modes
roiToolbar = qt.QToolBar()  # The layout to store the buttons
roiToolbar.setIconSize(qt.QSize(16, 16))

for roiClass in roiManager.getSupportedRoiClasses():
    # Create a tool button and associate it with the QAction of each mode
    action = roiManager.getInteractionModeAction(roiClass)
    roiToolbar.addAction(action)
Example #6
0
class TestStatsROI(TestStatsBase, TestCaseQt):
    """
    Test stats based on ROI
    """
    def setUp(self):
        TestCaseQt.setUp(self)
        self.createRois()
        TestStatsBase.setUp(self)
        self.createHistogramContext()

        self.roiManager = RegionOfInterestManager(self.plot2d)
        self.roiManager.addRoi(self._2Droi_rect)
        self.roiManager.addRoi(self._2Droi_poly)

    def tearDown(self):
        self.roiManager.clear()
        self.roiManager = None
        self._1Droi = None
        self._2Droi_rect = None
        self._2Droi_poly = None
        self.plotHisto.setAttribute(qt.Qt.WA_DeleteOnClose)
        self.plotHisto.close()
        self.plotHisto = None
        TestStatsBase.tearDown(self)
        TestCaseQt.tearDown(self)

    def createRois(self):
        self._1Droi = ROI(name='my1DRoi', fromdata=2.0, todata=5.0)
        self._2Droi_rect = RectangleROI()
        self._2Droi_rect.setGeometry(size=(10, 10), origin=(10, 0))
        self._2Droi_poly = PolygonROI()
        points = numpy.array(((0, 20), (0, 0), (10, 0)))
        self._2Droi_poly.setPoints(points=points)

    def createCurveContext(self):
        TestStatsBase.createCurveContext(self)
        self.curveContext = stats._CurveContext(
            item=self.plot1d.getCurve('curve0'),
            plot=self.plot1d,
            onlimits=False,
            roi=self._1Droi)

    def createHistogramContext(self):
        self.plotHisto = Plot1D()
        x = range(20)
        y = range(20)
        self.plotHisto.addHistogram(x, y, legend='histo0')

        self.histoContext = stats._HistogramContext(
            item=self.plotHisto.getHistogram('histo0'),
            plot=self.plotHisto,
            onlimits=False,
            roi=self._1Droi)

    def createScatterContext(self):
        TestStatsBase.createScatterContext(self)
        self.scatterContext = stats._ScatterContext(
            item=self.scatterPlot.getScatter('scatter plot'),
            plot=self.scatterPlot,
            onlimits=False,
            roi=self._1Droi)

    def createImageContext(self):
        TestStatsBase.createImageContext(self)

        self.imageContext = stats._ImageContext(item=self.plot2d.getImage(
            self._imgLgd),
                                                plot=self.plot2d,
                                                onlimits=False,
                                                roi=self._2Droi_rect)

        self.imageContext_2 = stats._ImageContext(item=self.plot2d.getImage(
            self._imgLgd),
                                                  plot=self.plot2d,
                                                  onlimits=False,
                                                  roi=self._2Droi_poly)

    def testErrors(self):
        # test if onlimits is True and give also a roi
        with self.assertRaises(ValueError):
            stats._CurveContext(item=self.plot1d.getCurve('curve0'),
                                plot=self.plot1d,
                                onlimits=True,
                                roi=self._1Droi)

        # test if is a curve context and give an invalid 2D roi
        with self.assertRaises(TypeError):
            stats._CurveContext(item=self.plot1d.getCurve('curve0'),
                                plot=self.plot1d,
                                onlimits=False,
                                roi=self._2Droi_rect)

    def testBasicStatsCurve(self):
        """Test result for simple stats on a curve"""
        _stats = self.getBasicStats()
        xData = yData = numpy.array(range(0, 10))
        self.assertEqual(_stats['min'].calculate(self.curveContext), 2)
        self.assertEqual(_stats['max'].calculate(self.curveContext), 5)
        self.assertEqual(_stats['minCoords'].calculate(self.curveContext),
                         (2, ))
        self.assertEqual(_stats['maxCoords'].calculate(self.curveContext),
                         (5, ))
        self.assertEqual(_stats['std'].calculate(self.curveContext),
                         numpy.std(yData[2:6]))
        self.assertEqual(_stats['mean'].calculate(self.curveContext),
                         numpy.mean(yData[2:6]))
        com = numpy.sum(xData[2:6] * yData[2:6]) / numpy.sum(yData[2:6])
        self.assertEqual(_stats['com'].calculate(self.curveContext), com)

    def testBasicStatsImageRectRoi(self):
        """Test result for simple stats on an image"""
        self.assertEqual(self.imageContext.values.compressed().size, 121)
        _stats = self.getBasicStats()
        self.assertEqual(_stats['min'].calculate(self.imageContext), 10)
        self.assertEqual(_stats['max'].calculate(self.imageContext), 1300)
        self.assertEqual(_stats['minCoords'].calculate(self.imageContext),
                         (10, 0))
        self.assertEqual(_stats['maxCoords'].calculate(self.imageContext),
                         (20.0, 10.0))
        self.assertAlmostEqual(_stats['std'].calculate(self.imageContext),
                               numpy.std(self.imageData[0:11, 10:21]))
        self.assertAlmostEqual(_stats['mean'].calculate(self.imageContext),
                               numpy.mean(self.imageData[0:11, 10:21]))

        compressed_values = self.imageContext.values.compressed()
        compressed_values = compressed_values.reshape(11, 11)
        yData = numpy.sum(compressed_values.astype(numpy.float64), axis=1)
        xData = numpy.sum(compressed_values.astype(numpy.float64), axis=0)

        dataYRange = range(11)
        dataXRange = range(10, 21)

        ycom = numpy.sum(yData * dataYRange) / numpy.sum(yData)
        xcom = numpy.sum(xData * dataXRange) / numpy.sum(xData)
        self.assertEqual(_stats['com'].calculate(self.imageContext),
                         (xcom, ycom))

    def testBasicStatsImagePolyRoi(self):
        """Test a simple rectangle ROI"""
        _stats = self.getBasicStats()
        self.assertEqual(_stats['min'].calculate(self.imageContext_2), 0)
        self.assertEqual(_stats['max'].calculate(self.imageContext_2), 2432)
        self.assertEqual(_stats['minCoords'].calculate(self.imageContext_2),
                         (0.0, 0.0))
        # not 0.0, 19.0 because not fully in. Should all pixel have a weight,
        # on to manage them in stats. For now 0 if the center is not in, else 1
        self.assertEqual(_stats['maxCoords'].calculate(self.imageContext_2),
                         (0.0, 19.0))

    def testBasicStatsScatter(self):
        self.assertEqual(self.scatterContext.values.compressed().size, 2)
        _stats = self.getBasicStats()
        self.assertEqual(_stats['min'].calculate(self.scatterContext), 6)
        self.assertEqual(_stats['max'].calculate(self.scatterContext), 7)
        self.assertEqual(_stats['minCoords'].calculate(self.scatterContext),
                         (2, 3))
        self.assertEqual(_stats['maxCoords'].calculate(self.scatterContext),
                         (3, 4))
        self.assertEqual(_stats['std'].calculate(self.scatterContext),
                         numpy.std([6, 7]))
        self.assertEqual(_stats['mean'].calculate(self.scatterContext),
                         numpy.mean([6, 7]))

    def testBasicHistogram(self):
        _stats = self.getBasicStats()
        xData = yData = numpy.array(range(2, 6))
        self.assertEqual(_stats['min'].calculate(self.histoContext), 2)
        self.assertEqual(_stats['max'].calculate(self.histoContext), 5)
        self.assertEqual(_stats['minCoords'].calculate(self.histoContext),
                         (2, ))
        self.assertEqual(_stats['maxCoords'].calculate(self.histoContext),
                         (5, ))
        self.assertEqual(_stats['std'].calculate(self.histoContext),
                         numpy.std(yData))
        self.assertEqual(_stats['mean'].calculate(self.histoContext),
                         numpy.mean(yData))
        com = numpy.sum(xData * yData) / numpy.sum(yData)
        self.assertEqual(_stats['com'].calculate(self.histoContext), com)