Skip to content

Commit

Permalink
Merge pull request #349 from sot/use-cxotime-now-for-default-stop
Browse files Browse the repository at this point in the history
Use CXOTIME_NOW, deprecate KADI_COMMANDS_DEFAULT_STOP for default stop
  • Loading branch information
taldcroft authored Feb 8, 2025
2 parents e14977a + 9b02563 commit 6bac076
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 42 deletions.
40 changes: 33 additions & 7 deletions docs/commands_states/commands_details.rst
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ of the 2021:296 NSM recovery::
>>> events_cti.write(path_cti, overwrite=True)

>>> import os
>>> os.environ['KADI_COMMANDS_DEFAULT_STOP'] = '2021:299'
>>> os.environ['CXOTIME_NOW'] = '2021:299'

>>> cmds = get_cmds('2021:296:10:35:00', '2021:298:01:58:00', scenario='nsm-cti')
>>> cmds[cmds['event'] == 'RTS'].pprint_like_backstop()
Expand Down Expand Up @@ -190,21 +190,47 @@ forgetting to revert it later.
Environment variables
---------------------

``CXOTIME_NOW``
For testing and demonstration purposes, this environment variable can be set to make
the code believe that ``CXOTIME_NOW`` is the current time. See the
`Mocking the current time`_ section for more details.

``KADI``
Override the default location of kadi flight data files ``cmds2.h5`` and
``cmds2.pkl``.

``KADI_COMMANDS_DEFAULT_STOP``
For testing and demonstration purposes, this environment variable can be set
to a date which is used as the default stop time for commands. In effect this
makes the code believe that this is the current time and that there are no
command loads available after this time.

``KADI_SCENARIO``
Set the default scenario. This can be used to set the scenario in an
application that is not aware of kadi scenarios, effectively a back door to
override the flight commands.

Mocking the current time
------------------------
Setting the ``CXOTIME_NOW`` environment variable allows you to pretend that the current
time is a different time. Any calls to ``CxoTime`` or ``DateTime`` that normally return
the current time will now return a time object corresponding to ``CXOTIME_NOW``.

Many Ska functions have a ``stop`` argument that defaults to the current time, so setting
``CXOTIME_NOW`` will change the behavior of these functions.

For kadi commands functions, the situation is a bit more complex. Because kadi commands
are *predictive*, the default ``stop`` used by :func:`~kadi.commands.get_cmds` is the
current time plus one year. If ``CXOTIME_NOW`` is set, the "current time" will be the
value of ``CXOTIME_NOW`` and the default ``stop`` will be one year after that.

Setting ``CXOTIME_NOW`` also impacts the behavior of commands ingest and generation:

- Only Chandra Command Events that are before this time will be included.
- Only weekly approved loads with a load date before this time will be included. The
load date of a weekly load set is midnight on date of the load name, so JAN2025A
has a load date of 2025:020:00:00:00.
- Kadi commands dynamically regenerates recent commands (normally within 30 days of
the current time) from the weekly approved loads and the Chandra Command Events.
This is done to ensure that the commands are up-to-date with the current state of
the spacecraft. If ``CXOTIME_NOW`` is set, the commands will be regenerated from
the weekly approved loads and Chandra Command Events that are 30 days before this
time.

Data files and resources
------------------------

Expand Down
30 changes: 14 additions & 16 deletions kadi/commands/commands_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
LazyVal,
_find,
get_cmds_from_backstop,
get_default_stop,
get_par_idx_update_pars_dict,
load_idx_cmds,
load_name_to_cxotime,
Expand Down Expand Up @@ -222,19 +223,16 @@ def get_cmds(
Parameters
----------
start : CxoTime-like
Start time for cmds
stop : CxoTime-like
Stop time for cmds
scenario : str, None
Scenario name
start : CxoTime-like, optional
Start time for cmds. Default is 1999:001.
stop : CxoTime-like, optional
Stop time for cmds. Default is current time + 1 year.
scenario : str, optional
Name of commands archive scenario to use instead of default.
inclusive_stop : bool
Include commands at exactly ``stop`` if True.
loads_stop : CxoTime-like, None
Stop time for loads table (default is all available loads, but useful
for development/testing work)
**kwargs : dict
key=val keyword argument pairs for filtering
key=val keyword argument pairs for filtering.
Returns
-------
Expand All @@ -248,7 +246,7 @@ def get_cmds(
stop = (CxoTime.now() + 1 * u.year) if stop is None else CxoTime(stop)

# Default stop is either now (typically) or set by env var
default_stop = CxoTime(os.environ.get("KADI_COMMANDS_DEFAULT_STOP"))
default_stop = CxoTime(get_default_stop())

# For flight scenario or no internet or if the query stop time is guaranteed
# to not require recent commands then just use the archive.
Expand Down Expand Up @@ -1014,7 +1012,7 @@ def update_cmd_events(scenario=None) -> Table:
ok = np.isin(cmd_events["State"], allowed_states)
cmd_events = cmd_events[ok]

# If KADI_COMMANDS_DEFAULT_STOP is set, filter out events after that date.
# If CXOTIME_NOW is set, filter out events after that date.
cmd_events = filter_cmd_events_default_stop(cmd_events)

logger.info(f"Writing {len(cmd_events)} cmd_events to {cmd_events_path}")
Expand Down Expand Up @@ -1042,14 +1040,14 @@ def get_cmd_events(scenario=None):
str(cmd_events_path), format="csv", fill_values=[], converters={"Params": str}
)

# If KADI_COMMANDS_DEFAULT_STOP is set, filter out events after that date.
# If CXOTIME_NOW is set, filter out events after that date.
cmd_events = filter_cmd_events_default_stop(cmd_events)

return cmd_events


def filter_cmd_events_default_stop(cmd_events):
if (stop := os.environ.get("KADI_COMMANDS_DEFAULT_STOP")) is not None:
if (stop := get_default_stop()) is not None:
stop = CxoTime(stop)
# Filter table based on stop date. Need to use CxoTime on each event separately
# because the date format could be inconsistent.
Expand All @@ -1066,7 +1064,7 @@ def update_loads(scenario=None, *, cmd_events=None, lookback=None, stop=None) ->
"""Update local copy of approved command loads though ``lookback`` days."""
# For testing allow override of default `stop` value
if stop is None:
stop = os.environ.get("KADI_COMMANDS_DEFAULT_STOP")
stop = get_default_stop()

if lookback is None:
lookback = conf.default_lookback
Expand Down Expand Up @@ -1287,7 +1285,7 @@ def update_cmds_archive(
"""
# For testing allow override of default `stop` value
if stop is None:
stop = os.environ.get("KADI_COMMANDS_DEFAULT_STOP")
stop = get_default_stop()

# Local context manager for log_level and data_root
kadi_logger = logging.getLogger("kadi")
Expand Down
23 changes: 23 additions & 0 deletions kadi/commands/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import calendar
import functools
import logging
import os
import pickle
import struct
import warnings
Expand Down Expand Up @@ -1107,3 +1108,25 @@ def ska_load_dir(load_name: str) -> Path:
from parse_cm.paths import load_dir_from_load_name

return load_dir_from_load_name(load_name)


def get_default_stop() -> str | None:
"""Get the default stop date for kadi commands.
This returns the value of the CXOTIME_NOW environment variable if set,
otherwise the value of the KADI_COMMANDS_DEFAULT_STOP environment variable,
otherwise None.
"""

stop = os.environ.get(
"CXOTIME_NOW", kadi_stop := os.environ.get("KADI_COMMANDS_DEFAULT_STOP")
)

if kadi_stop:
warnings.warn(
"Setting KADI_COMMANDS_DEFAULT_STOP env var is deprecated, use CXOTIME_NOW",
UserWarning,
stacklevel=2,
)

return stop
32 changes: 16 additions & 16 deletions kadi/commands/states.py
Original file line number Diff line number Diff line change
Expand Up @@ -2139,22 +2139,22 @@ def get_states(
Parameters
----------
start
start of states (optional, DateTime compatible)
stop
stop of states (optional, DateTime compatible)
state_keys
state keys of interest (optional, list or str or None)
cmds
input commands (optional, CmdList, CommandTable)
continuity
initial state (optional, dict)
reduce
call reduce_states() on output
merge_identical
merge identical states (see reduce_states() docs)
scenario
commands archive scenario to use
start : CxoTime-like, optional
Start of states (default is 1999:001).
stop : CxoTime-like, optional
Stop of states (default is current time + 1 year).
state_keys : list of str, optional
State keys of interest.
cmds : CmdList, CommandTable, optional
Input commands.
continuity : dict, optional
Initial state.
reduce : bool, optional
Call reduce_states() on output (default=True).
merge_identical : bool, optional
Merge identical states (see reduce_states() docs, default=False).
scenario : str, optional
Name of commands archive scenario to use instead of default.
Returns
-------
Expand Down
4 changes: 2 additions & 2 deletions kadi/commands/tests/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ def stop_date_fixture_factory(stop_date):
@pytest.fixture()
def stop_date_fixture(monkeypatch):
commands.clear_caches()
monkeypatch.setenv("KADI_COMMANDS_DEFAULT_STOP", stop_date)
monkeypatch.setenv("CXOTIME_NOW", stop_date)
cmds_dir = Path(conf.commands_dir) / CxoTime(stop_date).iso[:9]
with commands.conf.set_temp("commands_dir", str(cmds_dir)):
yield
Expand Down Expand Up @@ -1281,7 +1281,7 @@ def test_scenario_with_rts(monkeypatch, fast_sun_position_method):
# example in the documentation.
from kadi import paths

monkeypatch.setenv("KADI_COMMANDS_DEFAULT_STOP", "2021:299")
monkeypatch.setenv("CXOTIME_NOW", "2021:299")

# Ensure local cmd_events.csv is up to date by requesting "recent" commands
# relative to the default stop.
Expand Down
2 changes: 1 addition & 1 deletion kadi/commands/tests/test_validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def regress_stop(local_testing):
To see what is happening behind the scenes, update the code to enable kadi debug
logging (kadi.commands.logger.setLevel("DEBUG")) and run the tests with ``-s``.
"""
with temp_env_var("KADI_COMMANDS_DEFAULT_STOP", REGRESSION_STOP):
with temp_env_var("CXOTIME_NOW", REGRESSION_STOP):
yield


Expand Down

0 comments on commit 6bac076

Please sign in to comment.