def pyfxcor(inspec, template, vmin=-200., vmax=200., res=3, rej=1000):
    rv, cc = pyasl.crosscorrRV(inspec[0],
                               inspec[1],
                               template[0],
                               template[1],
                               vmin,
                               vmax,
                               res,
                               skipedge=rej)

    cen_gs = np.argmax(cc)
    perfx, perfy = rv[cen_gs - 5:cen_gs + 6], cc[cen_gs - 5:cen_gs + 6]

    try:
        gauss = ConstantModel() + GaussianModel()
        pars = gauss.make_params()
        pars['center'].set(value=rv[np.argmax(cc)], vary=True)
        pars['amplitude'].set(value=max(cc), vary=True)
        pars['sigma'].set(vary=True)
        pars['c'].set(value=0, vary=True)
        out = gauss.fit(perfy, pars, x=perfx)
        ct = out.best_values['center']
        cterr = out.params['center'].stderr
    except:
        return 'error', ''

    return ct, cterr
示例#2
0
def cross_correlate_order(wave, flux, template, ap=200):
    mask = template[:, 0] > min(wave) - 1000 * median(wave) / c
    mask *= template[:, 0] < max(wave) + 1000 * median(wave) / c

    flux = normalise(flux, deg=4)
    template_flux = normalise(template[:, 1][mask], deg=0)
    #template_flux = template[:,1][mask]

    ### do some more normalisation against the template
    fit = interpolate.splrep(template[:, 0][mask], template_flux)
    fit = interpolate.splev(wave, fit)

    diff = flux / fit
    diffmask = diff - median(diff) < 0.2
    diffmask *= diff - median(diff) > -0.6

    try:
        fit = polyfit(wave[diffmask], diff[diffmask], 10)
        fit = polyval(fit, wave)
        flux /= fit
    except:
        print "Bad normalisation"

    flux = -1 * (flux - 1)
    template_flux = -1 * (template_flux - 1)

    #flux = apodize(flux,ap=ap)
    #template_flux = apodize(template_flux,ap=ap)

    drv, cc = pyasl.crosscorrRV(wave,
                                flux,
                                template[:, 0][mask],
                                template_flux,
                                -300,
                                +300,
                                0.01,
                                mode='doppler',
                                skipedge=0,
                                edgeTapering=None)
    # plt.subplot(211)
    # plt.plot(wave,flux)
    # plt.plot(template[:,0][mask],template_flux)

    # plt.subplot(212)
    # plt.plot(drv,cc)
    # plt.show()

    try:
        #epos = pyasl.quadExtreme(drv, cc, mode='max', dp=(50, 50), exInd=None, fullOutput=False, fullPoint=False)[0]
        dp = len(cc[cc > 0.5 * nanmax(cc)]) / 2
        print "len of cc peak find", dp
        epos = fitquad(drv, cc, dp=dp)
        print "rv", epos
    except:
        epos = nan

    return epos, drv, cc
示例#3
0
 def sanity_ShiftedGaussian(self):
   """
     Checking the shift of a single Gaussian.
   """
   from PyAstronomy import pyasl
   import numpy as np
   
   # Create the template
   tw = np.linspace(5000,5010,1000)
   tf = np.exp(-(tw-5004.0)**2/(2.*0.1**2))
   
   # Create data, which are not that well sampled
   dw = np.linspace(5000,5010,200)
   df = np.exp(-(dw-5004.0)**2/(2.*0.1**2))
   
   rv1, cc1 = pyasl.crosscorrRV(dw, df, tw, tf, -30., 30., 60./100., skipedge=20, mode="doppler")
   rv2, cc2 = pyasl.crosscorrRV(dw, df, tw, tf, -30., 30., 60./100., skipedge=20, mode="lin")
   
   m1 = np.argmax(cc1)
   m2 = np.argmax(cc2)
   
   self.assertAlmostEqual(rv1[m1], rv2[m2], delta=1e-10)
   
   accu = 60./100.
   for dwl in np.linspace(-0.2,0.2,20):
     # Create the template
     tw = np.linspace(5000,5010,1000)
     tf = np.exp(-(tw-5004.0)**2/(2.*0.1**2))
   
     # Create data, which are not that well sampled
     dw = np.linspace(5000,5010,200)
     df = np.exp(-(dw-(5004.0+dwl))**2/(2.*0.1**2))
     
     rv1, cc1 = pyasl.crosscorrRV(dw, df, tw, tf, -30., 30., 60./100., skipedge=20, mode="doppler")
     rv2, cc2 = pyasl.crosscorrRV(dw, df, tw, tf, -30., 30., 60./100., skipedge=20, mode="lin")
     
     m1 = np.argmax(cc1)
     m2 = np.argmax(cc2)
     
     rv = dwl/np.mean(tw) * 299792.458
     
     self.assertAlmostEqual(rv1[m1], rv2[m2], delta=accu)
     self.assertAlmostEqual(rv1[m1], rv, delta=accu)
     self.assertAlmostEqual(rv2[m1], rv, delta=accu)
示例#4
0
def get_rv(shifted_flux_of_star, shifted_wavelength_of_star, flux_of_star,
           wavelength_of_star):
    rv, cc = pyasl.crosscorrRV(wavelength_of_star,
                               flux_of_star,
                               wavelength_of_star,
                               shifted_flux_of_star,
                               -300.,
                               300.,
                               5.,
                               skipedge=40)
    return rv[np.argmax(cc)]
示例#5
0
def velocity_shift(dw, df, tw, tf):
    '''Carry out the cross-correlation.
    The RV-range is -30 - +30 km/s in steps of 0.6 km/s.
    The first and last 20 points of the data are skipped.'''
    rv, cc = pyasl.crosscorrRV(dw, df, tw, tf, -40., 40., 0.01, skipedge=100)
    # Find the index of maximum cross-correlation function
    maxind = np.argmax(cc)
    print("Cross-correlation function is maximized at dRV = ", rv[maxind], " km/s")
    #plt.plot(rv, cc, 'bp-')
    #plt.plot(rv[maxind], cc[maxind], 'ro')
    #plt.show()
    return rv[maxind]
示例#6
0
def rv_correct(temp_lam, temp_spec, obs_lam, obs_spec):
    # Plot template and data
    #plt.title("Template (blue) and data (red)")
    #plt.plot(temp_lam, temp_spec, 'b.-')
    #plt.plot(obs_lam, obs_spec, 'r.-')
    #plt.show()

    ###############################################################
    ####            Carry out the cross-correlation.           ####
    ####The RV-range is -30 - +30 km/s in steps of 0.6 km/s.   ####
    #### The first and last 20 points of the data are skipped. ####
    ###############################################################
    rv, cc = pyasl.crosscorrRV(obs_lam,
                               obs_spec,
                               temp_lam,
                               temp_spec,
                               -30.,
                               30.,
                               30. / 50.,
                               skipedge=20)

    # Find the index of maximum cross-correlation function
    maxind = np.argmax(cc)

    print "Cross-correlation function is maximized at dRV = ", rv[
        maxind], " km/s"
    if rv[maxind] > 0.0: print " A red-shift with respect to the template"
    if rv[maxind] < 0.0: print " A blue-shift with respect to the template"
    if rv[maxind] < 1e-10: print "No shift"

    #plt.plot(rv, cc, 'bp-')

    #plt.plot(rv[maxind], cc[maxind], 'ro')
    #plt.show()

    c = 3.0 * 10**5  #speed of light
    RV_wavelength = obs_lam * (1. - rv[maxind] / c)

    try:
        f = interpolate.interp1d(RV_wavelength, obs_spec, kind='linear')
        return f(obs_lam)
    except ValueError:
        f = interpolate.interp1d(RV_wavelength,
                                 obs_spec,
                                 kind='linear',
                                 bounds_error=False,
                                 fill_value=1)
        return f(obs_lam)
