def get_smooth_continuum(s, wvl=None): """ wvl : required for masking our some absorption features """ from libs.trace_flat import get_finite_boundary_indices k1, k2 = get_finite_boundary_indices(s) if k1 == k2: r = np.empty(len(s), dtype="d") r.fill(np.nan) return r sl = slice(k1, k2+1) #s1m = ni.median_filter(np.array(s1[sl]), 150) s1m = np.array(s[sl]) if wvl is not None: wvl11 = np.array(wvl[sl]) for ww1, ww2 in [(1.9112, 1.9119), (1.91946, 1.92139), (1.92826, 1.92901), (1.92372, 1.92457)]: msk = (ww1 < wvl11) & (wvl11 < ww2) s1m[msk] = np.nan if len(s1m) > 351: f12 = sv_iter(s1m, winsize1=351, winsize2=91) elif len(s1m) > 25: f12 = sv_iter(s1m, winsize1=25, winsize2=11) else: f12 = None r = np.empty(len(s), dtype="d") r.fill(np.nan) if f12 is not None: r[sl] = f12 return r
def get_sv_mask(self, ratio): # use sv_iter to derive continuum level from ratio from libs.smooth_continuum import sv_iter from libs.trace_flat import get_finite_boundary_indices # naive iterative approach. ratio = ratio.copy() for thresh in [0.05, 0.03, 0.01]: #, 0.005, 0.0001]: i1, i2 = get_finite_boundary_indices(ratio) sl2 = slice(i1, i2+1) f12 = sv_iter(ratio[sl2], winsize1=251, winsize2=151) #fl = s1_orig_n[sl2]/f12 # s1m : normalization factor # f12 : flattening curve # fl : flattened spectrum new_msk = np.abs(ratio[sl2]-f12) > thresh ratio[sl2][new_msk] = np.nan # # recover masked area due to underestimated continuum # ratio0 = s1_orig_n/tt # model corrected spec # mmm = ratio0[sl2] > f12 # ratio[sl2][mmm] = ratio0[sl2][mmm] # for thresh in [0.01]: # i1, i2 = get_finite_boundary_indices(ratio) # sl2 = slice(i1, i2+1) # f12 = sv_iter(ratio[sl2], winsize1=351, winsize2=261) # fl = (s1_orig/s1m)[sl2]/f12 # s1m : normalization factor # # f12 : flattening curve # # fl : flattened spectrum # new_msk = np.abs(ratio[sl2]-f12) > thresh # ratio[sl2][new_msk] = np.nan msk = ~np.isfinite(ratio) return msk
a0v_ss = a0v1/f12 a0v_ss[f12<np.nanmax(f12)*0.1] = np.nan ax3.plot(wvl1, a0v_ss/np.nanmax(a0v_ss[100:-100])) #ax3.set_ylim(0.7, 1.1) #ax3.plot(wvl1[sl], a0v_ss/np.median(a0v_ss)*0.02) #ax3.set_ylim(-0.02, 0.05) if 0: #for s1, a0v1, wvl1 in zip(specs, dd, wvl_sol): #s1 = specs[ii] #a0v1 = dd[ii] from libs.trace_flat import get_finite_boundary_indices k1, k2 = get_finite_boundary_indices(s1) sl = slice(k1, k2+1) #s1m = ni.median_filter(np.array(s1[sl]), 150) s1m = np.array(s1[sl]) wvl11 = np.array(wvl1[sl]) for ww1, ww2 in [(1.9112, 1.9119), (1.91946, 1.92139), (1.92826, 1.92901), (1.92372, 1.92457)]: msk = (ww1 < wvl11) & (wvl11 < ww2) s1m[msk] = np.nan
def flatten_deprecated(self, w1, s1_orig, dw_opt, gw_opt, try_small=True, ax1=None, ax2=None): tel_interp1d_f = self.tel_interp1d_f s_a0v = self.a0v_interp1d(w1+dw_opt) s1_orig = s1_orig / s_a0v tel_interp1d = tel_interp1d_f(gw_opt) tt = tel_interp1d(w1+dw_opt) # telluric model if ax2: # plot telluric model ax2.plot(w1, tt, alpha=0.2, lw=3) s1m = np.nanmax(s1_orig) #s1m = 1. s1_orig_n = s1_orig/s1m # normalize # plot raw spec if ax1: ax1.plot(w1, s1_orig, alpha=0.3) ratio = s1_orig_n/tt # model corrected spec thresh=0.5 ratio[tt<thresh] = np.nan # blank out area with low tel-trans. # now we blank out area where derivative varies significantly. # derivative of ratio ratiom = ni.gaussian_filter1d(ratio, 3, order=1) # do median filtering to derive a baseline for derivative. # Because of nan values of original spec. doing it with # single value of filter size does not seem to work well. # Instead, we first filter with large filter size, then # with smaller one. Then replaces nan of former with # result of latter. dd = ni.median_filter(ratiom, 11) dd_small = ni.median_filter(ratiom, 5) dd_msk = ~np.isfinite(dd) dd[dd_msk] = dd_small[dd_msk] # subtract baseline from derivative. dd1 = (ratiom - dd) # mask out areas of high deriv. # The threshold is arbitrary but seem to work for most of orders. msk = np.abs(dd1) > 0.0005 #msk = np.abs(dd1) > 0.0003# for H # do binary-closing for mask msk = ni.binary_closing(msk, iterations=1) | ~np.isfinite(dd1) dd1[msk] = np.nan if ax1: # plot mask ax1.plot(w1, dd1) if ax2: # plot mask ax2.plot(w1, dd1) # now, mask out msk from original ratio. ratio[msk] = np.nan ratio[:4] = np.nan ratio[-4:] = np.nan # use sv_iter to derive continuum level from ratio from libs.smooth_continuum import sv_iter from libs.trace_flat import get_finite_boundary_indices # naive iterative approach. for thresh in [0.05, 0.03, 0.01]: i1, i2 = get_finite_boundary_indices(ratio) sl2 = slice(i1, i2+1) f12 = sv_iter(ratio[sl2], winsize1=251, winsize2=151) fl = (s1_orig/s1m)[sl2]/f12 # s1m : normalization factor # f12 : flattening curve # fl : flattened spectrum new_msk = np.abs(ratio[sl2]-f12) > thresh ratio[sl2][new_msk] = np.nan # recover masked area due to underestimated continuum ratio0 = s1_orig_n/tt # model corrected spec mmm = ratio0[sl2] > f12 ratio[sl2][mmm] = ratio0[sl2][mmm] for thresh in [0.01]: i1, i2 = get_finite_boundary_indices(ratio) sl2 = slice(i1, i2+1) f12 = sv_iter(ratio[sl2], winsize1=351, winsize2=261) fl = (s1_orig/s1m)[sl2]/f12 # s1m : normalization factor # f12 : flattening curve # fl : flattened spectrum new_msk = np.abs(ratio[sl2]-f12) > thresh ratio[sl2][new_msk] = np.nan if try_small: i1, i2 = get_finite_boundary_indices(ratio) sl2 = slice(i1, i2+1) f12 = sv_iter(ratio[sl2], winsize1=151, winsize2=91) fl = (s1_orig/s1m)[sl2]/f12 # f12 : flattening curve # fl : flattened spectrum new_msk = np.abs(ratio[sl2]-f12) > thresh ratio[sl2][new_msk] = np.nan if ax1: # show model corrected raw spec ax1.plot(w1, ratio*s1m, lw=3, color="0.8") # show fitted continuum ax1.plot(w1[sl2], f12*s1m) #plot(w1, s1_new) if ax2: # plot flattened spec ax2.plot(w1[sl2], np.ma.array(fl,mask=f12<0.05).filled(np.nan)) f12_0 = np.zeros_like(s1_orig) f12_0[sl2] = f12 return s1m*f12_0, np.isfinite(ratio)