API docs

Model

Xija - framework to model complex time-series data using a network of coupled nodes with pluggable model components that define the node interactions.

exception xija.model.FetchError[source]
xija.model.ThermalModel

alias of XijaModel

class xija.model.XijaModel(name=None, start=None, stop=None, dt=None, model_spec=None, cmd_states=None, evolve_method=None, rk4=None, limits=None)[source]

Xija model class to encapsulate all ModelComponents and provide the infrastructure to define and evaluate models.

The parameters name, start, and stop are determined as follows:

  • If a model specification is provided then that sets the default values for keywords that are not supplied to the class init call.

  • evolve_method = 1 uses the original ODE solver which treats every two steps as a full RK2 step.

  • evolve_method = 2 uses the new ODE solver which treats every step as a full RK2 step, and optionally allows for RK4 if rk4 = 1.

  • Otherwise defaults are: name='xijamodel', start = stop - 45 days, stop = NOW - 30 days, dt = 328 secs, evolve_method = 1, rk4 = 0

Parameters:
name

model name

start

model start time (any DateTime format)

stop

model stop time (any DateTime format)

dt

delta time step (default=328 sec)

model_spec

model specification (None | filename | dict)

cmd_states

commanded states input (None | structured array)

evolve_method

choose method to evolve ODE (None | 1 or 2, default 1)

rk4

use 4th-order Runge-Kutta to evolve ODE, only works with evolve_method == 2 (None | 0 or 1, default 0)

limits

dict of limit values (None | dict)

Returns:
add(ComponentClass, *args, **kwargs)[source]

Add a new component to the model

Parameters:
ComponentClass
*args
**kwargs
Returns:
calc()[source]

Calculate the model. The results appear in the self.mvals array.

calc_stat()[source]

Calculate model fit statistic as the sum of component fit stats

calc_staterror(data)[source]

Calculate model fit statistic error (dummy array for Sherpa use)

Parameters:
data
Returns:
property cmd_states

test cmdstats

property comps

List of model components

property core_1

Lazy-load the “core_1” ctypes shared object libary that does the low-level model calculation via the C “calc_model_1” routine. Only load once by setting/returning a class attribute.

Parameters:
Returns:
property core_2

Lazy-load the “core_2” ctypes shared object libary that does the low-level model calculation via the C “calc_model_2” routine. Only load once by setting/returning a class attribute.

Parameters:
Returns:
fetch(msid, attr='vals', method='linear')[source]

Get data from the Chandra engineering archive.

Parameters:
msid
attr

(Default value = ‘vals’)

method

(Default value = ‘linear’)

Returns:
get_comp(name)[source]

Get a model component. Works with either a string or a component object

Parameters:
name
Returns:
get_model_code()[source]

Return Python code that will create the current model.

This is useful during model development as a way to derive from and modify existing models while retaining good parameter values.

Parameters:
Returns:
type

string of Python code

inherit_from_model_spec(inherit_spec)[source]

Inherit parameter values from any like-named parameters within the inherit_spec model specification. This is useful for making a new variation of an existing model.

Parameters:
inherit_spec
Returns:
interpolate_data(data, times, comp=None)[source]

Interpolate supplied data values at the model times using nearest-neighbor or state value interpolation.

The times arg can be either a 1-d or 2-d ndarray. If 1-d, then data is interpreted as a set of values at the specified times. If 2-d then data is interpreted as a set of binned state values with tstarts = times[0, :] and tstops = times[1, :].

Parameters:
data
times
comp

(Default value = None)

Returns:
make()[source]

Call self.make_mvals and self.make_tmal to prepare for model evaluation once all model components have been added.

Parameters:
Returns:
make_mvals()[source]

Initialize the global mvals (model values) array. This is an N (rows) x n_times (cols) array that contains all data needed to compute the model prediction. All rows are initialized to relevant data values (e.g. node temps, time-dependent power, external temperatures, etc). In the model calculation some rows will be overwritten with predictions.

Parameters:
Returns:
make_tmal()[source]

Make the TMAL “code” using components that generate TMAL statements

Parameters:
Returns:
property model_spec

Generate a full model specification data structure for this model

Parameters:
Returns:
write(filename, model_spec=None)[source]

Write the model specification as JSON or Python to a file.

If the file name ends with “.py” then the output will the Python code to create the model (using get_model_code()), otherwise the JSON model specification will be written.

Parameters:
filename

output filename

model_spec

model spec structure (optional) (Default value = None)

Returns:
write_vals(filename)[source]

Write dvals and mvals for each model component (as applicable) to an ascii table file. Some component have neither (couplings), some have just dvals (TelemData), others have both (Node, AcisDpaPower). Everything is guaranteed to be time synced, so write a single time column.

Parameters:
filename
Returns:

Components

Base classes

class xija.component.base.AcisFPtemp(model, mask=None)[source]

Make a wrapper around MSID FPTEMP_11 because that currently comes from the eng_archive in K instead of C.

Parameters:
Returns:
class xija.component.base.CmdStatesData(model, msid, mval=True, data=None, fetch_attr='vals', units=None)[source]
class xija.component.base.Coupling(model, node1, node2, tau)[source]

First-order coupling between Nodes node1 and node2

dy1/dt = -(y1 - y2) / tau
Parameters:
Returns:
class xija.component.base.Delay(model, node, delay=0)[source]

Delay mval from node by delay ksec

See the example in examples/delay/. For a positive delay, the computed model value (node.mval) will be constant at the initial value for the first delay ksec. Conversely for a negative delay the values at the end will be constant for delay ksec.

class xija.component.base.Eclipse(model)[source]
class xija.component.base.HeatSink(model, node, T=0.0, tau=20.0)[source]

