Tuesday, May 31, 2016

Blog purpose update

The blog posts I've made in the past couple weeks have the following purpose:

Sometimes when I am working on a technical issue in my research, I'll google some general keywords and hope a solution comes up. These blog posts have been intended to address specific solutions to the problems I encountered, such that they would have been helpful when I first encountered the issue and googled them.

Right now I'm not blogging for a wide readership, but if something you find here is helpful, I'm glad.

print more source code in the IPython debugger

This hardly deserves its own post, but I was doing some IPython debugging and wanted to see a little bit more source code than the few lines of context that it showed me by default. It turns out you can type "list" at the debugger prompt to see more.

Friday, May 27, 2016

How to manually extract the flux (in Jy) from a datacube of flux density (in Jy/beam)

I'm working with interferometric data from NOEMA. I have a datacube with intensity values that are in the units of "Jy/beam" (janskys per beam). My goal was to extract the flux (in regular janskys, or Jy) corresponding to the central source in these observations. This involved two hang-ups:

1. Selecting the pixels corresponding to the clean beam shape and size
2. Correctly calculating the beam area to match convention and get the proper number of janskys out.

I'm pretty sure that tools like CASA and gildas/mapping have already figured this stuff out, but for my purposes I wanted to extract the flux using my own tooling so that I could have more control (and have it be more reproducible); additionally, I'm not familiar enough with CASA or gildas to know where to start.

For issue #1, I needed to figure out how to select a rotated ellipse with major/minor axes corresponding to my beam. I found this math-stackexchange post super helpful in getting the Cartesian coordinates defining such an ellipse:

http://math.stackexchange.com/questions/426150/what-is-the-general-equation-of-the-ellipse-that-is-not-in-the-origin-and-rotate

In the following code snippet, you can see how I pulled this off:

For Issue #2, I needed to know how exactly the beam area was defined, which wasn't obvious. I was told (by gildas/mapping and by the FITS header of my datacube) that the beam major and minor FWHM were 1.9 and 1.0 arcseconds, respectively. But what ellipse, exactly, defines the beam area? Is it the ellipse with major and minor axes equal to the FWHM listed previously, or was it an ellipse that used Gaussian sigmas as its major and minor axes? A FWHM and a Gaussian sigma (or "c") differ by the following factor:

so the impact on the area calculation could be fairly large.

Guided by the following astropy documentation page:
http://docs.astropy.org/en/stable/api/astropy.units.equivalencies.brightness_temperature.html
I concluded that it was the ellipse with this area:
>>> bmaj = 15*u.arcsec
>>> bmin = 15*u.arcsec
>>> fwhm_to_sigma = 1./(8*np.log(2))**0.5
>>> beam_area = 2.*np.pi*(bmaj*bmin/fwhm_to_sigma**2)
(where I assume 'bmaj' and 'bmin' are the FWHM of the beam).
In the above example, there is a typo in the last line (already noted here: https://github.com/astropy/astropy/pull/4766 and ready to be fixed in the next astropy release) where the fwhm_to_sigma factor should be multiplied, not divided.

This page is probably also super helpful:
https://www.cv.nrao.edu/course/astr534/Interferometers2.html
especially this bit:

The beam solid angle of a Gaussian beam with HPBW 0 is

A=024ln2 



Ultimately I chose to extract flux corresponding to a "three-sigma" ellipse around the source, in order to capture the whole beam's flux.

I confirmed that my conversion was correct by looking at the integrated flux of a bright line in the "go view" mapping tool and comparing it to the integrated flux that I computed.
Blue: integrated flux (Jy) over the whole source size. Green: flux density (Jy/beam) at the central pixel.
gildas/mapping, showing basically the same as above, except that here the integrated flux is from a rectangular selection (the zoom window) rather than a more careful ellipse.



Wednesday, May 25, 2016

How to export a NOEMA datacube into FITS

This is a post to demonstrate how I got a spectrum from NOEMA (formerly PdBI) interferometry to export to FITS.

I have my data located in the following directory:

directory:
/Users/tsrice/Documents/Data/NOEMA/W15AI/maps

file:
l1455irs1_WIDEX.lmv-clean

$ mapping
MAPPING> fits widex_clean_cube.fits from l1455irs1_WIDEX.lmv-clean

I then load it into Python (in a pylab/IPython environment) like this, with astropy:

In [19]: widex_clean_cube, widex_clean_header = astropy.io.fits.getdata("widex_clean_cube.fits", header=True)

Wednesday, May 18, 2016

How to get a NOEMA spectrum to load in CLASS

This is a post to demonstrate how I got a spectrum from NOEMA (formerly PdBI) interferometry to load into CLASS.

I have my data located in the following directory:

directory:
/Users/tsrice/Documents/Data/NOEMA/W15AI/maps

file:
l1455irs1_WIDEX.lmv-clean

then I did this in CLASS, from the "maps" directory:
$ class
LAS >
file out mycube.bin single
lmv l1455irs1_WIDEX.lmv-clean
file in mycube.bin

! this makes a box 2'' x 2'' to extract spectra from:
set match 2
find /offset 0 0

set weight equal
average /nocheck position

plot


I learned this from the following page (102):

in this tutorial:

I have bothered with all of these steps in order to get WEEDS to work on a NOEMA spectrum.