Contamination#
pytransit.contamination models flux contamination, also called third light or blending: light
from a star other than the transit host falling into the same photometric aperture.
Why it matters#
A transit dilutes the total flux by a fraction set by the radius ratio. If a fraction \(c\) of the light in the aperture comes from an unrelated star, the observed transit is shallower than the true one, and the radius ratio inferred from it is too small:
The two helper functions true_radius_ratio() and
apparent_radius_ratio() convert between the two.
The complication that makes this a modelling problem rather than a single correction is that contamination is wavelength-dependent. The host and the contaminant generally have different effective temperatures, so their flux ratio varies across the spectrum. A cool contaminant blended with a hot host contributes little in the blue and much in the red, making the transit look shallower in the red than in the blue – exactly the signature a real wavelength-dependent radius ratio would produce.
This is the classic false positive in multicolour transit photometry, and it is also why contamination has to be modelled jointly across passbands rather than fitted independently in each.
Passbands and instruments#
A contamination model needs to know which passbands the observations were made in.
Filter and its subclasses describe a passband’s
transmission as a function of wavelength in nanometres.
Class |
Description |
|---|---|
Unit transmission between two wavelengths, zero outside. A good approximation for many broadband filters. |
|
A measured transmission curve, interpolated with a cubic spline. |
|
Monochromatic, for narrow spectroscopic bins. |
The module ships with the SDSS g’, r’, i’, and z’ passbands as boxcar approximations, and the Kepler passband as a tabulated curve.
Instrument bundles the passbands, optionally with
detector quantum efficiency curves. The order of the filters fixes the passband order used
everywhere downstream, including the passband indices (pbids) given to a transit model.
from pytransit.contamination import Instrument, sdss_g, sdss_r, sdss_i, sdss_z
instrument = Instrument('MuSCAT2', (sdss_g, sdss_r, sdss_i, sdss_z))
instrument.pb_names
# ["g'", "r'", "i'", "z'"]
Contamination models#
Both models are parametrised the same way: by the contamination in a chosen reference passband and the effective temperatures of the host and the contaminant. Everything else follows. This is a deliberate choice – it reduces a per-passband nuisance parameter set to three physically meaningful numbers, and it enforces the physical relation between the passbands that makes contamination distinguishable from a real transmission spectrum.
BBContamination approximates both stars as black
bodies. It is fast, has no data dependencies, and is adequate when the temperatures are not too
low.
SMContamination uses real stellar spectrum models,
either the BT-Settl or the Husser et al. (2013) PHOENIX grid shipped with PyTransit (see
Stellar spectra). It is the better choice for cool stars, where the black body approximation breaks
down badly: molecular absorption removes large fractions of the flux from specific bands, and no
black body reproduces that.
from numpy import array, full
from pytransit.contamination import Instrument, SMContamination, sdss_g, sdss_r, sdss_i, sdss_z
instrument = Instrument('MuSCAT2', (sdss_g, sdss_r, sdss_i, sdss_z))
cm = SMContamination(instrument, ref_pb="i'")
# 30% contamination in i', a 5500 K host, and a 3500 K contaminant
cm.contamination(cref=0.3, teff1=5500.0, teff2=3500.0)
# array([0.0939, 0.1201, 0.3 , 0.3944])
The contamination is 30% in the reference passband by construction, only 9% in g’, and 39% in z’: the cool contaminant contributes far more red light than blue. That wavelength dependence is the signal a contamination analysis exploits.
Note
teff1 and teff2 must have the same shape. Pass both as scalars, or both as arrays of
equal length – use full(teff2.size, teff1) to scan a range of contaminant temperatures
against a fixed host.
c_as_pandas and c_as_xarray return the same numbers as labelled arrays, which is much
easier to work with when scanning temperatures.
teff2 = array([3000.0, 3500.0, 4000.0])
cm.c_as_pandas(0.3, full(teff2.size, 5500.0), teff2)
# passband g' r' i' z'
# teff
# 3000 0.0468 0.0540 0.3 0.4802
# 3500 0.0939 0.1201 0.3 0.3944
# 4000 0.1461 0.2118 0.3 0.3386
Applying contamination to a light curve#
contaminate_light_curve() blends a modelled transit
with a per-passband contamination array,
using the passband index of each exposure.
from pytransit.contamination import contaminate_light_curve
flux = tm.evaluate(k=0.1, ldc=ldc, t0=0.0, p=1.0, a=3.0, i=0.5*pi)
contaminated = contaminate_light_curve(flux, cm.contamination(0.3, 5500.0, 3500.0),
pbids=pbids_per_exposure)
Note
The pbids argument here maps each exposure to a passband, unlike the pbids given to
set_data, which maps each light curve to a passband. Use model.pbids[model.lcids] to
convert.
Planning observations#
exposure_times gives the exposure times that yield equal flux in each passband, given a
reference exposure time in the reference passband. This is useful when planning multicolour
photometry with an instrument that can set exposure times per channel.
API#
Module to model flux contamination in transit light curves.
Radius ratio conversions#
- pytransit.contamination.contamination.contaminate_light_curve(flux, contamination, pbids)[source]#
Contaminates a transit light curve.
Contaminates a transit light curve with npb passbands.
- Parameters:
flux (1d array-like) – Transit light curve with npb passbands.
contamination (1d array-like) – Array of per-passband contamination values.
pbids (1d array-like) – Passband indices that map each light curve element to a single passband.
- Returns:
Contaminated transit light curve
Passbands#
- class pytransit.contamination.filter.Filter(name)[source]#
Bases:
objectBase class for the passband transmission profiles.
A filter is a callable that maps a wavelength in nanometres to a transmission between 0 and 1. Subclasses implement __call__ and sample; this class only defines the interface.
- Parameters:
name (str) – Passband name. Used as the passband identifier by
Instrument.- Variables:
bbox (ndarray) – Wavelength bounding box
[wl_min, wl_max]in nm, outside which the transmission is zero.
- class pytransit.contamination.filter.BoxcarFilter(name, wl_min, wl_max)[source]#
Bases:
FilterFilter with a transmission of 1 inside the minimum and maximum wavelengths and 0 outside.
- class pytransit.contamination.filter.TabulatedFilter(name, wl, tm)[source]#
Bases:
FilterInterpolated tabulated filter.
- __init__(name, wl, tm)[source]#
- Parameters:
name (str) – Passband name.
wl (array-like) – Wavelengths in nm. Must increase monotonically.
tm (array-like) – Transmission values in [0, 1], one per wavelength. Interpolated with a cubic spline.
- Raises:
AssertionError – If the arrays differ in size, the wavelengths are not monotonically increasing, or a transmission value falls outside [0, 1].
- class pytransit.contamination.filter.DeltaFilter(name, wl)[source]#
Bases:
FilterMonochromatic filter transmitting at a single wavelength.
Useful for modeling spectroscopic bins narrow enough that the transmission profile does not matter, and as the default passband of the gravity-darkened model.
- class pytransit.contamination.instrument.Instrument(name, filters, qes=None)[source]#
Bases:
objectA set of passbands with optional detector quantum efficiency curves.
An Instrument bundles the passbands a contamination model integrates stellar spectra over. The order of filters fixes the passband order used everywhere downstream: the columns of the contamination arrays and the passband indices (pbids) given to a transit model refer to this order.
- Parameters:
name (str) – Instrument name.
filters (sequence of Filter) – The passband transmission profiles, one per passband.
qes (Filter or sequence of Filter, optional) – Detector quantum efficiency profiles. A single Filter is applied to every passband, a sequence gives one profile per passband. Defaults to a flat unit response over 0-10000 nm, i.e. no quantum efficiency weighting.
- Variables:
Contamination models#
- class pytransit.contamination.contamination.BBContamination(instrument, ref_pb, delta_l=10)[source]#
Bases:
_BaseContaminationThird light contamination based on black body approximation.
This class offers a simple black-body model for flux contamination in which the target star and the contaminant(s) are approximated as black bodies with effective temperatures Tt, Tc1, Tc2, …, Tcn.
- __init__(instrument, ref_pb, delta_l=10)[source]#
- Parameters:
instrument – Instrument configuration.
ref_pb – Reference passband name.
delta_l – Wavelength grid spacing in nm.
- static absolute_flux(teff, wl)[source]#
The absolute flux given an effective temperature and wavelength.
- Parameters:
teff – The effective temperature in K
wl – The wavelength (or an array of) in nm
- Returns:
Black body spectral radiance.
- static relative_flux(teff, wl, wlref)[source]#
The black body flux normalized to a given reference wavelength.
- Parameters:
teff – The effective temperature of the radiating body [K]
wl – The wavelength [nm]
wlref – The reference wavelength [nm]
- Returns:
The black body flux normalized to a given reference wavelength
- absolute_fluxes(teff)[source]#
Calculates the integrated absolute fluxes for all filters for a star with the given effective temperature
- Parameters:
teff – The effective temperature of the radiating body [K]
- Returns:
The integrated absolute fluxes for the filters in the instrument.
- relative_fluxes(teff)[source]#
Calculates the integrated fluxes for all filters normalized to the reference passband.
- Parameters:
teff – The effective temperature of the radiating body [K]
- Returns:
The integrated fluxes for all filters normalized to the reference passband.
- contamination(cref, teff1, teff2)[source]#
Calculates the contamination factors for all the filters given the contamination in the reference passband.
- Parameters:
cref – Reference passband contamination
teff1 – Host star effective temperature
teff2 – Contaminant effective temperature
- Returns:
Contamination factors for all the filters.
- c_as_pandas(ci, teff1, teff2)#
Contamination as a pandas DataFrame.
- c_as_xarray(ci, teff1, teff2)#
Contamination as an xarray DataArray.
- exposure_times(teff, rtime, rflux=1.0, tflux=1.0)#
Exposure times that give equal flux as in the reference passband
- plot(teff1, teff2, cref, wlref=600, wlmin=305, wlmax=995, nwl=500, figsize=None, axs=None)#
Plots the contamination model.
- Parameters:
teff1
teff2
cref
wlref
wlmin
wlmax
nwl
figsize
- class pytransit.contamination.contamination.SMContamination(instrument, ref_pb=None, data='BT-SETTL')[source]#
Bases:
_BaseContaminationA class that models flux contamination based on stellar spectrum models.
- __init__(instrument, ref_pb=None, data='BT-SETTL')[source]#
- Parameters:
instrument – Instrument configuration.
ref_pb – Name of the reference passband, i.e. the passband in which the contamination is parametrised.
data – Stellar spectrum grid to use, either
'BT-SETTL'(default) or'Husser2013'.
- Raises:
ValueError – If data is neither
'BT-SETTL'nor'Husser2013'.
- absolute_flux(teff, wl)[source]#
The absolute flux given an effective temperature and a set of wavelength.
- Parameters:
teff (float) – The effective temperature [K]
wl (array-like) – The wavelengths to calculate the flux in [nm]
- Returns:
Spectral radiance.
- relative_flux(teff, wl, wlref)[source]#
The stellar flux normalized to a given reference wavelength.
- c_as_pandas(ci, teff1, teff2)#
Contamination as a pandas DataFrame.
- c_as_xarray(ci, teff1, teff2)#
Contamination as an xarray DataArray.
- contamination(cref, teff1, teff2, absolute=False)[source]#
Contamination given reference contamination, host TEff, and contaminant TEff(s)
Per-passband contamination given the contamination in the reference passband and TEffs of the two stars.
- Parameters:
cref (float) – contamination in the reference passband
teff1 – Effective stellar temperature [K]
teff2 – Effective stellar temperature [K]
- Returns:
Per-passband contamination
- exposure_times(teff, rtime, rflux=1.0, tflux=1.0)#
Exposure times that give equal flux as in the reference passband
- plot(teff1, teff2, cref, wlref=600, wlmin=305, wlmax=995, nwl=500, figsize=None, axs=None)#
Plots the contamination model.
- Parameters:
teff1
teff2
cref
wlref
wlmin
wlmax
nwl
figsize