Skip to content

Commit

Permalink
Merge pull request #210 from sot/grating-move-duration-again
Browse files Browse the repository at this point in the history
Make changes for grating move duration (again)
  • Loading branch information
taldcroft authored Oct 22, 2021
2 parents d246971 + 4a9d49d commit a11c3d2
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 11 deletions.
87 changes: 81 additions & 6 deletions kadi/commands/states.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
This module provides the functions for dynamically determining Chandra commanded states
based entirely on known history of commands.
"""
from __future__ import division, print_function, absolute_import

import contextlib
import re
import collections
import itertools
Expand All @@ -12,8 +11,10 @@
import numpy as np

from astropy.table import Table, Column
import astropy.units as u

from Chandra.Time import DateTime, date2secs, secs2date
from cxotime import CxoTime
import Chandra.Maneuver
from Quaternion import Quat
import Ska.Sun
Expand Down Expand Up @@ -51,6 +52,17 @@
'vid_board')


@contextlib.contextmanager
def disable_grating_move_duration():
"""
Temporarily disable the grating move duration
"""
apply_move_duration = MechMove.apply_move_duration
MechMove.apply_move_duration = False
yield
MechMove.apply_move_duration = apply_move_duration


class NoTransitionsError(ValueError):
"""No transitions found within commands"""
pass
Expand Down Expand Up @@ -378,36 +390,99 @@ class SubFormatSSR_Transition(FixedTransition):
# Mech transitions
###################################################################

class HETG_INSR_Transition(FixedTransition):
class MechMove(FixedTransition):
"""
Transitions for mech moves that have non-zero duration.
This adds two transitions per matched command:
- First one at cmd time with the transition value with ``_MOVE`` appended
- Second one at cmd time + move_duration with the straight transition value
This inherits from FixedTransition for the case of an attribute that gets
set to a fixed value when the command occurs, e.g. pcad_mode='NMAN' for
AONMMODE.
Class attributes:
:param transition_key: single transition key or list of transition keys
:param transition_val: single transition value or list of values
:param move_duration: duration of the move (astropy time Quantity)
:param apply_move_duration: if True, apply the move duration to states
"""
apply_move_duration = True

@classmethod
def set_transitions(cls, transitions_dict, cmds, start, stop):
"""
Set transitions for a Table of commands ``cmds``.
:param transitions_dict: global dict of transitions (updated in-place)
:param cmds: commands (CmdList)
:param start: start time for states
:param stop: stop time for states
:returns: None
"""
state_cmds = cls.get_state_changing_commands(cmds)
vals = cls.transition_val
attrs = cls.transition_key
move_duration = cls.move_duration

if not isinstance(vals, list):
vals = [vals]
if not isinstance(attrs, list):
attrs = [attrs]

for cmd in state_cmds:
date_start = CxoTime(cmd['date'])
date_stop = date_start + move_duration
for val, attr in zip(vals, attrs):
if attr == 'grating':
transitions_dict[date_start.date][attr] = val
else:
# 'letg' or 'hetg' insert/retract status, include the move
# interval here
if cls.apply_move_duration:
transitions_dict[date_start.date][attr] = val + '_MOVE'
transitions_dict[date_stop.date][attr] = val
else:
transitions_dict[date_start.date][attr] = val


class HETG_INSR_Transition(MechMove):
"""HETG insertion"""
command_attributes = {'tlmsid': '4OHETGIN'}
state_keys = ['letg', 'hetg', 'grating']
transition_key = ['hetg', 'grating']
transition_val = ['INSR', 'HETG']
move_duration = 157 * u.s


class HETG_RETR_Transition(FixedTransition):
class HETG_RETR_Transition(MechMove):
"""HETG retraction"""
command_attributes = {'tlmsid': '4OHETGRE'}
state_keys = ['letg', 'hetg', 'grating']
transition_key = ['hetg', 'grating']
transition_val = ['RETR', 'NONE']
move_duration = 153 * u.s


class LETG_INSR_Transition(FixedTransition):
class LETG_INSR_Transition(MechMove):
"""LETG insertion"""
command_attributes = {'tlmsid': '4OLETGIN'}
state_keys = ['letg', 'hetg', 'grating']
transition_key = ['letg', 'grating']
transition_val = ['INSR', 'LETG']
move_duration = 203 * u.s


class LETG_RETR_Transition(FixedTransition):
class LETG_RETR_Transition(MechMove):
"""LETG retraction"""
command_attributes = {'tlmsid': '4OLETGRE'}
state_keys = ['letg', 'hetg', 'grating']
transition_key = ['letg', 'grating']
transition_val = ['RETR', 'NONE']
move_duration = 203 * u.s


class SimTscTransition(ParamTransition):
Expand Down
34 changes: 29 additions & 5 deletions kadi/commands/tests/test_states.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,9 @@ def get_states_test(start, stop, state_keys, continuity=None):
lenr = len(rcstates)

cmds = commands.get_cmds(start - 7, stop)
kstates = states.get_states(state_keys=state_keys, cmds=cmds,
continuity=continuity, reduce=False)
with states.disable_grating_move_duration():
kstates = states.get_states(state_keys=state_keys, cmds=cmds,
continuity=continuity, reduce=False)
rkstates = states.reduce_states(kstates, state_keys, merge_identical=True)[-lenr:]

return rcstates, rkstates
Expand Down Expand Up @@ -155,7 +156,9 @@ def test_quick():

# Now test using start/stop pair with start/stop and no supplied cmds or continuity.
# This also tests the API kwarg order: datestart, datestop, state_keys, ..)
sts = states.get_states('2018:235:12:00:00', '2018:245:12:00:00', state_keys, reduce=False)
with states.disable_grating_move_duration():
sts = states.get_states('2018:235:12:00:00', '2018:245:12:00:00',
state_keys, reduce=False)
assert np.all(DateTime(sts['tstart']).date == sts['datestart'])
assert np.all(DateTime(sts['tstop']).date == sts['datestop'])

Expand Down Expand Up @@ -383,7 +386,8 @@ def test_get_continuity_regress():
'targ_q4': '2018:001:11:52:10.175',
'vid_board': '2018:001:11:58:21.735'}

continuity = states.get_continuity('2018:001:12:00:00')
with states.disable_grating_move_duration():
continuity = states.get_continuity('2018:001:12:00:00')

for key, val in expected.items():
if isinstance(val, (int, str)):
Expand Down Expand Up @@ -552,7 +556,8 @@ def test_reduce_states_cmd_states():

# Default setting is reduce states with merge_identical=False, which is the same
# as cmd_states.
ksr = states.get_states('2018:235:12:00:00', '2018:245:12:00:00', state_keys)
with states.disable_grating_move_duration():
ksr = states.get_states('2018:235:12:00:00', '2018:245:12:00:00', state_keys)

assert len(ksr) == len(cs)

Expand Down Expand Up @@ -1453,3 +1458,22 @@ def test_acisfp_setpoint_state():
'2018:294:22:29:00.000 2020:048:20:59:22.304 -121.0 acisfp_setpoint',
'2020:048:20:59:22.304 2020:049:13:05:52.537 -126.0 acisfp_setpoint',
'2020:049:13:05:52.537 2020:061:12:00:00.000 -121.0 acisfp_setpoint']


def test_grating_motion_states():
sts = states.get_states('2021:227:12:00:00', '2021:230:12:00:00',
state_keys=['letg', 'hetg', 'grating'])
del sts['tstart']
del sts['tstop']
exp = [' datestart datestop letg hetg grating trans_keys ',
'--------------------- --------------------- --------- --------- ------- ------------',
'2021:227:12:00:00.000 2021:227:23:06:03.276 RETR RETR NONE ',
'2021:227:23:06:03.276 2021:227:23:08:40.276 RETR INSR_MOVE HETG grating,hetg',
'2021:227:23:08:40.276 2021:228:08:15:00.722 RETR INSR HETG hetg',
'2021:228:08:15:00.722 2021:228:08:17:33.722 RETR RETR_MOVE NONE grating,hetg',
'2021:228:08:17:33.722 2021:229:17:41:45.525 RETR RETR NONE hetg',
'2021:229:17:41:45.525 2021:229:17:45:08.525 INSR_MOVE RETR LETG grating,letg',
'2021:229:17:45:08.525 2021:230:00:37:56.002 INSR RETR LETG letg',
'2021:230:00:37:56.002 2021:230:00:41:19.002 RETR_MOVE RETR NONE grating,letg',
'2021:230:00:41:19.002 2021:230:12:00:00.000 RETR RETR NONE letg']
assert sts.pformat_all() == exp

0 comments on commit a11c3d2

Please sign in to comment.