Transit light curve routines

Contents:

The Mandel & Agol (2002) transit light curve equations.

FUNCTIONS:

occultuniform() – uniform-disk transit light curve

occultquad() – quadratic limb-darkening

occultnonlin() – full (4-parameter) nonlinear limb-darkening

occultnonlin_small() – small-planet approximation with full

nonlinear limb-darkening.

t2z() – convert dates to transiting z-parameter for circular

orbits.

REQUIREMENTS:

numpy

scipy.special

NOTES:

Certain values of p (<0.09, >0.5) cause some routines to hang; your mileage may vary. If you find out why, please let me know!

Cursory testing suggests that the Python routines contained within

are slower than the corresponding IDL code by a factor of 5-10.

For occultquad() I relied heavily on the IDL code of E. Agol and J. Eastman.

Function appellf1() comes from the mpmath compilation, and is adopted (with modification) for use herein in compliance with its BSD license (see function documentation for more details).

REFERENCE:

The main reference is that seminal work by Mandel and Agol (2002).

LICENSE:

Created by Ian Crossfield at UCLA. The code contained herein may be reused, adapted, or modified so long as proper attribution is made to the original authors.

REVISIONS:
2011-04-22 11:08 IJMC: Finished, renamed occultation functions.

Cleaned up documentation. Published to website.

2011-04-25 17:32 IJMC: Fixed bug in ellpic_bulirsch().

2012-03-09 08:38 IJMC: Several major bugs fixed, courtesy of
  1. Aigrain at Oxford U.
2012-03-20 14:12 IJMC: Fixed modeleclipse_simple based on new

format of :func:`occultuniform. `

transit.JKTEBOP_lightcurve(v, vary, ldtype, nsine, psine, npoly, ppoly, time, dtype1, la, lb, numint, ninterval, nthreads=1)[source]

Generate a JKTEBOP light curve using the F2Py-compiled library.

INPUTS:

The inputs to the Fortran function ‘jktebop.getmodel’ are many, and their formatting is complicated. You may want to examine the Fortran source code for more insight.

v : 138-sequence of floats

Photometric parameters. In full, these are:

V(0) = central surface brightness ratio (starB/starA)

V(1) = sum of the fractional radii (radii divided by semimajor axis)

V(2) = ratio of stellar radii (starB/starA)

V(3) = linear limb darkening coefficient for star A

V(4) = linear limb darkening coefficient for star B

V(5) = orbital inclination (degrees)

V(6) = e cos(omega) OR ecentricity

V(7) = e sin(omega) OR omega(degrees)

V(8) = gravity darkening of star A

V(9) = gravity darkening of star B

V(10) = reflected light for star A

V(11) = reflected light for star A

V(12) = mass ratio (starB/starA) for the light curve calculation

V(13) = tidal lead/lag angle (degrees)

V(14) = third light in units where (LA + LB + LC = 1)

V(15) = phase correction factor (i.e. phase of primary eclipse)

V(16) = light scaling factor (magnitudes)

V(17) = integration ring size (degrees)

V(18) = orbital period (days)

V(19) = ephemeris timebase (days)

V(20) = limb darkening coefficient 2 for star A

V(21) = limb darkening coefficient 3 for star A

V(22) = limb darkening coefficient 4 for star A

V(23) = limb darkening coefficient 2 for star B

V(24) = limb darkening coefficient 3 for star B

V(25) = limb darkening coefficient 4 for star B

V(26) = velocity amplitude of star A (km/s)

V(27) = velocity amplitude of star B (km/s)

V(28) = systemic velocity of star A (km/s)

V(29) = systemic velocity of star B (km/s)

V(30-56) nine lots of sine curve parameters [T0,period,amplitude]

V(57-137) nine lots of polynomial parameters [pivot,Tstart,Tend,const,x,x2,x3,x4,x5]

vary : 138-sequence of ints

“Which parameters are fitted.” But for directly called jktebop.getmodel, the only possible relevant values are [a] all values zero (normal operations) or [b] all values zero, but vary[29]=-1 (if dtype1=8).

ldtype : 2-sequence of ints

LD law type for the stars A and B, respectively:

1 –> “lin” – linear 2 –> “log” – linear + log 3 –> “sqrt” – linear + sqrt 4 –> “quad” – linear + quadratic 5 –> “cub” – linear + cubic 6 –> “4par” – Claret’s 4-parameter form.

nsine, npoly : ints

The number of sines and polynomials, respectively.

psine, ppoly : 9-sequences

The parameters for sines and polynomials, respectively.

time

The given TIME, PHASE or CYCLE

dtype1 : int, 1-8 inclusive.
Precise meaning of the output value depends on DTYPE.

1 it outputs an EBOP magnitude for given time 2 it outputs a light ratio for the given time 3 outputs a time of eclipse for the given =CYCLE= 4 it simply outputs the third light value 5 it outputs e or e*cos(omega) 6 it outputs omega or e*sin(omega) 7 it outputs the RV of star A 8 it outputs the RV of star B

la, lb : floats

Light produced by each star (??)

numint : int, >= 1.

Number of numerical integrations. Long exposure times can be split up into NUMINT points.

ninterval : float

Time interval for integrations. If numint>1, each point in the numerical integration occupies a total time interval of NINTERVAL seconds.

OPTIONS:

None (so far!)

NOTES:

See the JKTEBOP documentation for more details. JKTEBOP is currently available online at http://www.astro.keele.ac.uk/~jkt/codes/jktebop.html

To compile JKTEBOP (v34) with F2Py, I had to rename the source file to be “jktebop_orig.f90”, and then I ran the following command:

