import sys
import csv
import numpy as np
from numpy import sin, cos, tan, pi
import ast
# mode: 'file': read data from csvfile, other: make from func(x)
mode = 'file'
# for mode != 'file'
x0 = 0.0
x1 = 1.0
ndata = 1024
# low and high index limits to remove from FT data
#kcut0 = 5
#kcut1 = 1020
kcut0 = 0
kcut1 = 10
csvfile = 'xrd.csv'
outfile = 'smoothing-fft.csv'
[ドキュメント]
def getarg(iarg, defval = None):
try:
return argv[iarg]
except:
return defval
[ドキュメント]
def getintarg(iarg, defval = None):
try:
return int(argv[iarg])
except:
return defval
[ドキュメント]
def getfloatarg(iarg, defval = None):
try:
return float(argv[iarg])
except:
return defval
if __name__ == "__main__":
argv = sys.argv
narg = len(argv)
if narg <= 2:
print("")
print("Usage: python smmothing-fft.py csvfile kcut0 kcut1")
print("")
exit()
else:
csvfile = getarg(1, csvfile)
kcut0 = getfloatarg(2, kcut0)
kcut1 = getfloatarg(3, kcut1)
# three trigonometric functions with randomized frequencies
# A: amplitude, f: frequency, p1: phase
[ドキュメント]
def func(x):
x += 0.03 * np.random.rand();
f1, p1, A1 = ( 1.5, pi/4.0, 1.0);
f2, p2, A2 = ( 3.0, pi/3.0, 0.3);
f3, p3, A3 = (10.0, pi/6.0, 0.5);
return A1 * sin(2.0*pi * f1 * x + p1) \
+ A2 * sin(2.0*pi * f2 * x + p2) \
+ A3 * sin(2.0*pi * f3 * x + p3);
[ドキュメント]
def main():
global x0, x1, ndata
global csvfile
global outfile
print("")
print("========================================")
print("mode:", mode)
print("csv file:", csvfile)
print("k range: {} - {}".format(kcut0, kcut1))
if mode == 'file':
x = []
y = []
print("Read data from [{}]".format(csvfile))
with open(csvfile) as f:
fin = csv.reader(f)
next(fin)
c = 0
for row in fin:
if c == 0:
label = row
print("{}\t{}".format(label[0], label[1]))
else:
print("{}\t{}".format(row[0], row[1]))
x.append(float(row[0]))
y.append(float(row[1]))
c += 1
ndata = len(x)
xstep = x[1] - x[0]
x0 = x[1]
x1 = x0 + xstep * (ndata-1)
else:
x = np.zeros(ndata)
y = np.zeros(ndata)
print("Make data by func(x) with random scattering")
xstep = (x1 - x0) / ndata
print("x = ({}, {}, {})".format(x0, x1, xstep))
print("ndata={}".format(ndata))
for i in range(0, ndata):
x[i] = x0 + i * xstep
y[i] = func(x[i])
ndata = len(x)
print("")
print("ndata:", ndata)
# FFT
F = np.fft.fft(y)
# calculate FFTed x axis
xfrange = 1.0 / xstep
dxf = xfrange / (ndata-1)
xf = np.zeros(ndata)
for i in range(0, ndata):
xf[i] = i * dxf
print("")
print("x range : {} - {}".format(min(x), max(x)))
print("x(fft) range: {} - {}".format(min(xf), max(xf)))
# cut FT data outside [lf, hf] for smoothing
# note the FFTed data is symmetric for real part and anti-symmetric for imagenary part with respect to ndata/2
# LF data are near ix = 0 and ix = ndata - 1 HF data are around ndata/2
Fs = np.zeros(ndata, dtype = 'complex')
for i in range(0, int(ndata/2)):
if kcut0 <= xf[i] <= kcut1:
Fs[i] = F[i]
Fs[ndata - i - 1] = F[ndata - i - 1]
else:
# print("cut: {} {}".format(i, xf[i]))
Fs[i] = 0.0
Fs[ndata - i - 1] = 0.0
# iFFT
print("")
fs = np.fft.ifft(Fs)
f = open(outfile, 'w')
fout = csv.writer(f, lineterminator='\n')
fout.writerow(['x', 'y', 'x(fft)', 'y(fft).r', 'y(fft).i',
'ys(fft,cut).r', 'ys(fft,cut).i',
'ys(ifft).r', 'ys(ifft).i', '|ys(ifft)|'])
for i in range(0, ndata):
fout.writerow([x[i], y[i], xf[i], F[i].real, F[i].imag,
Fs[i].real, Fs[i].imag,
fs[i].real, fs[i].imag, abs(fs[i])])
print("")
if __name__ == "__main__":
main()