示例#1
0
    def testGeneral(self):
        # ---------------------
        # pulse-resolved data
        # ---------------------

        data = ProcessedData(1234)

        self.assertEqual(1234, data.tid)
        self.assertEqual(0, data.n_pulses)

        data.image = ImageData.from_array(np.zeros((1, 2, 2)))
        self.assertEqual(1, data.n_pulses)

        data = ProcessedData(1235)
        data.image = ImageData.from_array(np.zeros((3, 2, 2)))
        self.assertEqual(3, data.n_pulses)

        # ---------------------
        # train-resolved data
        # ---------------------

        data = ProcessedData(1236)
        data.image = ImageData.from_array(np.zeros((2, 2)))

        self.assertEqual(1236, data.tid)
        self.assertEqual(1, data.n_pulses)
示例#2
0
    def testInitWithSpecifiedParametersPS(self):
        with self.assertRaises(ValueError):
            ImageData.from_array(np.ones((2, 2, 2)), sliced_indices=[0, 1, 2])

        with self.assertRaises(ValueError):
            ImageData.from_array(np.ones((2, 2, 2)), sliced_indices=[1, 1, 1])

        imgs = np.ones((3, 2, 3))
        imgs[:, 0, :] = 2
        image_mask = np.zeros((2, 3), dtype=np.bool)
        image_mask[::2, ::2] = True
        image_data = ImageData.from_array(imgs,
                                          image_mask=image_mask,
                                          threshold_mask=(0, 1),
                                          poi_indices=[0, 1])

        self.assertEqual(2e-3, image_data.pixel_size)
        self.assertIsInstance(image_data.images, list)
        self.assertEqual(3, image_data.n_images)

        self.assertListEqual([0, 1, 2], image_data.sliced_indices)
        np.testing.assert_array_equal(np.array([[np.nan, np.nan, np.nan], [1., 1., 1.]]),
                                      image_data.images[0])
        np.testing.assert_array_equal(np.array([[np.nan, np.nan, np.nan], [1., 1., 1.]]),
                                      image_data.images[1])
        self.assertIsNone(image_data.images[2])

        np.testing.assert_array_equal(np.array([[2., 2., 2.], [1., 1., 1.]]),
                                      image_data.mean)
        np.testing.assert_array_equal(np.array([[np.nan, np.nan, np.nan], [1., 1., 1.]]),
                                      image_data.masked_mean)

        self.assertIsNone(image_data.gain_mean)
        self.assertIsNone(image_data.offset_mean)
        self.assertEqual((0, 1), image_data.threshold_mask)
示例#3
0
    def processed_data(cls, tid, shape, *,
                       gen='random',
                       dtype=config['SOURCE_PROC_IMAGE_DTYPE'],
                       roi_histogram=False,
                       histogram=False,
                       correlation=False,
                       binning=False,
                       **kwargs):

        processed = ProcessedData(tid)
        imgs = cls._gen_images(gen, shape, dtype)
        processed.image = ImageData.from_array(imgs, **kwargs)

        if roi_histogram:
            pass

        if histogram:
            hist = processed.hist
            hist.hist = np.arange(10)
            hist.bin_centers = np.arange(10) / 100.
            hist.mean, hist.median, hist.std = 1., 0, 0.1

        if correlation:
            pass

        if binning:
            pass

        return processed
