Ejemplo n.º 1
0
    def test_get_instance_stream(self):
        instance_manager = get_test_pipeline_manager_with_real_cam()
        instance_manager.stop_all_instances()

        self.assertTrue(
            len(instance_manager.get_info()["active_instances"]) == 0,
            "There should be no running instances.")

        pipeline_id = "test_pipeline"
        pipeline_config = PipelineConfig(
            pipeline_id, parameters={"camera_name": "simulation"})

        instance_manager.config_manager.save_pipeline_config(
            pipeline_id, pipeline_config.get_configuration())
        instance_stream_1 = instance_manager.get_instance_stream(pipeline_id)

        self.assertTrue(
            instance_manager.get_info()["active_instances"][pipeline_id]
            ["read_only"], "Instance should be read only.")

        with self.assertRaisesRegex(
                ValueError, "Cannot set config on a read only instance."):
            instance_manager.get_instance(pipeline_id).set_parameter({})

        instance_stream_2 = instance_manager.get_instance_stream(pipeline_id)

        self.assertEqual(instance_stream_1, instance_stream_2,
                         "Only one instance should be present.")

        instance_manager.stop_all_instances()
    def test_both_rois(self):
        pipeline_config = PipelineConfig("test_pipeline")

        simulated_camera = CameraSimulation(CameraConfig("simulation"))
        image = simulated_camera.get_image()
        x_axis, y_axis = simulated_camera.get_x_y_axis()
        parameters = pipeline_config.get_configuration()
        camera_name = simulated_camera.get_name()

        parameters["roi_signal"] = [0, 200, 0, 200]
        parameters["roi_background"] = [0, 200, 0, 200]

        for i in range(10):
            result = process_image(image=image,
                                   pulse_id=i,
                                   timestamp=time.time(),
                                   x_axis=x_axis,
                                   y_axis=y_axis,
                                   parameters=parameters)

        required_fields_in_result = [
            camera_name + ".processing_parameters",
            camera_name + '.roi_signal_x_profile',
            # camera_name + '.edge_position',
            # camera_name + '.cross_correlation_amplitude',
            camera_name + '.roi_background_x_profile'
        ]

        self.assertSetEqual(set(required_fields_in_result), set(result.keys()),
                            "Not all required keys are present in the result")
Ejemplo n.º 3
0
    def test_noop_pipeline(self):
        pipeline_config = PipelineConfig("test_pipeline")

        simulated_camera = CameraSimulation(CameraConfig("simulation"))
        image = simulated_camera.get_image()
        x_axis, y_axis = simulated_camera.get_x_y_axis()
        parameters = pipeline_config.get_configuration()

        result = process_image(image=image,
                               timestamp=time.time(),
                               x_axis=x_axis,
                               y_axis=y_axis,
                               parameters=parameters)

        required_fields_in_result = ['x_center_of_mass', 'x_axis', 'y_axis', 'x_profile', 'y_fit_standard_deviation',
                                     'y_rms', 'timestamp', 'y_profile', 'image', 'max_value', 'x_fit_offset',
                                     'x_fit_gauss_function', 'y_center_of_mass', 'min_value', 'y_fit_mean',
                                     'x_fit_mean', 'x_rms', 'y_fit_amplitude', 'x_fit_amplitude',
                                     'y_fit_gauss_function', 'x_fit_standard_deviation', 'y_fit_offset',
                                     "processing_parameters", "intensity"]

        self.assertSetEqual(set(required_fields_in_result), set(result.keys()),
                            "Not all required keys are present in the result")

        self.assertTrue(numpy.array_equal(result["image"], image),
                        "The input and output image are not the same, but the pipeline should not change it.")

        self.assertDictEqual(parameters, json.loads(result["processing_parameters"]),
                             "The passed and the received processing parameters are not the same.")
    def test_background_roi(self):
        pipeline_config = PipelineConfig("test_pipeline")

        simulated_camera = CameraSimulation(CameraConfig("simulation"))
        image = simulated_camera.get_image()
        x_axis, y_axis = simulated_camera.get_x_y_axis()
        parameters = pipeline_config.get_configuration()
        camera_name = simulated_camera.get_name()

        parameters["roi_background"] = [0, 200, 0, 200]

        result = process_image(image=image,
                               pulse_id=0,
                               timestamp=time.time(),
                               x_axis=x_axis,
                               y_axis=y_axis,
                               parameters=parameters)

        required_fields_in_result = [
            camera_name + ".processing_parameters",
            camera_name + '.roi_background_x_profile'
        ]

        self.assertSetEqual(set(required_fields_in_result), set(result.keys()),
                            "Not all required keys are present in the result")
