Skip to content
2 changes: 1 addition & 1 deletion galsim/roman/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
# Maxinum allowed angle from the telecope solar panels to the sun in degrees.
max_sun_angle = 36.

from .roman_bandpass import getBandpasses
from .roman_bandpass import getBandpass, getBandpasses
from .roman_backgrounds import getSkyLevel
from .roman_psfs import getPSF
from .roman_wcs import getWCS, findSCA, allowedPos, bestPA, convertCenter
Expand Down
52 changes: 45 additions & 7 deletions galsim/roman/roman_bandpass.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@
import os

from .. import meta_data
from ..errors import galsim_warn
from ..errors import GalSimValueError, galsim_warn
from .. import Bandpass, LookupTable

def getBandpasses(AB_zeropoint=True, default_thin_trunc=True, include_all_bands=False, **kwargs):
def getBandpasses(AB_zeropoint=True, default_thin_trunc=True, include_all_bands=False, bandnames=None,
**kwargs):
"""Utility to get a dictionary containing the Roman ST bandpasses used for imaging.

This routine reads in a file containing a list of wavelengths and throughput for all Roman
Expand Down Expand Up @@ -96,6 +97,9 @@ def getBandpasses(AB_zeropoint=True, default_thin_trunc=True, include_all_bands=
There is currently no estimate for the thermal background for these
bands and they are set to zero arbitrarily.
[default: False]
bandnames: Iterable of bandpass names to get. If None, it gets all the imaging
bands if ``include_all_bands`` is False, or all bands if
``include_all_bands`` is True.
**kwargs: Other kwargs are passed to either `Bandpass.thin` or
`Bandpass.truncate` as appropriate.

Expand All @@ -109,11 +113,19 @@ def getBandpasses(AB_zeropoint=True, default_thin_trunc=True, include_all_bands=
data = np.genfromtxt(datafile, names=True)
wave = 1000.*data['Wave']

if bandnames is None:
bandnames = data.dtype.names[1:]
elif (invalid_bandnames := set(bandnames).difference(data.dtype.names[1:])):
raise GalSimValueError("Invalid Roman bandpasses requested;",
value=invalid_bandnames,
allowed_values=data.dtype.names[1:],
)

# Read in and manipulate the sky background info.
sky_file = os.path.join(meta_data.share_dir, "roman", "roman_sky_backgrounds.txt")
sky_data = np.loadtxt(sky_file).transpose()
ecliptic_lat = sky_data[0, :]
ecliptic_lon = sky_data[1, :]
sky_data = np.genfromtxt(sky_file, names=True)
ecliptic_lat = sky_data['Latitude']
ecliptic_lon = sky_data['Longitude']

# Parse kwargs for truncation, thinning, etc., and check for nonsense.
truncate_kwargs = ['blue_limit', 'red_limit', 'relative_throughput']
Expand All @@ -138,7 +150,7 @@ def getBandpasses(AB_zeropoint=True, default_thin_trunc=True, include_all_bands=
# Set up a dictionary.
bandpass_dict = {}
# Loop over the bands.
for index, bp_name in enumerate(data.dtype.names[1:]):
for bp_name in bandnames:
if include_all_bands is False and bp_name in non_imaging_bands:
continue

Expand All @@ -160,10 +172,36 @@ def getBandpasses(AB_zeropoint=True, default_thin_trunc=True, include_all_bands=
# Store the sky level information as an attribute.
bp._ecliptic_lat = ecliptic_lat
bp._ecliptic_lon = ecliptic_lon
bp._sky_level = sky_data[2+index, :]
bp._sky_level = sky_data[bp_name]

# Add it to the dictionary.
bp.name = bp_name if bp_name != 'W149' else 'W146'
bandpass_dict[bp.name] = bp

return bandpass_dict

def getBandpass(bandname, AB_zeropoint=True, default_thin_trunc=True, **kwargs):
"""Utility to get a single bandpass from the Roman ST bandpasses used.

If you need to get more than one bandpass, use `getBandpasses` instead.
This function just provides a cleaner interface when only one bandpass
is needed.

See also `getBandpasses`.

Parameters:
bandname: Name of the bandpass to get.
AB_zeropoint: Should the routine set an AB zeropoint before returning the bandpass?
If False, then it is up to the user to set a zero point. [default:
True]
default_thin_trunc: Use the default thinning and truncation options? Users who wish to
use no thinning and truncation of bandpasses, or who want control over
the level of thinning and truncation, should have this be False.
[default: True]
**kwargs: Other kwargs are passed to either `Bandpass.thin` or
`Bandpass.truncate` as appropriate.

