Beispiel #1
0
    def bestParams2(theta, data):

        i, alpha, c2, c0, c1 = theta
        data2 = copy.deepcopy(data)
        data2.wave = data2.wave * c1 + c0
        telluric_model = smart.convolveTelluric(i, data2, alpha=alpha)
        model = smart.continuum(data=data2, mdl=telluric_model)
        return np.sum(data.flux - (model.flux + c2))**2
Beispiel #2
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 = smart.convolveTelluric(i, data2, alpha=alpha)
        model = smart.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 = smart.convolveTelluric(i, data2, alpha=alpha)
        model = smart.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 = smart.convolveTelluric(popt[0], data, alpha=popt[1])
    model = smart.continuum(data=data, mdl=telluric_model)

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

    return popt[0]
Beispiel #3
0
    def bestParams(data, i, alpha, c2, c0):

        data2 = copy.deepcopy(data)
        data2.wave = data2.wave + c0
        telluric_model = smart.convolveTelluric(i, data2, alpha=alpha)
        model = smart.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
Beispiel #4
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 = smart.continuumTelluric(data=tell_sp, order=tell_sp.order)

    ## get a telluric model
    lsf = smart.getLSF(tell_sp)
    alpha = smart.getAlpha(tell_sp, lsf)
    tell_mdl = smart.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.lismartace(0.01,10,100000)
    f = np.lismartace(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)]
Beispiel #5
0
def fringeTelluric(data):
    """
    Model the fringe pattern for telluric data.
    
    Note: The input data should be continuum corrected 
    before using this function.
    """
    lsf = smart.getLSF(data)
    alpha = smart.getAlpha(data, lsf)
    tell_mdl2 = smart.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.lismartace(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]
Beispiel #6
0
def makeTelluricModel(lsf,
                      alpha,
                      flux_offset,
                      wave_offset,
                      data=data,
                      pwv=pwv,
                      airmass=airmass,
                      deg=cont_deg):
    """
	Make a telluric model as a function of LSF, alpha, and flux offset.

	## Note: The function "convolveTelluric " used is from the model_fit.py, not in the tellurics!s 
	"""
    niter = 5  # continuum iteration

    data2 = copy.deepcopy(data)
    data2.wave = data2.wave + wave_offset
    #data2.wave          = data2.wave * (1 + wave_offset1) + wave_offset
    telluric_model = smart.convolveTelluric(lsf, data2, alpha=alpha, pwv=pwv)

    #if data.order == 35:
    #	from scipy.optimize import curve_fit
    #	data_flux_avg = np.average(data2.flux)
    #	popt, pcov = curve_fit(smart.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               = smart.continuum(data=data2, mdl=telluric_model, deg=2)
    #	model = telluric_model
    #	max_model_flux      = np.max(smart.voigt_profile(data2.wave, *popt))
    #	model.flux         *= smart.voigt_profile(data2.wave, *popt)/max_model_flux
    #	model               = smart.continuum(data=data2, mdl=model, deg=deg)
    #else:
    model = smart.continuum(data=data2, mdl=telluric_model, deg=deg)
    for i in range(niter):
        model = smart.continuum(data=data2, mdl=model, deg=deg)

    model.flux += flux_offset

    return model
Beispiel #7
0
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()

deg = cont_deg
niter = 5

data2 = copy.deepcopy(data)
data2.wave = data2.wave + B_mcmc[0]
telluric_model = smart.convolveTelluric(lsf_mcmc[0], data, alpha=alpha_mcmc[0])
model, pcont = smart.continuum(data=data,
                               mdl=telluric_model,
                               deg=deg,
                               tell=True)
polyfit = np.polyval(pcont, model.wave)
for i in range(niter):
    model, pcont2 = smart.continuum(data=data2, mdl=model, deg=deg, tell=True)
    polyfit2 = np.polyval(pcont2, model.wave)
    polyfit *= polyfit2

polyfit += A_mcmc[0]

model.flux += A_mcmc[0]

plt.tick_params(labelsize=20)
Beispiel #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 = 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
Beispiel #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 = 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
Beispiel #10
0
    def writeto(self, save_to_path, method='ascii', tell_sp=None):
        """
		Save the data as an ascii or a fits file.

		Parameters
		----------
		save_to_path 	:	str
							the path to save the output file

		method 			: 	'ascii' or 'fits'
							the output file format, either in
							a single ascii file or several fits
							files labeled in the order of 
							wavelength


		Optional Parameters
		-------------------
		tell_sp 		: 	Spectrum object
							the telluric data for the corresponding
							wavelength calibration

		Returns
		-------
		ascii or fits 	: 	see the method keyword
							The wavelength is in microns


		"""
        #pixel = np.delete(np.arange(1024),list(self.mask))
        pixel = np.arange(len(self.oriWave))
        ## create the output mask array 0=good; 1=bad
        if self.applymask:
            mask = np.zeros((len(self.oriWave), ), dtype=int)
            np.put(mask, self.mask, int(1))
        else:
            mask = np.zeros((len(self.oriWave), ), dtype=int)

        if method == 'fits':
            #fullpath = self.path + '/' + self.name + '_' + str(self.order) + '_all.fits'
            #hdulist = fits.open(fullpath, ignore_missing_end=True)
            #hdulist.writeto(save_to_path)
            #hdulist.close()
            if self.header['NAXIS1'] == 1024:
                save_to_path2 = save_to_path + self.header['FILENAME'].split('.')[0]\
                + '_O' + str(self.order)
            else:
                save_to_path2 = save_to_path + self.header['OFNAME'].split('.')[0]\
                + '_O' + str(self.order)
            ## wavelength
            hdu1 = fits.PrimaryHDU(self.wave / 10000, header=self.header)
            save_to_path2_1 = save_to_path2 + '_wave.fits'
            hdu1.writeto(save_to_path2_1)
            ## flux
            hdu2 = fits.PrimaryHDU(self.flux, header=self.header)
            save_to_path2_2 = save_to_path2 + '_flux.fits'
            hdu2.writeto(save_to_path2_2)
            ## uncertainty
            hdu3 = fits.PrimaryHDU(self.noise, header=self.header)
            save_to_path2_3 = save_to_path2 + '_uncertainty.fits'
            hdu3.writeto(save_to_path2_3)
            ## pixel
            hdu4 = fits.PrimaryHDU(pixel, header=self.header)
            save_to_path2_4 = save_to_path2 + '_pixel.fits'
            hdu4.writeto(save_to_path2_4)
            ## mask
            hdu5 = fits.PrimaryHDU(mask, header=self.header)
            save_to_path2_5 = save_to_path2 + '_mask.fits'
            hdu5.writeto(save_to_path2_5)

            if tell_sp is not None:
                tell_sp2 = copy.deepcopy(tell_sp)
                # the telluric standard model
                wavelow = tell_sp2.wave[0] - 20
                wavehigh = tell_sp2.wave[-1] + 20
                tell_mdl = smart.getTelluric(wavelow=wavelow,
                                             wavehigh=wavehigh)
                # continuum correction for the data
                tell_sp2 = smart.continuumTelluric(data=tell_sp2,
                                                   model=tell_mdl,
                                                   order=tell_sp2.order)
                # telluric flux
                hdu6 = fits.PrimaryHDU(tell_sp.flux, header=tell_sp.header)
                save_to_path2_6 = save_to_path2 + '_telluric_flux.fits'
                hdu5.writeto(save_to_path2_6)
                # telluric uncertainty
                hdu7 = fits.PrimaryHDU(tell_sp.noise, header=tell_sp.header)
                save_to_path2_7 = save_to_path2 + '_telluric_uncertainty.fits'
                hdu5.writeto(save_to_path2_7)
                # telluric model
                hdu8 = fits.PrimaryHDU(tell_mdl.flux, header=tell_sp.header)
                save_to_path2_8 = save_to_path2 + '_telluric_model.fits'
                hdu5.writeto(save_to_path2_8)

        elif method == 'ascii':
            if self.header['NAXIS1'] == 1024:
                save_to_path2 = save_to_path + self.header['FILENAME'].split('.')[0]\
                + '_O' + str(self.order) + '.txt'
            else:
                save_to_path2 = save_to_path + self.header['OFNAME'].split('.')[0]\
                + '_O' + str(self.order) + '.txt'

            if tell_sp is None:
                df = pd.DataFrame(
                    data={
                        'wavelength': list(self.oriWave / 10000),
                        'flux': list(self.oriFlux),
                        'uncertainty': list(self.oriNoise),
                        'pixel': list(pixel),
                        'mask': list(mask)
                    })
                df.to_csv(save_to_path2,
                          index=None,
                          sep='\t',
                          mode='a',
                          header=True,
                          columns=[
                              'wavelength', 'flux', 'uncertainty', 'pixel',
                              'mask'
                          ])

            elif tell_sp is not None:
                tell_sp2 = copy.deepcopy(tell_sp)
                tell_sp2 = smart.continuumTelluric(data=tell_sp2,
                                                   order=self.order)
                lsf0 = smart.getLSF(tell_sp2)
                tell_sp2.flux = tell_sp2.oriFlux
                tell_sp2.wave = tell_sp2.oriWave
                tell_mdl = smart.convolveTelluric(lsf0, tell_sp2)

                print(len(self.oriWave), len(self.oriFlux), len(self.oriNoise),
                      len(tell_sp.oriFlux), len(tell_sp.oriNoise),
                      len(tell_mdl.flux), len(pixel), len(mask))

                df = pd.DataFrame(
                    data={
                        'wavelength': list(self.oriWave / 10000),
                        'flux': list(self.oriFlux),
                        'uncertainty': list(self.oriNoise),
                        'telluric_flux': list(tell_sp.oriFlux),
                        'telluric_uncertainty': list(tell_sp.oriNoise),
                        'telluric_model': list(tell_mdl.flux),
                        'pixel': list(pixel),
                        'mask': list(mask)
                    })

                df.to_csv(save_to_path2,
                          index=None,
                          sep='\t',
                          mode='a',
                          header=True,
                          columns=[
                              'wavelength', 'flux', 'uncertainty',
                              'telluric_flux', 'telluric_uncertainty',
                              'telluric_model', 'pixel', 'mask'
                          ])