Thermal Models

ACISpy provides the ability to run Xija thermal models via a special class, ThermalModelRunner, which can input commanded states from a variety of sources. The really nice thing about ThermalModelRunner is that it is actually a Dataset object, so we can look at the different fields, make plots, and create derived fields.

[1]:
import acispy
import numpy as np

Basic Use of ThermalModelRunner

If a thermal model is being run entirely within the past or another situation where kadi commanded states are fully specified, you can simply run a thermal model by specifying the MSID to be modeled and the start and stop times of the model. The initial temperature will be specified from telemetry unless one sets an initial value using the T_init keyword argument. If we want to take model “bad times” into account, we also need to set mask_bad_times=True:

[2]:
dea_model = acispy.ThermalModelRunner("1deamzt", "2020:142", "2020:150",
                                      get_msids=True, mask_bad_times=True)
acispy: [INFO     ] 2022-01-06 21:49:58,572 Using model for dea from chandra_models version = 3.37
Fetching msid: sim_z over 2020:141:23:33:58.816 to 2020:150:00:21:26.816
Fetching msid: pitch over 2020:141:23:33:58.816 to 2020:150:00:21:26.816
Fetching msid: roll over 2020:141:23:33:58.816 to 2020:150:00:21:26.816
Fetching msid: aoeclips over 2020:141:23:33:58.816 to 2020:150:00:21:26.816
Getting kadi commanded states over 2020:142:00:01:18.816 to 2020:149:23:54:06.816
Fetching msid: dp_dpa_power over 2020:141:23:33:58.816 to 2020:150:00:21:26.816

get_msids=True is set, so the resulting Dataset object will be populated with actual telemetry as well as model data, so that you can examine and plot both:

[3]:
print(dea_model["model","1deamzt"][:10])
print(dea_model["msids","1deamzt"][:10])
[18.04144287 17.38565513 17.00264474 16.63986756 16.28379916 15.93363725
 15.58928472 15.2506595  14.91766727 14.59023318] deg_C
[17.756287 17.506805 17.328583 17.22165  16.972137 16.687012 16.50879
 16.259277 15.902863 15.653381] deg_C
[4]:
dp = acispy.DatePlot(dea_model, [("msids", "1deamzt"), ("model", "1deamzt")], plot_bad=True)
dp
[4]:
_images/Thermal_Models_7_0.png

Note that for this period of time a segment of it was marked as a “bad time” in the model, and this shows up in the cyan region in the plot.

By default, model specification files will be searched for in the chandra_models package. If your model spec file is not in that package, or you want to specify a different model specification file, you can pass ThermalModelRunner a model_spec optional argument:

[5]:
dea_model2 = acispy.ThermalModelRunner("1deamzt", "2020:142", "2020:150", model_spec="dea_model_spec.json")
acispy: [INFO     ] 2022-01-06 21:50:02,249 model_spec = /Users/jzuhone/Source/acispy/doc/source/dea_model_spec.json
Fetching msid: sim_z over 2020:141:23:33:58.816 to 2020:150:00:21:26.816
Fetching msid: pitch over 2020:141:23:33:58.816 to 2020:150:00:21:26.816
Fetching msid: roll over 2020:141:23:33:58.816 to 2020:150:00:21:26.816
Fetching msid: aoeclips over 2020:141:23:33:58.816 to 2020:150:00:21:26.816
Getting kadi commanded states over 2020:142:00:01:18.816 to 2020:149:23:54:06.816
Fetching msid: dp_dpa_power over 2020:141:23:33:58.816 to 2020:150:00:21:26.816

Running Thermal Models Using States from Various Sources

The ThermalModelRunner class also has various methods which one can use to run thermal models using states from various sources.

Running a Thermal Model from Commands

You can use a set of commands (either a kadi CommandTable or list of command dicts) to run a thermal model using the from_commands method:

[6]:
from kadi import commands
# commands as a CommandTable
cmds = commands.get_cmds('2018:001:00:00:00', '2018:002:00:00:00')
psmc_model = acispy.ThermalModelRunner.from_commands("1pdeaat", cmds)
# commands as a list of dicts
dict_cmds = cmds.as_list_of_dict()
psmc_model2 = acispy.ThermalModelRunner.from_commands("1pdeaat", dict_cmds)
acispy: [INFO     ] 2022-01-06 21:50:05,155 Using model for psmc from chandra_models version = 3.37
Fetching msid: aoeclips over 2018:001:02:07:50.816 to 2018:002:00:10:46.816
acispy: [INFO     ] 2022-01-06 21:50:06,234 Using model for psmc from chandra_models version = 3.37
Fetching msid: aoeclips over 2018:001:02:07:50.816 to 2018:002:00:10:46.816

Running a Thermal Model from a Backstop File

You can use a backstop file as input to ThermalModelRunner to generate states for a thermal model run. In this case, ThermalModelRunner will go back to the latest telemetry to determine the initial temperature (unless one is specified, see below) and construct states from that point and handle continuity between those and the commands in the backstop file appropriately. To show this, we’ll use the ACA thermal model, which requires that the initial value for the aca0 pseudonode be specified, which we can do using the other_init keyword argument:

[7]:
tm_aca = acispy.ThermalModelRunner.from_backstop(
    "aacccdpt", "/data/acis/LoadReviews/2020/AUG1720/ofls/CR229_2202.backstop",
    other_init={"aca0": -10})
acispy: [INFO     ] 2022-01-06 21:50:07,972 Using model for aca from chandra_models version = 3.37
Fetching msid: aoeclips over 2020:226:22:27:02.816 to 2020:237:01:59:26.816
[8]:
dp = acispy.DatePlot(tm_aca, ('model','aacccdpt'), field2="pitch")
dp
[8]:
_images/Thermal_Models_19_0.png

Running a Thermal Model Using a states.dat File

One can run a thermal model from a states.dat table file which would be outputted by the thermal model check scripts during a load review, using the from_states_file() method:

[9]:
dpa_model = acispy.ThermalModelRunner.from_states_file("1dpamzt", "my_states.dat")
acispy: [INFO     ] 2022-01-06 21:50:09,437 Using model for dpa from chandra_models version = 3.37
Fetching msid: aoeclips over 2017:035:18:00:22.816 to 2017:051:06:00:46.816

Running Thermal Models Using States Constructed By Hand

You can create a dictionary of states completely by hand and submit them as a keyword argument to ThermalModelRunner, for running completely hypothetical thermal models. For simplicity, we’ll pick constant states except change the CCD count.

[10]:
states = {"ccd_count": np.array([5,6,1]),
          "pitch": np.array([150.0]*3),
          "fep_count": np.array([5,6,1]),
          "clocking": np.array([1]*3),
          "vid_board": np.array([1]*3),
          "off_nom_roll": np.array([0.0]*3),
          "simpos": np.array([-99616.0]*3),
          "datestart": np.array(["2015:002:00:00:00","2015:002:12:00:00","2015:003:12:00:00"]),
          "datestop": np.array(["2015:002:12:00:00","2015:003:12:00:00","2015:005:00:00:00"])}

In the previous examples, we never specified an initial temperature, but we can always do so, and must do so if we are past the end value in telemetry. This is not the case here, but we’ll set one anyway:

[11]:
T_init = 13.0 # in degrees C

Now we can pass in the states dict we created, as well as the T_init:

[12]:
dea_model = acispy.ThermalModelRunner("1deamzt", "2015:002:00:00:00",
                                      "2015:005:00:00:00", states=states, T_init=T_init)
acispy: [INFO     ] 2022-01-06 21:50:10,048 Using model for dea from chandra_models version = 3.37
Fetching msid: aoeclips over 2015:001:23:34:56.816 to 2015:005:00:17:20.816
[13]:
dp = acispy.DatePlot(dea_model, ("model","1deamzt"), field2="ccd_count")
dp.set_ylim2(0,7)
dp
[13]:
_images/Thermal_Models_30_0.png

