def rotationally_broaden(wavelengths,spec,ld,vsini): ''' A function to rotationally broaden a spectrum ''' from PyAstronomy import pyasl # import pdb;pdb.set_trace() spec_broadened = pyasl.fastRotBroad(wavelengths.to(u.AA).value,spec.value,ld,vsini.to(u.km/u.s).value)*spec.unit return spec_broadened
def evaluate(self, x): """ Calculates the model for current parameters. The "model" is calculated on a wavelength axis with binning specified by the `modelBinsize` parameter. The line positions are Doppler shifted and the resulting model is rotationally broadened. Finally, the entire model is multiplied by the `scale` parameter to account for a global normalization. Parameters ---------- x : array The wavelengths at which to calculate the model. Returns ------- model : array The model evaluated at the specified positions. """ if self._verbose: print("Evaluating with parameters: ", self.parameters()) # Calculate how much longer the model wavelength axis should # be to ensure that Doppler shift and rotational broadening # to not "violate" its edges. maxV = abs(self["vsini"]) + abs(self["vrad"]) deltaWvl = max(x) * (1.0 + maxV/299792.458) - max(x) # The additional summand `_modelBinsize` is needed to ensure # that the wavelength axis is long enough even if the velocities # are very small. mwvl = np.arange(min(x)-deltaWvl, max(x)+deltaWvl+self._modelBinsize, self._modelBinsize) mflux = np.ones(len(mwvl)) # Set parameters of multiGauss for i in smo.range(self._nl): p = str(i+1) # Apply global scaling of amplitudes self._mg["A"+p] = -self["A"+p] * self["lineScale"] self._mg["sig"+p] = self["sig"+p] # Apply doppler shift of lines self._mg["mu"+p] = (1.0 + self["vrad"]/299792.458) * self["mu"+p] mflux += self._mg.evaluate(mwvl) if abs(self["vsini"]) > 0.0: if self._usefastRB: mflux = pyasl.fastRotBroad(mwvl, mflux, self["eps"], np.abs(self["vsini"])) else: mflux = pyasl.rotBroad(mwvl, mflux, self["eps"], np.abs(self["vsini"])) mflux *= self["scale"] # Return model interpolated at input wavelength f = sci.interp1d(mwvl, mflux) return f(x)
def multiccf(pars): teff, logg, feh, vsini = pars[0], pars[1], pars[2], pars[3] vmin = -500 vmax = 500. vstep = 20. sc = get_model(teff, logg, feh) hd = pyfits.getheader(model_path + get_modname(7000, 4.5, 0.0) + '.fits') wav = np.arange(len(sc)) * hd['CDELT1'] + hd['CRVAL1'] try: sc = get_model(teff, logg, feh) hd = pyfits.getheader(model_path + get_modname(7000, 4.5, 0.0) + '.fits') mw = np.arange(len(sc)) * hd['CDELT1'] + hd['CRVAL1'] except: mw, sc = trilinear_interpolation(teff, logg, feh, model_path) sc = clean_strong_lines(mw, sc) II = np.where(sc != 1)[0] JJ = np.where(sc == 1)[0] coef = normalize_model(mw[II], sc[II]) sc /= np.polyval(coef, mw) sc[JJ] = 1. mw = ToVacuum(mw) weis1 = [] ccftot = [] for i in range(wavs.shape[0]): scf = flxs[i].copy() scw = wavs[i].copy() J = np.where(scf != 0)[0] scw, scf = scw[J], scf[J] I = np.where((mw > scw[0] - 100) & (mw < scw[-1] + 100)) tmf = pyasl.fastRotBroad(mw[I], sc[I], 0.5, vsini) #plot(mw[I],tmf) J = np.where(scf != 1)[0] if len(J) > 100: ccv, ccf = spec_ccf(scw, scf, mw[I], tmf, vmin, vmax, vstep) #ccv,ccf = ccf_fft(scw,scf,mw[I],tmf) #plot(ccv,ccf) #show() wei1 = len(np.where(scf != 1)[0])**2 weis1.append(wei1) if len(ccftot) == 0: ccftot = ccf.copy() * wei1 else: ccftot = np.vstack((ccftot, ccf.copy() * wei1)) weis1 = np.array(weis1) ccftot = np.sum(ccftot, axis=0) / np.sum(weis1) #print gfds #ccftot = np.mean(ccftot,axis=0) #print pars, ccftot.min() return ccftot.min()
def add_rot_broad(wlen, flux, rot_vel, method='fast', edgeHandling='cut'): if method == 'fast': flux_broad = fastRotBroad(wlen, flux, 0, rot_vel) else: # method == 'slow' flux_broad = rotBroad(wlen, flux, 0, rot_vel) if edgeHandling == 'cut': skipping = abs(wlen[-1] * rot_vel * 1000 / cst.c) wvl_stepsize = np.mean( [wlen[i + 1] - wlen[i] for i in range(len(wlen) - 1)]) skipped_bins = int(skipping / wvl_stepsize) #print('Bins skipped for rotational broadening {b}'.format(b=skipped_bins)) wlen_cut, flux_cut = cut_spectrum(wlen, flux_broad, nb_bins_left=skipped_bins, nb_bins_right=skipped_bins) return wlen_cut, flux_cut else: # edgeHandling == 'keep' return wlen, flux_broad
def calc_log_likelihood(self,param): # param is spin velocity investigated spin_vel,radial_vel = param log_prior = 0. log_likelihood = 0. self.function_calls += 1 # check priors log_prior += self.log_prior(spin_vel,'spin_vel') log_prior += self.log_prior(radial_vel,'radial_vel') if log_prior == -np.inf: return -np.inf wlen,flux={},{} for key in self.t_wvl.keys(): wlen[key],flux[key] = self.t_wvl[key],self.t_flux[key] # Doppler shift if 'radial_vel' in self.params_names: for key in wlen.keys(): wlen[key],flux[key] = doppler_shift(wlen[key],flux[key],radial_vel) # rot. broad. spectrum if 'spin_vel' in self.params_names: for key in self.t_wvl.keys(): if self.algo == 'fast': flux[key] = pyasl.fastRotBroad(wlen[key],flux[key],0,spin_vel) else: # 'slow' flux[key] = pyasl.rotBroad(wlen[key],flux[key],0,spin_vel) # make sure that we have same wvl coverage as data for key in wlen.keys(): wlen[key],flux[key] = np.transpose([[wlen[key][i],flux[key][i]] for i in range(len(wlen[key])) if wlen[key][i] >= self.d_wvl[key][0] and wlen[key][i] <= self.d_wvl[key][-1]]) # calculate CCF between template and rot. broadened template CC_range_i = {} for key in self.t_wvl.keys(): dRV,CC_range_i[key] = pyasl.crosscorrRV(wlen[key],flux[key], self.t_wvl[key],self.t_flux[key], rvmin=self.rvmin,rvmax=self.rvmax,drv=self.drv, skipedge=self.skipedge ) CC = np.array([sum([CC_range_i[key][drv_i] for key in CC_range_i.keys()]) for drv_i in range(len(dRV))]) drv_max_i = np.argmax(CC) drv_max = dRV[drv_max_i] # normalise CCF CC_max = CC[drv_max_i] CC = CC/CC_max """ # the problem of just shifting the CCF by some RV value is that is doesnt account for the fact that the doppler shift also stretches the spectrum CCF_new = CC if 'radial_vel' in self.params_names: CCF_f = interp1d(dRV + radial_vel,CC,fill_value = 0) CCF_new = CCF_f(self.CCF_dRV) """ CC_final = [CC[i] for i in range(len(CC)) if dRV[i] >= self.CCF_dRV[0] and dRV[i] <= self.CCF_dRV[-1]] assert(len(CC_final)==len(self.CCF_CC)) for rv_i in range(len(self.CCF_dRV)): log_likelihood += -0.5*((CC_final[rv_i]-self.CCF_CC[rv_i])/self.std_CCF)**2 if self.function_calls%self.write_threshold == 0: hours = (time() - self.start_time)/3600.0 info_list = [self.function_calls, log_likelihood, hours] with open(self.diag_file,'a') as f: for i in np.arange(len(info_list)): if (i == len(info_list) - 1): f.write(str(info_list[i]).ljust(15) + "\n") else: f.write(str(info_list[i]).ljust(15) + " ") if self.function_calls%(self.write_threshold) == 0: plt.figure() plt.plot(self.CCF_dRV,self.CCF_CC,'r',label='CCF with data') plt.plot(dRV,CC,'k',label='CCF with template') plt.legend() plt.savefig(self.output_dir + 'model/CCF_'+str(self.function_calls)+'.png') print(log_prior + log_likelihood) print("--> ", self.function_calls) return log_prior + log_likelihood
mod = 1. # print rot_coef temp_filename = "spec_wasp33_" + str(mol) + "_inv" + str(vmr) + ".dat" print temp_filename xtemp, ytemp = np.loadtxt(exotempdir + temp_filename, unpack=True, dtype="float") #Loading the template spectrum Is = np.array( intensity(xtemp * 1.e-10, 7400.)) #Calculating blackbody to normalize the template ytempnorm = (mul) * ytemp * ( (Rp * const.R_jup.value) / (Rs * const.R_sun.value))**2 / Is #Scaling to the real contrast ################ function_broad_dopp = [] broadened_spec = pyasl.fastRotBroad(xtemp, ytempnorm, 0.0, vp_rotation * rot_coef) for filenum in range(len(phase_mid)): #Doppler Shifting fi = sci.interp1d(xtemp * (1.0 + v_mid[filenum] / c), broadened_spec) function_broad_dopp.append(fi) ################ # print vp_rotation*rot_coef for ccd in ccd_list: if ccd == "blue": len_order = 19 else: len_order = 13 h5f_eqwv = h5py.File( specdir + str(ccd) + str(whichdata) + "_eqwv_fullmatrix.h5", 'r') for order in tqdm(range(1, len_order), ascii="True",
def plot_retrieved_rotbroad(samples, dRV_data, CC_data, wlen, flux, config, output_dir='', fontsize=15): rvmin, rvmax, drv = min(dRV_data), max(dRV_data), abs(dRV_data[1] - dRV_data[0]) skipping = {} for key in wlen.keys(): wvl_stepsize = max([ wlen[key][i + 1] - wlen[key][i] for i in range(len(wlen[key]) - 1) ]) ds_max = max([ abs(wlen[key][-1] * rvmin * 1000 / cst.c), abs(wlen[key][-1] * rvmax * 1000 / cst.c) ]) skipping[key] = int(ds_max / wvl_stepsize) + 1 if skipping[key] / len(wlen[key]) >= 0.25: print( 'WARNING: NEED TO SKIP {p:.2f} % OF TEMPLATE SPECTRUM TO INVESTIGATE ALL DOPPLER-SHIFT DURING CROSS-CORRELATION' .format(p=skipping[key] / len(wlen[key]))) skipedge = int(max([skipping[key] for key in skipping.keys()]) * 1.5) nb_positions = len(samples) nb_params = len(samples[0]) assert (nb_params == 1) quantiles = {} for param_i, param in config['PARAMS_NAMES']: quantiles[param] = np.quantile(samples[param_i][0], q=[0.16, 0.5, 0.84]) wlen_temp, flux_temp = {}, {} for key in wlen.keys(): wlen_temp[key], flux_temp[key] = wlen[key], flux[key] plt.figure() for quant_i, quant in enumerate([0.16, 0.5, 0.84]): CC_range_i = {} for key_i, key in enumerate(wlen.keys()): print('Progress: {p:.2f} %'.format(p=int(100 * (key_i + 1) / len(wlen.keys())))) if 'radial_vel' in config['PARAMS_NAMES'] and quant == 0.5: wlen_temp[key], flux_temp[key] = doppler_shift( wlen_temp[key], flux_temp[key], quantiles['radial_vel'][quant_i]) if 'spin_vel' in config['PARAMS_NAMES']: flux_temp[key] = fastRotBroad(wlen_temp[key], flux_temp[key], 0, quantiles['spin_vel'][quant_i]) dRV, CC_range_i[key] = crosscorrRV(wlen[key], flux[key], wlen_temp[key], flux_temp, rvmin=rvmin, rvmax=rvmax, drv=drv, skipedge=skipedge) CC = np.array([ sum([CC_range_i[key][drv_i] for key in CC_range_i.keys()]) for drv_i in range(len(dRV)) ]) CC = CC / max(CC) RV_max_i = np.argmax(CC_data) if quant_i == 1: median_str, q2_str, q1_str = {}, {}, {} for param in config['PARAMS_NAMES']: median_str[param] = '{median:.2f}'.format( median=quantiles[param][1]) q2_str[param] = '{q2:.2f}'.format(q2=quantiles[param][2] - quantiles[param][1]) q1_str[param] = '{q1:.2f}'.format(q1=quantiles[param][1] - quantiles[param][0]) plt.plot(dRV, CC, 'k', label='Retrieved v$_{spin}$ = ' + median_str['spin_vel'] + '$^{+' + q2_str['spin_vel'] + '}_{-' + q1_str['spin_vel'] + '}$ km$s^{-1}$') plt.axvline(quantiles['radial_vel'][1], color='g', label='Retrieved RV: ' + median_str['radial_vel'] + '$^{+' + q2_str['radial_vel'] + '}_{-' + q1_str['radial_vel'] + '}$ km$s^{-1}$') else: plt.plot(dRV, CC, 'k--') plt.axvline(quantiles['radial_vel'][quant_i], color='g', ls='--') plt.axvline(quantiles['radial_vel'][quant_i], color='g', ls='--') CC_data = CC_data / max(CC_data) if 'spin_vel' in config['PARAMS_NAMES']: plt.plot(dRV_data, CC_data, 'r', label='True v$_{spin}$: ' + str(config['DATA_PARAMS']['spin_vel']) + ' km$s^{-1}$') else: plt.plot(dRV_data, CC_data, 'r') if 'radial_vel' in config['PARAMS_NAMES']: plt.axvline(config['DATA_PARAMS']['radial_vel'], color='r', ls='--') plt.legend(fontsize=fontsize) plt.xlabel('Radial velocity [kms$^{-1}$]') plt.ylabel('Normalised CCF') plt.savefig(output_dir + 'retrieved_rot_broad.png', dpi=300)
def RVforFR(wavs, flxs, teff=6700, logg=4.0, feh=-1.0, vsini=100., model_path='../../data/COELHO2014/', vmin=-1000., vmax=1000., vstep=10.): def fitfunc(p, x): ret = p[3] + p[0] * np.exp(-.5 * ((x - p[1]) / p[2])**2) return ret errfunc = lambda p, x, y: np.ravel((fitfunc(p, x) - y)) #sc = get_model(teff,logg,feh) #hd = pyfits.getheader(model_path+get_modname(7000,4.5,0.0)+'.fits') #wav = np.arange(len(sc))*hd['CDELT1'] + hd['CRVAL1'] teff = float(teff) try: sc = get_model(teff, logg, feh) hd = pyfits.getheader(model_path + get_modname(7000, 4.5, 0.0) + '.fits') mw = np.arange(len(sc)) * hd['CDELT1'] + hd['CRVAL1'] except: mw, sc = trilinear_interpolation(teff, logg, feh, model_path) for order in range(len(flxs)): flxs[order] = clean_strong_lines(wavs[order], flxs[order]) sc = clean_strong_lines(mw, sc) II = np.where(sc != 1)[0] JJ = np.where(sc == 1)[0] coef = normalize_model(mw[II], sc[II]) sc /= np.polyval(coef, mw) sc[JJ] = 1. mw = ToVacuum(mw) weis1 = [] ccftot = [] for i in range(wavs.shape[0]): #plot(wavs[i],flxs[i]) scf = flxs[i] scw = wavs[i] J = np.where(scf != 0)[0] scw, scf = scw[J], scf[J] I = np.where((mw > scw[0] - 100) & (mw < scw[-1] + 100)) tmf = pyasl.fastRotBroad(mw[I], sc[I], 0.5, vsini) #plot(mw[I],tmf) J = np.where(scf != 1)[0] if len(J) > 100: ccv, ccf = spec_ccf(scw, scf, mw[I], tmf, vmin, vmax, vstep) #plot(ccv,ccf) #show() #ccf = np.array(ccf) wei1 = len(np.where(scf != 1)[0])**2 weis1.append(wei1) if len(ccftot) == 0: ccftot = ccf.copy() * wei1 else: ccftot = np.vstack((ccftot, ccf.copy() * wei1)) #show() weis1 = np.array(weis1) ccftot = np.sum(ccftot, axis=0) / np.sum(weis1) p0 = [ccftot.min(), ccv[np.argmin(ccftot)], vsini, ccftot[0]] p1, success = scipy.optimize.leastsq(errfunc, p0, args=(ccv, ccftot)) return p1, ccv, ccftot, fitfunc(p1, ccv)