jayrock

jayrock#

JWST observation planning and simulation for minor bodies across the Solar System. You define the target and instrument(s) – jayrock does the rest.[1]

import jayrock

Compute visibility windows and ephemeris.

After defining the target of your observation, use jayrock to compute its visibility during a given JWST cycle and query its ephemeris from JPL Horizons.

achilles = jayrock.Target("achilles")
achilles.compute_ephemeris(cycle=6)   # compute ephemeris for JWST Cycle 6

Get a quick overview of visibility windows with the print_ephemeris() method.

achilles.print_ephemeris()
(588) Achilles: Ephemeris from 2027-07-01 to 2028-06-30
├── Window 1: 2027-07-02 -> 2027-08-10
   ├── Duration         40 days
   ├── Vmag             16.18 -> 16.48
   └── Thermal @ 15um   393.39 -> 308.31 mJy
├── Window 2: 2028-03-02 -> 2028-04-21
   ├── Duration         51 days
   ├── Vmag             16.54 -> 16.15
   └── Thermal @ 15um   279.80 -> 360.74 mJy
└── errRA/errDec in arcsec: 0.027 / 0.005

Model the target’s spectrum at different dates of observation.

You can model the spectrum of your target as seen from JWST at different dates during the visibility window. The spectrum is modelled as the sum of reflected sunlight and thermal emission using synphot and NEATM. Physical parameters of your target are retrieved with rocks.

Use the plot_spectrum() method to plot the spectrum at a given date.

achilles.plot_spectrum(date_obs="2028-03-06")

Provide multiple dates to investigate the spectral change e.g. at minimum and maximum thermal emission during the visibility window.

date_thermal_max = achilles.get_date_obs(at="thermal_max")
date_thermal_min = achilles.get_date_obs(at="thermal_min")
achilles.plot_spectrum(date_obs=[date_thermal_max, date_thermal_min])
_images/achilles_spec_date_dark.png

Fig. 1: Spectrum of (588) Achilles on 2028-03-06.#

_images/achilles_spec_date.png

Fig. 1: Spectrum of (588) Achilles on 2028-03-06.#

_images/achilles_spec_thermal_dark.png

Fig. 2: (588) Achilles at highest and lowest thermal flux.#

_images/achilles_spec_thermal.png

Fig. 2: (588) Achilles at highest and lowest thermal flux.#

Compute detector configurations to meet SNR targets.

Simulate observations with different instruments, modes, filters and dispersers, conveniently in a loop. Specify exposure times or define SNR target values and let jayrock configure the detector. Computations run locally using pandeia – no need for the browser.

The code below simulates observations with NIRSpec IFU using G235M/F170LP and G395M/F290LP optics. We set exposure times directly via the ngroup, nint, and nexp settings and plot the resulting SNR over wavelength.

_images/achilles_nirspec_dark.png

Fig. 3: SNR curves of NIRSpec/IFU observations of (588) Achilles. Vertical lines indicate the minium wavelength of the disperser/filter combination.#

_images/achilles_nirspec.png

Fig. 3: SNR curves of NIRSpec/IFU observations of (588) Achilles. Vertical lines indicate the minium wavelength of the disperser/filter combination.#

# Simulate observation of Achilles on date of minimum Vmag
date_obs = achilles.get_date_obs(at="vmag_min")

observations = []  # list to store observations

inst = jayrock.Instrument("NIRSpec", mode="IFU")

for disp, filt in [("G235M", "F170LP"), ("G395M", "F290LP")]:

    # Set filter and disperser
    inst.disperser = disp
    inst.filter = filt

    # Set ngroup, nint, nexp directly
    inst.detector.ngroup = 10  # number of groups per integration
    inst.detector.nint = 1     # number of integrations per exposure
    inst.detector.nexp = 4     # number of exposures -> number of dithers

    obs = jayrock.observe(achilles, inst, date_obs=date_obs)
    observations.append(obs)

# Plot SNR over wavelength
jayrock.plot_snr(observations)

In this example, we simulate observations across all apertures and disperser of the MIRI/MRS mode. We define SNR targets instead of exposure times.[2] This is possible for all JWST instruments and modes.

_images/achilles_miri_dark.png

Fig. 3: SNR of MIRI observations of (588) Achilles. All SNR targets are reached.#

_images/achilles_miri.png

Fig. 3: SNR of MIRI observations of (588) Achilles. All SNR targets are reached.#

# Simulate observation of Achilles on date of minimum Vmag
date_obs = achilles.get_date_obs(at="vmag_min")

observations = []  # list to store observations

inst = jayrock.Instrument("MIRI", mode="MRS")

# Each aperture and disperser is simulated separately
for aperture, disp in zip(['ch1', 'ch2', 'ch3', 'ch4'], ['short', 'medium', 'long']):

   # Set aperture and disperser
   inst.aperture = aperture
   inst.disperser = disp

   inst.detector.nexp = 4  # 4-pt dither

   # ------
   # Define SNR target based on aperture
   # mrsshort: ch1|ch2 - mrslong: ch3|ch4
   if aperture == 'ch1':  # 4.9-7.65μm
     snr_target = 10

   if aperture == 'ch2':  # 7.51-11.70μm
     snr_target = 300

   if aperture == 'ch3':  # 11.55-17.98μm
     snr_target = 200

   if aperture == 'ch4':  # 17.70-27.9μm
     snr_target = 100

   # jayrock sets ngroup and nint based on snr target
   inst.set_snr_target(snr_target, achilles, date_obs)

   obs = jayrock.observe(achilles, inst, date_obs=date_obs)
   observations.append(obs)

# Plot SNR over wavelength
jayrock.plot_snr(observations)