STPSF Tutorials

This article provides basic Jupyter notebook examples of how to use STPSF . We also provide information on additional Jupyter Notebooks and narrative documentation that further demonstrate the usage of the Roman functionality with STPSF



In addition to the examples provided below, the STPSF GitHub repository offers many tutorials, including one specific to Roman, to help users get started. The foremost example is a Jupyter Notebook with a general demonstration of how to simulate, visualize, analyze, and export a point spread function (PSF) for the Roman Wide Field Instrument (WFI). To run the tutorials on your system, please follow the installation instructions from the readthedocs documentation

The readthedocs documentation's dedicated page on the Roman Instrument Model contains several more detailed usage examples alongside narrative text explaining how all of the functionality comes together. Readers with previous experience using the JWST modes of STPSF  should note the differences highlighted for Roman simulations.

Warning

While the GitHub repository for STPSF  also offers a Jupyter Notebook that demonstrates usage of its class for the Roman Coronagraph Instrument, we warn the reader that the  STPSF Coronagraph model was developed as a prototype and has not been actively updated or developed since 2017.




Example 1: PSF with Default Parameters

import matplotlib.pyplot as plt
import stpsf

plt.rcParams['figure.figsize'] = (8, 10) # Make the default figure size larger
plt.rcParams['image.interpolation'] = 'nearest' # Don't blur/smooth image plots

wfi = stpsf.roman.WFI()

default_psf = wfi.calc_psf(display=True)

Figure of WFI F062 PSF from STPSF

STPSF for Roman: PSF with default parameters.

The simulated PSF in detector pixels can be displayed and saved using the following calls:

stpsf.display_psf(default_psf, ext='DET_SAMP')

default_psf.writeto('./test_PSF.fits', overwrite=True)

Figure of WFI PSF in Detector Pixels 

STPSF for Roman: Displaying the PSF in detector pixels.






Example 2: PSF with various specified parameters 

import matplotlib.pyplot as plt
import stpsf

plt.rcParams['figure.figsize'] = (8, 10) # Make the default figure size larger
plt.rcParams['image.interpolation'] = 'nearest' # Don't blur/smooth image plots

wfi = stpsf.roman.WFI()

wfi.filter = 'GRISM1'
wfi.detector = 'SCA14'
wfi.detector_position = (1024, 1024)

src = stpsf.specFromSpectralType('G0V', catalog='phoenix')

poly_psf = wfi.calc_psf(source=src, nlambda=10, display=True)

Figure of WFI Grism PSF from STPSF

STPSF for Roman: Specifying a few parameters.





Example 3: PSF Profile & Encircled Energy 

STPSF also includes functions for measuring encircled energy, profiles, and centroids (described in the STPSF  documentation and the POPPY documentation). Below, we measure the radial profile and encircled energy curve for the polychromatic PSF. Note that the FWHM is also computed and labeled on the radial profile plot.

import matplotlib.pyplot as plt
import stpsf
  
wfi = stpsf.roman.WFI()

wfi.filter = 'GRISM1'
wfi.detector = 'SCA14'
wfi.detector_position = (1024, 1024)

src = stpsf.specFromSpectralType('G0V', catalog='phoenix')

poly_psf = wfi.calc_psf(source=src, nlambda=10, display=False)

stpsf.display_profiles(poly_psf)

Figure of PSF Profile and Encircled Energy Plots 

STPSF for Roman: PSF Profile (top) and Encircled Energy (bottom)





Example 4: Oversampling & PSF positioning

By design, an evenly-oversampled PSF will be centered at the intersection of the four central pixels in the output images. For users interested in positioning an evenly-oversampled PSF on the central pixel instead, we provide the following example. Note that the example below is a simple workaround and will produce "OVERSAMP" and "DET_SAMP" FITS extensions in the output image that are identical, despite their names. Additional information is available in the online documentation.


from matplotlib import pyplot as plt
import stpsf

# Create a default evenly-oversampled PSF:
wfi = stpsf.roman.WFI()
wfi.filter='F062'
wfi.detector='SCA18'
wfi.detector_position=(2044, 2044)

oversample = 8
fov  = 3  #pixels in DET_SAMP extension

psf_default = wfi.calc_psf(oversample=oversample, fov_pixels=fov)


# Create an evenly-oversampled PSF centered on a pixel:
wfi.pixelscale /= oversample
over=1
fov  = 25  #pixels in all the extensions

psf_pixel_centered = wfi.calc_psf(oversample=over, fov_pixels=fov)


# Plot the results
fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(12,6))

stpsf.display_psf(psf_default, ext='OVERSAMP', vmin=1e-5, vmax=0.03, crosshairs=True, ax=ax[0], colorbar=False, title="Evenly oversampled\n\nPSF centered on intersection of pixels")

stpsf.display_psf(psf_pixel_centered, ext='OVERSAMP', vmin=1e-5, vmax=0.03, crosshairs=True, ax=ax[1], colorbar=False, title="Evenly oversampled\n\nPSF centered on pixel") 


Figure showing the effect of oversampling and positioning of the PSF on a grid of pixels

STPSF for Roman: An even oversampling leads to a PSF centered at the intersection of the four central pixels (left). The code example above shows how one may create an evenly-oversampled PSF that is centered on the central pixel instead (right).






For additional questions not answered in this article, please contact the Roman Help Desk. You may also open an issue at the GitHub repository.




Latest Update

 

WebbPSF was renamed to STPSF.
Publication

 

Initial publication of the article.