Pandeia Tutorials
This article provides several examples of how to use Pandeia for Roman.
How to Use this Article
In this article, several examples of how to use Pandeia for Roman are given. Prior to reading these examples, users should consult the article Overview of Pandeia for information on how to install Pandeia and the necessary supporting data files, as well as for configuration information for Pandeia simulations.
Example 1: Compute the Signal-to-Noise Ratio
Running the code below will generate output in the form of a dictionary that contains all of the information from the Pandeia Engine Report. This is largely the standard way of running Pandeia where the properties of the instrumental set up and astronomical scene are specified.
Description of Code Snippet
The configuration below uses the default point source normalized to 25 AB magnitudes, the WFI multi-accumulation (MA) table "High Latitude Wide Area Survey – Imaging" with a truncation after 5 resultants (91.20 seconds of total exposure time), and the F129 imaging filter. The Appendix: WFI MultiAccum Tables article in the Roman APT User's Guide provides and overview of MA tables in Roman at this time. See the article Overview of Pandeia for more information.
Python Implementation
from pandeia.engine.perform_calculation import perform_calculation from pandeia.engine.calc_utils import build_default_calc # Get Default Parameters calc = build_default_calc('roman','wfi','imaging') # set the global variable for the filter name (change to any valid filter) FILTER = 'f129' # Modify defaults to simulate a 25th AB magnitude source mag = 25 calc['scene'][0]['spectrum']['normalization']['norm_flux'] = mag calc['scene'][0]['spectrum']['normalization']['norm_fluxunit'] = 'abmag' # Set number of exposures and filter nexp = 3 calc['configuration']['detector']['nexp'] = nexp calc['configuration']['instrument']['filter'] = FILTER # Run calculation and return signal-to-noise ratio report = perform_calculation(calc) SNR = report['scalar']['sn'] print(f'Estimated S/N: {SNR:.2f}')
Warnings from Running the Code Block
This step may generate a WARNING from synphot that the spectrum is extrapolated, which can be ignored.
Running
Pandeia
for Roman will likely return a warning such as: if np.log(abs(val)) < -1*precision and val != 0.0
. This is related to a JWST-specific test for float precision, and can be ignored in this case.
Result from the Example
This calculation should output an estimated signal-to-noise of . 28.82
Example 2: Compute Limiting Magnitude
In this example, it is assumed that the user has an exposure configuration and is interested in understanding the limiting magnitude at a set signal-to-noise. This application may be common for Roman when users are exploring the Roman science data archive.
The default observational setup for Roman will be used. As in the previous example, the MA table is set to the "High Latitude Wide Area Survey – Imaging" table with 5 resultants. The Table of Code Inputs for Limiting Magnitude Calculation summarizes the parameters that can be adjusted in the Python implementation of this example and their presets. Starting with this example, users can change these parameters to better match their scientific use case.
Description of Code Snippet
The output from the code is the the
of a source with
limiting magnitude
=
SN
5
from
=
NEXP
10
=
FILTER
'f129'
; the code will assume a flat SED. The calculation is determined by setting up a helper function to optimize the signal-to-noise at the input magnitude and a method that computes the magnitude of at a given signal-to-noise given the number of exposures. The latter function sets up the build_default_calc
for Roman and performs the
Pandeia
simulations over a range of magnitudes iteratively to find the best match magnitude for the specified signal-to-noise. The parameters summarized in the Table of Code Inputs for Limiting Magnitude Calculation are input near the end of the code-block and can be easily modified for the use case of interest. The result of this code is given at the end of the code block for a user to confirm their execution of the code.
Table of Code Inputs for Limiting Magnitude Calculation
Specified Input | Description | Parameter in Code Example | Value in Code Example |
---|---|---|---|
signal-to-noise | the value that is useful for the science case being investigated | SN | 5 |
number of exposures | the number of individual exposures of a given Multi-Accumulation sequence | NEXP | 10 |
filter | the filter used in the observation | FILTER | 'f129' |
Python Implementation
from scipy.optimize import minimize_scalar from pandeia.engine.calc_utils import build_default_calc from pandeia.engine.perform_calculation import perform_calculation def _mag2sn_(mag,calc,sntarget): """ Helper function to optimize the S/N given a magnitude. """ calc['scene'][0]['spectrum']['normalization']['norm_flux'] = mag etc = perform_calculation(calc)['scalar'] return (sntarget-etc['sn'])**2 def compute_mag(filt,sn,nexp,bracket=(18.,30.),xtol=1e-4): """ Method to compute the magnitude from S/N and number of exposures Parameters ---------- filt : str Name of Roman WFI filter sn : float Required S/N nexp : int Number of exposures bracket : tuple, default (18., 30.) Range of magnitudes to test xtold: float, default 1e-4 Target tolerance for minimizer Returns ------- mag : float Optimal magnitude for specified S/N and number of exposures report: dict Pandeia dictionary with optimal parameters """ # Setup default Roman observation calc = build_default_calc('roman','wfi','imaging') # Modify defaults to place a source with an AB magnitude calc['scene'][0]['spectrum']['normalization']['norm_fluxunit'] = 'abmag' calc['scene'][0]['spectrum']['normalization']['norm_waveunit'] = 'um' # Set number of exposures and filter calc['configuration']['detector']['nexp'] = nexp calc['configuration']['instrument']['filter'] = filt res=minimize_scalar(_mag2sn_,bracket=bracket,args=(calc,sn), method='brent',options={'xtol':xtol}) mag=res['x'] calc['scene'][0]['spectrum']['normalization']['norm_flux'] = mag report=perform_calculation(calc) return mag,report # Required S/N and number of exposures sn = 5. nexp = 10 FILTER = 'f129' # Run minimizer function to estimate the magnitude given sn and nexp mag, report = compute_mag(FILTER, sn, nexp) print(f'Estimated magnitude: {mag:.2f}')
Result from the Example
This calculation should output an estimated limiting magnitude of mag at a signal-to-noise of 5 based on the inputs from the 27.68 Table of Code Inputs for Limiting Magnitude Calculation.
Example 3: Determine the Number of Exposures
In this example, we assume the user has a required signal-to-noise at a desired magnitude limits, and wishes to know the number of exposures, for the default MA table, required to achieve these observational results.
Description of Code Snippet
In this case, the inputs to the code are
,
SN
, and
MAG
, which are described in the
FILTER
Table of Code Inputs for Determining Number of Exposures. The output will be
NEXP
. The code will assume a flat SED. The calculation is determined by setting up a helper function to optimize the signal-to-noise at the input magnitude and a method that computes the number-of-exposures of at a given signal-to-noise given the source magnitude. The latter function sets up the build_default_calc
for Roman and performs the
Pandeia
simulations over a range of number of exposures iteratively to find the best match. The parameters summarized in the Table of Code Inputs for Determining Number of Exposures are input near the end of the code-block and can be easily modified for the use case of interest. The result of this code is given at the end of the code block for a user to confirm their execution of the code.
Table of Code Inputs for Determining Number of Exposures
Specified Input | Description | Parameter in Code Example | Value in Code Example |
---|---|---|---|
signal-to-noise | the value that is useful for the science case being investigated | SN | 20 |
source magnitude | the magnitude in ABMag for the source of interest | MAG | 27 |
filter | the filter used in the observation | FILTER | 'f129' |
Python Implementation
from scipy.optimize import minimize_scalar from pandeia.engine.calc_utils import build_default_calc from pandeia.engine.perform_calculation import perform_calculation def _nexp2sn_(nexp,calc,sntarget): """ Helper function to optimize the S/N given a number of exposures. """ calc['configuration']['detector']['nexp'] = int(nexp) etc = perform_calculation(calc)['scalar'] return (sntarget-etc['sn'])**2 def compute_nexp(filt,sn,mag,bracket=(1,1000),xtol=0.1): """ Method to compute the number of exposures from S/N and magnitude Parameters ---------- filt : str Name of Roman WFI filter sn : float Required S/N mag : float AB Magnitude of source bracket : tuple, default (1, 1000) Range of magnitudes to test xtold: float, default 0.1 Target tolerance for minimizer Returns ------- nexp : float Optimal number of exposures for specified S/N and magnitude report: dict Pandeia dictionary with optimal parameters exptime: float Exposure time for optimal observation """ # Setup default Roman observation calc = build_default_calc('roman','wfi','imaging') # Modify defaults to place a source with an AB magnitude calc['scene'][0]['spectrum']['normalization']['norm_flux'] = mag calc['scene'][0]['spectrum']['normalization']['norm_fluxunit'] = 'abmag' calc['scene'][0]['spectrum']['normalization']['norm_waveunit'] = 'um' # Set filter calc['configuration']['instrument']['filter'] = filt # Check that the minimum of 1 exposure has a S/N lower than requested, # otherwise there is no sense in attempting to minimize nexp. calc['configuration']['detector']['nexp'] = 1 report=perform_calculation(calc) if report['scalar']['sn']>sn: nexp=1 else: res=minimize_scalar(_nexp2sn_,bracket=bracket,bounds=bracket, args=(calc,sn),method='bounded', options={'xatol':xtol}) nexp=int(res['x']) calc['configuration']['detector']['nexp'] = nexp report = perform_calculation(calc) # this generally returns a S/N less than the required amount. # let's ensure that we get *AT LEAST* the required S/N for 2 reasons: # 1) better to err on the side of caution # 2) make code consistent with the above if-clause if report['scalar']['sn']<sn: nexp+=1 exptime = report['scalar']['total_exposure_time'] return nexp,report,exptime # Desired magnitude and S/N mag = 27. sn = 20. FILTER = 'f129' # Run minimizer function nexp, etc, exptime = compute_nexp(FILTER, sn, mag) # Print reported numbers print(f'number of exposures: {nexp}') print(f'actual S/N reached: {etc["scalar"]["sn"]:.2f}') print(f'Exposure time: {exptime:.2f}')
Warnings Issued by Running this Code
This step may generate a WARNING from synphot that the spectrum is extrapolated, which may be ignored. There may be an additional WARNING that the signal-to-noise for a single exposure is larger than what was requested, which may also be ignored.
Result from the Example
This calculation should output
47
exposures, a signal-to-noise reached of
20.06
, and an exposure time of
26147.04
seconds.
Since nexp must be an integer, the signal-to-noise returned will be at least the required value, but could be a higher value. The value of the returned signal-to-noise can be significantly higher than the requested value when the inferred nexp is small (ie. bright sources and/or very high signal-to-noise).
Example 4: Modify Spectral Energy Distribution (SED)
A scientific goal may require specifying something more complex than a flat spectral energy distribution (as assumed in other examples). In this instance, we assume that the spectral energy distribution is determined by a star selected from a grid of Phoenix models (the only supported models at this time).
Description of Code Snippet
The code will simulate a
= 25 AB magnitude source in
mag
=
FILTER
'f129'
with
=
nexp
3
(using the default MA table). A step is added, however, to modify the SED shape from the default flat spectrum; the user sets the
to
sed_type
'phoenix'
and then specifies the
as
key
'a0v'
, which is a star of type A0V (i.e., an A0 main-sequence star). A summary of these options is given in Pre-Configured Spectral Energy Distributions section of the article Overview of Pandeia.
Python Implementation
from pandeia.engine.perform_calculation import perform_calculation from pandeia.engine.calc_utils import build_default_calc # Get Default Parameters calc = build_default_calc('roman','wfi','imaging') # set the global variable for the filter name (change to any valid filter) FILTER = 'f129' # Modify defaults to simulate a 25th AB magnitude source mag = 25 calc['scene'][0]['spectrum']['normalization']['norm_flux'] = mag calc['scene'][0]['spectrum']['normalization']['norm_fluxunit'] = 'abmag' # Set number of exposures and filter nexp = 3 calc['configuration']['detector']['nexp'] = nexp calc['configuration']['instrument']['filter'] = FILTER # Modify SED shape calc['scene'][0]['spectrum']['sed']['sed_type'] = 'phoenix' calc['scene'][0]['spectrum']['sed']['key'] = 'a0v' # Run calculation and return signal-to-noise ratio report = perform_calculation(calc) SNR = report['scalar']['sn'] print(f'Estimated S/N: {SNR:.2f}')
Result from the Example
This calculation should output an estimated signal-to-noise ratio of
51.91
.
More Information and Options to Explore
Further information about the Pandeia is available on the Pandeia for JWST Documentation on JDox, including detailed breakdowns of all of the allowable keywords and pre-configured options.
For additional questions not answered in this article, please contact the Roman Help Desk at STScI.