Synthetic photometry (pwkit.synphot)

Synthetic photometry and database of instrumental bandpasses.

The basic structure is that we have a registry of bandpass info. You can use it to create Bandpass objects that can perform various calculations, especially the computation of synthetic photometry given a spectral model. Some key attributes of each bandpass are pre-computed so that certain operations can be done without needing to load the actual bandpass profile (though so far none of these profiles are very large at all).

The bandpass definitions built into this module are:

  • 2MASS (JHK)

  • Bessell (UBVRI)

  • GALEX (NUV, FUV)

  • LMIRCam on LBT

  • MEarth

  • Mauna Kea Observatory (MKO) (JHKLM)

  • SDSS (u’ g’ r’ i’ z’)

  • Swift (UVW1)

  • WISE (1234)

Classes:

AlreadyDefinedError(fmt, *args)

Raised when re-registering bandpass info.

Bandpass()

Computations regarding a particular filter bandpass.

NotDefinedError(fmt, *args)

Raised when needed bandpass info is unavailable.

Registry()

A registry of known bandpass properties.

Functions:

get_std_registry()

Get a Registry object pre-filled with information for standard telescopes.

Various internal utilities may be useful for reference but are not documented here.

Variables:

builtin_registrars

Hashtable of functions to register the builtin telescopes.

Example

from pwkit import synphot as ps, cgs as pc, msmt as pm
reg = ps.get_std_registry()
print(reg.telescopes()) # list known telescopes
print(reg.bands('2MASS')) # list known 2MASS bands
bp = reg.get('2MASS', 'Ks')
mag = 12.83
mjy = pm.repval(bp.mag_to_fnu(mag) * pc.jypercgs * 1e3)
print('%.2f mag is %.2f mjy in 2MASS/Ks' % (mag, mjy))

Conventions

It is very important to maintain consistent conventions throughout.

Wavelengths are measured in angstroms. Flux densities are either per-wavelength (f_λ, “flam”) or per-frequency (f_ν, “fnu”). These are measured in units of erg/s/cm²/Å and erg/s/cm²/Hz, respectively. Janskys can be converted to f_ν by multiplying by cgs.cgsperjy. f_ν’s and f_λ’s can be interconverted for a given filter if you know its “pivot wavelength”. Some of the routines below show how to calculate this and do the conversion. “AB magnitudes” can be directly converted to Janskys and, thus, f_ν’s.

Filter bandpasses can be expressed in two conventions: either “equal-energy” (EE) or “quantum-efficiency” (QE). The former gives the response per unit energy across the band, while the latter gives the response per photon. The EE convention can be integrated directly against a model spectrum, so we store all bandpasses internally in this convention. CCDs are photon-counting devices and so their response curves are generally expressed in the QE convention. Interconversion is easy: EE = QE * λ.

We don’t expect any particular normalization of bandpass response curves.

The “width” of a bandpass is not a well-defined quantity, but is often needed for display purposes or approximate calculations. We use the locations of the half-maximum points (in the EE convention) to define the band edges.

This module requires Scipy and Pandas. It doesn’t reeeeallllly need Pandas but it’s convenient.

References

Casagrande & VandenBerg (2014; arxiv:1407.6095) has a lot of good stuff; see also references therein.

References for specific bandpasses are given in their implementation docstrings.

The Registry class

pwkit.synphot.get_std_registry()[source]

Get a Registry object pre-filled with information for standard telescopes.

class pwkit.synphot.Registry[source]

A registry of known bandpass properties.

Instances of Registry have the following methods:

bands(telescope)

Return a list of bands associated with the specified telescope.

get(telescope, band)

Get a Bandpass object for a known telescope and filter.

register_bpass(telescope, klass)

Register a Bandpass class.

register_halfmaxes(telescope, band, lower, upper)

Register precomputed half-max points.

register_pivot_wavelength(telescope, band, wlen)

Register precomputed pivot wavelengths.

telescopes()

Return a list of telescopes known to this registry.

Registry.bands(telescope)[source]

Return a list of bands associated with the specified telescope.

Registry.get(telescope, band)[source]