示例#7
0
def ccf(wave, flux, mask='G2', rvmin=-300, rvmax=300, drv=0.1):
    """Compute the CCF of a spectrum.

    Based on PyAstronomy implementation of the cross-correlation.

    Parameters
    ----------
    wave: array_like
        The input wavelength array.
    flux: array_like
        The input flux array.
    mask: str
        The binary mask to use for the CCF. Options are G2, K0, K5 and M2
    rvmin: float, optional
        The minimum radial velocity to inspect in km/s. Default is -300 km/s
    rvmax: float, optional
        The maximum radial velocity to inspect in km/s. Default is 300 km/s
    drv: float, optional
        The radial velocity step. Default is 0.1 km/s

    Returns
    -------
    rvs: array_like
        The rv axis of the CCF.
    cc: array_like
        The median normalized CCF
    """
    # read mask, call crosscorr
    x1 = sp.arange(wave[0] - 200, wave[0], wave[1] - wave[0])
    x2 = sp.arange(wave[-1], wave[-1] + 200, wave[-1] - wave[-2])
    wtem = sp.hstack([x1, wave, x2])

    lines1, lines2, flux_l = sp.loadtxt('masks/' + mask + '.mas', unpack=True)
    ilines = sp.where((lines1 > wave[0]) & (lines2 < wave[-1]))[0]
    lines1_new = lines1[ilines]
    lines2_new = lines2[ilines]
    flux_l_new = flux_l[ilines]

    ftem = sp.zeros(wtem.size)

    for i in range(len(flux_l_new)):
        indices = sp.where((wtem >= lines1_new[i]) & (wtem <= lines2_new[i]))
        if indices[0].size > 0:
            ftem[indices[0]] = flux_l_new[i]
        del indices

    rvs, cc = pyasl.crosscorrRV(wave, flux, wtem, ftem, rvmin, rvmax, drv)
    return rvs, cc / sp.median(cc)
示例#8
0
def deconv_RL(f_tpl, w_tpl, bb=4):
    # Deconvolution of f_tpl using Richardson Lucy algorithm
    # needed for CRIRES data
    psf = np.ones((1, bb)) / bb
    f2 = f_tpl + 0.
    f_tpl1 = np.reshape(f_tpl, (1, -1))

    deconv_RL = restoration.richardson_lucy(f_tpl1 / np.max(f_tpl1) / 2.,
                                            psf,
                                            iterations=30)[0]
    f_tpl = deconv_RL * np.max(f_tpl1) * 2

    rv, ccc = pyasl.crosscorrRV(w_tpl[200:-200],
                                f_tpl[200:-200],
                                w_tpl[200:-200],
                                f2[200:-200],
                                -10.,
                                10.,
                                0.01,
                                skipedge=20)
    pol = (np.poly1d(np.polyfit(rv, ccc, 15)))(rv)
    shift = rv[np.argmax(pol)]

    print('shift RL:         ', shift, rv[np.argmax(ccc)])
    # there seems to appear a shift in the spectra after the deconvolution
    # why ???
    # correction ???
    # more testing needed, or another way of deconvolution

    plot_RL = 0
    if plot_RL:
        gplot(rv, ccc, 'w l,', rv, pol, 'w l')
        #  gplot(w_tpl, f2, 'w l,', w_tpl /(1+shift/3e5),f_tpl,'w l')
        pause()

#     w_tpl /= (1+shift/3e5)
    '''
        bo = 10
        f_tpl = f_tpl[bo:-bo]
        w_tpl = w_tpl[bo:-bo]
        f_ok = f_ok[bo:-bo]
        w_ok = w_ok[bo:-bo]
        x_ok = x_ok[bo:-bo]
        '''

    return f_tpl, w_tpl
示例#9
0
    def errfunc(x0, return_ccf=False):
        wave = polyval(x0, xpos)
        spec_i = -1 * (spec - 1)

        wave_template = arange(min(wave) - 150, max(wave) + 150, abs(x0[0]))

        template_i = interpolate.splev(
            wave_template, template_interp,
            ext=1)  ### interpolate the template spectrum
        template_i = normalise(
            template_i
        )  ### comment out this step if using normalised template spectrum
        template_i = -1 * (template_i - 1)

        #spec_i /= max(spec_i)
        #template_i /= max(template_i)

        mask = wave_template == wave_template

        drv, cc = pyasl.crosscorrRV(wave,
                                    spec_i,
                                    wave_template[mask],
                                    template_i[mask],
                                    -5000,
                                    +5000,
                                    1,
                                    mode='doppler',
                                    skipedge=0,
                                    edgeTapering=None)

        peak_loc = drv[argmax(cc)]
        mask = abs(drv - peak_loc) > 1000
        fit = polyfit(drv[mask], cc[mask], 2)
        fit = polyval(fit, drv)
        cc -= fit

        snr = (max(cc) - median(cc[mask])) / std(cc[mask])

        if return_ccf:
            return drv, cc
        else:
            print(x0, snr)
            #return -1*max(cc)
            return -1 * snr
示例#10
0
文件: rvMS.py 项目: dhitals/astro-py
def measure_rv(wdnum, spT, files):
    from PyAstronomy import pyasl    
    
    ## define paramters for cross-correlation
    c = 2.99792458e5                      ## speed of light in km/s
    box = 10.                             ## size of moving "box" for correlation
    bbox = 10*box                         ## size of window to CC
    ccRange = np.arange(5850.,6750.,bbox/2.) ## start of CC region -- 5850:6750
    nCC = np.size(ccRange)
    maxRV = 200 ## maximum possible value of RV -- absolute value

    # read the list of the spectra for that WD
    #wdnum = 'WD2350-081'
    #spT = 'K5V'

    # read the template spectra appropriate for that MS
    temWave, temFlux = readtem(spT)

    for fname in files:                    
        obsdate = fname[fname.find('_')+1 : fname.find('.fits')]
        wave, flux, hdr = readSpec(fname)    # read the object spectrum
        
        helio_corr = wave_helio(wave, hdr)   # correction to heliocentric velocity

        for j in np.arange(nCC-1):
            
            ind = (wave > ccRange[j]) & (wave < (ccRange[j] + bbox)) # select wave range

            if wave[ind].size > 1:
                c = 2.99792458e5 # speed of light in km/s
                R = wave[ind][0] / (wave[ind][1] - wave[ind][0])
                dv = c / R      ## velocity resolution per pixel in km/s         

                rv, cc = pyasl.crosscorrRV(wave[ind], flux[ind], temWave, temFlux, 
                                           -1.*maxRV, maxRV, dv, mode='doppler')

                # Find the index of maximum cross-correlation function
                maxind = np.argmax(cc)

                if abs(rv[maxind]) < maxRV:
                    print('%12s %3s %10s %.2f %i--%i %.2f %.2f' %(wdnum, spT, obsdate, helio_corr, ccRange[j], (ccRange[j]+bbox), 
                            dv, rv[maxind]+helio_corr))
