def test_modify_camera_config(self): self.cam_client.set_camera_config( "test_camera", self.cam_client.get_camera_config("camera_example_2")) from cam_server import CamClient # Initialize the camera client. cam_client = CamClient() cam_client = self.cam_client # Print the list of available cameras. print(cam_client.get_cameras()) # Put the name of the camera you want to modify. camera_to_modify = "test_camera" # Retrieve the camera config. camera_config = cam_client.get_camera_config(camera_to_modify) # Change the mirror_x setting. camera_config["mirror_x"] = False # Change the camera_calibration setting. camera_config["camera_calibration"] = { "reference_marker": [0, 0, 100, 100], "reference_marker_width": 100.0, "reference_marker_height": 100.0, "angle_horizontal": 0.0, "angle_vertical": 0.0 } # Save the camera configuration. cam_client.set_camera_config(camera_to_modify, camera_config) # You can also save the same (or another) config under a different camera name. cam_client.set_camera_config("camera_to_delete", camera_config) # And also delete camera configs. cam_client.delete_camera_config("camera_to_delete")
class CameraClientTest(unittest.TestCase): def setUp(self): self.host = "0.0.0.0" self.port = 8888 test_base_dir = os.path.split(os.path.abspath(__file__))[0] self.config_folder = os.path.join(test_base_dir, "camera_config/") self.process = Process(target=start_camera_server, args=(self.host, self.port, self.config_folder)) self.process.start() # Give it some time to start. sleep(0.5) server_address = "http://%s:%s" % (self.host, self.port) self.client = CamClient(server_address) def tearDown(self): self.client.stop_all_cameras() os.kill(self.process.pid, signal.SIGINT) try: os.remove(os.path.join(self.config_folder, "testing_camera.json")) except: pass # Wait for the server to die. sleep(1) def test_client(self): server_info = self.client.get_server_info() self.assertIsNot(server_info["active_instances"], "There should be no running instances.") expected_cameras = set([ "camera_example_1", "camera_example_2", "camera_example_3", "camera_example_4", "simulation" ]) self.assertSetEqual(set(self.client.get_cameras()), expected_cameras, "Not getting all expected cameras") camera_stream_address = self.client.get_camera_stream("simulation") self.assertTrue(bool(camera_stream_address), "Camera stream address cannot be empty.") self.assertTrue( "simulation" in self.client.get_server_info()["active_instances"], "Simulation camera not present in server info.") # Check if we can connect to the stream and receive data (in less than 2 seconds). host, port = get_host_port_from_stream_address(camera_stream_address) with source(host=host, port=port, receive_timeout=2000, mode=SUB) as stream: data = stream.receive() self.assertIsNotNone(data, "Received data was none.") required_fields = set( ["image", "timestamp", "width", "height", "x_axis", "y_axis"]) self.assertSetEqual(required_fields, set(data.data.data.keys()), "Required fields missing.") image = data.data.data["image"].value x_size, y_size = CameraSimulation( CameraConfig("simulation")).get_geometry() self.assertListEqual( list(image.shape), [y_size, x_size], "Original and received image are not the same.") self.assertEqual(data.data.data["width"].value, x_size, "Width not correct.") self.assertEqual(data.data.data["height"].value, y_size, "Height not correct.") # Stop the simulation instance. self.client.stop_camera("simulation") self.assertTrue( "simulation" not in self.client.get_server_info()["active_instances"], "Camera simulation did not stop.") self.client.get_camera_stream("simulation") self.assertTrue( "simulation" in self.client.get_server_info()["active_instances"], "Camera simulation did not start.") self.client.stop_all_cameras() self.assertTrue( "simulation" not in self.client.get_server_info()["active_instances"], "Camera simulation did not stop.") example_1_config = self.client.get_camera_config("camera_example_1") self.assertTrue(bool(example_1_config), "Cannot retrieve config.") # Change the name to reflect tha camera. example_1_config["name"] = "testing_camera" self.client.set_camera_config("testing_camera", example_1_config) testing_camera_config = self.client.get_camera_config("testing_camera") self.assertDictEqual(example_1_config, testing_camera_config, "Saved and loaded configs are not the same.") geometry = self.client.get_camera_geometry("simulation") simulated_camera = CameraSimulation(CameraConfig("simulation")) size_x, size_y = simulated_camera.get_geometry() self.assertListEqual( geometry, [size_x, size_y], 'The geometry of the simulated camera is not correct.') self.assertTrue("testing_camera" in self.client.get_cameras(), "Testing camera should be present.") self.client.delete_camera_config("testing_camera") self.assertTrue("testing_camera" not in self.client.get_cameras(), "Testing camera should not be present.") # Test if it fails quickly enough. with self.assertRaisesRegex( ValueError, "Camera with prefix EPICS_example_1 not online - Status None"): self.client.get_camera_stream("camera_example_1") self.assertTrue(self.client.is_camera_online("simulation"), "Simulation should be always online") self.assertFalse(self.client.is_camera_online("camera_example_1"), "Epics not working in this tests.") self.client.set_camera_config( "simulation_temp", self.client.get_camera_config("simulation")) stream_address = self.client.get_camera_stream("simulation_temp") camera_host, camera_port = get_host_port_from_stream_address( stream_address) sim_x, sim_y = CameraSimulation( CameraConfig("simulation")).get_geometry() instance_info = self.client.get_server_info( )["active_instances"]["simulation_temp"] self.assertTrue("last_start_time" in instance_info) self.assertTrue("statistics" in instance_info) # Collect from the pipeline. with source(host=camera_host, port=camera_port, mode=SUB) as stream: data = stream.receive() x_size = data.data.data["width"].value y_size = data.data.data["height"].value self.assertEqual(x_size, sim_x) self.assertEqual(y_size, sim_y) x_axis_1 = data.data.data["x_axis"].value y_axis_1 = data.data.data["y_axis"].value self.assertEqual(x_axis_1.shape[0], sim_x) self.assertEqual(y_axis_1.shape[0], sim_y) camera_config = self.client.get_camera_config("simulation_temp") camera_config["rotate"] = 1 self.client.set_camera_config("simulation_temp", camera_config) sleep(0.5) # Collect from the pipeline. with source(host=camera_host, port=camera_port, mode=SUB) as stream: data = stream.receive() x_size = data.data.data["width"].value y_size = data.data.data["height"].value # We rotate the image for 90 degrees - X and Y size should be inverted. self.assertEqual(x_size, sim_y) self.assertEqual(y_size, sim_x) x_axis_2 = data.data.data["x_axis"].value y_axis_2 = data.data.data["y_axis"].value # We rotate the image for 90 degrees - X and Y size should be inverted. self.assertEqual(x_axis_2.shape[0], sim_y) self.assertEqual(y_axis_2.shape[0], sim_x) self.client.delete_camera_config("simulation_temp") image = self.client.get_camera_image("simulation") self.assertGreater(len(image.content), 0) image = self.client.get_camera_image_bytes("simulation") dtype = image["dtype"] shape = image["shape"] bytes = base64.b64decode(image["bytes"].encode()) x_size, y_size = CameraSimulation( CameraConfig("simulation")).get_geometry() self.assertEqual(shape, [y_size, x_size]) image_array = numpy.frombuffer(bytes, dtype=dtype).reshape(shape) self.assertIsNotNone(image_array) self.client.stop_all_cameras()
class PipelineTransceiverTest(unittest.TestCase): def setUp(self): self.host = "127.0.0.1" self.port = 8888 test_base_dir = os.path.split(os.path.abspath(__file__))[0] self.config_folder = os.path.join(test_base_dir, "camera_config/") self.user_scripts_folder = os.path.join(test_base_dir, "user_scripts/") self.process = Process(target=start_camera_server, args=(self.host, self.port, self.config_folder, self.user_scripts_folder)) self.process.start() # Give it some time to start. sleep(1.0) self.rest_api_endpoint = "http://%s:%s" % (self.host, self.port) self.client = CamClient(self.rest_api_endpoint) def tearDown(self): test_cleanup( [self.client], [self.process], [os.path.join(self.config_folder, "simulation_temp.json")]) 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_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) 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() x_size, y_size = get_simulated_camera().get_geometry() simulated_camera_shape = (y_size, x_size) background_array = numpy.zeros(shape=simulated_camera_shape) background_array.fill(65535) background_manager.save_background("full_background", background_array, append_timestamp=False) def send(): processing_pipeline(stop_event, statistics, parameter_queue, self.client, pipeline_config, 12001, background_manager) thread = Thread(target=send) thread.start() with source(host="127.0.0.1", port=12001, mode=SUB, receive_timeout=3000) as stream: import time 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() 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() 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() 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)
class PipelineClientTest(unittest.TestCase): def setUp(self): self.host = "localhost" self.cam_port = 8888 self.pipeline_port = 8889 test_base_dir = os.path.split(os.path.abspath(__file__))[0] self.cam_config_folder = os.path.join(test_base_dir, "camera_config/") self.pipeline_config_folder = os.path.join(test_base_dir, "pipeline_config/") self.background_config_folder = os.path.join(test_base_dir, "background_config/") self.user_scripts_folder = os.path.join(test_base_dir, "user_scripts/") require_folder(self.background_config_folder) require_folder(self.user_scripts_folder) cam_server_address = "http://%s:%s" % (self.host, self.cam_port) pipeline_server_address = "http://%s:%s" % (self.host, self.pipeline_port) self.cam_process = Process(target=start_camera_server, args=(self.host, self.cam_port, self.cam_config_folder, None)) self.cam_process.start() self.pipeline_process = Process( target=start_pipeline_server, args=(self.host, self.pipeline_port, self.pipeline_config_folder, self.background_config_folder, self.user_scripts_folder, cam_server_address)) self.pipeline_process.start() # Give it some time to start. sleep(1) self.cam_client = CamClient(cam_server_address) self.pipeline_client = PipelineClient(pipeline_server_address) def tearDown(self): test_cleanup([self.pipeline_client, self.cam_client], [ self.pipeline_process, self.cam_process ], [ os.path.join(self.pipeline_config_folder, "testing_config.json"), os.path.join(self.pipeline_config_folder, "test_pipeline.json"), os.path.join(self.cam_config_folder, "test_camera.json"), "testing_dump.h5", self.background_config_folder, self.user_scripts_folder, ]) def test_a_quick_start(self): from cam_server import PipelineClient from cam_server.utils import get_host_port_from_stream_address from bsread import source, SUB # Create a pipeline client. client = PipelineClient() # ADDITIONAL, FOR THE TEST camera_name = "simulation" client = self.pipeline_client client.create_instance_from_config( configuration={"camera_name": camera_name}, instance_id=camera_name + "_sp1") # Define the camera name you want to read. This should be the same camera you are streaming in screen panel. camera_name = "simulation" # Format of the instance id when screen_panel creates a pipeline. pipeline_instance_id = camera_name + "_sp1" # Get the stream for the pipelie instance. stream_address = client.get_instance_stream(pipeline_instance_id) # Extract the stream host and port from the stream_address. stream_host, stream_port = get_host_port_from_stream_address( stream_address) # Open connection to the stream. When exiting the 'with' section, the source disconnects by itself. with source(host=stream_host, port=stream_port, mode=SUB) as input_stream: input_stream.connect() # Read one message. message = input_stream.receive() # Print out the received stream data - dictionary. print("Dictionary with data:\n", message.data.data) # Print out the X center of mass. print("X center of mass: ", message.data.data["x_center_of_mass"].value) def test_get_simulated_camera(self): from cam_server import CamClient from cam_server.utils import get_host_port_from_stream_address from bsread import source, SUB # Change to match your camera server server_address = "http://0.0.0.0:8888" # Initialize the client. camera_client = CamClient(server_address) # Get stream address of simulation camera. Stream address in format tcp://hostname:port. camera_stream_address = camera_client.get_instance_stream("simulation") # Extract the stream hostname and port from the stream address. camera_host, camera_port = get_host_port_from_stream_address( camera_stream_address) # Subscribe to the stream. with source(host=camera_host, port=camera_port, mode=SUB) as stream: # Receive next message. data = stream.receive() image_width = data.data.data["width"].value image_height = data.data.data["height"].value image_bytes = data.data.data["image"].value print("Image size: %d x %d" % (image_width, image_height)) print("Image data: %s" % image_bytes) x_size, y_size = get_simulated_camera().get_geometry() self.assertIsNotNone(data) self.assertEqual(image_width, x_size) self.assertIsNotNone(image_height, y_size) def test_get_basic_pipeline_with_simulated_camera(self): from cam_server import PipelineClient from cam_server.utils import get_host_port_from_stream_address from bsread import source, SUB # Change to match your pipeline server server_address = "http://0.0.0.0:8889" # Initialize the client. pipeline_client = PipelineClient(server_address) # Setup the pipeline config. Use the simulation camera as the pipeline source. pipeline_config = {"camera_name": "simulation"} # Create a new pipeline with the provided configuration. Stream address in format tcp://hostname:port. instance_id, pipeline_stream_address = pipeline_client.create_instance_from_config( pipeline_config) # Extract the stream hostname and port from the stream address. pipeline_host, pipeline_port = get_host_port_from_stream_address( pipeline_stream_address) # Subscribe to the stream. with source(host=pipeline_host, port=pipeline_port, mode=SUB) as stream: # Receive next message. data = stream.receive() image_width = data.data.data["width"].value image_height = data.data.data["height"].value image_bytes = data.data.data["image"].value print("Image size: %d x %d" % (image_width, image_height)) print("Image data: %s" % image_bytes) x_size, y_size = get_simulated_camera().get_geometry() self.assertIsNotNone(data) self.assertEqual(image_width, x_size) self.assertIsNotNone(image_height, y_size) def test_create_pipeline_with_background(self): from cam_server import PipelineClient from cam_server.utils import get_host_port_from_stream_address from bsread import source, SUB # Change to match your pipeline server server_address = "http://0.0.0.0:8889" camera_name = "simulation" # Initialize the client. pipeline_client = PipelineClient(server_address) # Collect the background for the given camera. background_id = pipeline_client.collect_background(camera_name) # Setup the pipeline config. Use the simulation camera as the pipeline source, and the collected background. pipeline_config = { "camera_name": camera_name, "background_id": background_id } # Create a new pipeline with the provided configuration. Stream address in format tcp://hostname:port. instance_id, pipeline_stream_address = pipeline_client.create_instance_from_config( pipeline_config) # Extract the stream hostname and port from the stream address. pipeline_host, pipeline_port = get_host_port_from_stream_address( pipeline_stream_address) # Subscribe to the stream. with source(host=pipeline_host, port=pipeline_port, mode=SUB) as stream: # Receive next message. data = stream.receive() image_width = data.data.data["width"].value image_height = data.data.data["height"].value image_bytes = data.data.data["image"].value print("Image size: %d x %d" % (image_width, image_height)) print("Image data: %s" % image_bytes) x_size, y_size = get_simulated_camera().get_geometry() self.assertIsNotNone(data) self.assertEqual(image_width, x_size) self.assertIsNotNone(image_height, y_size) def test_modify_camera_config(self): self.cam_client.set_camera_config( "test_camera", self.cam_client.get_camera_config("camera_example_2")) from cam_server import CamClient # Initialize the camera client. cam_client = CamClient() cam_client = self.cam_client # Print the list of available cameras. print(cam_client.get_cameras()) # Put the name of the camera you want to modify. camera_to_modify = "test_camera" # Retrieve the camera config. camera_config = cam_client.get_camera_config(camera_to_modify) # Change the mirror_x setting. camera_config["mirror_x"] = False # Change the camera_calibration setting. camera_config["camera_calibration"] = { "reference_marker": [0, 0, 100, 100], "reference_marker_width": 100.0, "reference_marker_height": 100.0, "angle_horizontal": 0.0, "angle_vertical": 0.0 } # Save the camera configuration. cam_client.set_camera_config(camera_to_modify, camera_config) # You can also save the same (or another) config under a different camera name. cam_client.set_camera_config("camera_to_delete", camera_config) # And also delete camera configs. cam_client.delete_camera_config("camera_to_delete") def test_modify_pipeline_config(self): self.pipeline_client.save_pipeline_config( "test_pipeline", self.pipeline_client.get_pipeline_config("pipeline_example_1")) from cam_server import PipelineClient # Initialize the pipeline client. pipeline_client = PipelineClient() pipeline_client = self.pipeline_client # Print the list of available pipelines. print(pipeline_client.get_pipelines()) # Put the name of the pipeline you want to modify. pipeline_to_modify = "test_pipeline" # Retrieve the camera config. pipeline_config = pipeline_client.get_pipeline_config( pipeline_to_modify) # Change the image threshold. pipeline_config["image_threshold"] = 0.5 # Change the image region of interest. pipeline_config["image_region_of_interest"] = [0, 100, 0, 100] # Save the camera configuration. pipeline_client.save_pipeline_config(pipeline_to_modify, pipeline_config) # You can also save the same (or another) config under a different camera name. pipeline_client.save_pipeline_config("pipeline_to_delete", pipeline_config) # And also delete camera configs. pipeline_client.delete_pipeline_config("pipeline_to_delete") def test_create_camera(self): # Specify the desired camera config. camera_config = { "name": "camera_example_3", "source": "EPICS:CAM1:EXAMPLE", "source_type": "epics", "mirror_x": False, "mirror_y": False, "rotate": 0, "camera_calibration": { "reference_marker": [0, 0, 100, 100], "reference_marker_width": 100.0, "reference_marker_height": 100.0, "angle_horizontal": 0.0, "angle_vertical": 0.0 } } # Specify the new camera name. new_camera_name = "new_camera_name" # Save the camera configuration. self.cam_client.set_camera_config(new_camera_name, camera_config) self.assertTrue(new_camera_name in self.cam_client.get_cameras()) # Delete the camera config you just added. self.cam_client.delete_camera_config(new_camera_name) self.assertTrue(new_camera_name not in self.cam_client.get_cameras()) def get_single_message(self): self.pipeline_client.create_instance_from_name("pipeline_example_1", "simulation_sp1") # Name of the camera we want to get a message from. camera_name = "simulation" # Screen panel defines the instance name as: [CAMERA_NAME]_sp1 instance_name = camera_name + "_sp1" # Get the data. data = self.pipeline_client.get_instance_message(instance_name) self.assertIsNotNone(data) self.assertTrue("image" in data.data.data) def test_save_camera_stream_to_h5(self): from bsread import h5, SUB camera_name = "simulation" file_name = "testing_dump.h5" n_messages = 10 # Change to match your camera server server_address = "http://0.0.0.0:8889" client = PipelineClient(server_address) instance_id, stream_address = client.create_instance_from_config( {"camera_name": camera_name}) # The output file 'output.h5' has 10 images from the simulation camera stream. h5.receive(source=stream_address, file_name=file_name, mode=SUB, n_messages=n_messages) self.assertTrue(os.path.exists(file_name))
class PipelineTransceiverTest(unittest.TestCase): def setUp(self): self.host = "0.0.0.0" self.port = 8888 test_base_dir = os.path.split(os.path.abspath(__file__))[0] self.config_folder = os.path.join(test_base_dir, "camera_config/") self.process = Process(target=start_camera_server, args=(self.host, self.port, self.config_folder)) self.process.start() # Give it some time to start. sleep(0.5) self.rest_api_endpoint = "http://%s:%s" % (self.host, self.port) self.client = CamClient(self.rest_api_endpoint) def tearDown(self): self.client.stop_all_cameras() sleep(1) try: os.kill(self.process.pid, signal.SIGINT) except: pass try: os.remove(os.path.join(self.config_folder, "testing_camera.json")) except: pass # Wait for the server to die. sleep(2) 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) 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' ]) self.assertSetEqual( required_keys, set(data.data.data.keys()), "Missing required keys in pipeline output bsread message.") stop_event.set() thread.join() 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() 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() simulated_camera_shape = (960, 1280) 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.") 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() 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_cameras() pipeline_config = PipelineConfig("test_pipeline") def send(): store_pipeline(stop_event, statistics, parameter_queue, self.client, pipeline_config, 12000, MockBackgroundManager()) thread = Thread(target=send) thread.start() sleep(0.5) with source(host="127.0.0.1", port=12000, mode=PULL) as stream: data = stream.receive() self.assertIsNotNone(data, "Received None message.") required_keys = set(["simulation"]) self.assertSetEqual( required_keys, set(data.data.data.keys()), "Missing required keys in pipeline output bsread message.") stop_event.set() thread.join()