Get a Bandpass object for a known telescope and filter.

Registry.register_bpass(telescope, klass)[source]

Register a Bandpass class.

Registry.register_halfmaxes(telescope, band, lower, upper)[source]

Register precomputed half-max points.

Registry.register_pivot_wavelength(telescope, band, wlen)[source]

Register precomputed pivot wavelengths.

Registry.telescopes()[source]

Return a list of telescopes known to this registry.

pwkit.synphot.builtin_registrars = {'2MASS': <function register_2mass>, 'Bessell': <function register_bessell>, 'GALEX': <function register_galex>, 'LBT': <function register_lbt>, 'MEarth': <function register_mearth>, 'MKO': <function register_mko>, 'SDSS': <function register_sdss>, 'Swift': <function register_swift>, 'WISE': <function register_wise>}

Hashtable of functions to register the builtin telescopes.

The Bandpass class

class pwkit.synphot.Bandpass[source]

Computations regarding a particular filter bandpass.

The underlying bandpass shape is assumed to be sampled at discrete points. It is stored in _data and loaded on-demand. The object is a Pandas DataFrame containing at least the columns wlen and resp. The former holds the wavelengths of the sample points, in Ångström and in ascending order. The latter gives the response curve in the EE convention. No particular normalization is assumed. Other columns may be present but are not used generically.

Instances of Bandpass have the following attributes:

band

The name of this bandpass' associated band.

native_flux_kind

Which kind of flux this bandpass is calibrated to: 'flam', 'fnu', or 'none'.

registry

This object's parent Registry instance.

telescope

The name of this bandpass' associated telescope.

And the following methods:

calc_halfmax_points()

Calculate the wavelengths of the filter half-maximum values.

calc_pivot_wavelength()

Compute and return the bandpass' pivot wavelength.

halfmax_points()

Get the bandpass' half-maximum wavelengths.

jy_to_flam(jy)

Convert a f_ν flux density measured in Janskys to a f_λ flux density.

mag_to_flam(mag)

Convert a magnitude in this band to a f_λ flux density.

mag_to_fnu(mag)

Convert a magnitude in this band to a f_ν flux density.

pivot_wavelength()

Get the bandpass' pivot wavelength.

synphot(wlen, flam)

wlen and flam give a tabulated model spectrum in wavelength and f_λ units.

blackbody(T)

Calculate the contribution of a blackbody through this filter.

Detailed descriptions of attributes

Bandpass.band = None

The name of this bandpass’ associated band.

Bandpass.native_flux_kind = 'none'

Which kind of flux this bandpass is calibrated to: ‘flam’, ‘fnu’, or ‘none’.

Bandpass.registry = None

This object’s parent Registry instance.

Bandpass.telescope = None

The name of this bandpass’ associated telescope.

Detailed descriptions of methods

Bandpass.calc_halfmax_points()[source]

Calculate the wavelengths of the filter half-maximum values.

Bandpass.calc_pivot_wavelength()[source]

Compute and return the bandpass’ pivot wavelength.

This value is computed directly from the bandpass data, not looked up in the Registry. Most of the values in the Registry were in fact derived from this function originally.

Bandpass.halfmax_points()[source]

Get the bandpass’ half-maximum wavelengths. These can be used to compute a representative bandwidth, or for display purposes.

Unlike calc_halfmax_points(), this function will use a cached value if available.

Bandpass.jy_to_flam(jy)[source]

Convert a f_ν flux density measured in Janskys to a f_λ flux density.

This conversion is bandpass-dependent because it depends on the pivot wavelength of the bandpass used to measure the flux density.

Bandpass.mag_to_flam(mag)[source]

Convert a magnitude in this band to a f_λ flux density.

It is assumed that the magnitude has been computed in the appropriate photometric system. The definition of “appropriate” will vary from case to case.

Bandpass.mag_to_fnu(mag)[source]

Convert a magnitude in this band to a f_ν flux density.

It is assumed that the magnitude has been computed in the appropriate photometric system. The definition of “appropriate” will vary from case to case.

Bandpass.pivot_wavelength()[source]

