def test_wrong_background_size(self): pipeline_parameters = { "camera_name": "simulation", "image_background": "white_background" } simulated_camera = get_simulated_camera() 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, 0, time.time(), x_axis, y_axis, parameters, image_background_array)
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_image(self): simulated_camera = get_simulated_camera() image = simulated_camera.get_image() self.assertIsNotNone(image) raw_image = simulated_camera.get_image(raw=True) self.assertIsNotNone(raw_image)
def test_noop_pipeline(self): pipeline_config = PipelineConfig("test_pipeline") simulated_camera = get_simulated_camera() image = simulated_camera.get_image() x_axis, y_axis = simulated_camera.get_x_y_axis() parameters = pipeline_config.get_configuration() result = process_image(image, 0, time.time(), x_axis, y_axis, 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", "x_fwhm", "y_fwhm", 'width', 'height' ] 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_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.")
def test_sum_images(self): simulated_camera = get_simulated_camera() image = simulated_camera.get_image() accumulated_image = None n_images = 1000 for _ in range(n_images): accumulated_image = sum_images(image=image, accumulator_image=accumulated_image) processed_image = accumulated_image / n_images processed_image = processed_image.astype(dtype="uint16") numpy.testing.assert_array_equal(image, processed_image)
def test_background_file(self): bg = self.pipeline_client.get_latest_background("simulation") image = self.pipeline_client.get_background_image(bg) self.assertGreater(len(image.content), 0) image = self.pipeline_client.get_background_image_bytes(bg) dtype = image["dtype"] shape = image["shape"] bytes = base64.b64decode(image["bytes"].encode()) x_size, y_size = get_simulated_camera().get_geometry() self.assertEqual(shape, [y_size, x_size]) image_array = numpy.frombuffer(bytes, dtype=dtype).reshape(shape) self.assertIsNotNone(image_array)
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_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 run_the_pipeline(configuration, simulated_image=None): parameters = PipelineConfig("test_pipeline", configuration).get_configuration() simulated_camera = get_simulated_camera() if simulated_image is None: simulated_image = simulated_camera.get_image() x_axis, y_axis = simulated_camera.get_x_y_axis() return process_image(simulated_image, 0, time.time(), x_axis=x_axis, y_axis=y_axis, parameters=parameters)
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_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", "simulation2"]) print (self.client.get_cameras()) #self.assertSetEqual(set(self.client.get_cameras()), expected_cameras, "Not getting all expected cameras") for camera in expected_cameras: self.assertIn(camera, set(self.client.get_cameras()), "Not getting expected camera: " + camera) print (self.client.get_camera_aliases()) print(self.client.get_camera_groups()) camera_stream_address = self.client.get_instance_stream("simulation") self.assertTrue(bool(camera_stream_address), "Camera stream address cannot be empty.") self.assertTrue(self.client.is_instance_running("simulation"), "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 = config.CAMERA_STREAM_REQUIRED_FIELDS self.assertSetEqual(required_fields, set(data.data.data.keys()), "Required fields missing.") image = data.data.data["image"].value x_size, y_size = get_simulated_camera().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_instance("simulation") self.assertTrue(not self.client.is_instance_running("simulation"), "Camera simulation did not stop.") self.client.get_instance_stream("simulation") self.assertTrue(self.client.is_instance_running("simulation"), "Camera simulation did not start.") self.client.stop_all_instances() self.assertTrue(not self.client.is_instance_running("simulation"), "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 = get_simulated_camera() 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 is offline"): self.client.get_instance_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_instance_stream("simulation_temp") camera_host, camera_port = get_host_port_from_stream_address(stream_address) sim_x, sim_y = get_simulated_camera().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 = get_simulated_camera().get_geometry() self.assertEqual(shape, [y_size, x_size]) image_array = numpy.frombuffer(bytes, dtype=dtype).reshape(shape) self.assertIsNotNone(image_array) #Check logs self.assertIsInstance(self.client.get_logs(False), list) self.assertIsInstance(self.client.get_logs(True), str) self.client.stop_all_instances()
def test_update_instance_config_with_running(self): instance_manager = get_test_pipeline_manager_with_real_cam() instance_manager.background_manager = BackgroundImageManager( self.background_folder) pipeline_config = {"camera_name": "simulation"} x_size, y_size = get_simulated_camera().get_geometry() black_image = numpy.zeros(shape=(y_size, x_size)).astype(dtype="uint16") pipeline_id, pipeline_stream_address = instance_manager.create_pipeline( configuration=pipeline_config) 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: normal_image_data = stream.receive() self.assertIsNotNone(normal_image_data, "This should really not happen anymore.") self.assertFalse( numpy.array_equal(normal_image_data.data.data['image'].value, black_image), "There should be a non black image.") self.assertEqual(normal_image_data.data.data["width"].value, x_size, "Incorrect width.") self.assertEqual(normal_image_data.data.data["height"].value, y_size, "Incorrect height.") white_image = numpy.zeros(shape=(y_size, x_size)) white_image.fill(65535) instance_manager.background_manager.save_background( "white_background", white_image, append_timestamp=False) instance_manager.update_instance_config( pipeline_id, {"image_background": "white_background"}) # Give it some time to load the background. sleep(0.5) # Collect from the camera. with source(host=pipeline_host, port=pipeline_port, mode=SUB) as stream: image_data = stream.receive() self.assertIsNotNone(image_data, "This should really not happen anymore.") # Because we didn't set the "image_background_enable" yet. self.assertFalse( numpy.array_equal(image_data.data.data["image"].value, black_image), "Background should not be yet applied.") instance_manager.update_instance_config(pipeline_id, { "image_background_enable": True, "image_threshold": 0 }) # Give it some time to load the background. sleep(1.0) # Collect from the camera. with source(host=pipeline_host, port=pipeline_port, mode=SUB) as stream: black_image_data = stream.receive() print(pipeline_host, pipeline_port) self.assertIsNotNone(black_image_data, "This should really not happen anymore.") print("---") print(black_image_data.data.data["image"].value.shape, black_image_data.data.data["image"].value.dtype) print(black_image.shape, black_image.dtype) black_image.astype(dtype="uint16") for i in range(len(black_image)): for j in range(len(black_image[0])): if black_image_data.data.data["image"].value[i][ j] != black_image[i][j]: print(i, j, black_image_data.data.data["image"].value[i][j], black_image[i][j]) self.assertTrue( numpy.array_equal(black_image_data.data.data["image"].value, black_image), "Now background should work.") instance_manager.stop_all_instances()
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_region_of_interest_default_values(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() 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, 0, time.time(), x_axis, y_axis, 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, 0, time.time(), x_axis, y_axis, 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, 0, time.time(), x_axis, y_axis, 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)))))
def test_image_background(self): pipeline_parameters = { "camera_name": "simulation", "image_background": "white_background" } simulated_camera = get_simulated_camera() 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")) if image_background_array is not None: image_background_array = image_background_array.astype("uint16", copy=False) image = subtract_background(image, image_background_array) result = process_image(image, 0, time.time(), x_axis, y_axis, parameters) 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")) if image_background_array is not None: image_background_array = image_background_array.astype("uint16", copy=False) image = subtract_background(image, image_background_array) expected_image = numpy.zeros(shape=(y_size, x_size)) result = process_image(image, 0, time.time(), x_axis, y_axis, parameters) self.assertTrue( numpy.array_equal(result["image"], expected_image), "The image should be all zeros - negative numbers are not allowed." )
def test_slices(self): def run_the_pipeline(configuration, simulated_image=None): parameters = PipelineConfig("test_pipeline", configuration).get_configuration() simulated_camera = get_simulated_camera() if simulated_image is None: simulated_image = simulated_camera.get_image() x_axis, y_axis = simulated_camera.get_x_y_axis() return process_image(simulated_image, 0, time.time(), x_axis=x_axis, y_axis=y_axis, parameters=parameters) pipeline_configuration = { "camera_name": "simulation", "image_good_region": { "threshold": 1 }, "image_slices": { "number_of_slices": 9 } } result = run_the_pipeline(pipeline_configuration) self.assertEqual(result["slice_amount"], 9) self.assertEqual(result["slice_orientation"], "vertical", "Default slice orientation should be vertical.") self.assertTrue("slice_length" in result) pipeline_configuration = { "camera_name": "simulation", "image_good_region": { "threshold": 1 }, "image_slices": { "orientation": "horizontal" } } result = run_the_pipeline(pipeline_configuration) self.assertEqual(result["slice_orientation"], "horizontal") self.assertTrue("slice_length" in result) with self.assertRaisesRegex(ValueError, "Invalid slice orientation 'invalid'."): pipeline_configuration = { "camera_name": "simulation", "image_good_region": { "threshold": 1 }, "image_slices": { "orientation": "invalid" } } run_the_pipeline(pipeline_configuration) image = get_simulated_camera().get_image() pipeline_configuration = { "camera_name": "simulation", "image_good_region": { "threshold": 0.1 }, "image_slices": { "orientation": "vertical", "number_of_slices": 3 } } result_1 = run_the_pipeline(pipeline_configuration, image) result_2 = run_the_pipeline(pipeline_configuration, image) # 2 calculations with the same data should give the same result. self.assertEqual(result_1["slice_0_center_x"], result_2["slice_0_center_x"]) self.assertEqual(result_1["slice_0_center_y"], result_2["slice_0_center_y"]) pipeline_configuration = { "camera_name": "simulation", "image_good_region": { "threshold": 0.1 }, "image_slices": { "orientation": "horizontal", "number_of_slices": 3 } } result_3 = run_the_pipeline(pipeline_configuration, image) # If we orientate the slices horizontally, the slice center has to change. self.assertNotEqual(result_1["slice_0_center_x"], result_3["slice_0_center_x"]) self.assertNotEqual(result_1["slice_0_center_y"], result_3["slice_0_center_y"])