@returns A Bandpass object for the specified band.
"""
return getBandpasses(AB_zeropoint=AB_zeropoint, default_thin_trunc=default_thin_trunc,
include_all_bands=True, bandnames=[bandname], **kwargs)[bandname]
6 changes: 3 additions & 3 deletions galsim/roman/roman_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from . import n_pix, exptime, dark_current, read_noise, gain
from . import stray_light_fraction, thermal_backgrounds
from .roman_psfs import getPSF
from .roman_bandpass import getBandpasses
from .roman_bandpass import getBandpass, getBandpasses
from .roman_wcs import getWCS
from .roman_backgrounds import getSkyLevel
from ..config import ParseAberrations, BandpassBuilder, GetAllParams, GetRNG
Expand Down Expand Up @@ -112,7 +112,7 @@ def buildBandpass(self, config, base, logger):
from ..deprecated import depr
depr('W149', 2.5, 'W146', 'Note: this is to match current Roman filter naming schemes')
name = 'W146'
bandpass = getBandpasses()[name]
bandpass = getBandpass(name)

return bandpass, safe

Expand Down Expand Up @@ -200,7 +200,7 @@ def setup(self, config, base, image_num, obj_num, ignore, logger):

def getBandpass(self, filter_name):
if not hasattr(self, 'all_roman_bp'):
self.all_roman_bp = getBandpasses()
self.all_roman_bp = getBandpasses(include_all_bands=True)
return self.all_roman_bp[filter_name]

def addNoise(self, image, config, base, image_num, obj_num, current_var, logger):
Expand Down
5 changes: 2 additions & 3 deletions galsim/roman/roman_psfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from . import pixel_scale, n_pix, pixel_scale_mm
from . import n_pix, n_sca, longwave_bands, shortwave_bands
from . import diameter, obscuration
from .roman_bandpass import getBandpasses
from .roman_bandpass import getBandpass

from ..utilities import LRU_Cache
from ..position import PositionD
Expand Down Expand Up @@ -335,8 +335,7 @@ def _get_single_PSF(SCA, bandpass, SCA_pos, pupil_bin,
aper=aper, gsparams=gsparams)
if n_waves is not None:
# To decide the range of wavelengths to use, check the bandpass.
bp_dict = getBandpasses()
bp = bp_dict[bandpass]
bp = getBandpass(bandpass)
PSF = PSF.interpolate(waves=np.linspace(bp.blue_limit, bp.red_limit, n_waves),
oversample_fac=1.5)
else:
Expand Down
1 change: 1 addition & 0 deletions share/roman/roman_sky_backgrounds.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Latitude Longitude R062 Z087 Y106 J129 H158 F184 W146 K213 SNPrism Grism_1stOrder Grism_0thOrder
0.0000 0.0000 -10.0000 -10.0000 -10.0000 -10.0000 -10.0000 -10.0000 -10.0000 -10.0000 -10.0000 -10.0000 -10.0000
1.3976 0.0000 -10.0000 -10.0000 -10.0000 -10.0000 -10.0000 -10.0000 -10.0000 -10.0000 -10.0000 -10.0000 -10.0000
2.7960 0.0000 -10.0000 -10.0000 -10.0000 -10.0000 -10.0000 -10.0000 -10.0000 -10.0000 -10.0000 -10.0000 -10.0000
Expand Down
37 changes: 37 additions & 0 deletions tests/test_roman.py
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,43 @@ def test_roman_nonimaging_bandpass():
assert 'Grism_1stOrder' not in bp_imaging
assert 'SNPrism' not in bp_imaging

@timer
def test_roman_bandpass_subsets():
"""Test that we can get a subset of Roman bandpasses.
"""
bandnames = ["J129", "H158"]
bp_dict = galsim.roman.getBandpasses(bandnames=bandnames)

# Check that the imaging bandpasses are a subset of the all bandpasses
for bandname in bandnames:
assert bandname in bp_dict
bp_dict.pop(bandname)

# Check that we have no bandpasses left
assert len(bp_dict) == 0

# Test that we get an error for invalid bandpasses
with assert_raises(galsim.GalSimValueError):
galsim.roman.getBandpasses(bandnames=["u", "g", "r", "i"])

@timer
def test_roman_single_bandpass():
"""Test getting a single bandpass from the Roman bandpass utility.
"""
bp = galsim.roman.getBandpass('F184')
assert bp.name == 'F184'

# Check that the default values are the same for getBandpass and getBandpasses.
bp_dict = galsim.roman.getBandpasses()
assert bp == bp_dict[bp.name]

# Explicitly check for the W-band, since that's a special case.
bp = galsim.roman.getBandpass("W146")
assert bp == bp_dict[bp.name]

# Test for a non-imaging bandpass.
bp = galsim.roman.getBandpass("SNPrism")
assert bp.name == "SNPrism"

@timer
def test_roman_detectors():
Expand Down
Loading