Beispiel #1
0
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
Beispiel #2
0
  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)
Beispiel #3
0
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()
Beispiel #4
0
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
Beispiel #5
0
 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
Beispiel #6
0
        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)
Beispiel #8
0
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)