From 1190da0c2d58701edb3393e71b23389bc8928b95 Mon Sep 17 00:00:00 2001 From: laurensaunders Date: Wed, 7 Sep 2022 15:59:30 -0400 Subject: [PATCH] New parameter for scan start position in generator scans (#323) * New parameter for scan start position in generator scans Include new string parameter az_start to indicate the beginning point of a generator scan. Defaults to starting scans from the midpoint between the two az endpoint inputs. * Add parameters to generate_scan process * Add defaults to params in generate_scan No longer require user to provide all inputs for generate_scan. All new options still exist, but now have default values. * Keyword arguments update, fix typos Create dictionary of optional params in generate_scan and ** method of passing them. Fix indentation in docstring, remove ptstack_fmt from docstring, fix docstring typo Co-authored-by: simonsobs Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- agents/acu/acu_agent.py | 37 ++++++++++++++++++++++++++++++------ agents/acu/scan_helpers.py | 39 ++++++++++++++++++++++++++++---------- 2 files changed, 60 insertions(+), 16 deletions(-) diff --git a/agents/acu/acu_agent.py b/agents/acu/acu_agent.py index 09c5d7146..d6c9bd0fc 100644 --- a/agents/acu/acu_agent.py +++ b/agents/acu/acu_agent.py @@ -946,7 +946,9 @@ def _run_specified_scan(self, session, times, azs, els, vas, ves, azflags, elfla def generate_scan(self, session, params): """generate_scan(az_endpoint1=None, az_endpoint2=None, az_speed=None, \ acc=None, el_endpoint1=None, el_endpoint2=None, \ - el_speed=None) + el_speed=None, num_batches=None, start_time=None, \ + wait_to_start=None, step_time=None, batch_size=None, \ + az_start=None) **Process** - Scan generator, currently only works for constant-velocity az scans with fixed elevation. @@ -961,7 +963,22 @@ def generate_scan(self, session, params): currently both el endpoints should be equal el_speed (float): speed of motion for a scan with changing elevation. For dev, currently set to 0.0 - + num_batches (int or None): sets the number of batches for the + generator to create. Default value is None (interpreted as infinite + batches). + start_time (float or None): a ctime at which to start the scan. + Default is None, interpreted as now + wait_to_start (float): number of seconds to wait before starting a + scan. Default is 3 seconds + step_time (float): time between points on the constant-velocity + parts of the motion. Default is 0.1 s. Minimum 0.05 s + batch_size (int): number of values to produce in each iteration. + Default is 500. Batch size is reset to the length of one leg of the + motion if num_batches is not None. + az_start (str): part of the scan to start at. Options are: + 'az_endpoint1', 'az_endpoint2', 'mid_inc' (start in the middle of + the scan and start with increasing azimuth), 'mid_dec' (start in + the middle of the scan and start with decreasing azimuth). """ ok, msg = self._try_set_job('control') if not ok: @@ -972,12 +989,20 @@ def generate_scan(self, session, params): az_speed = params.get('az_speed') acc = params.get('acc') el_endpoint1 = params.get('el_endpoint1') - el_endpoint2 = params.get('el_endpoint2') - el_speed = params.get('el_speed') + scan_params = {k: params.get(k) for k in ['num_batches', 'start_time', + 'wait_to_start', 'step_time', 'batch_size', 'az_start'] + if params.get(k) is not None} + el_endpoint2 = params.get('el_endpoint2', el_endpoint1) + el_speed = params.get('el_speed', 0.0) yield self.acu_control.stop() - g = sh.generate_constant_velocity_scan(az_endpoint1, az_endpoint2, - az_speed, acc, el_endpoint1, el_endpoint2, el_speed) + g = sh.generate_constant_velocity_scan(az_endpoint1=az_endpoint1, + az_endpoint2=az_endpoint2, + az_speed=az_speed, acc=acc, + el_endpoint1=el_endpoint1, + el_endpoint2=el_endpoint2, + el_speed=el_speed, + **scan_params) self.acu_control.mode('ProgramTrack') while self.jobs['control'] == 'run': lines = next(g) diff --git a/agents/acu/scan_helpers.py b/agents/acu/scan_helpers.py index 213250744..cc7083561 100644 --- a/agents/acu/scan_helpers.py +++ b/agents/acu/scan_helpers.py @@ -175,7 +175,7 @@ def generate_constant_velocity_scan(az_endpoint1, az_endpoint2, az_speed, el_speed, num_batches=None, start_time=None, wait_to_start=3., step_time=0.1, batch_size=500, - ptstack_fmt=True): + az_start='mid_inc', ptstack_fmt=True): """ Python generator to produce times, azimuth and elevation positions, azimuth and elevation velocities, azimuth and elevation flags for @@ -206,6 +206,10 @@ def generate_constant_velocity_scan(az_endpoint1, az_endpoint2, az_speed, batch_size (int): number of values to produce in each iteration. Default is 500. Batch size is reset to the length of one leg of the motion if num_batches is not None. + az_start (str): part of the scan to start at. Options are: + 'az_endpoint1', 'az_endpoint2', 'mid_inc' (start in the middle of + the scan and start with increasing azimuth), 'mid_dec' (start in + the middle of the scan and start with decreasing azimuth). ptstack_fmt (bool): determine whether values are produced with the necessary format to upload to the ACU. If False, this function will produce lists of time, azimuth, elevation, azimuth velocity, @@ -214,13 +218,36 @@ def generate_constant_velocity_scan(az_endpoint1, az_endpoint2, az_speed, """ az_min = min(az_endpoint1, az_endpoint2) az_max = max(az_endpoint1, az_endpoint2) + if az_max == az_min: + raise ValueError('Generator requires two different az endpoints!') + if az_start in ['az_endpoint1', 'az_endpoint2']: + if az_start == 'az_endpoint1': + az = az_endpoint1 + else: + az = az_endpoint2 + if az == az_min: + increasing = True + az_vel = az_speed + elif az == az_max: + increasing = False + az_vel = -1 * az_speed + elif az_start in ['mid_inc', 'mid_dec']: + az = (az_endpoint1 + az_endpoint2) / 2 + if az_start == 'mid_inc': + increasing = True + az_vel = az_speed + else: + increasing = False + az_vel = -1 * az_speed + else: + raise ValueError('az_start value not supported. Choose from ' + 'az_endpoint1, az_endpoint2, mid_inc, mid_dec') if start_time is None: t0 = time.time() + wait_to_start else: t0 = start_time t = 0 turntime = 2.0 * az_speed / acc - az = az_endpoint1 el = el_endpoint1 if step_time < 0.05: raise ValueError('Time step size too small, must be at least ' @@ -229,14 +256,6 @@ def generate_constant_velocity_scan(az_endpoint1, az_endpoint2, az_speed, el_vel = el_speed az_flag = 0 el_flag = 0 - if az < az_endpoint2: - increasing = True - az_vel = az_speed - elif az > az_endpoint2: - increasing = False - az_vel = -1 * az_speed - else: - raise ValueError('Need two different motion endpoints') if num_batches is None: stop_iter = float('inf') else: