def make_week_predict(opt, tstart, tstop, bs_cmds, tlm, db): print "In make_week_predict" # Try to make initial state0 from cmd line options state0 = dict((x, getattr(opt, x)) for x in ('pitch', 'simpos', 'ccd_count', 'fep_count', 'vid_board', 'clocking', 'T_dea')) print state0 state0.update({'tstart': tstart - 30, 'tstop': tstart, 'datestart': DateTime(tstart - 30).date, 'datestop': DateTime(tstart).date, 'q1': 0.0, 'q2': 0.0, 'q3': 0.0, 'q4': 1.0, } ) print state0 # If cmd lines options were not fully specified then get state0 as last # cmd_state that starts within available telemetry. Update with the # mean temperatures at the start of state0. if None in state0.values(): state0 = cmd_states.get_state0(tlm['date'][-5], db, datepar='datestart') ok = ((tlm['date'] >= state0['tstart'] - 700) & (tlm['date'] <= state0['tstart'] + 700)) state0.update({'T_dea': np.mean(tlm['1deamzt'][ok])}) # TEMPORARY HACK: core model doesn't actually support predictive # active heater yet. Initial temperature determines active heater # state for predictions now. if state0['T_dea'] < 15: state0['T_dea'] = 15.0 logger.debug('state0 at %s is\n%s' % (DateTime(state0['tstart']).date, pformat(state0))) # Get commands after end of state0 through first backstop command time cmds_datestart = state0['datestop'] cmds_datestop = bs_cmds[0]['date'] # Get timeline load segments including state0 and beyond. timeline_loads = db.fetchall("""SELECT * from timeline_loads WHERE datestop > '%s' and datestart < '%s'""" % (cmds_datestart, cmds_datestop)) logger.info('Found {} timeline_loads after {}'.format( len(timeline_loads), cmds_datestart)) # Get cmds since datestart within timeline_loads db_cmds = cmd_states.get_cmds(cmds_datestart, db=db, update_db=False, timeline_loads=timeline_loads) # Delete non-load cmds that are within the backstop time span # => Keep if timeline_id is not None or date < bs_cmds[0]['time'] db_cmds = [x for x in db_cmds if (x['timeline_id'] is not None or x['time'] < bs_cmds[0]['time'])] logger.info('Got %d cmds from database between %s and %s' % (len(db_cmds), cmds_datestart, cmds_datestop)) # Get the commanded states from state0 through the end of backstop commands states = cmd_states.get_states(state0, db_cmds + bs_cmds) states[-1].datestop = bs_cmds[-1]['date'] states[-1].tstop = bs_cmds[-1]['time'] logger.info('Found %d commanded states from %s to %s' % (len(states), states[0]['datestart'], states[-1]['datestop'])) # Create array of times at which to calculate DEA temps, then do it. logger.info('Calculating DEA thermal model') print state0 model = calc_model(opt.model_spec, states, state0['tstart'], tstop, state0['T_dea']) # Make the DEA limit check plots and data files plt.rc("axes", labelsize=10, titlesize=12) plt.rc("xtick", labelsize=10) plt.rc("ytick", labelsize=10) temps = {'dea': model.comp['1deamzt'].mvals} plots = make_check_plots(opt, states, model.times, temps, tstart) viols = make_viols(opt, states, model.times, temps) write_states(opt, states) write_temps(opt, model.times, temps) return dict(opt=opt, states=states, times=model.times, temps=temps, plots=plots, viols=viols)
def get_prediction_states(self, tbegin): """ Get the states used for the prediction. Parameters ---------- tbegin : string The starting date/time from which to obtain states for prediction. """ """ Get state0 as last cmd_state that starts within available telemetry. The original logic in get_state0() is to return a state that is absolutely, positively reliable by insisting that the returned state is at least ``date_margin`` days old, where the default is 10 days. That is too conservative (given the way commanded states are actually managed) and not what is desired here, which is a recent state from which to start thermal propagation. Instead we supply ``date_margin=None`` so that get_state0 will find the newest state consistent with the ``date`` criterion and pcad_mode == 'NPNT'. """ state0 = cmd_states.get_state0(tbegin, self.db, datepar='datestart', date_margin=None) self.logger.debug('state0 at %s is\n%s' % (DateTime(state0['tstart']).date, pformat(state0))) # Get commands after end of state0 through first backstop command time cmds_datestart = state0['datestop'] cmds_datestop = self.bs_cmds[0]['date'] # Get timeline load segments including state0 and beyond. timeline_loads = self.db.fetchall("""SELECT * from timeline_loads WHERE datestop >= '%s' and datestart < '%s'""" % (cmds_datestart, cmds_datestop)) self.logger.info('Found {} timeline_loads after {}'.format( len(timeline_loads), cmds_datestart)) # Get cmds since datestart within timeline_loads db_cmds = cmd_states.get_cmds(cmds_datestart, db=self.db, update_db=False, timeline_loads=timeline_loads) # Delete non-load cmds that are within the backstop time span # => Keep if timeline_id is not None (if a normal load) # or date < bs_cmds[0]['time'] # If this is an interrupt load, we don't want to include the end # commands from the continuity load since not all of them will be valid, # and we could end up evolving on states which would not be present in # the load under review. However, once the load has been approved and is # running / has run on the spacecraft, the states in the database will # be correct, and we will want to include all relevant commands from the # continuity load. To check for this, we find the current time and see # the load under review is still in the future. If it is, we then treat # this as an interrupt if requested, otherwise, we don't. current_time = DateTime().secs interrupt = self.interrupt and self.bs_cmds[0]["time"] > current_time db_cmds = [ x for x in db_cmds if ((x['timeline_id'] is not None and not interrupt) or x['time'] < self.bs_cmds[0]['time']) ] self.logger.info('Got %d cmds from database between %s and %s' % (len(db_cmds), cmds_datestart, cmds_datestop)) # Get the commanded states from state0 through the end of backstop commands states = cmd_states.get_states(state0, db_cmds + self.bs_cmds) states[-1].datestop = self.bs_cmds[-1]['date'] states[-1].tstop = self.bs_cmds[-1]['time'] self.logger.info( 'Found %d commanded states from %s to %s' % (len(states), states[0]['datestart'], states[-1]['datestop'])) return states, state0
print '%s not found' % table for table in tables: sqldef = file(table + '_def.sql').read() db.execute(sqldef, commit=True) datestart = state0['datestart'] timeline_loads = db.fetchall("""SELECT * from timeline_loads WHERE datestop > '%s'""" % datestart) timeline_loads_mod = timeline_loads.copy()[:-2] timeline_loads_mod[-1].datestop = '2009:053:00:00:00.000' print '=' * 40 print 'Processing with timeline_loads' cmds = cmd_states.get_cmds(datestart, db=db, update_db=True, timeline_loads=timeline_loads) states = cmd_states.get_states(state0, cmds) print 'len(cmds) =',len(cmds) cmd_states.update_states_db(states, db) if 0: print '=' * 40 print 'Processing with timeline_loads_mod' cmds = cmd_states.get_cmds(datestart, db=db, update_db=True, timeline_loads=timeline_loads_mod) states = cmd_states.get_states(state0, cmds) print 'len(cmds) =',len(cmds) print states[0] print states[-1] cmd_states.update_states_db(states, db) print '=' * 40
def make_week_predict(opt, tstart, tstop, bs_cmds, tlm, db): logger.debug("In make_week_predict") # Try to make initial state0 from cmd line options state0 = dict((x, getattr(opt, x)) for x in ('pitch', 'simpos', 'ccd_count', 'fep_count', 'vid_board', 'clocking', 'T_psmc','T_pin1at', 'dh_heater')) state0.update({'tstart': tstart - 30, 'tstop': tstart, 'datestart': DateTime(tstart - 30).date, 'datestop': DateTime(tstart).date, 'q1': 0.0, 'q2': 0.0, 'q3': 0.0, 'q4': 1.0, } ) logger.debug("Completed state0 update") # If cmd lines options were not fully specified then get state0 as last # cmd_state that starts within available telemetry. Update with the # mean temperatures at the start of state0. if None in state0.values(): state0 = cmd_states.get_state0(tlm['date'][-5], db, datepar='datestart') ok = ((tlm['date'] >= state0['tstart'] - 700) & (tlm['date'] <= state0['tstart'] + 700)) state0.update({'T_psmc': np.mean(tlm['1pdeaat'][ok])}) # state0.update({'T_pin1at': np.mean(tlm['1pin1at'][ok]) + 3.0 }) state0.update({'T_pin1at': np.mean(tlm['1pdeaat'][ok]) - 10.0 }) # TEMPORARY HACK: core model doesn't actually support predictive # active heater yet. Initial temperature determines active heater # state for predictions now. if state0['T_psmc'] < 15: state0['T_psmc'] = 15.0 logger.info('state0 at %s is\n%s' % (DateTime(state0['tstart']).date, pformat(state0))) # Get commands after end of state0 through first backstop command time cmds_datestart = state0['datestop'] cmds_datestop = bs_cmds[0]['date'] # Get timeline load segments including state0 and beyond. timeline_loads = db.fetchall("""SELECT * from timeline_loads WHERE datestop > '%s' and datestart < '%s'""" % (cmds_datestart, cmds_datestop)) logger.info('Found {} timeline_loads after {}'.format( len(timeline_loads), cmds_datestart)) # Get cmds since datestart within timeline_loads db_cmds = cmd_states.get_cmds(cmds_datestart, db=db, update_db=False, timeline_loads=timeline_loads) # Delete non-load cmds that are within the backstop time span # => Keep if timeline_id is not None or date < bs_cmds[0]['time'] db_cmds = [x for x in db_cmds if (x['timeline_id'] is not None or x['time'] < bs_cmds[0]['time'])] logger.info('Got %d cmds from database between %s and %s' % (len(db_cmds), cmds_datestart, cmds_datestop)) # Get the commanded states from state0 through the end of backstop commands states = cmd_states.get_states(state0, db_cmds + bs_cmds) states[-1].datestop = bs_cmds[-1]['date'] states[-1].tstop = bs_cmds[-1]['time'] logger.info('Found %d commanded states from %s to %s' % (len(states), states[0]['datestart'], states[-1]['datestop'])) # htrbfn='/home/edgar/acis/thermal_models/dhheater_history/dahtbon_history.rdb' htrbfn='dahtbon_history.rdb' logger.info('Reading file of dahtrb commands from file %s' % htrbfn) htrb=Ska.Table.read_ascii_table(htrbfn,headerrow=2,headertype='rdb') dh_heater_times=Chandra.Time.date2secs(htrb['time']) dh_heater=htrb['dahtbon'].astype(bool) # Create array of times at which to calculate PSMC temps, then do it. logger.info('Calculating PSMC thermal model') logger.info('state0 at start of calc is\n%s' % (pformat(state0))) model = calc_model(opt.model_spec, states, state0['tstart'], tstop, state0['T_psmc'],None,state0['T_pin1at'], None, dh_heater,dh_heater_times) # Make the PSMC limit check plots and data files plt.rc("axes", labelsize=10, titlesize=12) plt.rc("xtick", labelsize=10) plt.rc("ytick", labelsize=10) temps = dict(psmc=model.comp['1pdeaat'].mvals,pin=model.comp['pin1at'].mvals) plots = make_check_plots(opt, states, model.times, temps, tstart) viols = make_viols(opt, states, model.times, temps) write_states(opt, states) write_temps(opt, model.times, temps) return dict(opt=opt, states=states, times=model.times, temps=temps, plots=plots, viols=viols)
def get_prediction_states(self, tbegin): """ Get the states used for the prediction. Parameters ---------- tbegin : string The starting date/time from which to obtain states for prediction. """ """ Get state0 as last cmd_state that starts within available telemetry. The original logic in get_state0() is to return a state that is absolutely, positively reliable by insisting that the returned state is at least ``date_margin`` days old, where the default is 10 days. That is too conservative (given the way commanded states are actually managed) and not what is desired here, which is a recent state from which to start thermal propagation. Instead we supply ``date_margin=None`` so that get_state0 will find the newest state consistent with the ``date`` criterion and pcad_mode == 'NPNT'. """ state0 = cmd_states.get_state0(tbegin, self.db, datepar='datestart', date_margin=None) self.logger.debug('state0 at %s is\n%s' % (DateTime(state0['tstart']).date, pformat(state0))) # Get commands after end of state0 through first backstop command time cmds_datestart = state0['datestop'] cmds_datestop = self.bs_cmds[0]['date'] # Get timeline load segments including state0 and beyond. timeline_loads = self.db.fetchall("""SELECT * from timeline_loads WHERE datestop >= '%s' and datestart < '%s'""" % (cmds_datestart, cmds_datestop)) self.logger.info('Found {} timeline_loads after {}'.format( len(timeline_loads), cmds_datestart)) # Get cmds since datestart within timeline_loads db_cmds = cmd_states.get_cmds(cmds_datestart, db=self.db, update_db=False, timeline_loads=timeline_loads) # Delete non-load cmds that are within the backstop time span # => Keep if timeline_id is not None (if a normal load) # or date < bs_cmds[0]['time'] # If this is an interrupt load, we don't want to include the end # commands from the continuity load since not all of them will be valid, # and we could end up evolving on states which would not be present in # the load under review. However, once the load has been approved and is # running / has run on the spacecraft, the states in the database will # be correct, and we will want to include all relevant commands from the # continuity load. To check for this, we find the current time and see # the load under review is still in the future. If it is, we then treat # this as an interrupt if requested, otherwise, we don't. current_time = DateTime().secs interrupt = self.interrupt and self.bs_cmds[0]["time"] > current_time db_cmds = [x for x in db_cmds if ((x['timeline_id'] is not None and not interrupt) or x['time'] < self.bs_cmds[0]['time'])] self.logger.info('Got %d cmds from database between %s and %s' % (len(db_cmds), cmds_datestart, cmds_datestop)) # Get the commanded states from state0 through the end of backstop commands states = cmd_states.get_states(state0, db_cmds + self.bs_cmds) states[-1].datestop = self.bs_cmds[-1]['date'] states[-1].tstop = self.bs_cmds[-1]['time'] self.logger.info('Found %d commanded states from %s to %s' % (len(states), states[0]['datestart'], states[-1]['datestop'])) return states, state0
def make_week_predict(opt, tstart, tstop, bs_cmds, tlm, db): # Try to make initial state0 from cmd line options state0 = dict((x, getattr(opt, x)) for x in ("pitch", "simpos", "power", "T_dea", "T_pin")) state0.update( { "tstart": tstart - 30, "tstop": tstart, "datestart": DateTime(tstart - 30).date, "datestop": DateTime(tstart).date, } ) # If cmd lines options were not fully specified then get state0 as last # cmd_state that starts within available telemetry. Update with the # mean temperatures at the start of state0. if None in state0.values(): state0 = cmd_states.get_state0(tlm[-5].date, db, datepar="datestart") ok = (tlm.date >= state0["tstart"] - 150) & (tlm.date <= state0["tstart"] + 150) state0.update({"T_dea": np.mean(tlm["1pdeaat"][ok]), "T_pin": np.mean(tlm["1pin1at"][ok])}) logger.debug("state0 at %s is\n%s" % (DateTime(state0["tstart"]).date, pformat(state0))) if opt.old_cmds: cmds_datestart = DateTime(state0["tstop"]).date cmds_datestop = DateTime(bs_cmds[0]["time"]).date db_cmds = cmd_states.get_cmds(cmds_datestart, cmds_datestop, db) else: # Get the commands after end of state0 through first backstop command time cmds_datestart = state0["datestop"] cmds_datestop = bs_cmds[0]["date"] # *was* DateTime(bs_cmds[0]['time']).date # Get timeline load segments including state0 and beyond. timeline_loads = db.fetchall( """SELECT * from timeline_loads WHERE datestop > '%s' and datestart < '%s'""" % (cmds_datestart, cmds_datestop) ) logger.info("Found %s timeline_loads after %s" % (len(timeline_loads), cmds_datestart)) # Get cmds since datestart within timeline_loads db_cmds = cmd_states.get_cmds(cmds_datestart, db=db, update_db=False, timeline_loads=timeline_loads) # Delete non-load cmds that are within the backstop time span # => Keep if timeline_id is not None or date < bs_cmds[0]['time'] db_cmds = [x for x in db_cmds if (x["timeline_id"] is not None or x["time"] < bs_cmds[0]["time"])] logger.info("Got %d cmds from database between %s and %s" % (len(db_cmds), cmds_datestart, cmds_datestop)) # Get the commanded states from state0 through the end of the backstop commands states = cmd_states.get_states(state0, db_cmds + bs_cmds) states[-1].datestop = bs_cmds[-1]["date"] states[-1].tstop = bs_cmds[-1]["time"] logger.info( "Found %d commanded states from %s to %s" % (len(states), states[0]["datestart"], states[-1]["datestop"]) ) # Add power column based on ACIS commanding in states states = Ska.Numpy.add_column(states, "power", get_power(states)) # Create array of times at which to calculate PSMC temperatures, then do it. times = np.arange(state0["tstart"], tstop, opt.dt) logger.info("Calculating PSMC thermal model") T_pin, T_dea = twodof.calc_twodof_model(states, state0["T_pin"], state0["T_dea"], times, characteristics.model_par) # Make the PSMC limit check plots and data files plt.rc("axes", labelsize=10, titlesize=12) plt.rc("xtick", labelsize=10) plt.rc("ytick", labelsize=10) temps = dict(dea=T_dea, pin=T_pin) plots = make_check_plots(opt, states, times, temps, tstart) viols = make_viols(opt, states, times, temps) write_states(opt, states) write_temps(opt, times, temps) return dict(opt=opt, states=states, times=times, temps=temps, plots=plots, viols=viols)