We can also dump the results of the model run to disk, both the states and the model components:

[14]:
dea_model.write_model("model.dat", overwrite=True)
dea_model.write_states("states.dat", overwrite=True)

These files can be loaded in at a later date using ModelDataFromFiles.

Making Dashboard Plots

NOTE: This functionality requires the xijafit package to be installed.

It is possible to use the thermal model objects and the xijafit package to make dashboard plots. For this, use the make_dashboard_plots() method:

[15]:
dpa_model_long = acispy.ThermalModelRunner("1dpamzt", "2016:200", "2017:200",
                                           mask_bad_times=True, get_msids=True)
dpa_model_long.make_dashboard_plots("1dpamzt", figfile="my_dpa_dash.png")
acispy: [INFO     ] 2022-01-06 21:50:11,233 Using model for dpa from chandra_models version = 3.37
Fetching msid: sim_z over 2016:199:23:37:59.816 to 2017:200:00:17:34.816
Fetching msid: pitch over 2016:199:23:37:59.816 to 2017:200:00:17:34.816
Fetching msid: roll over 2016:199:23:37:59.816 to 2017:200:00:17:34.816
Fetching msid: aoeclips over 2016:199:23:37:59.816 to 2017:200:00:17:34.816
Getting kadi commanded states over 2016:200:00:05:19.816 to 2017:199:23:50:14.816
Fetching msid: dp_dpa_power over 2016:199:23:37:59.816 to 2017:200:00:17:34.816
WARNING: imaging routines will not be available,
failed to import sherpa.image.ds9_backend due to
'RuntimeErr: DS9Win unusable: Could not find xpaget on your PATH'
[15]:
_images/Thermal_Models_37_2.png

figfile sets the filename to save the dashboard plot to.

One can also use the errorplotlimits and yplotlimits arguments to set the bounds of the temperature and the errors on the plots:

[16]:
fp_model_long = acispy.ThermalModelRunner("fptemp_11", "2016:200", "2017:200",
                                          mask_bad_times=True, get_msids=True)
fp_model_long.make_dashboard_plots("fptemp_11", yplotlimits=(-120.0, -104.0),
                                   errorplotlimits=(-5.0, 5.0))
acispy: [INFO     ] 2022-01-06 21:50:37,234 Using model for acisfp from chandra_models version = 3.37
Fetching msid: 1cbat over 2016:199:23:37:59.816 to 2017:200:00:17:34.816
Fetching msid: pitch over 2016:199:23:37:59.816 to 2017:200:00:17:34.816
Fetching msid: roll over 2016:199:23:37:59.816 to 2017:200:00:17:34.816
Fetching msid: 1dahtbon over 2016:199:23:37:59.816 to 2017:200:00:17:34.816
Fetching msid: aoeclips over 2016:199:23:37:59.816 to 2017:200:00:17:34.816
Fetching msid: sim_z over 2016:199:23:37:59.816 to 2017:200:00:17:34.816
Getting kadi commanded states over 2016:200:00:05:19.816 to 2017:199:23:50:14.816
Fetching msid: dp_dpa_power over 2016:199:23:37:59.816 to 2017:200:00:17:34.816
Fetching msid: orbitephem0_x over 2016:199:23:37:59.816 to 2017:200:00:17:34.816
Fetching msid: orbitephem0_y over 2016:199:23:37:59.816 to 2017:200:00:17:34.816
Fetching msid: orbitephem0_z over 2016:199:23:37:59.816 to 2017:200:00:17:34.816
Fetching msid: aoattqt1 over 2016:199:23:37:59.816 to 2017:200:00:17:34.816
Fetching msid: aoattqt2 over 2016:199:23:37:59.816 to 2017:200:00:17:34.816
Fetching msid: aoattqt3 over 2016:199:23:37:59.816 to 2017:200:00:17:34.816
Fetching msid: aoattqt4 over 2016:199:23:37:59.816 to 2017:200:00:17:34.816
[16]:
_images/Thermal_Models_39_2.png

Plotting Pitch and State Power Heating Values

All thermal models have a solar heating component. To make a quick solar heating plot, use the make_solarheat_plot method, with the node that the solar heating component acts upon as the first argument.

[17]:
dpa_model_long.make_solarheat_plot("dpa0", figfile="dpa0_pitches.png")
[17]:
_images/Thermal_Models_42_0.png

Similarly, to plot the ACIS state power coefficients for a model (if present), use the make_power_plot method:

[18]:
# For the 1DEAMZT model set use_ccd_count=True
dpa_model_long.make_power_plot(figfile="acis_state_power.png", use_ccd_count=False)
[18]:
_images/Thermal_Models_44_0.png

Simulating Single States

The SimulateSingleState class is a simplified implemenation of ThermalModelRunner which assumes that the spacecraft state is constant over a period of time. This class takes the name of the temperature to simulate, a start and stop date, and a dictionary of states. It is not required to specify all states in this dictionary, but note that states not specified will be assumed to be the following:

  • pitch: 90 deg

  • off_nom_roll: 0 deg

  • ccd_count: 0

  • fep_count: 0

  • clocking: 0

  • vid_board: 0

  • simpos: -99616.0

  • hetg: "RETR"

  • letg: "RETR"

  • dh_heater: 0

  • q1: 1.0

  • q2: 0.0

  • q3: 0.0

  • q4: 0.0

[19]:
datestart = "2019:181:01:00:00" # start time of run
datestop = "2019:183:01:00:00" # stop time of run
states = {"pitch": 70.0}
T_init = -11.0 # in degrees F
aca_m = acispy.SimulateSingleState("aacccdpt", datestart, datestop, states, T_init, other_init={"aca0": T_init})
acispy: [INFO     ] 2022-01-06 21:51:07,445 Using model for aca from chandra_models version = 3.37
Fetching msid: aoeclips over 2019:181:00:35:02.816 to 2019:183:01:19:42.816
[20]:
dp = acispy.DatePlot(aca_m, "aacccdpt")
dp
[20]:
_images/Thermal_Models_48_0.png

Simulating ECS Runs

A further special case of running a single state is an ECS run, which may be performed after a safing action. The SimulateECSRun class is a limited version of SimulateSingleState which assumes that the SIM-Z position is HRC-S (-99616) and that ACIS is clocking. The goal is to predict if the temperature will hit the planning limit within the time frame of the ECS run. A start time is specified, as well as the number of hours in the ECS run (the same number of hours as specified on the ECS CAP). Then, an attitude must be specified, which can take one of three forms: * A (pitch, off-nominal roll) combination * An attitude quaternion * The name of a load (for vehicle load ECS runs)

We pick a model to run (most relevant is "1dpamzt") along with a start time a length of the ECS run in hours (24 in this case), and feed the parameters into SimulateECSRun:

[21]:
datestart = "2015:002:00:00:00" # start time of run
hours = 24 # length of ECS run in hours
attitude = [137.0, 0.0] # pitch, off-nominal roll in degrees
T_init = 7.5 # in degrees C
ccd_count = 6 # number of CCDs
dpa_ecs_run = acispy.SimulateECSRun("1dpamzt", datestart, hours, T_init, attitude,
                                    ccd_count)
