diff --git a/docs/commands_states.rst b/docs/commands_states.rst index 0585cf0b..8afa8083 100644 --- a/docs/commands_states.rst +++ b/docs/commands_states.rst @@ -509,6 +509,9 @@ classes which affect the keys. .. Run kadi.commands.states.print_state_keys_transition_classes_docs() to generate this list. +``acisfp_setpoint`` + - :class:`~kadi.commands.states.ACISFP_SetPointTransition` + ``aoephem1``, ``aoephem2``, ``aoratio``, ``aoargper``, ``aoeccent``, ``ao1minus``, ``ao1plus``, ``aomotion``, ``aoiterat``, ``aoorbang``, ``aoperige``, ``aoascend``, ``aosini``, ``aoslr``, ``aosqrtmu`` - :class:`~kadi.commands.states.EphemerisTransition` diff --git a/kadi/commands/states.py b/kadi/commands/states.py index 688a83aa..2e1b18dd 100644 --- a/kadi/commands/states.py +++ b/kadi/commands/states.py @@ -4,6 +4,7 @@ """ from __future__ import division, print_function, absolute_import +import re import collections import itertools import inspect @@ -979,6 +980,41 @@ def set_transitions(cls, transitions, cmds, start, stop): transitions[date].update(si_mode='TE_' + tlmsid[2:7]) +class ACISFP_SetPointTransition(BaseTransition): + """ + Implement transitions for ACIS focal plane temperature setpoint state. + + Looks for ACISPKT commands with TLMSID like ``WSFTNEG``, where the + ACIS FP setpoint temperature is ``-``. + """ + command_attributes = {'type': 'ACISPKT'} + state_keys = ['acisfp_setpoint'] + default_value = -121.0 + + @classmethod + def set_transitions(cls, transitions, 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) + for cmd in state_cmds: + tlmsid = cmd['tlmsid'] + date = cmd['date'] + + if tlmsid.startswith('WSFTNEG'): + match = re.search(r'(\d+)$', tlmsid) + if not match: + raise ValueError(f'unable to parse command {tlmsid}') + transitions[date].update(acisfp_setpoint=-float(match.group(1))) + + ################################################################### # State transitions processing code ################################################################### @@ -1414,6 +1450,18 @@ def get_continuity(date=None, state_keys=None, lookbacks=(7, 30, 180, 1000)): return continuity +def interpolate_states(states, times): + """Interpolate ``states`` table at given times. + + :param states: states (np.recarray) + :param times: times (np.array or list) + + :returns: ``states`` view at ``times`` + """ + indexes = np.searchsorted(states['tstop'], times) + return states[indexes] + + def _unique(seq): """Return unique elements of ``seq`` in order""" seen = set() diff --git a/kadi/commands/tests/test_states.py b/kadi/commands/tests/test_states.py index 5c477a4f..fd87738a 100644 --- a/kadi/commands/tests/test_states.py +++ b/kadi/commands/tests/test_states.py @@ -1246,3 +1246,30 @@ def test_get_pitch_from_mid_maneuver(): assert np.all(exp['datestop'] == sts['datestop']) assert np.all(exp['pcad_mode'] == sts['pcad_mode']) assert np.all(np.isclose(exp['pitch'], sts['pitch'], rtol=0, atol=1e-8)) + + +def test_acisfp_setpoint_state(): + sts = states.get_states('1999-01-01', '2004-01-01', state_keys='acisfp_setpoint') + assert repr(sts).splitlines() == [ + '', + ' datestart datestop acisfp_setpoint trans_keys ', + ' str21 str21 float64 object ', + '--------------------- --------------------- --------------- ---------------', + '1999:001:12:00:00.000 2003:130:05:07:28.341 -121.0 ', + '2003:130:05:07:28.341 2003:130:19:09:28.930 -130.0 acisfp_setpoint', + '2003:130:19:09:28.930 2003:132:14:22:33.782 -121.0 acisfp_setpoint', + '2003:132:14:22:33.782 2003:133:22:04:22.425 -130.0 acisfp_setpoint', + '2003:133:22:04:22.425 2004:001:12:00:00.000 -121.0 acisfp_setpoint'] + + sts = states.get_states('2018-01-01', '2020-03-01', state_keys='acisfp_setpoint') + assert repr(sts).splitlines() == [ + '
', + ' datestart datestop acisfp_setpoint trans_keys ', + ' str21 str21 float64 object ', + '--------------------- --------------------- --------------- ---------------', + '2018:001:12:00:00.000 2018:249:20:16:04.603 -121.0 ', + '2018:249:20:16:04.603 2018:250:07:19:51.657 -126.0 acisfp_setpoint', + '2018:250:07:19:51.657 2018:294:22:29:00.000 -121.0 acisfp_setpoint', + '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']