f2py-2.7 -c –debug -m jktebop_f2py jktebop_orig.f90

OR

f2py-2.7 -c –debug -m jktebop_mod jktebop.f90

EXAMPLE:
import pylab as py
import jktebop_f2py
import transit

v = np.zeros(138, dtype=float)
v[[1,2,3,4,5]] = [0.211, 0.154, 0.3, 0.3, 88.59]
v[12] = 0.0013    # Mass ratio
v[17] = 1         # Integration ring size; cannot be zero.
v[18] = 1.3382320363  # Orbital period
v[19] = 54740.62  # Transit ephemeris
vary = np.zeros(138, dtype=int)
ldtype = [4, 1]   # Quadratic for star, linear for planet.
nsine, npoly = 0, 0
psine, ppoly = np.zeros(9), np.zeros(9)
times = py.linspace(v[19]-0.1, v[19]+0.1, 100)
dtype1 = 1   # To compute a light curve
la, lb = 0, 0  # (????)
numint = 1    # Cannot be zero
ninterval = 0 # Irrelevant, because numint=1

magout_direct = py.array([jktebop_f2py.getmodel(v, vary, ldtype, nsine, psine, npoly, ppoly, time, dtype1, la, lb, numint, ninterval) for time in times])

magout_alt = transit.JKTEBOP_lightcurve(v, vary, ldtype, nsine, psine, npoly, ppoly, times, dtype1, la, lb, numint, ninterval) 
SEE_ALSO:

runJKTEBOP()

transit.JKTEBOP_lightcurve_helper(all_args)[source]

vv = ((v, vary, ldtype, nsine, psine, npoly, ppoly, bjd, 1, 0, 0, numint, ninterval))

out0 = np.array([jktebop_f2py.getmodel(v, vary, ldtype, nsine, psine, npoly, ppoly, time, 1, 0, 0, numint, ninterval) for time in bjd]) out00 = jktebop_mod.getmodelarray(v, vary, ldtype, nsine, psine, npoly, ppoly, bjd, 1, 0, 0, numint, ninterval, bjd.size) out1 = transit.JKTEBOP_lightcurve(*vv) out2 = transit.JKTEBOP_lightcurve_helper(vv)

out3 = np.array(map(transit.JKTEBOP_lightcurve_helper, [(v, vary, ldtype, nsine, psine, npoly, ppoly, time0, 1, 0, 0, numint, ninterval) for time0 in bjd])).squeeze() out4 = np.array(pool.map(transit.JKTEBOP_lightcurve_helper, [(v, vary, ldtype, nsine, psine, npoly, ppoly, time0, 1, 0, 0, numint, ninterval) for time0 in bjd])).squeeze()

1e4 1e5 1e6

0 0.104 0.984 9.762 1 0.103 0.979 9.878 2 0.101 0.999 9.801 3 0.252 3.028 31.8 4 0.228 3.006 30.7

This method doesn’t seem any faster!
transit.analyze_jktebop(guess_params, times, NL, NP, data2fit, weights=None, nwalkers=None, maxSteps=20000, gr_cutoff=1.1, priors=None, pool=None, verbose=False)[source]

Determine best fit and uncertainties on transits, eclipses, phasecurves.

SEE_ALSO:blender.modeltransit_jktebop

returns: bestfit, sampler, weights, bestmod

transit.analyzeeclipse_simple(guess_params, tparams, times, data2fit, weights=None, nwalkers=None, maxSteps=20000, gr_cutoff=1.1, priors=None, pool=None)[source]

Determine best fit and uncertainties on secondary eclipse data.

SEE_ALSO:modeleclipse_simple

returns: bestfit, sampler, weights, bestmod

transit.analyzetransit_general(params, NL, NP, time, data, weights=None, dopb=False, domcmc=False, gaussprior=None, ngaussprior=None, uniformprior=None, nsigma=4, maxiter=10, parinfo=None, nthread=1, nstep=2000, nwalker_factor=20, xtol=1e-12, ftol=1e-10, errscale=1000000.0, smallplanet=True, svs=None, verbose=False)[source]

Fit transit to data, and estimate uncertainties on the fit.

INPUTS:
params : sequence

A guess at the best-fit model transit parameters, to be passed to modeltransit_general().

If ‘svs’ are passed in (see below), then params should have an additional value concatenated on the end as the coefficient for each state vector.

NL : int

number of limb-darkening parameters (cf. modeltransit_general())

NP : int

number of normalizing polynomial coefficients (cf. modeltransit_general())

time : sequence

time values (e.g., BJD_TDB - BJD_0)

data : sequence

photometric values (i.e., the transit light curve) to be fit to.

weights : sequence

weights to the photometric values. If None, weights will be set equal to the inverse square of the residuals to the best-fit model. In either case, extreme outliers will be de-weighted in the fitting process. This will not change the values of the input ‘weights’.

nsigma : scalar

Residuals beyond this value of sigma-clipped standard deviations will be de-weighted.

dopb : bool

If True, run prayer-bead (residual permutation) error analysis.

domcmc : bool

If True, run Markov Chain Monte Carlo error analysis (requires EmCee)

nstep : int

Number of steps for EmCee MCMC run. This should be at least several thousand.

errscale: scalar

See modeltransit_general()

smallplanet: bool

See modeltransit_general()

svs : None, or sequence of 1D NumPy arrays

State vectors, for additional decorrelation of data in a least-squares sense. See modeltransit_general()

OUTPUTS:

(eventually, some object with useful fields)

SEE_ALSO:

modeltransit_general()

transit.appellf1(a, b1, b2, c, z1, z2, **kwargs)[source]

Give the Appell hypergeometric function of two variables.

INPUTS:

six parameters, all scalars.

OPTIONS:

eps – scalar, machine tolerance precision. Defaults to 1e-10.

NOTES:

Adapted from the mpmath module, but using the scipy (instead of mpmath) Gauss hypergeometric function speeds things up.

LICENSE:

MPMATH Copyright (c) 2005-2010 Fredrik Johansson and mpmath contributors. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  3. Neither the name of mpmath nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

transit.bls_simple(times, flux, prange, dlogper=0.0004, nbins=150, maxwid=10, nthreads=1)[source]

Implement a simple/stupid version of the Box-Least-Squares algorithm.

INPUTS:
times : 1D NumPy array.

timestamps of the input time series

flux : 1D NumPy array.

input time series

prange : 2-sequence

Minimum and maximum periods to search.

dlogper : positive scalar

Test periods will be uniformly separated in log-space, with this spacing in log10.

nbins : positive int

Number of bins to use when binning the phase-folded data. The width of each bin will depend on the test period considered, as (P/nbins)

maxwid : positive int

Maximum width of the transit signal sought, in terms of the number of phase bins.

nthreads : positive int

Number of multiprocessing threads to use.

OUTPUTS:

(test_periods, reduction_in_dispersion)

NOTES:

Transits shorter than (prange[0]/nbins) and longer than (maxwid*prange[1]/nbins) may not be correctly modelled.

This routine is my own crude attempt at a box-fitting least-squares algorithm. Note however that this is NOT the well-publicized (and more rigorous) version of Kovacs et al. (2002). Here for each trial period, I bin the data and construct simple box-shaped transit models for combinations of ingress and egress times. For each model the reduction in the standard deviation of (binned data - model) is calculated; for each period, the greatest reduction value is reported.

transit.computeInTransitIndex(time, period, tt, t14)[source]

REturn a boolean mask, True wherever the planet is in transit.

transit.createJKTEBOPinput(*args, **kw)[source]

Create an input file suitable for running JKTEBOP.

INPUT:

A long sequence of numerical & string inputs, defined as follows. If simulating a transiting planet, object “A” indicates the star and object “B” indicates the planet.

JKTEBOP “Task” to do (from 1 to 9) – for now, only 2 is valid.

Integrating ring size (deg) – between 0.1 and 10.0 degrees

Sum of the radii (R_A/a + R_B/a)

Ratio of the radii (R_B / R_A)

Orbital inclination (deg)

Mass ratio of system (M_B / M_A)

e*cos(omega) or orbital eccentricity – see NOTES below.

e*sin(omega) or periastron longitude (deg) – see NOTES below.

Gravity darkening (object A; typically set to 1.0)

Grav darkening (object B; typically set to 1.0)

Surface brightness ratio (typically set to 0.0)

Amount of third light

Limb-darkening law type for star A:

one of (‘lin’, ‘log’, ‘sqrt’, ‘quad’, ‘cub’, ‘4par’)

Limb-darkening law type for star A:

(any of the preceding options, or ‘same’ for same)

LD star A:

if LD law is ‘4par’ then one after another enter the 4 values (coef1, coef2, coef3, coef). Otherwise, (linear coeff, nonlincoef)

LD star B:

Same as described above.

Reflection effect star A

Reflection effect star B

Orbital phase of primary eclipse

Light scale factor : scalar

Apparent magnitude of the target star

OPTIONS:
period : scalar

Orbital period of the binary in days, used to compute the output timestamps. If not entered, output ‘time’ will be orbital phase.

t0 : scalar

Time index of mid-transit.

infile : str

Name of the ‘input file’ to be created by this routine.

outfile : str

Name of the ‘output file’ to be created by JKTEBOP.

datfile : str

Name of the ‘data file’ to be input; has 2-3 columns of timestamps, photometry, and (optional) uncertainties, respectively.

clobber : bool

If true, overwrite any existing file. Otherwise: don’t!

OUTPUT:

If no ‘filename’ option was passed in, returns a list of strings, suitable to writing to disk via the usual:

f = open(filename, 'w')
f.writelines(data)
f.close()
EXAMPLE:
vals = [2, 1, 0.21, 0.15, 88.5, 0.0013, 0, 0, 1, 1, 0, 0,              'quad', 'lin', 0.3, 0, 0.3, 0, 0, 0, 0, 0.6]
output = transit.createJKTEBOPinput(vals, filename='test.in', clobber=False)
NOTES:

Put a negative number for the mass ratio to force the stars to be spherical. The mass ratio will then be irrelevant (it is only used to get deformations).

To input R_A/a and R_B/a (instead of [R_A+R_B]/a and R_B/R_A), give a negative value for [R_A+R_B]/a. Then it will be interpreted to mean R_A/a, and R_B/R_A will be interpreted as R_B/a.

If eccentricity < 10 then e and omega will be assumed to be e*cos(omega) and e*sin(omega). If e >= 10 then e and omega will be assumed to be (e+10) and omega (degrees). The first option is often better unless eccentricity is larger or fixed.

See the JKTEBOP documentation for more details on all these parameters. JKTEBOP is currently available online at http://www.astro.keele.ac.uk/~jkt/codes/jktebop.html

TO_DO:

Add other optional parameters: TMIN, LRAT, THDL, ECSW, ENSW, SINE, POLY, NUMI, RV1 & RV2, orbital period, reference epoch...

Allow fitting (i.e., enable Tasks 3-9).