示例#11
0
 def sanity_randomDIstribution(self):
   """
     Checking the shift with random numbers.
   """
   from PyAstronomy import pyasl
   import numpy as np
   
   # Create the template
   tw = np.linspace(10000,10010,100)
   tf = np.random.normal(0.0, 1.0, len(tw))
   
   dw = tw
   df = np.roll(tf, 2)
   
   rv1, cc1 = pyasl.crosscorrRV(dw, df, tw, tf, -30., 30., 60./1000., skipedge=20, mode="doppler")
   
   m1 = np.argmax(cc1)
   rv = (tw[2] - tw[0])/np.mean(tw) * 299792.458
   
   accu = 60./1000.
   self.assertAlmostEqual(rv1[m1], rv, delta=accu)
示例#12
0
def read_tapas(file_tapas, wl, flux, rvshift=False):
    raw_wl, raw_trans = np.loadtxt(file_tapas, skiprows=38, unpack=True)
    wl_tapas = raw_wl[::-1]
    trans_tapas = raw_trans[::-1]
    if rvshift:
        print('Doppler shift TAPAS transmission')
        rv, cc = pyasl.crosscorrRV(wl,
                                   flux,
                                   wl_tapas,
                                   trans_tapas,
                                   rvmin=-60.,
                                   rvmax=60.0,
                                   drv=0.1,
                                   mode='doppler',
                                   skipedge=50)
        maxind = np.argmax(cc)
        print("CCF is maximized at dRV = ", rv[maxind], " km/s")
        wlcorr_tapas = wl_tapas * (1. + rv[maxind] / 299792.)
        return wlcorr_tapas, trans_tapas
    else:
        return wl_tapas, trans_tapas
示例#13
0
def find_rv(wavelength,
            flux,
            mask_lines=[
                5371.50, 5394.64, 5397.10, 5405.80, 5409.80, 5429.70, 5432.55,
                5434.52, 5446.90, 5535.50, 6090.20, 6102.72, 6119.52, 6122.22
            ],
            delta_rv=200):
    wave_mask = np.arange(mask_lines[0] - 5., mask_lines[-1] + 5., 0.01)
    flux_mask = 1. + wave_mask * 0.0
    for line in mask_lines:
        flux_mask -= gaussian(wave_mask, line, 0.1)

    ind_wi = np.where(wavelength < wave_mask[0])[0][-1]
    ind_wf = np.where(wavelength > wave_mask[-1])[0][0]

    wave_t = wavelength[ind_wi:ind_wf]
    flux_t = flux[ind_wi:ind_wf]

    rv, cc = pyasl.crosscorrRV(wave_t,
                               flux_t,
                               wave_mask,
                               flux_mask,
                               -delta_rv,
                               delta_rv,
                               0.1,
                               skipedge=500)
    maxind = np.argmax(cc)

    # plt.figure(1)
    # plt.plot(wave_t,flux_t/np.median(flux_t))
    # plt.plot(wave_mask,flux_mask)
    # plt.figure(2)
    # plt.plot(rv, cc)
    # plt.show()
    # plt.plot(rv, cc, 'bp-')
    # plt.plot(rv[maxind], cc[maxind], 'ro')
    # plt.show()

    return rv[maxind]
示例#14
0
def pyfxcor(inspec, template, obj, vmin=-400., vmax=400., res=3, rej=200):
    
    rv, cc = pyasl.crosscorrRV(inspec[0], inspec[1], template[0], template[1],
                               vmin, vmax, res, skipedge=rej)
    
    cen_gs = np.argmax(cc)
    perfx, perfy = rv[cen_gs-5:cen_gs+6], cc[cen_gs-5:cen_gs+6]
    
    try:
        gauss = ConstantModel() + GaussianModel()
        pars = gauss.make_params()
        pars['center'].set(value=rv[np.argmax(cc)], vary=True)
        pars['amplitude'].set(value=max(cc), vary=True)
        pars['sigma'].set(vary=True)
        pars['c'].set(value=0, vary=True)
        out = gauss.fit(perfy, pars, x=perfx)
        ct = out.best_values['center']
        cterr = out.params['center'].stderr
    except:
        plt.plot(inspec[0], inspec[1])
        plt.savefig(obj+'.png', dpi=300)
        pl.clf()
        return 'error', ''
    
    plt.subplot(311)
    plt.plot(rv, cc)
    curraxlim = plt.axis()
    out.plot_fit(numpoints=100)
    plt.axis(curraxlim)
    plt.subplot(312)
    plt.plot(obj[1][0], obj[1][1], 'r-', linewidth=0.5)
    plt.subplot(313)
    plt.plot(inspec[0], inspec[1], 'b-', linewidth=0.5)
    plt.savefig(obj[0]+'.png', dpi=300)
    plt.clf()
    
    return ct, cterr
