diff --git a/kadi/commands/commands_v2.py b/kadi/commands/commands_v2.py index 2a2a4780..b97255a4 100644 --- a/kadi/commands/commands_v2.py +++ b/kadi/commands/commands_v2.py @@ -1315,26 +1315,12 @@ def get_matching_block_idx(cmds_arch, cmds_recent): idx_arch_recent = cmds_arch.find_date(cmds_recent["date"][0]) logger.info("Selecting commands from cmds_arch[{}:]".format(idx_arch_recent)) cmds_arch_recent = cmds_arch[idx_arch_recent:] + cmds_arch_recent.rev_pars_dict = weakref.ref(REV_PARS_DICT) - # Define the column names that specify a complete and unique row - key_names = ("date", "type", "tlmsid", "scs", "step", "source", "vcdu") + arch_vals = get_list_for_matching(cmds_arch_recent) + recent_vals = get_list_for_matching(cmds_recent) - recent_vals = [ - tuple( - row[x].decode("ascii") if isinstance(row[x], bytes) else str(row[x]) - for x in key_names - ) - for row in cmds_arch_recent - ] - arch_vals = [ - tuple( - row[x].decode("ascii") if isinstance(row[x], bytes) else str(row[x]) - for x in key_names - ) - for row in cmds_recent - ] - - diff = difflib.SequenceMatcher(a=recent_vals, b=arch_vals, autojunk=False) + diff = difflib.SequenceMatcher(a=arch_vals, b=recent_vals, autojunk=False) matching_blocks = diff.get_matching_blocks() logger.info("Matching blocks for (a) recent commands and (b) existing HDF5") @@ -1362,6 +1348,32 @@ def get_matching_block_idx(cmds_arch, cmds_recent): return idx0_arch, idx0_recent +def get_list_for_matching(cmds: CommandTable) -> list[tuple]: + # Define the column names that specify a complete and unique row + keys = ("date", "type", "tlmsid", "scs", "step", "source", "vcdu") + rows = [] + for cmd in cmds: + row = tuple( + cmd[key].decode("ascii") if isinstance(cmd[key], bytes) else str(cmd[key]) + for key in keys + ) + # Special case for OBS command. The obs_stop param can change during anomaly + # recovery when there is a CMD_EVT maneuver but no subsequent maneuver to define + # obs_stop. In theory we could include these params in the match tuple for every + # command in the matching, but it turns out that (for reasons I don't fully + # understand) the AOSTRCAT yang and zang params are very slightly different at + # floating point precision level, so the matches fail. Since all the other + # commands are not mutable in this way we just apply this for OBS commands. + if cmd["tlmsid"] == "OBS": + row_params = tuple( + (key, cmd["params"][key]) for key in sorted(cmd["params"]) + ) + row += row_params + rows.append(row) + + return rows + + TYPE_MAP = ["ACQ", "GUI", "BOT", "FID", "MON"] IMGSZ_MAP = ["4x4", "6x6", "8x8"] PAR_MAPS = [