def nufft(netCDFfile): ds = Dataset(netCDFfile, 'a') var_temp = ds.variables["TEMP"] var_cndc = ds.variables["CNDC"] time_var = ds.variables["TIME"] time = num2date(time_var[:], units=time_var.units, calendar=time_var.calendar) time_deploy = parser.parse(ds.time_deployment_start, ignoretz=True) time_recovery = parser.parse(ds.time_deployment_end, ignoretz=True) mask = (time <= time_deploy) | (time >= time_recovery) temp = var_temp[:] print("t0 = ", time[~mask][0]) hours = np.array([(t - datetime(2018, 8, 22, 13, 0, 0)).total_seconds()/3600 for t in time[~mask]]) fig, ax = plt.subplots(1, 1) ax.plot(hours, temp[~mask]) # , marker='.' ax.grid(True) samples = np.arange(0, len(hours)) print("len samples ", samples.size, hours[-1]) n_samples = samples.size Fnx = nufftpy.nufft1(hours, temp[~mask], M = hours[-1]*np.pi, df = np.pi*2/hours[-1], iflag=-1) * n_samples/(np.pi) # *6.2832 freq = nufftpy.nufftfreqs(n_samples) F = np.fft.fftshift(Fnx) #trange = np.arange(0, 6000) Fx = np.fft.fft(temp[~mask]) freqx = np.fft.fftfreq(samples.size) window = 1 - np.hanning(len(F)) # invert the window, making a low pass filter, how to create a cur frequency fig2, ax2 = plt.subplots(1, 1) #ax2.plot(freq[1:int(len(F)/2)], np.log(abs(F[1:int(len(F)/2)]))) ax2.plot(np.log(abs(F))) ax2.plot(np.log(abs(Fx))) print("FFT length " , len(F), hours[-1]) F1 = np.fft.ifft(F) #ax[1].plot(F1) ax.plot(abs(F1)) print(F1) plt.show() ds.close()
def nufftpy(y, t, half_width, resolution): import nufftpy as nfpy steps = int((2 * half_width) / resolution) freq = nfpy.nufftfreqs(steps, df=resolution) freq = freq[len(freq) // 2:-1] harmonic_content = nfpy.nufft1(t, y, steps, df=(resolution * 2 * math.pi)) harmonic_content = harmonic_content[len(harmonic_content) // 2:-1] return [ freq, harmonic_content.real**2 + harmonic_content.imag**2, harmonic_content.real, harmonic_content.imag ]
# # Pull variables from data time = data[0].ravel() # ravel() is used to change shape from (n, 1) to (n, ) flux = data[1].ravel() # # Used to indicate which window, modulus and scaling should be used dataset = 1 # 0 = sun, 1 = star2, 2 = nuindi # # Frequency Conversion muHz = 0.000001 # Variable for converting to microHz # # Frequency calculation resolution = 0.001 * muHz # 0.01 normal halfwidth_set = [6000, 1000, 600, 20] # sun, star2, nuindi, betelgeuse halfwidth = halfwidth_set[dataset] * muHz steps = int((2 * halfwidth) / resolution) freq = nufftpy.nufftfreqs(steps, df=resolution) freq = freq[len(freq) // 2:-1] # # Spectrum calculation from non-uniform fft result = nufftpy.nufft1(time, flux, steps, df=(resolution * 2 * math.pi)) res_pos = result[len(result) // 2:-1] spectral_power = res_pos.real**2 + res_pos.imag**2 plt.figure() plt.plot(freq / muHz / 11.57, spectral_power) # plt.plot(spectral_power) plt.xlabel('Frequency [1/days]') plt.xlim([0.04, 1.7]) plt.ylim([-10, 1.34 * 10**11]) plt.ylabel('Power (non-uniform fft)')
def nufft(t, y, n_iter, halfwidth, resolution, window=None, mph=1): """ Perform CLEAN procedure using FFT (NUFFT) """ # # Preparation import nufftpy # Preload lists for storing found peaks p_freq = [] p_power = [] p_alpha = [] p_beta = [] # Get amount of frequency steps for nufft1 steps = int((2 * halfwidth) / resolution) # Make carbon copy of signal for manipulation y_copy = np.copy(y) # # Loop for i in range(0, n_iter): t1 = tm.time() # Get cyclic frequencies for nufft1 freq = nufftpy.nufftfreqs(steps, df=resolution) freq = freq[len(freq) // 2:-1] # Take only positive frequencies # Call nufft1 to perform nufft calculation harmonic_content = nufftpy.nufft1(t, y_copy, steps, df=(resolution * 2 * np.pi)) harmonic_content = harmonic_content[len(harmonic_content)//2:-1] # Create window (if None) and apply to spectrum to only observe relevant area if window is None: window = range(0, len(harmonic_content)) harmonic_content = harmonic_content[window] freq = freq[window] # Calculate power spectral_power = harmonic_content.real ** 2 + harmonic_content.imag ** 2 # Detect peaks in power spectrum, and find power, frequency, alpha and beta values peaks = detect_peaks(spectral_power, mph=mph) peaks_power = spectral_power[peaks] peaks_alpha = harmonic_content.real[peaks] peaks_beta = harmonic_content.imag[peaks] peaks_freq = freq[peaks] # Find highest peak try: max_indx = np.argmax(peaks_power) max_freq = peaks_freq[max_indx] max_power = peaks_power[max_indx] max_alpha = peaks_alpha[max_indx] max_beta = peaks_beta[max_indx] except ValueError: break # plt.figure() # plt.plot(freq, spectral_power) # plt.plot(peaks_freq, peaks_power, 'r*', markersize=4) # plt.plot(max_freq, max_power, 'b*', markersize=6) # plt.show(block=False) # Calculate harmonic signal corresponding to highest peak in power spectrum max_signal = (max_alpha * np.cos(2*np.pi*max_freq * t) + max_beta * np.sin(2*np.pi*max_freq * t)) * 2 # plt.plot(t, y_copy, linewidth=0.5) # plt.plot(t, max_signal, '--', linewidth=0.3) # plt.show() # Subtract calculated signal from y_copy and save the peak used y_copy -= max_signal p_power.append(max_power) p_alpha.append(max_alpha) p_beta.append(max_beta) p_freq.append(max_freq) t2 = tm.time() print(t2-t1) # # Result # Get cyclic frequencies for nufft1 freq = nufftpy.nufftfreqs(steps, df=resolution) freq = freq[len(freq) // 2:-1] # Call nufft1 to perform nufft calculation for unchanged signal y harmonic_content = nufftpy.nufft1(t, y, steps, df=(resolution * 2 * np.pi)) harmonic_content = harmonic_content[len(harmonic_content) // 2:-1] # Calculate spectral power spectral_power = harmonic_content.real ** 2 + harmonic_content.imag ** 2 # Plot power spectrum and peaks found by cleaning plt.figure() plt.plot(freq, spectral_power) plt.plot(p_freq, p_power, 'r*', markersize=4) plt.show() # Save peaks found by cleaning in .dat file ps_f.writer('clean_peaks', p_freq, p_power) return p_freq, p_power, p_alpha, p_beta
def numpy(t, y, n_iter, freq_centre, fft_half_width, resolution, np_half_width, chunk_size=100, window=None, mph=1): """ CLEAN procedure using numpy matrix multiplication on a small frequency range, using nufftpy to find the approximate frequency of the highest peak beforehand. """ # # # Preparation # # # import nufftpy p_freq = [] p_power = [] p_alpha = [] p_beta = [] freq_centre = [freq_centre] # Get amount of frequency steps for nufft1 steps = 2 * int((2 * fft_half_width) / resolution) # Make carbon copy of signal for manipulation y_copy = np.copy(y) # # # # CLEAN LOOP # # # # for i in range(0, n_iter): t1 = tm.time() # # # Do FFT to find expected highest peak area # # # # Get cyclic frequencies for nufft1 freq = nufftpy.nufftfreqs(steps, df=resolution) freq = freq[len(freq) // 2:-1] # Take only positive frequencies # Call nufft1 to perform nufft calculation harmonic_content = nufftpy.nufft1(t, y_copy, steps, df=(resolution * 2 * np.pi)) harmonic_content = harmonic_content[len(harmonic_content) // 2:-1] spectral_power_fft = harmonic_content.real ** 2 + harmonic_content.imag ** 2 # Detect peaks in power spectrum, and find power, frequency, alpha and beta values peaks = detect_peaks(spectral_power_fft, mph=mph) peaks_power = spectral_power_fft[peaks] peaks_freq = freq[peaks] # Find highest peak try: max_indx = np.argmax(peaks_power) max_freq = peaks_freq[max_indx] except ValueError: print('no more peaks, i = ', i) break t2 = tm.time() print('fft time: ', t2-t1) # # # Do sine-cosine fitting to estimate power spectrum using numpy matrix multiplication # # # spectral_res = create_pspectrum.numpy(y_copy, t, half_width=np_half_width, freq_centre=[max_freq], resolution=resolution, chunk_size=1000) spectral_res=spectral_res[0] spectral_power = spectral_res[1] # cut data to window window = None if window is None: window = range(0, len(spectral_power)) spectral_power = spectral_power[window] # # Do peak finding # # peaks = detect_peaks(spectral_power, mph=mph) peaks_power = spectral_power[peaks] peaks_alpha = spectral_res[2][peaks] peaks_beta = spectral_res[3][peaks] peaks_freq = spectral_res[0][peaks] # Find highest peak try: max_indx = np.argmax(peaks_power) max_freq = peaks_freq[max_indx] max_power = peaks_power[max_indx] max_alpha = peaks_alpha[max_indx] max_beta = peaks_beta[max_indx] except ValueError: break # plt.figure() # plt.plot(freq / 0.000001, spectral_power_fft*4) # plt.plot(peaks_freq / 0.000001, peaks_power, 'r*', markersize=4) # plt.plot(max_freq / 0.000001, max_power, 'b*', markersize=6) # plt.show(block=True) # # # Calculate harmonic signal corresponding to highest peak in power spectrum # # # max_signal = (max_beta * np.cos(2*np.pi*max_freq * t) + max_alpha * np.sin(2*np.pi*max_freq * t)) # plt.plot(t, y_copy) # plt.plot(t, max_signal, 'r--') # plt.show() # # Subtract calculated signal from y_copy and save the peak used # # y_copy -= max_signal p_power.append(max_power) p_alpha.append(max_alpha) p_beta.append(max_beta) p_freq.append(max_freq) t3 = tm.time() print('numpy time: ', t3-t2) # # # # Results # # # # # Calculate original power spectrum spectral_res = create_pspectrum.numpy(y, t, freq_centre=freq_centre, half_width=fft_half_width, resolution=resolution, chunk_size=chunk_size) spectral_res = spectral_res[0] p_freq = np.asarray(p_freq) # Plot spectrum and found peaks plt.figure() plt.plot(spectral_res[0] / 0.000001, spectral_res[1]) plt.plot(p_freq / 0.000001, p_power, 'r*', markersize=4) plt.show() # Save peaks found by cleaning in .dat file ps_f.writer('clean_peaks_numpy', p_freq, p_power) return p_freq, p_power, p_alpha, p_beta