Get the bandpass’ pivot wavelength.

Unlike calc_pivot_wavelength(), this function will use a cached value if available.

Bandpass.synphot(wlen, flam)[source]

wlen and flam give a tabulated model spectrum in wavelength and f_λ units. We interpolate linearly over both the model and the bandpass since they’re both discretely sampled.

Note that quadratic interpolation is both much slower and can blow up fatally in some cases. The latter issue might have to do with really large X values that aren’t zero-centered, maybe?

I used to use the quadrature integrator, but Romberg doesn’t issue complaints the way quadrature did. I should probably acquire some idea about what’s going on under the hood.

Bandpass.blackbody(T)[source]

Calculate the contribution of a blackbody through this filter. T is the blackbody temperature in Kelvin. Returns a band-averaged spectrum in f_λ units.

We use the composite Simpson’s rule to integrate over the points at which the filter response is sampled. Note that this is a different technique than used by synphot, and so may give slightly different answers than that function.

Simple, careful conversions

fnu_cgs_to_flam_ang(fnu_cgs, pivot_angstrom)

erg/s/cm²/Hz → erg/s/cm²/Å

flam_ang_to_fnu_cgs(flam_ang, pivot_angstrom)

erg/s/cm²/Å → erg/s/cm²/Hz

abmag_to_fnu_cgs(abmag)

Convert an AB magnitude to f_ν in erg/s/cm²/Hz.

abmag_to_flam_ang(abmag, pivot_angstrom)

Convert an AB magnitude to f_λ in erg/s/cm²/Å.

ghz_to_ang(ghz)

Convert a photon frequency in GHz to its wavelength in Ångström.

flat_ee_bandpass_pivot_wavelength(wavelen1, ...)

Compute the pivot wavelength of a bandpass that's flat in equal-energy terms.

pivot_wavelength_ee(bpass)

Compute pivot wavelength assuming equal-energy convention.

pivot_wavelength_qe(bpass)

Compute pivot wavelength assuming quantum-efficiency convention.

pwkit.synphot.fnu_cgs_to_flam_ang(fnu_cgs, pivot_angstrom)[source]

erg/s/cm²/Hz → erg/s/cm²/Å

pwkit.synphot.flam_ang_to_fnu_cgs(flam_ang, pivot_angstrom)[source]

erg/s/cm²/Å → erg/s/cm²/Hz

pwkit.synphot.abmag_to_fnu_cgs(abmag)[source]

Convert an AB magnitude to f_ν in erg/s/cm²/Hz.

pwkit.synphot.abmag_to_flam_ang(abmag, pivot_angstrom)[source]

Convert an AB magnitude to f_λ in erg/s/cm²/Å. AB magnitudes are f_ν quantities, so a pivot wavelength is needed.

pwkit.synphot.ghz_to_ang(ghz)[source]

Convert a photon frequency in GHz to its wavelength in Ångström.

pwkit.synphot.flat_ee_bandpass_pivot_wavelength(wavelen1, wavelen2)[source]

Compute the pivot wavelength of a bandpass that’s flat in equal-energy terms. It turns out to be their harmonic mean.

pwkit.synphot.pivot_wavelength_ee(bpass)[source]

Compute pivot wavelength assuming equal-energy convention.

bpass should have two properties, resp and wlen. The units of wlen can be anything, and resp need not be normalized in any particular way.

pwkit.synphot.pivot_wavelength_qe(bpass)[source]

Compute pivot wavelength assuming quantum-efficiency convention. Note that this is NOT what we generally use in this module.

bpass should have two properties, resp and wlen. The units of wlen can be anything, and resp need not be normalized in any particular way.

Exceptions

AlreadyDefinedError(fmt, *args)

Raised when re-registering bandpass info.

NotDefinedError(fmt, *args)

Raised when needed bandpass info is unavailable.

class pwkit.synphot.AlreadyDefinedError(fmt, *args)[source]

Raised when re-registering bandpass info.

class pwkit.synphot.NotDefinedError(fmt, *args)[source]

Raised when needed bandpass info is unavailable.