示例#4
0
    def testSetImage(self):
        widget = ImageAnalysis()
        item = widget._mask_item

        with self.assertRaisesRegex(TypeError, "ImageData"):
            widget.setImage([1, 2])

        with patch.object(item, "maybeInitializeMask") as init:
            with patch.object(item, "setMask") as set_mask:
                # test set valid data
                image_data = ImageData.from_array(np.ones((2, 10, 10)))
                widget.setImage(image_data)
                np.testing.assert_array_equal(image_data.image_mask_in_modules,
                                              widget._mask_in_modules)
                np.testing.assert_array_equal(image_data.masked_mean,
                                              widget._image)
                init.assert_called_once()
                init.reset_mock()
                set_mask.assert_not_called()

                # test set image with different shape
                with patch(
                        "extra_foam.gui.items.GeometryItem.geometry") as geom:
                    image_data = ImageData.from_array(np.ones((2, 4, 4)))
                    # image_mask_in_modules is None
                    widget.setImage(image_data)
                    geom.output_array_for_position_fast.assert_not_called()
                    geom.position_all_modules.assert_not_called()
                    init.assert_called_once()
                    init.reset_mock()
                    set_mask.assert_not_called()
                    # set image_mask_in_modules
                    image_data = ImageData.from_array(np.ones((2, 8, 8)))
                    image_data.image_mask_in_modules = np.ones((4, 2, 2))
                    widget.setImage(image_data)
                    geom.output_array_for_position_fast.assert_called_once()
                    geom.position_all_modules.assert_called_once()
                    init.assert_called_once()
                    init.reset_mock()
                    set_mask.assert_called_once()

                # test set with image = None
                image_data = ImageData()
                widget.setImage(image_data)
                self.assertIsNone(widget._mask_in_modules)
                self.assertIsNone(widget._image)
                init.assert_not_called()
示例#5
0
    def testInitWithSpecifiedParametersTS(self):
        with self.assertRaises(ValueError):
            ImageData.from_array(np.ones((2, 2)), sliced_indices=[0])

        img = np.array([[2, 1], [1, 1]])
        image_data = ImageData.from_array(img, threshold_mask=(0, 1))

        self.assertEqual([0], image_data.sliced_indices)
        self.assertEqual([None], image_data.images)
        self.assertEqual(1, image_data.n_images)

        np.testing.assert_array_equal(np.array([[2., 1.], [1., 1.]]),
                                      image_data.mean)
        np.testing.assert_array_equal(np.array([[np.nan, 1.], [1., 1.]]),
                                      image_data.masked_mean)

        self.assertEqual((0, 1), image_data.threshold_mask)
示例#6
0
    def testInitWithSpecifiedParameters(self):

        # ---------------------
        # pulse-resolved data
        # ---------------------
        with self.assertRaises(ValueError):
            ImageData.from_array(np.ones((2, 2, 2)), sliced_indices=[0, 1, 2])

        with self.assertRaises(ValueError):
            ImageData.from_array(np.ones((2, 2, 2)), sliced_indices=[1, 1, 1])

        imgs = np.ones((3, 2, 2))
        imgs[:, 0, :] = 2
        image_data = ImageData.from_array(imgs,
                                          threshold_mask=(0, 1),
                                          poi_indices=[0, 1])

        self.assertEqual(2e-3, image_data.pixel_size)
        self.assertIsInstance(image_data.images, list)
        self.assertEqual(3, image_data.n_images)

        self.assertListEqual([0, 1, 2], image_data.sliced_indices)
        np.testing.assert_array_equal(np.array([[2., 2.], [1., 1.]]),
                                      image_data.images[0])
        np.testing.assert_array_equal(np.array([[2., 2.], [1., 1.]]),
                                      image_data.images[1])
        self.assertIsNone(image_data.images[2])

        np.testing.assert_array_equal(np.array([[2., 2.], [1., 1.]]),
                                      image_data.mean)
        np.testing.assert_array_equal(np.array([[0., 0.], [1., 1.]]),
                                      image_data.masked_mean)

        self.assertIsNone(image_data.gain_mean)
        self.assertIsNone(image_data.offset_mean)
        self.assertEqual((0, 1), image_data.threshold_mask)

        # ---------------------
        # train-resolved data
        # ---------------------
        with self.assertRaises(ValueError):
            ImageData.from_array(np.ones((2, 2)), sliced_indices=[0])

        img = np.array([[2, 1], [1, 1]])
        image_data = ImageData.from_array(img, threshold_mask=(0, 1))

        self.assertEqual([0], image_data.sliced_indices)
        self.assertEqual([None], image_data.images)
        self.assertEqual(1, image_data.n_images)

        np.testing.assert_array_equal(np.array([[2., 1.], [1., 1.]]),
                                      image_data.mean)
        np.testing.assert_array_equal(np.array([[0., 1.], [1., 1.]]),
                                      image_data.masked_mean)

        self.assertEqual((0, 1), image_data.threshold_mask)
