Final GSoC Post

Wow, what a journey! It’s hard to believe that GSoC is coming to an end. This project has taken quite a few twists and turns, which I will attempt to lead you through here, but ultimately I think it has all come together into a product that will be useful for anyone in the astronomical community who is planning an observation.

Looking back on the proposal to Google Summer of Code, our original plan was to build “a simple API for retrieving signal-to-noise estimates for an arbitrary astronomical observation” – in other words, we wanted to create something which could simulate an observation given a celestial object and some telescope specifications, then return a signal to noise ratio one could expect from such an exposure. I’m happy to say that we have succeeded, though not exactly in the way we had originally imagined.

In the beginning we had envisioned this functionality taking the form of a whole new package called telescopy, but it quickly became clear that a good chunk of the work behind this already existed as an astropy affiliated package called synphot. Specifically, synphot provided the means to create the synthetic photometry we needed to evaluate the expected count rate of an observation, and therefore the exposure time/signal to noise.

Much of the first half of GSoC therefore revolved around unveiling what exactly we could use from synphot and what more we needed to code. To do this, we decided that I would write a suite of Jupyter tutorials showing how to use synphot to obtain a count rate, signal to noise ratio (SNR), and exposure time for a few example observations, which can be seen at the following links:

The conversations between me and my mentors on the development of these tutorials can be seen by browsing these pull requests (which are just made to my own github simply for the sake of following the open source philosophy).

Parts of these tutorials now exist as a pull request to astropy-tutorials, which I expect to be merged soon! All that needs to be done in that regard is to get the tutorials reviewed by one more astropy-tutorials collaborator (and for me to respond to those suggestions). When that is done, our tutorials will exist on the astropy-tutorials website to help others learn how to use synphot.

The original tutorials I wrote include SNR and exposure time calculations, which I had integrated into the synphot code on my own branch. My additions to synphot (which will not be merged – more on that later) can be seen at the PR here, where the relevant discussion on the changes can be seen by navigating to the “Conversation” tab on the same page.

Once I had written these tutorials (and after much head scratching), it became evident that my additions would live much more comfortably inside of astroplan instead of synphot, since the exposure time and SNR calculators I had written are much more relevant to planning observations (indeed, the express purpose of astroplan), than to creating synthetic photometry. So at this point I shifted gears and started thinking about how what I had written could fit into the astroplan API.

The code (and relevant tests) that I’ve written and reference to in the remainder of the write-up can be viewed by clicking this link. To be clear, everything highlighted in green/red has been added/removed by me.

In brief, the additions I’ve made to astroplan now allow it to not only give when it’s best to observe, but also for how long to observe, given a desired SNR. It sounds simple at face value, but to do this, astroplan needed to learn how to:

  1. Model an observation, which means convolving a model spectrum with:
    • a bandpass
    • CCD response function
    • atmospheric transmission
    • etc…
  2. Measure the count rate of the observation
  3. Calculate the required exposure time for the given SNR

The bandpass and CCD response function are all inherent to whatever telescope/instrument is in use, so it seemed appropriate to write a Telescope class to the new astroplan.telescope module. The Telescope object serves as a container for the specs of the observer’s instrument, where the diameter, bandpass, and gain are given by the user and set as attributes (optional attributes include the read noise and CCD response function).

The atmospheric transmission is instead inherent to the observer’s location. astroplan already has a module for the observer’s location (, but it didn’t yet include an option to model the atmospheric transmission. Enter astroplan.skymodel, a new module I’ve written which queries an atmospheric transmission model from the SkyCalc Sky Model Calculator. To obtain a sky model, the user just has to set the skymodel attribute of their Observer object, where all of the variable parameters seen on the SkyCalc page can be set as so (if none are set, skymodel just queries the default parameters seen on the SkyCalc page):

>>> from astroplan import Observer, skymodel

>>> observer = Observer.at_site('apo')
>>> observer.skymodel = skymodel(airmass=2)

Finally, I wrote the exptime module and added it to astroplan for calculating an exposure time using the Observer and Telescope objects. This module (and astroplan.telescope) require that synphot be installed, since exptime calls on synphot to convolve the spectral elements given and to calculate the subsequent count rate of the simulated observation. The expressions for actually calculating the exposure times given an idealized SNR are taken from pgs 57-58 of the trusty “Handbook of CCD Astronomy” by Howell (2000).

To see how all of this is used on the user-side of things, I have also written a tutorial to the astroplan documentation (unfortunately this can only really be seen once it’s been merged, but the code can be viewed in the /docs/tutorials/exptime.rst file).

What’s left to do:

  • Respond to suggestions on my astropy-tutorials PR
  • Submit a PR to astroquery for the SkyCalc query I wrote (permission has been granted by the maintainers of the SkyCalc Calculator)
  • Finish writing tests for astroplan.exptime
  • Get suggestions from collaborators on any changes that should be made to my astroplan additions
  • Get merged!!!

I have learned SO MUCH as a GSoC student, and am really grateful to have been a part of it. I can confidently say that I’ve become a better programmer thanks to all of the excellent advice from my GSoC mentors. You all are the best! I look forward to contributing to astropy in the future and hope to run into you soon!

Week 13: Hello from Reykjavik!

What I completed this week:

  • Moved basically all of the stuff I’ve been exploring with synphot over to astroplan, which in hindsight makes more sense! In brief, this is what I did:
    • Added a new module to astroplan, which uses synphot to calculate the exposure time needed to obtain a given signal to noise ratio. Even though it uses synphot, it is not a required package of astroplan unless the user wants to use exptime_from_ccd_snr
    • Added a new class called Telescope which carries information about the instrument the observer is using, such as the bandpass, gain, read noise, and CCD response function.
    • Added a new module which has a function to query the SKYCALC Sky Calculator for optional modeling of atmospheric transmission
  • Wrote a tutorial for using astroplan to calculate exposure time, which you can see here
I’m in Iceland this week for the 4th Extreme Solar Systems conference! Which is appropriate, because Iceland has what is closest to an alien landscape that I can imagine.

This week’s goals:

  • Write tests for the new functionality in astroplan
  • Add examples to the astroplan documentation
    • I think I’ll just copy and paste my Jupyter notebook tutorial into something Sphinx will display nicely
    • Add a reference to the exptime example mentioned above to the “getting started” part of a documentation. I originally wanted to add a simple 1-2 line example to “getting started”, but since you have to model the spectrum of the target and all that I think it would be more appropriate to just keep the example on its own page
  • Write my final blog post, which will summarize everything I’ve done and serve as my “code submission” in the final evaluation!

Week 12: astroplanning

What I completed this week:

  • Submitted my synphot tutorials as a pull request to astropy/astropy-tutorials. Just waiting for someone (outside of my GSoC mentors) to review!
  • Moved my synphot work (including the wrapper and signal-to-noise functions) into an experimental folder. I’m still uncertain whether this folder will be merged as an experimental folder or if its contents will be merged back into the synphot API, but I guess we will see..! Also, I’m still open to suggestions on any other functionality I should include.
  • Emailed ESO inquiring about any plans to merge skycalc_cli into astroquery, and if they would be open to me submitting a PR (no response yet).
  • Thought more about how my wrapper, signal-to-noise functions, and “synspec” can be implemented into already-existing astronomical observing tools. Simply put, I think my GSoC work (and synphot in general) would serve as valuable additions to astroplan. As it stands, astroplan is a great tool for scheduling observations, but its definition leaves its functionality open to aspects of planning which are outside of the scheduling realm:

The goal of astroplan is to make a flexible toolbox for observation planning and scheduling. 

The astroplan Documentation

Specifically, I think a count rate function and exposure time calculator would be of greatest use. Then not only could astroplan help determine when to observe, it could also suggest exposure durations given model photometric/spectroscopic observations generated by synphot/synphot tools.

I also took a weekend trip with my family to go rafting on the Yakima river (pictured here). And I fed a cow. Its tongue was disturbingly pokey.

This week’s goals:

  • If everyone is open to the idea, I would like to submit a PR to astroplan for adding the exposure time calculator (supported by synphot and its tools)

Week 11: A wrapper says its first word

What I completed this week:

  • Continued working on the synphot wrapper class, which we’ve renamed “Exposure” (since “Observe” is a little too close to the other synphot class “Observation”). So far this class works pretty much like how I imagined it last week, where the most simple (read: default) synthetic observation can be initiated given a source spectrum, telescope diameter, and exposure time:
>>> from synphot.spectrum import SourceSpectrum
>>> from synphot.exposure import Exposure
>>> import astropy.units as u

>>> source_spec = SourceSpectrum(...)
>>> tele_diameter = 1 * u.m
>>> exptime = 1 * u.s

>>> some_observation = Exposure(source_spec, tele_diameter, exptime)

Then attributes can be called and methods applied to view some characteristics of this observation, such as the count rate, signal to noise ratio (SNR), and the exposure time needed to obtain a specified SNR:

>>> some_observation.aperture_area
<Quantity 0.78539816 m2>

>>> some_observation.countrate
<Quantity 126398.52488845 ct / s>

>>> some_observation.snr()
<Quantity 355.52570215>

>>> desired_snr = 100
>>> some_observation.required_exptime(desired_snr)
<Quantity 0.07911485 s>
I also took a little break to see family and go “tubing”, as seen above (wee)

This week’s goals:

  • Finish the wrapper! Now taking suggestions for anything else I should include
  • Take a look at telescopy and astroplan and think how they, along with synspec and any higher order functions we come up with, can be merged (okay, I really need to do this one this week)

Longer term goals: