# Python program to load a FITS spectrum and display it

# import needed extensions
from numpy import *
import pyfits
import matplotlib.pyplot as plt # plotting package
import matplotlib.cm as cm # colormaps
from matplotlib.colors import LogNorm
from scipy.interpolate import interp1d


# calibration
centralp, centralw, slope = 1000.00, 480.00, 1.00000


plt.ion() # do plots in interactive mode

# read in the spectrum image file for the calibration star
# change the file names as appropriate
stdfile = pyfits.open('std1.fits')
# copy the image data into a numpy (numerical python) array
stdimg = stdfile[0].data

# calculate a spectrum
# y0 is the center of the band over which the spectrum is extracted
y0 = 94
# dy sets the width of the band (y0-dy to y0+dy)
dy = 7
# figure out dimensions of spectrum image
(ny, nx) = shape(stdimg)
# find a 1-d spectrum by integrating across the band
std = zeros(nx)
for i in range(nx):
  std[i] = sum(stdimg[(y0-dy):(y0+dy+1), i])

# calculate the wavelength for each bin
p = 1+arange(len(std)) # pixel numbers
w = centralw + slope*(p-centralp) # wavelengths
# change the wavelength to Angstroms
w = w*10.0

# keep only data at wavelengths 3500-6000 Ang
q = where((w >= 3500.0) & (w < 6000.0))
w, std = w[q], std[q]

# plot the spectrum versus wavelength
plt.figure(1)
plt.clf()
plt.xlabel('Wavelength (Ang)')
plt.ylabel('Counts')
plt.yscale('log')
#plt.axis([0, 750, 0, 1E5])
plt.plot(w, std, '-b')

# read in the reference spectrum from Hamuy 1992
# variables are wavelength, flux, flux in Janksy, bin width
rw, rf, rfj, rb = transpose(genfromtxt('feg274.dat'))

# plot the reference spectrum for comparison
# first normalize the reference spectrum
norm = max(std)/max(rf)
plt.plot(rw, norm*rf, '--r')

# now we wish to use the Hamuy reference spectrum to calculate a 
# conversion factor to apply to our measured spectra in order to
# convert them to physical units
# create a function that returns the reference flux at any wavelength
rfi = interp1d(rw, rf) 
# find reference flux in the bins of the measured spectrum
rfb = rfi(w)
# find the conversion factor
conv = rfb/std

# plot the conversion factor versus wavelength
plt.figure(2)
plt.clf()
plt.xlabel('Wavelength (Ang)')
plt.ylabel('Conversion')
#plt.axis([0, 750, 0, 1E5])
plt.plot(w, conv, '-b')


# read in the spectrum image file for the target star
# change the file names as appropriate
stdfile = pyfits.open('s.fits')
# copy the image data into a numpy (numerical python) array
simg = stdfile[0].data

# calculate a spectrum of the target
# y0 is the center of the band over which the spectrum is extracted
y0 = 61
# dy sets the width of the band (y0-dy to y0+dy)
dy = 7
# figure out dimensions of spectrum image
(ny, nx) = shape(simg)
# find a 1-d spectrum by integrating across the band
s = zeros(nx)
for i in range(nx):
  s[i] = sum(simg[(y0-dy):(y0+dy+1), i])


# calculate a sky background spectrum
# y0 is the center of the band over which the spectrum is extracted
y0 = 81
# dy sets the width of the band (y0-dy to y0+dy)
dy = 7
# figure out dimensions of spectrum image
(ny, nx) = shape(simg)
# find a 1-d spectrum by integrating across the band
b = zeros(nx)
for i in range(nx):
  b[i] = sum(simg[(y0-dy):(y0+dy+1), i])

# subtract the sky background from the spectrum
ss = s-b

# keep only data at wavelengths 3500-6000 Ang
q = where((w >= 3500.0) & (w < 6000.0))
w, s, b, ss = w[q], s[q], b[q], ss[q]

# plot the spectrum versus wavelength
plt.figure(3)
plt.clf()
plt.xlabel('Wavelength (Ang)')
plt.ylabel('Counts')
plt.yscale('log')
#plt.axis([0, 750, 0, 1E5])
plt.plot(w, s, '-b') # source spectrum
plt.plot(w, b, '-r') # background spectrum
plt.plot(w, ss, '-k') # source with sky subtracted


# convert the spectrum into physical units
sc = ss*conv
# plot the corrected spectrum versus wavelength
plt.figure(4)
plt.clf()
plt.xlabel('Wavelength (Ang)')
plt.ylabel('Flux ()')
#plt.yscale('log')
#plt.axis([0, 750, 0, 1E5])
plt.plot(w, sc, '-b')