acispy: [INFO     ] 2022-01-06 21:51:08,102 Using model for dpa from chandra_models version = 3.37
Fetching msid: aoeclips over 2015:001:23:34:56.816 to 2015:003:16:29:28.816
acispy: [INFO     ] 2022-01-06 21:51:08,362 Run Parameters
acispy: [INFO     ] 2022-01-06 21:51:08,363 --------------
acispy: [INFO     ] 2022-01-06 21:51:08,363 Modeled Temperature: 1dpamzt
acispy: [INFO     ] 2022-01-06 21:51:08,364 Start Datestring: 2015:002:00:00:00.000
acispy: [INFO     ] 2022-01-06 21:51:08,364 Length of state in hours: 24
acispy: [INFO     ] 2022-01-06 21:51:08,365 Stop Datestring: 2015:003:16:10:18.000
acispy: [INFO     ] 2022-01-06 21:51:08,365 Initial Temperature: 7.5 degrees C
acispy: [INFO     ] 2022-01-06 21:51:08,366 CCD/FEP Count: 6
acispy: [INFO     ] 2022-01-06 21:51:08,366 Pitch: 137.0
acispy: [INFO     ] 2022-01-06 21:51:08,367 Off-nominal Roll: 0.0
acispy: [INFO     ] 2022-01-06 21:51:08,367 Detector Housing Heater: OFF
acispy: [INFO     ] 2022-01-06 21:51:08,368 Model Result
acispy: [INFO     ] 2022-01-06 21:51:08,368 ------------
acispy: [INFO     ] 2022-01-06 21:51:08,370 The limit of 37.5 degrees C will be reached at 2015:002:18:48:24.816, after 67.70481599998475 ksec.
acispy: [INFO     ] 2022-01-06 21:51:08,370 The limit is reached before the end of the observation.
acispy: [WARNING  ] 2022-01-06 21:51:08,371 This observation is NOT safe from a thermal perspective.

NOTE that the actual length of the ECS run, as per the ECS CAP, is hours+ 10 ks + 12 s.

The run reports back the input parameters and the time when the limit was reached, if it was at all. We can plot the model using the plot_model() method, which shows the limit value as a dashed green line and the time at which the limit was reached as a dashed red line, as well as whether or not this was a safe ECS run:

[22]:
dpa_ecs_run.plot_model()
[22]:
_images/Thermal_Models_54_0.png

On the other hand, if the ECS run had been shorter, the limit would be reached after the ECS run, so this is safe.

[23]:
hours = 14
dpa_ecs_run = acispy.SimulateECSRun("1dpamzt", datestart, hours, T_init, attitude,
                                    ccd_count)
dpa_ecs_run.plot_model()
acispy: [INFO     ] 2022-01-06 21:51:09,382 Using model for dpa from chandra_models version = 3.37
Fetching msid: aoeclips over 2015:001:23:34:56.816 to 2015:003:01:27:28.816
acispy: [INFO     ] 2022-01-06 21:51:09,591 Run Parameters
acispy: [INFO     ] 2022-01-06 21:51:09,592 --------------
acispy: [INFO     ] 2022-01-06 21:51:09,593 Modeled Temperature: 1dpamzt
acispy: [INFO     ] 2022-01-06 21:51:09,593 Start Datestring: 2015:002:00:00:00.000
acispy: [INFO     ] 2022-01-06 21:51:09,594 Length of state in hours: 14
acispy: [INFO     ] 2022-01-06 21:51:09,595 Stop Datestring: 2015:003:01:10:18.000
acispy: [INFO     ] 2022-01-06 21:51:09,595 Initial Temperature: 7.5 degrees C
acispy: [INFO     ] 2022-01-06 21:51:09,596 CCD/FEP Count: 6
acispy: [INFO     ] 2022-01-06 21:51:09,596 Pitch: 137.0
acispy: [INFO     ] 2022-01-06 21:51:09,597 Off-nominal Roll: 0.0
acispy: [INFO     ] 2022-01-06 21:51:09,597 Detector Housing Heater: OFF
acispy: [INFO     ] 2022-01-06 21:51:09,598 Model Result
acispy: [INFO     ] 2022-01-06 21:51:09,599 ------------
acispy: [INFO     ] 2022-01-06 21:51:09,601 The limit of 37.5 degrees C will be reached at 2015:002:18:48:24.816, after 67.70481599998475 ksec.
acispy: [INFO     ] 2022-01-06 21:51:09,601 The limit is reached after the end of the observation.
acispy: [INFO     ] 2022-01-06 21:51:09,601 This observation is safe from a thermal perspective.
[23]:
_images/Thermal_Models_56_3.png

Note that for some combinations of parameters the limit may never be reached. For example, let’s knock the CCD count down to 4:

[24]:
ccd_count = 4 # only 4 CCDs
dpa_ecs_run = acispy.SimulateECSRun("1dpamzt", datestart, hours, T_init, attitude,
                                    ccd_count)
dpa_ecs_run.plot_model()
acispy: [INFO     ] 2022-01-06 21:51:10,312 Using model for dpa from chandra_models version = 3.37
Fetching msid: aoeclips over 2015:001:23:34:56.816 to 2015:003:01:27:28.816
acispy: [INFO     ] 2022-01-06 21:51:10,521 Run Parameters
acispy: [INFO     ] 2022-01-06 21:51:10,521 --------------
acispy: [INFO     ] 2022-01-06 21:51:10,522 Modeled Temperature: 1dpamzt
acispy: [INFO     ] 2022-01-06 21:51:10,523 Start Datestring: 2015:002:00:00:00.000
acispy: [INFO     ] 2022-01-06 21:51:10,523 Length of state in hours: 14
acispy: [INFO     ] 2022-01-06 21:51:10,524 Stop Datestring: 2015:003:01:10:18.000
acispy: [INFO     ] 2022-01-06 21:51:10,524 Initial Temperature: 7.5 degrees C
acispy: [INFO     ] 2022-01-06 21:51:10,525 CCD/FEP Count: 4
acispy: [INFO     ] 2022-01-06 21:51:10,525 Pitch: 137.0
acispy: [INFO     ] 2022-01-06 21:51:10,526 Off-nominal Roll: 0.0
acispy: [INFO     ] 2022-01-06 21:51:10,526 Detector Housing Heater: OFF
acispy: [INFO     ] 2022-01-06 21:51:10,527 Model Result
acispy: [INFO     ] 2022-01-06 21:51:10,527 ------------
acispy: [INFO     ] 2022-01-06 21:51:10,528 The limit of 37.5 degrees C is never reached.
acispy: [INFO     ] 2022-01-06 21:51:10,528 This observation is safe from a thermal perspective.
[24]:
_images/Thermal_Models_58_3.png

Simulating ECS Runs with Vehicle Loads

If the spacecraft executed SCS-107, we may be running an ECS run while the vehicle load is still running, which means that the pitch and off-nominal roll may change during the ECS run. If this is the case, pass the name of the load to the attitude parameter. An example of an ECS run with a vehicle load that is not safe:

[25]:
datestart = "2017:256:03:20:00"
hours = 24
T_init = 12.0 # in degrees C
attitude = "SEP0917C" # attitude info will be take from this load
ccd_count = 6 # number of CCDs
dpa_ecs_run = acispy.SimulateECSRun("1dpamzt", datestart, hours, T_init, attitude, ccd_count)
dpa_ecs_run.plot_model()
acispy: [INFO     ] 2022-01-06 21:51:10,977 Modeling a 6-chip state concurrent with the SEP0917C vehicle loads.
acispy: [INFO     ] 2022-01-06 21:51:12,441 Using model for dpa from chandra_models version = 3.37
Fetching msid: aoeclips over 2017:256:02:54:54.816 to 2017:257:19:49:26.816
acispy: [INFO     ] 2022-01-06 21:51:12,683 Run Parameters
acispy: [INFO     ] 2022-01-06 21:51:12,684 --------------
acispy: [INFO     ] 2022-01-06 21:51:12,684 Modeled Temperature: 1dpamzt
acispy: [INFO     ] 2022-01-06 21:51:12,685 Start Datestring: 2017:256:03:20:00.000
acispy: [INFO     ] 2022-01-06 21:51:12,685 Length of state in hours: 24
acispy: [INFO     ] 2022-01-06 21:51:12,686 Stop Datestring: 2017:257:19:30:18.000
acispy: [INFO     ] 2022-01-06 21:51:12,686 Initial Temperature: 12.0 degrees C
acispy: [INFO     ] 2022-01-06 21:51:12,687 CCD/FEP Count: 6
acispy: [INFO     ] 2022-01-06 21:51:12,687 Detector Housing Heater: OFF
acispy: [INFO     ] 2022-01-06 21:51:12,688 Model Result
acispy: [INFO     ] 2022-01-06 21:51:12,689 ------------
acispy: [INFO     ] 2022-01-06 21:51:12,691 The limit of 37.5 degrees C will be reached at 2017:256:11:17:50.816, after 28.670815999984743 ksec.
acispy: [INFO     ] 2022-01-06 21:51:12,691 The limit is reached before the end of the observation.
acispy: [WARNING  ] 2022-01-06 21:51:12,692 This observation is NOT safe from a thermal perspective.
[25]:
_images/Thermal_Models_61_3.png

But if we drop it down to 5 chips, it is safe:

[26]:
ccd_count = 5 # number of CCDs
dpa_ecs_run = acispy.SimulateECSRun("1dpamzt", datestart, hours, T_init, attitude, ccd_count)
dpa_ecs_run.plot_model()
acispy: [INFO     ] 2022-01-06 21:51:13,449 Modeling a 5-chip state concurrent with the SEP0917C vehicle loads.
acispy: [INFO     ] 2022-01-06 21:51:15,029 Using model for dpa from chandra_models version = 3.37
Fetching msid: aoeclips over 2017:256:02:54:54.816 to 2017:257:19:49:26.816
acispy: [INFO     ] 2022-01-06 21:51:15,248 Run Parameters
acispy: [INFO     ] 2022-01-06 21:51:15,248 --------------
acispy: [INFO     ] 2022-01-06 21:51:15,249 Modeled Temperature: 1dpamzt
acispy: [INFO     ] 2022-01-06 21:51:15,249 Start Datestring: 2017:256:03:20:00.000
acispy: [INFO     ] 2022-01-06 21:51:15,250 Length of state in hours: 24
acispy: [INFO     ] 2022-01-06 21:51:15,250 Stop Datestring: 2017:257:19:30:18.000
acispy: [INFO     ] 2022-01-06 21:51:15,251 Initial Temperature: 12.0 degrees C
acispy: [INFO     ] 2022-01-06 21:51:15,251 CCD/FEP Count: 5
acispy: [INFO     ] 2022-01-06 21:51:15,251 Detector Housing Heater: OFF
acispy: [INFO     ] 2022-01-06 21:51:15,253 Model Result
acispy: [INFO     ] 2022-01-06 21:51:15,253 ------------
acispy: [INFO     ] 2022-01-06 21:51:15,254 The limit of 37.5 degrees C is never reached.
acispy: [INFO     ] 2022-01-06 21:51:15,254 This observation is safe from a thermal perspective.
[26]:
_images/Thermal_Models_63_3.png

Simulating the Focal Plane Temperature for ECS Runs

The ACIS Focal Plane (FP) temperature can also be modeled for an ECS run. This will track the amount of “cold time” for the ECS measurement, as well as determine if the run will exceed the FP limit for that particular instrument, ACIS-I or ACIS-S. In this case, a quaternion generally should be supplied for the value of attitude, since the FP temperature can depend on the value of the Earth solid angle. The instrument argument should also be supplied to determine what thermal limit will be applied.

[27]:
datestart = "2020:148:14:45:00" # start time of run
hours = 24 # length of ECS run in hours
T_init = -115.0 # in degrees C
ccd_count = 4 # number of CCDs
attitude = [-0.04470333, 0.63502552, -0.67575906, 0.37160988] # attitude quaternion required
instrument = "ACIS-S"

fp_ecs_run = acispy.SimulateECSRun("fptemp_11", datestart, hours, T_init, attitude, ccd_count,
                                   instrument=instrument)