Ejemplo n.º 5
0
    def test_collect_background(self):
        instance_manager = get_test_pipeline_manager_with_real_cam()
        instance_manager.background_manager = BackgroundImageManager(
            self.background_folder)

        pipeline_id = "test_pipeline"
        number_of_images = 10

        pipeline_config = PipelineConfig(
            pipeline_id, parameters={"camera_name": "simulation"})

        instance_manager.config_manager.save_pipeline_config(
            pipeline_id, pipeline_config.get_configuration())

        pipeline_stream_address = instance_manager.get_instance_stream(
            pipeline_id)
        pipeline_host, pipeline_port = get_host_port_from_stream_address(
            pipeline_stream_address)

        # Collect from the pipeline.
        with source(host=pipeline_host, port=pipeline_port,
                    mode=SUB) as stream:
            data = stream.receive()
            self.assertIsNotNone(data,
                                 "This should really not happen anymore.")

        camera_name = instance_manager.get_instance(
            pipeline_id).get_info()["camera_name"]
        background_id = instance_manager.collect_background(
            camera_name, number_of_images)

        self.assertTrue(background_id.startswith("simulation"),
                        "Background id not as expected.")

        host, port = get_host_port_from_stream_address(
            instance_manager.cam_server_client.get_instance_stream(
                "simulation"))

        # Collect from the camera.
        with source(host=host, port=port, mode=SUB) as stream:
            data = stream.receive()
            self.assertIsNotNone(data,
                                 "This should really not happen anymore.")

        self.assertEqual(
            instance_manager.background_manager.get_background(
                background_id).shape, data.data.data["image"].value.shape,
            "Background and image have to be of the same shape.")

        self.assertEqual(
            instance_manager.background_manager.get_background(
                background_id).dtype, data.data.data["image"].value.dtype,
            "Background and image have to be of the same dtype.")

        instance_manager.stop_all_instances()
    def test_invalid_pipeline_type(self):
        configuration = {"camera_name": "simulation"}
        expanded_configuration = PipelineConfig.expand_config(configuration)
        PipelineConfig.validate_pipeline_config(expanded_configuration)

        expanded_configuration["pipeline_type"] = "invalid"

        with self.assertRaisesRegex(
                ValueError,
                "pipeline_type 'invalid' not present in mapping. Available:"):
            PipelineConfig.validate_pipeline_config(expanded_configuration)
    def test_invalid_number_of_slices(self):
        configuration = {
            "camera_name": "simulation",
            "image_slices": {
                "number_of_slices": 1.2
            }
        }

        expanded_configuration = PipelineConfig.expand_config(configuration)
        with self.assertRaisesRegex(ValueError,
                                    "number_of_slices must be an integer"):
            PipelineConfig.validate_pipeline_config(expanded_configuration)
Ejemplo n.º 8
0
    def test_wrong_background_size(self):
        pipeline_parameters = {
            "camera_name": "simulation",
            "image_background": "white_background"
        }

        simulated_camera = CameraSimulation(CameraConfig("simulation"))
        image = simulated_camera.get_image()
        x_axis, y_axis = simulated_camera.get_x_y_axis()

        background_provider = MockBackgroundManager()

        # Invalid background size.
        background_provider.save_background("white_background", numpy.zeros(shape=(100, 100)),
                                            append_timestamp=False)

        parameters = PipelineConfig("test_pipeline", pipeline_parameters).get_configuration()
        image_background_array = background_provider.get_background("white_background")

        with self.assertRaisesRegex(RuntimeError, "Invalid background_image size "):
            process_image(image=image,
                          timestamp=time.time(),
                          x_axis=x_axis,
                          y_axis=y_axis,
                          parameters=parameters,
                          image_background_array=image_background_array)
    def test_store_pipeline_with_simulated_camera(self):
        manager = multiprocessing.Manager()
        stop_event = multiprocessing.Event()
        statistics = manager.Namespace()
        parameter_queue = multiprocessing.Queue()

        self.client.stop_all_instances()

        pipeline_config = PipelineConfig("test_pipeline")

        def send():
            store_pipeline(stop_event, statistics, parameter_queue,
                           self.client, pipeline_config, 12003,
                           MockBackgroundManager())

        thread = Thread(target=send)
        thread.start()

        sleep(0.5)

        with source(host="127.0.0.1",
                    port=12003,
                    mode=PULL,
                    receive_timeout=3000) as stream:
            data = stream.receive()
            self.assertIsNotNone(data, "Receiving timeout.")

            required_keys = set(["simulation" + config.EPICS_PV_SUFFIX_IMAGE])

            self.assertSetEqual(
                required_keys, set(data.data.data.keys()),
                "Missing required keys in pipeline output bsread message.")

        stop_event.set()
        thread.join()
