Esempio n. 1
0
def get_tdb_limits(msid, dbver=None, tdbs=None):
    """ Retrieve the TDB limits from a json version of the MS Access database.

    :param msid: String containing the mnemonic name, must correspond to a numeric limit set

    :returns safetylimits: Dictionary of numeric limits with keys: 'warning_low', 'caution_low',
        'caution_high', 'warning_high'


    Returns an empty dict object if there are no limits specified in the
    database
    """

    def assign_sets(dbsets):
        """ Copy over only the limit/expst sets, other stuff is not copied.

        This also adds a list of set numbers.
        """
        limits = {'setkeys': []}
        for setnum in dbsets.keys():
            setnumint = int(setnum) - 1
            limits.update({setnumint: dbsets[setnum]})
            limits['setkeys'].append(setnumint)
        return limits

    def get_tdb(dbver, tdbs):
        if tdbs:
            return tdbs[dbver.lower()]
        else:
            tdbs = open_tdb_file()
            return tdbs[dbver.lower()]

    msid = msid.lower().strip()

    if not dbver:
        tdbversions = get_tdb_dates(return_dates=True)
        dbver = max(tdbversions.keys())

    try:
        tdb = get_tdb(dbver, tdbs)

        limits = assign_sets(tdb[msid]['limit'])
        limits['type'] = 'limit'

        if is_not_nan(tdb[msid]['limit_default_set_num']):
            limits['default'] = tdb[msid]['limit_default_set_num'] - 1
        else:
            limits['default'] = 0

        # Add limit switch info if present
        if is_not_nan(tdb[msid]['limit_switch_msid']):
            limits['mlimsw'] = tdb[msid]['limit_switch_msid']

        # Fill in switchstate info if present
        for setkey in limits['setkeys']:
            if 'state_code' in limits[setkey].keys():
                limits[setkey]['switchstate'] = limits[setkey]['state_code']
                _ = limits[setkey].pop('state_code')

        # For now, only the default limit set is returned, this will help with backwards compatibility.
        # Future versions, rewritten for web applications will not have this limitation.
        tdblimits = limits[limits['default']]

    except KeyError:
        print('{} does not have limits in the TDB'.format(msid.upper()))
        tdblimits = {}

    return tdblimits
Esempio n. 2
0
def get_mission_safety_limits(msid, tdbs=None):
    """
    this assumes that glimmon limits can indicate when a safety limit has been adjusted
    """
    def liminterp(tsum, times, limits):
        # nans are filled in for cases where a limit isn't established until some point after launch
        # The last date for safety limits and for trending limits should be near the current time and
        #  be identical so that one doesn't dominate when it shouldn't.
        f = interpolate.interp1d(times, limits, kind='zero', bounds_error=False, fill_value=np.nan)
        return list(f(tsum))

    limdict = get_limits(msid)
    lastdate = np.max(limdict['limsets'][0]['times'])

    trendinglimits = {'msid': msid, 'warning_low': [], 'caution_low': [], 'caution_high': [],
                      'warning_high': [], 'times': []}

    # Assume the default set is always 0 - I know this is a hack, but it will work for now
    trendinglimits['warning_low'] = limdict['limsets'][0]['warning_low']
    trendinglimits['caution_low'] = limdict['limsets'][0]['caution_low']
    trendinglimits['caution_high'] = limdict['limsets'][0]['caution_high']
    trendinglimits['warning_high'] = limdict['limsets'][0]['warning_high']
    trendinglimits['times'] = limdict['limsets'][0]['times']

    if not tdbs:
        tdbs = open_tdb_file()
    tdbversions = get_tdb_dates(return_dates=True)
    allsafetylimits = {'warning_low': [], 'caution_low': [], 'caution_high': [],
                       'warning_high': [], 'times': []}
    for ver in np.sort(tdbversions.keys()):
        date = tdbversions[ver]
        safetylimits = get_tdb_limits(msid, dbver=ver, tdbs=tdbs)
        if safetylimits:
            allsafetylimits['warning_low'].append(safetylimits['warning_low'])
            allsafetylimits['caution_low'].append(safetylimits['caution_low'])
            allsafetylimits['caution_high'].append(safetylimits['caution_high'])
            allsafetylimits['warning_high'].append(safetylimits['warning_high'])
            allsafetylimits['times'].append(DateTime(date).secs)

    if len(allsafetylimits['warning_low']) == 0:
        return None

    # Repeat the last limit to prevent nans from being entered for safety limits when interpolating
    for key in allsafetylimits.keys():
        allsafetylimits[key].append(allsafetylimits[key][-1])
    allsafetylimits['times'][-1] = lastdate

    tsum = np.sort(np.unique(np.concatenate((trendinglimits['times'], allsafetylimits['times']))))
    for kind in ['warning_low', 'caution_low', 'caution_high', 'warning_high']:
        trendinglimits[kind] = liminterp(tsum, trendinglimits['times'], trendinglimits[kind])
        allsafetylimits[kind] = liminterp(tsum, allsafetylimits['times'], allsafetylimits[kind])
        if 'high' in kind:
            allsafetylimits[kind] = [
                np.nanmax((t, a)) for t, a in zip(trendinglimits[kind], allsafetylimits[kind])]
            # allsafetylimits[kind] = list(np.nanmax((trendinglimits[kind], allsafetylimits[kind]), axis=0))
        else:
            allsafetylimits[kind] = [
                np.nanmin((t, a)) for t, a in zip(trendinglimits[kind], allsafetylimits[kind])]

    allsafetylimits['times'] = list(tsum)

    return allsafetylimits