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)]
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]
data.flux = data.flux[pixel_start:pixel_end] data.noise = data.noise[pixel_start:pixel_end] tell_sp.wave = tell_sp.wave[pixel_start:pixel_end] tell_sp.flux = tell_sp.flux[pixel_start:pixel_end] tell_sp.noise = tell_sp.noise[pixel_start:pixel_end] #if final_mcmc: # priors, limits = mcmc_utils.generate_final_priors_and_limits(sp_type=sp_type, barycorr=barycorr, save_to_path1=save_to_path1) #else: # priors, limits = mcmc_utils.generate_initial_priors_and_limits(sp_type=sp_type) #print(priors, limits) if lsf is None: lsf = smart.getLSF(tell_sp, alpha=alpha_tell, test=True, save_path=save_to_path) # print("LSF: ", lsf) #else: # print("Use input lsf:", lsf) # log file log_path = save_to_path + '/mcmc_parameters.txt' """ file_log = open(log_path,"w+") file_log.write("data_path {} \n".format(data.path)) file_log.write("tell_path {} \n".format(tell_sp.path)) file_log.write("data_name {} \n".format(data.name)) file_log.write("tell_name {} \n".format(tell_sp.name)) file_log.write("order {} \n".format(data.order)) file_log.write("custom_mask {} \n".format(custom_mask))
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' ])