Skip to content

Commit a025c94

Browse files
committed
Further rework of stop time handling in commands
1 parent 3cf3b89 commit a025c94

File tree

2 files changed

+45
-44
lines changed

2 files changed

+45
-44
lines changed

kadi/commands/commands_v2.py

+41-40
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
LazyVal,
3131
_find,
3232
get_cmds_from_backstop,
33-
get_default_stop,
33+
get_cxotime_now,
3434
get_par_idx_update_pars_dict,
3535
load_idx_cmds,
3636
load_name_to_cxotime,
@@ -252,17 +252,20 @@ def get_cmds(
252252
scenario = os.environ.get("KADI_SCENARIO", scenario)
253253
start = CxoTime("1999:001" if start is None else start)
254254
stop = (CxoTime.now() + 1 * u.year) if stop is None else CxoTime(stop)
255+
lookback = conf.default_lookback
255256

256-
# Default stop is either now (typically) or set by env var
257-
default_stop = CxoTime(get_default_stop())
257+
# Get current "now" time, which might be mocked via CXOTIME_NOW.
258+
# get_cxotime_now() returns None if the env var is not set.
259+
cxotime_now = get_cxotime_now()
260+
now = CxoTime(cxotime_now)
258261

259-
# Cache key used for CMDS_RECENT and MATCHING_BLOCKS.
260-
# TODO: make more complete.
261-
cache_key = scenario
262+
# Cache key used for CMDS_RECENT and MATCHING_BLOCKS. These are all the relevant
263+
# kwargs in update_archive_and_get_cmds_recent().
264+
cache_key = scenario, cxotime_now, lookback, event_filter
262265

263266
# For flight scenario or no internet or if the query stop time is guaranteed
264267
# to not require recent commands then just use the archive.
265-
before_recent_cmds = stop < default_stop - conf.default_lookback * u.day
268+
before_recent_cmds = stop < now - lookback * u.day
266269
if scenario == "flight" or not HAS_INTERNET or before_recent_cmds:
267270
cmds = IDX_CMDS
268271
logger.info(
@@ -271,8 +274,10 @@ def get_cmds(
271274
)
272275
else:
273276
if cache_key not in CMDS_RECENT:
274-
cmds_recent = update_archive_and_get_cmds_recent(
277+
cmds_recent = update_cmd_events_and_loads_and_get_cmds_recent(
275278
scenario,
279+
lookback=lookback,
280+
stop_loads=cxotime_now,
276281
cache=True,
277282
pars_dict=PARS_DICT,
278283
rev_pars_dict=REV_PARS_DICT,
@@ -351,11 +356,11 @@ def get_cmds(
351356
# APR0122 commands will also not be in the archive.
352357

353358

354-
def update_archive_and_get_cmds_recent(
359+
def update_cmd_events_and_loads_and_get_cmds_recent(
355360
scenario=None,
356361
*,
357362
lookback=None,
358-
stop=None,
363+
stop_loads=None,
359364
cache=True,
360365
pars_dict=None,
361366
rev_pars_dict=None,
@@ -377,8 +382,8 @@ def update_archive_and_get_cmds_recent(
377382
lookback : int, None
378383
Lookback time from ``stop`` for recent loads in days. If None, use
379384
conf.default_lookback.
380-
stop : CxoTime-like, None
381-
Stop time for recent loads. If None, use default_stop.
385+
stop_loads : CxoTime-like[str], None
386+
Stop time for recent loads. If None, use get_cxotime_now().
382387
cache : bool
383388
Cache the result in CMDS_RECENT dict.
384389
pars_dict : dict, None
@@ -396,10 +401,9 @@ def update_archive_and_get_cmds_recent(
396401
"""
397402
# List of CommandTable objects from loads and cmd_events
398403
cmds_list: List[CommandTable] = []
399-
default_stop = get_default_stop()
400404

401405
# Update local cmds_events.csv from Google Sheets
402-
cmd_events = update_cmd_events(scenario, event_filter, default_stop)
406+
cmd_events = update_cmd_events(scenario, event_filter)
403407

404408
# Get load names that were not run at all or where observing was not run.
405409
# E.g. an SCS-107 near end of loads where next week vehicle loads only were
@@ -413,7 +417,7 @@ def update_archive_and_get_cmds_recent(
413417
}
414418

415419
# Update loads table and download/archive backstop files from OCCweb
416-
loads = update_loads(scenario, lookback=lookback, stop=stop)
420+
loads = update_loads(scenario, lookback=lookback, stop_loads=stop_loads)
417421
logger.info(f"Including loads {', '.join(loads['name'])}")
418422

419423
for load in loads:
@@ -454,11 +458,11 @@ def update_archive_and_get_cmds_recent(
454458

455459
# Filter events outside the time interval, assuming command event cannot
456460
# last more than 2 weeks.
457-
start = CxoTime(min(loads["cmd_start"]))
458-
stop = CxoTime(max(loads["cmd_stop"]))
461+
start_cmds = CxoTime(min(loads["cmd_start"]))
462+
stop_cmds = CxoTime(max(loads["cmd_stop"]))
459463
# Allow for variations in input format of date
460464
dates = np.array([CxoTime(date).date for date in cmd_events["Date"]], dtype=str)
461-
bad = (dates < (start - 14 * u.day).date) | (dates > stop.date)
465+
bad = (dates < (start_cmds - 14 * u.day).date) | (dates > stop_cmds.date)
462466
cmd_events = cmd_events[~bad]
463467
cmd_events_ids = [evt["Event"] + " at " + evt["Date"] for evt in cmd_events]
464468
if len(cmd_events) > 0:
@@ -530,7 +534,7 @@ def update_archive_and_get_cmds_recent(
530534
cmds_recent.deduplicate_orbit_cmds()
531535
cmds_recent.remove_not_run_cmds()
532536
cmds_recent = add_obs_cmds(cmds_recent, pars_dict, rev_pars_dict)
533-
cmds_recent.meta["loads_start"] = start.date
537+
cmds_recent.meta["loads_start"] = start_cmds.date
534538

535539
if cache:
536540
# Cache recent commands so future requests for the same scenario are fast
@@ -998,7 +1002,6 @@ def is_google_id(scenario):
9981002
def update_cmd_events(
9991003
scenario=None,
10001004
event_filter: Callable | list[Callable] | None = None,
1001-
default_stop: CxoTime | None = None,
10021005
) -> Table:
10031006
"""Update local cmd_events.csv from Google Sheets and read events for ``scenario``.
10041007
@@ -1025,9 +1028,6 @@ def update_cmd_events(
10251028
Callable function or list of callable functions that takes an Event Table as
10261029
input and returns a boolean mask with same length as Table. This is used to
10271030
select rows from the Table. If None, no filtering is done.
1028-
default_stop : CxoTime, None
1029-
Default stop time for filtering events. Normally None, which implies no
1030-
filtering, but this can be set via the CXOTIME_NOW environment variable.
10311031
10321032
Returns
10331033
-------
@@ -1054,8 +1054,8 @@ def update_cmd_events(
10541054
event_filters.append(filter_cmd_events_state)
10551055

10561056
# If CXOTIME_NOW is set, filter out events after that date.
1057-
if default_stop is not None:
1058-
event_filters.append(filter_cmd_events_date_stop(default_stop))
1057+
if cxotime_now := get_cxotime_now():
1058+
event_filters.append(filter_cmd_events_date_stop(cxotime_now))
10591059

10601060
if event_filters:
10611061
ok = np.ones(len(cmd_events), dtype=bool)
@@ -1170,11 +1170,17 @@ def func(cmd_events):
11701170
return func
11711171

11721172

1173-
def update_loads(scenario=None, *, lookback=None, stop=None) -> Table:
1173+
def update_loads(scenario=None, *, lookback=None, stop_loads=None) -> Table:
11741174
"""Update local copy of approved command loads though ``lookback`` days."""
1175-
# For testing allow override of default `stop` value
1176-
if stop is None:
1177-
stop = get_default_stop()
1175+
dt = 21 * u.day
1176+
cxotime_now = get_cxotime_now()
1177+
# This is either the true current time or else the mock time from CXOTIME_NOW.
1178+
stop = CxoTime(stop_loads or cxotime_now)
1179+
start = stop - lookback * u.day
1180+
# Find loads out to 21 days into the future by default (in the case where
1181+
# stop is the current time).
1182+
if stop_loads is None and cxotime_now is None:
1183+
stop += dt
11781184

11791185
if lookback is None:
11801186
lookback = conf.default_lookback
@@ -1197,12 +1203,6 @@ def update_loads(scenario=None, *, lookback=None, stop=None) -> Table:
11971203
# Probably too complicated, but this bit of code generates a list of dates
11981204
# that are guaranteed to sample all the months in the lookback period with
11991205
# two weeks of margin on the tail end.
1200-
dt = 21 * u.day
1201-
start = CxoTime(stop) - lookback * u.day
1202-
if stop is None:
1203-
stop = CxoTime.now() + dt
1204-
else:
1205-
stop = CxoTime(stop)
12061206
n_sample = int(np.ceil((stop - start) / dt))
12071207
dates = start + np.arange(n_sample + 1) * (stop - start) / n_sample
12081208
dirs_tried = set()
@@ -1378,7 +1378,8 @@ def update_cmds_archive(
13781378
Number of days to look back to get recent load commands from OCCweb.
13791379
Default is ``conf.default_lookback`` (currently 30).
13801380
stop : CxoTime-like, None
1381-
Stop date to update the archive to. Default is NOW + 21 days.
1381+
Stop date to update the archive to. Default is that future loads and command
1382+
events are included.
13821383
log_level : int
13831384
Logging level. Default is ``logging.INFO``.
13841385
scenario : str, None
@@ -1392,7 +1393,7 @@ def update_cmds_archive(
13921393
"""
13931394
# For testing allow override of default `stop` value
13941395
if stop is None:
1395-
stop = get_default_stop()
1396+
stop = get_cxotime_now()
13961397

13971398
# Local context manager for log_level and data_root
13981399
kadi_logger = logging.getLogger("kadi")
@@ -1405,7 +1406,7 @@ def update_cmds_archive(
14051406
kadi_logger.setLevel(log_level_orig)
14061407

14071408

1408-
def _update_cmds_archive(lookback, stop, match_prev_cmds, scenario, data_root):
1409+
def _update_cmds_archive(lookback, stop_loads, match_prev_cmds, scenario, data_root):
14091410
"""Do the real work of updating the cmds archive"""
14101411
idx_cmds_path = Path(data_root) / "cmds2.h5"
14111412
pars_dict_path = Path(data_root) / "cmds2.pkl"
@@ -1423,9 +1424,9 @@ def _update_cmds_archive(lookback, stop, match_prev_cmds, scenario, data_root):
14231424
pars_dict = {}
14241425
match_prev_cmds = False # No matching of previous commands
14251426

1426-
cmds_recent = update_archive_and_get_cmds_recent(
1427+
cmds_recent = update_cmd_events_and_loads_and_get_cmds_recent(
14271428
scenario=scenario,
1428-
stop=stop,
1429+
stop_loads=stop_loads,
14291430
lookback=lookback,
14301431
cache=False,
14311432
pars_dict=pars_dict,

kadi/commands/core.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1110,15 +1110,15 @@ def ska_load_dir(load_name: str) -> Path:
11101110
return load_dir_from_load_name(load_name)
11111111

11121112

1113-
def get_default_stop() -> str | None:
1114-
"""Get the default stop date for kadi commands.
1113+
def get_cxotime_now() -> str | None:
1114+
"""Get the value of CXOTIME_NOW env var (or legacy proxy) for kadi commands.
11151115
11161116
This returns the value of the CXOTIME_NOW environment variable if set,
11171117
otherwise the value of the KADI_COMMANDS_DEFAULT_STOP environment variable,
11181118
otherwise None.
11191119
"""
11201120

1121-
stop = os.environ.get(
1121+
cxotime_now = os.environ.get(
11221122
"CXOTIME_NOW", kadi_stop := os.environ.get("KADI_COMMANDS_DEFAULT_STOP")
11231123
)
11241124

@@ -1129,4 +1129,4 @@ def get_default_stop() -> str | None:
11291129
stacklevel=2,
11301130
)
11311131

1132-
return stop
1132+
return cxotime_now

0 commit comments

Comments
 (0)