This is the Python module that has the FITS reader (and writer).


In [23]:
import pyfits
# some configuration for plotting the way I like it. Should really put this
# into my general config file.
%pylab qt
rcParams['image.interpolation'] = 'nearest'
rcParams['image.cmap'] = 'gray'
rcParams['image.aspect'] = 'auto'


Populating the interactive namespace from numpy and matplotlib

Reading in filenames that are fits

For the run scan5 we forgot to rename the filenames, so the data files are still called limb-xxx (from the run scan4) even so the data is from the Hermite crater, taken with the prism (in contrast to the grate we used for scan3 on day 1.)

going to scan5 for now.


In [17]:
fitsfiles = !ls /Users/maye/data/irtf/guidedog/scan4/fname*.fits

In [18]:
def read_scan1(fname):
    data = pyfits.getdata(fname, 0)
    return data[248:394, :]

Moon master

Above shape is the shape of one spectral image. Now reading in all data into a 3D cube. The on_moon data goes until image number 104.


In [19]:
pyfits.getheader(fitsfiles[0])['TIME_OBS']


Out[19]:
'15:01:49.910650'

In [40]:
data = pyfits.getdata(fitsfiles[10])

In [41]:
from scipy.ndimage import median_filter
filtered = median_filter(data, 2)

In [42]:
imshow(filtered, vmax=2000)


Out[42]:
<matplotlib.image.AxesImage at 0x119101ad0>

In [26]:
hist(data.flatten(), 50, log=True)


Out[26]:
(array([  1.00000000e+00,   4.00000000e+00,   2.20708000e+05,
          3.29870000e+04,   6.96300000e+03,   1.27700000e+03,
          1.01000000e+02,   1.20000000e+01,   1.00000000e+01,
          8.00000000e+00,   4.00000000e+00,   6.00000000e+00,
          3.00000000e+00,   3.00000000e+00,   4.00000000e+00,
          5.00000000e+00,   6.00000000e+00,   5.00000000e+00,
          2.00000000e+00,   2.00000000e+00,   1.00000000e+00,
          2.00000000e+00,   1.00000000e+00,   4.00000000e+00,
          1.00000000e+00,   1.00000000e+00,   6.00000000e+00,
          1.00000000e+00,   1.00000000e+00,   2.00000000e+00,
          1.00000000e+00,   1.00000000e+00,   2.00000000e+00,
          0.00000000e+00,   1.00000000e+00,   3.00000000e+00,
          2.00000000e+00,   0.00000000e+00,   0.00000000e+00,
          1.00000000e+00,   0.00000000e+00,   1.00000000e+00,
          0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
          0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
          0.00000000e+00,   1.00000000e+00]),
 array([  -875.  ,   -537.78,   -200.56,    136.66,    473.88,    811.1 ,
          1148.32,   1485.54,   1822.76,   2159.98,   2497.2 ,   2834.42,
          3171.64,   3508.86,   3846.08,   4183.3 ,   4520.52,   4857.74,
          5194.96,   5532.18,   5869.4 ,   6206.62,   6543.84,   6881.06,
          7218.28,   7555.5 ,   7892.72,   8229.94,   8567.16,   8904.38,
          9241.6 ,   9578.82,   9916.04,  10253.26,  10590.48,  10927.7 ,
         11264.92,  11602.14,  11939.36,  12276.58,  12613.8 ,  12951.02,
         13288.24,  13625.46,  13962.68,  14299.9 ,  14637.12,  14974.34,
         15311.56,  15648.78,  15986.  ]),
 <a list of 50 Patch objects>)

In [4]:
cube = []
for fitsfile in fitsfiles:
    # fish out the image number from the filename
    nr = int(fitsfile.split('-')[1][:5])
    cube.append(read_scan1(fitsfile))
    if nr > 104:
        break
# making a contiguous C-array out of the slow list container
cube = np.array(cube)
cube.shape


Out[4]:
(50, 146, 1024)

In [ ]:

Above dimensions indicate that I have stacked 50 spectra with each 146x1024 pixels.


