Category Archives: Uncategorized

Sun projector for Princeton Communiversity

There’s a big street fair today in Princeton. To add a science outreach presence to the event, my officemate, Mike Heppler, and I teamed up yesterday to build a simple projecting refractor telescope out of surplus optics and cardboard. It works surprisingly well, and we hope to show many people today their first (and safe!) view of the Sun’s surface. More photos, and complete instructions to build your own cheap sun projector will be posted here soon!


archival search for secondary stars

This week I’ve continued the task of assembling new targets for ESPRI. We require a “secondary” or “reference” star next to each star that we survey for planets. That way, if the target star hosts a giant planet, then the secondary star serves as the reference point by which we can measure the orbit recoil motion.


Even though the secondary is next to the target star on the sky, in most cases the alignment is only an illusion, and it is actually at a great physical distance in the background.

To look for secondary stars, I’m using public data archives to dig up images already taken of our target candidates. In the case above, I happened to find two useful archive images of the same target. There’s a strong difference in image quality between the two, mostly because they were made with different sized telescopes. The one on the left was taken with the 4-meter VISTA observatory, while the one on the right was taken with the 1.3-meter, southern 2MASS telescope. It’s the same wavelength however, the near-infrared K band.

Sometimes, this kind of difference in quality (in terms of angular resolution and dynamic range) makes the difference between spotting a secondary star and missing it. Below is an example of a target for which the better VISTA image reveals the star, while it is completely lost in the 2MASS data. The two images are matched in terms of spatial scale on the sky.


The downside of the VISTA’s archive, however, is that it doesn’t cover the entire sky. The VISTA observing teams just haven’t gotten around to capturing all the stars, even though that is one of their goals. So in practice we are forced to look across several archives to pick out the best images available.

Deformable mirror command visualization

Deformable mirror command visualization

I wrote a python/matplotlib script to visualize the command I send to our deformable mirror in terms of voltage applied to the bimorph electrodes. We want to avoid using too much stroke to compensate for the rest state trifoil figure. The max/min voltage is +/- 400 V. From this plot, it’s clear that only the outer actuator ring is a concern, where we use upwards of 100 V in some cases to achieve the flattened figure I showed a few weeks ago.

a new target list for ESPRI

The ESPRI team that I am part of at MPIA aspires to detect exoplanets based on the orbital recoil motion of their host stars. These are the “wobbles” like the ones our own Sun traces out due to the gravitational tug from the planets in the solar system. There are severe engineering obstacles to making this work: the extremely small angular scale of the star’s wobble as projected onto the sky, combined with relentless distortion of starlight traveling through our turbulent atmosphere. To detect a statistically meaningful population of gas giant planets by astrometry, we need to measure the position of stars so precisely that our uncertainty, in terms of angle on the celestial sphere, is less than 50 microarcseconds on each night we look. Even then, only after 2 years or more of data collecting can the signature of a planet’s orbit jump out of the data.

Over the last decade, the PRIMA instrument team, based at the European Southern Observatory, has made progress towards this formidable technological goal. How this machine works is a story for another day. But the ESPRI team (it stands for Exoplanet Survey with PRIMA) is leading the plan to make the best of use of PRIMA’s exoplanet science potential, once the instrument reaches its challenging performance specs.

There is competition on the way, however. Gaia, a satellite dedicated to high-precision astrometry, will launch into orbit within a year. Unhindered by Earth’s atmosphere, Gaia will achieve 20 microarcsecond astrometry precision for millions of stars over a five-year mission period. It was designed to answer questions about the structure and dynamical history of the Milky Way galaxy, but as a by-product, it will also uncover hundreds of gas giant planets orbiting nearby stars. Therefore, in planning our own target list, the ESPRI team is forced to ask the question, ‘What will Gaia not be able to do?’

The short answer is, the bright stars. Gaia’s detectors can only handle a certain range of brightness. So as not to lose out on many distant, faint stars, the designers of Gaia trade off sensitivity for the brightest ones. According to the official specs, stars of about 6th magnitude or brighter will overwhelm the detectors. This means that despite Gaia’s superb precision and total sky coverage, the recoil orbital motion of many stars will still be up for grabs. Furthermore, these stars are compelling for another reason. Tending to be nearby, their planetary systems will be the ones we can explore in greatest detail in the future with a suite of complementary techniques. Exciting follow-up observations will be possible with next generation, giant telescopes and satellite observatories, directly imaging the planets and measuring the colors and spectra of their atmospheres.

We’re also keeping in mind the stars that are left behind by another exoplanet discovery powerhouse, the radial velocity programs now based at large ground-based observatories. For a few scientific and technical reasons, these radial velocity surveys tend to concentrate on stars with mass near the same as the Sun, excluding the slightly larger ones.