Fixed temperature external heat bath

class xija.component.base.HeatSinkRef(model, node, T=0.0, tau=20.0, T_ref=20.0)[source]

Fixed temperature external heat bath, reparameterized so that varying tau does not affect the mean model temperature. This requires an extra non-fitted parameter T_ref which corresponds to a reference temperature for the node.:

dT/dt = U * (Te - T)
      = P + U* (T_ref - T)   # reparameterization

P = U * (Te - T_ref)
Te = P / U + T_ref

In code below, “T” corresponds to “Te” above. The “T” above is node.dvals.

Parameters:
Returns:
class xija.component.base.ModelComponent(model)[source]

Model component base class

class xija.component.base.Node(model, msid, sigma=-10, quant=None, predict=True, mask=None, name=None, data=None, fetch_attr='vals', units='degC')[source]

Time-series dataset for prediction.

If the sigma value is negative then sigma is computed from the node data values as the specified percent of the data standard deviation. The default sigma value is -10, so this implies using a sigma of 10% of the data standard deviation. If sigma is set to 0 then the fit statistic is set to 0.0 for this node.

Parameters:
model

parent model

msid

MSID for telemetry data

name

component name (default=``msid``)

sigma

sigma value used in chi^2 fit statistic

quant

use quantized stats (not currently implemented)

predict

compute prediction for this node (default=True)

mask

Mask component for masking values from fit statistic

data

Node data (None or a single value)

Returns:
property randx

Random X-offset for plotting which is a uniform distribution with width = self.quant or 1.0

Parameters:
Returns:
class xija.component.base.Param(comp_name, name, val, min=-1e+38, max=1e+38, fmt='{:.4g}', frozen=False)[source]

Model component parameter. Inherits from dict but adds attribute access for convenience.

Parameters:
Returns:
class xija.component.base.Pitch(model)[source]
class xija.component.base.Roll(model)[source]
class xija.component.base.SimZ(model)[source]
class xija.component.base.TelemData(model, msid, mval=True, data=None, fetch_attr='vals', units=None)[source]

Heat classes

Mask classes

class xija.component.mask.Mask(model, node, op, val, min_=-1e+38, max_=1e+38)[source]
Create object with a mask attribute corresponding to

node.dvals op val

where op is a binary operator in operator module that returns a np mask

“ge”: >= “gt”: > “le”: <= “lt”: < “eq”: == “ne” !=

Parameters:
Returns:
class xija.component.mask.MaskBox(model, node, val0, val1, min_=-1000, max_=1000)[source]
Create object with a mask attribute corresponding to

val0 < node.dvals < val1

Parameters:
Returns:

Get model spec

Get Chandra model specifications

xija.get_model_spec.get_github_version(url: str = 'https://api.github.com/repos/sot/chandra_models/releases/latest', timeout: int | float = 5) bool | None[source]

Get latest chandra_models GitHub repo release tag (version).

This queries GitHub for the latest release of chandra_models.

Parameters:
urlstr

URL for latest chandra_models release on GitHub API

timeoutint, float

Request timeout (sec, default=5)

Returns:
str, None

Tag name (str) of latest chandra_models release on GitHub. None if the request timed out, indicating indeterminate answer.

xija.get_model_spec.get_repo_version(repo_path: Path | None = None, repo: Repo | None = None) str[source]

Return version (most recent tag) of models repository.

Returns:
str

Version (most recent tag) of models repository

xija.get_model_spec.get_xija_model_names(repo_path=None) List[str][source]

Return list of available xija model names.

Parameters:
repo_pathstr, Path

Path to directory containing chandra_models repository (default is $SKA/data/chandra_models)

Returns:
list

List of available xija model names

Examples

>>> from xija.get_model_spec import get_xija_model_names
>>> names = get_xija_model_names()
['aca',
 'acisfp',
 'dea',
 'dpa',
 '4rt700t',
 'minusyz',
 'pm1thv2t',
 'pm2thv1t',
 'pm2thv2t',
 'pftank2t',
 'pline03t_model',
 'pline04t_model',
 'psmc',
 'tcylaft6']
xija.get_model_spec.get_xija_model_spec(model_name, version=None, repo_path=None, check_version=False, timeout=5) tuple[source]

Get Xija model specification for the specified model_name.

Supported model names include (but are not limited to): 'aca', 'acisfp', 'dea', 'dpa', 'psmc', 'minusyz', and 'pftank2t'.

Use get_xija_model_names() for the full list.

Parameters:
model_namestr

Name of model

versionstr, None

Tag, branch or commit of chandra_models to use (default=latest tag from repo)

repo_pathstr, Path

Path to directory or URL containing chandra_models repository (default is $SKA/data/chandra_models)

check_versionbool

Check that version matches the latest release on GitHub

timeoutint, float

Timeout (sec) for querying GitHub for the expected chandra_models version. Default = 5 sec.

Returns:
tuple of dict, str

Xija model specification dict, chandra_models version

Examples

Get the latest version of the acisfp model spec from the local Ska data directory $SKA/data/chandra_models, checking that the version matches the latest release tag on GitHub.

>>> import xija
>>> from xija.get_model_spec import get_xija_model_spec
>>> model_spec, version = get_xija_model_spec('acisfp', check_version=True)
>>> model = xija.XijaModel('acisfp', model_spec=model_spec,
...                        start='2020:001', stop='2020:010')
>>> model.make()
>>> model.calc()

Get the aca model spec from release version 3.30 of chandra_models from GitHub.

>>> repo_path = 'https://github.com/sot/chandra_models.git'
>>> model_spec, version = get_xija_model_spec('aca', version='3.30',
...                                           repo_path=repo_path)