Ejemplo n.º 10
0
    def create_pipeline(self, pipeline_name=None, configuration=None, instance_id=None):

        """
        Create the pipeline stream address. Either pass the pipeline name, or the configuration.
        :param pipeline_name: Name of the pipeline to load from config.
        :param configuration: Configuration to load the pipeline with.
        :param instance_id: Name to assign to the instace. It must be unique.
        :return: instance_id, Pipeline stream address.
        """

        # User specified or random uuid as the instance id.
        if not instance_id:
            instance_id = str(uuid.uuid4())

        if self.is_instance_present(instance_id):
            raise ValueError("Instance with id '%s' is already present and running. "
                             "Use another instance_id or stop the current instance "
                             "if you want to reuse the same instance_id." % instance_id)

        if (not pipeline_name) and (not configuration):
            raise ValueError("You must specify either the pipeline name or the configuration for the pipeline.")

        if pipeline_name:
            pipeline_config = self.config_manager.load_pipeline(pipeline_name)
            if configuration is not None:
                pipeline_config.update( configuration )
        else:
            pipeline_config = PipelineConfig(instance_id, configuration)

        self._create_and_start_pipeline(instance_id, pipeline_config, read_only_pipeline=False)

        pipeline_instance = self.get_instance(instance_id)

        return pipeline_instance.get_instance_id(), pipeline_instance.get_stream_address()
    def test_expand_pipeline_config(self):
        configuration = {
            "camera_name": "simulation",
            "image_slices": {
                "number_of_slices": None,
                "scale": 7
            }
        }

        expanded_configuration = PipelineConfig.expand_config(configuration)
        self.assertEqual(
            expanded_configuration["image_slices"]["number_of_slices"],
            PipelineConfig.DEFAULT_IMAGE_SLICES["number_of_slices"],
            "Default not applied.")

        self.assertEqual(expanded_configuration["pipeline_type"],
                         PipelineConfig.DEFAULT_CONFIGURATION["pipeline_type"],
                         "Default not applied.")

        configuration = {"camera_name": "simulation", "image_slices": None}

        expanded_configuration = PipelineConfig.expand_config(configuration)

        self.assertIsNone(expanded_configuration["image_slices"],
                          "It should still be None.")

        configuration = {"camera_name": "simulation", "image_slices": {}}

        expanded_configuration = PipelineConfig.expand_config(configuration)

        self.assertDictEqual(expanded_configuration["image_slices"],
                             PipelineConfig.DEFAULT_IMAGE_SLICES,
                             "Image slices defaults not applied.")

        configuration = {
            "camera_name": "simulation",
            "image_background_enable": None
        }

        expanded_configuration = PipelineConfig.expand_config(configuration)

        self.assertEqual(
            expanded_configuration["image_background_enable"],
            PipelineConfig.DEFAULT_CONFIGURATION["image_background_enable"],
            "Default value not applied. It should not be None.")
Ejemplo n.º 12
0
        def run_the_pipeline(configuration, simulated_image=None):
            parameters = PipelineConfig("test_pipeline", configuration).get_configuration()

            simulated_camera = CameraSimulation(CameraConfig("simulation"))

            if simulated_image is None:
                simulated_image = simulated_camera.get_image()

            x_axis, y_axis = simulated_camera.get_x_y_axis()

            return process_image(image=simulated_image, timestamp=time.time(), x_axis=x_axis, y_axis=y_axis,
                                 parameters=parameters)
    def test_default_config(self):
        configuration = {
            "camera_name": "simulation",
            "image_background": "test_background",
            "image_good_region": {}
        }

        configuration = PipelineConfig("test", configuration)
        complete_config = configuration.get_configuration()

        self.assertIsNone(complete_config["image_slices"],
                          "This section should be None.")

        self.assertSetEqual(set(complete_config["image_good_region"].keys()),
                            set(["threshold", "gfscale"]))

        configuration = {
            "camera_name": "simulation",
            "image_good_region": {},
            "image_slices": {}
        }

        configuration = PipelineConfig("test", configuration)
        complete_config = configuration.get_configuration()

        self.assertSetEqual(set(complete_config["image_good_region"].keys()),
                            set(["threshold", "gfscale"]),
                            "Missing keys in camera calibration.")

        self.assertSetEqual(set(complete_config["image_slices"].keys()),
                            set(["number_of_slices", "scale", "orientation"]),
                            "Missing keys in camera calibration.")
