Example #1
0
def lnlike(theta, data=data):
    """
	Log-likelihood, computed from chi-squared.

	Parameters
	----------
	theta
	data

	Returns
	-------
	-0.5 * chi-square + sum of the log of the noise
	"""
    ## Parameters MCMC

    lsf, airmass, pwv, A, B = theta

    model = tellurics.makeTelluricModel(lsf,
                                        airmass,
                                        pwv,
                                        A,
                                        B,
                                        data=data,
                                        deg=2,
                                        niter=None)

    chisquare = smart.chisquare(data, model)

    return -0.5 * (chisquare + np.sum(np.log(2 * np.pi * data.noise**2)))
Example #2
0
def lnlike(theta, data, lsf):
    """
	Log-likelihood, computed from chi-squared.

	Parameters
	----------
	theta
	lsf
	data

	Returns
	-------
	-0.5 * chi-square + sum of the log of the noise

	"""

    ## Parameters MCMC
    teff, logg, vsini, rv, teff2, logg2, vsini2, rv2, flsc, am, pwv, A, B, N = theta  #N noise prefactor
    #teff, logg, vsini, rv, , am, pwv, A, B, freq, amp, phase = theta

    model = model_fit.makeModel(teff=teff,
                                logg=logg,
                                metal=0.0,
                                vsini=vsini,
                                rv=rv,
                                teff2=teff2,
                                logg2=logg2,
                                vsini2=vsini2,
                                rv2=rv2,
                                flux_scale=flsc,
                                tell_alpha=1.0,
                                wave_offset=B,
                                flux_offset=A,
                                lsf=lsf,
                                order=data.order,
                                data=data,
                                modelset=modelset,
                                airmass=am,
                                pwv=pwv,
                                binary=True)

    chisquare = smart.chisquare(data, model) / N**2

    return -0.5 * (chisquare + np.sum(np.log(2 * np.pi * (data.noise * N)**2)))
Example #3
0
def telluric_mask(data, sigma=2.5, lsf=4.8, pwv=None, pixel_start=10, pixel_end=-30, outlier_rejection=2.5, diagnostic=True, save_to_path='./'):
	"""
	Routine to generate a mask for tellurics as the MCMC initialization.

	Parameters
	----------
	sigma 				: 	float; default 2.5
							The sigma-clipping method to reject the outliers.

	lsf 				:	float; default 4.8
							The value of line spread function. 
							The default is the normal value of LSF for Keck/NIRSPEC.

	pwv 				: 	float; default None
							precitable water vapor.
							The default is to run the chi2 grids of pwv to obtain the best pwv.

	pixel_start			: 	int; default 10
							The starting pixel to compute the mask.

	pixel_end 			: 	int; default -30
							The ending pixel to compute the mask.

	outlier_rejection 	: 	float; default 2.5
							The value for number * sigma to reject outliers

	diagnostic 			: 	bool; default True
							Generate the diagnostic plots for pwv-ch2 and model-data before/after masks

	save_to_path 		: 	str; default the current working directory


	Returns
	-------
	mask 				: numpy array

	pwv 				: float 

	airmass 			: float


	Example
	-------
	>>> from smart.forward_model import mask
	>>> tell_mask, pwv, airmass = mask.telluric_mask(data, diagnostic=False)

	"""

	data.flux  = data.flux[pixel_start:pixel_end]
	data.wave  = data.wave[pixel_start:pixel_end]
	data.noise = data.noise[pixel_start:pixel_end]

	data0 = copy.deepcopy(data)

	# take the closest airmass from the header
	airmass = float(round(data.header['AIRMASS']*2)/2)
	if airmass > 3.0: airmass = 3.0

	# simple chi2 comparison with different pwv
	if pwv is None:
		pwvs = [0.5, 1.0, 1.5, 2.5, 3.5, 5.0, 7.5, 10.0, 20.0]
		pwv_chi2 = []
		
		for pwv in pwvs:
			data_tmp       = copy.deepcopy(data)
	
			#data_tmp       = smart.continuumTelluric(data=data_tmp, model=model_tmp)
			model_tmp      = tellurics.makeTelluricModel(lsf=lsf, airmass=airmass, pwv=pwv, flux_offset=0, wave_offset=0, data=data_tmp, deg=10)
	
			model_tmp.flux = np.array(smart.integralResample(xh=model_tmp.wave, yh=model_tmp.flux, xl=data_tmp.wave))
			model_tmp.wave = data_tmp.wave

			#plt.plot(data_tmp.wave, data_tmp.flux, 'k-')
			#plt.plot(model_tmp.wave, model_tmp.flux, 'r-')
			#plt.show()
			#plt.close()
	
			pwv_chi2.append(smart.chisquare(data_tmp, model_tmp))
		# find the pwv with minimum chisquare
		pwv_chi2_array = np.array(pwv_chi2)
		
		if diagnostic:
			plt.plot(pwvs, pwv_chi2)
			plt.xlabel('pwv (mm)', fontsize=15)
			plt.ylabel('$\chi^2$', fontsize=15)
			plt.tight_layout()
			plt.savefig(save_to_path+'pwv_chi2.png')
			#plt.show()
			plt.close()

	pwv_min_index = np.where(pwv_chi2_array == np.min(pwv_chi2_array))[0][0]
	pwv           = pwvs[pwv_min_index]

	data_tmp  = copy.deepcopy(data)

	model      = tellurics.makeTelluricModel(lsf=lsf, airmass=airmass, pwv=pwv, flux_offset=0, wave_offset=0, data=data_tmp)

	model_0 = copy.deepcopy(model)

	# generate the mask based on sigma clipping
	pixel = np.delete(np.arange(len(data.oriWave)), data.mask)[pixel_start: pixel_end]
	#pixel = np.delete(np.arange(len(data_tmp.oriWave)),data_tmp.mask)
	mask  = pixel[np.where(np.abs(data_tmp.flux-model.flux) > outlier_rejection*np.std(data_tmp.flux-model.flux))]

	#plt.plot(data_tmp.wave, data_tmp.flux, 'k-')
	#plt.plot(model.wave, model.flux, 'r-')
	#plt.show()
	#plt.close()

	data_tmp.mask_custom(mask)
	data_tmp.flux  = data_tmp.flux[pixel_start:pixel_end]
	data_tmp.wave  = data_tmp.wave[pixel_start:pixel_end]
	data_tmp.noise = data_tmp.noise[pixel_start:pixel_end]

	#plt.plot(data_tmp.wave, data_tmp.flux, 'k-')
	#plt.plot(model.wave, model.flux, 'r-')
	#plt.show()
	#plt.close()

	# use curve_fit
	def tell_model_fit(wave, airmass, pwv, flux_offset, wave_offset):
		model      = tellurics.makeTelluricModel(lsf=lsf, airmass=airmass, pwv=pwv, flux_offset=flux_offset, wave_offset=wave_offset, data=data_tmp)
		return model.flux

	print('initial airmass and pwv', airmass, pwv)
	flux_med = np.median(data_tmp.flux)
	p0 = [airmass, pwv, 0, 0]
	bounds = ([airmass-0.5, pwv-0.5, -flux_med*0.05, -0.05], [airmass+0.5, pwv+0.5, flux_med*0.05, 0.05])

	popt, pcov = curve_fit(tell_model_fit, data_tmp.wave, data_tmp.flux, p0=p0, bounds=bounds)

	airmass, pwv, flux_offset, wave_offset = popt[0], popt[1], popt[2], popt[3]
	print('best-fit airmass, pwv, flux_offset, wave_offset', airmass, pwv, flux_offset, wave_offset)
	model      = tellurics.makeTelluricModel(lsf=lsf, airmass=airmass, pwv=pwv, flux_offset=0, wave_offset=0, data=data_tmp)
	print('old telluric mask', mask)
	pixel = np.delete(np.arange(len(data_tmp.oriWave)), mask)[pixel_start: pixel_end]
	#print('len pixel, data, model', len(pixel), len(data_tmp.wave), len(model.wave))
	mask  = pixel[np.where(np.abs(data_tmp.flux-model.flux) > outlier_rejection*np.std(data_tmp.flux-model.flux))]
	# combine the masks
	mask = np.union1d(mask,np.array(data_tmp.mask))
	print('new telluric mask', mask)

	data.mask_custom(mask)
	data.flux  = data.flux[pixel_start:pixel_end]
	data.wave  = data.wave[pixel_start:pixel_end]
	data.noise = data.noise[pixel_start:pixel_end]
	print(data.mask)

	#plt.plot(data.wave, data.flux, 'k-')
	#plt.plot(model.wave, model.flux, 'r-')
	#plt.plot(model_0.wave, model_0.flux, 'b-', alpha=0.5)
	#plt.show()
	#plt.close()

	if diagnostic:
		data.flux  = data.flux[pixel_start:pixel_end]
		data.wave  = data.wave[pixel_start:pixel_end]
		data.noise = data.noise[pixel_start:pixel_end]
		
		model      = tellurics.makeTelluricModel(lsf=lsf, airmass=airmass, pwv=pwv, flux_offset=0, wave_offset=0, data=data)
		
		plt.plot(data0.wave, data0.flux, 'k-', label='original data', alpha=0.5)
		plt.plot(data.wave, data.flux, 'k-', label='masked data')
		plt.plot(model.wave, model.flux, 'r-', alpha=0.7)
		plt.plot(data.wave, data.flux-model.flux, 'r-')
		plt.xlabel('$\lambda (\AA)$')
		plt.ylabel('$F_{\lambda}$')
		plt.savefig(save_to_path+'telluric_data_model_mask.png')
		#plt.show()
		plt.close()

	return mask.tolist(), pwv, airmass
