Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SHINY: support migration from Chandra.cmd_states / Ska.ParseCM to kadi #30

Merged
merged 9 commits into from
Aug 14, 2020
60 changes: 32 additions & 28 deletions acis_thermal_check/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@
import re
import time
import pickle
import getpass
import numpy as np
import Ska.DBI
import Ska.Numpy
from Chandra.Time import DateTime, date2secs, secs2date
from Chandra.Time import DateTime, date2secs, secs2date, use_noon_day_start
import matplotlib.pyplot as plt
from Ska.Matplotlib import cxctime2plotdate, \
pointpair, plot_cxctime
Expand All @@ -35,6 +36,9 @@
"less_equal": "<="}


use_noon_day_start()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs a comment, like: Without using this then the epoch times in the existing model spec files are interpreted using midnight for YYYY:DDD dates while the regression data are for YYYY:DDD:12:00:00. This compatibility shim makes everything work without changing all the configured model spec files.



class ACISThermalCheck(object):
r"""
ACISThermalCheck class for making thermal model predictions
Expand Down Expand Up @@ -78,15 +82,15 @@ class ACISThermalCheck(object):
names understood by Xija to MSIDs.
flag_cold_viols : boolean, optional
If set, violations for the lower planning limit will be
checked for and flagged, and
checked for and flagged, and
hist_ops : list of strings, optional
This sets the operations which will be used to create the
error histograms, e.g., including only temperatures above
or below a certain value. Should be a list equal to the
length of the *hist_limit* length. For example,
length of the *hist_limit* length. For example,
["greater_equal", "greater_equal"] for two histogram limits.
Options are "greater", "less", "greater_equal",
"less_equal" Defaults to "greater_equal" for all values
Options are "greater", "less", "greater_equal",
"less_equal" Defaults to "greater_equal" for all values
in *hist_limit*.
"""
def __init__(self, msid, name, validation_limits, hist_limit,
Expand Down Expand Up @@ -331,11 +335,11 @@ def calc_model(self, model_spec, states, tstart, tstop, state0=None):
tstart : float
The start time of the model run.
tstop : float
The end time of the model run.
The end time of the model run.
state0 : dict, optional
This is used to set the initial temperature. It's a dictionary
indexed by MSID name so that more than one can be input if
necessary.
indexed by MSID name so that more than one can be input if
necessary.
"""
import xija
model = xija.ThermalModel(self.name, start=tstart, stop=tstop,
Expand Down Expand Up @@ -499,7 +503,8 @@ def write_states(self, outdir, states):
states_table['pitch'].format = '%.2f'
states_table['tstart'].format = '%.2f'
states_table['tstop'].format = '%.2f'
states_table.write(outfile, format='ascii', delimiter='\t', overwrite=True)
states_table.write(outfile, format='ascii', delimiter='\t', overwrite=True,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also needs a comment. The fast writer fails because there is an object column (the transition keys) which makes it crash. The Python writer just takes the str of every entry and that gives the desired output.

fast_writer=False)

def write_temps(self, outdir, times, temps):
"""
Expand Down Expand Up @@ -570,7 +575,7 @@ def _make_state_plots(self, plots, num_figs, w1, plot_start,

def make_prediction_plots(self, outdir, states, temps, load_start):
"""
Make plots of the thermal prediction as well as associated
Make plots of the thermal prediction as well as associated
commanded states.

Parameters
Expand All @@ -592,13 +597,13 @@ def make_prediction_plots(self, outdir, states, temps, load_start):
# Start time of loads being reviewed expressed in units for plotdate()
load_start = cxctime2plotdate([load_start])[0]
# Value for left side of plots
plot_start = max(load_start-2.0,
plot_start = max(load_start-2.0,
cxctime2plotdate([times[0]])[0])

w1 = None
mylog.info('Making temperature prediction plots')
plots[self.name] = plot_two(fig_id=1, x=times, y=temps[self.name],
x2=times,
x2=times,
y2=self.predict_model.comp["pitch"].mvals,
title=self.msid.upper(), xmin=plot_start,
xlabel='Date', ylabel='Temperature (C)',
Expand All @@ -609,7 +614,7 @@ def make_prediction_plots(self, outdir, states, temps, load_start):
ymax = max(self.yellow_hi+1, ymax)
plots[self.name]['ax'].axhline(self.yellow_hi, linestyle='-', color='gold',
linewidth=2.0)
plots[self.name]['ax'].axhline(self.plan_limit_hi, linestyle='-',
plots[self.name]['ax'].axhline(self.plan_limit_hi, linestyle='-',
color='C2', linewidth=2.0)
if self.flag_cold_viols:
ymin = min(self.yellow_lo-1, ymin)
Expand Down Expand Up @@ -638,11 +643,11 @@ def make_prediction_plots(self, outdir, states, temps, load_start):
def get_histogram_mask(self, tlm, limits):
"""
This method determines which values of telemetry
should be used to construct the temperature
histogram plots, using limits provided by the
should be used to construct the temperature
histogram plots, using limits provided by the
calling program to mask the array via a logical
operation. The default implementation is to plot
values above a certain limit. This method may be
operation. The default implementation is to plot
values above a certain limit. This method may be
overriden by subclasses of ACISThermalCheck.

Parameters
Expand Down Expand Up @@ -677,7 +682,7 @@ def make_validation_plots(self, tlm, model_spec, outdir, run_start):
outdir : string
The directory to write outputs to.
run_start : string
The starting date/time of the run.
The starting date/time of the run.
"""
start = tlm['date'][0]
stop = tlm['date'][-1]
Expand Down Expand Up @@ -749,7 +754,7 @@ def make_validation_plots(self, tlm, model_spec, outdir, run_start):
ticklocs, fig, ax = plot_cxctime(model.times, tlm[msid] / scale,
fig=fig, ls='-', lw=2, color=thermal_blue)
if np.any(~good_mask):
ticklocs, fig, ax = plot_cxctime(model.times[~good_mask],
ticklocs, fig, ax = plot_cxctime(model.times[~good_mask],
tlm[msid][~good_mask] / scale,
fig=fig, fmt='.c')
ax.set_title(msid.upper() + ' validation; data: blue, model: red')
Expand All @@ -760,7 +765,7 @@ def make_validation_plots(self, tlm, model_spec, outdir, run_start):
for rz in rzs:
ptimes = cxctime2plotdate([rz.tstart, rz.tstop])
for ptime in ptimes:
ax.axvline(ptime, ls='--', color='C2',
ax.axvline(ptime, ls='--', color='C2',
linewidth=2, zorder=-10)
# Add horizontal lines for the planning and caution limits
# or the limits for the focal plane model. Make sure we can
Expand All @@ -775,9 +780,9 @@ def make_validation_plots(self, tlm, model_spec, outdir, run_start):
linewidth=2)
ymax = max(acis_i+1, ymax)
else:
ax.axhline(self.yellow_hi, linestyle='-', color='gold',
ax.axhline(self.yellow_hi, linestyle='-', color='gold',
zorder=-8, linewidth=2)
ax.axhline(self.plan_limit_hi, linestyle='-', color='C2',
ax.axhline(self.plan_limit_hi, linestyle='-', color='C2',
zorder=-8, linewidth=2)
ymax = max(self.yellow_hi+1, ymax)
if self.flag_cold_viols:
Expand Down Expand Up @@ -923,7 +928,7 @@ def rst_to_html(self, outdir, proc):
Parameters
----------
outdir : string
The path to the directory to which the outputs will be
The path to the directory to which the outputs will be
written to.
proc : dict
A dictionary of general information used in the output
Expand All @@ -934,7 +939,7 @@ def rst_to_html(self, outdir, proc):
dirname = os.path.dirname(docutils.writers.html4css1.__file__)
shutil.copy2(os.path.join(dirname, 'html4css1.css'), outdir)

shutil.copy2(os.path.join(TASK_DATA, 'acis_thermal_check', 'templates',
shutil.copy2(os.path.join(TASK_DATA, 'acis_thermal_check', 'templates',
'acis_thermal_check.css'), outdir)

# Spawn a shell and call rst2html to generate HTML from the reST.
Expand All @@ -960,7 +965,7 @@ def rst_to_html(self, outdir, proc):
def write_index_rst(self, outdir, context):
"""
Make output text (in ReST format) in outdir, using jinja2
to fill out the template.
to fill out the template.

Parameters
----------
Expand Down Expand Up @@ -1009,7 +1014,7 @@ def _setup_proc_and_logger(self, args):
config_logging(args.outdir, args.verbose)

# Store info relevant to processing for use in outputs
proc = dict(run_user=os.environ['USER'],
proc = dict(run_user=getpass.getuser(),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The USER environment variable doesn't exist on Mac. This version is platform-independent.

run_time=time.ctime(),
errors=[],
msid=self.msid.upper(),
Expand All @@ -1018,8 +1023,7 @@ def _setup_proc_and_logger(self, args):
if self.msid != "fptemp":
proc["msid_limit"] = self.yellow_hi - self.margin
# Figure out the MD5 sum of model spec file
model_json = json.dumps(args.model_spec, sort_keys=True, indent=4).encode("utf-8")
md5sum = hashlib.md5(model_json).hexdigest()
md5sum = hashlib.md5(open(args.model_spec, 'rb').read()).hexdigest()
pkg_version = ska_helpers.get_version("{}_check".format(self.name))
mylog.info('##############################'
'#######################################')
Expand Down
Loading