def main(): X = Numeric.arange(0, 20 * Numeric.pi, 0.01, typecode=Numeric.Float) Y1 = Numeric.sin(X) Y2 = Numeric.sin(2 * X) out = open('fncs.dat', 'w') for i in range(len(X)): out.write(str(X[i]) + ' ' + str(Y1[i]) + ' ' + str(Y2[i]) + '\n') out.close() # Take FFT's FY1 = FFT.fft(Y1).real FY2 = FFT.fft(Y2).real N = float(len(X)) # get # of data points dX = X[1] - X[0] # get distance spacing T = N * dX # define the period (total time) dQ = 1. / T # define frequency step Q = Numeric.arange(N, typecode=Numeric.Float) * dQ print Q[list(FY1).index(max(FY1))], max(FY1) print Q[list(FY2).index(max(FY2))], max(FY2) print list(FY1).index(max(FY1)) print list(FY2).index(max(FY2)) out = open('FFTs.dat', 'w') for i in range(len(Q)): out.write(str(Q[i]) + ' ' + str(FY1[i]) + ' ' + str(FY2[i]) + '\n') out.close()
def test_fft(ndims): x=randmat( ndims ) print 'dimensions=%s' % str( Numeric.shape(x) ), if doreal: xver = FFT.real_fftnd(x) else: xver = FFT.fftnd(x) open('/tmp/fftexp.dat','w').write(dopack( flatten(xver) , True ) ) x2=dofft(x) err = xver - x2 errf = flatten(err) xverf = flatten(xver) errpow = Numeric.vdot(errf,errf)+1e-10 sigpow = Numeric.vdot(xverf,xverf)+1e-10 snr = 10*math.log10(abs(sigpow/errpow) ) print 'SNR (compared to NumPy) : %.1fdB' % float(snr) if snr<minsnr: print 'xver=',xver print 'x2=',x2 print 'err',err sys.exit(1)
def main(): # Retrieve user input try: f = open(sys.argv[1], 'r') lines = f.readlines() f.close() except: print '\n usage: ' + sys.argv[0] + ' XY.dat\n' sys.exit(0) # Parse the data t, y = [], [] for line in lines: t.append(float(line.split()[0])) y.append(float(line.split()[1])) # Calculate the FFT and get the frequencies N = float(len(t)) dt = t[1] - t[0] T = N * dt df = 1.0 / T f = Numeric.arange(N, typecode=Numeric.Float) * df H = (FFT.fft(y) * Numeric.conjugate(FFT.fft(y))).real / N # Write to file out = open('PSD.dat', 'w') for i in range(len(f) / 2): out.write(str(f[i]) + ' ' + str(H[i]) + '\n') out.close()
def PCreateFFT(image, dir): """ Create an FFT object suitable for FFTing an image Create an FFT for an efficient size equal to or larger than image One needed for each direction to be FFTed. returns Python FFT object * image = Image to be FFTed * dir = FFT direction 1 -> R2C, 2 -> C2R """ ################################################################ # Checks if not Image.PIsA(image): raise TypeError("image MUST be a Python Obit Image") # # Get image info from descriptor desc = image.Desc descDict = desc.Dict rank = 2 # Only 2D FFTs dim = descDict["inaxes"] # Compute size to be efficient i = 0 effDim = [] for x in dim: effDim.append(FFT.PSuggestSize(x)) i = i+1 effDim name = "FFT for " + Image.PGetName(image) out = FFT.FFT(name, dir, 2, rank, effDim) return out
def main(): # Retrieve user input try: f = open(sys.argv[1],'r') lines = f.readlines() f.close() except: print '\n usage: '+sys.argv[0]+' XY.dat\n' sys.exit(0) # Parse the data t, y = [], [] for line in lines: t.append(float(line.split()[0])) y.append(float(line.split()[1])) # Calculate the FFT and get the frequencies N = float(len(t)) dt = t[1] - t[0] T = N * dt df = 1.0 / T f = Numeric.arange(N,typecode=Numeric.Float)*df H = ( FFT.fft(y)*Numeric.conjugate(FFT.fft(y)) ).real / N # Write to file out = open('PSD.dat','w') for i in range(len(f)/2): out.write(str(f[i])+' '+str(H[i])+'\n') out.close()
def caluclate_SF(hr, r, natom, alat, verbose=False): """ Perform Fourier Transform and calculate the strucure factor """ # Structure Factor Caluclation N = float(len(r)) # get # of data points dr = r[1] - r[0] # get distance spacing R = N * dr # define the period (total time) dQ = 1. / R # define frequency step Q = Numeric.arange(N, typecode=Numeric.Float) * dQ H = FFT.fft(hr) # calculate the fft print N, dr, R, dQ SF = 1.0 + (natom / alat**3) * H.real #(Numeric.conjugate(H)*H).real SF = Numeric.array(list(SF)[:int(len(SF) / 2.0)]) if verbose == True: hr2 = FFT.inverse_fft(H).real out = open('hr2.dat', 'w') for i in range(len(hr2)): out.write( str(r[i]) + ' ' + str(hr2[i]) + ' ' + str(Q[i]) + ' ' + str(H.real[i]) + '\n') out.close() return SF, Q
def Skew_Term_plot(sigma, v0, kappa, rho, theta): parameters = [sigma, v0, kappa, rho, theta] param_name = ['sigma', 'v0', 'kappa', 'rho', 'theta'] chg_var = [parameters.index(v) for v in parameters if isinstance(v, list)][0] title = 'Impact of ' + param_name[chg_var] fig, ax = plt.subplots(nrows=1, ncols=2) fig.suptitle(title, size=20) if chg_var == 0: variable = sigma for var in variable: b = FFT(var, v0, kappa, rho, theta, S0=150, r=0.025, T=0.25) K_T_vol_analysis(b, alpha, ax, variable) elif chg_var == 1: variable = v0 for var in variable: b = FFT(sigma, var, kappa, rho, theta, S0=150, r=0.025, T=0.25) K_T_vol_analysis(b, alpha, ax, variable) elif chg_var == 2: variable = kappa for var in variable: b = FFT(sigma, v0, var, rho, theta, S0=150, r=0.025, T=0.25) K_T_vol_analysis(b, alpha, ax, variable) elif chg_var == 3: variable = rho for var in variable: b = FFT(sigma, v0, kappa, var, theta, S0=150, r=0.025, T=0.25) K_T_vol_analysis(b, alpha, ax, variable) elif chg_var == 4: variable = theta for var in variable: b = FFT(sigma, v0, kappa, rho, var, S0=150, r=0.025, T=0.25) K_T_vol_analysis(b, alpha, ax, variable)
def test_fft(ndims): if ndims == 1: nfft = int(random.uniform(50, 520)) if doreal: nfft = int(nfft / 2) * 2 x = Numeric.array(make_random([nfft])) else: x = randmat(ndims) print 'dimensions=%s' % str(Numeric.shape(x)), if doreal: xver = FFT.real_fftnd(x) else: xver = FFT.fftnd(x) x2 = dofft(x) err = xver - x2 errf = flatten(err) xverf = flatten(xver) errpow = Numeric.vdot(errf, errf) + 1e-10 sigpow = Numeric.vdot(xverf, xverf) + 1e-10 snr = 10 * math.log10(abs(sigpow / errpow)) print 'SNR (compared to NumPy) : %.1fdB' % float(snr) if snr < minsnr: print 'xver=', xver print 'x2=', x2 print 'err', err sys.exit(1)
def test_fft(ndims): x = randmat(ndims) print 'dimensions=%s' % str(Numeric.shape(x)), if doreal: xver = FFT.real_fftnd(x) else: xver = FFT.fftnd(x) open('/tmp/fftexp.dat', 'w').write(dopack(flatten(xver), True)) x2 = dofft(x) err = xver - x2 errf = flatten(err) xverf = flatten(xver) errpow = Numeric.vdot(errf, errf) + 1e-10 sigpow = Numeric.vdot(xverf, xverf) + 1e-10 snr = 10 * math.log10(abs(sigpow / errpow)) print 'SNR (compared to NumPy) : %.1fdB' % float(snr) if snr < minsnr: print 'xver=', xver print 'x2=', x2 print 'err', err sys.exit(1)
def main(): path = 'C:/Users/2015136133/Desktop/' #경로 fft1 = FFT.FFT() fft2 = FFT.FFT() fft3 = FFT.FFT() startFun(fft1, path + 'fft1.wav') #FFT 과정을 수행함 startFun(fft2, path + 'fft2.wav') #FFT 과정을 수행함 startFun(fft3, path + 'fft3.wav') #FFT 과정을 수행함 #fft1.showPltFFT() #fft2.showPltFFT() #fft3.showPltFFT() fftavg = [((fft1.fftdata[i] + fft2.fftdata[i] + fft3.fftdata[i]) / 3) for i in range(len(fft1.fftdata))] # fft1, 2, 3의 평균값을 fftavg에다 넣어줌 fft4 = FFT.FFT() startFun(fft4,path + 'fft4.wav') cnt = 0 for i in range(len(fft4.fftdata)): if errrate(fftavg[i],fft4.fftdata[i]) > 70: cnt+=1 print((cnt/len(fftavg)*100), '% 입니다.') FFT.FFT.saveTextFile(fft1.freq, fftavg, path + 'avgfft.txt') #fft 평균을 txt로 저장
def test_fft(ndims): if ndims == 1: nfft = int(random.uniform(50,520)) if doreal: nfft = int(nfft/2)*2 x = Numeric.array(make_random( [ nfft ] ) ) else: x=randmat( ndims ) print 'dimensions=%s' % str( Numeric.shape(x) ), if doreal: xver = FFT.real_fftnd(x) else: xver = FFT.fftnd(x) x2=dofft(x) err = xver - x2 errf = flatten(err) xverf = flatten(xver) errpow = Numeric.vdot(errf,errf)+1e-10 sigpow = Numeric.vdot(xverf,xverf)+1e-10 snr = 10*math.log10(abs(sigpow/errpow) ) print 'SNR (compared to NumPy) : %.1fdB' % float(snr) if snr<minsnr: print 'xver=',xver print 'x2=',x2 print 'err',err sys.exit(1)
def main(): X = Numeric.arange(0,20*Numeric.pi,0.01,typecode=Numeric.Float) Y1 = Numeric.sin(X) Y2 = Numeric.sin(2*X) out = open('fncs.dat','w') for i in range(len(X)): out.write(str(X[i])+' '+str(Y1[i])+' '+str(Y2[i])+'\n') out.close() # Take FFT's FY1 = FFT.fft(Y1).real FY2 = FFT.fft(Y2).real N = float(len(X)) # get # of data points dX = X[1]-X[0] # get distance spacing T = N*dX # define the period (total time) dQ = 1./T # define frequency step Q=Numeric.arange(N,typecode=Numeric.Float)*dQ print Q[list(FY1).index(max(FY1))], max(FY1) print Q[list(FY2).index(max(FY2))], max(FY2) print list(FY1).index(max(FY1)) print list(FY2).index(max(FY2)) out = open('FFTs.dat','w') for i in range(len(Q)): out.write(str(Q[i])+' '+str(FY1[i])+' '+str(FY2[i])+'\n') out.close()
def compress(filename="lena.mn",output_filename="lena",compression_factor=.5): '''Writes a compressed mnc file. The number of values kept is the (orginal number)*(compression_factor). This version of the compression function acts on square images only.''' data = read_mn(filename) transformed_data = FFT(data) col_length=len(transformed_data) #also equals the number of rows row_length=len(transformed_data[0]) #also equals the number of columns #flatten the array: transformed_data=transformed_data.reshape((1,np.multiply(*transformed_data.shape)))[0] #given a compression factor, compression threshold is the value below which the... #function throws away frequency in the FFT data compression_threshold={'real':0,'imag':0} compression_threshold['real']=find_threshold(transformed_data.real,compression_factor) compression_threshold['imag']=find_threshold(transformed_data.imag,compression_factor) #by symmetry, the lower half of the data can be reproduced by the top half, excluding the first row upper_half=np.array(transformed_data[:(col_length/2+1)*row_length]) #split FFT data into two pieces, real and imag uh_real=upper_half.real uh_imag=upper_half.imag #throw away small values using compression threshold uh_real=np.array([i if abs(i)>compression_threshold['real'] else 0 for i in uh_real]) uh_imag=np.array([i if abs(i)>compression_threshold['imag'] else 0 for i in uh_imag]) #writes to mnc file write_mnc(output_filename+".mnc",np.around(uh_real).astype('int'),np.around(uh_imag).astype('int'), (len(data),len(data)),(1,0,1,0))
def azimuth_modulation_signal(param): # %%%%%%%%%%%%% INTRODUCING THE AZIMUTH MODULATION %%%%%%%%%%%%% # Load the data if param.signal == 1: data_signal = readsav('Scenes/compl_refl_lake.sav') if param.signal == 2: data_signal = readsav('Scenes/compl_refl_city.sav') if param.signal == 3: data_signal = readsav('Scenes/compl_refl_forest.sav') if param.signal == 4: data_signal = readsav('Scenes/compl_refl_town.sav') # Scene signal_compl_refl_zp = np.zeros((param.n_az, param.n_rg), dtype=complex) signal_compl_refl_zp[ int(1 * param.n_az / 4):int(3 * param.n_az / 4), int(3 * param.n_rg / 8):int( 5 * param.n_rg / 8 )] = data_signal.compl_refl # Use for data 16384x8192 (just comment out or in) #int(7 * param.n_rg / 16): int(9 * param.n_rg / 16)] = data_signal.compl_refl # Use for data 32768x8192 (just comment out or in) # Azimuth modulation FFT.my_ifft_azimuth( FFT.my_fft_azimuth(signal_compl_refl_zp) * FFT.my_fft_azimuth( Azimuth_Antenna_Pattern.antenna_pattern_signal(param)), savpath='u1') np.save('u1_conv', np.load('u1.npy', mmap_mode='r'))
def compress(filename="lena.mn", output_filename="lena", compression_factor=.5): '''Writes a compressed mnc file. The number of values kept is the (orginal number)*(compression_factor). This version of the compression function acts on square images only.''' data = read_mn(filename) transformed_data = FFT(data) col_length = len(transformed_data) #also equals the number of rows row_length = len(transformed_data[0]) #also equals the number of columns #flatten the array: transformed_data = transformed_data.reshape( (1, np.multiply(*transformed_data.shape)))[0] #given a compression factor, compression threshold is the value below which the... #function throws away frequency in the FFT data compression_threshold = {'real': 0, 'imag': 0} compression_threshold['real'] = find_threshold(transformed_data.real, compression_factor) compression_threshold['imag'] = find_threshold(transformed_data.imag, compression_factor) #by symmetry, the lower half of the data can be reproduced by the top half, excluding the first row upper_half = np.array(transformed_data[:(col_length / 2 + 1) * row_length]) #split FFT data into two pieces, real and imag uh_real = upper_half.real uh_imag = upper_half.imag #throw away small values using compression threshold uh_real = np.array( [i if abs(i) > compression_threshold['real'] else 0 for i in uh_real]) uh_imag = np.array( [i if abs(i) > compression_threshold['imag'] else 0 for i in uh_imag]) #writes to mnc file write_mnc(output_filename + ".mnc", np.around(uh_real).astype('int'), np.around(uh_imag).astype('int'), (len(data), len(data)), (1, 0, 1, 0))
def PMakeBeamMask(inImage, inFFT, err): """ Make uv plane weighting array Creates an FArray the size of a plane in inImage, FFT, takes real part and normalizes the central value to one Resulting array is returned. * inImage = Python Image whose FArray is to be converted to a weight mask * inFFT = Python Obit fortward FFT object * err = Python Obit Error/message stack """ ################################################################ # Checks if not Image.PIsA(inImage): print "Actually ", inImage.__class__ raise TypeError, "inImage MUST be a Python Obit Image" if not FFT.PIsA(inFFT): print "Actually ", inFFT.__class__ raise TypeError, "inFFT MUST be a Python Obit FFT" # # Make copy of data array inArray = inImage.FArray outArray = FArray.PClone(inArray, err) #OErr.printErrMsg(err, "Error duplicating FArray for "+Image.PGetName(inImage)) # Add model PCreateModel(inImage, outArray) # Pad for FFT FFTdim = FFT.PGetDim(inFFT) FFTArray = FArray.PClone(inArray, err) naxis = FFTdim[0:2] # Make output big enough for FFT FFTArray = FArray.FArray("FFT array", naxis) PPadArray(inFFT, outArray, FFTArray) del outArray # Cleanup # Swaparoonie FArray.PCenter2D(FFTArray) # FFT uvArray = PCreateFFTArray(inFFT) PFFTR2C(inFFT, FFTArray, uvArray) del FFTArray # Cleanup # Extract Real part naxis = CArray.PGetNaxis(uvArray)[0:2] maskArray = FArray.FArray("Mask array for " + Image.PGetName(inImage), naxis) CArray.PReal(uvArray, maskArray) del uvArray # Cleanup # Normalize pos = [0, 1 + naxis[1] / 2] peak = FArray.PMax(maskArray, pos) norm = 1.0 / peak FArray.PSMul(maskArray, norm) return maskArray
def FFT3D(array): """Returns the FFT of a three dimensional array This method can be used to obtain the FFT of a three dimensional array. """ import FFT N1, N2, N3 = array.shape return FFT.fft(FFT.fft2d(array, (N1, N2), axes=(0, 1)), N3, axis=2)
def fft2d(f): (Nr,Nc)=f.shape F=np.zeros((Nr,Nc),dtype=complex) for m in range(Nr): F[m,:]=FFT.fft(f[m,:]) for n in range(Nc): F[:,n]=FFT.fft(F[:,n]) return(F)
def azimuth_modulation_nadir(param): # %%%%%%%%%%%%% INTRODUCING THE AZIMUTH MODULATION %%%%%%%%%%%%% signal_compl_refl_zp=np.load('nadir_echo.npy', mmap_mode='r').T # Load the nadir echos signal (backscatter) file nadir_echo.npy generated with nadir_echo_generation.py # Azimuth modulation FFT.my_ifft_azimuth(FFT.my_fft_azimuth(signal_compl_refl_zp) * FFT.my_fft_azimuth(Azimuth_Antenna_Pattern.antenna_pattern_signal(param)), savpath='nadir_echo_az')
def range_modulation_conv_nadir(param): # %%%%%%%%%%%%% CONVENTIONAL SAR: LOAD AZIMUTH MODULATED DATA %%%%%%%%%%%%% u1_conv = np.load('nadir_echo_az.npy', mmap_mode='r') # %%%%%%%%%%%%% INTRODUCING THE CHIRP MODULATION %%%%%%%%%%%%% # Range modulation (performed in the frequency domain): Conventional SAR filter_mod = Filters.chirp_modulation_conv(param) FFT.my_ifft_range(FFT.my_fft_range(u1_conv) * FFT.my_fft_range(filter_mod), savpath='nadir_echo_raw_conv_rg_az')
def main(): from getopt import getopt import popen2 opts,args = getopt( sys.argv[1:],'u:n:Rt:' ) opts=dict(opts) exitcode=0 util = opts.get('-u','./kf_float') try: dims = [ int(d) for d in opts['-n'].split(',')] cpx = opts.get('-R') is None fmt=opts.get('-t','f') except KeyError: sys.stderr.write(""" usage: compfft.py -n d1[,d2,d3...] : FFT dimension(s) -u utilname : see sample_code/fftutil.c, default = ./kf_float -R : real-optimized version\n""") sys.exit(1) x = fft.make_random( dims ) cmd = '%s -n %s ' % ( util, ','.join([ str(d) for d in dims]) ) if cpx: xout = FFT.fftnd(x) xout = reshape(xout,(size(xout),)) else: cmd += '-R ' xout = FFT.real_fft(x) proc = popen2.Popen3( cmd , bufsize=len(x) ) proc.tochild.write( dopack( x , fmt ,cpx ) ) proc.tochild.close() xoutcomp = dounpack( proc.fromchild.read( ) , fmt ,1 ) #xoutcomp = reshape( xoutcomp , dims ) sig = xout * conjugate(xout) sigpow = sum( sig ) diff = xout-xoutcomp noisepow = sum( diff * conjugate(diff) ) snr = 10 * math.log10(abs( sigpow / noisepow ) ) if snr<100: print xout print xoutcomp exitcode=1 print 'NFFT=%s,SNR = %f dB' % (str(dims),snr) sys.exit(exitcode)
def main(): from getopt import getopt import popen2 opts, args = getopt(sys.argv[1:], 'u:n:Rt:') opts = dict(opts) exitcode = 0 util = opts.get('-u', './kf_float') try: dims = [int(d) for d in opts['-n'].split(',')] cpx = opts.get('-R') is None fmt = opts.get('-t', 'f') except KeyError: sys.stderr.write(""" usage: compfft.py -n d1[,d2,d3...] : FFT dimension(s) -u utilname : see sample_code/fftutil.c, default = ./kf_float -R : real-optimized version\n""") sys.exit(1) x = fft.make_random(dims) cmd = '%s -n %s ' % (util, ','.join([str(d) for d in dims])) if cpx: xout = FFT.fftnd(x) xout = reshape(xout, (size(xout), )) else: cmd += '-R ' xout = FFT.real_fft(x) proc = popen2.Popen3(cmd, bufsize=len(x)) proc.tochild.write(dopack(x, fmt, cpx)) proc.tochild.close() xoutcomp = dounpack(proc.fromchild.read(), fmt, 1) #xoutcomp = reshape( xoutcomp , dims ) sig = xout * conjugate(xout) sigpow = sum(sig) diff = xout - xoutcomp noisepow = sum(diff * conjugate(diff)) snr = 10 * math.log10(abs(sigpow / noisepow)) if snr < 100: print xout print xoutcomp exitcode = 1 print 'NFFT=%s,SNR = %f dB' % (str(dims), snr) sys.exit(exitcode)
def filtre_son_extrait(t, a, b): """calcul de la transformee de Fourier, application du filtre [a,b], recomposition du signal""" fft = FFT.fft(t) global fourier if fourier == None and indice != None: fourier = copy.copy(fft) for i in xrange(0, len(t)): if a <= i <= b: pass else: fft[i] = complex(0, 0) tt = FFT.inverse_fft(fft) for i in xrange(0, len(t)): t[i] = int(tt[i].real)
def filtre_son_extrait(t,a,b): """calcul de la transformee de Fourier, application du filtre [a,b], recomposition du signal""" fft = FFT.fft (t) global fourier if fourier == None and indice != None : fourier = copy.copy(fft) for i in xrange(0,len(t)): if a <= i <= b: pass else: fft [i] = complex(0,0) tt = FFT.inverse_fft(fft) for i in xrange(0,len(t)): t [i] = int(tt [i].real)
def polynomial_multi(pol1, pol2): '''returns the multiplication of two polynomials, parameters are lists of co-efficients here.''' l1 = len(pol1) l2 = len(pol2) large = l1 if l1 > l2 else l2 exp2 = FFT.nearest_2_exp(large) pol1_padded = FFT.zero_padder(pol1, 2 * exp2) pol2_padded = FFT.zero_padder(pol2, 2 * exp2) #we will now evaluate the polynomials at 2*exp2 values which is at least equal to the length of the multiplied poly DFT1 = FFT.discrete_fourier_transform(pol1_padded) DFT2 = FFT.discrete_fourier_transform(pol2_padded) DFT_mult_pol = [DFT1[i] * DFT2[i] for i in range(2 * exp2)] #Now we will apply inverse fft here to get the co-efficients co_eff_list = Inverse_FFT.inverse_discrete_fourier_transform(DFT_mult_pol) return co_eff_list
def getFreq(self, seconds): if self.fake: base = 300 if random.random() < .2: freq = base + randint(-50, 50) else: freq = base + randint(-200, 200) #freq = (random.random() * 400) + 100.0 distance = freq * 0.0051 - 0.0472 return (distance, freq, 1, 1, 1, 1) data = self.read(seconds) self.timestamp = time.time() transform = FFT.real_fft(data).real minFreq = 20 maxFreq = 700 minFreqPos = int(minFreq * seconds) maxFreqPos = int(maxFreq * seconds) minFreqPos = max(0, minFreqPos) maxFreqPos = min(int(self.sample_rate * seconds), maxFreqPos) if minFreqPos == maxFreqPos: self.lastFreq = int(self.sample_rate * sampleTime / 2.0) return elif minFreqPos > maxFreqPos: minFreqPos, maxFreqPos = maxFreqPos, minFreqPos freqPos = Numeric.argmax(transform[1 + minFreqPos:maxFreqPos]) value = transform[1 + minFreqPos:maxFreqPos][freqPos] freq = int((freqPos + minFreqPos) / seconds) distance = freq * 0.0051 - 0.0472 bestFreqPos = Numeric.argmax(transform[1:]) bestValue = transform[1:][bestFreqPos] bestFreq = int(bestFreqPos / seconds) return (distance, freq, value, transform[0], bestFreq, bestValue)
def __init__(self, input_token, threaded=True, kwargs_dict={}): """ The class implements the math processor abstract class the arguments in **kwargs are: window_duration window_start number_of_steps animated (if False means only one single frame of fft is calculated) """ window_duration_text = 'window_duration' window_start_text = 'window_start' number_of_steps_text = 'number_of_steps' animated_text = 'animated' if (not window_duration_text in kwargs_dict or not window_start_text in kwargs_dict or not number_of_steps_text in kwargs_dict or not animated_text in kwargs_dict): raise NecessaryArgNotPresent self.__window_duration = kwargs_dict[window_duration_text] self.__window_start = kwargs_dict[window_start_text] self.__number_of_steps = kwargs_dict[number_of_steps_text] self.__animated = kwargs_dict[animated_text] super().__init__(input_token, threaded) ## The queue to hold fft responses as a function of their ## start time self.__fft_frames_queue = queue.Queue() self.__fft_calculator = FFT.FFT()
def compute_notch_taps(self,notchlist): NOTCH_TAPS = 256 tmptaps = Numeric.zeros(NOTCH_TAPS,Numeric.Complex64) binwidth = self.bw / NOTCH_TAPS for i in range(0,NOTCH_TAPS): tmptaps[i] = complex(1.0,0.0) for i in notchlist: diff = i - self.observing if i == 0: break if (diff > 0): idx = diff / binwidth idx = int(idx) if (idx < 0 or idx > (NOTCH_TAPS/2)): break tmptaps[idx] = complex(0.0, 0.0) if (diff < 0): idx = -diff / binwidth idx = (NOTCH_TAPS/2) - idx idx = int(idx+(NOTCH_TAPS/2)) if (idx < 0 or idx > (NOTCH_TAPS)): break tmptaps[idx] = complex(0.0, 0.0) self.notch_taps = FFT.inverse_fft(tmptaps)
def Crosspectrum_5var(): pan_obs_gapfill = load('%s/pan_obs_gapfill_good_stations' % workspace) rn = load('%s/Rn_0.2_0.5_good_stations' % (workspace)) ist = 0 for ibasin in xrange(0, 10): cross_basin = [] data = scipy.io.loadmat('%s/%s_AP.mat' % (datadir, ibasin + 1)) for istation in good_stations[ibasin]: # the PowerSpectrum method take the matrix as different segment, so shoule be a 1d array input = [ Gapfill(data[v][0, istation][0:tstep].flatten()).flatten() for v in variables ] input.insert(1, rn[ist, :].flatten()) panobs = pan_obs_gapfill[ist, :].flatten() cross_basin.append( vstack([ FFT.CrossPowerSpectrum(panobs, v, sampling_frequency, 'linear')[1] for v in input ]).reshape(1, 5, nf)) ist = ist + 1 cross_basin = vstack(cross_basin) cross_basin.dump('%s/cross_5var_good_station_%s' % (workspace, basinlongs[ibasin])) return
def sample(self): newData = self.monitor.read() if len(newData) == 0: return self.timeDomain = newData # Round our actual sample size down to the nearest power of two for the FFT, # and only save the absolute value of the first half of the real part. self.numSamples = len(self.timeDomain) f = 1 while f <= self.numSamples: self.fftSamples = f f *= 2 self.freqDomain = FFT.real_fft(self.timeDomain, self.fftSamples).real self.freqDomain = Numeric.fabs(self.freqDomain[:len(self.freqDomain)/2]) self.spectrum = [] for s in self.spectrumSamplers: self.spectrum.append(s.get()) self.spectrum = Numeric.array(self.spectrum) self.beat = self.spectrum - self.oldSpectrum self.oldSpectrum = self.spectrum self.vuMeter = self.vuMeterSampler.get()
def Coherence_obs_5var(): "Prepare the data for plotting" pan_obs_gapfill = load('%s/pan_obs_gapfill_good_stations' % workspace) rn = load('%s/Rn_0.2_0.5_good_stations' % (workspace)) ist = 0 for ibasin in xrange(0, 10): cohere_obs_basin = [] data = scipy.io.loadmat('%s/%s_AP.mat' % (datadir, ibasin + 1)) for istation in good_stations[ibasin]: # the PowerSpectrum method take the matrix as different segment, so shoule be a 1d array input = [ Gapfill(data[v][0, istation][0:tstep].flatten()).flatten() for v in variables ] input.insert(1, rn[ist, :].flatten()) panobs = pan_obs_gapfill[ist, :].flatten() # Compute the coherence cohere_obs_basin.append( vstack([ FFT.Coherence(v, panobs, sampling_frequency, 'linear')[1] for v in input ]).reshape(1, 5, nf)) ist = ist + 1 # store basin average cohere_obs_basin = vstack(cohere_obs_basin) cohere_obs_basin.dump('%s/coherence_obs_5var_good_station_%s' % (workspace, basinlongs[ibasin])) # cohere_obs_basin.dump('%s/coherence_obs_5var_test2048_%s' %(workspace, basinlongs[ibasin])) return
def transform(self, inputSignal): # Automatic gain control gain = 0.4e5 / self.inputVolume # Read the audio, take an FFT of the left channel audio = inputSignal[0] fft = abs(FFT.real_fft(audio * gain)) # Track the input volume, for automatic gain control total = abs(add.reduce(audio)) alpha = 0.0025 self.inputVolume = (1-alpha)*self.inputVolume + alpha*total # Scale down the frequency axis nicely by integrating, # sampling, then differentiating. sums = add.accumulate(fft) hscaled = take(sums, self.taps) hscaled = maximum(hscaled[1:] - hscaled[:-1], 0) vscaled = hscaled * 4e-7 # Add gradual decay to bar heights if self.bars: self.bars -= 0.05 self.bars = maximum(self.bars, vscaled) else: self.bars = vscaled return self.bars
def PBackFFT(FFTrev, inArray, outArray, err): """ Back transform half plane complex to real inArray is FFTed (half plane complex - real) to outArray * FFTref = FFT object to FT inArray * inArray = CArray with image to be FFTed must be a size compatable with FFTrev * outArray = FArray for output must be a size compatable with FT of inArray * err = Python Obit Error/message stack """ ################################################################ # Checks if not FFT.PIsA(FFTrev): print("Actually ",FFTrev.__class__) raise TypeError("FFTrev MUST be a Python Obit FFT") if not CArray.PIsA(inArray ): print("Actually ",inArray.__class__) raise TypeError("inArray MUST be a Python Obit CArray") if not FArray.PIsA(outArray ): print("Actually ",outArray.__class__) raise TypeError("outArray MUST be a Python Obit FArray") if not OErr.OErrIsA(err): raise TypeError("err MUST be an OErr") # # FFT PFFTC2R (FFTrev, inArray, outArray) FArray.PCenter2D (outArray)
def getFreq(self, seconds): if self.fake: base = 300 if random.random() < .2: freq = base + randint(-50,50) else: freq = base + randint(-200, 200) #freq = (random.random() * 400) + 100.0 distance = freq * 0.0051 - 0.0472 return (distance, freq, 1, 1, 1, 1) data = self.read(seconds) self.timestamp = time.time() transform = FFT.real_fft(data).real minFreq = 20 maxFreq = 700 minFreqPos = int(minFreq * seconds) maxFreqPos = int(maxFreq * seconds) minFreqPos = max(0, minFreqPos) maxFreqPos = min(int(self.sample_rate * seconds), maxFreqPos) if minFreqPos == maxFreqPos: self.lastFreq = int(self.sample_rate * sampleTime/ 2.0) return elif minFreqPos > maxFreqPos: minFreqPos, maxFreqPos = maxFreqPos, minFreqPos freqPos = Numeric.argmax(transform[1+minFreqPos:maxFreqPos]) value = transform[1+minFreqPos:maxFreqPos][freqPos] freq = int((freqPos + minFreqPos) / seconds) distance = freq * 0.0051 - 0.0472 bestFreqPos = Numeric.argmax(transform[1:]) bestValue = transform[1:][bestFreqPos] bestFreq = int(bestFreqPos / seconds) return (distance, freq, value, transform[0], bestFreq, bestValue)
def PExtract (inFFT, inArray, outArray, err): """ Extract a Real array from one padded for FFTs Any blanked values are replaces with zeroes returns outArray * inFFT = Gives size of FFT used * inArray = Python FArray with FFT results. * outArray = Python FArray describing results * err = Python Obit Error/message stack """ ################################################################ # Checks if not FFT.PIsA(inFFT): raise TypeError("inFFT MUST be a Python Obit FFT") if not FArray.PIsA(inArray): print("Actually ",inArray.__class__) raise TypeError("inArray MUST be a Python Obit FArray") if not FArray.PIsA(outArray): print("Actually ",outArray.__class__) raise TypeError("outArray MUST be a Python Obit FArray") if not OErr.OErrIsA(err): raise TypeError("err MUST be an OErr") # # FFT info FFTrank = FFT.PGetRank(inFFT) FFTdim = FFT.PGetDim(inFFT) # Target Array info ArrayNdim = outArray.Ndim ArrayNaxis = outArray.Naxis # Get window to extract cen = [FFTdim[0]//2, FFTdim[1]//2]; blc = [0,0]; trc=[0,0] blc[0] = cen[0] - ArrayNaxis[0] // 2; trc[0] = cen[0] - 1 + ArrayNaxis[0] // 2 blc[1] = cen[1] - ArrayNaxis[1] // 2; trc[1] = cen[1] - 1 + ArrayNaxis[1] // 2 # Make sure to fill output array if ((trc[0]-blc[0]+1)<ArrayNaxis[0]): trc[0] = blc[0] + ArrayNaxis[0] - 1 if ((trc[1]-blc[1]+1)<ArrayNaxis[1]): trc[1] = blc[1] + ArrayNaxis[1] - 1 # Extract out = FArray.PSubArr(inArray, blc, trc, err) return out
def execute_cb(self, *args): layer = gview.app.sel_manager.get_active_layer() if not layer_is_raster(layer): gvutils.error("Please select a raster layer.") return ds = layer.get_parent().get_dataset() data = gdalnumeric.DatasetReadAsArray(ds) if self.switch_forward.get_active(): data_tr = FFT.fft2d(data) else: data_tr = FFT.inverse_fft2d(data) array_name = gdalnumeric.GetArrayFilename(data_tr) if self.switch_new_view.get_active(): gview.app.new_view() gview.app.file_open_by_name(array_name)
def Coherence_Frequency(): data = scipy.io.loadmat('%s/1_AP.mat' % (datadir)) input = data[variables[0]][0, 0][0:tstep].flatten() pan = data['pan'][0, 0][0:tstep].flatten() freq = FFT.Coherence(input, pan, sampling_frequency, 'linear')[0] return freq
def execute_cb( self, *args ): layer = gview.app.sel_manager.get_active_layer() if not layer_is_raster(layer): gvutils.error("Please select a raster layer."); return ds = layer.get_parent().get_dataset() data = gdalnumeric.DatasetReadAsArray(ds) if self.switch_forward.get_active(): data_tr = FFT.fft2d(data) else: data_tr = FFT.inverse_fft2d(data) array_name = gdalnumeric.GetArrayFilename(data_tr) if self.switch_new_view.get_active(): gview.app.new_view() gview.app.file_open_by_name(array_name)
def register_all(): if led_cube is not None: led_cube.register(Snake.Snake(api.cubeSize, frame_size), Pong.Pong(api.cubeSize, frame_size), PongMulti.PongMulti(api.cubeSize, frame_size), Weather.Weather(api.cubeSize, frame_size), FFT.AudioVis(api.cubeSize, frame_size), Exit.Exit(api.cubeSize, frame_size))
def pdata(): while (endFlag == 0): for i in range(16): data = sdr.read_samples(CHUNK) # data=[0.1+0.1j]*CHUNK F = FFT.FFT(data, level) q.put(F) print('endFlag=', endFlag) exit()
def filter2d_freq(img, the_filter): height = len(img) width = len(img[0]) adjust_height = calculate_pow2(height) adjust_width = calculate_pow2(width) FFT_filter = np.zeros((adjust_height,adjust_width), np.int32) adjust_img = np.zeros((adjust_height,adjust_width), np.int32) for x in xrange(height): for y in xrange(width): adjust_img[x, y] = img[x, y] for x in xrange(len(the_filter)): for y in xrange(len(the_filter[0])): FFT_filter[x, y] = the_filter[x, y] FFT_filter = FFT.centralize(FFT_filter) adjust_img = FFT.centralize(adjust_img) FFT_filter = FFT.fft2d(FFT_filter, 1) FFT_image = FFT.fft2d(adjust_img, 1) print "done Fourier transform" Result = FFT_image * FFT_filter print "done frequecy processing" Result = FFT.fft2d(Result, -1).real print "done Inverse Fourier transform" Result_img = np.zeros((height, width), np.float64) Result = diolog_transform(Result) for x in xrange(height): for y in xrange(width): Result_img[x, y] = Result[x, y] Result_img = centralize(Result_img) return Result_img
def InverseFFT(array): """Returns the inverse FFT of an array This method can be used to obtain the inverse FFT of an array """ import FFT dim = array.shape for i in range(len(dim)): array = FFT.inverse_fft(array, dim[i], axis=i) return array
def PFFTC2R (inFFT, inArray, outArray): """ Half plane complex to Real FFT * inFFT = Python Obit FFT object * inArray = Python CArray To be FFTed * outArray = Python FArray to contain the FFT Must previously exist """ ################################################################ if not FFT.PIsA(inFFT): raise TypeError("inFFT MUST be a Python Obit FFT") if not CArray.PIsA(inArray): print("Actually ",inArray.__class__) raise TypeError("inArray MUST be a Python Obit CArray") if not FArray.PIsA(outArray): print("Actually ",outArray.__class__) raise TypeError("outArray MUST be a Python Obit FArray") # FFT.PC2R(inFFT, inArray, outArray)
def line(data, xl): power = math.ceil(math.log2(xl)) length = 2**power remain = length - xl left = remain // 2 right = remain - left #print("left,right",left,right) data = ([0 + 0j] * left) + data + ([0 + 0j] * right) #d=data d = data[length // 2:] + data[0:length // 2] return FFT.iFFT(d, power)
def gen_midi(self): """ Gets the samples from the .wav input file and uses the FFT object to transform them into a midi file. """ self.progress_bar.show() self.progress_bar.setValue(10) self.app.processEvents() self.samples, self.rate = WavParser.get_samples_from_wav(str(self.infile)) fft = FFT( self.samples, self.rate, self.time_quantum, self.activation_level, self.condense, self.single_note, self.outfile, self.progress_bar, self.app, ) fft.calculate()
def test_cpx( n,inverse ,short): v = randvec(n,1) scale = 1 if short: minsnr=30 else: minsnr=100 if inverse: tvecout = FFT.inverse_fft(v) if short: scale = 1 else: scale = len(v) else: tvecout = FFT.fft(v) if short: scale = 1.0/len(v) tvecout = [ c * scale for c in tvecout ] s="""#define NFFT %d""" % len(v) + """ { double snr; kiss_fft_cpx test_vec_in[NFFT] = { """ + c_format(v) + """}; kiss_fft_cpx test_vec_out[NFFT] = {""" + c_format( tvecout ) + """}; kiss_fft_cpx testbuf[NFFT]; void * cfg = kiss_fft_alloc(NFFT,%d,0,0);""" % inverse + """ kiss_fft(cfg,test_vec_in,testbuf); snr = snr_compare(test_vec_out,testbuf,NFFT); printf("DATATYPE=" xstr(kiss_fft_scalar) ", FFT n=%d, inverse=%d, snr = %g dB\\n",NFFT,""" + str(inverse) + """,snr); if (snr<""" + str(minsnr) + """) exit_code++; free(cfg); } #undef NFFT """ return s
def compute_dispfilter(self,dm,doppler,bw,centerfreq): npts = len(self.disp_taps) tmp = Numeric.zeros(npts, Numeric.Complex64) M_PI = 3.14159265358 DM = dm/2.41e-10 # # Because astronomers are a crazy bunch, the "standard" calcultion # is in Mhz, rather than Hz # centerfreq = centerfreq / 1.0e6 bw = bw / 1.0e6 isign = int(bw / abs (bw)) # Center frequency may be doppler shifted cfreq = centerfreq / doppler # As well as the bandwidth.. bandwidth = bw / doppler # Bandwidth divided among bins binwidth = bandwidth / npts # Delay is an "extra" parameter, in usecs, and largely # untested in the Swinburne code. delay = 0.0 # This determines the coefficient of the frequency response curve # Linear in DM, but quadratic in center frequency coeff = isign * 2.0*M_PI * DM / (cfreq*cfreq) # DC to nyquist/2 n = 0 for i in range(0,int(npts/2)): freq = (n + 0.5) * binwidth phi = coeff*freq*freq/(cfreq+freq) + (2.0*M_PI*freq*delay) tmp[i] = complex(math.cos(phi), math.sin(phi)) n += 1 # -nyquist/2 to DC n = int(npts/2) n *= -1 for i in range(int(npts/2),npts): freq = (n + 0.5) * binwidth phi = coeff*freq*freq/(cfreq+freq) + (2.0*M_PI*freq*delay) tmp[i] = complex(math.cos(phi), math.sin(phi)) n += 1 self.disp_taps = FFT.inverse_fft(tmp) return(self.disp_taps)
def makeSpectrogram(slice): """ Returns a list of length 32, with the FFT of the slice. We seem to need 64 samples to do this. If the sample rate is 256Hz, then we're talking about 1/4th of a second's worth of data here. """ assert len(slice)==64, "we want 32 bins, so we need 64 samples" res = abs(FFT.real_fft(slice))[:-1] # discard 33rd slot (is this okay?) res = Numeric.floor(res) # round off to integers assert len(res)==32, len(res) return res
def test_DFT_native_roots(): x = Numeric.arange(256, typecode=Numeric.Complex) start = time.time() for i in range(10): X = DFT_naive_roots(x) stop = time.time() print '%.6f' % ((stop - start) / 10.0) XX = FFT.fft(x) # for x1, x2 in zip(X, XX): # print x1, x2 return
def caluclate_SF(hr,r,natom,alat,verbose=False): """ Perform Fourier Transform and calculate the strucure factor """ # Structure Factor Caluclation N = float(len(r)) # get # of data points dr = r[1] - r[0] # get distance spacing R = N*dr # define the period (total time) dQ = 1./R # define frequency step Q = Numeric.arange(N,typecode=Numeric.Float)*dQ H = FFT.fft(hr) # calculate the fft print N,dr,R,dQ SF = 1.0 + (natom/alat**3)*H.real#(Numeric.conjugate(H)*H).real SF = Numeric.array( list(SF)[:int(len(SF)/2.0)] ) if verbose == True: hr2 = FFT.inverse_fft(H).real out = open('hr2.dat','w') for i in range(len(hr2)): out.write(str(r[i])+' '+str(hr2[i])+' '+str(Q[i])+' '+str(H.real[i])+'\n') out.close() return SF, Q
def test_FFT_simple(): x = Numeric.arange(256, typecode=Numeric.Complex) start = time.time() for i in range(1): X = FFT_simple(x) stop = time.time() print '%.6f' % ((stop - start) / 1.0) XX = FFT.fft(x) i = 0 for x1, x2 in zip(X, XX): # Complex eq is too sensitive, compare string representations s1, s2 = str(x1), str(x2) assert(s1 == s2) return
def test_fftnd(ndims=3): import FFT import Numeric x=randmat( ndims ) print 'dimensions=%s' % str( Numeric.shape(x) ) #print 'x=%s' %str(x) xver = FFT.fftnd(x) x2=myfftnd(x) err = xver - x2 errf = flatten(err) xverf = flatten(xver) errpow = Numeric.vdot(errf,errf)+1e-10 sigpow = Numeric.vdot(xverf,xverf)+1e-10 snr = 10*math.log10(abs(sigpow/errpow) ) if snr<80: print xver print x2 print 'SNR=%sdB' % str( snr )
def plot_spect(jspec=None, plist=[0], beg=0, end=n_steps, endp=None): """plot_spect(jspec=None, plist=[0], beg=0, end=n_steps, endp=end/2) Fourier Spectra of particle trajectories. Plots over all species, by default, unless a range of species is provided via the parameter 'jspec' 'plist' is a list of particles to calculate spectrum over (Default is test particle #0). """ import FFT if endp is None: endp = nint(end/2) if jspec is None: jspec = range(0, top.ns) for sp in jspec: for part in plist: title = runid+": species "+`sp`+' '+colors[sp % ncolors]+'; particle '+`part` #absc = for plot in plots: __main__.__dict__['spect_'+plot] = FFT.fft( eval(plot+'_'+runid, __main__.__dict__)[sp,beg:end,part]) plg(abs(eval("spect_"+plot, __main__.__dict__))[:endp], marker=plot) #plg(eval("spect_"+plot, __main__.__dict__), absc, marker=plot) ptitles(plot+' '+title, "frequency", "spectral power"); fma()
def espectrofourier(img, libdir, ts, frings, fsectors, raios, angulos): M,N = img.shape[0], img.shape[1] d = min(M,N) # dimensao menor das imagens ci, cj = M/2, N/2 # coordenadas do centro da img rmax = d/2 # raio maximo da circ. que cabe na img slices = [] desc = [] F = FFT.fft2d(img) Fview = iadftview(F) # passar threshold aqui! # threshold realizado com dinamica - valores de extinção: #iawrite(Fview,'../tmp/fv.pgm') #os.system('%s./extinction htop ../tmp/fv.pgm ../tmp/result.pgm' % (libdir)) #Fvd = iaread('../tmp/result.pgm') #iashow(Fv) #Fvd = (Fvd>1)*Fview #iawrite(Fv,'../tmp/fv2.pgm') #iashow(dimask) #nz = nonzeroarea(dimask) #print nz #print "soma de tudo = "+str(nz.sum()) #ts = nz.sum()/nz.shape[0] #print ts #iashow(Fview) # threshold simples: #Fv = Fview Fv = Fview * (Fview > ts) #iashow(Fv) #a = raw_input() # em seguida é cortado o lado direito da imagem do espectro if M>N: # se a imagem for mais alta que larga: rightside = iaroi(Fv,[abs(ci-rmax),cj],[(ci+rmax-1),N]) #rightsided = iaroi(Fvd,[abs(ci-rmax),cj],[(ci+rmax-1),N]) elif N>M: # se for mais larga que alta: rightside = iaroi(Fv,[0,cj],[M-1,(cj+rmax-1)]) #rightsided = iaroi(Fvd,[0,cj],[M-1,(cj+rmax-1)]) else: # se for quadrada: rightside = iaroi(Fv,[0,cj],[M,N]) #rightsided = iaroi(Fvd,[0,cj],[M,N]) # carrega uma lista com templates para setores for ang in angulos: file = "../imgs/templates/%d.pbm" % (ang) slices.append(iaread(file)) for r in raios: circ = iacircle([d,d],r,[rmax,rmax]) circ = iaroi(circ,[0,rmax],[d,d]) # recorta lado direito do circulo circ2 = iacircle([d,d],50,[rmax,rmax]) circ2 = iaroi(circ2,[0,rmax],[d,d]) ring = circ-circ2 # diminui circulo maior pelo menor para formar anel if frings == "yes": # quantidade de pixels do anel qtd = ring.sum() # aplica a mascara para o anel inteiro rough = rightside*ring #roughd = rightsided*ring # calcular só p/ valores não-zero #nz = nonzeroarea(roughd) mean = rough.sum()/float(qtd) std = sqrt(((rough - mean)**2).sum()/qtd) desc += [std,mean] #desc += [nz.sum()] # media e desvio padrão dos setores if fsectors == "yes": for slice in slices: sector = slice*ring qtd = sector.sum() area = rightside*sector #aread = rightsided*sector #nz = nonzeroarea(aread) mean = area.sum()/float(qtd) std = sqrt(((area - mean)**2).sum()/qtd) # desc += [std,mean] #desc += [nz.sum()] return desc
def AutoCorrelationFunction(series): n = 2*len(series) FFTSeries = FFT.fft(series,n,0) FFTSeries = FFTSeries*N.conjugate(FFTSeries) FFTSeries = FFT.inverse_fft(FFTSeries,len(FFTSeries),0) return FFTSeries[:len(series)]/(len(series)-N.arange(len(series)))
else: Usage() i = i + 1 if infile is None: Usage() if outfile is None: Usage() if type == None: type = GDT_CFloat32 indataset = gdal.Open( infile, GA_ReadOnly ) out_driver = gdal.GetDriverByName(format) outdataset = out_driver.Create(outfile, indataset.RasterXSize, indataset.RasterYSize, indataset.RasterCount, type) for iBand in range(1, indataset.RasterCount + 1): inband = indataset.GetRasterBand(iBand) outband = outdataset.GetRasterBand(iBand) data = inband.ReadAsArray(0, 0) if transformation == 'forward': data_tr = FFT.fft2d(data) else: data_tr = FFT.inverse_fft2d(data) outband.WriteArray(data_tr)