def setUp(self): self.host = "0.0.0.0" self.cam_port = 8888 self.pipeline_port = 8889 self.cam_proxy_port = 8898 self.pipeline_proxy_port = 8899 for port in self.cam_port, self.pipeline_port, self.cam_proxy_port, self.pipeline_proxy_port: print("Port ", port, "avilable: ", is_port_available(port)) 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) cam_server_proxy_address = "http://%s:%s" % (self.host, self.cam_proxy_port) pipeline_server_proxy_address = "http://%s:%s" % ( self.host, self.pipeline_proxy_port) self.cam_process = Process(target=start_camera_server, args=(self.host, self.cam_port, self.cam_config_folder, self.user_scripts_folder)) self.cam_process.start() self.cam_proxy_process = Process(target=start_camera_proxy, args=(self.host, self.cam_proxy_port, cam_server_address, self.cam_config_folder)) self.cam_proxy_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_proxy_address)) self.pipeline_process.start() self.pipeline_proxy_process = Process( target=start_pipeline_proxy, args=(self.host, self.pipeline_proxy_port, pipeline_server_address, self.pipeline_config_folder, self.background_config_folder, self.user_scripts_folder, cam_server_proxy_address)) self.pipeline_proxy_process.start() self.cam_client = CamClient(cam_server_proxy_address) self.pipeline_client = PipelineClient(pipeline_server_proxy_address) # Give it some time to start. sleep(1.0) # Give it some time to start.
def __init__( self, name=None, reduction_client_address="http://sf-daqsync-02:12003/", delay_stages={"spatial_tt": "SLAAR21-LMOT-M522:MOTOR_1"}, pipeline_id="SARES20-CAMS142-M4_psen_db1", ): self.name = name self.alias = Alias(name) # append_object_to_object(self,MotorRecord,pvname+":MOTOR_X1",name='x_target') # append_object_to_object(self,MotorRecord,pvname+":MOTOR_Y1",name='y_target') if delay_stages: for key, pv in delay_stages.items(): tname = "delay_" + key + "_stg" append_object_to_object(self, MotorRecord, pv, name=tname) append_object_to_object(self, DelayTime, self.__dict__[tname], name="delay_" + key) # self.delay = MotorRecord(self.Id + "-M424:MOT") # self.delayTime = DelayStage(self.delay) # self.data_reduction_client = PsenProcessingClient(address=reduction_client_address) self._camera_server_client = PipelineClient() self._camera_server_pipeline_id = pipeline_id
def setUp(self): self.host = "0.0.0.0" 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/") 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)) 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, 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 get_images(screen, n_images, beamline='Aramis', dry_run=None): print('Start get_images for screen %s, %i images, beamline %s' % (screen, n_images, beamline)) meta_dict_1 = get_meta_data(screen) positioner = pyscan.BsreadPositioner(n_messages=n_images) settings = pyscan.scan_settings(settling_time=0.01, measurement_interval=0.2, n_measurements=1) pipeline_client = PipelineClient("http://sf-daqsync-01:8889/") cam_instance_name = str(screen) + "_sp1" stream_address = pipeline_client.get_instance_stream(cam_instance_name) stream_host, stream_port = get_host_port_from_stream_address( stream_address) # Configure bsread pyscan.config.bs_default_host = stream_host pyscan.config.bs_default_port = stream_port logging.getLogger("mflow.mflow").setLevel(logging.ERROR) readables = get_readables(beamline) raw_output = pyscan.scan(positioner=positioner, readables=readables, settings=settings) output = [[x] for x in raw_output] result_dict = pyscan_result_to_dict(readables, output, scrap_bs=True) for ax in ['x_axis', 'y_axis']: arr = result_dict[ax] * 1e-6 # convert to m if len(arr.shape) == 3: result_dict[ax + '_m'] = arr[0, 0, :] elif len(arr.shape) == 2: result_dict[ax + '_m'] = arr[0, :] else: raise ValueError('Unexpected', len(arr.shape)) meta_dict_2 = get_meta_data(screen) output_dict = { 'pyscan_result': result_dict, 'meta_data_begin': meta_dict_1, 'meta_data_end': meta_dict_2, } print('End get_images') return output_dict
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 get_image(camName, ROI, numImg, angle): pipeline_client = PipelineClient() pipeline_config = {"camera_name": camName, "image_region_of_interest": ROI} pipeline_config = {"camera_name": camName,"rotation":angle} instance_id, pipeline_stream_address = pipeline_client.create_instance_from_config(pipeline_config) pipeline_host, pipeline_port = get_host_port_from_stream_address(pipeline_stream_address) img = [] x_profile = [] y_profile = [] x_fwhm = [] y_fwhm = [] x_center_of_mass = [] y_center_of_mass = [] intensity = [] max_value = [] width = [] height = [] with source(host=pipeline_host, port=pipeline_port, mode=SUB) as stream: for i in range(0,numImg): data = stream.receive() img.append(data.data.data["image"].value) x_profile.append(data.data.data["x_profile"].value) y_profile.append(data.data.data["y_profile"].value) x_fwhm.append(data.data.data["x_fwhm"].value) y_fwhm.append(data.data.data["y_fwhm"].value) x_center_of_mass.append(data.data.data["x_center_of_mass"].value) intensity.append(data.data.data["intensity"].value) width.append(data.data.data["width"].value) height.append(data.data.data["height"].value) img = np.asarray(img) dataout = { "mean": img.mean(axis=0), "image":img, "x_profile":x_profile, "y_profile":y_profile, "x_fwhm":x_fwhm, "y_fwhm":y_fwhm, "x_center_of_mass":x_center_of_mass, "y_center_of_mass":y_center_of_mass, "intensity":intensity, "max_value":max_value, "width":width, "height":height } return dataout
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_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))
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 setUp(self): 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/") self.temp_folder = os.path.join(test_base_dir, "temp/") require_folder(self.background_config_folder) require_folder(self.user_scripts_folder) require_folder(self.temp_folder) self.host = "localhost" self.cam_server_ports = [8880, 8881] self.cam_manager_port = 8888 self.pipeline_server_ports = [8890, 8891] self.pipeline_manager_port = 8889 self.cam_server_address = [] self.process_camserver = [] port_range = config.CAMERA_STREAM_PORT_RANGE for p in self.cam_server_ports: port_range = [port_range[0] + 10000, port_range[1] + 10000] self.cam_server_address.append("http://%s:%s" % (self.host, p)) process = Process(target=start_camera_worker, args=(self.host, p, self.user_scripts_folder, None, port_range)) self.process_camserver.append(process) process.start() self.cam_proxy_host = "0.0.0.0" self.process_camproxy = Process( target=start_camera_manager, args=(self.host, self.cam_manager_port, ",".join(self.cam_server_address), self.cam_config_folder, self.user_scripts_folder)) self.process_camproxy.start() cam_server_proxy_address = "http://%s:%s" % (self.host, self.cam_manager_port) pipeline_server_proxy_address = "http://%s:%s" % ( self.host, self.pipeline_manager_port) self.pipeline_server_address = [] self.process_pipelineserver = [] port_range = config.PIPELINE_STREAM_PORT_RANGE for p in self.pipeline_server_ports: port_range = [port_range[0] + 10000, port_range[1] + 10000] self.pipeline_server_address.append("http://%s:%s" % (self.host, p)) process = Process(target=start_pipeline_worker, args=(self.host, p, self.temp_folder, self.temp_folder, cam_server_proxy_address, None, port_range)) self.process_pipelineserver.append(process) process.start() cfg = """{ "http://localhost:8890": { "expanding": true }, "http://localhost:8891": { "cameras": [ "simulation3" ], "expanding": false, "instances": [ "simulation_sp:10123" ] } }""" self.pipeline_proxy_process = Process( target=start_pipeline_manager, args=(self.host, self.pipeline_manager_port, cfg, self.pipeline_config_folder, self.background_config_folder, config.DEFAULT_BACKGROUND_FILES_DAYS_TO_LIVE, self.user_scripts_folder, cam_server_proxy_address)) self.pipeline_proxy_process.start() sleep(1.0) # Give it some time to start. cam_server_address = "http://%s:%s" % (self.host, self.cam_manager_port) self.cam_client = CamClient(cam_server_address) pipeline_server_address = "http://%s:%s" % (self.host, self.pipeline_manager_port) self.pipeline_client = PipelineClient(pipeline_server_address) self.cam_proxy_client = ProxyClient(cam_server_address) self.pipeline_proxy_client = ProxyClient(pipeline_server_address)
def __init__( self, name=None, processing_pipeline="SARES20-CAMS142-M5_psen_db", processing_instance="SARES20-CAMS142-M5_psen_db1", spectrometer_camera_channel="SARES20-CAMS142-M5:FPICTURE", delaystage_PV="SLAAR21-LMOT-M524:MOTOR_1", pvname_mirror="SARES23-LIC9", pvname_zoom="SARES20-MF1:MOT_8", mirror_in=15, mirror_out=-5, ): super().__init__(name=name) self.mirror_in_position = mirror_in self.mirror_out_position = mirror_out # Table 1, Benrina hutch self._append(MotorRecord, delaystage_PV, name="delaystage_tt_usd", is_setting=True) self._append(DelayTime, self.delaystage_tt_usd, name="delay", is_setting=True) self.proc_client = PipelineClient() self.proc_pipeline = processing_pipeline self.proc_instance = processing_instance self.spectrometer_camera_channel = spectrometer_camera_channel self._append( Target_xyz, pvname_x="SARES20-MF2:MOT_1", pvname_y="SARES20-MF2:MOT_2", pvname_z="SARES20-MF2:MOT_3", name="target_stages", is_status="recursive", ) self.target = self.target_stages.presets # self._append(MotorRecord, "SARES20-MF2:MOT_1", name="x_target", is_setting=True) # self._append(MotorRecord, "SARES20-MF2:MOT_2", name="y_target", is_setting=True) # self._append(MotorRecord, "SARES20-MF2:MOT_3", name="z_target", is_setting=True) self._append(MotorRecord, "SARES20-MF2:MOT_4", name="zoom_microscope", is_setting=True) self._append( SmaractStreamdevice, pvname_mirror, name="x_mirror_microscope", is_setting=True, is_status=False, ) self._append( AdjustableVirtual, [self.x_mirror_microscope], lambda v: abs(v - self.mirror_in_position) < 0.003, lambda v: self.mirror_in_position if v else self.mirror_out_position, name="mirror_in", is_setting=True, is_status=True, ) self._append( CameraBasler, "SARES20-PROF141-M1", name="camera_microscope", is_setting=True, is_status=False, ) self._append(MotorRecord, pvname_zoom, name="zoom", is_setting=True, is_status=True) self._append( CameraPCO, "SARES20-CAMS142-M5", name="camera_spectrometer", is_setting=True, is_status=False, ) self._append( PvRecord, pvsetname="SLAAR21-LMNP-ESBIR11:DRIVE", pvreadbackname="SLAAR21-LMNP-ESBIR11:MOTRBV", name="las_in_ry", accuracy=10, is_setting=True, ) self._append( PvRecord, pvsetname="SLAAR21-LMNP-ESBIR12:DRIVE", pvreadbackname="SLAAR21-LMNP-ESBIR12:MOTRBV", name="las_in_rx", accuracy=10, is_setting=True, ) self._append( PvRecord, pvsetname="SLAAR21-LMNP-ESBIR13:DRIVE", pvreadbackname="SLAAR21-LMNP-ESBIR13:MOTRBV", name="las_out_rx", accuracy=10, is_setting=True, ) self._append( PvRecord, pvsetname="SLAAR21-LMNP-ESBIR14:DRIVE", pvreadbackname="SLAAR21-LMNP-ESBIR14:MOTRBV", name="las_out_ry", accuracy=10, is_setting=True, )
def get_image(Device_params, numImg, angle=None): if angle == None: angle = 0 pipeline_client = PipelineClient() # pipeline_config = {"camera_name": camName, "image_region_of_interest": ROI} pipeline_config = { "camera_name": Device_params['FullName'], "rotation": angle } instance_id, pipeline_stream_address = pipeline_client.create_instance_from_config( pipeline_config) pipeline_host, pipeline_port = get_host_port_from_stream_address( pipeline_stream_address) img = [] x_profile = [] y_profile = [] x_fit_gauss_function = [] y_fit_gauss_function = [] x_fit_mean = [] y_fit_mean = [] x_fit_standard_deviation = [] y_fit_standard_deviation = [] x_fwhm = [] y_fwhm = [] x_center_of_mass = [] y_center_of_mass = [] intensity = [] max_value = [] width = [] height = [] with source(host=pipeline_host, port=pipeline_port, mode=SUB) as stream: for i in range(0, numImg): data = stream.receive() img.append(data.data.data["image"].value) x_profile.append(data.data.data["x_profile"].value) y_profile.append(data.data.data["y_profile"].value) x_fit_gauss_function.append( data.data.data["x_fit_gauss_function"].value) y_fit_gauss_function.append( data.data.data["y_fit_gauss_function"].value) x_fwhm.append(data.data.data["x_fwhm"].value) y_fwhm.append(data.data.data["y_fwhm"].value) x_center_of_mass.append(data.data.data["x_center_of_mass"].value) y_center_of_mass.append(data.data.data["y_center_of_mass"].value) x_fit_mean.append(data.data.data["x_fit_mean"].value) y_fit_mean.append(data.data.data["y_fit_mean"].value) x_fit_standard_deviation.append( data.data.data["x_fit_standard_deviation"].value) y_fit_standard_deviation.append( data.data.data["y_fit_standard_deviation"].value) intensity.append(data.data.data["intensity"].value) width.append(data.data.data["width"].value) height.append(data.data.data["height"].value) max_value.append(data.data.data["max_value"].value) print(list(data.data.data.keys())) img = np.asarray(img) # Take metedata PhotonEnergy = ep.caget('SARUN08-UIND030:FELPHOTENE.VAL') PulseEnergy = ep.caget('SARFE10-PBPG050:PHOTON-ENERGY-PER-PULSE-US') ATT053 = ep.caget('SARFE10-OATT053:TRANS_RB') APU044_x_pos = ep.caget('SARFE10-OAPU044:MOTOR_X.RBV') APU044_y_pos = ep.caget('SARFE10-OAPU044:MOTOR_Y.RBV') APU044_w_pos = ep.caget('SARFE10-OAPU044:MOTOR_W.RBV') APU044_h_pos = ep.caget('SARFE10-OAPU044:MOTOR_H.RBV') dataout = { "mean": img.mean(axis=0), "image": img, "x_profile": x_profile, "y_profile": y_profile, "x_fwhm": x_fwhm, "y_fwhm": y_fwhm, "x_center_of_mass": x_center_of_mass, "y_center_of_mass": y_center_of_mass, "intensity": intensity, "max_value": max_value, "width": width, "height": height, "camera_name": Device_params['FullName'], "Bit_depth": Device_params['BitDepth'], "PhotonEnergy": PhotonEnergy, "PulseEnergy": PulseEnergy, "x_fit_gauss_function": x_fit_gauss_function, "y_fit_gauss_function": y_fit_gauss_function, "x_fit_mean": x_fit_mean, "y_fit_mean": y_fit_mean, "x_fit_standard_deviation": x_fit_standard_deviation, "y_fit_standard_deviation": y_fit_standard_deviation, "x_axis": data.data.data["x_axis"].value, "y_axis": data.data.data["y_axis"].value, "APU044_x_pos": APU044_x_pos, "APU044_y_pos": APU044_y_pos, "APU044_w_pos": APU044_w_pos, "APU044_h_pos": APU044_h_pos, "ATT053": ATT053 } return dataout
from cam_server import PipelineClient client = PipelineClient() instance_id = "SARES11-SPEC125-M2_psen_db1" # New parameters to set. # [offset_x, size_x, offset_y, size_y] - the offsets are calculated from the top left corner of the image. parameters = { "roi_signal": [300, 2048, 1150, 400], "roi_background": [300, 2048, 600, 400], } client.set_instance_config(instance_id, parameters)
def get_pipelineclient(): global PIPELINE_CLIENT if not PIPELINE_CLIENT: PIPELINE_CLIENT = PipelineClient() return PIPELINE_CLIENT
import pickle import base64 from cam_server import PipelineClient pipeline_client = PipelineClient("http://sf-daqsync-01:8889/") bg = pipeline_client.get_latest_background("SARBD02-DSCR050") image = pipeline_client.get_background_image_bytes(bg) dtype = image["dtype"] shape = image["shape"] bytes = base64.b64decode(image["bytes"].encode()) with open('./bytes.pkl', 'wb') as f: pickle.dump(bytes, f)
def data_streaker_offset(streaker, offset_range, screen, n_images, dry_run, beamline='Aramis'): print( 'Start data_streaker_offset for streaker %s, screen %s, beamline %s, dry_run %s' % (streaker, screen, beamline, dry_run)) meta_dict_1 = get_meta_data(screen) pipeline_client = PipelineClient('http://sf-daqsync-01:8889/') offset_pv = streaker + ':CENTER' current_val = caget(offset_pv + '.RBV') # Start from closer edge of scan if abs(current_val - offset_range[0]) > abs(current_val - offset_range[-1]): offset_range = offset_range[::-1] if dry_run: screen = 'simulation' writables = None positioner = pyscan.TimePositioner(time_interval=(1.1 * n_images), n_intervals=len(offset_range)) else: positions = offset_range * 1e3 # convert to mm positioner = pyscan.VectorPositioner(positions=positions.tolist()) writables = [ pyscan.epics_pv(pv_name=offset_pv, readback_pv_name=offset_pv + '.RBV', tolerance=0.005) ] cam_instance_name = screen + '_sp1' stream_address = pipeline_client.get_instance_stream(cam_instance_name) stream_host, stream_port = get_host_port_from_stream_address( stream_address) # Configure bsread pyscan.config.bs_default_host = stream_host pyscan.config.bs_default_port = stream_port logging.getLogger('mflow.mflow').setLevel(logging.ERROR) settings = pyscan.scan_settings(settling_time=1, n_measurements=n_images, write_timeout=60) readables = get_readables(beamline) raw_output = pyscan.scan(positioner=positioner, readables=readables, settings=settings, writables=writables) result_dict = pyscan_result_to_dict(readables, raw_output, scrap_bs=True) #import pdb; pdb.set_trace() for ax in ['x_axis', 'y_axis']: arr = result_dict[ax] * 1e-6 if len(arr.shape) == 3: result_dict[ax + '_m'] = arr[0][0] elif len(arr.shape) == 2: result_dict[ax + '_m'] = arr[0] else: raise ValueError('Unexpected', len(arr.shape)) meta_dict_2 = get_meta_data(screen) output = { 'pyscan_result': result_dict, 'streaker_offsets': offset_range, 'screen': screen, 'n_images': n_images, 'dry_run': dry_run, 'streaker': streaker, 'meta_data_begin': meta_dict_1, 'meta_data_end': meta_dict_2, } print('End data_streaker_offset') return output