Example #4
0
plt.figtext(0.89,0.83,"${0}^{{+{1}}}_{{-{2}}}/{3}^{{+{4}}}_{{-{5}}}/{6}^{{+{7}}}_{{-{8}}}$".format(\
 round(lsf_mcmc[0],2),
round(lsf_mcmc[1],2),
round(lsf_mcmc[2],2),
round(alpha_mcmc[0],2),
round(alpha_mcmc[1],2),
round(alpha_mcmc[2],2),
round(B_mcmc[0],2),
round(B_mcmc[1],2),
round(B_mcmc[2],2)),
            color='r',
            horizontalalignment='right',
            verticalalignment='center',
            fontsize=12)
plt.figtext(0.89,0.80,r"$\chi^2$ = {}, DOF = {}".format(\
 round(smart.chisquare(data,model)), round(len(data.wave-ndim)/3)),
            color='k',
            horizontalalignment='right',
            verticalalignment='center',
            fontsize=12)
plt.fill_between(data.wave, -data.noise, data.noise, alpha=0.5)
plt.tick_params(labelsize=15)
plt.ylabel('Flux (counts/s)', fontsize=15)
plt.xlabel('Wavelength ($\AA$)', fontsize=15)

ax2 = ax1.twiny()
ax2.plot(pixel, data.flux, color='w', alpha=0)
ax2.set_xlabel('Pixel', fontsize=15)
ax2.tick_params(labelsize=15)
ax2.set_xlim(pixel[0], pixel[-1])
ax2.minorticks_on()
Example #5
0
def initModelFit(sci_data, lsf, modelset='btsettl08'):
    """
	Conduct simple chisquare fit to obtain the initial parameters
	for the forward modeling MCMC.

	The function would calculate the chisquare for teff, logg, vini, rv, and alpha.

	Parameters
	----------
	data 				:	spectrum object
							input science data

	lsf 				:	float
							line spread function for the NIRSPEC

	Returns
	-------
	best_params_dic 	:	dic
							a dictionary that stores the best parameters for 
							teff, logg, vsini, rv, and alpha

	chisquare 			:	int
							minimum chisquare

	"""
    data = copy.deepcopy(sci_data)

    ## set up the parameter grid for chisquare computation
    teff_array = np.arange(1200, 3001, 100)
    logg_array = np.arange(3.5, 5.51, 0.5)
    vsini_array = np.arange(10, 101, 10)
    rv_array = np.arange(-200, 201, 50)
    alpha_array = np.arange(0.5, 2.01, 0.5)
    chisquare_array = np.empty(len(teff_array)*len(logg_array)*len(vsini_array)*len(rv_array)*len(alpha_array))\
    .reshape(len(teff_array),len(logg_array),len(vsini_array),len(rv_array),len(alpha_array))

    time1 = time.time()
    for i, teff in enumerate(teff_array):
        for j, logg in enumerate(logg_array):
            for k, vsini in enumerate(vsini_array):
                for l, rv in enumerate(rv_array):
                    for m, alpha in enumerate(alpha_array):
                        model = smart.makeModel(teff,
                                                logg,
                                                0.0,
                                                vsini,
                                                rv,
                                                alpha,
                                                0,
                                                0,
                                                lsf=lsf,
                                                order=str(data.order),
                                                data=data,
                                                modelset=modelset)
                        chisquare_array[i, j, k, l,
                                        m] = smart.chisquare(data, model)
    time2 = time.time()
    print("total time:", time2 - time1)

    ind = np.unravel_index(np.argmin(chisquare_array, axis=None),
                           chisquare_array.shape)
    print("ind ", ind)
    chisquare = chisquare_array[ind]

    best_params_dic = {
        'teff': teff_array[ind[0]],
        'logg': logg_array[ind[1]],
        'vsini': vsini_array[ind[2]],
        'rv': rv_array[ind[3]],
        'alpha': alpha_array[ind[4]]
    }

    print(best_params_dic, chisquare)

    return best_params_dic, chisquare
Example #6
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 = smart.continuumTelluric(data=data)

    for i in test_alpha:
        telluric_model = smart.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 = smart.chisquare(data2, tell_mdl)

        else:
            chisquare = smart.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
Example #7
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 = smart.continuumTelluric(data=data)

    data.flux **= alpha
    for i in test_lsf:
        telluric_model = smart.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 = smart.chisquare(data2, tell_mdl)

        else:
            chisquare = smart.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