def makeTelluricModel(lsf, alpha, flux_offset, wave_offset0, data=data):
	"""
	Make a telluric model as a function of LSF, alpha, and flux offset.
	"""
	data2               = copy.deepcopy(data)
	data2.wave          = data2.wave + wave_offset0
	#data2.wave          = data2.wave * (1 + wave_offset1) + wave_offset0
	telluric_model      = nsp.convolveTelluric(lsf, data2, alpha=alpha)

	if data.order == 35:
		from scipy.optimize import curve_fit
		data_flux_avg = np.average(data2.flux)
		popt, pcov = curve_fit(nsp.voigt_profile,data2.wave[0:-10], data2.flux[0:-10], 
			p0=[21660,data_flux_avg,0.1,0.1,0.01,0.1,10000,1000], maxfev=10000)
		#model               = nsp.continuum(data=data2, mdl=telluric_model, deg=2)
		model = telluric_model
		max_model_flux      = np.max(nsp.voigt_profile(data2.wave, *popt))
		model.flux         *= nsp.voigt_profile(data2.wave, *popt)/max_model_flux
		model               = nsp.continuum(data=data2, mdl=model, deg=2)
	else:
		model               = nsp.continuum(data=data2, mdl=telluric_model, deg=2)
	
	model.flux             += flux_offset

	return model
示例#2
0
	def bestParams2(theta, data):

		i, alpha, c2, c0, c1 = theta 
		data2                = copy.deepcopy(data)
		data2.wave           = data2.wave*c1 + c0
		telluric_model       = nsp.convolveTelluric(i, data2, alpha=alpha)
		model                = nsp.continuum(data=data2, mdl=telluric_model)
		return np.sum(data.flux - (model.flux + c2))**2
示例#3
0
	def bestParams(data, i, alpha, c2, c0):

		data2          = copy.deepcopy(data)
		data2.wave     = data2.wave + c0
		telluric_model = nsp.convolveTelluric(i, data2, alpha=alpha)
		model          = nsp.continuum(data=data2, mdl=telluric_model)
		#plt.figure(2)
		#plt.plot(model.wave, model.flux+c2, 'r-', alpha=0.5)
		#plt.plot(data.wave*c1+c0, data.flux, 'b-', alpha=0.5)
		#plt.close()
		#plt.show()
		#sys.exit()
		return model.flux + c2
示例#4
0
def getLSF2(telluric_data, continuum=True, test=False, save_path=None):
	"""
	Return a best LSF value from a telluric data.
	"""
	
	data = copy.deepcopy(telluric_data)

	def bestParams(data, i, alpha, c2, c0):

		data2          = copy.deepcopy(data)
		data2.wave     = data2.wave + c0
		telluric_model = nsp.convolveTelluric(i, data2, alpha=alpha)
		model          = nsp.continuum(data=data2, mdl=telluric_model)
		#plt.figure(2)
		#plt.plot(model.wave, model.flux+c2, 'r-', alpha=0.5)
		#plt.plot(data.wave*c1+c0, data.flux, 'b-', alpha=0.5)
		#plt.close()
		#plt.show()
		#sys.exit()
		return model.flux + c2

	def bestParams2(theta, data):

		i, alpha, c2, c0, c1 = theta 
		data2                = copy.deepcopy(data)
		data2.wave           = data2.wave*c1 + c0
		telluric_model       = nsp.convolveTelluric(i, data2, alpha=alpha)
		model                = nsp.continuum(data=data2, mdl=telluric_model)
		return np.sum(data.flux - (model.flux + c2))**2

	from scipy.optimize import curve_fit, minimize

	popt, pcov = curve_fit(bestParams, data, data.flux, p0=[4.01, 1.01, 0.01, 1.01], maxfev=1000000, epsfcn=0.1)

	#nll = lambda *args: bestParams2(*args)
	#results = minimize(nll, [3., 1., 0.1, -10., 1.], args=(data))
	#popt = results['x']

	data.wave      = data.wave+popt[3]

	telluric_model = nsp.convolveTelluric(popt[0], data, alpha=popt[1])
	model          = nsp.continuum(data=data, mdl=telluric_model)

	#model.flux * np.e**(-popt[2]) + popt[3]
	model.flux + popt[2]

	return popt[0]
