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

SNR Calculation Example
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  Output Product 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  Output Product limiting magnitude of a source with Input Parameter SN = 5  from Input Parameter NEXP = 10  Input Parameter 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 DescriptionParameter in Code ExampleValue in Code Example

signal-to-noise

the value that is useful for the science case being investigated

Input Parameter SN

5

number of exposures

the number of individual exposures of a given Multi-Accumulation sequence

Input Parameter NEXP

10

filter

the filter used in the observation 

Input Parameter FILTER

'f129'

Python Implementation 

Code to Estimate the Limiting Magnitude
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  Output Product 27.68 mag at a signal-to-noise of 5 based on the inputs from the 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 Input Parameter SN , Input Parameter MAG , and Input Parameter FILTER , which are described in the Table of Code Inputs for Determining Number of Exposures. The output will be Output Product 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 DescriptionParameter in Code ExampleValue in Code Example

signal-to-noise

the value that is useful for the science case being investigated

Input Parameter SN

20

source magnitude

the magnitude in ABMag for the source of interest

Input Parameter MAG

27

filter

the filter used in the observation 

Input Parameter 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 Output Product 47 exposures, a signal-to-noise reached of  Output Product 20.06 , and an exposure time of Output Product 26147.04 seconds. 

Since Input Parameter 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 Input Parameter 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  Input Parameter mag = 25 AB magnitude source in  Input Parameter FILTER = 'f129' with Input Parameter 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 Input Parameter sed_type to 'phoenix' and then specifies the  Input Parameter key as '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  Output Product 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.



Latest Update

 

Updated in 2023B
Publication

 

Initial publication of the article.