def baseline_and_deglitch(orig_spec, ww=300, sigma_cut=4., poly_n=2., filt_width=7.): """ (1) Calculate a rolling standard deviation (s) in a window of 2*ww pixels (2) Mask out portions of the spectrum where s is more than sigma_cut times the median value for s. (3) Fit and subtract-out a polynomial of order poly_n (currently hard-coded to 2) (4) Median filter (with a filter width of filt_width) to remove the single-channel spikes seen. """ ya = rolling_window(orig_spec,ww*2) #Calculate standard dev and pad the output stds = my_pad.pad(np.std(ya,-1),(ww-1,ww),mode='edge') #Figure out which bits of the spectrum have signal/glitches med_std = np.median(stds) std_std = np.std(stds) sigma_x_bar = med_std/np.sqrt(ww) sigma_s = (1./np.sqrt(2.))*sigma_x_bar #Mask out signal for baseline masked = ma.masked_where(stds > med_std+sigma_cut*sigma_s,orig_spec) xx = np.arange(masked.size) ya = ma.polyfit(xx,masked,2) baseline = ya[0]*xx**2+ya[1]*xx+ya[2] sub = orig_spec-baseline #Filter out glitches in baseline-subtracted version final = im.median_filter(sub,filt_width)[::filt_width] return(final)
def make_local_stddev(orig_spec, ww=300): """ Make an array that encodes the local standard deviation within a window of width ww """ import my_pad ya = rolling_window(orig_spec, ww * 2) y = my_pad.pad(np.std(ya, -1), (ww - 1, ww), mode='edge') return (y)
def baseline_and_deglitch(orig_spec, ww=300, sigma_cut=1.5, poly_n=2., filt_width=7.): """ (1) Calculate a rolling standard deviation (s) in a window of 2*ww pixels (2) Mask out portions of the spectrum where s is more than sigma_cut times the median value for s. This seems to be mis-calibrated (perhaps not independent?). A value of 1.5 works well to remove all signal. (3) Downsample the masked spectrum (to avoid memory bug) and find the minimum order polynomial baseline that does a good job of fitting the data. (3) Median filter (with a filter width of filt_width) to remove the single-channel spikes seen. """ ya = rolling_window(orig_spec,ww*2) #Calculate standard dev and pad the output stds = my_pad.pad(np.std(ya,-1),(ww-1,ww),mode='edge') #Figure out which bits of the spectrum have signal/glitches med_std = np.median(stds) std_std = np.std(stds) sigma_x_bar = med_std/np.sqrt(ww) sigma_s = (1./np.sqrt(2.))*sigma_x_bar #Mask out signal for baseline masked = ma.masked_where(stds > med_std+sigma_cut*sigma_s,orig_spec) #Down-sample for the polyfit. #For speed, but mostly for memory masked = im.median_filter(masked,filt_width)[::filt_width] xx = np.arange(masked.size) npoly = find_best_baseline(masked,xx) basepoly = fit_baseline(masked,xx,ndeg=npoly) #Some kludgy code to refactor the baseline polynomial to #the full size spectra xxx = np.arange(orig_spec.size) params = np.asarray(basepoly) rr = filt_width newparams = [] for i,p in enumerate(params[::-1]): newparams.append(p/rr**i) newparams = newparams[::-1] newpoly = np.poly1d(newparams) newbaseline = newpoly(xxx) #Subtract off baseline sub = orig_spec-newbaseline #Filter out glitches in baseline-subtracted version final = im.median_filter(sub,filt_width)[::filt_width] return(final)