示例#15
0
def atm_model(w, f, berv, o):
    # divides spectra by atmosphere model
    # much more testing needed !
    modelfile = 'inst/CRIRES_atm/stdAtmos_crires_airmass1.fits'
    hdu = fits.open(modelfile, ignore_blank=True)
    atm_model = hdu[1].data
    w_atm2 = atm_model.field(0).astype(np.float64)
    f_atm2 = atm_model.field(1).astype(np.float64)

    #       file_obs2 = "data/CRIRES/210220_PiOri/cr2res_obs_nodding_extracted_combined.fits"
    file_obs2 = "/data/jana/VIPER/210220_tetVir/K2166/cr2res_obs_nodding_extracted_combined.fits"
    x2, w_atm, f_atm, bp2, bjd2, berv2 = Spectrum(file_obs2, o=o)
    bw = (np.load('wave_solution_tetvir.npy'))[o - 1]
    w_atm = np.poly1d(bw[::-1])(x2)

    #  bb = [-0.457193, 314.784913, 5675608.219445]
    ba = (np.load("lib/CRIRES/blaze_K2166.npy"))[o - 1]
    bandp = np.poly1d(ba)(x2)

    lmin = w[0]
    lmax = w[-1]
    lmin = max(w[0], w_atm[0])
    lmax = min(w[-1], w_atm[-1])

    smo = slice(*np.searchsorted(w_atm, [lmin, lmax]))
    w_atm1 = w_atm[smo]
    f_atm1 = f_atm[smo]
    smo = slice(*np.searchsorted(w, [lmin, lmax]))
    w = w[smo]
    f = f[smo]
    bandp = bandp[smo]

    gplot(w_atm, f_atm / np.nanmean(f_atm), 'w l t "tell",', w,
          f / np.nanmean(f), 'w l t "data",', w, bandp / np.mean(bandp) * 0.9,
          'w l t "bandp"')  #, w_atm1,f_atm1/np.nanmean(f_atm1),'w l')
    pause()

    # correction of shift between model and observed data
    rv, ccc = pyasl.crosscorrRV(w,
                                f,
                                w_atm1,
                                f_atm1,
                                -5.,
                                5.,
                                0.005,
                                skipedge=20)
    pol = (np.poly1d(np.polyfit(rv, ccc, 15)))(rv)
    shift = rv[np.argmax(pol)]
    print('shift atmmod: ', shift)
    print(w, w_atm1)
    w_atm /= (1 + shift / 3e5)
    smo = slice(*np.searchsorted(w_atm, [lmin, lmax]))
    w_atm1 = w_atm[smo]
    f_atm1 = f_atm[smo]

    print(w, w_atm1)

    f_atm1 = np.interp(w, w_atm1, f_atm1)

    #    f_div = f/np.nanmean(f)/(f_atm1/np.mean(f_atm1))
    f_div = f / f_atm1
    print('mean', np.nanmean(abs(f / np.mean(f) - f_div / np.mean(f_div))))
    i_flag = np.where(
        abs(f_div) <= (np.median(f_div) + 2 * np.std(abs(f_div))))[0]
    #      i_flag = np.where(abs(f/np.nanmean(f)-f_div/np.nanmean(f_div)) <= 0.2)[0]
    #    f_div[f_div<=0] = 1000
    #     i_flag = np.where(abs(f_div) <= (np.median(f_div)*1.5))[0]
    w1 = w * 1.
    w = w[i_flag]
    f = f[i_flag]
    f_div = f_div[i_flag]  #*np.median(f)

    plot_tell = 1
    if plot_tell:
        print('mean', np.nanmean(abs(f / np.mean(f) - f_div / np.mean(f_div))))
        #        gplot(w,f/np.mean(f),'w l,', w,f_atm1/np.mean(f_atm1),'w l')
        gplot(w, f / np.mean(f), 'w l t "data",', w, f_div / np.mean(f_div),
              'w l t "div data",', w1, f_atm1 / np.mean(f_atm1),
              'w l t "tell",', w,
              abs(f / np.nanmean(f) - f_div / np.nanmean(f_div)),
              'w p pt 7 ps 0.4 t "res"')
        pause()

    return w, f_div, i_flag  #f_atm
示例#16
0
def resolution(wave, flux, err, waverange,
               filter):  # determines spectral resolution

    from PyAstronomy.pyasl import crosscorrRV
    import numpy as np
    from scipy.optimize import curve_fit
    from scipy.signal import savgol_filter

    # gaussian for fitting CC to find width
    def gauss(x, a, b, x0, sigma):
        return a * np.exp(-(x - x0)**2 / (2 * sigma**2)) + b

    wave_temp_low = 0.97  # minimum wavelength in microns
    rvmin = -300.  # RV range
    rvmax = 300
    drv = 2.  # increment of RV
    c = 3.0e5  # speed of light in km/s
    minsr = 100  # minimum SNR
    nsmooth = 51
    resmin = 2000.  # minimum expected resolution

    max_wave = np.max(waverange) * (1 + 2 * rvmax / c)
    min_wave = np.min(waverange) * (1 + 2 * rvmin / c)
    which = ((wave > min_wave) & (wave < max_wave))
    wave_template = wave[which]
    flux_template = flux[which]
    err_template = err[which]
    smooth_template = savgol_filter(flux_template, nsmooth, 2)
    flux_template = flux_template / smooth_template
    err_template = err_template / smooth_template

    which = ((wave > np.min(waverange)) & (wave < np.max(waverange)))
    wave_target = wave[which]
    flux_target = flux[which]
    err_target = err[which]
    smooth_target = savgol_filter(flux_target, nsmooth, 2)
    flux_target = flux_target / smooth_target
    err_target = err_target / smooth_target

    rv, cc = crosscorrRV(wave_target,
                         flux_target,
                         wave_template,
                         flux_template,
                         rvmin,
                         rvmax,
                         drv,
                         mode='doppler')
    mean = sum(rv * cc) / sum(cc)
    sigma = np.sqrt(sum(cc * (rv - mean)**2) / sum(cc))
    base = np.min(cc)
    amp = np.max(cc) - base

    popt, pcov = curve_fit(gauss, rv, cc, p0=[amp, base, mean, sigma])
    sigma = popt[3]
    res = c / popt[3]
    print('Inferred SpeX resolution =', res)

    #import matplotlib.pyplot as plt
    #plt.plot(rv,cc,'k')
    #plt.plot(rv,gauss(rv,popt[0],popt[1],popt[2],popt[3]),'r')
    #plt.show(block='True')

    # return resolution and piece of spectrum to use to compare with models
    if (res < resmin):
        print('Setting resolution to minimum =', resmin)
        res = resmin
    res = 2 * res  # this is fudge-factor based on eye
    return res, wave_target, flux_target
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)
# Create the template
tw = np.linspace(5000,5010,1000)
tf = np.exp(-(tw-5004.0)**2/(2.*0.1**2))

# Create data, which are not that well sampled
dw = np.linspace(5000,5010,200)
df = np.exp(-(dw-5004.17)**2/(2.*0.1**2))

# Plot template and data
plt.title("Template (blue) and data (red)")
plt.plot(tw, tf, 'b.-')
plt.plot(dw, df, 'r.-')
plt.show()

# Carry out the cross-correlation.
# The RV-range is -30 - +30 km/s in steps of 0.6 km/s.
# The first and last 20 points of the data are skipped.
rv, cc = pyasl.crosscorrRV(dw, df, tw, tf, -30., 30., 30./50., skipedge=20)

# Find the index of maximum cross-correlation function
maxind = np.argmax(cc)

print "Cross-correlation function is maximized at dRV = ", rv[maxind], " km/s"
if rv[maxind] > 0.0:
  print "  A red-shift with respect to the template"
else:
  print "  A blue-shift with respect to the template"