Taking these facts together, ESPRI’s planet-hunting advantage boils down to a list of nearby and bright stars, with mass around 1.5 to 2.5 times that of the Sun (spectral types A and F). In the last week I’ve written scripts to dig through catalogs to find stars fitting our criteria: too bright for Gaia, the right color (since color tells us mass) and distance. This is complicated by the special needs of our instrument. We can’t deal with close double star systems, and we have to be careful to include only stars that have the right combination of mass and distance such that a planet orbiting it would cause a wobble big enough for our instrument to perceive.

The plot below visualizes a the process of elimination of target candidates from 795 to 222, after taking into account all the information culled from the astronomical databases. The vertical axis corresponds to brightness and the horizontal axis is color. The blue dots are the “survivors” that we will look at more closely to consider as ESPRI targets.


Flattening a deformable mirror

In the AO lab here at MPIA, we are building and testing a near-infrared wave front sensor for the four 8-meter VLT telescopes, to be used for long-baseline interferometry projects like GRAVITY.

My role is to characterize and calibrate the deforming element on our test bench, the MACAO 60-actuator bimorph mirror.

In the fall, after connecting ESO’s spare DM to its electronics rack and aligning a pupil shearing interferometer, we could clearly see the whopping trefoil figure of the mirror surface, caused by expected mounting stresses. The peak-to-valley of the trefoil is over 4 waves @ lambda = 633 nm.


In order to measure the actuator influence functions and make a first attempt at building the control matrix, we needed to first flatten the figure. After a few software tricks failed, Stefan suggested we go through the actuators step by step, wiping out the bumps by trial and error.

To my surprise, this approach worked well. Below is the result after about a day’s worth of poking and tweaking half of the 60 electrodes. The surface RMS is now down to 0.03 waves, and the peak-to-valley is near 0.3 waves (overestimated in the diagram’s color bar due to some erroneous edge points). With this offset command in place, the surface is flat enough that we can begin measuring the influence functions, and form a working control matrix.Image

coding KLIP

Here I rewrite the recipe of the KLIP PSF-subtraction algorithm by Soummer & Pueyo & Larkin (2012) in vector form — less of the confusing indices and easier to code:

  • Assemble the reference images into matrix \mathbf{R}, containing K rows, each one a reference image vector of length N pixels. Subtract the mean of each image vector (row) from itself.
  • Get the eigendecomposition of \mathbf{R} \mathbf{R}^T. This yields the ranked eigenvalue vector \mathbf{\Lambda}, and corresponding eigenvectors as rows of the KxK matrix \mathbf{V}.
  • Divide each (kth) row of \mathbf{V} by its singular value, \sqrt{\lambda_k}, call this new matrix \mathbf{V'}.
  • The principle component basis, \mathbf{Z} (dim. KxN), is formed by a transformation of \mathbf{R} (S&P&L eq 5): \mathbf{Z} = \mathbf{V'R}. The kth row of \mathbf{Z} is the kth principal component of the reference data matrix \mathbf{R}.
  • Choose K_{\rm KLIP} principal components to retain. The truncated basis, \mathbf{Z}_{\rm KL} (with K_{\rm KLIP} \le K rows) is the new K-L basis for describing the PSF.
  • To form the PSF estimate, \mathbf{\hat{I}}, project the target row vector \mathbf{T} (dim. 1xN) onto the K-L basis (S&P&L eq 8): \mathbf{\hat{I}} = \mathbf{T} \mathbf{Z}_{\rm KL}^T \mathbf{Z}_{\rm KL}. This last step is by far the most time- and memory-consuming part, because of the large NxN operand.

and here’s a python implementation:

def get_klip_basis(R, cutoff):
    w, V = np.linalg.eig(, np.transpose(R)))
    sort_ind = np.argsort(w)[::-1] #indices of eigenvals sorted in descending order
    sv = np.sqrt(w[sort_ind]).reshape(-1,1) #column of ranked singular values
    Z =*np.transpose(V[:, sort_ind]), R)
    return Z[0:cutoff, :], sv

python/numpy tip: form an image mask based on compound logic

Here’s an example of an easy way to form a pixel-wise image mask based on a compound logical condition, using numpy’s where routine. In this example, img is your 2-d image array:

mask_logic = np.array([np.not_equal(img, badval).flatten(),
                       np.less_equal(img, thresh).flatten()])
img_mask = np.where(np.all(mask_logic, axis=0), np.ones(mask_logic.shape[1]),

Numpy’s all implements the “AND” condition; to do a logical “OR”, use the similar any routine.