diff --git a/.github/workflows/tox-tests.yml b/.github/workflows/tox-tests.yml index c07e0e5c8..f8415acc6 100644 --- a/.github/workflows/tox-tests.yml +++ b/.github/workflows/tox-tests.yml @@ -95,14 +95,14 @@ jobs: - name: Set up python for coverage test uses: actions/setup-python@v4 with: - python-version: 3.12 + python-version: 3.9 - name: Install base dependencies run: | python -m pip install --upgrade pip python -m pip install tox - name: Test with tox run: | - tox -e py312-cov -- --remote-data + tox -e py309-cov -- --remote-data - name: Upload coverage to codecov uses: codecov/codecov-action@v1 with: diff --git a/beast/observationmodel/tests/test_filters_and_vega_consistent.py b/beast/observationmodel/tests/test_filters_and_vega_consistent.py new file mode 100644 index 000000000..8578f383c --- /dev/null +++ b/beast/observationmodel/tests/test_filters_and_vega_consistent.py @@ -0,0 +1,33 @@ +from astropy.table import QTable + +from beast.config import __ROOT__ +from beast.tools import get_libfiles + + +def test_filters_and_vega_consistent(): + """ + Test to ensure that the filters.hd5 and vega.hd5 are consistent. + In other words, both have the same filters. + """ + + # download the BEAST library files + get_libfiles.get_libfiles(vega_filters_only=True) + + ftab = QTable.read(__ROOT__ + "filters.hd5", path="content") + vtab = QTable.read(__ROOT__ + "vega.hd5", path="sed") + + otxt = "" + for cfilt in ftab["TABLENAME"].data: + if cfilt not in vtab["FNAME"].data: + otxt = f"{otxt} {cfilt}" + assert otxt == "", "filters in filters.hd5 missing from vega.hd5:" + otxt + + otxt = "" + for cfilt in vtab["FNAME"].data: + if cfilt not in ftab["TABLENAME"].data: + otxt = f"{otxt} {cfilt}" + assert otxt == "", "filters in vega.hd5 missing from filters.hd5:" + otxt + + +if __name__ == "__main__": # pragma: no cover + test_filters_and_vega_consistent() diff --git a/beast/plotting/plot_filters.py b/beast/plotting/plot_filters.py index 06bd81bda..05aa135ab 100755 --- a/beast/plotting/plot_filters.py +++ b/beast/plotting/plot_filters.py @@ -15,12 +15,10 @@ def plot_filters( filter_names, filterLib=None, - save_name="beast_filters", - xlim=[1.4e3, 2e4], + xlim=None, ylim=[1e-4, 2], show_plot=True, ): - """Plots transmission curves in log-log space. Parameters @@ -42,7 +40,8 @@ def plot_filters( fig, ax = plt.subplots(1, 1, figsize=(10, 6)) # wavelength grid in angstroms for response functions - waves = np.logspace(3, np.log10(3e4), 501) + # cover all HST and JWST wavelengths + waves = np.logspace(np.log10(912.0), np.log10(3e5), 1001) # read in the filter response functions flist = phot.load_filters( @@ -50,24 +49,38 @@ def plot_filters( ) color_indices = np.log10(np.array(np.sort([f.norm for f in flist]))) - color_indices -= color_indices.min() - color_indices /= color_indices.max() + if len(color_indices) > 1: + color_indices -= color_indices.min() + color_indices /= color_indices.max() + else: + color_indices = [0.0] cmap = mpl.cm.plasma # ax.set_prop_cycle(color=[cmap(i) for i in color_indices]) color = iter(cmap(np.linspace(0.2, 0.8, len(filter_names)))) + dxlim = np.array([3e5, 912.0]) * 1e-4 for f in flist: + wavelength = f.wavelength * 1e-4 c = next(color) - ax.plot(f.wavelength, f.transmit, color=c, lw=2) - ax.fill_between(f.wavelength, f.transmit, alpha=0.2, color=c) + ax.plot(wavelength, f.transmit, color=c, lw=2) + ax.fill_between(wavelength, f.transmit, alpha=0.2, color=c) + yval_text = max(f.transmit * 0.1) ax.text( - np.nanmean(f.wavelength[f.transmit > 100.0 * ylim[0]]), - 1.3 * np.nanmax(f.transmit[f.transmit > ylim[0]]), + np.nanmean(wavelength[f.transmit > yval_text]), + 1.3 * np.nanmax(f.transmit[f.transmit > yval_text]), f.name.split("_")[-1], ha="center", color=c, ) + gvals = (f.transmit > ylim[0]) & (f.transmit < ylim[1]) + if min(wavelength[gvals]) < dxlim[0]: + dxlim[0] = min(wavelength[gvals]) + if max(wavelength[gvals]) > dxlim[1]: + dxlim[1] = max(wavelength[gvals]) + + if xlim is None: + xlim = dxlim ax.set_xscale("log") ax.set_yscale("log") @@ -77,7 +90,7 @@ def plot_filters( ax.set_ylabel(r"$B_i(\lambda)$") # ax.set_xticks([0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 2.0]) - ax.get_xaxis().set_major_formatter(mpl.ticker.ScalarFormatter()) + # ax.get_xaxis().set_major_formatter(mpl.ticker.ScalarFormatter()) fig.tight_layout() @@ -95,9 +108,7 @@ def plot_filters( default="filters.appendVegaFilter", help="Save figure to file", ) - args = parser.parse_args() - - filter_names = [ + def_filter_names = [ "HST_WFC3_F225W", "HST_WFC3_F275W", "HST_WFC3_F336W", @@ -107,8 +118,12 @@ def plot_filters( "HST_WFC3_F110W", "HST_WFC3_F160W", ] + parser.add_argument( + "filter_names", help="names of filters", nargs="+", default=def_filter_names + ) + args = parser.parse_args() - fig = plot_filters(filter_names, show_plot=False) + fig = plot_filters(args.filter_names, show_plot=False) if args.tex: plt.rc({"usetex": True}) diff --git a/beast/tests/test_regresscheck.py b/beast/tests/test_regresscheck.py index de7d1e478..e3d53675a 100644 --- a/beast/tests/test_regresscheck.py +++ b/beast/tests/test_regresscheck.py @@ -68,7 +68,7 @@ def setUpClass(cls): cls.dset = "metal" if cls.dset == "metal": - cls.basesubdir = "metal_small_9Nov22/" + cls.basesubdir = "metal_small/" cls.basename = f"{cls.basesubdir}beast_metal_small" cls.obsname = f"{cls.basesubdir}14675_LMC-13361nw-11112.gst_samp.fits" cls.astname = f"{cls.basesubdir}14675_LMC-13361nw-11112.gst.fake.fits" diff --git a/beast/tools/get_libfiles.py b/beast/tools/get_libfiles.py index de79a7184..a3372b615 100644 --- a/beast/tools/get_libfiles.py +++ b/beast/tools/get_libfiles.py @@ -15,12 +15,13 @@ def _download_rename(filename, url_loc, local_loc): return filename -def get_libfiles(): +def get_libfiles(vega_filters_only=False): """ Download all the library files needed by the BEAST """ for ckey, clib in libs.items(): - _download_rename(clib, libs_server, __ROOT__) + if ((not vega_filters_only) or (vega_filters_only & (ckey in ["vega", "filters"]))): + _download_rename(clib, libs_server, __ROOT__) if __name__ == "__main__": # pragma: no cover diff --git a/beast/tools/make_libfile.py b/beast/tools/make_libfile.py index 1a083e937..742369774 100644 --- a/beast/tools/make_libfile.py +++ b/beast/tools/make_libfile.py @@ -1,7 +1,11 @@ # script to generate BEAST library files +import os import numpy as np import stsynphot as stsyn +from pandeia.engine.instrument_factory import InstrumentFactory +import astropy.units as u +from astropy.table import QTable import h5py @@ -9,81 +13,46 @@ from beast.observationmodel import phot -def make_libfile(): +def make_filters_libfile(): """ Extract filters from STSYNPHOT and save to main library file. """ - # wfc3_obsmodes_uvis - wfc3_uvis = [ - "f218w", - "f225w", - "f275w", - "f336w", - "f390m", - "f390w", - "f410m", - "f438w", - "f467m", - "f475w", - "f547m", - "f555w", - "f606w", - "f621m", - "f625w", - "f689m", - "f763m", - "f775w", - "f814w", - "f845m", - ] - - wfc3_ir = [ - "f098m", - "f105w", - "f110w", - "f125w", - "f127m", - "f139m", - "f140w", - "f153m", - "f160w", - ] - - wfpc2 = [ - "f122m", - "f157w", - "f336w", - "f410m", - "f467m", - "f547m", - "f439w", - "f569w", - "f675w", - "f791w", - "f170w", - "f185w", - "f218w", - "f255w", - "f300w", - "f380w", - "f555w", - "f622w", - "f450w", - "f606w", - "f702w", - "f814w", - ] - - acs_wfc = [ - "f435w", - "f475w", - "f550m", - "f555w", - "f606w", - "f625w", - "f775w", - "f814w", - ] + + # fmt: off + wfc3_uvis = ["f218w", "f225w", "f275w", "f336w", "f390w", "f438w", + "f475w", "f555w", "f606w", "f625w", "f775w", "f814w", + "f390m", "f410m", "f467m", "f547m", "f621m", "f689m", "f763m", "f845m", + "f280n", "f343n", "f373n", "f395n", "f469n", "f487n", "f502n", "f631n", + "f645n", "f656n", "f657n", "f658n", "f665n", "f673n", "f680n", "f953n"] + + wfc3_ir = ["f105w", "f110w", "f125w", "f140w", "f160w", + "f098m", "f127m", "f139m", "f153m"] + + wfpc2 = ["f157w", "f170w", "f185w", "f218w", "f255w", + "f300w", "f336w", "f380w", "f439w", "f450w", "f555w", + "f569w", "f606w", "f622w", "f675w", "f702w", "f791w", "f814w", + "f122m", "f410m", "f467m", "f547m"] + + acs_wfc = ["f435w", "f475w", "f555w", "f606w", "f625w", "f775w", "f814w", "f850lp", + "f502n", "f550m", "f658n"] + + acs_sbc = ["f115lp", "f125lp", "f140lp", "f150lp", "f165lp", "f122m"] + + jwst_nircam_sw = ["f150w2", "f070w", "f090w", "f115w", "f150w", "f200w", + "f140m", "f162m", "f182m", "f210m", + "f164n", "f187n", "f212n"] + + jwst_nircam_lw = ["f332w2", "f277w", "f356w", "f444w", + "f250m", "f300m", "f335m", "f360m", "f410m", "f430m", "f460m", "f480m", + "f323n", "f405n", "f466n", "f470n"] + + jwst_niriss = ["f090w", "f115w", "f150w", "f200w", "f277w", "f356w", "f444w", + "f140m", "f158m", "f380m", "f430m", "f480m"] + + jwst_miri = ["f560w", "f770w", "f1000w", "f1130w", "f1280w", "f1500w", "f1800w", "f2100w", "f2550w", + "f1065c", "f1140c", "f1550c", "f2300c"] + # fmt: on + # galex galex = ["fuv", "nuv"] @@ -228,7 +197,7 @@ def make_libfile(): pwaves.append(newfilt.lpivot.value) comments.append("avg of 1, 2, 3, 4") - # Loop through ACS filters + # Loop through ACS WFC filters for filt in acs_wfc: # define wfc1, wfc2 modes @@ -270,6 +239,43 @@ def make_libfile(): pwaves.append(newfilt.lpivot.value) comments.append("avg of wfc1 and wfc2") + # Loop through ACS SBC filters + for filt in acs_sbc: + + # define ir mode + mode = "acs, sbc, " + filt + + # pull bandpasses from stsynphot for the two uvis modes + bp = stsyn.band(mode) + + # extract the wavelength array + wave = bp.waveset + + # define the filter name + filter_name = "HST_ACS_SBC_" + filt.upper() + + # build array of wavelength and throughput + arr = np.array( + list(zip(wave.value.astype(np.float64), bp(wave).astype(np.float64))), + dtype=[("WAVELENGTH", "float64"), ("THROUGHPUT", "float64")], + ) + + # append dataset to the hdf5 filters group + f.create_dataset(filter_name, data=arr) + + # generate filter instance to compute relevant info + newfilt = phot.Filter(wave, bp(wave), name=filt.upper()) + + # populate contents lists with relevant information + tablenames.append(filter_name) + observatories.append("HST") + instruments.append("ACS") + names.append(newfilt.name) + norms.append(newfilt.norm.value) + cwaves.append(newfilt.cl.value) + pwaves.append(newfilt.lpivot.value) + comments.append("") + # Loop through GALEX filters: for filt in galex: # define ir mode @@ -306,6 +312,230 @@ def make_libfile(): pwaves.append(newfilt.lpivot.value) comments.append("") + for filt in jwst_nircam_sw: + # mock configuration + conf = { + "detector": { + "nexp": 1, + "ngroup": 10, + "nint": 1, + "readout_pattern": "deep2", + "subarray": "full", + }, + "instrument": { + "aperture": "sw", + "disperser": "null", + "filter": filt, + "instrument": "nircam", + "mode": "sw_imaging", + }, + } + + # create a configured instrument + instrument_factory = InstrumentFactory(config=conf) + + # set up your wavelengths + pwave = np.logspace(np.log10(0.5), np.log10(7.0), 501) * u.micron + + # get the throughput of the instrument over the desired wavelength range + eff = instrument_factory.get_total_eff(pwave.value) + + # get wavelengths in Angstroms + wave = pwave.to(u.AA) + + # define the filter name + filter_name = "JWST_NIRCAM_" + filt.upper() + + # build array of wavelength and throughput + arr = np.array( + list(zip(wave.value.astype(np.float64), eff.astype(np.float64))), + dtype=[("WAVELENGTH", "float64"), ("THROUGHPUT", "float64")], + ) + + # append dataset to the hdf5 filters group + f.create_dataset(filter_name, data=arr) + + # generate filter instance to compute relevant info + newfilt = phot.Filter(wave, eff, name=filt.upper()) + + # populate contents lists with relevant information + tablenames.append(filter_name) + observatories.append("JWST") + instruments.append("NIRCAM") + names.append(newfilt.name) + norms.append(newfilt.norm.value) + cwaves.append(newfilt.cl.value) + pwaves.append(newfilt.lpivot.value) + comments.append("") + + for filt in jwst_nircam_lw: + # mock configuration + conf = { + "detector": { + "nexp": 1, + "ngroup": 10, + "nint": 1, + "readout_pattern": "deep2", + "subarray": "full", + }, + "instrument": { + "aperture": "lw", + "disperser": "null", + "filter": filt, + "instrument": "nircam", + "mode": "lw_imaging", + }, + } + + # create a configured instrument + instrument_factory = InstrumentFactory(config=conf) + + # set up your wavelengths + pwave = np.logspace(np.log10(0.5), np.log10(7.0), 501) * u.micron + + # get the throughput of the instrument over the desired wavelength range + eff = instrument_factory.get_total_eff(pwave.value) + + # get wavelengths in Angstroms + wave = pwave.to(u.AA) + + # define the filter name + filter_name = "JWST_NIRCAM_" + filt.upper() + + # build array of wavelength and throughput + arr = np.array( + list(zip(wave.value.astype(np.float64), eff.astype(np.float64))), + dtype=[("WAVELENGTH", "float64"), ("THROUGHPUT", "float64")], + ) + + # append dataset to the hdf5 filters group + f.create_dataset(filter_name, data=arr) + + # generate filter instance to compute relevant info + newfilt = phot.Filter(wave, eff, name=filt.upper()) + + # populate contents lists with relevant information + tablenames.append(filter_name) + observatories.append("JWST") + instruments.append("NIRCAM") + names.append(newfilt.name) + norms.append(newfilt.norm.value) + cwaves.append(newfilt.cl.value) + pwaves.append(newfilt.lpivot.value) + comments.append("") + + for filt in jwst_niriss: + # mock configuration + conf = { + "detector": { + "nexp": 1, + "ngroup": 10, + "nint": 1, + "readout_pattern": "nis", + "subarray": "full", + }, + "instrument": { + "aperture": "imager", + "disperser": "null", + "filter": filt, + "instrument": "niriss", + "mode": "imaging", + }, + } + + # create a configured instrument + instrument_factory = InstrumentFactory(config=conf) + + # set up your wavelengths + pwave = np.logspace(np.log10(0.5), np.log10(7.0), 501) * u.micron + + # get the throughput of the instrument over the desired wavelength range + eff = instrument_factory.get_total_eff(pwave.value) + + # get wavelengths in Angstroms + wave = pwave.to(u.AA) + + # define the filter name + filter_name = "JWST_NIRISS_" + filt.upper() + + # build array of wavelength and throughput + arr = np.array( + list(zip(wave.value.astype(np.float64), eff.astype(np.float64))), + dtype=[("WAVELENGTH", "float64"), ("THROUGHPUT", "float64")], + ) + + # append dataset to the hdf5 filters group + f.create_dataset(filter_name, data=arr) + + # generate filter instance to compute relevant info + newfilt = phot.Filter(wave, eff, name=filt.upper()) + + # populate contents lists with relevant information + tablenames.append(filter_name) + observatories.append("JWST") + instruments.append("NIRISS") + names.append(newfilt.name) + norms.append(newfilt.norm.value) + cwaves.append(newfilt.cl.value) + pwaves.append(newfilt.lpivot.value) + comments.append("") + + for filt in jwst_miri: + # mock configuration + conf = { + "detector": { + "nexp": 1, + "ngroup": 10, + "nint": 1, + "readout_pattern": "fastr1", + "subarray": "full", + }, + "dynamic_scene": True, + "instrument": { + "aperture": "imager", + "filter": filt, + "instrument": "miri", + "mode": "imaging", + }, + } + + # create a configured instrument + instrument_factory = InstrumentFactory(config=conf) + + # set up your wavelengths + pwave = np.logspace(np.log10(3.0), np.log10(40.0), 501) * u.micron + + # get the throughput of the instrument over the desired wavelength range + eff = instrument_factory.get_total_eff(pwave.value) + + # get wavelengths in Angstroms + wave = pwave.to(u.AA) + + # define the filter name + filter_name = "JWST_MIRI_" + filt.upper() + + # build array of wavelength and throughput + arr = np.array( + list(zip(wave.value.astype(np.float64), eff.astype(np.float64))), + dtype=[("WAVELENGTH", "float64"), ("THROUGHPUT", "float64")], + ) + + # append dataset to the hdf5 filters group + f.create_dataset(filter_name, data=arr) + + # generate filter instance to compute relevant info + newfilt = phot.Filter(wave, eff, name=filt.upper()) + + # populate contents lists with relevant information + tablenames.append(filter_name) + observatories.append("JWST") + instruments.append("MIRI") + names.append(newfilt.name) + norms.append(newfilt.norm.value) + cwaves.append(newfilt.cl.value) + pwaves.append(newfilt.lpivot.value) + comments.append("") + # smash the contents arrays together contents = np.array( list( @@ -339,5 +569,66 @@ def make_libfile(): hf.close() +def make_vega_libfile(): + + # Read an updated filters.hd5 lib + __default_filtlist__ = __ROOT__ + "/filters.hd5" + filtlist = QTable.read(__default_filtlist__, path="content") + filters = [cfilt.decode("UTF-8") for cfilt in filtlist["TABLENAME"].data] + + # filenames for vega info + __default_vega__ = __ROOT__ + "/vega.hd5" + __default_vega_old__ = __ROOT__ + "/vega_old.hd5" + + # rename the current file so we can write a new version + os.rename(__default_vega__, __default_vega_old__) + + # Get a spectrum from the need-to-be updated vega lib + vega_old = QTable.read(__default_vega_old__, path="spectrum") + vl = vega_old["WAVELENGTH"].data + vf = vega_old["FLUX"].data + + # Write out an updated vega.hd5 file + vega = h5py.File(__default_vega__, "w") + + vega.create_dataset("spectrum", data=vega_old) + flist = phot.load_filters( + filters, interp=True, lamb=vl, filterLib=__default_filtlist__ + ) + + fname = [] + cwave = [] + lum = [] + mag = [] + + for cfilt in flist: + fname.append(cfilt.name) + cwave.append(cfilt.cl) + flux = cfilt.getFlux(vl, vf) + lum.append(flux) + mag.append(-2.5 * np.log10(flux)) + + contents = np.array( + list( + zip( + fname, + cwave, + lum, + mag, + ) + ), + dtype=[ + ("FNAME", "S30"), + ("CWAVE", " - Command to create it: .. code-block:: console diff --git a/docs/beast_filters.rst b/docs/beast_filters.rst new file mode 100644 index 000000000..e9364b1f1 --- /dev/null +++ b/docs/beast_filters.rst @@ -0,0 +1,261 @@ +####### +Filters +####### + +Filters included in the BEAST + +Hubble +====== + +WFC3 +---- + +Imaging, UVIS, Wide + +.. plot:: + + from beast.plotting.plot_filters import plot_filters + + # required to get the filters library needed for building on RTD + from beast.tools import get_libfiles + get_libfiles.get_libfiles(vega_filters_only=True) + + wfc3_uvis = ["f218w","f225w", "f275w", "f336w", "f390w", "f438w", + "f475w", "f555w", "f606w", "f625w", "f775w", "f814w"] + filters = [f"HST_WFC3_{cfilt.upper()}" for cfilt in wfc3_uvis] + plot_filters(filters) + +Imaging, UVIS, Medium + +.. plot:: + + from beast.plotting.plot_filters import plot_filters + + wfc3_uvis = ["f390m", "f410m", "f467m", "f547m", "f621m", "f689m", "f763m", "f845m"] + filters = [f"HST_WFC3_{cfilt.upper()}" for cfilt in wfc3_uvis] + plot_filters(filters) + +Imaging, UVIS, Narrow, Blue + +.. plot:: + + from beast.plotting.plot_filters import plot_filters + + wfc3_uvis = ["f280n", "f343n", "f373n", "f395n", "f469n", "f487n", "f502n", "f631n"] + filters = [f"HST_WFC3_{cfilt.upper()}" for cfilt in wfc3_uvis] + plot_filters(filters) + +Imaging, UVIS, Narrow, Red +(Note: F656N not included, error when plotting) + +.. plot:: + + from beast.plotting.plot_filters import plot_filters + + wfc3_uvis = ["f645n", "f657n", "f658n", "f665n", "f673n", "f680n", "f953n"] + filters = [f"HST_WFC3_{cfilt.upper()}" for cfilt in wfc3_uvis] + plot_filters(filters) + +Imaging, IR, wide + +.. plot:: + + from beast.plotting.plot_filters import plot_filters + + wfc3_ir = ["f105w", "f110w", "f125w", "f140w", "f160w"] + filters = [f"HST_WFC3_{cfilt.upper()}" for cfilt in wfc3_ir] + plot_filters(filters) + +Imaging, IR, medium + +.. plot:: + + from beast.plotting.plot_filters import plot_filters + + wfc3_ir = ["f098m", "f127m", "f139m", "f153m"] + filters = [f"HST_WFC3_{cfilt.upper()}" for cfilt in wfc3_ir] + plot_filters(filters) + +ACS +--- + +Imaging, WFC, wide + +.. plot:: + + from beast.plotting.plot_filters import plot_filters + + acs_wfc = ["f435w", "f475w", "f555w", "f606w", "f625w", "f775w", "f814w"] + filters = [f"HST_ACS_WFC_{cfilt.upper()}" for cfilt in acs_wfc] + plot_filters(filters) + + +Imaging, WFC, extrawide, medium and narrow + +.. plot:: + + from beast.plotting.plot_filters import plot_filters + + acs_wfc = ["f850lp", "f502n", "f550m", "f658n"] + filters = [f"HST_ACS_WFC_{cfilt.upper()}" for cfilt in acs_wfc] + plot_filters(filters) + +Imaging, SBC + +.. plot:: + + from beast.plotting.plot_filters import plot_filters + + acs_sbc = ["f115lp", "f125lp", "f140lp", "f150lp", "f165lp", "f122m"] + filters = [f"HST_ACS_SBC_{cfilt.upper()}" for cfilt in acs_sbc] + plot_filters(filters) + +WFPC2 +----- + +Imaging, UV, Wide + +.. plot:: + + from beast.plotting.plot_filters import plot_filters + + wfpc2 = ["f157w", "f170w", "f185w", "f218w", "f255w", "f300w"] + filters = [f"HST_WFPC2_{cfilt.upper()}" for cfilt in wfpc2] + plot_filters(filters) + +Imaging, Optical, Blue + +.. plot:: + + from beast.plotting.plot_filters import plot_filters + + wfpc2 = ["f336w", "f380w", "f439w", "f450w", "f555w", "f569w"] + filters = [f"HST_WFPC2_{cfilt.upper()}" for cfilt in wfpc2] + plot_filters(filters) + +Imaging, Optical, Red + +.. plot:: + + from beast.plotting.plot_filters import plot_filters + + wfpc2 = ["f606w", "f622w", "f675w", "f702w", "f791w", "f814w"] + filters = [f"HST_WFPC2_{cfilt.upper()}" for cfilt in wfpc2] + plot_filters(filters) + +Imaging, Medium + +.. plot:: + + from beast.plotting.plot_filters import plot_filters + + wfpc2 = ["f122m", "f410m", "f467m", "f547m"] + filters = [f"HST_WFPC2_{cfilt.upper()}" for cfilt in wfpc2] + plot_filters(filters) + +Webb +==== + +NIRCam +------ + +Imaging, Very Wide Bands + +.. plot:: + + from beast.plotting.plot_filters import plot_filters + + jwst_nircam = ["f150w2", "f332w2"] + filters = [f"JWST_NIRCAM_{cfilt.upper()}" for cfilt in jwst_nircam] + plot_filters(filters) + +Imaging, Wide Bands + +.. plot:: + + from beast.plotting.plot_filters import plot_filters + + jwst_nircam = ["f070w", "f090w", "f115w", "f150w", "f200w", + "f277w", "f356w", "f444w"] + filters = [f"JWST_NIRCAM_{cfilt.upper()}" for cfilt in jwst_nircam] + plot_filters(filters) + +Imaging, Medium Bands + +.. plot:: + + from beast.plotting.plot_filters import plot_filters + + jwst_nircam = ["f140m", "f162m", "f182m", "f210m", + "f250m", "f300m", "f335m", "f360m", "f410m", "f430m", "f460m", "f480m"] + filters = [f"JWST_NIRCAM_{cfilt.upper()}" for cfilt in jwst_nircam] + plot_filters(filters) + +Imaging, Narrow Bands + +.. plot:: + + from beast.plotting.plot_filters import plot_filters + + jwst_nircam = ["f164n", "f187n", "f212n", + "f323n", "f405n", "f466n", "f470n"] + filters = [f"JWST_NIRCAM_{cfilt.upper()}" for cfilt in jwst_nircam] + plot_filters(filters) + +NIRISS +------ + +Imaging, Wide Bands + +.. plot:: + + from beast.plotting.plot_filters import plot_filters + + jwst_niriss = ["f090w", "f115w", "f150w", "f200w", "f277w", "f356w", "f444w"] + filters = [f"JWST_NIRISS_{cfilt.upper()}" for cfilt in jwst_niriss] + plot_filters(filters) + +Imaging, Medium Bands + +.. plot:: + + from beast.plotting.plot_filters import plot_filters + + jwst_niriss = ["f140m", "f158m", "f380m", "f430m", "f480m"] + filters = [f"JWST_NIRISS_{cfilt.upper()}" for cfilt in jwst_niriss] + plot_filters(filters) + +MIRI +---- + +Imaging + +.. plot:: + + from beast.plotting.plot_filters import plot_filters + + jwst_miri = ["f560w", "f770w", "f1000w", "f1130w", "f1280w", "f1500w", "f1800w", "f2100w", "f2550w"] + filters = [f"JWST_MIRI_{cfilt.upper()}" for cfilt in jwst_miri] + plot_filters(filters) + +Coronagraphy + +.. plot:: + + from beast.plotting.plot_filters import plot_filters + + jwst_miri = ["f1065c", "f1140c", "f1550c", "f2300c"] + filters = [f"JWST_MIRI_{cfilt.upper()}" for cfilt in jwst_miri] + plot_filters(filters) + +GALEX +===== + +Imaging + +.. plot:: + + from beast.plotting.plot_filters import plot_filters + + plot_filters(["GALEX_FUV", "GALEX_NUV"]) + diff --git a/docs/beast_setup.rst b/docs/beast_setup.rst index d6b4c1f2e..6f43d4293 100644 --- a/docs/beast_setup.rst +++ b/docs/beast_setup.rst @@ -137,7 +137,8 @@ BEAST Filters ============= The filters are defined in ``beast/libs/filters.hd5``. The file -has been updated in March, 2022 using stsynphot to have correct, +has been updated in Feb 2024 using stsynphot (HST/GALEX) and +pandeia (JWST) to have correct, total throughput for HST filters and to remove unused filters. The file contains two groups: @@ -154,128 +155,5 @@ The filters currently included in the BEAST filter library are as follows. Please do not forget updating ``beast/libs/vega.hd5`` as well when making any updates in ``beast/libs/filters.hd5``. Vega fluxes and magnitudes in -udpated filters need to be correspondingly recomputed and saved in vega.hd5. - -+--------------------------+ -| HST_WFC3_F218W | -+--------------------------+ -| HST_WFC3_F225W | -+--------------------------+ -| HST_WFC3_F275W | -+--------------------------+ -| HST_WFC3_F336W | -+--------------------------+ -| HST_WFC3_F390M | -+--------------------------+ -| HST_WFC3_F390W | -+--------------------------+ -| HST_WFC3_F410M | -+--------------------------+ -| HST_WFC3_F438W | -+--------------------------+ -| HST_WFC3_F467M | -+--------------------------+ -| HST_WFC3_F475W | -+--------------------------+ -| HST_WFC3_F547M | -+--------------------------+ -| HST_WFC3_F555W | -+--------------------------+ -| HST_WFC3_F606W | -+--------------------------+ -| HST_WFC3_F621M | -+--------------------------+ -| HST_WFC3_F625W | -+--------------------------+ -| HST_WFC3_F689M | -+--------------------------+ -| HST_WFC3_F763M | -+--------------------------+ -| HST_WFC3_F775W | -+--------------------------+ -| HST_WFC3_F814W | -+--------------------------+ -| HST_WFC3_F845M | -+--------------------------+ -| HST_WFC3_F098M | -+--------------------------+ -| HST_WFC3_F105W | -+--------------------------+ -| HST_WFC3_F110W | -+--------------------------+ -| HST_WFC3_F125W | -+--------------------------+ -| HST_WFC3_F127M | -+--------------------------+ -| HST_WFC3_F139M | -+--------------------------+ -| HST_WFC3_F140W | -+--------------------------+ -| HST_WFC3_F153M | -+--------------------------+ -| HST_WFC3_F160W | -+--------------------------+ -| HST_WFPC2_F122M | -+--------------------------+ -| HST_WFPC2_F157W | -+--------------------------+ -| HST_WFPC2_F336W | -+--------------------------+ -| HST_WFPC2_F410M | -+--------------------------+ -| HST_WFPC2_F467M | -+--------------------------+ -| HST_WFPC2_F547M | -+--------------------------+ -| HST_WFPC2_F439W | -+--------------------------+ -| HST_WFPC2_F569W | -+--------------------------+ -| HST_WFPC2_F675W | -+--------------------------+ -| HST_WFPC2_F791W | -+--------------------------+ -| HST_WFPC2_F170W | -+--------------------------+ -| HST_WFPC2_F185W | -+--------------------------+ -| HST_WFPC2_F218W | -+--------------------------+ -| HST_WFPC2_F255W | -+--------------------------+ -| HST_WFPC2_F300W | -+--------------------------+ -| HST_WFPC2_F380W | -+--------------------------+ -| HST_WFPC2_F555W | -+--------------------------+ -| HST_WFPC2_F622W | -+--------------------------+ -| HST_WFPC2_F450W | -+--------------------------+ -| HST_WFPC2_F606W | -+--------------------------+ -| HST_WFPC2_F702W | -+--------------------------+ -| HST_WFPC2_F814W | -+--------------------------+ -| HST_ACS_WFC_F435W | -+--------------------------+ -| HST_ACS_WFC_F475W | -+--------------------------+ -| HST_ACS_WFC_F550M | -+--------------------------+ -| HST_ACS_WFC_F555W | -+--------------------------+ -| HST_ACS_WFC_F606W | -+--------------------------+ -| HST_ACS_WFC_F625W | -+--------------------------+ -| HST_ACS_WFC_F775W | -+--------------------------+ -| HST_ACS_WFC_F814W | -+--------------------------+ -| GALEX_FUV | -+--------------------------+ -| GALEX_NUV | -+--------------------------+ +updated filters need to be correspondingly recomputed and saved in vega.hd5. +See :doc:`beast_filters` for the full current set of included filters. diff --git a/docs/index.rst b/docs/index.rst index 920022309..57fd9a863 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -30,6 +30,7 @@ Basics: :maxdepth: 1 Run setup + Filters supported Photometry files Output files diff --git a/setup.cfg b/setup.cfg index ca16800c7..e42fca74a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -30,6 +30,7 @@ install_requires = graphviz asdf stsynphot + pandeia.engine [options.entry_points] console_scripts = diff --git a/tox.ini b/tox.ini index 9511c33c9..de198742a 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - py{310,311,312}-test{,-alldeps}{,-cov} + py{309,310,311,312}-test{,-alldeps}{,-cov} build_docs linkcheck codestyle