plt.plot(rv, cc, 'bp-')
plt.plot(rv[maxind], cc[maxind], 'ro')
plt.show()
示例#19
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
示例#20
0
def dopp_signatures(templates, signals, axis, phase_fmt='int'):

    ### ----- LOAD DATA ----- ###

    templates = sorted(glob.glob(templates))
    signals = sorted(glob.glob(signals))

    phases = np.zeros(len(templates) + 1)
    RVs = np.zeros(len(templates) + 1)

    axis.set_xlim([-9, 9])
    axis.set_ylim([0, 10.6])

    # list of colors
    colors = np.linspace(0, 1, len(templates))

    # keep track of color and offset
    color_idx = 0
    offset = 0

    for i in range(len(templates)):

        # save orbital
        if phase_fmt == 'int':
            phase = int(templates[i][-7:-4])
        elif phase_fmt == 'float':
            phase = float(templates[i][-10:-4])
        else:
            print('ERROR\n Unrecognized phase format.')
            exit()

        print(phase)
        phases[i] = phase

        tw, tf = np.loadtxt(templates[i], unpack=True)
        dw, df = np.loadtxt(signals[i], unpack=True)
        #print(np.sum(tf))

        # Carry out the cross-correlation.
        # The RV-range is -10 to +10 km/s in steps of 0.1 km/s.
        # The first and last 200 points of the data are skipped.
        rv, cc = pyasl.crosscorrRV(dw,
                                   df,
                                   tw,
                                   tf,
                                   -10.,
                                   10.,
                                   0.1,
                                   mode='lin',
                                   skipedge=200)

        # normalize cc function
        cc = (cc - min(cc)) / (max(cc) - min(cc))

        # Find the index of maximum cross-correlation function
        maxind = np.argmax(cc)

        # define Gaussian function
        def gaussian(x, a, x0, sigma):
            return a * np.exp(-(x - x0) * (x - x0) / (2 * sigma * sigma))

        # fit Guassian to peak region of cc function
        rv_range = rv[maxind - 20:maxind + 20]
        cc_range = cc[maxind - 20:maxind + 20]

        popt, pcov = curve_fit(gaussian, rv_range, cc_range, p0=[1, 0, 1])

        # calculate best fit guassian
        rv_fit = np.linspace(rv[maxind - 20], rv[maxind + 20], 1000)
        cc_fit = gaussian(rv_fit, *popt)

        # index of maximum of Gaussian
        max_gauss = np.argmax(cc_fit)

        # save radial velocity
        RVs[i] = rv_fit[max_gauss]

        # plot CCFs
        axis.plot(rv, cc + offset, lw=1.5, color=my_colors(colors[color_idx]))
        axis.plot(rv_fit[max_gauss],
                  cc_fit[max_gauss] + offset,
                  '.',
                  ms=8,
                  color=my_colors(colors[color_idx]))

        offset += 0.4
        color_idx += 1

    phases[-1] = 360
    RVs[-1] = RVs[0]

    return RVs, phases
示例#21
0
test_rv = -15.205  # km/s

template_spectrum = Spectrum(xaxis=w_mod, flux=i_star, calibrated=True)
template_spectrum.wav_select(2100, 2200)

obs_spectrum = Spectrum(xaxis=w_mod, flux=i_star, calibrated=True)
obs_spectrum.doppler_shift(test_rv)
obs_spectrum.wav_select(2100, 2200)

print(len(obs_spectrum.xaxis))

rv, cc = pyasl.crosscorrRV(obs_spectrum.xaxis,
                           obs_spectrum.flux,
                           template_spectrum.xaxis,
                           template_spectrum.flux,
                           rvmin=-60.,
                           rvmax=60.0,
                           drv=0.1,
                           mode='doppler',
                           skipedge=2000)

maxind = np.argmax(cc)
print("Cross-correlation function is maximized at dRV = ", rv[maxind], " km/s")

# Test xcorr in spectrum
rv2, cc2 = obs_spectrum.crosscorr_rv(template_spectrum,
                                     rvmin=-60.,
                                     rvmax=60.0,
                                     drv=0.1,
                                     mode='doppler',
                                     skipedge=2000)