示例#5
0
def getFringeFrequecy(tell_data, test=False):
	"""
	Use the Lomb-Scargle Periodogram to identify 
	the fringe pattern.
	"""
	tell_sp  = copy.deepcopy(tell_data)

	## continuum correction
	tell_sp  = nsp.continuumTelluric(data=tell_sp, order=tell_sp.order)

	## get a telluric model
	lsf      = nsp.getLSF(tell_sp)
	alpha    = nsp.getAlpha(tell_sp,lsf)
	tell_mdl = nsp.convolveTelluric(lsf=lsf,
		telluric_data=tell_sp,alpha=alpha)

	## fit the fringe pattern in the residual
	pgram_x = np.array(tell_sp.wave,float)[10:-10]
	pgram_y = np.array(tell_sp.flux - tell_mdl.flux,float)[10:-10]
	offset  = np.mean(pgram_y)
	pgram_y -= offset
	mask    = np.where(pgram_y - 1.5 * np.absolute(np.std(pgram_y)) > 0)
	pgram_x = np.delete(pgram_x, mask)
	pgram_y = np.delete(pgram_y, mask)
	pgram_x = np.array(pgram_x, float)
	pgram_y = np.array(pgram_y, float)

	#f = np.linspace(0.01,10,100000)
	f = np.linspace(1.0,10,100000)

	## Lomb Scargle Periodogram
	pgram = signal.lombscargle(pgram_x, pgram_y, f)

	if test:
		fig, ax = plt.subplots(figsize=(16,6))
		ax.plot(f,pgram, 'k-', label='residual',alpha=0.5)
		ax.set_xlabel('frequency')
		plt.legend()
		plt.show()
		plt.close()

	return f[np.argmax(pgram)]
示例#6
0
def fringeTelluric(data):
    """
    Model the fringe pattern for telluric data.
    
    Note: The input data should be continuum corrected 
    before using this function.
    """
    lsf = nsp.getLSF(data)
    alpha = nsp.getAlpha(data, lsf)
    tell_mdl2 = nsp.convolveTelluric(lsf=lsf, telluric_data=data, alpha=alpha)

    pgram_x = np.array(data.wave, float)[10:-10]
    pgram_y = np.array(data.flux - tell_mdl2.flux, float)[10:-10]
    offset = np.mean(pgram_y)
    pgram_y -= offset
    mask = np.where(np.absolute(pgram_y) - 1. * np.std(pgram_y) > 0)
    pgram_x = np.delete(pgram_x, mask)
    pgram_y = np.delete(pgram_y, mask)
    pgram_x = np.array(pgram_x, float)
    pgram_y = np.array(pgram_y, float)

    f = np.linspace(0.01, 10, 100000)

    ## Lomb Scargle Periodogram
    pgram = signal.lombscargle(pgram_x, pgram_y, f)

    freq = f[np.argmax(pgram)]

    ## initial guess for the sine fit
    amp0 = np.absolute(np.std(pgram_y))
    p0 = [freq, amp0, 0, 0]
    popt, pcov = curve_fit(sineFit, pgram_x, pgram_y, p0=p0, maxfev=100000)

    #data.wave = pgram_x
    #data.flux = np.delete(data.flux[10:-10],
    #    mask)-(sineFit(pgram_x,*popt)-popt[-1])
    #data.noise = np.delete(data.noise[10:-10],mask)
    data.flux -= (sineFit(data.wave, *popt) - popt[-1])

    return data, sineFit(data.wave, *popt) - popt[-1]
fig = corner.corner(triangle_samples, 
	labels=ylabels,
	truths=[lsf_mcmc[0], 
	alpha_mcmc[0],
	A_mcmc[0],
	B_mcmc[0]],
	quantiles=[0.16, 0.84],
	label_kwargs={"fontsize": 20})
plt.minorticks_on()
fig.savefig(save_to_path+'/triangle.png', dpi=300, bbox_inches='tight')
#plt.show()
plt.close()

data2               = copy.deepcopy(data)
data2.wave          = data2.wave + B_mcmc[0]
telluric_model      = nsp.convolveTelluric(lsf_mcmc[0], data, alpha=alpha_mcmc[0])
model, pcont        = nsp.continuum(data=data, mdl=telluric_model, deg=2, tell=True)
model.flux         += A_mcmc[0]