In [5]:
moon_master = cube.mean(axis=0)
moon_master.shape


Out[5]:
(146, 1024)

Again, the dimensions indicate the correct result that I averaged the first axis, resulting in an image with the same dimensions as each original spectral image.

Now on to some filtering.


In [6]:
from scipy.ndimage import median_filter

Moon master unfiltered


In [143]:
imshow(moon_master, aspect='auto')
colorbar(orientation='horizontal')
title('Moon master raw')
savefig('moon_master_original.png', dpi=200)

Moon master filtered


In [11]:
moon_master_filtered = median_filter(moon_master, 2)

In [12]:
imshow(moon_master_filtered, aspect='auto')
colorbar(orientation='horizontal')
title('Moon master median filter (size 2)')
savefig('hermite_master_median_filtered.png', dpi=200)

Sky master

Unfortunately, we did not take off-moon sky data for scan5. So skipping this, but leave it in, maybe for later.

Starting to read from 107 (106 might be okay as well).


In [23]:
cube = []
for fitsfile in fitsfiles:
    # fish out the image number from the filename
    nr = int(fitsfile.split('-')[1][:5])
    if nr < 107:
        continue
    cube.append(read_scan1(fitsfile))
# making a contiguous C-array out of the slow list container
sky_cube = np.array(cube)
sky_cube.shape


Out[23]:
(33, 146, 1024)

In [24]:
sky_master = sky_cube.mean(axis=0)
sky_master.shape


Out[24]:
(146, 1024)

In [145]:
imshow(sky_master, aspect='auto', vmax=20000)
colorbar(orientation='horizontal')
title('sky master, raw, clipping at 20000')
savefig('sky_master_raw.png', dpi=200)

In [26]:
# do a minimal pepper/salt filter
sky_master_filtered = median_filter(sky_master, 3)

In [144]:
imshow(sky_master_filtered, aspect='auto', vmax=20000)
colorbar(orientation='horizontal')
title('sky master, median size 3 filter, clipping at 20000')
savefig('sky_master_median_filtered.png', dpi=200)

Taking an upper limit of 20000 counts to exclude hot pixels.


In [28]:
sky_master_filtered[sky_master_filtered > 20000]= np.nan

Regions

Initially, I was subtracting the sky and only worked with the master, but Dave pointed out that it is important to keep looking at the sky data on it's own, so in the next section I do things separaed.


In [29]:
master = moon_master_filtered - sky_master_filtered

In [30]:
rcParams['image.aspect'] = 'auto'

In [31]:
imshow(master)
colorbar(orientation='horizontal')
title('Background("sky")-subtracted master')
savefig('master_subtracted.png',dpi=200)

Now, having the master, let's cut out regions.


In [32]:
master.shape


Out[32]:
(146, 1024)

In [33]:
region1 = master[:36, :]
region2 = master[37:73, :]
region3 = master[74:110, :]
region4 = master[110:,:]

In [34]:
for region in [region1,region2,region3,region4]:
    print region.shape


(36, 1024)
(36, 1024)
(36, 1024)
(36, 1024)

In [35]:
spec1 = region1.mean(axis=0)
spec2 = region2.mean(axis=0)
spec3 = region3.mean(axis=0)
spec4 = region4.mean(axis=0)

In [36]:
for i,spec in enumerate([spec1,spec2,spec3,spec4]):
    plot(spec, label=i+1)
legend(loc='best')
title('master spectra for each region')
savefig('master_spectra_in_counts.png',dpi=200)

In [37]:
rcParams['lines.linewidth'] = 1.5

Regions before subtracting.


In [14]:
moon_regions = []
moon_regions.append(moon_master_filtered[:36, :])
moon_regions.append(moon_master_filtered[37:73, :])
moon_regions.append(moon_master_filtered[74:110, :])
moon_regions.append(moon_master_filtered[110:,:])

Trying same with the raw master, to see if it has an effect...


In [115]:
moon_regions_raw = []
moon_regions_raw.append(moon_master[:36, :])
moon_regions_raw.append(moon_master[37:73, :])
moon_regions_raw.append(moon_master[74:110, :])
moon_regions_raw.append(moon_master[110:,:])

In [ ]:
# only if we have them, obviously
sky_regions = []
sky_regions.append(sky_master_filtered[:36, :])
sky_regions.append(sky_master_filtered[37:73, :])
sky_regions.append(sky_master_filtered[74:110, :])
sky_regions.append(sky_master_filtered[110:, :])

In [16]:
# these are the wavelength conversions from pixel number in the wavelegnh
waves = pd.read_excel('lucy_spectral_cal.xlsx', parse_cols=0)

In [123]:
plot(waves, moon_regions[3].mean(axis=0), label='salt/pepper filtered')
plot(waves, moon_regions_raw[3].mean(axis=0), label='raw')


Out[123]:
[<matplotlib.lines.Line2D at 0x125412090>]

In [113]:
fig, axes = subplots(nrows=2)
for i, moon_region in enumerate(moon_regions):
    axes[0].plot(waves, moon_region.mean(axis=0), 
                 label='moon{}'.format(i+1))
axes[0].set_title('Moon regions master spectra')
axes[0].legend(loc='best')
for i, sky_region in enumerate(sky_regions):
    axes[1].plot(waves, sky_region.mean(axis=0),
                 label='sky{}'.format(i+1))
axes[1].set_title('Sky regions master spectra')
axes[1].legend(loc='best')
axes[1].set_xlabel('Wavelengths [micron]')
axes[0].set_ylabel('Digital counts unscaled')
axes[1].set_ylabel('Digital counts unscaled')
savefig('moon_and_sky_separated_regions.png', dpi=200)

In [21]:
# copied from above, but axes2 removed,
# as we don't have sky data
for i, moon_region in enumerate(moon_regions):
    plot(waves, moon_region.mean(axis=0), 
                 label='moon{}'.format(i+1))
title('Hermite regions master spectra')
legend(loc='best')
xlabel('Wavelengths [micron]')
ylabel('Digital counts unscaled')
savefig('hermite_regions_spectra.png', dpi=200)

In [19]:
#sky_masters = []
#for sky in sky_regions:
#    sky_masters.append(sky.mean(axis=0))
moon_masters = []
for moon in moon_regions:
    moon_masters.append(moon.mean(axis=0))

In [125]:
fig, axes = subplots(nrows=2)
for t in [(4,3),(4,2),(4,1), (3,2), (3,1), (2,1)]:
    axes[0].plot(waves, sky_masters[t[0]-1]/sky_masters[t[1]-1],
                 label='{}/{}'.format(*t))
    axes[1].plot(waves, moon_masters[t[0]-1]/moon_masters[t[1]-1],
                 label='{}/{}'.format(*t))
axes[0].set_title('Sky regional master spectra ratios')
axes[1].set_title('Moon regional master spectra ratios')
for ax in axes:
    ax.legend(loc='best')
axes[0].set_ylim(0.8, 1.2)
axes[1].set_ylim(0.8, 1.8)
axes[1].set_xlabel("Wavelengths [micron]")
savefig('individual_moon_and_sky_ratios.png', dpi=200)

In [20]:
# copied from above, but removed sky parts
for t in [(4,3),(4,2),(4,1), (3,2), (3,1), (2,1)]:
    plot(waves, moon_masters[t[0]-1]/moon_masters[t[1]-1],
                 label='{}/{}'.format(*t))
title('Hermite regional master spectra ratios')
legend(loc='best')
xlabel("Wavelengths [micron]")
savefig('hermite_ratios.png', dpi=200)

In [132]:
fig, axes = subplots(nrows=1)
for i in range(4):
    axes.plot(waves, moon_masters[i]/sky_masters[i], label=i)
axes.legend(loc='best')


Out[132]:
<matplotlib.legend.Legend at 0x11f7adf90>

In [137]:
for i in range(0,1000, 100):
    plot(moon_master[:, i:i+100].mean(axis=1), label=i)
legend(loc='best')


Out[137]:
<matplotlib.legend.Legend at 0x126a1b950>

In [ ]: