Esempio n. 1
0
def p2d(p,farr,ph):
    """
    Shows the power for the BLS 2D spectrum
    """

    # first index is plotted as y,this should be the other way around
    

    p = np.swapaxes(p,0,1)
    f = plt.gcf()
    f.clf()

    # create two axes, one for the image, the other for the profile.
    r1d = [0.1,0.75,0.8,0.2]
    r2d = [0.1,0.1,0.8,0.65]

    ax1d = plt.axes(r1d)
    ax2d = plt.axes(r2d,sharex=ax1d)

    power = np.max(p,axis=0)
    ax1d.plot(farr,power)
    ax1d.set_ylabel('Power') 


    ax2d.pcolorfast(farr,ph,p)
    ax2d.set_xlabel('frequency days^-1') 
    ax2d.set_ylabel('phase of trans / 2 pi') 


    plt.show()
Esempio n. 2
0
def bbfold(P):
    

    # Trial Data:
    tbase = 90.
    f,t = keptoy.lightcurve(tbase=tbase,s2n=5,P=10.1)
    
    o = pbls.blswrap(t,f,blsfunc=blsw.blsw)
    farr = linspace(min(o['farr']),max(o['farr']),100)
    sig = zeros(len(f)) + std(f)

 #   for fq in farr:

    tfold = mod(t,P) # Fold according to trial period.
    sidx = argsort(tfold)
    tfold = tfold[sidx]
    ffold = f[sidx]

    last,val = find_blocks.pt(tfold,ffold,sig,ncp=8)

    fig = plt.gcf()
    fig.clf()

    ax = fig.add_subplot(111)
    ax.plot(tfold,ffold,'o',ms=1,alpha=0.5)

    cp = unique(last)
    n = len(t)
    idxlo = cp                    # index of left side of region
    idxhi = append(cp[1:],n)-1 # index of right side of region         
    ax.hlines(val[idxhi],tfold[idxlo],tfold[idxhi],'red',lw=5)
    ax.set_ylabel('Flux (normalized)')

    plt.show()
Esempio n. 3
0
def blsbb():
    """
    Simulate a time series.  Compare two bls spectra.

    1. Normal BLS
    2. Blocks returned by BB

    Also plot the timeseries.

    """


    s2n = logspace(0.5,2,8)

    for i in range( len(s2n) ):

        f,t = keptoy.lightcurve(s2n = s2n[i],tbase=600)

        sig = zeros(len(t)) + std(f)
        last,val =  find_blocks.pt(t,f,sig,ncp=5)
        fb = bb.get_blocks(f,last,val)

        o = pbls.blswrap(t,f,blsfunc=blsw.blsw,nf=1000)
        ob = pbls.blswrap(t,fb,blsfunc=blsw.blsw,nf=1000)

        fig = plt.gcf()
        fig.clf()


        ax = fig.add_subplot(211)


        ax.plot(t,f+1,'o',ms=1,alpha=0.5)
        
        cp = unique(last)
        n = len(t)
        idxlo = cp                    # index of left side of region
        idxhi = append(cp[1:],n)-1 # index of right side of region         
        ax.hlines(val[idxhi],t[idxlo],t[idxhi],'red',lw=5)
        ax.set_ylabel('Flux (normalized)')
        ax.set_xlabel('Flux (normalized)')



        ax = fig.add_subplot(212)
        ax.plot(o['farr'],o['p']    ,label = 'BLS')
        ax.plot(ob['farr'],ob['p']  ,label = 'BLS + BB')
        ax.set_xlabel('Frequency days^-1')
        ax.set_ylabel('SR')
        ax.legend()

        fig.text(0.9,0.9, "S/N - %.1e" % (s2n[i]) ,
                 ha="center",fontsize=36,
                 bbox=dict(boxstyle="round", fc="w", ec="k"))

        fig.savefig('frames/blsbb%02d.png' % i)
        plt.show()
Esempio n. 4
0
 def plot_graph(self, auroc_results, y_label: str):
     for ad_key, ad_label in AD_NAMES.items():
         plt.plot(self.x_axis,
                  numpy.asarray(auroc_results[ad_key], ),
                  label=ad_label)
     plt.legend(loc='lower left')
     plt.xlabel(self.x_axis_label)
     plt.ylabel(ylabel=y_label)
     to_print = plt.gcf()
     plt.show()
     file_name_with_metric = y_label + "-" + self.file_name
     to_print.savefig(file_name_with_metric, bbox_inches='tight')
Esempio n. 5
0
def perfind2():
    
    P = 200.
    tbase = 1000.
    nf = 5000


    s2n = logspace( log10(3),log10(15),5 )
    print "S/N sig-noise noise-noise" 
    for s in s2n:
        # Generate a lightcurve.
        f,t = keptoy.lightcurve(P=P,tbase=tbase,s2n=s)
        o = blsw.blswrap(t,f,nf=nf,fmax=1/50.)

        # Subtract off the trend
        o['p'] -= median_filter(o['p'],size=200)

        # Find the highest peak.
        mxid = argmax(o['p'])
        mxpk = o['p'][mxid]

        # Find all the peaks        
        mxt,mnt = peakdet(o['p'],delta=1e-3*mxpk,x=o['parr'])
        mxt = array(mxt)

        # Restrict attention to the highest 100 but leaving off top 10
        t1id = where( (mxt[::,1] > sort( mxt[::,1] )[-100]) &
                      (mxt[::,1] < sort( mxt[::,1] )[-10]) )



        fig = plt.gcf()
        fig.clf()
        ax = fig.add_subplot(111)
        ax.plot(o['parr'],o['p'],label='Signal')
        ax.scatter( mxt[t1id,0],mxt[t1id,1],label='Tier 1' )
        
        # tpyical values of the highest 100 peaks.
        hair = median(mxt[t1id,1]) 


        left  = min(o['parr'])
        right  = max(o['parr'])
        ax.hlines(hair,left,right)

        if mxpk > 3*hair:
            print "Peroid is %.2f" % (o['parr'][mxid])
        else:
            print "No signal"
        
        ax.legend()
        plt.show()
Esempio n. 6
0
def phasemov():

    parr=np.linspace(0,2*pi,30)
    for i in range(len(parr)):
        f,t = keptoy.lightcurve(s2n=1000,P=10.,phase=parr[i])

        nf,fmin,df,nb,qmi,qma,n = pbls.blsinit(t,f,nf=1000)
        p,farr,ph = blsw.blswph(t,f,nf,fmin,df,nb,qmi,qma,n)
        p2d(p,farr,ph)

        f = plt.gcf()
        f.text(0.8,0.7, "EEBLS Phase %.2f" % (parr[i]) ,ha="center",
               bbox=dict(boxstyle="round", fc="w", ec="k"))
        f.savefig('frames/ph%02d.png' % i)
        
        plt.show()
Esempio n. 7
0
def phasemov():
    ph=linspace(0,2*pi,30)
    for i in range(len(ph)):
        f,t = keptoy.lightcurve(s2n=1000,P=10.,phase=ph[i])

        nf,fmin,df,nb,qmi,qma,n = pbls.blsinit(t,f,nf=1000)
        p = blswph(t,f,nf,fmin,df,nb,qmi,qma,n)
        f = plt.gcf()
        f.clf()
        ax = f.add_subplot(111)
        ax.imshow(p,aspect='auto')

        ax.set_xlabel('bin number of start of transit')
        ax.set_ylabel('frequency')
        ax.set_title('2D BLS spectrum - phase %.2f' % ph[i])
        f.savefig('frames/ph%02d.png' % i)

        plt.show()
Esempio n. 8
0
def perfind():
    """
    Test how good the KS test is at descriminating a real planet from
    a none.    
    """

    P = 200.
    tbase = 1000.
    nf = 500

    s2n = logspace( log10(3),log10(15),5 )
    print "S/N sig-noise noise-noise" 
    for s in s2n:
        # Generate a lightcurve.
        f,t = keptoy.lightcurve(P=P,tbase=tbase,s2n=s)
        o = blsw.blswrap(t,f,nf=nf,fmax=1/50.)

        # Generate a null lightcurve
        fn = std(f)*random.randn(len(f))
        on = blsw.blswrap(t,fn,nf=nf,fmax=1/50.)

        # Generate another null lightcurve
        fn2 = std(f)*random.randn(len(f))
        on2 = blsw.blswrap(t,fn2,nf=nf,fmax=1/50.)

        o['p'] -= median_filter(o['p'],size=200)
        on['p'] -= median_filter(on['p'],size=200)
        on2['p'] -= median_filter(on2['p'],size=200)
        
        print "%.2f %.2e %.2e %.2f" % \
            (s,(ks_2samp(o['p'],on['p']))[1],(ks_2samp(o['p'],on2['p']))[1],
             o['parr'][argmax(o['p'])])
        

        fig = plt.gcf()
        fig.clf()
        ax = fig.add_subplot(111)
        ax.plot(o['parr'],o['p'],label='Signal')
        ax.plot(o['parr'],on['p'],label='Noise')        
        ax.plot(o['parr'],on2['p'],label='Noise2')
        ax.legend()
        plt.show()
Esempio n. 9
0
def ncp(s2n):
    """
    Explore the output of BB as we change the prior on the number of
    change points
    """
    
    nncp = logspace(0.5,1.5,9)
    
    f,t = keptoy.lightcurve(s2n=s2n)
    sig = zeros(len(t)) + std(f)

    for i in range( len(nncp) ):
        last,val = find_blocks.pt( t,f,sig,ncp=nncp[i] )
        blocks(t,f,last,val)
        
        ax = plt.gca()
        ax.set_title('s2n - %.1e, cpts prior - %.2e' % (s2n,nncp[i]) )
        fig = plt.gcf()

        fig.savefig('frames/s2n-%.1e_%02d.png' % (s2n,i) )
        plt.show()
Esempio n. 10
0
def blocks(t,f,last,val):
    """
    Plot lines for the Bayesian Blocks Algorithm
    """

    fig = plt.gcf()
    fig.clf()
    ax = fig.add_subplot(111)

    ax.plot(t,f,'o',ms=1,alpha=0.5)

    cp = unique(last)
    n = len(t)
    idxlo = cp                    # index of left side of region
    idxhi = append(cp[1:],n)-1 # index of right side of region 

    ax.hlines(val[idxhi],t[idxlo],t[idxhi],'red',lw=5)
    ax.set_xlabel('Time (days)')
    ax.set_ylabel('Flux (normalized)')

    plt.show()
Esempio n. 11
0
import analysis
import keptoy
import numpy as np
from matplotlib.pylab import plt

q12 = analysis.loadKOI('Q12')
q12 = q12.dropna()
q12.index = q12.koi
q12['Pcad'] = q12['P'] / keptoy.lc

q12['twd'] = np.round(q12['tdur'] / 24 / keptoy.lc).astype(int)
q12['mean'] = q12['df'] * 1e-6
q12['s2n'] = 0
q12['noise'] = 0

tpar = dict(q12.ix[koi])  # transit parameters for a particular koi

opath = 'grid/%(kic)09d.h5' % tpar
npath = opath.split('/')[-1].split('.')[0] + '_temp.h5'
cmd = 'cp %s %s' % (opath, npath)
os.system(cmd)

with h5plus.File(npath) as h5:
    kplot.plot_diag(h5, tpar=tpar)

    if args.o is not None:
        plt.gcf().savefig(args.o)
        print "created figure %s" % args.o
    else:
        plt.show()
Esempio n. 12
0
def save(name, fig=None):
    fig = plt.gcf() if fig is None else fig
    path = os.path.join(root, name + '.png')
    fig.savefig(path)
    print(path)
Esempio n. 13
0
def telluric_psf(obs,plot=False,plot_med=False):
    """
    Telluric PSF
    
    Measure the instrumental profile of HIRES by treating telluric
    lines as delta functions. The width of the telluric lines is a
    measure of the PSF width.

    Method
    ------ 
    Fit a comb of gaussians to the O2 bandhead from 6270-6305A. The
    comb of gaussians that describes the telluric lines has 4 free
    parameters:

       - sig  : width of the line
       - wls0 : shift of telluric line centers: -0.1 to +0.1 angstroms
       - wls1 : wavelength stretch allows for 1% fluctuation in dlam/dpix
              0.99 to 1.01.
       - d    : scale factor to apply to the telluric lines

    If wls0 is off by more than a line width, we might not find a
    solution. We perform a scan in wls0.
    
    Parameters
    ----------
    obs : CPS observation id.
    """
    
    # Load spectral region and prep.
    spec = smio.getspec_fits(obs=obs)[14]
    spec = spec[(spec['w'] > 6270) & (spec['w'] < 6305)]
    spec['s'] /= continuum.cfit(spec)

    # figure out where the 95 percentile is for data that's this
    # noisey, then adjust continuum
    serr = np.median(spec['serr'])
    contlevel = np.percentile(np.random.randn(spec.size)*serr,95)
    spec['s'] *= (1+contlevel)
    darr = np.array(tell.d)

    # Intialize parameters
    p0 = lmfit.Parameters()
    p0.add('wls0',value=0.0)
    p0.add('sig',value=0.02,min=0,max=0.1)
    p0.add('wls1',value=1.0,min=0.99,max=1.01)
    p0.add('d',value=1,min=0.25,max=2)

    def model(p):
        return telluric_comb(p['sig'].value,p['wls0'].value,p['wls1'].value,
                             spec['w'],tell.wcen,darr=p['d'].value*darr)

    def res(p):
        """
        Residuals

        Returns residuals for use in the LM fitter. I compute the
        median absolute deviation to flag outliers. I remove these
        values from the residual array. However, I divide the
        residuals by the total number of residuals (post sigma
        clipping) so a to not penalize solutions with more points.

        Parameters
        ----------
        p : lmfit parameters object

        Returns
        -------
        res : Residual array (used in lmfit)
        
        """
        mod = model(p)
        res = (spec['s'] - mod) / spec['serr'] # normalized residuals

        mad = np.median(np.abs(res))
        b =  (np.abs(res) < 5*mad ) 
        res /= b.sum()

        if b.sum() < 10:
            return res * 10
        else:
            return res[b]

    # Do a scan over different wavelength shifts
    wstep = 0.01
    wrange = 0.1
    wls0L = np.arange(-wrange,wrange+wstep,wstep)

    chiL = np.zeros(len(wls0L))
    outL = []
    for i in range(len(wls0L)):
        p = copy.deepcopy(p0)
        p['wls0'].value = wls0L[i]
        out = lmfit.minimize(res,p)
        chiL[i] = np.sum(res(p)**2)
        outL+=[out] 

    # If the initial shift is off by a lot, the line depths will go to
    # zero and median residual will be 0. Reject these values
    out = outL[np.nanargmin(chiL)]
    p = out.params
    lmfit.report_fit(out.params)

    # Bin up the regions surronding the telluric lines
    wtellmid = np.mean(tell.wcen)
    def getseg(wcen):
        wcen = wtellmid + (wcen-wtellmid)*p['wls1'].value + p['wls0'].value
        dw = spec['w'] - wcen
        b = np.abs(dw) < 0.3

        seg = pd.DataFrame({'dw':dw,'s':spec['s'],'model':model(p)})
        seg = pdplus.LittleEndian(seg.to_records(index=False))
        seg = pd.DataFrame(seg)
        return seg[b]
    
    seg = map(getseg,list(tell.wcen))
    seg = pd.concat(seg,ignore_index=True)
    wstep = 0.025
    bins = np.arange(-0.3,0.3+wstep,wstep)
    seg['dw0'] = 0.
    for dw0 in np.arange(-0.3,0.3,wstep):
        seg['dw0'][seg.dw.between(dw0,dw0+wstep)] = dw0
    bseg = seg.groupby('dw0',as_index=False).median()

    mod = model(p) # best fit model
    def plot_spectrum():
        # Plot telluric lines and fits
        plt.plot(spec['w'],spec['s'],label='Stellar Spectrum')
        plt.plot(spec['w'],mod,label='Telluric Model')
        plt.plot(spec['w'],spec['s']-mod+0.5,label='Residuals')
        plt.xlim(6275,6305)
        plt.ylim(0.0,1.05)
        plt.xlabel('Wavelength (A)')
        plt.ylabel('Intensity')
        plt.title('Telluric Lines')
        
    def plot_median_profile():
        # Plot median line profile
        plt.plot(bseg.dw,bseg.s,'.',label='Median Stellar Spectrum')
        plt.plot(bseg.dw,bseg.model,'-',label='Median Telluric Model')
        plt.title('Median Line Profile')
        plt.xlabel('Distance From Line Center (A)')
        yl = list(plt.ylim())
        yl[1] = 1.05
        plt.ylim(*yl)

    if plot:
        # Used for stand-alone telluric diagnostic plots
        gs = GridSpec(1,4)
        fig = plt.figure(figsize=(12,3))
        plt.gcf().set_tight_layout(True)
        plt.sca(fig.add_subplot(gs[0,:3]))
        plot_spectrum()
        plt.sca(fig.add_subplot(gs[0,3]))
        plot_median_profile()

    if plot_med:
        # Used in quicklook plot
        plot_median_profile()


    # sig = width of telluric line in
    sig = p['sig'].value # [Angstroms]
    sig = sig/6290*3e5 # [km/s]
    sig = sig/1.3 # [pixels]
    return sig
