# The Joker [YO-ker] /’joʊkər/¶

## Introduction¶

*The Joker* [1] is a custom Monte Carlo sampler for the two-body problem and
is therefore useful for constraining star-star or star-planet systems. It is
designed to generate posterior samples over the orbital parameters of the
primary (observed) star given time-domain radial velocity measurements of this
star. Though it is assumed the system has only a primary and a companion,
*The Joker* can also be used for hierarchical systems in which the velocity
perturbations from a third or other bodies are much longer than the dominant
companion. See the paper [2] for more details about the method and
applications.

*The Joker* is particularly useful for sparse or low-quality radial velocity
data.

Note

The Joker was recently updated with some API-breaking changes. To see a list of these changes, and a guide on how to migrate to the new version, please see Updating to 0.2.

## Getting started¶

Generating samples with *The Joker* requires specifying three things:

The data,`RVData`

: radial velocity measurements, uncertainties, and observation timesThe model parameters,`JokerParams`

: hyper-parameters, what parameters to sample overThe sampler parameters,`TheJoker`

: how many prior samples to generate, etc.

Here we’ll work through a simple example to generate samples for orbital
parameters for some sparse, pre-generated data (shown below). We’ll first turn
these data into a `RVData`

object:

```
>>> from thejoker.data import RVData
>>> import astropy.units as u
>>> t = [0., 49.452, 95.393, 127.587, 190.408]
>>> rv = [38.77, 39.70, 37.45, 38.31, 38.31] * u.km/u.s
>>> err = [0.184, 0.261, 0.112, 0.155, 0.223] * u.km/u.s
>>> data = RVData(t=t, rv=rv, stddev=err)
>>> ax = data.plot()
>>> ax.set_xlim(-10, 200)
>>> ax.set_xlabel("Time [day]")
>>> ax.set_ylabel("RV [km/s]")
```

(Source code, png)

We next need to specify some hyper-parameters for *The Joker*. At minimum, we
have to specify the minimum and maximum period to consider:

```
>>> from thejoker.sampler import JokerParams
>>> params = JokerParams(P_min=8*u.day, P_max=512*u.day)
```

Finally we can create the sampler object and run:

```
>>> from thejoker.sampler import TheJoker
>>> joker = TheJoker(params)
>>> samples = joker.rejection_sample(data, n_prior_samples=65536)
```

Of the 65536 prior samples we considered, only a handful pass the rejection
sampling step of *The Joker*. Let’s visualize the surviving samples in the
subspace of the period \(P\) and velocity semi-amplitude \(K\). We’ll
also plot the true values as a green marker. As a separate plot, we’ll also
visualize orbits computed from these posterior samples (check the source code
below to see how these were made):