Tutorial¶
Setup for Xija modeling¶
When you first start working with Xija create a local copy of the Xija source code:
% mkdir -p ~/git # OR WHEREVER, but ~/git is easiest!
% cd ~/git
% git clone git://github.com/sot/xija.git # on HEAD
% git clone /proj/sot/ska/git/xija # on GRETA
% cd xija
% setenv XIJA $PWD
% python setup.py build_ext --inplace # build C core module
Later on you should work in your xija repository and update to the latest development version of Xija:
% cd ~/git/xija
% git pull # Update with latest dev version of xija
% python setup.py build_ext --inplace # build C core module
Finally set the PYTHONPATH environment variable to ensure that you import your local version of xija from any sub-directory where you might be working:
% setenv PYTHONPATH $XIJA
Creating and understanding models¶
The example models show here are available in the examples/doc/ directory of the Xija git repository.
Each model component is handled by a separate Python class. Some currently implemented examples include:
ModelComponent: model component base class (name, parameter methods)Node: single node with a temperature, sigma, data_quantization, etcCoupling: Couple two nodes together (one-way coupling)HeatSink: Fixed temperature external heat bathSolarHeat: Solar heating (pitch dependent)EarthHeat: Earth heating of ACIS cold radiator (attitude, ephem dependent)PropHeater: Proportional heater (P = k * (T - T_set) for T > T_set)ThermostatHeater: Thermostat heater (with configurable deadband)AcisDpaStatePower: Heating from ACIS electronics (ACIS config dependent CCDs, FEPs etc)
Example 1: simplest model¶
Start with the simplest example with a single node with solar heating. We use only two bin points at 45 and 180 degrees.
model = xija.XijaModel(name, start='2015:001', stop='2015:050')
model.add(xija.Node, 'aacccdpt')
model.add(xija.Pitch)
model.add(xija.Eclipse)
model.add(xija.SolarHeat,
node='aacccdpt',
pitch_comp='pitch',
eclipse_comp='eclipse',
P_pitches=[45, 180],
Ps=[0.0, 0.0],
ampl=0.0,
epoch='2010:001',
)
To make and run the model do:
% cd $XIJA/examples/doc
% python example1.py
% xija_gui_fit example1.json
Points for discussion:
What is fundamentally wrong with this model?
Example 2: add a heat sink¶
Same as example 1, but add a heat sink with a temperature of -16 C and a tau of 30 ksec.
model.add(xija.HeatSink,
node='aacccdpt',
tau=30.0,
T=-16.0,
)
To make and run the model do:
% cd $XIJA/examples/doc
% python example2.py
% xija_gui_fit example2.json
Points for discussion:
Twiddle each fittable parameter and observe the response.
Use a longer interval
xija_gui_fit example2.json --stop=2015:240 --days=400for dP and solar amplitude.Discuss epoch:
xija_gui_fit example2.json --stop=2015:240 --days=400 --keep-epoch. It is important to verify that SolarHeat epoch is explicitly in JSON file in order to have auto-epoch updating. This should be an"epoch"field in the"init_kwargs"element ofSolarHeatcomponents. (Note:SolarHeatOffNomRollis a bit different and does not have an epoch).
Example 3: add pitch bins¶
Same as example 2, but now the SolarHeat component has 6 pitch bins:
model.add(xija.SolarHeat,
node='aacccdpt',
pitch_comp='pitch',
eclipse_comp='eclipse',
[45, 70, 90, 115, 140, 180],
[0.0] * 6,
ampl=0.0,
epoch='2010:001',
)
To make and run the model do:
% cd $XIJA/examples/doc
% python example3.py
% xija_gui_fit example3.json --stop=2015:240 --days=400
Points for discussion:
Fit the model
Naive try.
Set heat sink time scale
Managing degenerate model parameters (heatsink T, solarheat bias, solarheat P values).
But note: eclipse data breaks degeneracy. This can be used for short-timescale components.
Save the best fit as
example3_fit.json
Working with a model¶
As an example, here is the code (available in examples/dpa/plot_dpa_resid.py) to plot
residuals versus temperature for the ACIS DPA model. You can run this with
cd examples/dpa; python plot_dpa_resid.py.
import xija
import numpy as np
import matplotlib.pyplot as plt
from Ska.Matplotlib import pointpair
start = '2010:001'
stop = '2011:345'
msid = '1dpamzt'
model_spec = 'dpa.json'
model = xija.XijaModel('dpa', start=start, stop=stop,
model_spec=model_spec)
model.make()
model.calc()
dpa = model.get_comp(msid)
resid = dpa.dvals - dpa.mvals
xscatter = np.random.uniform(-0.2, 0.2, size=len(dpa.dvals))
yscatter = np.random.uniform(-0.2, 0.2, size=len(dpa.dvals))
plt.clf()
plt.plot(dpa.dvals + xscatter, resid + yscatter, '.', ms=1.0, alpha=1)
plt.xlabel('{} telemetry (degC)'.format(msid.upper()))
plt.ylabel('Data - Model (degC)')
plt.title('Residual vs. Data ({} - {})'.format(start, stop))
bins = np.arange(6, 26.1, 2.0)
r1 = []
r99 = []
ns = []
xs = []
for x0, x1 in zip(bins[:-1], bins[1:]):
ok = (dpa.dvals >= x0) & (dpa.dvals < x1)
val1, val99 = np.percentile(resid[ok], [1, 99])
xs.append((x0 + x1) / 2)
r1.append(val1)
r99.append(val99)
ns.append(sum(ok))
xspp = pointpair(bins[:-1], bins[1:])
r1pp = pointpair(r1)
r99pp = pointpair(r99)
plt.plot(xspp, r1pp, '-r')
plt.plot(xspp, r99pp, '-r', label='1% and 99% limits')
plt.grid()
plt.ylim(-8, 14)
plt.xlim(5, 31)
plt.plot([5, 31], [3.5, 3.5], 'g--', alpha=1, label='+/- 3.5 degC')
plt.plot([5, 31], [-3.5, -3.5], 'g--', alpha=1)
for x, n, y in zip(xs, ns, r99):
plt.text(x, max(y + 1, 5), 'N={}'.format(n),
rotation='vertical', va='bottom', ha='center')
plt.legend(loc='upper right')
plt.savefig('dpa_resid_{}_{}.png'.format(start, stop))
Note
ThermalModel is a synonym for XijaModel available for back-compatibility,
but new code should use XijaModel.
Modifying an existing model¶
Much of the time the best way to create a new model is to start from an existing model. There are a few strategies for doing this:
Extend an existing model at the Python API level
Create a new model in Python and inherit existing model parameters
Directly edit the model JSON specification
Convert the model spec to Python and edit the Python
Extend an existing model¶
If you have an existing model (e.g. pcm03t from the previous examples) and
want to extend it by adding a model component, the technique is to read in the
model, add the component, make the model, and then write out the new model.
This is illustrated in the Xija extend model notebook.
Inherit from an existing model¶
This option provides a way to use some of the existing (calibrated) components from an existing model. In particular if you want to remove a component this is one way to do it. This is illustrated in the Xija inherit IPython notebook.
Edit the model specification¶
Xija models are stored in a file format called JSON. This captures the model definition, model parameters, and also everything about the GUI fit application (screen size, plots, frozen / thawed parameters) when the model was saved.
Although it requires a bit of care, sometimes the easiest way to produce a derived model is by directly editing the JSON model specification.
Convert model spec back to Python¶
A very good way to modify an existing model spec is to write it back out as Python code. This can be done in three ways:
Within
xija_gui_fitsave the model with a name ending in.pyWithin a Python session or script use the
write()method of a Xija model:model = xija.XijaModel('mdl', model_spec='mdl.json') model.write('mdl.py')
From the command line use the xija.convert module:
% python -m xija.convert --help % python -m xija.convert mdl.json
Bad Times¶
If there are one or more intervals of time where the data are effectively
bad for fitting (i.e. the thermal model is not expected to predict accurately
due to off-nominal spacecraft configuration), then one can add a bad_times
tag to the JSON model file. This would like:
{
"bad_times": [
[
"2014:001",
"2014:003"
],
[
"2014:010",
"2014:013"
]
],
"comps": [
{
"class_name": "Mask",
"init_args": [
"1dpamzt",
"gt",
20.0
],
"init_kwargs": {},
"name": "mask__1dpamzt_gt"
},
...
Exercises¶
The exercise for both teams will be to first get familiar with the GUI fit tool by playing with an existing calibrated model. Do one of the following:
% cp ~aldcroft/git/xija/examples/dpa/dpa.json ./ # ACIS
% cp ~aldcroft/git/xija/examples/minusz/minusz.json ./ # Spacecraft
You will run xija_gui_fit specifying the stop time as 2012:095 and
the number of days to fit as 90.
Then do the following:
Explore the different available plots.
Try moving various sliders and see how it affects the model.
Try fitting various parameter sets using both the check boxes and the glob tool to freeze and thaw.
Team ACIS¶
Goal: Make a model for 1DEAMZT that is analogous to the 1DPAMZT model.
Choose the best way to derive a DEA model from the DPA model.
Team Spacecraft¶
Goal: Make a working model for PCM03T.
The first step will be to calibrate the PCM03T model that we have created which uses TCYLAFT6 and TCYLFMZM as known inputs. The second step will be to integrate the PCM03T model into the MinusZ model.
% cp ~aldcroft/git/xija/examples/pcm/pcm.json ./ # Spacecraft