示例#7
0
    def testFromArray(self):
        with self.assertRaises(TypeError):
            ImageData.from_array()

        with self.assertRaises(ValueError):
            ImageData.from_array(np.ones(2))

        with self.assertRaises(ValueError):
            ImageData.from_array(np.ones((2, 2, 2, 2)))

        image_data = ImageData.from_array(np.ones((2, 2, 3)))
        self.assertEqual((2, 3), image_data.mask.shape)

        image_data = ImageData.from_array(np.ones((3, 2)))
        self.assertEqual((3, 2), image_data.mask.shape)
示例#8
0
    def testFromArray(self):
        with self.assertRaises(TypeError):
            ImageData.from_array()

        with self.assertRaises(ValueError):
            ImageData.from_array(np.ones(2))

        with self.assertRaises(ValueError):
            ImageData.from_array(np.ones((2, 2, 2, 2)))
示例#9
0
    def testBulletinView(self):
        processed = ProcessedData(1357)

        processed.image = ImageData.from_array(np.ones((10, 4, 4), np.float32))
        processed.image.dark_count = 99
        processed.image.n_dark_pulses = 10
        processed.pidx.mask([1, 3, 5, 6])
        self.gui._queue.append(processed)
        self.image_tool.updateWidgetsF()

        view = self.image_tool._bulletin_view
        self.assertEqual(1357, int(view._latest_tid.intValue()))
        self.assertEqual(10, int(view._n_total_pulses.intValue()))
        self.assertEqual(6, int(view._n_kept_pulses.intValue()))
        self.assertEqual(99, int(view._dark_train_counter.intValue()))
        self.assertEqual(10, int(view._n_dark_pulses.intValue()))
示例#10
0
    def processed_data(cls,
                       tid,
                       shape,
                       *,
                       gen='random',
                       dtype=config['SOURCE_PROC_IMAGE_DTYPE'],
                       roi_histogram=False,
                       histogram=False,
                       correlation=False,
                       binning=False,
                       **kwargs):

        processed = ProcessedData(tid)
        imgs = cls._gen_images(gen, shape, dtype)
        processed.image = ImageData.from_array(imgs, **kwargs)

        if roi_histogram:
            pass

        if histogram:
            hist = processed.hist
            hist.hist = np.arange(10)
            hist.bin_centers = np.arange(10) / 100.
            hist.mean, hist.median, hist.std = 1., 0, 0.1

        if correlation:
            corr_resolution = 2
            for i in range(2):
                corr = processed.corr[i]
                if i == 0:
                    data = SimplePairSequence()
                else:
                    data = OneWayAccuPairSequence(corr_resolution)

                for j in range(5):
                    data.append((j, 5 * j))

                corr.x, corr.y = data.data()
                corr.source = f"abc - {i}"
                corr.resolution = 0 if i == 0 else corr_resolution

        if binning:
            pass

        return processed
示例#11
0
    def testBulletinView(self):
        processed = ProcessedData(1357)

        processed.image = ImageData.from_array(np.ones((10, 4, 4), np.float32))
        processed.image.dark_count = 99
        processed.image.n_dark_pulses = 10
        processed.pidx.mask([1, 3, 5, 6])
        self.gui._queue.append(processed)
        self.image_tool.updateWidgetsF()

        view = self.image_tool._bulletin_view
        self.assertEqual(1357, int(view._displayed_tid.intValue()))
        self.assertEqual(10, int(view._n_total_pulses.intValue()))
        self.assertEqual(6, int(view._n_kept_pulses.intValue()))
        self.assertEqual(99, int(view._dark_train_counter.intValue()))
        self.assertEqual(10, int(view._n_dark_pulses.intValue()))

        with patch.object(view._mon, "reset_process_count") as reset:
            view._reset_process_count_btn.clicked.emit()
            reset.assert_called_once()