Ejemplo n.º 14
0
    def test_image_threshold(self):
        simulated_camera = get_simulated_camera()
        image = simulated_camera.get_image()
        x_axis, y_axis = simulated_camera.get_x_y_axis()
        x_size, y_size = simulated_camera.get_geometry()

        pipeline_parameters = {
            "camera_name": "simulation",
            "image_threshold": 9999999
        }

        pipeline_config = PipelineConfig("test_pipeline", pipeline_parameters)
        parameters = pipeline_config.get_configuration()

        result = process_image(image, 0, time.time(), x_axis, y_axis,
                               parameters)

        expected_image = numpy.zeros(shape=(y_size, x_size), dtype="uint16")
        self.assertTrue(numpy.array_equal(result["image"], expected_image),
                        "An image of zeros should have been produced.")

        pipeline_parameters = {
            "camera_name": "simulation",
            "image_threshold": 0
        }

        pipeline_config = PipelineConfig("test_pipeline", pipeline_parameters)
        parameters = pipeline_config.get_configuration()

        result = process_image(image, 0, time.time(), x_axis, y_axis,
                               parameters)

        self.assertTrue(numpy.array_equal(result["image"], image),
                        "The image should be the same as the original image.")
Ejemplo n.º 15
0
    def create_pipeline(self, pipeline_name=None, configuration=None, instance_id=None):
        """
        If both pipeline_name and configuration are set, pipeline is create from name and
        configuration field added as additional config parameters
        """
        status = self.get_status()

        if (not pipeline_name) and (not configuration):
            raise ValueError("You must specify either the pipeline name or the configuration for the pipeline.")

        if pipeline_name is not None:
            cfg = self.config_manager.get_pipeline_config(pipeline_name)
        elif configuration is not None:
            cfg = PipelineConfig.expand_config(configuration)
            PipelineConfig.validate_pipeline_config(cfg)

        server,port = None,None
        if instance_id is not None:
            server = self.get_server(instance_id, status)
        if server is None:
            (server,port) = self.get_server_for_pipeline(pipeline_name, cfg, status)
            if port:
                if not configuration:
                    configuration = {}
                configuration["port"] = port

        self._check_background(server, cfg)
        self._check_script(server, cfg)
        if pipeline_name is not None:
            server.save_pipeline_config(pipeline_name, cfg)
            _logger.info("Creating stream from name %s at %s" % (pipeline_name, server.get_address()))
            instance_id, stream_address = server.create_instance_from_name(pipeline_name, instance_id, configuration)
        elif cfg is not None:
            _logger.info("Creating stream from config to camera %s at %s" % (str(cfg.get("camera_name")), server.get_address()))
            instance_id, stream_address = server.create_instance_from_config(cfg, instance_id)
        else:
            raise Exception("Invalid parameters")

        return instance_id, stream_address
Ejemplo n.º 16
0
    def test_image_background(self):
        pipeline_parameters = {
            "camera_name": "simulation",
            "image_background": "white_background"
        }

        simulated_camera = CameraSimulation(CameraConfig("simulation"))
        image = simulated_camera.get_image()
        x_axis, y_axis = simulated_camera.get_x_y_axis()

        background_provider = MockBackgroundManager()
        x_size, y_size = simulated_camera.get_geometry()
        background_provider.save_background("white_background", numpy.zeros(shape=(y_size, x_size)),
                                            append_timestamp=False)

        pipeline_config = PipelineConfig("test_pipeline", pipeline_parameters)
        parameters = pipeline_config.get_configuration()
        image_background_array = background_provider.get_background(parameters.get("image_background"))

        result = process_image(image=image,
                               timestamp=time.time(),
                               x_axis=x_axis,
                               y_axis=y_axis,
                               parameters=parameters,
                               image_background_array=image_background_array)

        self.assertTrue(numpy.array_equal(result["image"], image),
                        "A zero background should not change the image.")

        max_value_in_image = result["max_value"]

        pipeline_parameters = {
            "camera_name": "simulation",
            "image_background": "max_background",
            "image_threshold": 0
        }

        max_background = numpy.zeros(shape=(y_size, x_size), dtype="uint16")
        max_background.fill(max_value_in_image)
        background_provider.save_background("max_background", max_background, append_timestamp=False)

        pipeline_config = PipelineConfig("test_pipeline", pipeline_parameters)
        parameters = pipeline_config.get_configuration()
        image_background_array = background_provider.get_background(parameters.get("image_background"))

        expected_image = numpy.zeros(shape=(y_size, x_size))

        result = process_image(image=image,
                               timestamp=time.time(),
                               x_axis=x_axis,
                               y_axis=y_axis,
                               parameters=parameters,
                               image_background_array=image_background_array)

        self.assertTrue(numpy.array_equal(result["image"], expected_image),
                        "The image should be all zeros - negative numbers are not allowed.")
Ejemplo n.º 17
0
    def test_pipeline_background_manager(self):
        manager = multiprocessing.Manager()
        stop_event = multiprocessing.Event()
        statistics = manager.Namespace()
        parameter_queue = multiprocessing.Queue()

        pipeline_config = PipelineConfig("test_pipeline",
                                         parameters={
                                             "camera_name": "simulation",
                                             "image_background":
                                             "full_background",
                                             "image_background_enable": True,
                                             "image_threshold": 0
                                         })

        background_manager = MockBackgroundManager()

        with self.assertRaises(Exception):
            processing_pipeline(stop_event, statistics, parameter_queue,
                                self.client, pipeline_config, 12000,
                                background_manager)

        simulated_camera_shape = (960, 1280)

        background_array = numpy.zeros(shape=simulated_camera_shape)
        background_array.fill(99999)
        background_manager.save_background("full_background",
                                           background_array,
                                           append_timestamp=False)

        def send():
            processing_pipeline(stop_event, statistics, parameter_queue,
                                self.client, pipeline_config, 12000,
                                background_manager)

        thread = Thread(target=send)
        thread.start()

        with source(host="127.0.0.1", port=12000, mode=SUB) as stream:
            data = stream.receive()

            self.assertIsNotNone(data, "Received None message.")
            self.assertTrue(
                numpy.array_equal(data.data.data["image"].value,
                                  numpy.zeros(shape=simulated_camera_shape)))

        stop_event.set()
        thread.join()
Ejemplo n.º 18
0
    def get_instance_stream_from_config(self, configuration):
        pipeline_config = PipelineConfig(None, parameters=configuration)

        instance_id = self._find_instance_id_with_config(pipeline_config)
        if self.is_instance_present(instance_id):
            return instance_id, self.get_instance(instance_id).get_stream_address()
        else:
            # If the instance is not present, it was deleted because it was stopped.
            instance_id = None

        if instance_id is None:
            instance_id = str(uuid.uuid4())

        self._create_and_start_pipeline(instance_id, pipeline_config, read_only_pipeline=True)

        return instance_id, self.get_instance(instance_id).get_stream_address()
Ejemplo n.º 19
0
    def test_intensity(self):
        simulated_camera = get_simulated_camera()
        image = simulated_camera.get_image()
        x_axis, y_axis = simulated_camera.get_x_y_axis()

        parameters = PipelineConfig("test_pipeline", {
            "camera_name": "simulation"
        }).get_configuration()

        result = process_image(image, 0, time.time(), x_axis, y_axis,
                               parameters)

        x_sum = result["x_profile"].sum()
        y_sum = result["y_profile"].sum()

        # The sums of X and Y profile should always give us the same result as the intensity.
        self.assertAlmostEqual(x_sum, result["intensity"], delta=10000)
        self.assertAlmostEqual(y_sum, result["intensity"], delta=10000)
    def test_system_exit(self):
        manager = multiprocessing.Manager()
        stop_event = multiprocessing.Event()
        statistics = manager.Namespace()
        parameter_queue = multiprocessing.Queue()
        pipeline_config = PipelineConfig("test_pipeline",
                                         parameters={
                                             "camera_name": "simulation",
                                             "image_background":
                                             "full_background",
                                             "image_background_enable": True,
                                             "image_threshold": 0
                                         })

        background_manager = MockBackgroundManager()

        with self.assertRaises(SystemExit):
            processing_pipeline(stop_event, statistics, parameter_queue,
                                self.client, pipeline_config, 12001,
                                background_manager)