fp_ecs_run.plot_model()
acispy: [INFO     ] 2022-01-06 21:51:16,173 Using model for acisfp from chandra_models version = 3.37
Fetching msid: aoeclips over 2020:148:14:22:22.816 to 2020:150:07:16:54.816
acispy: [INFO     ] 2022-01-06 21:51:16,420 Run Parameters
acispy: [INFO     ] 2022-01-06 21:51:16,421 --------------
acispy: [INFO     ] 2022-01-06 21:51:16,422 Modeled Temperature: fptemp_11
acispy: [INFO     ] 2022-01-06 21:51:16,422 Start Datestring: 2020:148:14:45:00.000
acispy: [INFO     ] 2022-01-06 21:51:16,423 Length of state in hours: 24
acispy: [INFO     ] 2022-01-06 21:51:16,423 Stop Datestring: 2020:150:06:55:18.000
acispy: [INFO     ] 2022-01-06 21:51:16,424 Initial Temperature: -115.0 degrees C
acispy: [INFO     ] 2022-01-06 21:51:16,424 CCD/FEP Count: 4
acispy: [INFO     ] 2022-01-06 21:51:16,425 Quaternion: [-0.04470333, 0.63502552, -0.67575906, 0.37160988]
acispy: [INFO     ] 2022-01-06 21:51:16,425 Pitch: 155.13828486037553
acispy: [INFO     ] 2022-01-06 21:51:16,426 Off-nominal Roll: 10.637704660891393
acispy: [INFO     ] 2022-01-06 21:51:16,426 Detector Housing Heater: OFF
acispy: [INFO     ] 2022-01-06 21:51:16,427 Model Result
acispy: [INFO     ] 2022-01-06 21:51:16,428 ------------
acispy: [INFO     ] 2022-01-06 21:51:16,428 The focal plane is never cold for this ECS measurement.
acispy: [INFO     ] 2022-01-06 21:51:16,430 The limit of -111.0 degrees C will be reached at 2020:149:06:02:38.816, after 55.058815999984745 ksec.
acispy: [INFO     ] 2022-01-06 21:51:16,430 The limit is reached before the end of the observation.
[27]:
_images/Thermal_Models_65_3.png

This can also be done for a vehicle load as the attitude parameter:

[28]:
datestart = "2017:256:03:20:00"
hours = 24
T_init = -119.0 # in degrees C
attitude = "SEP0917C" # attitude info will be take from this load
ccd_count = 6 # number of CCDs
fp_ecs_run = acispy.SimulateECSRun("fptemp_11", datestart, hours, T_init, attitude, ccd_count,
                                    instrument="ACIS-I")
fp_ecs_run.plot_model()
acispy: [INFO     ] 2022-01-06 21:51:16,978 Modeling a 6-chip state concurrent with the SEP0917C vehicle loads.
acispy: [INFO     ] 2022-01-06 21:51:18,412 Using model for acisfp from chandra_models version = 3.37
Fetching msid: aoeclips over 2017:256:02:54:54.816 to 2017:257:19:49:26.816
acispy: [INFO     ] 2022-01-06 21:51:18,620 Run Parameters
acispy: [INFO     ] 2022-01-06 21:51:18,620 --------------
acispy: [INFO     ] 2022-01-06 21:51:18,621 Modeled Temperature: fptemp_11
acispy: [INFO     ] 2022-01-06 21:51:18,621 Start Datestring: 2017:256:03:20:00.000
acispy: [INFO     ] 2022-01-06 21:51:18,622 Length of state in hours: 24
acispy: [INFO     ] 2022-01-06 21:51:18,622 Stop Datestring: 2017:257:19:30:18.000
acispy: [INFO     ] 2022-01-06 21:51:18,623 Initial Temperature: -119.0 degrees C
acispy: [INFO     ] 2022-01-06 21:51:18,624 CCD/FEP Count: 6
acispy: [INFO     ] 2022-01-06 21:51:18,624 Detector Housing Heater: OFF
acispy: [INFO     ] 2022-01-06 21:51:18,625 Model Result
acispy: [INFO     ] 2022-01-06 21:51:18,625 ------------
acispy: [INFO     ] 2022-01-06 21:51:18,626 The focal plane is cold for 7.872 ks.
acispy: [INFO     ] 2022-01-06 21:51:18,627 The limit of -112.0 degrees C is never reached.
[28]:
_images/Thermal_Models_67_3.png