示例#12
0
    def data_with_assembled(cls, tid, shape, *,
                            src_type=DataSource.BRIDGE,
                            dtype=config['SOURCE_PROC_IMAGE_DTYPE'],
                            gen='random',
                            slicer=None,
                            with_xgm=False,
                            with_digitizer=False,
                            **kwargs):
        imgs = cls._gen_images(gen, shape, dtype)

        processed = ProcessedData(tid)

        processed.image = ImageData.from_array(imgs, **kwargs)

        if imgs.ndim == 2:
            slicer = None
        else:
            slicer = slice(None, None) if slicer is None else slicer

        src_list = [('Foo', 'oof'), ('Bar', 'rab'), ('karaboFAI', 'extra_foam')]
        src_name, key_name = random.choice(src_list)

        catalog = SourceCatalog()
        ctg = 'ABCD'
        src = f'{src_name} {key_name}'
        catalog.add_item(SourceItem(ctg, src_name, [], key_name, slicer, None))
        catalog._main_detector = src

        n_pulses = processed.n_pulses

        if with_xgm:
            # generate XGM data
            processed.pulse.xgm.intensity = np.random.rand(n_pulses)
            processed.xgm.intensity = random.random()
            processed.xgm.x = random.random()
            processed.xgm.y = random.random()

        if with_digitizer:
            # generate digitizer data
            digitizer = processed.pulse.digitizer
            digitizer.ch_normalizer = 'B'
            for ch in digitizer:
                digitizer[ch].pulse_integral = np.random.rand(n_pulses)

        data = {
            'processed': processed,
            'catalog': catalog,
            'meta': {
                src: {
                    'timestamp.tid': tid,
                    'source_type': src_type,
                }
            },
            'raw': {
                src: dict()
            },
            'assembled': {
                'data': imgs,
            }
        }
        if imgs.ndim == 2:
            data['assembled']['sliced'] = imgs
        else:
            data['assembled']['sliced'] = imgs[slicer]

        return data, processed
