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
% ../../gui_fit.py example1.json --autoscale
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
% ../../gui_fit.py example2.json --autoscale
Points for discussion:
Twiddle each fittable parameter and observe the response.
Use a longer interval ./gui_fit.py example2.json –autoscale –stop=2015:240 –days=400 for dP and solar amplitude.
Discuss epoch: ./gui_fit.py example2.json –autoscale –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 ofSolarHeat
components. (Note:SolarHeatOffNomRoll
is 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 example2.py
% ../../gui_fit.py example3.json --stop=2015:240 --days=400
Points for discussion:
Why no
--autoscale
?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
gui_fit.py
save the model with a name ending in.py
Within 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
Fitting a model¶
So far we have been manually working with a Xija model to understand a bit of
what is going on underneath and know how to make performance predictions.
However, the key task of actually calibrating the model parameters is done with
the gui_fit.py
application.
GUI fit overview
The image below shows an example of fitting the ACIS DPA model with
gui_fit.py
.
Live demo using a Ska window:
cd $XIJA/examples/pcm
../../gui_fit.py pcm.json --stop 2012:095 --days 30
Command line options¶
The GUI fit tool supports the following command line options:
% ./gui_fit.py --help
usage: gui_fit.py [-h] [--days DAYS] [--stop STOP] [--nproc NPROC]
[--fit-method FIT_METHOD] [--inherit-from INHERIT_FROM]
[--set-data SET_DATA_EXPRS] [--quiet] [--keep-epoch]
filename
positional arguments:
filename Model file
optional arguments:
-h, --help show this help message and exit
--days DAYS Number of days in fit interval (default=90
--stop STOP Stop time of fit interval (default=model values)
--nproc NPROC Number of processors (default=1)
--fit-method FIT_METHOD
Sherpa fit method (simplex|moncar|levmar)
--inherit-from INHERIT_FROM
Inherit par values from model spec file
--set-data SET_DATA_EXPRS
Set data value as '<comp_name>=<value>'
--quiet Suppress screen output
--keep-epoch Maintain epoch in SolarHeat models (default=recenter
on fit interval)
Most of the time you should use the --days
and --stop
options. Note that
if you have saved a model specification and then restart gui_fit.py
, the
most recently specified values will be used by default.
--nproc
This option has not been tested recently though it might work.
--fit-method
The default fit method is
simplex
which is a good compromise between speed and completeness. For the fastest fitting uselevmar
. If already have somewhat decent parameters and want to try to refine for the very best fit then selectmoncar
. However, do not choose this option with more than about 10 or 15 free parameters as it can take a long time. Typically withmoncar
you need to start the fitting and then do something else for a while (many hours or more).--inherit-from
This provides a way to construct a model which is similar to an existing model but has some differences. All the model parameters which are exactly the same will be taking from the inherited model specification.
Assuming you have created a model specification file my_model_spec.json
then a typical calling sequence from the Xija source directory is:
./gui_fit.py --stop 2012:002 --days 180 my_model_spec.json
Manipulating plots¶
Many model components have built-in plots that can be added to the fit window
via the Add plots...
drop down menu. The available plot names correspond to the
model component followed by a description of the plot. Plots can be deleted by
pressing the corresponding Delete
button.
One handy feature is that the time-based plots are always linked in the time
axis so that if you zoom in to one then all plots zoom accordingly. When you
want to go back to the full view you can use the Home
button on the plot
where you originally zoomed.
Manipulating parameters¶
One of the key features of the GUI fit tool is the ability to visualize and manipulate the dozens of parameters in a typical Xija model.
The parameters are on the right side panel. Each one has a checkbox that indicates whether it will be fit (checked) or not (unchecked). The value is shown, then the minimum allowed fit value, a slider bar to select the value, and then the maximum allowed fit value. As you change the slider the model will be recalculated and the plots updated. It helps to make the GUI fit window as wide as possible to make the sliders longer.
If you want to change the min or max values just type in the box and then hit enter. (If you don’t hit enter the new value won’t apply).
You can freeze or thaw many parameters at once using the “glob” syntax in the entry box at the top of the fit window. Examples:
thaw * # thaw all parameters
freeze solarheat* # freeze all the solarheat params
freeze solarheat*_dP_* # freeze the long-term solarheat variation params
Fit strategy¶
Fitting Xija models is a bit of an art and will it take some time to develop skill here. A few rules of thumb and tips:
Start with all long-term variations frozen. You want to begin with a single time span that is about a year long and ends near the present. The more parameters in the model that get fit, the more data you need. Start by try to get the model in the right ballpark. Typically this means:
Freeze? Parameters Initial values ------- ------------------ ---------------------- freeze solarheat_*_dP_* 0 freeze solarheat_*_tau 365 freeze solarheat_*_ampl 0 freeze heatsink_T ~10 deg below typical thaw solarheat_*_P_* 0 thaw heatsink_tau Typical time scale thaw coupling_* 30
Almost always have the
solarheat_*_bias
terms frozen at 0. This parameter is degenerate with thesolarheat_*_P_*
values and is used for certain diagnostics.Once you have a model that fits reasonably well over the one year period then freeze all parameters except for
solarheat_*_dP_*
andsolarheat_*_ampl
parameters. Fit over a 2-3 year time period which ends at the present time.Next you might want to refine the
solarheat_*_P_*
parameters at this point by thawing those ones and freezing the long-term parameters and fitting. Remember that if the time span is not long enough thenP
anddP
are degenerate and the fit may not converge.It can be useful to include long normal-sun dwells in the fitting to have some high-temperature data in the fit dataset.
Remember to save your model fit when you get a good fit. It is not saved by default and there is currently no warning to this effect. Often there is a progression of model fits and it may be useful to incrementally number the models, e.g.
pcm03t_1.json
,pcm03t_2.json
, etc. By convention the final “flight” models that get configured are called<modelname>_model_spec.json
, so avoid using this name during development.Saving also saves the state of plots and your parameters.
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 gui_fit.py
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