PhotometricFilters
This package provides access to, and operations on, photometric filter curves. Such filter curves are defined by a filter's transmission as a function of wavelength. Transmission and wavelength vectors are therefore the foundation of a filter curve, but it is also important to note whether the filter is used for photon counter or energy counter detectors, as the integrals used to calculate statistics over a filter curve are different between these two types of detectors.
Types
We use the PhotometricFilter
type to represent photometric filters in this package.
PhotometricFilters.PhotometricFilter
— TypePhotometricFilter(wave::AbstractVector, throughput::AbstractVector{T};
detector::DetectorType=Photon(), name::Union{String, Nothing}=nothing)
Struct representing a photometric filter, defined by vectors of wavelengths (wave
) and filter throughputs (throughput
). wave
can have Unitful
units attached, otherwise they are assumed to be Å. Optional keyword arguments define the detector type for which the filter is valid and a name to identify the filter.
julia> using PhotometricFilters: PhotometricFilter, Photon, wave, throughput
julia> using Unitful
julia> f = PhotometricFilter(1000:2000, vcat(fill(0.25, 250), fill(0.5, 500), fill(0.25, 251))) # Specify only wavelength and throughput
1001-element PhotometricFilter{Float64}: nothing
min. wave.: 1000 Å
max. wave.: 2000 Å
effective wave.: 1603.6927025575474 Å
mean wave.: 1499.8333333333333 Å
central wave.: 1499.5 Å
pivot wave.: 1478.1028279485677 Å
eff. width: 750.0 Å
fwhm: 501.0 Å
julia> f == PhotometricFilter(uconvert.(Unitful.nm, wave(f)), throughput(f)) # Can also specify wavelength argument with Unitful units
true
julia> f[10] # Indexing into the filter as `f[i]` returns `throughput(f)[i]`
0.25
julia> f(1001.1) # Calling `f` like a function interpolates the throughput
0.25
julia> f(100.11 * Unitful.nm) # Can also specify wavelength with units
0.25
Users can construct their own filter curvers from raw data using this type.
Accessing Filter Curves
We provide a modest collection of filter curves through a data dependency. The available filter curves are accessible via the FILTER_NAMES
module constant,
using PhotometricFilters
PhotometricFilters.FILTER_NAMES |> println
["2MASS_H", "2MASS_J", "2MASS_Ks", "CFHT_CFH12K_CFH7406", "CFHT_CFH12K_CFH7504", "CFHT_MEGAPRIME_CFH7605", "CFHT_MEGAPRIME_CFH7701", "CFHT_MEGAPRIME_CFH7803", "CFHT_MEGAPRIME_CFH9301", "CFHT_MEGAPRIME_CFH9401", "CFHT_MEGAPRIME_CFH9601", "CFHT_MEGAPRIME_CFH9701", "CFHT_MEGAPRIME_CFH9702", "CFHT_MEGAPRIME_CFH9801", "CFHT_WIRCAM_CFH8002", "CFHT_WIRCAM_CFH8101", "CFHT_WIRCAM_CFH8102", "CFHT_WIRCAM_CFH8103", "CFHT_WIRCAM_CFH8104", "CFHT_WIRCAM_CFH8201", "CFHT_WIRCAM_CFH8202", "CFHT_WIRCAM_CFH8203", "CFHT_WIRCAM_CFH8204", "CFHT_WIRCAM_CFH8301", "CFHT_WIRCAM_CFH8302", "CFHT_WIRCAM_CFH8303", "CFHT_WIRCAM_CFH8304", "CFHT_WIRCAM_CFH8305", "GALEX_FUV", "GALEX_NUV", "GROUND_BESSELL_H", "GROUND_BESSELL_J", "GROUND_BESSELL_K", "GROUND_COUSINS_I", "GROUND_COUSINS_R", "GROUND_JOHNSON_B", "GROUND_JOHNSON_U", "GROUND_JOHNSON_V", "GaiaDR2_BP", "GaiaDR2_G", "GaiaDR2_RP", "GaiaDR2_weiler_BPbright", "GaiaDR2_weiler_BPfaint", "GaiaDR2_weiler_G", "GaiaDR2_weiler_RP", "GaiaDR2v2_BP", "GaiaDR2v2_G", "GaiaDR2v2_RP", "Gaia_BP", "Gaia_G", "Gaia_MAW_BP_bright", "Gaia_MAW_BP_faint", "Gaia_MAW_G", "Gaia_MAW_RP", "Gaia_RP", "Gaia_rvs", "HERSCHEL_PACS_BLUE", "HERSCHEL_PACS_GREEN", "HERSCHEL_PACS_RED", "HERSCHEL_SPIRE_PLW", "HERSCHEL_SPIRE_PLW_EXT", "HERSCHEL_SPIRE_PMW", "HERSCHEL_SPIRE_PSW", "HERSCHEL_SPIRE_PSW_EXT", "HST_ACS_HRC_F220W", "HST_ACS_HRC_F250W", "HST_ACS_HRC_F330W", "HST_ACS_HRC_F344N", "HST_ACS_HRC_F435W", "HST_ACS_HRC_F475W", "HST_ACS_HRC_F502N", "HST_ACS_HRC_F550M", "HST_ACS_HRC_F555W", "HST_ACS_HRC_F606W", "HST_ACS_HRC_F625W", "HST_ACS_HRC_F658N", "HST_ACS_HRC_F660N", "HST_ACS_HRC_F775W", "HST_ACS_HRC_F814W", "HST_ACS_HRC_F850LP", "HST_ACS_HRC_F892N", "HST_ACS_WFC_F435W", "HST_ACS_WFC_F475W", "HST_ACS_WFC_F502N", "HST_ACS_WFC_F550M", "HST_ACS_WFC_F555W", "HST_ACS_WFC_F606W", "HST_ACS_WFC_F625W", "HST_ACS_WFC_F658N", "HST_ACS_WFC_F660N", "HST_ACS_WFC_F775W", "HST_ACS_WFC_F814W", "HST_ACS_WFC_F850LP", "HST_ACS_WFC_F892N", "HST_NIC2_F110W", "HST_NIC2_F160W", "HST_NIC2_F205W", "HST_NIC3_F108N", "HST_NIC3_F110W", "HST_NIC3_F113N", "HST_NIC3_F150W", "HST_NIC3_F160W", "HST_NIC3_F164N", "HST_NIC3_F166N", "HST_NIC3_F175W", "HST_NIC3_F187N", "HST_NIC3_F190N", "HST_NIC3_F196N", "HST_NIC3_F200N", "HST_NIC3_F205M", "HST_NIC3_F212N", "HST_NIC3_F215N", "HST_NIC3_F222M", "HST_NIC3_F240M", "HST_WFC3_F098M", "HST_WFC3_F105W", "HST_WFC3_F110W", "HST_WFC3_F125W", "HST_WFC3_F126N", "HST_WFC3_F127M", "HST_WFC3_F128N", "HST_WFC3_F130N", "HST_WFC3_F132N", "HST_WFC3_F139M", "HST_WFC3_F140W", "HST_WFC3_F153M", "HST_WFC3_F160W", "HST_WFC3_F164N", "HST_WFC3_F167N", "HST_WFC3_F200LP", "HST_WFC3_F218W", "HST_WFC3_F225W", "HST_WFC3_F275W", "HST_WFC3_F280N", "HST_WFC3_F300X", "HST_WFC3_F336W", "HST_WFC3_F343N", "HST_WFC3_F350LP", "HST_WFC3_F373N", "HST_WFC3_F390M", "HST_WFC3_F390W", "HST_WFC3_F395N", "HST_WFC3_F410M", "HST_WFC3_F438W", "HST_WFC3_F467M", "HST_WFC3_F469N", "HST_WFC3_F475W", "HST_WFC3_F475X", "HST_WFC3_F487N", "HST_WFC3_F502N", "HST_WFC3_F547M", "HST_WFC3_F555W", "HST_WFC3_F600LP", "HST_WFC3_F606W", "HST_WFC3_F621M", "HST_WFC3_F625W", "HST_WFC3_F631N", "HST_WFC3_F645N", "HST_WFC3_F656N", "HST_WFC3_F657N", "HST_WFC3_F658N", "HST_WFC3_F665N", "HST_WFC3_F673N", "HST_WFC3_F680N", "HST_WFC3_F689M", "HST_WFC3_F763M", "HST_WFC3_F775W", "HST_WFC3_F814W", "HST_WFC3_F845M", "HST_WFC3_F850LP", "HST_WFC3_F953N", "HST_WFC3_FQ232N", "HST_WFC3_FQ243N", "HST_WFC3_FQ378N", "HST_WFC3_FQ387N", "HST_WFC3_FQ422M", "HST_WFC3_FQ436N", "HST_WFC3_FQ437N", "HST_WFC3_FQ492N", "HST_WFC3_FQ508N", "HST_WFC3_FQ575N", "HST_WFC3_FQ619N", "HST_WFC3_FQ634N", "HST_WFC3_FQ672N", "HST_WFC3_FQ674N", "HST_WFC3_FQ727N", "HST_WFC3_FQ750N", "HST_WFC3_FQ889N", "HST_WFC3_FQ906N", "HST_WFC3_FQ924N", "HST_WFC3_FQ937N", "HST_WFPC2_F170W", "HST_WFPC2_F218W", "HST_WFPC2_F255W", "HST_WFPC2_F300W", "HST_WFPC2_F336W", "HST_WFPC2_F439W", "HST_WFPC2_F450W", "HST_WFPC2_F555W", "HST_WFPC2_F606W", "HST_WFPC2_F622W", "HST_WFPC2_F675W", "HST_WFPC2_F791W", "HST_WFPC2_F814W", "HST_WFPC2_F850LP", "JWST_NIRCAM_F070W", "JWST_NIRCAM_F090W", "JWST_NIRCAM_F115W", "JWST_NIRCAM_F140M", "JWST_NIRCAM_F150W", "JWST_NIRCAM_F150W2", "JWST_NIRCAM_F162M", "JWST_NIRCAM_F164N", "JWST_NIRCAM_F182M", "JWST_NIRCAM_F187N", "JWST_NIRCAM_F200W", "JWST_NIRCAM_F210M", "JWST_NIRCAM_F212N", "JWST_NIRCAM_F250M", "JWST_NIRCAM_F277W", "JWST_NIRCAM_F300M", "JWST_NIRCAM_F322W2", "JWST_NIRCAM_F323N", "JWST_NIRCAM_F335M", "JWST_NIRCAM_F356W", "JWST_NIRCAM_F360M", "JWST_NIRCAM_F405N", "JWST_NIRCAM_F410M", "JWST_NIRCAM_F430M", "JWST_NIRCAM_F444W", "JWST_NIRCAM_F460M", "JWST_NIRCAM_F466N", "JWST_NIRCAM_F470N", "JWST_NIRCAM_F480M", "KEPLER_Kp", "NGTS_I", "PS1_g", "PS1_i", "PS1_r", "PS1_w", "PS1_y", "PS1_z", "SDSS_g", "SDSS_i", "SDSS_r", "SDSS_u", "SDSS_z", "SPITZER_IRAC_36", "SPITZER_IRAC_45", "SPITZER_IRAC_58", "SPITZER_IRAC_80", "STROMGREN_b", "STROMGREN_u", "STROMGREN_v", "STROMGREN_y", "TESS", "TYCHO_B_MvB", "TYCHO_V_MvB", "WISE_RSR_W1", "WISE_RSR_W2", "WISE_RSR_W3", "WISE_RSR_W4", "ZTF_g", "ZTF_i", "ZTF_r"]
These included filter curves can be accessed like so,
using PhotometricFilters: SDSS_u, SDSS_g, SDSS_r, SDSS_i, SDSS_z, fwhm
filts = [SDSS_u(), SDSS_g(), SDSS_r(), SDSS_i(), SDSS_z()]
5-element Vector{PhotometricFilter{Float64, Vector{Float64}, PhotometricFilters.Photon, Vector{Float64}, String, Interpolations.FilledExtrapolation{Float64, 1, Interpolations.GriddedInterpolation{Float64, 1, Vector{Float64}, Interpolations.Gridded{Interpolations.Linear{Interpolations.Throw{Interpolations.OnGrid}}}, Tuple{Vector{Float64}}}, Interpolations.Gridded{Interpolations.Linear{Interpolations.Throw{Interpolations.OnGrid}}}, Float64}}}:
SDSS_u
SDSS_g
SDSS_r
SDSS_i
SDSS_z
NOTE THAT THESE INCLUDED FILTER CURVES ARE NOT GUARANTEED TO BE UP-TO-DATE. If you are using a filter/instrument that may have recently had its filter curves updated (e.g., JWST/NIRCAM), you should use our SVO query interface to make sure you get the most up-to-date filter curves. If you know the SVO-designated name of the filter you want, you can use get_filter
to retrieve its transmission data, which returns an instance of PhotometricFilter
.
PhotometricFilters.get_filter
— Functionget_filter(filtername::AbstractString, magsys::Symbol=:Vega)
Query the online SVO filter service for data on a photometric filter.
Arguments
filtername::AbstractString
: The desired filter ID, in the correct SVO specification (e.g.,"2MASS/2MASS.J"
).magsys::Symbol
: Desired magnitude system for associated metadata (e.g.,"ZeroPoint"
). Can be any of(:AB, :Vega, :ST)
. SVO uses Vega by default, so we mirror that choice here.
Returns
A length-2 tuple, with elements
- a
PhotometricFilter
containing the transmission data of the filter. - a dictionary containing additional metadata provided by SVO.
Examples
julia> using PhotometricFilters: get_filter
julia> filt = get_filter("2MASS/2MASS.J", :Vega);
julia> filt[1]
107-element PhotometricFilter{Float64}: 2MASS/2MASS.J
min. wave.: 10806.470589792389 Å
max. wave.: 14067.974683578484 Å
effective wave.: 12285.654731403807 Å
mean wave.: 12410.5170694321 Å
central wave.: 12390.584132888223 Å
pivot wave.: 12358.089456559974 Å
eff. width: 1624.3245065600008 Å
fwhm: 2149.1445403830403 Å
julia> filt[2] isa AbstractDict
true
julia> filt[2]["ZeroPoint"]
1594.0 Jy
If you'd like to perform a search on the filters available through the SVO filter service, you can use query_filters
.
PhotometricFilters.query_filters
— Functionquery_filters(; queries...)
Queries the filters available from the SVO filter service with search parameters and returns a table of the filters found.
The available search parameters can be found with PhotometricFilters.get_metadata
. The following should be available in general:
WavelengthRef
: Tuple of NumbersWavelengthMean
: Tuple of NumbersWavelengthEff
: Tuple of NumbersWavelengthMin
: Tuple of NumbersWavelengthMax
: Tuple of NumbersWidthEff
: Tuple of NumbersFWHM
: Tuple of NumbersInstrument
: StringFacility
: StringPhotSystem
: String
The returned table is a DataFrame
from the DataFrames
package with all the columns of the response VOTable.
The filter information and transmission data can be obtained by calling get_filter
with the ID obtained from the filterID
column.
Examples
julia> using DataFrames: DataFrame
julia> df = query_filters(; Facility="SLOAN", WavelengthEff=(1000, 5000));
julia> df isa DataFrame
true
julia> id = df.filterID[3]
"SLOAN/SDSS.g"
julia> get_filter(id)[1] isa PhotometricFilter
true
# Other examples for querying
query_filters(; Facility="SLOAN") # all filters from a given facility
query_filters(; Instrument="BUSCA", WavelengthEff=(1000u"angstrom", 5000u"angstrom")) # Unitful wavelengths
Supported Operations
We include functions for performing many common operations on photometric filters, summarized below.
Applying Filter Curves to Spectra
PhotometricFilters.apply
— Functionapply(f::PhotometricFilter, wave, flux)
Use linear interpolation to map the wavelengths of the photometric filter f
to the given wavelengths wave
and apply the filter throughput to the flux
. The wavelengths of the filter and wave
need to be compatible. This means if one has units, the other one needs units, too.
julia> using PhotometricFilters: SDSS_u, wave_unit, apply
julia> f = SDSS_u();
julia> λ = 3000:4000
3000:4000
julia> flux = fill(1.0, length(λ)); # If `flux` is all `1`, `apply` reduces to `f` interpolated at `λ`
julia> apply(f, λ, flux) == f(λ)
true
julia> λ_u = λ .* wave_unit # Can also put units on λ
(3000:4000) Å
julia> apply(f, λ_u, flux) == f.(λ_u)
true
PhotometricFilters.apply!
— Functionapply!(f::PhotometricFilter, wave, flux, out)
In-place version of apply
which modifies out
. It should have a compatible element type with flux
.
Statistics
PhotometricFilters.mean_wavelength
— Functionmean_wavelength(f::PhotometricFilter)
Returns the mean wavelength of the filter f
, defined as
\[\frac{\int \lambda \, T(\lambda) \, d\lambda}{\int T(\lambda) \, d\lambda}\]
PhotometricFilters.central_wavelength
— Functioncentral_wavelength(f::PhotometricFilter)
Returns the central wavelength of the filter f
, defined as the central wavelength between the two wavelengths used for the FWHM (fwhm
).
PhotometricFilters.effective_wavelength
— Functioneffective_wavelength(f::PhotometricFilter)
Returns the effective wavelength of the filter f
using the Vega spectrum as a standard. Defined as
\[\frac{\int \lambda \, T(\lambda) \text{Vg}(\lambda) \, d\lambda}{\int T(\lambda) \text{Vg}(\lambda) \, d\lambda}\]
where $T(\lambda)$ is the filter transmission at wavelength $\lambda$ and $\text{Vg}(\lambda)$ is the spectrum of Vega.
PhotometricFilters.pivot_wavelength
— Functionpivot_wavelength(f::PhotometricFilter)
Returns the pivot wavelength of the filter f
, defined for filters with Energy
detector types as
\[\sqrt{ \frac{\int T(\lambda) \, d\lambda}{\int T(\lambda) / \lambda^2 \, d\lambda} }\]
For filters with Photon
detector types, $\lambda \, T(\lambda)$ is substituted for $T(\lambda)$ in the above expression.
Internally integration is carried out using trapezoidal integration. It can be convenient to think of this as the "center of mass" of the filter.
PhotometricFilters.min_wave
— Functionmin_wave(f::PhotometricFilter; level=0.01)
Returns the shortest wavelength at which the filter transmission is equal to level * maximum(transmission)
.
PhotometricFilters.max_wave
— Functionmax_wave(f::PhotometricFilter; level=0.01)
Returns the longest wavelength at which the filter transmission is equal to level * maximum(transmission)
.
PhotometricFilters.fwhm
— Functionfwhm(f::PhotometricFilter)
Returns the difference between the furthest two wavelengths for which the filter transmission is equal to half its maximum value.
PhotometricFilters.width
— Functionwidth(f::PhotometricFilter)
Returns the effective width of the filter, defined as the horizontal size of a rectangle with height equal to the maximum transmission of the filter such that the area of the rectangle is equal to the area under the filter transmission curve. This is calculated as
\[\frac{\int T(\lambda) \, d\lambda}{\text{max}(T(\lambda))}\]
Internal Functions
PhotometricFilters.get_metadata
— Functionget_metadata()
Returns a table of the available parameters that can be used to query the SVO filter service from the FORMAT=metadata
VOTable they provide.
The table is a DataFrame
from the DataFrames
package with the following columns:
parameter
: parameter name that can be used for queries usingquery_filters
unit
:Unitful
unit of the parameterdatatype
:Type
of the parameterdescription
: description of the parametervalues
: vector of the possible values that the respective parameter can take on (e.g. for Instrument), or a vector of the minimum and maximum values that the parameter can assume (e.g. for WavelengthEff)
Example
julia> using DataFrames: DataFrame
julia> df = PhotometricFilters.get_metadata();
julia> df isa DataFrame
true
julia> facilities = df[findfirst(==("Facility"), df.parameter), :].values;
julia> facilities isa Vector{String}
true
This is not exported.
Index
PhotometricFilters.PhotometricFilter
PhotometricFilters.apply
PhotometricFilters.apply!
PhotometricFilters.central_wavelength
PhotometricFilters.effective_wavelength
PhotometricFilters.fwhm
PhotometricFilters.get_filter
PhotometricFilters.get_metadata
PhotometricFilters.max_wave
PhotometricFilters.mean_wavelength
PhotometricFilters.min_wave
PhotometricFilters.pivot_wavelength
PhotometricFilters.query_filters
PhotometricFilters.width