Ejemplo n.º 21
0
    def test_profiles(self):
        height = 10
        width = 10

        square_start = 4
        square_end = 6
        n_pixels = square_end - square_start
        pixel_value = 10000

        image = numpy.zeros((height, width), dtype="uint16")
        x_axis = numpy.linspace(0, width - 1, width, dtype='f')
        y_axis = numpy.linspace(0, height - 1, height, dtype='f')

        parameters = PipelineConfig("test_pipeline", {
            "camera_name": "simulation"
        }).get_configuration()

        # Add signal in the center
        image[square_start:square_end, square_start:square_end] = 10000

        result = process_image(image, 0, time.time(), x_axis, y_axis,
                               parameters)

        x_profile = result["x_profile"]
        y_profile = result["y_profile"]

        numpy.testing.assert_array_equal(x_profile[0:square_start],
                                         numpy.zeros(shape=square_start))
        numpy.testing.assert_array_equal(
            x_profile[square_start:square_end],
            numpy.zeros(shape=n_pixels) + (n_pixels * pixel_value))
        numpy.testing.assert_array_equal(x_profile[square_end],
                                         numpy.zeros(shape=width - square_end))

        numpy.testing.assert_array_equal(y_profile[0:square_start],
                                         numpy.zeros(shape=square_start))
        numpy.testing.assert_array_equal(
            y_profile[square_start:square_end],
            numpy.zeros(shape=n_pixels) + (n_pixels * pixel_value))
        numpy.testing.assert_array_equal(
            y_profile[square_end], numpy.zeros(shape=height - square_end))
    def test_pipeline_with_simulation_camera(self):
        manager = multiprocessing.Manager()
        stop_event = multiprocessing.Event()
        statistics = manager.Namespace()
        parameter_queue = multiprocessing.Queue()

        pipeline_config = PipelineConfig("test_pipeline")

        def send():
            processing_pipeline(stop_event, statistics, parameter_queue,
                                self.client, pipeline_config, 12000,
                                MockBackgroundManager())

        thread = Thread(target=send)
        thread.start()

        with source(host="127.0.0.1",
                    port=12000,
                    mode=SUB,
                    receive_timeout=3000) as stream:
            data = stream.receive()
            self.assertIsNotNone(data, "Received None message.")

            required_keys = set([
                'x_fit_standard_deviation', 'x_axis',
                'y_fit_standard_deviation', 'x_center_of_mass',
                'x_fit_amplitude', 'y_fit_mean', 'processing_parameters',
                'timestamp', 'y_fit_gauss_function', 'y_profile',
                'y_center_of_mass', 'x_fit_gauss_function', 'x_rms', 'y_rms',
                'y_fit_amplitude', 'image', 'y_axis', 'min_value',
                'x_fit_mean', 'max_value', 'x_fit_offset', 'x_profile',
                'y_fit_offset', 'width', 'height', 'intensity', "x_fwhm",
                "y_fwhm"
            ])

            self.assertSetEqual(
                required_keys, set(data.data.data.keys()),
                "Missing required keys in pipeline output bsread message.")

        stop_event.set()
        thread.join()
    def test_transparent_pipeline(self):
        manager = multiprocessing.Manager()
        stop_event = multiprocessing.Event()
        statistics = manager.Namespace()
        parameter_queue = multiprocessing.Queue()

        pipeline_config = PipelineConfig("test_pipeline",
                                         parameters={
                                             "camera_name": "simulation",
                                             "function": "transparent"
                                         })

        def send():
            processing_pipeline(stop_event, statistics, parameter_queue,
                                self.client, pipeline_config, 12004,
                                MockBackgroundManager())

        thread = Thread(target=send)
        thread.start()

        with source(host="127.0.0.1",
                    port=12004,
                    mode=SUB,
                    receive_timeout=3000) as stream:
            data = stream.receive()
            self.assertIsNotNone(data, "Received None message.")

            required_keys = set([
                "image", "timestamp", "width", "height", "x_axis", "y_axis",
                "processing_parameters"
            ])

            self.assertSetEqual(
                required_keys, set(data.data.data.keys()),
                "Missing required keys in pipeline output bsread message.")

        stop_event.set()
        thread.join(5.0)
Ejemplo n.º 24
0
    def test_region_of_interest_default_values(self):

        simulated_camera = CameraSimulation(CameraConfig("simulation"))
        image = simulated_camera.get_image()
        x_axis, y_axis = simulated_camera.get_x_y_axis()

        parameters = PipelineConfig("test_pipeline", {
            "camera_name": "simulation"
        }).get_configuration()

        good_region_keys = set(["good_region", "gr_x_axis", "gr_y_axis", "gr_x_fit_gauss_function", "gr_x_fit_offset",
                                "gr_x_fit_amplitude", "gr_x_fit_standard_deviation", "gr_x_fit_mean",
                                "gr_y_fit_gauss_function", "gr_y_fit_offset", "gr_y_fit_amplitude",
                                "gr_y_fit_standard_deviation", "gr_y_fit_mean", "gr_intensity",
                                "gr_x_profile", "gr_y_profile"])

        slices_key_formats = set(["slice_%s_center_x", "slice_%s_center_y", "slice_%s_standard_deviation",
                                  "slice_%s_intensity"])

        result = process_image(image=image,
                               timestamp=time.time(),
                               x_axis=x_axis,
                               y_axis=y_axis,
                               parameters=parameters)

        self.assertFalse(any((x in result for x in good_region_keys)), 'There should not be good region keys.')

        parameters = PipelineConfig("test_pipeline", {
            "camera_name": "simulation",
            "image_good_region": {
                "threshold": 99999
            }
        }).get_configuration()

        result = process_image(image=image,
                               timestamp=time.time(),
                               x_axis=x_axis,
                               y_axis=y_axis,
                               parameters=parameters)

        self.assertTrue(all((x in result for x in good_region_keys)), 'There should be good region keys.')
        self.assertTrue(all((result[x] is None for x in good_region_keys)), 'All values should be None.')

        number_of_slices = 7

        parameters = PipelineConfig("test_pipeline", {
            "camera_name": "simulation",
            "image_good_region": {
                "threshold": 99999
            },
            "image_slices": {
                "number_of_slices": number_of_slices
            }
        }).get_configuration()

        result = process_image(image=image,
                               timestamp=time.time(),
                               x_axis=x_axis,
                               y_axis=y_axis,
                               parameters=parameters)

        self.assertTrue(all((x in result for x in good_region_keys)), 'There should be good region keys.')
        self.assertTrue(all((x in result for x in (x % counter
                                                   for x in slices_key_formats
                                                   for counter in range(number_of_slices)))))
# Stream configuration. cam_server uses PUB for the output stream.
output_stream_port = 9999
output_stream_mode = PUB
# output_stream_mode = PUSH

simulated_camera = CameraSimulation(camera_config=CameraConfig("simulation"),
                                    size_x=image_size_x, size_y=image_size_y)
x_axis, y_axis = simulated_camera.get_x_y_axis()
x_size, y_size = simulated_camera.get_geometry()

# Documentation: https://github.com/datastreaming/cam_server#pipeline_configuration
pipeline_parameters = {
    "camera_name": "simulation"
}

pipeline_config = PipelineConfig("test_pipeline", pipeline_parameters)
parameters = pipeline_config.get_configuration()

image_number = 0

with sender(port=output_stream_port, mode=output_stream_mode) as output_stream:
    # Get simulated image.
    image = simulated_camera.get_image()

    # Generate timestamp.
    timestamp = time.time()

    # Pass data to processing pipeline.
    processed_data = process_image(image, 0, timestamp, x_axis, y_axis, pipeline_parameters)

    # Set height and width.
    def test_update_pipeline_config(self):
        configuration = {"camera_name": "simulation"}

        old_config = PipelineConfig("test", configuration).get_configuration()

        config_updates = {"image_good_region": {}}
        updated_config = update_pipeline_config(old_config, config_updates)

        self.assertIsNotNone(updated_config["image_good_region"])

        configuration = {
            "camera_name": "simulation",
            "image_slices": {
                "number_of_slices": 98
            }
        }

        old_config = PipelineConfig("test", configuration).get_configuration()

        config_updates = {"image_slices": {"scale": 99}}

        updated_config = update_pipeline_config(old_config, config_updates)
        self.assertEqual(updated_config["image_slices"]["scale"], 99,
                         "New value not updated.")
        self.assertEqual(updated_config["image_slices"]["number_of_slices"],
                         98, "Old value changed.")

        configuration = {
            "camera_name": "name 1",
            "image_background": "test",
            "image_threshold": 1,
            "image_region_of_interest": [0, 1, 2, 3],
            "image_good_region": {
                "threshold": 0.3,
                "gfscale": 1.8
            },
            "image_slices": {
                "number_of_slices": 1,
                "scale": 2
            }
        }

        old_config = PipelineConfig("test", configuration).get_configuration()

        config_updates = {
            "camera_name": "name 2",
            "image_background_enable": True,
            "image_background": "test_2",
            "image_threshold": 2,
            "image_region_of_interest": [3, 4, 5, 6],
            "image_good_region": {
                "threshold": 0.9,
                "gfscale": 3.6
            },
            "image_slices": {
                "number_of_slices": 6,
                "scale": 7
            },
            "pipeline_type": "processing"
        }

        updated_config = update_pipeline_config(old_config, config_updates)

        self.assertDictEqual(updated_config["image_good_region"],
                             config_updates["image_good_region"],
                             "Everything was not updated properly.")

        self.assertDictEqual(updated_config["image_slices"],
                             config_updates["image_slices"],
                             "Everything was not updated properly.")

        self.assertDictEqual(updated_config, config_updates,
                             "Everything was not updated properly.")

        # Try removing element by element from the config - negative update.

        updated_config = update_pipeline_config(updated_config,
                                                {"camera_name": None})
        self.assertEqual(updated_config["camera_name"], None)

        updated_config = update_pipeline_config(updated_config,
                                                {"image_background": None})
        self.assertEqual(updated_config["image_background"], None)

        updated_config = update_pipeline_config(
            updated_config, {"image_region_of_interest": None})
        self.assertEqual(updated_config["image_region_of_interest"], None)

        updated_config = update_pipeline_config(
            updated_config, {"image_good_region": {
                "threshold": None
            }})
        self.assertEqual(updated_config["image_good_region"]["threshold"],
                         None)
        self.assertEqual(updated_config["image_good_region"]["gfscale"], 3.6)

        updated_config = update_pipeline_config(updated_config,
                                                {"image_good_region": None})
        self.assertEqual(updated_config["image_good_region"], None)

        updated_config = update_pipeline_config(
            updated_config, {"image_slices": {
                "number_of_slices": None
            }})
        self.assertEqual(updated_config["image_slices"]["number_of_slices"],
                         None)
        self.assertEqual(updated_config["image_slices"]["scale"], 7)

        updated_config = update_pipeline_config(updated_config,
                                                {"image_slices": None})
        self.assertEqual(updated_config["image_slices"], None)

        updated_config = update_pipeline_config(updated_config,
                                                {"image_threshold": None})
        self.assertEqual(updated_config["image_threshold"], None)

        updated_config = update_pipeline_config(
            updated_config, {"image_background_enable": None})
        self.assertEqual(updated_config["image_background_enable"], None)

        updated_config = update_pipeline_config(updated_config,
                                                {"pipeline_type": None})
        self.assertEqual(updated_config["pipeline_type"], None)

        self.assertTrue(all(value is None
                            for value in updated_config.values()))
    def test_store_pipeline_port_requirement(self):
        configuration = {"camera_name": "simulation", "pipeline_type": "store"}
        expanded_configuration = PipelineConfig.expand_config(configuration)

        with self.assertRaisesRegex(ValueError, "stream_port"):
            PipelineConfig.validate_pipeline_config(expanded_configuration)

        configuration = {
            "camera_name": "simulation",
            "pipeline_type": "store",
            "stream_port": "test"
        }
        expanded_configuration = PipelineConfig.expand_config(configuration)

        with self.assertRaisesRegex(ValueError, "must be an integer"):
            PipelineConfig.validate_pipeline_config(expanded_configuration)

        configuration = {
            "camera_name": "simulation",
            "pipeline_type": "store",
            "stream_port": config.PIPELINE_STREAM_PORT_RANGE[0]
        }
        expanded_configuration = PipelineConfig.expand_config(configuration)

        with self.assertRaisesRegex(ValueError, "must be outside of"):
            PipelineConfig.validate_pipeline_config(expanded_configuration)

        configuration = {
            "camera_name": "simulation",
            "pipeline_type": "store",
            "stream_port": config.PIPELINE_STREAM_PORT_RANGE[1] + 1
        }
        expanded_configuration = PipelineConfig.expand_config(configuration)
        PipelineConfig.validate_pipeline_config(expanded_configuration)
    def test_rotate_camera(self):
        manager = multiprocessing.Manager()
        stop_event = multiprocessing.Event()
        statistics = manager.Namespace()
        parameter_queue = multiprocessing.Queue()

        self.client.set_camera_config(
            "simulation_temp", self.client.get_camera_config("simulation"))

        pipeline_config = PipelineConfig(
            "test_pipeline", parameters={"camera_name": "simulation_temp"})

        background_manager = MockBackgroundManager()

        x_size, y_size = get_simulated_camera().get_geometry()
        simulated_camera_shape = (y_size, x_size)

        def send():
            processing_pipeline(stop_event, statistics, parameter_queue,
                                self.client, pipeline_config, 12002,
                                background_manager)

        thread = Thread(target=send)
        thread.start()

        with source(host="127.0.0.1",
                    port=12002,
                    mode=SUB,
                    receive_timeout=3000) as stream:
            data = stream.receive()
            self.assertIsNotNone(data, "Received None message.")

            x_size = data.data.data["width"].value
            y_size = data.data.data["height"].value
            x_axis = data.data.data["x_axis"].value
            y_axis = data.data.data["y_axis"].value
            image_shape = data.data.data["image"].value.shape

            self.assertEqual(x_size, simulated_camera_shape[1])
            self.assertEqual(y_size, simulated_camera_shape[0])

            # Sanity checks.
            self.assertEqual(x_size, len(x_axis))
            self.assertEqual(y_size, len(y_axis))
            self.assertEqual(image_shape, (y_size, x_size))

            # Rotate the image by 90 degree.
            camera_config = self.client.get_camera_config("simulation_temp")
            camera_config["rotate"] = 1
            self.client.set_camera_config("simulation_temp", camera_config)

            # Make a few frames pass.
            for _ in range(5):
                data = stream.receive()

            self.assertIsNotNone(data, "Received None message.")

            x_size = data.data.data["width"].value
            y_size = data.data.data["height"].value
            x_axis = data.data.data["x_axis"].value
            y_axis = data.data.data["y_axis"].value
            image_shape = data.data.data["image"].value.shape

            # X and Y size should be inverted.
            self.assertEqual(x_size, simulated_camera_shape[0])
            self.assertEqual(y_size, simulated_camera_shape[1])

            # Sanity checks.
            self.assertEqual(x_size, len(x_axis))
            self.assertEqual(y_size, len(y_axis))
            self.assertEqual(image_shape, (y_size, x_size))

        self.client.delete_camera_config("simulation_temp")

        stop_event.set()
        thread.join()