Esempio n. 14
0
def telluric_psf(obs, plot=False, plot_med=False):
    """
    Telluric PSF
    
    Measure the instrumental profile of HIRES by treating telluric
    lines as delta functions. The width of the telluric lines is a
    measure of the PSF width.

    Method
    ------ 
    Fit a comb of gaussians to the O2 bandhead from 6270-6305A. The
    comb of gaussians that describes the telluric lines has 4 free
    parameters:

       - sig  : width of the line
       - wls0 : shift of telluric line centers: -0.1 to +0.1 angstroms
       - wls1 : wavelength stretch allows for 1% fluctuation in dlam/dpix
              0.99 to 1.01.
       - d    : scale factor to apply to the telluric lines

    If wls0 is off by more than a line width, we might not find a
    solution. We perform a scan in wls0.
    
    Parameters
    ----------
    obs : CPS observation id.
    """

    # Load spectral region and prep.
    spec = smio.getspec_fits(obs=obs)[14]
    spec = spec[(spec['w'] > 6270) & (spec['w'] < 6305)]
    spec['s'] /= continuum.cfit(spec)

    # figure out where the 95 percentile is for data that's this
    # noisey, then adjust continuum
    serr = np.median(spec['serr'])
    contlevel = np.percentile(np.random.randn(spec.size) * serr, 95)
    spec['s'] *= (1 + contlevel)
    darr = np.array(tell.d)

    # Intialize parameters
    p0 = lmfit.Parameters()
    p0.add('wls0', value=0.0)
    p0.add('sig', value=0.02, min=0, max=0.1)
    p0.add('wls1', value=1.0, min=0.99, max=1.01)
    p0.add('d', value=1, min=0.25, max=2)

    def model(p):
        return telluric_comb(p['sig'].value,
                             p['wls0'].value,
                             p['wls1'].value,
                             spec['w'],
                             tell.wcen,
                             darr=p['d'].value * darr)

    def res(p):
        """
        Residuals

        Returns residuals for use in the LM fitter. I compute the
        median absolute deviation to flag outliers. I remove these
        values from the residual array. However, I divide the
        residuals by the total number of residuals (post sigma
        clipping) so a to not penalize solutions with more points.

        Parameters
        ----------
        p : lmfit parameters object

        Returns
        -------
        res : Residual array (used in lmfit)
        
        """
        mod = model(p)
        res = (spec['s'] - mod) / spec['serr']  # normalized residuals

        mad = np.median(np.abs(res))
        b = (np.abs(res) < 5 * mad)
        res /= b.sum()

        if b.sum() < 10:
            return res * 10
        else:
            return res[b]

    # Do a scan over different wavelength shifts
    wstep = 0.01
    wrange = 0.1
    wls0L = np.arange(-wrange, wrange + wstep, wstep)

    chiL = np.zeros(len(wls0L))
    outL = []
    for i in range(len(wls0L)):
        p = copy.deepcopy(p0)
        p['wls0'].value = wls0L[i]
        out = lmfit.minimize(res, p)
        chiL[i] = np.sum(res(p)**2)
        outL += [out]

    # If the initial shift is off by a lot, the line depths will go to
    # zero and median residual will be 0. Reject these values
    out = outL[np.nanargmin(chiL)]
    p = out.params
    lmfit.report_fit(out.params)

    # Bin up the regions surronding the telluric lines
    wtellmid = np.mean(tell.wcen)

    def getseg(wcen):
        wcen = wtellmid + (wcen - wtellmid) * p['wls1'].value + p['wls0'].value
        dw = spec['w'] - wcen
        b = np.abs(dw) < 0.3

        seg = pd.DataFrame({'dw': dw, 's': spec['s'], 'model': model(p)})
        seg = pdplus.LittleEndian(seg.to_records(index=False))
        seg = pd.DataFrame(seg)
        return seg[b]

    seg = map(getseg, list(tell.wcen))
    seg = pd.concat(seg, ignore_index=True)
    wstep = 0.025
    bins = np.arange(-0.3, 0.3 + wstep, wstep)
    seg['dw0'] = 0.
    for dw0 in np.arange(-0.3, 0.3, wstep):
        seg['dw0'][seg.dw.between(dw0, dw0 + wstep)] = dw0
    bseg = seg.groupby('dw0', as_index=False).median()

    mod = model(p)  # best fit model

    def plot_spectrum():
        # Plot telluric lines and fits
        plt.plot(spec['w'], spec['s'], label='Stellar Spectrum')
        plt.plot(spec['w'], mod, label='Telluric Model')
        plt.plot(spec['w'], spec['s'] - mod + 0.5, label='Residuals')
        plt.xlim(6275, 6305)
        plt.ylim(0.0, 1.05)
        plt.xlabel('Wavelength (A)')
        plt.ylabel('Intensity')
        plt.title('Telluric Lines')

    def plot_median_profile():
        # Plot median line profile
        plt.plot(bseg.dw, bseg.s, '.', label='Median Stellar Spectrum')
        plt.plot(bseg.dw, bseg.model, '-', label='Median Telluric Model')
        plt.title('Median Line Profile')
        plt.xlabel('Distance From Line Center (A)')
        yl = list(plt.ylim())
        yl[1] = 1.05
        plt.ylim(*yl)

    if plot:
        # Used for stand-alone telluric diagnostic plots
        gs = GridSpec(1, 4)
        fig = plt.figure(figsize=(12, 3))
        plt.gcf().set_tight_layout(True)
        plt.sca(fig.add_subplot(gs[0, :3]))
        plot_spectrum()
        plt.sca(fig.add_subplot(gs[0, 3]))
        plot_median_profile()

    if plot_med:
        # Used in quicklook plot
        plot_median_profile()

    # sig = width of telluric line in
    sig = p['sig'].value  # [Angstroms]
    sig = sig / 6290 * 3e5  # [km/s]
    sig = sig / 1.3  # [pixels]
    return sig
Esempio n. 15
0
def injRec(pardict):
    """
    Inject and recover

    Parameters:
    pardict : Simulation parameters. Must contain the following keys.
              - lcfile
              - gridfile
              - climb, p, tau, b
              - P, t0
              - id. returned with output.  used in merge at the end
              - skic
    """
    name = "".join(random.random_integers(0, 9, size=10).astype(str))

    # Pull in raw light curve file.
    lc0 = prepro.Lightcurve(pardict['lcfile'], mode='r')
    lc = prepro.Lightcurve(name + '.h5', driver='core', backing_store=False)
    lc.copy(lc0['raw'], 'raw')
    raw = lc['raw']

    # Inject transits into individual quarters
    qL = [i[0] for i in list(raw.items())]
    for q in qL:
        r = raw[q][:]  # pull data out of h5py file
        ft = keptoy.synMA(pardict, r['t'])
        r['f'] += ft
        r = mlab.rec_append_fields(r, 'finj', ft)
        del raw[q]
        raw[q] = r

    # Perform detrending and calibration.
    lc.mask()
    lc.dt()
    lc.attrs['svd_folder'] = os.environ['WKDIR'] + '/eb10k/svd/'

    lc.cal()
    lc.sQ()

    # Grid search.
    grid0 = tfind.Grid(pardict['gridfile'], mode='r')
    res0 = grid0['RES'][:]
    grid = tfind.Grid(name + '.grid.h5', driver='core', backing_store=False)
    grid['mqcal'] = lc['mqcal'][:]

    # Only compute the grid over a narrow region in period
    deltaPcad = 10
    grid.P1 = int(pardict['P'] / config.lc - deltaPcad)
    grid.P2 = int(pardict['P'] / config.lc + deltaPcad)
    grid.P1 = max(grid.P1, res0['Pcad'][0])
    grid.P2 = min(grid.P2, res0['Pcad'][-1])
    grid.grid()

    # Add that narrow region to the already computed grid.
    res = grid['RES'][:]
    start = where(res0['Pcad'] == res['Pcad'][0])[0]
    stop = where(res0['Pcad'] == res['Pcad'][-1])[0]
    if len(start) > 1:
        start = start[1]
    if len(stop) > 1:
        stop = stop[0]
    res0[start:stop + 1] = res
    del grid['RES']
    grid['RES'] = res0

    # Outlier rejection is preformed on the hybrid grid
    grid.itOutRej()

    # DV
    p = tval.Peak(name + '.pk.h5', driver='core', backing_store=False)
    p['RES'] = grid['RES'][:]
    p['mqcal'] = grid['mqcal'][:]
    p.attrs['climb'] = array([pardict['a%i' % i] for i in range(1, 5)])
    p.attrs['skic'] = pardict['skic']

    p.findPeak()
    p.conv()
    p.checkHarm()
    p.at_phaseFold()
    p.at_fit()
    p.at_med_filt()
    p.at_s2ncut()
    p.at_SES()
    p.at_rSNR()
    p.at_autocorr()
    out = p.flatten(p.noDBRE)
    out['id'] = pardict['id']

    if list(pardict.keys()).count('pngfile') != 0:
        pngfile = pardict['pngfile']
        kplot.plot_diag(p)
        plt.gcf().savefig(pngfile)

    return out