transit.ellke(k)[source]

Compute Hasting’s polynomial approximation for the complete elliptic integral of the first (ek) and second (kk) kind.

INPUTS:k – scalar or Numpy array
OUTPUTS:ek, kk
NOTES:Adapted from the IDL function of the same name by J. Eastman (OSU).
transit.ellke2(k, tol=2.2204460492503131e-14, maxiter=100)[source]

Compute complete elliptic integrals of the first kind (K) and second kind (E) using the series expansions.

transit.ellpic_bulirsch(n, k, tol=2.2204460492503131e-13, maxiter=10000.0)[source]

Compute the complete elliptical integral of the third kind using the algorithm of Bulirsch (1965).

INPUTS:

n – scalar or Numpy array

k– scalar or Numpy array

NOTES:

Adapted from the IDL function of the same name by J. Eastman (OSU).

transit.eval_int_at_limit(limit, cn)[source]

Evaluate the integral at a specified limit (upper or lower)

transit.fiteclipse(data, sv, ords, tlc, edata=None, index=None, dotransit=True, dopb=True)[source]

data: time series to fit using least-squares.

sv: state vectors (e.g., various instrumental parameters)

ords: orders to raise each sv vector to: e.g., [1, [1,2], 3]

tlc: eclipse light curve

edata: error on the data (for chisq ONLY! No weighted fits.)

index: array index to apply to data, sv, and tlc

dopb: do prayer-bead uncertainty analysis

dotransit: include tlc in the fitting; otherwise, leave it out.

transit.get_reduction_factor(args)[source]

Helper function for bls_simple.

args = thisperiod, times, flux, phasebins, maxwid):

transit.integral_smallplanet_nonlinear(z, p, cn, lower, upper)[source]

Return the integral in I*(z) in Eqn. 8 of Mandel & Agol (2002). – Int[I(r) 2r dr]_{z-p}^{1}, where:

INPUTS:
z = scalar or array. Distance between center of star &

planet, normalized by the stellar radius.

p = scalar. Planet/star radius ratio.

cn = 4-sequence. Nonlinear limb-darkening coefficients,

e.g. from Claret 2000.

lower, upper – floats. Limits of integration in units of mu

RETURNS:

value of the integral at specified z.

transit.mcmc_eclipse(flux, sigma, t, func, params, tparams, stepsize, numit, nstep=1, posdef=None, holdfixed=None)[source]

MCMC for 3-parameter eclipse function with KNOWN orbit

INPUTS:
flux : 1D array

Contains dependent data

sigma : 1D array

Contains standard deviation (uncertainties) of flux data

t : 1D array

Contains independent data: timing info

func : function

Function to model eclipse (e.g., transit.occultuniform())

params : parameters to be fit:
EITHER:

[T_center, depth, Fstar]

OR:

[c0, ..., c13, T_center, depth, Fstar]

params : 4 KNOWN, CONSTANT orbital parameters

[b, Rstar/a, Rp/Rstar, period]

stepsize : 1D array

Array of 1-sigma change in parameter per iteration

numit : int

Number of iterations to perform

nstep : int

Saves every “nth” step of the chain

posdef : None, ‘all’, or sequences of indices.

Which elements should be restricted to positive definite? If indices, it should be of the form (e.g.): [0, 1, 4]

holdfixed : None, or sequences of indices.

Which elements should be held fixed in the analysis? If indices, it should be of the form (e.g.): [0, 1, 4]

RETURNS:
allparams : 2D array

Contains all parameters at each step

bestp : 1D array

Contains best paramters as determined by lowest Chi^2

numaccept: int

Number of accepted steps

chisq: 1D array

Chi-squared value at each step

REFERENCES:

Numerical Recipes, 3rd Edition (Section 15.8); Wikipedia

transit.mcmc_transit_single(flux, sigma, t, per, func, params, stepsize, numit, nstep=1, posdef=None, holdfixed=None)[source]

MCMC for 5-parameter eclipse function of transit with KNOWN period

INPUTS:
flux : 1D array

Contains dependent data

sigma : 1D array

Contains standard deviation (uncertainties) of flux data

t : 1D array

Contains independent data: timing info

per : scalar

Known orbital period (same units as t)

func : function

Function to model transit (e.g., transit.occultuniform)

params : 5+N parameters to be fit
[T_center, b, Rstar/a, Rp/Rstar, Fstar] + (limb-darkening parameters?)

#[Fstar, t_center, b, v (in Rstar/day), p (Rp/Rs)]

stepsize : 1D or 2D array

if 1D: array of 1-sigma change in parameter per iteration if 2D: array of covariances for new parameters

numit : int

Number of iterations to perform

nstep : int

Saves every “nth” step of the chain

posdef : None, ‘all’, or sequences of indices.

Which elements should be restricted to positive definite? If indices, it should be of the form (e.g.): [0, 1, 4]

holdfixed : None, or sequences of indices.

Which elements should be held fixed in the analysis? If indices, it should be of the form (e.g.): [0, 1, 4]

RETURNS:
allparams : 2D array

Contains all parameters at each step

bestp : 1D array

Contains best paramters as determined by lowest Chi^2

numaccept: int

Number of accepted steps

chisq: 1D array

Chi-squared value at each step

REFERENCES:

Numerical Recipes, 3rd Edition (Section 15.8); Wikipedia

transit.mcmc_transit_single14(flux, sigma, t, per, func, params, stepsize, numit, nstep=1, posdef=None, holdfixed=None)[source]

MCMC for 5-parameter eclipse function of transit with KNOWN period

INPUTS:
flux : 1D array

