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()
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()
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()
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')
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()
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()
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()
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()
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()
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()
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()
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)
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
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
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