Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


Documentation Status

specgp enables 2D Gaussian process computations in exoplanet. This is accomplished by a new kernel term which combines a celerite term with a specification of the covariance for the second dimension. The method


Installation is via pip:
pip install specgp


Documentation for specgp is available here.


One straightforward application of *specgp* is modeling multiwavelength stellar variability. While the tutorials at cover the details of optimizing a GP model and running MCMC on this kind of data, here we present a simple demonstration of a multiwavelength variability model that illustrates the most basic usage of *specgp*: We start by defining the covariance in the time dimension using a *celerite* term:

import numpy as np
import exoplanet as xo

term =, log_w0=1.0, log_Q=-np.log(np.sqrt(2)))

In the simplest case we can model the wavelength dependence of a star's variability as a simple scaling of the variability amplitude between bands (see our paper for details). In this case we can construct the 2D kernel by passing the *celerite* term along with a vector of scale factors for the wavelength-dependence to the KronTerm constructor:

import specgp as sgp

# scaling factors for a two band model. The 
# variability amplitude will scale by a factor 
# of two between the two bands.
alpha = [1, 2]
kernel = sgp.terms.KronTerm(term, alpha=alpha)

Now we define the white noise component of the GP as a 2D array containing the white noise variance for each input coordinate:

diag = np.array([0.001, 0.1])
diag = diag[:, None] * np.ones_like(t)
[[0.001 0.001 0.001 ... 0.001 0.001 0.001]
[0.1   0.1   0.1   ... 0.1   0.1   0.1  ]]

Here the first row represents the white noise variance at each time in the first band, and the second row represents the variance at each time in the second band. We also need to define a mean function for the GP. Here we define a flat mean for the GP as another 2D array of zeros with the same structure as for the white noise:

mu = sgp.means.KronMean(np.zeros((2, len(t))))

Now we're ready to define the GP.

gp =, kernel=kernel, diag=diag, mean=mu, J=2)

Let's take a look at a sample from the GP:

n = np.random.randn(2*len(t), 1)
y = gp.dot_l(n).eval()

pl.plot(t, y[::2], '.', color='#FE4365')
pl.plot(t, y[1::2], '.', color='#3F9778')


Note that the dot_l function returns the sample as a 1D vector with the coordinates all mixed up. This happens because dot_l operates directly on the Cholesky decomposition of the Kronecker-structured covariance matrix. For most use cases the user won't need to worry about details like this, but it's pretty easy to disentangle the output if you need to. The element of the output corresponding to time i in band j is located at the element (M-1)*i + j where M is the number of bands.


Gaussian processes for multi-wavelength and spectral observations







No releases published


No packages published