示例#22
0
    wav_band,
    R,
    flux_S,
    flux_T,
    flux_P,
    template_wav,
    template_flux,
    sigma_w=1e-3,
    I=1_000,
    N=10,
):

    P_obs = get_P_obs()

    # Compute v_max
    rv, cc = pyasl.crosscorrRV(wav, P_obs, template_wav, template_flux, -30,
                               30, 0.5)
    maxind = np.argmax(cc)
    v_max = rv[maxind]
    res = {
        "rv": rv,
        "cc": cc,
        "v_max": v_max,
        "wav": wav,
        "P_obs": P_obs,
        "C_in": C_in,
        "C_out": C_out,
        "sigma_w": sigma_w,
        "template_wav": template_wav,
        "template_flux": template_flux,
        "in_transit_samples": in_transit_samples,
        "out_of_transit_samples": out_of_transit_samples,
示例#23
0
plt.title("Spectrum (red) and the template (blue)")
plt.plot(spwl, spfl, 'r.-')
plt.plot(tpwl, tpfl, 'b.-')

plt.show()

# Carry out the cross-correlation.
# The RV-range is -rvmin to rvmax  km/s in steps of rvstep
# The first and last skipedge points of the data are skipped.

rv, cc = pyasl.crosscorrRV(spwl,
                           spfl,
                           tpwl,
                           tpfl,
                           rvmin,
                           rvmax,
                           rvstep,
                           mode='doppler',
                           skipedge=skip)

# Find the index of maximum cross-correlation function

maxind = np.argmax(cc)

print("Cross-correlation function is maximized at relative RV = ", rv[maxind],
      " (km/s)")
if rv[maxind] > 0.0:
    print("  This is a red-shift  with respect to the template.")
else:
    print("  This is a blue-shift with respect to the template.")
示例#24
0
def build_grid(gridfile, nbest, res, wave, ebv, flux, err, filter, wave_rv,
               flux_rv, feh, feh_err):

    # build the comparison grid of models

    import matplotlib.pyplot as plt
    import numpy as np
    from scipy.interpolate import interp1d
    from astropy.convolution import convolve, Gaussian1DKernel
    from scipy.signal import savgol_filter
    from PyAstronomy.pyasl import crosscorrRV
    from PyAstronomy.pyasl import vactoair2 as vactoair
    from extinction import fm07, apply

    from astropy.io import fits

    print('Building the Grid....')

    nn = 10
    rvmax = 400
    rvmin = -400
    drv = 2.
    c = 3.0e5
    gauss_kernel = Gaussian1DKernel(nn)

    # load the grid
    f = fits.open('../Grid/' + gridfile)
    g = f[1].data
    #header = g['HEADER'][0]
    modelspec = g['SPECTRUM'][0]
    teff = np.array(g['TEFF'][0])
    logg = np.array(g['LOGG'][0])
    metal = np.array(g['METAL'][0])
    a_fe = np.array(g['A_FE'][0])

    #junk = header[8]
    #junk = np.array(junk.split())
    #nlambda = int(np.asscalar((junk[2])))
    #junk = header[9]
    #junk = np.array(junk.split())
    #lambda0 = float(np.asscalar(junk[1]))
    #junk = header[10]
    #junk = np.array(junk.split())
    #dlambda = float(np.asscalar(junk[1]))
    #modelwave = lambda0 + dlambda*np.arange(nlambda) # for original PHOENIX
    modelwave = np.array(g['WAVE'][0])  # for Goettingen PHOENIX
    nwave, nmodels = modelspec.shape
    nwave = int(nwave)
    nmodels = int(nmodels)

    model_vac = np.array(
        modelwave)  # convert wavelengths from vacuum to air and to microns
    model_vac2 = model_vac.compress(model_vac > 2000.)
    model_wave = vactoair(model_vac2,
                          mode='edlen53') / 10000.  # convert to air
    npts = nn * res * np.log(np.max(model_wave) / np.min(model_wave))
    wave_log = np.min(model_wave) * np.exp(
        np.arange(npts) /
        (1. * npts) * np.log(np.max(model_wave) / np.min(model_wave)))

    av = ebv * 3.1
    #extinct_all = extinction.fm07(wave*10000.,av)/av_ref   # approximate extinction per unit magnitude
    #extinct = extinct_all.compress(filter==1)

    #model_compare = []
    rvbest = []
    chisq = []
    #avmodels = []
    #av_max = 4.
    #av_values = av_max*np.arange(100)/100.

    for imodel in np.arange(nmodels):

        model_spec = np.array(
            modelspec[:, imodel]) * 1.0e-8  # convert from per cm to per A
        model_spec = model_spec.compress(model_vac > 2000.)
        #model_spec = model_spec*10**(-0.4*extinction.fm07(model_vac,av)) # apply extinction  (EXPERIMENTAL)

        # interpolation function
        model_interp = interp1d(model_wave,
                                model_spec,
                                kind='linear',
                                bounds_error=False,
                                fill_value=0.)
        model_prelim = model_interp(wave)
        model_prelim = apply(fm07(wave * 10000, ebv, 3.1), model_prelim)
        fr = flux.compress(filter == 1.) / model_prelim.compress(filter == 1)

        # here we need to determine best-fit extinction
        #x = []

        #for av_val in av_values:
        #    x1 = np.sum(fr*10**(-0.4*extinct*av_val))/np.sum(10**(-0.8*extinct*av_val))
        #    x2 = np.sum(extinct*fr*10**(-0.4*extinct*av_val))/np.sum(extinct*10**(-0.8*extinct*av_val))
        #    x.append(abs(x1/x2-1.))
        #av_best = av_values[np.argmin(x)]
        #avmodels.append(av_best)

        #ratval = np.sum(fr*10**(-0.4*extinct*av_best))/np.sum(10**(-0.8*extinct*av_best))*10**(-0.4*extinct*av_best)
        ratval = np.median(fr)
        model_prelim = model_prelim.compress(filter == 1) * ratval
        sig = (flux.compress(filter == 1) -
               model_prelim) / err.compress(filter == 1)
        #plt.plot(wave.compress(filter==1),err.compress(filter==1))
        #plt.show(block=True)
        chisqval = np.sum(sig**2) * (1 + (
            (feh - metal[imodel]) / feh_err)**2)  # disabled for now
        chisq.append(chisqval)
        print('Model params =', teff[imodel], logg[imodel], metal[imodel],
              av_best, chisqval)

    indices = np.argsort(chisq)
    bestmodels = indices[0:nbest]
    chisq = np.array(chisq)

    teffbest = np.sort(np.unique(teff[bestmodels]))
    loggbest = np.sort(np.unique(logg[bestmodels]))
    metalbest = np.sort(np.unique(metal[bestmodels]))
    #avmodels = np.array(avmodels)
    #avbest = np.sort(np.unique(avmodels[bestmodels]))
    #print('Best Av = ',avmodels[indices[0]])

    bestparams = [teff[indices[0]], logg[indices[0]], metal[indices[0]]]
    print('Best parameters = ', bestparams)
    plt.pause(5)
    teffmin = np.min(teffbest)
    teffmax = np.max(teffbest)
    loggmin = np.min(loggbest)
    loggmax = np.max(loggbest)
    metalmin = np.min(metalbest)
    metalmax = np.max(metalbest)
    if teffmin == teffmax:
        teffmin = teffmin - 100.
        teffmax = teffmax + 100.
    if loggmin == loggmax:
        loggmin = loggmin - 0.5
        loggmax = loggmax + 0.5
    if metalmin == metalmax:
        metalmin = metalmin - 0.5
        metalmax = metalmax + 0.5

    gridmodels = np.arange(nmodels).compress((teff >= teffmin)
                                             & (teff <= teffmax)
                                             & (logg >= loggmin)
                                             & (logg <= loggmax)
                                             & (metal >= metalmin)
                                             & (metal <= metalmax))

    grid = np.zeros((len(teffbest), len(loggbest), len(metalbest), len(wave)))

    print('Creating subgrid with ', len(gridmodels), ' models')
    for imodel in gridmodels:
        model_spec = np.array(
            modelspec[:, imodel]) * 1.0e-8  # convert from per cm to per A
        model_spec = model_spec.compress(model_vac > 2000.)

        # interpolate model spectrum to logarithmic wavelengths
        model_interp = interp1d(model_wave,
                                model_spec,
                                kind='linear',
                                bounds_error=False,
                                fill_value=0.)
        model_log = model_interp(wave_log)
        model_conv = convolve(model_log,
                              gauss_kernel)  # convolve model with Gaussian
        smooth_model = savgol_filter(model_conv, 501, 2)
        model_norm = model_conv / smooth_model
        wavelim = wave_log.compress((wave_log < 1.01 * np.max(wave_rv))
                                    & (wave_log > 0.99 * np.min(wave_rv)))
        modellim = model_norm.compress((wave_log < 1.01 * np.max(wave_rv))
                                       & (wave_log > 0.99 * np.min(wave_rv)))

        # find Doppler shift of model
        rv, cc = crosscorrRV(wave_rv,
                             flux_rv,
                             wavelim,
                             modellim,
                             rvmin,
                             rvmax,
                             drv,
                             mode='doppler')
        index = np.argmax(cc)

        rvbest.append(rv[index])
        wave_shift = wave_log * (1 + rv[index] / c)

        model_interp = interp1d(wave_shift,
                                model_conv,
                                kind='linear',
                                bounds_error=False,
                                fill_value=0.)

        i = np.arange(len(teffbest)).compress(teff[imodel] == teffbest)
        j = np.arange(len(loggbest)).compress(logg[imodel] == loggbest)
        k = np.arange(len(metalbest)).compress(metal[imodel] == metalbest)
        #gridflux = model_interp(wave)*10**(-0.4*extinct_all*np.asscalar(avmodels[imodel])) # apply extinction at this step for consistency with the chi-squared minimization
        gridflux = model_interp(wave)
        grid[i, j, k, :] = gridflux

    return teffbest, loggbest, metalbest, grid, rvbest, bestparams
示例#25
0
path_dump = PCA._path + dump
PCA.setup(dump, PCA.lambda_polar, Resolution, "synspec")

lst_size = len(lst)
ii = 0

for i in lst:
    print str(ii + 1) + "/" + str(np.size(lst))
    star = lst[ii][12:]
    spec = np.loadtxt(i)

    noise = der_snr.DER_SNR(spec[:, 1])
    radialv, cc = pyasl.crosscorrRV(spec[:, 0],
                                    spec[:, 1],
                                    temp[:, 0],
                                    temp[:, 1],
                                    -200.,
                                    200.,
                                    0.1,
                                    skipedge=200)
    maxind = np.argmax(cc)
    print "Cross-correlation function is maximized at dRV = ", radialv[
        maxind], " km/s for", str(star), "with a noise of", round(noise, 4)

    spec_rvcor = PCA.rv_cor(spec[:, 1], spec[:, 0], float(radialv[maxind]))
    index_c, specc = PCA.inversion(spec_rvcor, cont=True)

    # In case we want to save the spectra with the corrected normalization and the best fit
    np.savetxt("corrected_gaz/" + str(star) + "_polar",
               np.array([PCA.wavelength, specc,
                         PCA.getspec(index_c)]).T)
    def calc_log_L_CC(self, wlen, flux, temp_params, data_wlen, data_flux,
                      data_N, data_sf2):

        log_L_CC = 0

        # get data
        wlen_data, flux_data = data_wlen, data_flux

        N = data_N
        s_f2 = data_sf2

        # cut what I don't need to improve speed
        #wlen_cut,flux_cut = trim_spectrum(wlen,flux,wlen_data,threshold=5000,keep=1000)

        wlen_removed, flux_removed, sgfilter, wlen_rebin, flux_rebin = rebin_to_CC(
            wlen,
            flux,
            wlen_data,
            win_len=self.config['WIN_LEN'],
            method='linear',
            filter_method='only_gaussian',
            convert=self.config['CONVERT_SINFONI_UNITS'],
            log_R=temp_params['log_R'],
            distance=self.config['DISTANCE'])

        if sum(np.isnan(flux_rebin)) > 0:
            self.NaN_spectRES += 1
            log_L_CC += -np.inf

        assert (len(wlen_removed) == len(flux_removed))

        if sum(np.isnan(flux_removed)) > 0:
            self.NaN_savgolay += 1
            log_L_CC += -np.inf
        # cross-correlation
        dRV, CC = crosscorrRV(wlen_data,
                              flux_data,
                              wlen_removed,
                              flux_removed,
                              rvmin=self.config['RVMIN'],
                              rvmax=self.config['RVMAX'],
                              drv=self.config['DRV'])

        if sum(np.isnan(CC) > 0):
            self.NaN_crosscorrRV += 1
            log_L_CC += -np.inf

        CC = CC / N
        RV_max_i = np.argmax(CC)
        CC_max = CC[RV_max_i]

        if self.plotting:
            if (self.function_calls % self.config['PLOTTING_THRESHOLD'] == 0):
                plt.figure()
                plt.plot(dRV, CC)
                plt.axvline(dRV[RV_max_i],
                            color='r',
                            label='Max CC at RV={rv}'.format(rv=dRV[RV_max_i]))
                plt.legend()
                plt.title('C-C ' + str(
                    int(self.function_calls /
                        self.config['PLOTTING_THRESHOLD'])))
                plt.savefig(self.output_path + 'model/CC_fct_' + str(
                    int(self.function_calls /
                        self.config['PLOTTING_THRESHOLD'])) + '.png',
                            dpi=100)

        # need to doppler shift the model to the argmax of the CC-function. For that, we need to go back to high-resolution spectrum out of petitRADTRAS

        wlen_removed, flux_removed = wlen, flux
        if abs(dRV[RV_max_i]) < max(abs(self.config['RVMIN']),
                                    abs(self.config['RVMAX'])) * 0.75:
            wlen_removed, flux_removed = doppler_shift(wlen, flux,
                                                       dRV[RV_max_i])
        else:
            print('Cant Dopplershift too much')
            self.nb_failed_DS += 1

        wlen_removed, flux_removed, sgfilter, wlen_rebin, flux_rebin = rebin_to_CC(
            wlen_removed,
            flux_removed,
            wlen_data,
            win_len=self.config['WIN_LEN'],
            method='datalike',
            filter_method='only_gaussian',
            convert=self.config['CONVERT_SINFONI_UNITS'],
            log_R=temp_params['log_R'],
            distance=self.config['DISTANCE'])

        assert (len(wlen_removed) == len(wlen_data))

        s_g2 = 1. / len(flux_removed) * np.sum(flux_removed**2)

        if (s_f2 - 2 * CC_max + s_g2) <= 0:
            self.NaN_crosscorrRV += 1
            log_L_CC += -np.inf
            print('Negative values inside logarithm')
        log_L_CC += -N * np.log(s_f2 - 2 * CC_max + s_g2) / 2

        return log_L_CC, wlen_removed, flux_removed, sgfilter
示例#27
0
def dopp_signatures(templates, signals, phase_fmt='int'):

    ### ----- LOAD DATA ----- ###

    templates = sorted(glob.glob(templates))
    signals = sorted(glob.glob(signals))

    phases = np.zeros(len(templates) + 1)
    RVs = np.zeros(len(templates) + 1)

    # set up CCF figure
    font = {'size': 14, 'family': 'serif'}
    plt.rc('font', **font)

    CCF_fig, ax = plt.subplots(1, 1, figsize=(10, 10))
    ax.set_ylabel('Doppler shift [km s$^{-1}$]')
    ax.set_xlabel('Phase angle [degrees]')
    ax.set_ylim([-10, 10])
    ax.set_xlim([-75, 360])

    ax_cc = ax.twiny()
    ax_cc.set_ylim([-5, 5])
    ax_cc.set_xlim([0, 5.8])
    ax_cc.set_xlabel('Cross correlation + constant')

    # add colorbar
    sm = plt.cm.ScalarMappable(cmap=plt.cm.jet,
                               norm=plt.Normalize(vmin=0, vmax=1))
    sm._A = []
    cbar = plt.colorbar(sm)
    cbar.ax.set_ylabel('Orbital phase')

    # list of colors
    colors = np.linspace(0, 1, len(templates))

    # keep track of color and offset
    color_idx = 0
    offset = 0

    for i in range(len(templates)):

        # save orbital
        if phase_fmt == 'int':
            phase = int(templates[i][-7:-4])
        elif phase_fmt == 'float':
            phase = float(templates[i][-10:-4])
        else:
            print('ERROR\n Unrecognized phase format.')
            exit()

        print(phase)
        phases[i] = phase

        tw, tf = np.loadtxt(templates[i], unpack=True)
        dw, df = np.loadtxt(signals[i], unpack=True)
        '''
		# Plot template and data in real time
		plt.plot(tw, tf, 'b-', label='Rest-frame (template)')
		plt.plot(dw, df, 'r-', label='Shifted')
		plt.legend()
		plt.xlim([2.311e-6, 2.313e-6])
		plt.ylim([0, 5e-9])
		plt.title(f'$\\varphi=${phase}')

		plt.plot()
		plt.show(block=False)
		plt.pause(0.01)
		plt.close()
		'''

        # Carry out the cross-correlation.
        # The RV-range is -10 to +10 km/s in steps of 0.1 km/s.
        # The first and last 200 points of the data are skipped.
        rv, cc = pyasl.crosscorrRV(dw,
                                   df,
                                   tw,
                                   tf,
                                   -10.,
                                   10.,
                                   0.1,
                                   mode='lin',
                                   skipedge=200)

        # normalize cc function
        cc = (cc - min(cc)) / (max(cc) - min(cc))

        # Find the index of maximum cross-correlation function
        maxind = np.argmax(cc)

        # define Gaussian function
        def gaussian(x, a, x0, sigma):
            return a * np.exp(-(x - x0) * (x - x0) / (2 * sigma * sigma))

        # fit Guassian to peak region of cc function
        rv_range = rv[maxind - 20:maxind + 20]
        cc_range = cc[maxind - 20:maxind + 20]
        popt, pcov = curve_fit(gaussian, rv_range, cc_range, p0=[1, 0, 1])

        # calculate best fit guassian
        rv_fit = np.linspace(rv[maxind - 20], rv[maxind + 20], 1000)
        cc_fit = gaussian(rv_fit, *popt)

        # index of maximum of Gaussian
        max_gauss = np.argmax(cc_fit)

        # save radial velocity
        RVs[i] = rv_fit[max_gauss]

        # plot CCFs
        ax_cc.plot(cc + offset, rv, lw=2, color=plt.cm.jet(colors[color_idx]))
        ax_cc.plot(cc[maxind] + offset,
                   rv[maxind],
                   'x',
                   color=plt.cm.jet(colors[color_idx]))

        ax_cc.plot(cc_fit + offset, rv_fit, 'k-', alpha=0.5)
        ax_cc.plot(cc_fit[max_gauss] + offset,
                   rv_fit[max_gauss],
                   'kx',
                   alpha=0.5)

        offset += 0.1
        color_idx += 1
        '''
		# print stuff and plot
		print("Cross-correlation function is maximized at dRV = ", rv_fit[max_gauss], " km/s")
		if rv_fit[max_gauss] > 0.0:
		  print("  A red-shift with respect to the template")
		else:
		  print("  A blue-shift with respect to the template")

		plt.plot(rv, cc, 'b-')
		plt.plot(rv[maxind], cc[maxind], 'bx')

		plt.plot(rv_fit, cc_fit, 'r-')
		plt.plot(rv_fit[max_gauss], cc_fit[max_gauss], 'rx')

		plt.title(f'$\\varphi$ = {phase}')
		plt.xlabel('Doppler shift [km/s]')
		plt.ylabel('Cross correlation')

		plt.show()
		'''

    phases[-1] = 360
    RVs[-1] = RVs[0]

    # plot RV line
    ax.set_zorder(2)
    ax.patch.set_visible(False)
    ax.plot(phases, RVs, 'r', lw=2)
    ax.plot(phases - 360, RVs, 'r', lw=2)

    # horizontal line
    ax.axhline(0, color='k', lw=1, ls='--', zorder=0)

    #plt.show()

    #CCF_fig.savefig(savefile, bbox_inches='tight', dpi=300)

    return phases, RVs
示例#28
0
def fit_echelle_solution_recc(initial_solutions, norders, spectrum, wshift=0):

    fit_w0, sigma = echelle_equation_fit_sigclip(initial_solutions[:, 0],
                                                 initial_solutions[:, 2])
    print(fit_w0)

    fit_deltaA = median(initial_solutions[:, 1] /
                        echelle_equation(fit_w0, initial_solutions[:, 0]))
    print(fit_deltaA)

    initial_solutions = transpose(
        array([
            arange(0, norders),
            echelle_equation(fit_w0, arange(0, norders)),
            fit_deltaA * echelle_equation(fit_w0, arange(0, norders))
        ]))

    for order in range(len(initial_solutions)):
        x0 = initial_solutions[order]

        spec = spectrum[order]
        xpos = arange(len(spec)) - len(spec) / 2
        mask = xpos > min(xpos) + 10
        mask *= xpos < max(xpos) - 10

        spec -= min(spec)
        spec = normalise(spec[mask], deg=10)
        xpos = xpos[mask]

        wave = polyval([x0[2], x0[1]], xpos)
        spec_i = -1 * (spec - 1)

        wave_template = arange(min(wave) - 150, max(wave) + 150, abs(x0[2]))

        template_i = interpolate.splev(
            wave_template, template_interp,
            ext=1)  ### interpolate the template spectrum
        template_i = normalise(
            template_i
        )  ### comment out this step if using normalised template spectrum
        template_i = -1 * (template_i - 1)

        #spec_i /= max(spec_i)
        #template_i /= max(template_i)

        mask = wave_template == wave_template

        try:

            drv, cc = pyasl.crosscorrRV(wave,
                                        spec_i,
                                        wave_template[mask],
                                        template_i[mask],
                                        -5000,
                                        +5000,
                                        1,
                                        mode='doppler',
                                        skipedge=0,
                                        edgeTapering=None)

            epos = pyasl.quadExtreme(drv,
                                     cc,
                                     mode='max',
                                     dp=(10, 10),
                                     exInd=None,
                                     fullOutput=False,
                                     fullPoint=False)[0]
            epos -= wshift
            wcenter = x0[1] - epos * x0[1] / c
        except:
            print("Could not cross correlate order", order)
        print(wcenter, x0[1])
        initial_solutions[order, 1] = wcenter

    fit_w0, sigma = echelle_equation_fit_sigclip(initial_solutions[:, 0],
                                                 initial_solutions[:, 1])
    print(fit_w0)

    fit_deltaA = median(initial_solutions[:, 2] /
                        echelle_equation(fit_w0, initial_solutions[:, 0]))
    print(fit_deltaA)

    initial_solutions = transpose(
        array([
            arange(0, norders),
            echelle_equation(fit_w0, arange(0, norders)),
            fit_deltaA * echelle_equation(fit_w0, arange(0, norders))
        ]))

    # plt.subplot(221)
    # plt.scatter(initial_solutions[:,0],initial_solutions[:,2])
    # plt.plot(arange(0,norders),echelle_equation(fit_w0,arange(0,norders)))

    # plt.subplot(222)
    # plt.scatter(initial_solutions[:,0],initial_solutions[:,2]-echelle_equation(fit_w0,initial_solutions[:,0]))

    # plt.subplot(223)
    # plt.scatter(initial_solutions[:,0],initial_solutions[:,1])
    # plt.plot(arange(0,norders),fit_deltaA*echelle_equation(fit_w0,arange(0,norders)))

    # plt.subplot(224)
    # plt.scatter(initial_solutions[:,0],initial_solutions[:,1]-fit_deltaA*initial_solutions[:,2])

    # #plt.savefig("echelle_equation_fit.pdf")
    # #plt.show()

    return initial_solutions
示例#29
0
"""
test = radial_velocity(dw, df, de, # spectral data on your target (uncertainty is NOT SNR)
                       tw, tf, te, # spectral data on a star with known RV, in the same (or at least overlapping) wavelength region
                       'HR_4521', 'HR_260', # their names, for the plots (see point 2 below for details)
                       0.3, 0.01, # the radial velocity of the standard, for the plots
                       1, # for the plots. Should be the same for both.
                       200, # set to 200 for 'default', see point 3 below for what this means
                       0, 0, 0) # set all to zero by default. See point 4 below for what this means

print(test)
"""

# Carry out the cross-correlation.
# The RV-range is -30 - +30 km/s in steps of 0.6 km/s.
# The first and last 20 points of the data are skipped.
# rv, cc = pyasl.crosscorrRV(dw, df, tw, tf, -30., 30., 30./50., skipedge=20)
rv, cc = pyasl.crosscorrRV(dw_cut, df_cut, tw, tf, -100., 100., 30./50, skipedge=20)

# Find the index of maximum cross-correlation function
maxind = np.argmax(cc)

print("Cross-correlation function is maximized at dRV = ", rv[maxind], " km/s")
if rv[maxind] > 0.0:
  print("  A red-shift with respect to the template")
else:
  print("  A blue-shift with respect to the template")

plt.plot(rv, cc, 'bp-')
plt.plot(rv[maxind], cc[maxind], 'ro')
plt.show()