plt.tick_params(labelsize=20)
fig = plt.figure(figsize=(20,8))
ax1 = fig.add_subplot(111)
ax1.plot(model.wave, model.flux, c='C3', ls='-', alpha=0.5)
ax1.plot(model.wave, np.polyval(pcont, model.wave) + A_mcmc[0], c='C1', ls='-', alpha=0.5)
ax1.plot(data.wave, data.flux, 'k-', alpha=0.5)
ax1.plot(data.wave, data.flux-(model.flux+A_mcmc[0]),'k-', alpha=0.5)
ax1.minorticks_on()
plt.figtext(0.89,0.86,"{} O{}".format(tell_data_name, order),
	color='k',
	horizontalalignment='right',
	verticalalignment='center',
示例#8
0
def getAlpha(telluric_data,lsf,continuum=True,test=False,save_path=None):
	"""
	Return a best alpha value from a telluric data.
	"""
	alpha_list = []
	test_alpha = np.arange(0.1,7,0.1)

	data = copy.deepcopy(telluric_data)
	if continuum is True:
		data = nsp.continuumTelluric(data=data, order=data.order)

	for i in test_alpha:
		telluric_model = nsp.convolveTelluric(lsf,data,
			alpha=i)
		#telluric_model.flux **= i 
		if data.order == 59:
			# mask hydrogen absorption feature
			data2          = copy.deepcopy(data)
			tell_mdl       = copy.deepcopy(telluric_model)
			mask_pixel     = 450
			data2.wave     = data2.wave[mask_pixel:]
			data2.flux     = data2.flux[mask_pixel:]
			data2.noise    = data2.noise[mask_pixel:]
			tell_mdl.wave  = tell_mdl.wave[mask_pixel:]
			tell_mdl.flux  = tell_mdl.flux[mask_pixel:]

			chisquare = nsp.chisquare(data2,tell_mdl)

		else:
			chisquare = nsp.chisquare(data,telluric_model)
		alpha_list.append([chisquare,i])

		if test is True:
			plt.plot(telluric_model.wave,telluric_model.flux+i*10,
				'k-',alpha=0.5)

	if test is True:
		plt.plot(telluric_data.wave,telluric_data.flux,
			'r-',alpha=0.5)
		plt.rc('font', family='sans-serif')
		plt.title("Test Alpha",fontsize=15)
		plt.xlabel("Wavelength ($\AA$)",fontsize=12)
		plt.ylabel("Transmission + Offset",fontsize=12)
		plt.minorticks_on()
		if save_path is not None:
			plt.savefig(save_path+\
				"/{}_O{}_alpha_data_mdl.png"\
				.format(telluric_data.name,
					telluric_data.order))
		plt.show()
		plt.close()

		fig, ax = plt.subplots()
		plt.rc('font', family='sans-serif')
		for i in range(len(alpha_list)):
			ax.plot(alpha_list[i][1],alpha_list[i][0],'k.',alpha=0.5)
		ax.plot(min(alpha_list)[1],min(alpha_list)[0],'r.',
			label="best alpha {}".format(min(alpha_list)[1]))
		ax.set_xlabel(r"$\alpha$",fontsize=12)
		ax.set_ylabel("$\chi^2$",fontsize=12)
		plt.minorticks_on()
		plt.legend(fontsize=10)
		if save_path is not None:
			plt.savefig(save_path+\
				"/{}_O{}_alpha_chi2.png"\
				.format(telluric_data.name,
					telluric_data.order))
		plt.show()
		plt.close()

	alpha = min(alpha_list)[1]

	return alpha
示例#9
0
def getLSF(telluric_data, alpha=1.0, continuum=True,test=False,save_path=None):
	"""
	Return a best LSF value from a telluric data.
	"""
	lsf_list = []
	test_lsf = np.arange(3.0,13.0,0.1)
	
	data = copy.deepcopy(telluric_data)
	if continuum is True:
		data = nsp.continuumTelluric(data=data)

	data.flux **= alpha
	for i in test_lsf:
		telluric_model = nsp.convolveTelluric(i,data)
		if telluric_data.order == 59:
			telluric_model.flux **= 3
			# mask hydrogen absorption feature
			data2          = copy.deepcopy(data)
			tell_mdl       = copy.deepcopy(telluric_model)
			mask_pixel     = 450
			data2.wave     = data2.wave[mask_pixel:]
			data2.flux     = data2.flux[mask_pixel:]
			data2.noise    = data2.noise[mask_pixel:]
			tell_mdl.wave  = tell_mdl.wave[mask_pixel:]
			tell_mdl.flux  = tell_mdl.flux[mask_pixel:]

			chisquare = nsp.chisquare(data2,tell_mdl)

		else:
			chisquare = nsp.chisquare(data,telluric_model)
		lsf_list.append([chisquare,i])

		if test is True:
			plt.plot(telluric_model.wave,telluric_model.flux+(i-3)*10+1,
				'r-',alpha=0.5)

	if test is True:
		plt.plot(data.wave,data.flux,
			'k-',label='telluric data',alpha=0.5)
		plt.title("Test LSF",fontsize=15)
		plt.xlabel("Wavelength ($\AA$)",fontsize=12)
		plt.ylabel("Transmission + Offset",fontsize=12)
		plt.minorticks_on()
		if save_path is not None:
			plt.savefig(save_path+\
				"/{}_O{}_lsf_data_mdl.png"\
				.format(data.name, data.order))
		#plt.show()
		plt.close()

		fig, ax = plt.subplots()
		for i in range(len(lsf_list)):
			ax.plot(lsf_list[i][1],lsf_list[i][0],'k.',alpha=0.5)
		ax.plot(min(lsf_list)[1],min(lsf_list)[0],'r.',
			label="best LSF {} km/s".format(min(lsf_list)[1]))
		ax.set_xlabel("LSF (km/s)",fontsize=12)
		ax.set_ylabel("$\chi^2$",fontsize=11)
		plt.minorticks_on()
		plt.legend(fontsize=10)
		if save_path is not None:
			plt.savefig(save_path+\
				"/{}_O{}_lsf_chi2.png"\
				.format(data.name, data.order))
		#plt.show()
		plt.close()

	lsf = min(lsf_list)[1]

	if telluric_data.order == 61 or telluric_data.order == 62 \
	or telluric_data.order == 63: #or telluric_data.order == 64:
		lsf = 5.5
		print("The LSF is obtained from orders 60 and 65 (5.5 km/s).")

	return lsf