Esempio n. 1
0
def calc_model(pitch_pdf=[1, 2, 3, 4], tank_start=None):
    """
    Calculate tank model for a simulated set of observations that follow
    the specified pitch probability density function ``pitch_pdf``.  This
    argument corresponds to the fraction of observations in the
    four PITCH_BINS.  This will be normalized to one by the function.
    """
    tank_start = F2C(tank_start)  # convert to degC
    model = xija.ThermalModel('pftank2t',
                              '2013:001',
                              '2013:008',
                              model_spec='pftank2t_spec.json')

    times = model.times
    pitches = get_pitches(len(times), pitch_pdf)

    model.comp['pftank2t'].set_data(tank_start)
    model.comp['pf0tank2t'].set_data(tank_start)
    model.comp['pitch'].set_data(pitches, times)
    model.comp['eclipse'].set_data(False)

    model.make()
    model.calc()

    return model
Esempio n. 2
0
def calc_model(start, pitch, model_spec):
    stop = DateTime(start) + 10
    model = xija.ThermalModel('pftank2t', start=start, stop=stop,
                              model_spec=model_spec)

    model.comp['eclipse'].set_data(False)
    model.comp['pitch'].set_data(pitch)
    model.comp['pf0tank2t'].set_data(35.0)
    model.comp['pftank2t'].set_data(35.0)

    model.make()
    model.calc()
    return model
Esempio n. 3
0
File: fit.py Progetto: sot/xijafit
    def update_fit_times(self, start=None, stop=None, days=180):
        """Update model fit times to new values.

        :param start: Start date for model fit duration
        :param stop: Stop date for model fit duration
        :param days: Number of days of data to use to fit the model

        Either 'start' and 'days', or 'stop' and 'days', or both 'start' and 'stop' must be defined,
        accounting for the fact that the default value for days is defined above.

        This re-initializes and runs the Xija model object with new times without changing the parameters.
        """
        if (start is None) and (stop is None):
            raise ValueError(
                "Either 'start' and 'days', or 'stop' and 'days', or both 'start' and 'stop' must be defined."
            )

        if start and stop:
            self.start = DateTime(start).date
            self.stop = DateTime(stop).date
        elif stop is None:
            self.start = DateTime(start).date
            self.stop = DateTime(DateTime(start).secs +
                                 days * 24 * 3600.).date[:8]
        else:
            self.start = DateTime(DateTime(start).secs -
                                  days * 24 * 3600.).date[:8]
            self.stop = DateTime(stop).date

        self.model = xija.ThermalModel(self.model_spec['name'],
                                       self.start,
                                       self.stop,
                                       model_spec=self.model.model_spec)

        # These solarheat parameters need to be defined to avoid an AttributeError in heat.py. The actual
        # values don't matter as they are deleted when setting the epoch.
        for key, value in list(self.model.comp.items()):
            if 'solarheat' in key:
                if not hasattr(self.model.comp[key], 't_days'):
                    self.model.comp[key].t_days = -1
                if not hasattr(self.model.comp[key], 't_phase'):
                    self.model.comp[key].t_phase = -1

        if self.set_data_exprs:
            self.set_init_data(self.set_data_exprs)

        if not self.keep_epoch:
            self.set_epoch()

        self.model.make()
        self.model.calc()
Esempio n. 4
0
def calc_model_pyger(self, states, times, T0s, state_only=False):
    print 'TANK:', CtoF(T0s)
    model = xija.ThermalModel('tank',
                              start=states['tstart'][0],
                              stop=states['tstop'][-1],
                              model_spec=self.model_spec)

    state_times = np.array([states['tstart'], states['tstop']])
    model.comp['pitch'].set_data(states['pitch'], state_times)
    model.comp['eclipse'].set_data(False)
    model.comp['pf0tank2t'].set_data(T0s[0])
    model.comp['pftank2t'].set_data(T0s[0])

    model.make()
    model.calc()
Esempio n. 5
0
File: timbre.py Progetto: sot/timbre
def setup_model(msid, t0, t1, model_spec, init):
    """ Create Xija model object

    This function creates a Xija model object with initial parameters, if any. This function is intended to create a
    streamlined method to creating Xija models that can take both single value data and time defined data
    (e.g. [pitch1, pitch2, pitch3], [time1, time2, time3]), defined in the `init` dictionary.

    :param msid: Primary MSID for model; in this case it can be anything as it is only being used to name the model,
           however keeping the convention to name the model after the primary MSID being predicted reduces confusion
    :type msid: str
    :param t0: Start time for model prediction; this can be any format that cxotime.CxoTime accepts
    :type t0: str or float or int
    :param t1: End time for model prediction; this can be any format that cxotime.CxoTime accepts
    :type t1: str or float or int
    :param model_spec: Dictionary of model parameters or file location where parameters can be imported
    :type model_spec: dict, str
    :param init: Dictionary of Xija model initialization parameters, can be empty
    :type init: dict
    :rtype: xija.model.XijaModel

    Example::

        model_specs = load_model_specs()
        init = {'1dpamzt': 35., 'dpa0': 35., 'eclipse': False, 'roll': 0, 'vid_board': True, 'pitch':155,
                'clocking': True, 'fep_count': 5, 'ccd_count': 5, 'sim_z': 100000}
        model = setup_model('1dpamzt', '2019:001:00:00:00', '2019:010:00:00:00', model_specs['1dpamzt'], init)

    Notes:

     - This does not run the model, only sets up the model to be run.
     - Any parameters not specified in `init` will either need to be pulled from telemetry or explicitly defined \
     outside of this function before running the model.

    """

    model = xija.ThermalModel(msid, start=t0, stop=t1, model_spec=model_spec)
    for key, value in init.items():
        if isinstance(value, dict):
            model.comp[key].set_data(value['data'], value['times'])
        else:
            model.comp[key].set_data(value)

    return model
Esempio n. 6
0
def calc_model(pitch):
    model = xija.ThermalModel('pftank2t',
                              '2013:001',
                              '2013:040',
                              model_spec='pftank2t_model_spec.json')

    times = model.times
    days = (model.times - model.times[0]) / 86400.
    ok = (days > 10.0) & (days < 30.0)
    pitches = np.zeros_like(times) + 160.0
    pitches[ok] = pitch

    model.comp['pftank2t'].set_data(22.0)
    model.comp['pf0tank2t'].set_data(22.0)
    model.comp['pitch'].set_data(pitches, times)
    model.comp['eclipse'].set_data(False)

    model.make()
    model.calc()

    return model
Esempio n. 7
0
# Licensed under a 3-clause BSD style license - see LICENSE.rst
"""
Replicate (mostly) the minusz TEPHIN node model.  (dPs set to zero though).

env PYTHONPATH=$PWD python minusz/minusz.py
"""

import xija
import json

P_pitches = [45, 60, 90, 120, 145, 170]
P_pitches2 = [45, 60, 90, 120, 145, 171]
minusz = json.load(open('/proj/sot/ska/share/nmass/minusz/pars_minusz.json'))
sigmas = {'tephin': -10}

mdl = xija.ThermalModel(name='minusz', start='2010:001', stop='2010:002')
nodes = {}
pitch = mdl.add(xija.Pitch)
eclipse = mdl.add(xija.Eclipse)

for msid in minusz:
    pars = minusz[msid]
    Ps = [pars['pf_{0:03d}'.format(p)] for p in P_pitches]
    nodes[msid] = mdl.add(xija.Node, msid, sigma=sigmas.get(msid, -20))
    mdl.add(xija.SolarHeat,
            msid,
            pitch,
            eclipse,
            P_pitches2,
            Ps,
            ampl=pars['p_ampl'])
Esempio n. 8
0
# Licensed under a 3-clause BSD style license - see LICENSE.rst
"""
Replicate (mostly) the minusz TEPHIN node model.  (dPs set to zero though).
"""

import numpy as np
import xija

mdl = xija.ThermalModel(start='2010:001', stop='2010:014')

tephin = mdl.add(xija.Node, 'tephin')
tcylaft6 = mdl.add(xija.Node, 'tcylaft6', predict=False)
tmzp_my = mdl.add(xija.Node, 'tmzp_my', predict=False)
coup__tephin__tcylaft6 = mdl.add(xija.Coupling, tephin, tcylaft6, tau=130.26)
coup__tephin__tmzp_my = mdl.add(xija.Coupling, tephin, tmzp_my, tau=105.91)
aosares1 = mdl.add(xija.TelemData, 'aosares1')
tephin_solar = mdl.add(xija.SolarHeat,
                       tephin,
                       aosares1,
                       P_pitches=[45, 60, 90, 120, 145, 170],
                       Ps=np.array([0.970, 1.42, 1.91, 1.92, 1.42, 0.69]),
                       ampl=0.0679)

tephin_heatsink = mdl.add(xija.HeatSink, tephin, T=0.0, tau=38.0)

pars_minusz = """
    "tephin": {
        "T_e": 0.0, 
        "p_ampl": 0.067919468805023628, 
        "pf_045": 0.96976110603706989, 
        "pf_060": 1.4221924089192244, 
Esempio n. 9
0
# Licensed under a 3-clause BSD style license - see LICENSE.rst
"""
Replicate (mostly) the minusz TEPHIN node model.  (dPs set to zero though).
"""

import json
import xija

P_pitches=[45, 60, 90, 120, 145, 170]
P_pitches2=[45, 60, 90, 120, 145, 171]
minusz = json.load(open('nmass/minusz/pars_minusz.json'))

mdl = xija.ThermalModel('minusz', start='2010:001', stop='2010:360')
nodes = {}
pitch = mdl.add(xija.Pitch)
eclipse = mdl.add(xija.Eclipse)

for msid in minusz:
    pars = minusz[msid]
    Ps = [pars['pf_{0:03d}'.format(p)] for p in P_pitches]
    nodes[msid] = mdl.add(xija.Node, msid)
    mdl.add(xija.SolarHeat, msid, pitch, eclipse, P_pitches2, Ps, ampl=pars['p_ampl'])
    mdl.add(xija.HeatSink, msid, T=pars['T_e'], tau=pars['tau_ext'])

for msid in minusz:
    pars = minusz[msid]
    coupled_nodes = [x for x in pars if x.startswith('tau_t')]
    for parname in coupled_nodes:
        mdl.add(xija.Coupling, msid, node2=parname[4:], tau=pars[parname])

mdl.make()
Esempio n. 10
0
File: worker.py Progetto: sot/xija
        comm.Reduce([semaphore, MPI.DOUBLE], None, op=MPI.SUM, root=0)
        break

    elif cmd == 'init':
        fit_start = DateTime(msg['tstart']).secs
        fit_stop = DateTime(msg['tstop']).secs
        dt = (fit_stop - fit_start) / size
        tstart = fit_start + dt * rank
        tstop = tstart + dt
        
        print 'xija_worker {4} of {5}: Working init {0}:{1} fetching data {2} {3}'.format(
            rank, procname, DateTime(tstart).date, DateTime(tstop).date, rank, size)

        src.update((x, msg[x]) for x in ('model', 'outdir', 'pardir'))
        model_spec = json.load(open(files['model_spec.json'].abs, 'r'))
        model = xija.ThermalModel(name=msg['model'], start=tstart, stop=tstop, model_spec=model_spec)
        model.make()

    elif cmd == 'calc_model':
        model.parvals[:] = msg['parvals']

    elif cmd == 'calc_stat':
        fit_stat = model.calc_stat()
        comm.Reduce([fit_stat, MPI.DOUBLE], None, op=MPI.SUM, root=0)

    elif cmd == 'model':
        model_func = getattr(model, msg['func'])
        args = msg.get('args', [])
        kwargs = msg.get('kwargs', {})
        model_func(*args, **kwargs)
Esempio n. 11
0
# Licensed under a 3-clause BSD style license - see LICENSE.rst
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.ThermalModel('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 = []
Esempio n. 12
0
File: app.py Progetto: sot/xija
def main():
    # Enable fully-randomized evaluation of ACIS-FP model which is desirable
    # for fitting.
    taco.set_random_salt(None)

    opt = get_options()

    src = pyc.CONTEXT['src'] if 'src' in pyc.CONTEXT else pyc.ContextDict(
        'src')
    files = (pyc.CONTEXT['file'] if 'file' in pyc.CONTEXT else pyc.ContextDict(
        'files', basedir=str(Path.cwd())))
    files.update(xija.files)

    sherpa_logger = logging.getLogger("sherpa")
    loggers = (fit_logger, sherpa_logger)
    if opt.quiet:
        for logger in loggers:
            for h in logger.handlers:
                logger.removeHandler(h)

    if opt.filename.endswith(".json"):
        model_spec = json.load(open(opt.filename, 'r'))
    elif opt.filename in get_xija_model_names():
        model_spec, model_version = get_xija_model_spec(opt.filename)
    else:
        raise RuntimeError("'filename' not a valid path to a JSON file "
                           "or a valid model name!")

    gui_config.update(model_spec.get('gui_config', {}))
    src['model'] = model_spec['name']

    # Use supplied stop time and days OR use model_spec values if stop not supplied
    if opt.stop:
        start = CxoTime(CxoTime(opt.stop).secs - opt.days * 86400).date[:8]
        stop = opt.stop
    else:
        start = model_spec['datestart']
        stop = model_spec['datestop']

    model = xija.ThermalModel(model_spec['name'],
                              start,
                              stop,
                              model_spec=model_spec)

    set_data_vals = gui_config.get('set_data_vals', {})
    for set_data_expr in opt.set_data_exprs:
        set_data_expr = re.sub('\s', '', set_data_expr)
        try:
            comp_name, val = set_data_expr.split('=')
        except ValueError:
            raise ValueError(
                "--set_data must be in form '<comp_name>=<value>'")
        # Set data to value.  ast.literal_eval is a safe way to convert any
        # string literal into the corresponding Python object.
        set_data_vals[comp_name] = ast.literal_eval(val)

    for comp_name, val in set_data_vals.items():
        model.comp[comp_name].set_data(val)

    model.make()

    if opt.inherit_from:
        inherit_spec = json.load(open(opt.inherit_from, 'r'))
        inherit_pars = {par['full_name']: par for par in inherit_spec['pars']}
        for par in model.pars:
            if par.full_name in inherit_pars:
                print("Inheriting par {}".format(par.full_name))
                par.val = inherit_pars[par.full_name]['val']
                par.min = inherit_pars[par.full_name]['min']
                par.max = inherit_pars[par.full_name]['max']
                par.frozen = inherit_pars[par.full_name]['frozen']
                par.fmt = inherit_pars[par.full_name]['fmt']

    filename = Path(opt.filename)
    if filename.exists():
        gui_config['filename'] = str(filename.resolve())
    else:
        gui_config['filename'] = None
    gui_config['set_data_vals'] = set_data_vals

    fit_worker = FitWorker(model, opt.maxiter, method=opt.fit_method)

    model.calc()

    app = QtWidgets.QApplication(sys.argv)
    icon_path = str(Path(__file__).parent / "app_icon.png")
    icon = QtGui.QIcon(icon_path)
    app.setWindowIcon(icon)
    MainWindow(model, fit_worker, opt.filename)
    sys.exit(app.exec_())
Esempio n. 13
0
# Licensed under a 3-clause BSD style license - see LICENSE.rst
import os
import json
import numpy as np
import xija

mdl = xija.ThermalModel(start='2010:001', stop='2010:004')

tephin = mdl.add(xija.Node, 'tephin')
tcylaft6 = mdl.add(xija.Node, 'tcylaft6', predict=False)
coup_tephin_tcylaft6 = mdl.add(xija.Coupling, tephin, tcylaft6, tau=20)
aosares1 = mdl.add(xija.TelemData, 'aosares1')

tephin_solar = mdl.add(xija.SolarHeat,
                       tephin,
                       aosares1,
                       Ps=[0.1, 0.5, 1.0, 1.5, 2.0],
                       dPs=[0.01, 0.02, 0.03, 0.04, 0.05])

tephin_heatsink = mdl.add(xija.HeatSink, tephin, T=0.0, tau=20.0)

mdl.make()
mdl.write('test_write.json')

model_spec = json.load(open('test_write.json'))
mdl2 = xija.ThermalModel(start='2010:001',
                         stop='2010:004',
                         model_spec=model_spec)

os.unlink('test_write.json')
Esempio n. 14
0
P_pitches = [50, 90, 150]
P_vals = []
for instr in ('hrcs', 'hrci', 'acis'):
    for pitch in P_pitches:
        P_vals.append(pars['{0}{1}'.format(instr, pitch)])
P_vals = np.array(P_vals).reshape(3, 3) * u01 / c1
P_vals = P_vals.tolist()

tau_e = c1 / u01
T_e = -128.0 * (1. / u01 + 1. / u12)
k = 1. / c2
tau12 = c1 / u12
tau21 = c2 / u12

mdl = xija.ThermalModel('psmc',
                        start='2011:103:00:00:00.00',
                        stop='2011:124:00:00:00')

pin1at = mdl.add(xija.Node, '1pin1at')
pdeaat = mdl.add(xija.Node, '1pdeaat')
pitch = mdl.add(xija.Pitch)
sim_z = mdl.add(xija.SimZ)

coup12 = mdl.add(xija.Coupling, pin1at, pdeaat, tau=tau12)
coup21 = mdl.add(xija.Coupling, pdeaat, pin1at, tau=tau21)
sol = mdl.add(xija.AcisPsmcSolarHeat,
              pin1at,
              pitch,
              sim_z,
              P_pitches=P_pitches,
              P_vals=P_vals)
Esempio n. 15
0
# Build the core.so module and put into the source directory.
# python setup.py build_ext --inplace
# Licensed under a 3-clause BSD style license - see LICENSE.rst

import xija

model = xija.ThermalModel('test', start='2011:001', stop='2011:005')
tephin = model.add(xija.Node, 'tephin')
model.add(xija.HeatSink, tephin, T=0.0, tau=200.0)
tephin.set_data(30.0)

model.make()
model.calc()

# plot(model.times - model.times[0], model.comp['tephin'].mvals)

mvals = model.comp['tephin'].mvals
assert len(mvals) == 1051
assert mvals[0] == 30.0
assert abs(mvals[500] - 8.75402) < 0.001
assert abs(mvals[1050] - 2.26212) < 0.001
Esempio n. 16
0
File: fit.py Progetto: sot/xija
loggers = (fit_logger, sherpa_logger)
if opt.quiet:
    for logger in loggers:
        for h in logger.handlers:
            logger.removeHandler(h)

# Use supplied stop time or NOW - 7 days (truncated to nearest day)
stop = opt.stop or DateTime(DateTime().secs - 7 * 86400).date[:8]
start = DateTime(DateTime(stop).secs - opt.days * 86400).date[:8]

src['model'] = opt.model
src['outdir'] = opt.outdir
src['pardir'] = opt.pardir or opt.model

model_spec = json.load(open(files['model_spec.json'].abs, 'r'))
model = xija.ThermalModel(opt.model, start, stop, model_spec=model_spec)

### UGHH, need to clean this up, probably have model elements accumulate dynamically
### instead of a make step.
if not opt.nproc:
    model.make()

model.outdir = src['outdir'].val
model.pardir = src['pardir'].val

thaw_pars = opt.thaw_pars.split()

make_out_dir()

hdlr = logging.FileHandler(files['fit_log'].abs, 'w')
hdlr.setLevel(logging.INFO)