Contains dependent data

sigma : 1D array

Contains standard deviation (uncertainties) of flux data

t : 1D array

Contains independent data: timing info

per : scalar

Known orbital period (same units as t)

func : function

Function to model transit (e.g., transit.occultuniform)

params : 14+5+N parameters to be fit

[c0,...,c13] + [T_center, b, Rstar/a, Rp/Rstar, Fstar] + (limb-darkening parameters?)

stepsize : 1D or 2D array

If 1D: 1-sigma change in parameter per iteration If 2D: covariance matrix for parameter changes.

numit : int

Number of iterations to perform

nstep : int

Saves every “nth” step of the chain

posdef : None, ‘all’, or sequences of indices.

Which elements should be restricted to positive definite? If indices, it should be of the form (e.g.): [0, 1, 4]

holdfixed : None, or sequences of indices.

Which elements should be held fixed in the analysis? If indices, it should be of the form (e.g.): [0, 1, 4]

RETURNS:
allparams : 2D array

Contains all parameters at each step

bestp : 1D array

Contains best paramters as determined by lowest Chi^2

numaccept: int

Number of accepted steps

chisq: 1D array

Chi-squared value at each step

REFERENCES:

Numerical Recipes, 3rd Edition (Section 15.8); Wikipedia

transit.modeleclipse(params, func, per, t)[source]

Model an eclipse light curve of arbitrary type to a flux time series, assuming zero eccentricity and a fixed, KNOWN period.

INPUTS:
params – (6-or-7)-sequence with the following:

the time of conjunction for each individual eclipse (Tc),

the impact parameter (b = a cos i/Rstar)

the stellar radius in units of orbital distance (Rstar/a),

planet-to-star radius ratio (Rp/Rstar),

eclipse depth (dimensionless),

stellar flux (F0),

orbital period (OPTIONAL!)

func – function to fit to data; presumably transit.occultuniform()

per – float.

Orbital period, OR

None, if period is included in params

t – numpy array.

Time of observations (same units as Tc and per)

transit.modeleclipse_simple(params, tparams, func, t)[source]

Model an eclipse light curve of arbitrary type to a flux time series, assuming zero eccentricity and a fixed, KNOWN orbit.

INPUTS:
params – (3)-sequence with eclipse parameters to FIT:

the time of conjunction for each individual eclipse (Tc),

eclipse depth (dimensionless),

stellar flux (F0),

tparams – (4)-sequence of transit parameters to HOLD FIXED:

the impact parameter (b = a cos i/Rstar)

the stellar radius in units of orbital distance (Rstar/a),

planet-to-star radius ratio (Rp/Rstar),

orbital period (same units as Tc and t)

func – function to fit to data; presumably transit.occultuniform()

t – numpy array. Time of observations.

transit.modeleclipse_simple14(params, tparams, func, t)[source]

Model an eclipse light curve of arbitrary type to a flux time series, assuming zero eccentricity and a fixed, KNOWN orbit.

INPUTS:
params – (14+3)-sequence with eclipse parameters to FIT:

the multiplicative sensitivity effects (c0, ..., c13), which affect each bit of data as (1. + c_j) * ... HOWEVER, to keep these from becoming degenerate with the overall stellar flux level, only 13 of these are free parameters: the first (c0) will always be set such that the product PROD_j(1 + c_j) = 1.

the time of conjunction for each individual eclipse (Tc),

eclipse depth (dimensionless),

stellar flux (F0),

tparams – (4)-sequence of transit parameters to HOLD FIXED:

the impact parameter (b = a cos i/Rstar)

the stellar radius in units of orbital distance (Rstar/a),

planet-to-star radius ratio (Rp/Rstar),

orbital period (same units as Tc and t)

func – function to fit to data; presumably transit.occultuniform()

t – numpy array. Time of observations.

Must either be of size (14xN), or if a 1D vector then t.reshape(14, N) must correctly reformat the data into data streams at 14 separate positions.

transit.modellightcurve(params, t, tfunc=<function occultuniform at 0x10dfb60c8>, nlimb=0, nchan=0)[source]

Model a full planetary light curve: transit, eclipse, and (sinusoidal) phase variation. Accept independent eclipse and transit times-of-center, but otherwise assume a circular orbit (and thus symmetric transits and eclipses).

INPUTS:

params – (M+10+N)-sequence with the following:

OPTIONALLY:

sensitivity variations for each of M channels (e.g., SST/MIPS). This assumes the times in ‘t’ are in the order (T_{1,0}, ... T_{1,M-1}, ... T_{2,0}, ...). The parameters affect the data multiplicatively as (1 + c_i), with the constraint that Prod_i(1+c_i) = 1.

the time of conjunction for each individual transit (T_t),

the time of conjunction for each individual eclipse (T_e),

the orbital period (P),

the impact parameter (b = a cos i/Rstar)

the stellar radius in units of orbital distance (Rstar/a),

planet-to-star radius ratio (Rp/Rstar),

stellar flux (F0),

maximum (hot-side) planet flux (Fbright),

minimum (cold-side) planet flux (Fdark),

phase curve offset (phi_0; 0 implies maximum flux near eclipse)

OPTIONALLY:

limb-darkening parameters (depending on tfunc):

EITHER:

gamma1, gamma2 – quadratic limb-darkening coefficients

OR:

c1, c2, c3, c4 – nonlinear limb-darkening coefficients

t – numpy array. Time of observations; same units as orbital

period and ephemerides. If nchan>0, t should be of shape (nchan, L), or a .ravel()ed version of that.

OPTIONS:
tfunc : model transit function

One of occultuniform(), occultnonlin_small(), occultquad(), or occultnonlin()

nlimb : int

number of limb-darkening parameters; these should be the last values of params.

nchan : int

number of photometric channel sensitivity perturbations; these should be the first ‘nchan’ values of params.

EXAMPLE:

TBW

NOTES:

This should be updated to use the new ‘transitonly’ options in t2z()

transit.modeltransit(params, func, per, t)[source]

Model a transit light curve of arbitrary type to a flux time series, assuming zero eccentricity and a fixed, KNOWN period.

INPUTS:
params – (5+N)-sequence with the following:

the time of conjunction for each individual transit (Tc),

the impact parameter (b = a cos i/Rstar)

the stellar radius in units of orbital distance (Rstar/a),

planet-to-star radius ratio (Rp/Rstar),

stellar flux (F0),

the limb-darkening parameters u1 and u2:

EITHER:

gamma1, gamma2 – quadratic limb-darkening coefficients

OR:

c1, c2, c3, c4 – nonlinear limb-darkening coefficients

OR:

Nothing at all (i.e., only 5 parameters).

func – function to fit to data, e.g. transit.occultquad

per – float. Orbital period, in days.

t – numpy array. Time of observations.

transit.modeltransit14(params, func, per, t)[source]

Model a transit light curve of arbitrary type to a flux time series, assuming zero eccentricity and a fixed, KNOWN period, and assuming MIPS-type data with 14 separate sensitivity dependencies.

INPUTS:

params – (14+5+N)-sequence with the following:

the multiplicative sensitivity effects (c0, ..., c13), which affect each bit of data as (1. + c_j) * ... HOWEVER, to keep these from becoming degenerate with the overall stellar flux level, only 13 of these are free parameters: the first (c0) will always be set such that the product PROD_j(1 + c_j) = 1.

the time of conjunction for each individual transit (Tc),

the impact parameter (b = a cos i/Rstar)

the stellar radius in units of orbital distance (Rstar/a),

planet-to-star radius ratio (Rp/Rstar),

stellar flux (F0),

the limb-darkening parameters u1 and u2:

EITHER:

gamma1, gamma2 – quadratic limb-darkening coefficients

OR:

c1, c2, c3, c4 – nonlinear limb-darkening coefficients

OR:

Nothing at all (i.e., only 5 parameters).

func – function to fit to data, e.g. transit.occultquad

per – float. Orbital period, in days.

t – numpy array. Time of observations.

Must either be of size (14xN), or if a 1D vector then t.reshape(14, N) must correctly reformat the data into data streams at 14 separate positions.

SEE ALSO:

modeltransit()

transit.modeltransit_general(params, t, NL, NP=1, errscale=1, smallplanet=True, svs=None)[source]

Model a transit light curve of arbitrary type to a flux time series, assuming zero eccentricity.

INPUTS:
params – (5 + NP + NL + NS)-sequence with the following:

Tc, the time of conjunction for each individual transit,

P, the orbital period (in units of “t”)

i, the orbital inclination (in degrees; 90 is edge-on)

R*/a, the stellar radius in units of orbital distance,

Rp/R*, planet-to-star radius ratio,

the NP polynomial coefficients to normalize the data.

EITHER:

F0 – stellar flux _ONLY_ (set NP=1)

OR:

[p_1, p_2, ..., p_(NP)] – coefficients for polyval, to be used as: numpy.polyval([p_1, ...], t)

the NL limb-darkening parameters (cf. Claret+2011):

EITHER:

u – linear limb-darkening (set NL=1)

OR:

a, b – quadratic limb-darkening (set NL=2)

OR:
c, d – root-square limb-darkening (set NL= -2)

where

I(mu) = 1 - c * (1 - mu) - d * (1 - mu^0.5)

OR:
a1, a2, a3, a4 – nonlinear limb-darkening (set NL=4)

where

I(mu) = 1 - a1 * (1 - mu^0.5) - a2 * (1 - mu) - a3 * (1 - mu^1.5) - a4 * (1 - mu^2)

OR:

Nothing at all – uniform limb-darkening (set NL=0)

multiplicative factors for the NS state vectors (passed in as ‘svs’)

t – numpy array. Time of observations.

smallplanet : bool

This only matters for root-square and four-parameter nonlinear limb-darkening. If “smallplanet” is True, use occultnonlin_small(). Otherwise, use occultnonlin()

errscale : int

If certain conditions (see below) are met, the resulting transit light curve is scaled by this factor. When fitting, set errscale to a very large value (e.g., 1e6) to use as an extremely crude hard-edged filter.

A better way would be to incorporate constrained fitting...

svs : None or list of 1D NumPy Arrays

State vectors, applied with coefficients as defined above. To avoid degeneracies with the NP polynomial terms (especially the constant offset term), it is preferable that the state vectors are all mean-subtracted.

NOTES:

If quadratic or linear limb-darkening (L.D.) is used, the sum of the L.D. coefficients cannot exceed 1. If they do, this routine normalizes the coefficients [g1,g2] to: g_i = g_i / (g1 + g2).

If “Rp/R*”, or “R*/a” are < 0, they will be set to zero.

If “P” < 0.01, it will be set to 0.01.

If “inc” > 90, it will be set to 90.

transit.modhaze_radspec_simple(params, wmod, rmod, rstar, retspec=False, filter_splines=None, w_star=None, f_star=None)[source]

Add a simple ad-hoc haze model to a planet’s radius spectrum.

INPUTS:
params : 3-sequence

params[0]: offset value for haze model params[1]: slope value (= alpha * H) for haze model params[2]: scaling factor for rmod

haze = params[1] * np.log(wmod) + params[0] newmod = vstack((rmod*params[2], haze/(planet.rstar*an.rsun))).max(0)

wmod : 1D NumPy array

Wavelength grid of model spectrum ‘rmod’

rmod : 1D NumPy array

Planet radius at each wavelength specified in ‘wmod’

rstar : scalar

Stellar radius, in units of solar radii.

retspec : bool

If True, just return the new model spectrum.

If False, return the filter-averaged value of the resulting spectrum for each filter profile specified in ‘filts’.

w_star : 1D NumPy array

Wavelength grid of stellar flux, in same units as wmod (but not necessary of same size!).

f_star : 1D NumPy array

Photon flux density of stellar flux at wavelengths specified in w_star.

NOTES:

Because this routine makes use of the numpy.interp function, using a smaller input model grid can significantly speed things up.

transit.occultnonlin(z, p0, cn)[source]

Nonlinear limb-darkening light curve; cf. Section 3 of Mandel & Agol (2002).

INPUTS:

z – sequence of positional offset values

p0 – planet/star radius ratio

cn – four-sequence. nonlinear limb darkening coefficients

EXAMPLE:
# Reproduce Figure 2 of Mandel & Agol (2002):
from pylab import *
import transit
z = linspace(0, 1.2, 50)
cns = vstack((zeros(4), eye(4)))
figure()
for coef in cns:
    f = transit.occultnonlin(z, 0.1, coef)
    plot(z, f)
SEE ALSO:

t2z(), occultnonlin_small(), occultuniform(), occultquad()

NOTES:

Scipy is much faster than mpmath for computing the Beta and Gauss hypergeometric functions. However, Scipy does not have the Appell hypergeometric function – the current version is not vectorized.

transit.occultnonlin_small(z, p, cn)[source]

Nonlinear limb-darkening light curve in the small-planet approximation (section 5 of Mandel & Agol 2002).

INPUTS:

z – sequence of positional offset values

p – planet/star radius ratio

cn – four-sequence nonlinear limb darkening coefficients. If

a shorter sequence is entered, the later values will be set to zero.

NOTE:

I had to divide the effect at the near-edge of the light curve by pi for consistency; this factor was not in Mandel & Agol, so I may have coded something incorrectly (or there was a typo).

EXAMPLE:
# Reproduce Figure 2 of Mandel & Agol (2002):
from pylab import *
import transit
z = linspace(0, 1.2, 100)
cns = vstack((zeros(4), eye(4)))
figure()
for coef in cns:
    f = transit.occultnonlin_small(z, 0.1, coef)
    plot(z, f, '--')
SEE ALSO:

t2z()

transit.occultquad(z, p0, gamma, retall=False, verbose=False)[source]

Quadratic limb-darkening light curve; cf. Section 4 of Mandel & Agol (2002).

INPUTS:

z – sequence of positional offset values

p0 – planet/star radius ratio

gamma – two-sequence.

quadratic limb darkening coefficients. (c1=c3=0; c2 = gamma[0] + 2*gamma[1], c4 = -gamma[1]). If only a single gamma is used, then you’re assuming linear limb-darkening.

OPTIONS:
retall – bool.

If True, in addition to the light curve return the uniform-disk light curve, lambda^d, and eta^d parameters. Using these quantities allows for quicker model generation with new limb-darkening coefficients – the speed boost is roughly a factor of 50. See the second example below.

EXAMPLE:
# Reproduce Figure 2 of Mandel & Agol (2002):
from pylab import *
import transit
z = linspace(0, 1.2, 100)
gammavals = [[0., 0.], [1., 0.], [2., -1.]]
figure()
for gammas in gammavals:
    f = transit.occultquad(z, 0.1, gammas)
    plot(z, f)
# Calculate the same geometric transit with two different
#    sets of limb darkening coefficients:
from pylab import *
import transit
p, b = 0.1, 0.5
x = (arange(300.)/299. - 0.5)*2.
z = sqrt(x**2 + b**2)
gammas = [.25, .75]
F1, Funi, lambdad, etad = transit.occultquad(z, p, gammas, retall=True)

gammas = [.35, .55]
F2 = 1. - ((1. - gammas[0] - 2.*gammas[1])*(1. - F1) + 
   (gammas[0] + 2.*gammas[1])*(lambdad + 2./3.*(p > z)) + gammas[1]*etad) / 
   (1. - gammas[0]/3. - gammas[1]/6.)
figure()
plot(x, F1, x, F2)
legend(['F1', 'F2'])
SEE ALSO:

t2z(), occultnonlin_small(), occultuniform()

NOTES:

In writing this I relied heavily on the occultquad IDL routine by E. Agol and J. Eastman, especially for efficient computation of elliptical integrals and for identification of several apparent typographic errors in the 2002 paper (see comments in the source code).

From some cursory testing, this routine appears about 9 times slower than the IDL version. The difference drops only slightly when using precomputed quantities (i.e., retall=True). A large portion of time is taken up in ellpic_bulirsch() and ellke(), but at least as much is taken up by this function itself. More optimization (or a C wrapper) is desired!

transit.occultuniform(z, p, complement=False, verbose=False)[source]

Uniform-disk transit light curve (i.e., no limb darkening).

INPUTS:
z – scalar or sequence; positional offset values of planet in

units of the stellar radius.

p – scalar; planet/star radius ratio.

complement : bool

If True, return (1 - occultuniform(z, p))

SEE ALSO:

t2z(), occultquad(), occultnonlin_small()

transit.pldEclipse(params, tparams, time, vecs)[source]

Simple toy model for Pixel-Level-Decorrelation testing.

tparams and time are for modeleclipse_simple()

vecs are: np.vstack((phat.T, othervecs.T)); of shape (Nvec x Nobs)

params are [eclipseCenter, ... then all the PLD coefs]

transit.runJKTEBOP(*args, **kw)[source]

Run JKTEBOP simulation from the command line, and return results.

INPUTS:

See createJKTEBOPinput() for a description of the inputs. For now, only “Task 2” can be run through this Python interface.

OPTIONS:
exe : string

Full path to the JKTEBOP executable.

period : scalar

Orbital period of the binary in days, used to compute the output timestamps. If not entered, output ‘time’ will be orbital phase.

infile : str

Name of the ‘input file’ to be created by this routine. If no value is passed, the routine will create a file named ‘testX.in’, where “X” is a random, long, integer.

outfile : str

Name of the ‘output file’ to be created by JKTEBOP. If no value is passed, the routine will create a file named “textX.out”

clobber : bool

If true, overwrite any and all existing files. Otherwise: don’t!

NOTES:

See the JKTEBOP documentation for more details. JKTEBOP is currently available online at http://www.astro.keele.ac.uk/~jkt/codes/jktebop.html

EXAMPLE:
vals = [2, 1, 0.21, 0.15, 88.5, 0.0013, 0, 0, 1, 1, 0, 0,              'quad', 'lin', 0.3, 0, 0.3, 0, 0, 0, 0, 0.6]
inputFile = 'JKTEBOP_test.in'
outputFile = 'JKTEBOP_test.out'
period = 9.8 
exe = os.path.expanduser('~')+'/proj/transit/jktebop/jktebop_orig'
time, mag = transit.runJKTEBOP(vals, infile=inputFile, outfile=outputFile, period=period, clobber=True, exe=exe)
## THIS IS A SPECIAL EXAMPLE FOR MY CODE ONLY --
##    I HAVE MODIFIED 'jktebop' SO DON'T EXPECT THE FOLLOWING TO
##    WORK PROPERLY ON YOUR COMPUTER!
import transit
import pylab as py

vals = [2, 1, 0.211, 0.154, 88.59, 0.0013, 0, 0, 1, 1, 0, 0,              'quad', 'lin', 0.3, 0., 0.3, 0, 0, 0, 0, 0.0]
inputFile = 'JKTEBOP_test_mod.in'
outputFile = 'JKTEBOP_test_mod.out'
dataFile    = 'wasp4.dat'   # data file; only its timestamps are used!
period = 1.3382320363      # Orbital period, in days
t0 = 54740.62  # Time of central transit, in days.
exe = os.path.expanduser('~')+'/proj/transit/jktebop/jktebop_mod'
time, mag = transit.runJKTEBOP(vals, infile=inputFile, outfile=outputFile, datfile=dataFile, period=period, t0=t0, clobber=True, exe=exe)

exampleData = py.loadtxt(dataFile)
examplePhase = (exampleData[:,0] - t0) / period

py.figure()
py.plot(examplePhase, 10**(-0.4*exampleData[:,1]), 'ob')
py.plot(time/period, 10**(-0.4*mag), '--r', linewidth=2)
py.xlabel('Orbital Phase')
py.ylabel('Normalized Flux')
py.minorticks_on()
py.legend(['Sample Observations', 'JKTEBOP Model'], 4)
SEE_ALSO:

createJKTEBOPinput()

TO_DO:

Enable light-curve simulations (Tasks 3-9).

transit.smallplanet_nonlinear(*arg, **kw)[source]

Placeholder for backwards compatibility with my old code. The function is now called occultnonlin_small().

transit.t2z(tt, per, inc, hjd, ars, ecc=0, longperi=0, transitonly=False, occultationonly=False)[source]

Convert HJD (time) to transit crossing parameter z.

INPUTS:

tt – scalar. transit ephemeris

per – scalar. planetary orbital period (in days)

inc – scalar. orbital inclination (in degrees)

hjd – scalar or array of times, typically heliocentric or

barycentric julian date.

ars – scalar. ratio a/Rs, orbital semimajor axis over stellar radius

ecc – scalar. orbital eccentricity.

longperi=0 scalar. longitude of periapse (in radians)

transitonly : bool

If False, both transits and occultations have z=0. But this means that other routines (e.g., occultuniform()) model two eclipse events per orbit. As a kludge, set transitonly=True – it sets all values of ‘z’ near occultations to be very large, so that they are not modeled as eclipses.

occultationonly : bool

Same as transitonly, but for occultations (secondary eclipses)

ALGORITHM:

At zero eccentricity, z relates to physical quantities by:

z = (a/Rs) * sqrt(sin[w*(t-t0)]**2+[cos(i)*cos(w*[t-t0])]**2)

transit.uniform(*arg, **kw)[source]

Placeholder for my old code; the new function is called occultuniform().

transit.z2dt_circular(per, inc, ars, z)[source]

Convert transit crossing parameter z to a time offset for circular orbits.

INPUTS:

per – scalar. planetary orbital period

inc – scalar. orbital inclination (in degrees)

ars – scalar. ratio a/Rs, orbital semimajor axis over stellar radius

z – scalar or array; transit crossing parameter z.

RETURNS:
|dt| – magnitude of the time offset from transit center at

which specified z occurs.

Table Of Contents

Previous topic

Plotting and analysis tools

Next topic

Transit/eclipse prediction charts

This Page