示例#13
0
    def testSaveLoadImageMask(self, mocked_pub, mocked_set_mask, mocked_open,
                              mocked_save):
        def save_mask_in_file(_fp, arr):
            _fp.seek(0)
            np.save(_fp, arr)
            _fp.seek(0)

        widget = ImageAnalysis()
        fp = tempfile.NamedTemporaryFile(suffix=".npy")
        img = np.arange(100, dtype=np.float).reshape(10, 10)

        # if image_data is None, it does not raise but only logger.error()
        with self.assertLogs(logger, level="ERROR") as cm:
            widget.saveImageMask()
            self.assertEqual('Image mask does not exist without an image!',
                             cm.output[0].split(':')[-1])

        with self.assertLogs(logger, level="ERROR") as cm:
            widget.loadImageMask()
            self.assertEqual(cm.output[0].split(':')[-1],
                             'Cannot load image mask without image!')

        widget.setImage(ImageData.from_array(img))

        # --------------------
        # test failing to save
        # --------------------

        # test saving a mask in modules without geometry
        widget._mask_save_in_modules = True
        with self.assertLogs(logger, level='ERROR') as cm:
            widget.saveImageMask()
            # geometry file is not specified
            self.assertIn('Failed to create geometry to dismantle image mask',
                          cm.output[0])

        # --------------------
        # test fail to load
        # --------------------

        # the IOError
        mocked_open.return_value = ['abc']
        with self.assertLogs(logger, level="ERROR") as cm:
            widget.loadImageMask()
            self.assertIn('Cannot load mask from abc', cm.output[0])

        # test mask data with dimension not equal to 2 or 3
        mocked_open.return_value = [fp.name]
        new_mask = np.ones(3, dtype=bool)
        save_mask_in_file(fp, new_mask)
        with self.assertLogs(logger, level='ERROR') as cm:
            widget.loadImageMask()
            self.assertIn('Expect array with dimensions (2, 3): actual 1',
                          cm.output[0])
            mocked_set_mask.assert_not_called()

        # test loading a mask in modules without geometry
        new_mask = np.ones((3, 3, 3), dtype=bool)
        save_mask_in_file(fp, new_mask)
        with patch("extra_foam.gui.items.GeometryItem._detector",
                   new_callable=PropertyMock,
                   create=True) as mocked:
            with self.assertLogs(logger, level='ERROR') as cm:
                mocked.return_value = "FastCCD"
                widget._require_geometry = False
                widget.loadImageMask()
                self.assertIn(
                    'Only detectors with a geometry can have image mask in modules',
                    cm.output[0])

            with self.assertLogs(logger, level='ERROR') as cm:
                mocked.return_value = "LPD"
                widget._require_geometry = True
                widget.loadImageMask()
                # geometry file is not specified
                self.assertIn(
                    'Failed to create geometry to assemble image mask',
                    cm.output[0])
                mocked_set_mask.assert_not_called()

        # test (assembled) mask shape is different from the image
        new_mask = np.ones((3, 3), dtype=bool)
        save_mask_in_file(fp, new_mask)
        with self.assertLogs(logger, level='ERROR') as cm:
            widget.loadImageMask()
            self.assertIn(
                'Shape of the image mask (3, 3) is different from the image (10, 10)',
                cm.output[0])
            mocked_set_mask.assert_not_called()

        # --------------------
        # test save and load
        # --------------------

        # first save a valid assembled mask
        widget._mask_save_in_modules = False
        mocked_save.return_value = [fp.name]
        with self.assertLogs(logger, level="INFO"):
            widget.saveImageMask()

        # then load
        fp.seek(0)
        with self.assertLogs(logger, level="INFO"):
            widget.loadImageMask()
        mocked_set_mask.assert_called_once()
        mocked_set_mask.reset_mock()

        # save and load another mask
        mask_item = widget._mask_item
        mask_item._mask.setPixelColor(0, 0, mask_item._fill_color)
        mask_item._mask.setPixelColor(5, 5, mask_item._fill_color)
        fp.seek(0)
        widget.saveImageMask()
        fp.seek(0)
        widget.loadImageMask()
        mocked_set_mask.assert_called_once()
        mocked_set_mask.reset_mock()

        # -----------------------------
        # test saving mask in modules
        # -----------------------------
        widget._mask_save_in_modules = True

        def dismantle_side_effect(*args, **kwargs):
            raise ValueError

        with patch("extra_foam.gui.items.GeometryItem.geometry") as geom:
            mask_in_modules = np.ones_like((3, 3, 3), dtype=bool)
            geom.output_array_for_dismantle_fast.return_value = mask_in_modules
            widget.saveImageMask()
            geom.output_array_for_dismantle_fast.assert_called_once()
            geom.dismantle_all_modules.assert_called_once()

            geom.dismantle_all_modules.side_effect = dismantle_side_effect
            with self.assertLogs(logger, level='ERROR') as cm:
                widget.saveImageMask()
                self.assertIn("Geometry does not match the assembled image",
                              cm.output[0])

        # -----------------------------
        # test loading mask in modules
        # -----------------------------

        new_mask = np.ones((3, 3, 3), dtype=bool)
        save_mask_in_file(fp, new_mask)
        fp.seek(0)
        with patch("extra_foam.gui.items.GeometryItem.geometry") as geom:
            assembled_mask = np.ones_like(img, dtype=bool)
            geom.output_array_for_position_fast.return_value = assembled_mask
            widget.loadImageMask()
            geom.output_array_for_position_fast.assert_called_once()
            geom.position_all_modules.assert_called_once()
            mocked_set_mask.assert_called_once_with(assembled_mask)

        fp.close()