def smooth_angle(angle, vmagnitude=1, kernel_width=21): """Smooth angles by decomposing them, applying a boxcar average Smoothing is done by using a 1D kernel smoothing filter of a given width. Parameters ---------- angle : numpy.ndarray The angle(s) in degree units. vmagnitude : numpy.ndarray, optional The magnitude array associated with each angle. It can be a scalar that is common to all ``angle`` elements. kernel_width : int, optional The width of the filter kernel. Returns ------- namedtuple namedtuple with ndarrays ``angle`` and ``magnitude``, in that order. """ x, y = decompose(angle, vmagnitude) x_smooth = convolve(x, Box1DKernel(kernel_width), boundary="extend") y_smooth = convolve(y, Box1DKernel(kernel_width), boundary="extend") return recompose(x_smooth, y_smooth)
def detect_lines(self): wave, flux = self.data_norm # Select only the regions where the spectra is larger than -1 ivalid = np.where(flux > -1.0)[0] ysmooth = convolve(flux[ivalid], Box1DKernel(3)) for n in range(3): gradient = np.gradient(ysmooth) ysmooth = convolve(gradient, Box1DKernel(3)) if n == 1: tckn = interpolate.UnivariateSpline(wave[ivalid], ysmooth, k=5, s=0) tck = interpolate.UnivariateSpline(wave[ivalid], ysmooth, k=3, s=0) zeros = tck.roots() flux_zeros = interpolate.UnivariateSpline(wave[ivalid], flux[ivalid], k=5, s=0)(zeros) ifinal = np.where((tckn(zeros) > 0.0) & (flux_zeros < -0.02))[0] del ysmooth, gradient, tckn, tck, ivalid return zeros[ifinal]
def get_smoothing_features(self): ''' Smoothes spectum using two different boxcar functions and finds differences ''' w1 = 10 w2 = 100 buff = 1 smooth1 = convolve(self.flux,Box1DKernel(w1))[buff*w2:-buff*w2] smooth2 = convolve(self.flux,Box1DKernel(w2))[buff*w2:-buff*w2] self.process_fits_file() total_flux = np.nanmean(self.flux) self.d1 = np.nanmean(abs(self.flux[buff*w2:-buff*w2]-smooth1))/total_flux self.d2 = np.nanmean(abs(self.flux[buff*w2:-buff*w2]-smooth2))/total_flux self.d3 = np.nanmean(abs(smooth1-smooth2))/total_flux
def highpassfilt(signal, highpassWidth): '''Run a signal through a highpass filter to remove high frequency signals. This function can be used to compute the continuum of a signal to be subtracted. Parameters ---------- signal: ndarray (1D) 1D array of values highpassWidth: int The width of the boxcar filter to use. Returns ------- smoothed_signal: ndarray (1D) An array containing the smoothed signal. Notes ----- History: - 14 Feb 2018 Lisa Dang Written for early version of SPCA - 23 Sep 2019 Taylor Bell Generalized upon the code - 02 Nov 2021 Taylor Bell Added to Eureka! ''' g = Box1DKernel(highpassWidth) return convolve(signal, g, boundary='extend')
def astropy_smooth(x, window, boundary="extend", normalize_kernel=True): kernel = Box1DKernel(window) smoothed = convolve(x, kernel, boundary=boundary, normalize_kernel=normalize_kernel) return smoothed
def test__cross_correlation(self): self.wc.lamp = self.ccd.copy() self.wc.serial_binning = 1 x_axis = np.arange(0, 4060, 1) reference = np.zeros(4060) gaussian = models.Gaussian1D(stddev=2) for i in sorted(np.random.choice(x_axis, 30)): gaussian.mean.value = i reference += gaussian(x_axis) offset = np.random.choice(range(1, 15), 1)[0] for slit in [1, 2, 3, 4, 5]: new_array = np.append(reference[offset:], np.zeros(offset)) if slit > 3: box_kernel = Box1DKernel(width=slit / 0.15) new_array = convolve(new_array, box_kernel) self.assertEqual(len(reference), len(new_array)) self.wc.lamp.header['SLIT'] = '{:d}.0" long slit'.format(slit) correlation_value = self.wc._cross_correlation(reference=reference, new_array=new_array) self.assertEqual(correlation_value, offset)
def get_solar_data(url, datemin, datemax, box=4): """Download the most recent solar data, save as file and dataframe, filter dataframe to date range. Also replace -1 values in the smoothed flux.""" response = request.urlopen(url) if response.status == 200: data = json.loads(response.read()) else: print("Invalid response! HTTP Status Code: {}".format(response.status)) df = pd.DataFrame(data) dates = [ datetime.datetime.strptime(val, '%Y-%m') for val in df['time-tag'] ] df.index = pd.DatetimeIndex(dates) todays_date = datetime.datetime.today().strftime('%b%d_%Y') outfile = os.path.join(COS_MONITORING, "noaa_solar_indices_{}.txt".format(todays_date)) # print("Saving outfile: {}".format(outfile)) df.to_csv(outfile, header=True, index=True) # print("Filtering the dataframe to the date range: {}, {}".format(datemin, # datemax)) df = df.loc[datemin:datemax] # smoothing the f10.7 data kernel = Box1DKernel(box) smoothed_107 = convolve(df["f10.7"], kernel) df["box_convolved_f10.7"] = smoothed_107 return df
def peakfinder(x, size1, size2, angle, S_Factor): img = plt.imread(str(x)) ang = [] rows, cols = img.shape if angle == 0: ang = 1 else: ang = angle M = cv2.getRotationMatrix2D((cols / 2, rows / 2), ang, 1) rot = cv2.warpAffine(img, M, (cols, rows)) Image = rot[size1:size2] smoothed_S = convolve(Image[0], Box1DKernel(20 + S_Factor)) peakind = signal.find_peaks_cwt(smoothed_S, np.arange(50, 150)) fig = plt.figure() plt.plot(smoothed_S) plt.plot( np.array(range(len(smoothed_S)))[peakind], smoothed_S[peakind], 'o') #plt.show fig.show() Tk.mainloop()
def specflat(flat,rows=True,indiv=False,wid=100) : """ Removes spectral signature from a flat by dividing by smoothed version Args: flat: input flat fields Keyword args: rows (bool) : specifies if smoothing is along rows (default), otherwise columns indiv (bool) : specifies if smoothing is done row-by-row, or single for whole image (default) wid (int) : boxcar kernel width (default=100) Returns: flat with spectral signature removed """ boxcar = Box1DKernel(wid) smooth=flat if rows : if indiv : for row in range(flat.shape[0]) : smooth[row,:] /= convolve(flat[row,:],boxcar,boundary='extend') else : c=convolve(flat.sum(axis=0),boxcar,boundary='extend') for row in range(flat.shape[0]) : smooth[row,:] /= c else : print('smoothing by columns not yet implemented!') pdb.set_trace() return smooth
def smooth_days(x, y, kernel, ksize, fix): """Smooth data (x, y) given parameters kernel, ksize, fix""" kernel = kernel.lower() if kernel == 'none' or not ksize: return x, y if kernel == 'box': from astropy.convolution import convolve, Box1DKernel ysm = convolve(y, Box1DKernel(ksize), boundary='extend') elif kernel == 'gaussian': from astropy.convolution import convolve, Gaussian1DKernel ysm = convolve(y, Gaussian1DKernel(ksize), boundary='extend') elif kernel == 'trapezoid': from astropy.convolution import convolve, Trapezoid1DKernel ysm = convolve(y, Trapezoid1DKernel(ksize), boundary='extend') elif kernel == 'triangle': from astropy.convolution import convolve, CustomKernel f = triangle(ksize) ysm = convolve(y, CustomKernel(f), boundary='extend') else: raise ValueError('{} not supported.'.format(kernel)) redo = int(np.floor(ksize / 2)) xsm = x if fix == 'cull': _sfs = slice(0, len(ysm) - redo) xsm = x[_sfs] ysm = ysm[_sfs] elif fix == 'redo': for i in range(len(y) - redo, len(y)): ave = 0.0 cnt = 0 for j in range(i, len(y)): ave += y[j] cnt += 1 ysm[i] = (ave / cnt + ysm[i]) / 2.0 return xsm, ysm
def getpts(self): #Smooth the spectrum: if ~self.extracted: self.getctrt() smooth = convolve(self.ctrt.value, Box1DKernel(10)) * u.ct / u.s #Select wavelengths devoid of tellurics selwav = np.array([[1.982,1.985],[2.034,2.039],[2.09,2.100],\ [2.140,2.150],[2.230,2.240],[2.31,2.315],\ [2.330,2.340],[2.360,2.365],[2.398,2.402],\ [2.438,2.440]]) means = np.zeros_like(selwav) i = 0 for row in selwav: mask = ~np.logical_and(self.lam.to(u.micron).value>=row[0],\ self.lam.to(u.micron).value<=row[1]) means[i, 0] = np.ma.mean(np.ma.array(data=self.lam, mask=mask)).value means[i, 1] = np.ma.mean(np.ma.array(data=smooth, mask=mask)).value i += 1 return means
def smooth_1dspec(common_text, sp=1.2, kernel='gaussian', prefix_str='z_', plot=False): """ Smoothens a 1-D spectra based on the smoothening parameter. Smoothening parameter is 'std.dev.' in case of isotropic Gaussian filter and is 'width' in the case of the non-isotropic box filter. Args: common_text : Common text of 1-D spectra files which have to be smoothened sp : Smoothening parameter kernel : Convolution Kernel used for smoothening (Gaussian or Box) prefix_str : Prefix to distinguish the smoothened 1-D spectra from the original plot : Boolean describing whether the smoothened spectra has to be plotted Returns: None """ list_spectra = group_similar_files('', common_text=common_text) usable_kernel = Gaussian1DKernel(int(sp)) if kernel.lower() != 'gaussian': if kernel.lower() == 'box': usable_kernel = Box1DKernel(int(sp)) else: print ("Error: Kernel '{0}' Not Recognised".format(kernel)) sys.exit(1) for file_name in list_spectra: wav_data, flux_data = read_1dspec(file_name) smoothed_data = convolve(flux_data, usable_kernel) write_1dspec(ref_filename=file_name, flux_array=smoothed_data, prefix_str=prefix_str) if plot: plt.plot(wav_data, flux_data, 'g', label='Original Spectrum') plt.plot(wav_data, smoothed_data, 'r', label='Smooth Spectrum') plt.legend() plt.show() plt.close()
def get_arclines_fiber(spectrum, init_loc=None, limit=1000, use_kernel=True): if use_kernel: B = Box1DKernel(9.5) y1 = convolve(spectrum, B) else: y1 = spectrum * 1. diff_array = y1[1:] - y1[:-1] loc = np.where((diff_array[:-1] > 0.) * (diff_array[1:] < 0.))[0] peaks = y1[loc + 1] loc = loc[peaks > limit] + 1 peaks = y1[loc] def get_trace_chunk(flat, XN): YM = np.arange(flat.shape[0]) inds = np.zeros((3, len(XN))) inds[0] = XN - 1. inds[1] = XN + 0. inds[2] = XN + 1. inds = np.array(inds, dtype=int) Trace = (YM[inds[1]] - (flat[inds[2]] - flat[inds[0]]) / (2. * (flat[inds[2]] - 2. * flat[inds[1]] + flat[inds[0]]))) return Trace loc = get_trace_chunk(y1, loc) if init_loc is not None: final_loc = [] for i in init_loc: final_loc.append(loc[np.argmin(np.abs(np.array(loc) - i))]) loc = final_loc return loc
def smooth_derivative(tseries, med_half_width, box_half_width): """ Calculate a smoothed version of the lightcurve derivative First smooth lightcurve wiht a median filter, then smooth numerical derivative with boxcar convolution. Parameters ----------- tseries: hipercam.hlog.Tseries Time series object med_half_width: int Half-width of median filter box_half_width: int Half-width of boxcar filter Returns -------- x, dy: np.ndarray Locations and values of smoothed derivative """ x = tseries.t.copy() y = tseries.y.copy() yf = medfilt(y, 2 * med_half_width + 1) deriv = (yf[1:] - yf[:-1]) / (x[1:] - x[:-1]) locs = 0.5 * (x[1:] + x[:-1]) kernel = Box1DKernel(2 * box_half_width + 1) return locs, convolve(deriv, kernel)
def prepped_data(self, min_wavelen, max_wavelen, input_shape): # remove nan values wavelen_prep, spec_data_prep = rem_nans(self.wavelen, self.spec_data) # sliding window to cut off strong emission or absorption lines wavelen_prep, spec_data_prep=rem_emi(wavelen_prep, spec_data_prep, 101, 71, 6, False) wavelen_prep, spec_data_prep=rem_emi(wavelen_prep, spec_data_prep, 81, 61, 10, False) # apply convolution with box kernel to emphasize step in continuum box_kernel_10=Box1DKernel(10) spec_data_prep=convolve(spec_data_prep, box_kernel_10) # crop to defined wavelength lower_ind=np.min(np.where(wavelen_prep>=min_wavelen)) upper_ind=np.min(np.where(wavelen_prep>=max_wavelen)) wavelen_prep=wavelen_prep[lower_ind: upper_ind] wavelen_prep=wavelen_prep[lower_ind: upper_ind] # crop to input_shape (cropping all spectra to same wavelength does not guarantee # same vector length, because distances between two pixels are not the same for all # spectra) assert len(spec_data_prep) >= input_shape[0] while len(spec_data_prep) > input_shape[0]: spec_data_prep=np.delete(spec_data_prep, 0) wavelen_prep=np.delete(wavelen_prep, 0) # bring all spectra to mean_value = 0 and norm to maximum of absolute values spec_data_prep = spec_data_prep-np.nanmean(spec_data_prep) spec_data_prep=spec_data_prep/np.absolute(spec_data_prep).max() return wavelen_prep, spec_data_prep
def smooth_fit(x, y, smoothing='boxcar', N=30): """ Function to smooth and perform linear fit to x,y data args x : array of x dimension of the data y : array of y dimension of the data smoothing : method to smooth the data 'boxcar' : (default) smoothed data is same size as input data 'bin' : (see bin_smoothing) smoothed data is smaller shape than input data returns m : slope of smoothed fit b : y-intercept of smoothed fit """ # smooth if smoothing == 'boxcar': # boxcar smoothing y_smooth = convolve(y, Box1DKernel(N), boundary='extend') x_smooth = x elif smoothing == 'bin': bin_smoothing(x, y, N) else: raise ValueError("Invalid smoothing type specified '%s'" % smoothing) # fit m, b = np.polyfit(x_smooth, y_smooth, 1) return m, b
def fluxes(spec_wl, spec_flux, central_wl): """Take vectors spec_wl and spec_flux of a spectrum, and the central_wl, assuming constant dlb in central_wl. spec_wl in angstrom spec_flux in W/m^2/micron firstly convolve the spectrum!! returns a vector of flux per spectral bin in photons/s/m^2/micron. """ #define the center wavelength of central_wl and d_lambda idx = np.logical_and(spec_wl > np.min(central_wl) - 0.01, spec_wl < np.max(central_wl) + 0.01) num_point = len(spec_wl[idx]) #print(num_point) interp_spec = interp1d(spec_wl, spec_flux) wl = np.linspace( np.min(central_wl) - 0.01, np.max(central_wl) + 0.01, num_point) #wl = np.linspace(lb-passband/2-0.1, lb+passband/2+0.1, num_point) fx = interp_spec(wl) / (h * c / wl) #This is per trace. #wlPerPix = 2.83e-3 #2.83 nm/pixel DIAGONAL dlb = np.median( wl[1:] - wl[:-1] ) #this is dlb. Note that in the resampled data, dlb is constant pixelKernel = Box1DKernel(wlPerPix / dlb) fx_pixRes = convolve(fx, pixelKernel) flux_in_pix = interp1d(wl, fx_pixRes)(central_wl) return np.array(flux_in_pix) #The unit returned is photons/s/m^2/micron
def smooth_flux(flux, width=10, kernel="boxcar"): if kernel == "boxcar" or kernel == "Boxcar": kernel = Box1DKernel(width) elif kernel == "gaussian" or kernel == "Gaussian": kernel = Gaussian1DKernel(width) return convolve(flux, kernel)
def test_convolve(): test_wcs_1 = WCS(naxis=1) spec = OneDSpectrum(twelve_qty_1d, wcs=test_wcs_1) from astropy.convolution import Box1DKernel specsmooth = spec.spectral_smooth(Box1DKernel(1)) np.testing.assert_allclose(spec, specsmooth)
def boxcar_smooth(): N = len(pytplot.data_quants['sgx'].data.index) x = pytplot.data_quants['sgx'].data.index y = pytplot.data_quants['sgx'].data print((y.values)) smoothed = convolve(y.values, Box1DKernel(4)) s = plt.plot(x, smoothed) t = plt.plot(x, y, 'r') plt.show([s, t])
def load_composite(mJy=False, getcontinuum=False, npix=64, wave_ext=0.): ''' Plot the composite LBG spectra from Shapley (2003); https://arxiv.org/pdf/astro-ph/0301230.pdf See the 2016 update by Steidel ++ https://arxiv.org/pdf/1605.07186.pdf ''' data = np.loadtxt('../quickspectra/spectra/spec-shapley-z0.000.dat') mlambda = data[0, 0] dlambda = data[1, 0] - data[0, 0] nlambda = len(data[:, 0]) ls = data[:, 0] vs = (ls * u.AA).to(u.Hz, equivalencies=u.spectral()) Fv = data[:, 1] if mJy: Fv *= 1e29 ## [micro Jy]. if getcontinuum: npix = npix ## Reflection at the far edge for convolution; zero padding on blue end is probably fine. ls = np.concatenate([ls, ls[-1] + ls]) Fv = np.concatenate([Fv, Fv[::-1]]) Fv = convolve(Fv, Box1DKernel(npix)) ## Cut reflection range. ls = ls[:nlambda] Fv = Fv[:nlambda] vs = (ls * u.AA).to(u.Hz, equivalencies=u.spectral()) if wave_ext > 0.: ## Blue extension to 0.0 angstroms and red extension to wave_ext. ext = np.arange(0.0, mlambda, dlambda) ls = np.concatenate([ext, ls]) Fv = np.concatenate([np.zeros_like(ext), Fv]) nir_amp = Fv[(ls > 1600.)].mean() nir_std = Fv[(ls > 1600.)].std() ext = np.arange(2000. + dlambda, wave_ext + dlambda, dlambda) ls = np.concatenate([ls, ext]) Fv = np.concatenate([ Fv, nir_amp * np.ones_like(ext) + nir_std * np.random.uniform(low=-.5, high=0.5, size=len(ext)) ]) vs = (ls * u.AA).to(u.Hz, equivalencies=u.spectral()) return vs.value, ls, Fv
def plot_spectrum(wavelength, flux, error, dq, rootname): """diagnostic plot. Smooths with a 5pt boxcar. Plots the raw spectrum in grey, then overlays another spectrum with flagged points removed""" flux = convolve(flux,Box1DKernel(5)) plt.figure(rootname) plt.plot(wavelength, flux, '0.5') wavelength_dq, flux_dq = wavelength[dq==0], flux[dq==0] plt.plot(wavelength_dq, flux_dq, label = 'spectrum') plt.plot(wavelength, error, label='error') plt.legend() plt.show()
def _update_params(all=False, best_period=None, best_t0=None): if all: # If we're updating everything, recalculate the BLS model minp, maxp = fig_bls.x_range.start, fig_bls.x_range.end period_values = np.logspace(np.log10(minp), np.log10(maxp), npoints_slider.value) ok = (period_values > duration_slider.value) & (period_values < maxp) if ok.sum() == 0: return period_values = period_values[ok] result = model.power(period_values, duration_slider.value) ok = np.isfinite(result['power']) & np.isfinite(result['duration']) &\ np.isfinite(result['transit_time']) & np.isfinite(result['period']) bls_source.data = dict( period=result['period'][ok], power=result['power'][ok], duration=result['duration'][ok], transit_time=result['transit_time'][ok]) loc = np.nanargmax(bls_source.data['power']) best_period = bls_source.data['period'][loc] best_t0 = bls_source.data['transit_time'][loc] minpow, maxpow = bls_source.data['power'].min()*0.95, bls_source.data['power'].max()*1.05 fig_bls.y_range.start = minpow fig_bls.y_range.end = maxpow # Otherwise, we can just update the best_period index minphase, maxphase = fig_folded.x_range.start, fig_folded.x_range.end f = lc.fold(best_period, best_t0) inwindow = (f.time > minphase) & (f.time < maxphase) nb = int(np.ceil(inwindow.sum()/10000)) f_source.data = {'phase': f[inwindow].time[::nb], 'flux': f[inwindow].flux[::nb]} mf = model.model(lc.time, best_period, duration_slider.value, best_t0) mf /= np.median(mf) mask = ~(convolve(np.asarray(mf == np.median(mf)), Box1DKernel(2)) > 0.9) model_lc = LightCurve(lc.time[mask], mf[mask]) model_lc_source.data = {'time': np.sort(model_lc.time), 'flux': model_lc.flux[np.argsort(model_lc.time)]} f_model_lc = model_lc.fold(best_period, best_t0) f_model_lc = LightCurve([-0.5], [1]).append(f_model_lc) f_model_lc = f_model_lc.append(LightCurve([0.5], [1])) f_model_lc_source.data = {'phase': f_model_lc.time, 'flux': f_model_lc.flux} vertical_line.update(location=best_period) fig_folded.title.text = 'Period: {} days \t T0: {}{}'.format( np.round(best_period, 7), np.round(best_t0, 7), time_format) text_output.text = "Period: {} days, \t T0: {}{}".format( np.round(best_period, 7), np.round(best_t0, 7), time_format)
def next(self, event): global yhat self.ajuste += 5 print(self.ajuste) box_kernel = Box1DKernel(self.ajuste) yha = convolve(y, box_kernel) yhat = ((y - yha)**2) yhat = (yhat / yhat.mean()) original.set_ydata(yoriginal) l.set_ydata(yhat) plt.draw()
def pixDownsample(spec_wl, spec_flux, wlPerPix): """Down sample the given spectrum to the pixel resolution by convolving with a box. Input: spec_wl -- a vector of wavelengths with regular dwl (equal increase in wl from element to element.) spec_flux -- a vector of flux wlPerPix -- wl coverage per pixel. This is determined by the grating specification. Output: a vector of flux at pixel resolution """ dwl = spec_wl[1] - spec_wl[0] pixKernel = Box1DKernel(wlPerPix / dwl) fx_pixRes = convolve(spec_flux, pixKernel) return fx_pixRes
def mkspecflat(self,flats,wid=101) : """ Spectral flat takes out variation along wavelength direction """ boxcar = Box1DKernel(wid) for iflat,flat in enumerate(flats) : nrows=flats[iflat].data.shape[0] med = convolve(np.median(flat,axis=0),boxcar,boundary='extend') for row in range(flats[iflat].data.shape[0]) : flats[iflat].data[row,:] /= med flats[iflat].uncertainty.array[row,:] /= med return flats
def boxcar(arg): time, flux = LC(arg) from astropy.convolution import convolve, Box1DKernel num = 0 Smooth = convolve(flux[num], Box1DKernel(17)) #plt.figure(1) #plt.subplot(211) #plt.plot(time[num],flux[num]) #plt.subplot(212) #plt.plot(time[num], Smooth) plt.plot(time[num], flux[num]) plt.plot(time[num], Smooth) return Smooth
def test_mask_convolve(): # Numpy is fundamentally incompatible with the objects we have created. # np.ma.is_masked(array) checks specifically for the array's _mask # attribute. We would have to refactor deeply to correct this, and I # really don't want to do that because 'None' is a much more reasonable # and less dangerous default for a mask. test_wcs_1 = WCS(naxis=1) spec = OneDSpectrum(twelve_qty_1d, wcs=test_wcs_1) assert spec.mask is False from astropy.convolution import convolve, Box1DKernel convolve(spec, Box1DKernel(3))
def boxsmooth(time, flux, kern): """Takes a time series and boxcar smoothes it, removing edge effects. time: ndarray, 1D flux: ndarray, 1D kern: boxcar smoothing """ box_flux = convolve(flux, Box1DKernel(kern), boundary='extend') flux2 = flux / box_flux return flux2, box_flux
def conv_detrend(flux, window, gap): """ return median detrended array centered on zero at the end. if gap is true, then don't use that point """ #filt = medfilt(flux,window) + 1e-8 box_kernel = Box1DKernel(window, mode="linear_interp") filt = convolve(flux[~gap], box_kernel, boundary="extend") median_det = flux[~gap] / filt - 1 return median_det