def aca_ccd_model(tstart, tstop, init_temp): cmd_states = get_cmd_states.fetch_states(tstart, tstop, vals=['obsid', 'pitch', 'q1', 'q2', 'q3', 'q4']) model_spec = chandra_models.get_xija_model_file('aca') model = xija.ThermalModel('aca', start=tstart, stop=tstop, model_spec=model_spec) times = np.array([cmd_states['tstart'], cmd_states['tstop']]) model.comp['pitch'].set_data(cmd_states['pitch'], times) model.comp['aca0'].set_data(init_temp, tstart) model.comp['aacccdpt'].set_data(init_temp, tstart) model.make() model.calc() return model
def test_get_states(): """Test Python function interface to getting commanded states. """ val_names = "obsid,simpos,pcad_mode,clocking,power_cmd".split(',') for dbi in ('sybase', 'hdf5'): states = fetch_states(start='2010:100', stop='2010:101', dbi=dbi, vals=val_names) for name in states.dtype.names: if states[name].dtype.kind == 'f': assert np.allclose(states[name], VALS[name]) else: assert np.all(states[name] == VALS[name]) names = ["datestart", "datestop", "tstart", "tstop"] assert names + val_names == list(states.dtype.names)
def get_week_states(tstart, tstop, bs_cmds, tlm): """ Make states from last available telemetry through the end of the backstop commands :param tstart: start time from first backstop command :param tstop: stop time from last backstop command :param bs_cmds: backstop commands for products under review :param tlm: available pitch and aacccdpt telemetry recarray from fetch :returns: numpy recarray of states """ cstates = Table(get_cmd_states.fetch_states(DateTime(tstart) - 30, tstop, vals=['obsid', 'pitch', 'q1', 'q2', 'q3', 'q4'])) # Get the last state at least 3 days before tstart and at least one hour # before the last available telemetry cstate0 = cstates[(cstates['tstart'] < (DateTime(tstart) - 3).secs) & (cstates['tstart'] < (tlm[-1]['date'] - 3600))][-1] # get temperature data in a range around that initial state ok = ((tlm['date'] >= cstate0['tstart'] - 700) & (tlm['date'] <= cstate0['tstart'] + 700)) init_aacccdpt = np.mean(tlm['aacccdpt'][ok]) pre_bs_states = cstates[(cstates['tstart'] >= cstate0['tstart']) & (cstates['tstart'] < tstart)] # cmd_states.get_states needs an initial state dictionary, so # construct one from the last pre-backstop state last_pre_bs_state = {col: pre_bs_states[-1][col] for col in pre_bs_states[-1].colnames} # Get the commanded states from last cmd_state through the end of backstop commands states = Table(cmd_states.get_states(last_pre_bs_state, bs_cmds)) states[-1]['datestop'] = bs_cmds[-1]['date'] states[-1]['tstop'] = bs_cmds[-1]['time'] # Truncate the last pre_bs_state at the new states start pre_bs_states[-1]['datestop'] = states[0]['datestart'] pre_bs_states[-1]['tstop'] = states[0]['tstart'] logger.info('Constructed %d commanded states from %s to %s' % (len(states), states[0]['datestart'], states[-1]['datestop'])) # Combine the pre-backstop states with the commanded states all_states = vstack([pre_bs_states, states]) # Add a column for temperature and pre-fill all to be the initial temperature # (the first state temperature is the only one used anyway) all_states['aacccdpt'] = init_aacccdpt return all_states
def get_starcheck_catalog_at_date(date, starcheck_db=None, timelines_db=None): """ For a given date, return a dictionary describing the starcheck catalog that should apply. The content of that dictionary is from the database tables that parsed the starcheck report. A catalog is defined as applying, in this function, to any time from the end of the previous dwell through the end of the dwell in which the catalog was used. Star catalog dictionary with keys: - cat: catalog rows as astropy.table - manvr: list of maneuvers to this attitude - pred_temp: predicted ACA CCD temperature - warnings: list of warnings below catalog in starcheck output - obs: dictionary of observation target and pointing information - mp_dir: directory with products that are the source of this catalog data - status: string describing status of that observation, described below. Status: - ran: observation was observed - planned: observation in a not-approved future schedule - approved: observation in an approved future schedule (ingested in timelines/cmd_states) - ran_pretimelines: ran, but before timelines database starts - timelines_gap: after timelines database start but missing data - no starcat: in the database but has no star catalog :param date: Chandra.Time compatible date :param starcheck_db: optional handle to already-open starcheck database :param timelines_db: optional handle to already-open timelines database :returns: dictionary with starcheck content described above """ date = DateTime(date).date if starcheck_db is None: starcheck_db = Ska.DBI.DBI(**DEFAULT_CONFIG['starcheck_db']) db = starcheck_db if timelines_db is None: timelines_db = Ska.DBI.DBI(**DEFAULT_CONFIG['timelines_db']) last_tl = timelines_db.fetchone( "select max(datestop) as datestop from timelines")['datestop'] first_tl = timelines_db.fetchone( "select min(datestart) as datestart from timelines")['datestart'] # Check kadi to get the first dwell that *ends* after the given time dwells = events.dwells.filter(stop__gte=date, subset=slice(None, 1)) # if we're outside of timelines or not yet in kadi, just try from the starcheck database if date > last_tl or date < first_tl: # Get one entry that is the last one before the specified time, in the most # recently ingested products directory starcheck = db.fetchone( """select * from starcheck_obs, starcheck_id where mp_starcat_time <= '{}' and mp_starcat_time > '{}' and starcheck_id.id = starcheck_obs.sc_id order by sc_id desc, mp_starcat_time desc """.format( date, (DateTime(date) - 1).date)) if starcheck: cat_info = get_starcheck_catalog(starcheck['obsid'], mp_dir=starcheck['dir']) if date < first_tl: cat_info['status'] = 'ran_pretimelines' if date > last_tl: cat_info['status'] = 'planned' return cat_info # We want to search for legitimate commanding that would cover the time when a star # catalog would have been commanded for this dwell. This is generally the time range # between the end of the previous dwell and the beginning of this dwell. However, if # there are multiple dwells from one maneuver, use the beginning of NMM from that one # maneuver else, use the end of the last dwell. Don't use nman_start time by default # because that doesn't appear to work if the catalog was commanded in a nonstandard # nmm sequence like dark cal. # There is a tiny window of time in cmd_states but not yet in kadi, but this code tries to # grab the dwell and maneuver that would be related to a date in that range if date < last_tl and len(dwells) == 0: pcad_states = get_cmd_states.fetch_states(start=DateTime(date) - 2, vals=['pcad_mode']) dwell = pcad_states[(pcad_states['pcad_mode'] == 'NPNT') & (pcad_states['datestop'] >= date)][0] manvr = pcad_states[(pcad_states['pcad_mode'] == 'NMAN') & (pcad_states['datestop'] <= dwell['datestart'])][-1] start_cat_search = manvr['datestart'] dwell_start = dwell['datestart'] else: # If we have a dwell from kadi, use it to search for commanding dwell = dwells[0] dwell_start = dwell.start # Try to use the beginning of the previous nman period to define when the catalog # should have been commanded. If there are multiple dwells for attitude, try to # use nman_start if available. if dwell.manvr.n_dwell > 1 and dwell.manvr.nman_start is not None: start_cat_search = dwell.manvr.nman_start else: start_cat_search = dwell.get_previous().stop timelines = timelines_db.fetchall( """select * from timeline_loads where scs < 131 and datestop > '{}' and datestart < '{}' order by datestart""".format( start_cat_search, dwell_start)) for timeline in timelines[::-1]: starchecks = db.fetchall( """select * from starcheck_obs, starcheck_id where dir = '{}' and mp_starcat_time >= '{}' and mp_starcat_time <= '{}' and mp_starcat_time <= '{}' and starcheck_id.id = starcheck_obs.sc_id order by mp_starcat_time """.format( timeline['mp_dir'], timeline['datestart'], timeline['datestop'], dwell_start)) # The last one should be the one before beginning of the dwell if len(starchecks): # Use the obsid and the known products directory to use the more generic get_starcheck_catalog # to fetch the right one from the database cat_info = get_starcheck_catalog(starchecks[-1]['obsid'], mp_dir=starchecks[-1]['dir']) cat_info['status'] = 'ran' if date < DateTime().date else 'approved' return cat_info return None