Often-times, the model spectrum is just not good enough to get an adequate fit using the normal Fitters.RVFitter. When that is the case, the automated flattening just doesn't work. Let's give this a shot without using models. The thing we want to minimize is the offset between the flux at one order and the flux in the adjacent order.
$$L = \sum_{i=1}^{N_{orders}-1} \left(\frac{O_i(\lambda)}{M(i, \lambda| \Theta)} - \frac{O_{i+1}(\lambda)}{M(i+1, \lambda | \theta)}\right)^2 $$Where $M(i, \lambda | \theta)$ is perhaps a 2d polynomial function of some order where $i$ is for the order number, $\lambda$ is the wavelength (or maybe pixel number?), and the $\theta$ are all the polynomial coefficients.
Try using Robust Linear Models from statsmodels. That might help it to ignore the big Balmer line. I will need to put the Chebyshev factors into a feature vector to use this...
Those might help a bit. How about a hybrid approach where I divide by a stellar model (or empirical spectrum of similar type as Adam suggests), and then do a full robust 2D fit.
I was able to sufficiently flatten a few of my spectra to get RV fits. I need to calibrate the RV though, so pretty much need to flatten every spectrum and fit the RV. This will take a while...
In [1]:
import SpecFlattener
import glob
import StarData
from astropy.io import fits
import SpectralTypeRelations
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
In [2]:
#hdf5_lib = '/media/ExtraSpace/Kurucz_FullGrid/CHIRON_grid_full.hdf5'
hdf5_lib = '/Volumes/DATADRIVE/Kurucz_Grid/IGRINS_grid_full.hdf5'
star_list = [f for f in glob.glob('../201*/*corrected.fits') if 'flattened' not in f and 'oph' not in f.lower() and 'HER' not in f]
print(len(star_list))
#star_list.index('../20131019/HIP_22913.fits')
for s in star_list:
print s
In [3]:
# Guess stellar properties
MS = SpectralTypeRelations.MainSequence()
def guess_teff_logg(fname):
header = fits.getheader(fname)
data = StarData.GetData(header['OBJECT'])
spt = data.spectype
teff = MS.Interpolate('Temperature', spt)
logg = 3.5 if 'I' in spt else 4.0
return teff, logg
In [4]:
teff, logg = guess_teff_logg(star_list[0])
print(teff, logg)
In [6]:
# Read in flat lamp spectrum (it is not flat!)
from scipy.interpolate import InterpolatedUnivariateSpline as spline
import numpy as np
out = np.loadtxt('../plp/flat_lamp.txt', unpack=True)
wvl, fl = out[:, 0], out[:, 1]
flat = spline(wvl, fl)
In [7]:
import HelperFunctions
orders = HelperFunctions.ReadExtensionFits(star_list[2])
import matplotlib.pyplot as plt
%matplotlib notebook
#nums = tuple(range(5, 16)) + tuple(range(18, 26))
nums = range(3, 18)
#for order in orders[4:25]:
n_left, n_right = 250, 100
good_orders = [o[n_left:-n_right].copy() for i, o in enumerate(orders) if i in nums]
for order in good_orders:
plt.plot(order.x, order.y, 'k-', alpha=0.5)
plt.plot(order.x, order.y*flat(order.x), 'r-', alpha=0.5)
In [9]:
reload(SpecFlattener)
print(len(nums))
output = SpecFlattener.flatten_spec(star_list[2], hdf5_lib, teff=teff, logg=logg, normalize_model=False,
ordernums=nums, x_degree=4, orders=good_orders)
final_orders, flattened, shifted_orders, mcf = output
In [42]:
%matplotlib notebook
for order in final_orders:
plt.plot(order.x, order.y, 'k-', alpha=0.5)
In [ ]: