コード例 #1
0
ファイル: ftk.py プロジェクト: flatironinstitute/ftk
def pft_to_cartesian(Shat, T, N, pf_grid):
    xnodesr = pf_grid['xnodesr']
    n_psi = pf_grid['n_psi']
    quad_wts = pf_grid['quad_wts']

    ngridr = xnodesr.shape[0]

    n_templates = Shat.shape[0]

    dx = T / N
    dy = T / N

    wx = pf_grid['wx']
    wy = pf_grid['wy']

    templates1 = np.zeros((n_templates, N, N))

    # Again, Fortran ordering is necessary for FINUFFT.
    gxx = np.empty((N, N), dtype=np.complex128, order='F')

    upsampfac = 1.25

    for k in range(n_templates):
        fcc1 = Shat[k, :] * quad_wts

        isign = 1
        eps = 1e-6

        finufftpy.nufft2d1(wx * dx,
                           wy * dy,
                           fcc1,
                           isign,
                           eps,
                           N,
                           N,
                           gxx,
                           upsampfac=upsampfac)

        gxx = gxx * dx * dy / (4 * np.pi**2)

        templates1[k, :, :] = np.real(gxx.transpose((1, 0)))

    return templates1
コード例 #2
0
def vel_convolution_nufft(scalar, source_strenth, num_modes, L,  eps=1e-8, method=1, *args, **kwargs):
    if('kernel_hat' in kwargs):
        kernel_hat = kwargs['kernel_hat']
        assert isinstance(kernel_hat, np.ndarray)
    else:
        raise Exception(
            'kernel_hat, fourier transform of kernel should be given')

    Nshape = scalar.shape
    dim = Nshape[0]
    assert dim == 2, "Dim should be 2!"
    nx, ny = num_modes[:]
    if method == 1:
        xj, yj = scalar
        nj = len(xj)
        xmin = xj.min()
        xmax = xj.max()
        ymin = yj.min()
        ymax = yj.max()
        Lx, Ly = L
        assert ((xmax-xmin) <= Lx) & ((ymax-ymin) <= Ly), "All particles should be limieted to given [Lx,Ly] box!"
        # double zero-padding the delta function and scale it into [-pi,pi)
        xj = (xj-(xmax+xmin)/2)/Lx*np.pi
        yj = (yj-(ymax+ymin)/2)/Ly*np.pi
        fk = np.zeros(num_modes, dtype=np.complex128, order='F')
        # particle locations change at every iteration, no need to reuse fftw object
        ret = finufftpy.nufft2d1(xj, yj, source_strenth, -1, eps, nx, ny, fk, modeord=1)
        assert ret == 0, "NUFFT not successful!"
        v_hat = np.zeros((nx, ny, 2), order='F', dtype=np.complex128)
        v_hat[:, :, 0] = fk * kernel_hat[0]
        v_hat[:, :, 1] = fk * kernel_hat[1]
        v = np.zeros((nj, 2), order='F', dtype=np.complex128)
        ret = finufftpy.nufft2d2many(xj, yj, v, 1, eps, v_hat, modeord=1)
        assert ret == 0, "NUFFT not successful!"
        v = np.real(v)/(2*Lx*2*Ly)  # Real?
        return v
コード例 #3
0
	u = u_function(x, y, t)
	v = v_function(x, y, t)
	ux, uy = gradient(u)
	vx, vy = gradient(v)
	# get arrival points
	xn = x + dt*u
	yn = y + dt*v
	# compute weights
	Jxx = 1 + dt*ux
	Jxy = dt*uy
	Jyx = dt*vx
	Jyy = 1 + dt*vy
	det = Jxx*Jyy - Jxy*Jyx
	cw = c*det
	ch = np.zeros([n,n], dtype=complex, order='F')
	finufftpy.nufft2d1(xn, yn, cw.astype(complex), -1, 1e-14, n, n, ch, modeord=1)
	c = np.fft.ifft2(ch).real
	t += dt
	print('   t = {:0.3f}'.format(t), max_time, '\r', end='')
c_arrival = c.copy()
time_arrival = time.time() - st

################################################################################
# Evaluate

print('\n')
print('Err, true vs. euler    {:0.1e}'.format(np.abs(c_true-c_eulerian).max()))
print('Err, eul vs. dep       {:0.1e}'.format(np.abs(c_true-c_nonlinear_departure).max()))
print('Err, true vs. lin dep  {:0.1e}'.format(np.abs(c_true-c_linear_departure).max()))
print('Err, true vs. arrival  {:0.1e}'.format(np.abs(c_true-c_arrival).max()))
コード例 #4
0
def accuracy_speed_tests(num_nonuniform_points,num_uniform_points,eps):
	nj,nk = int(num_nonuniform_points),int(num_nonuniform_points)
	iflag=1
	num_samples=int(np.minimum(5,num_uniform_points*0.5+1)) # number of outputs used for estimating accuracy; is small for speed

	print('Accuracy and speed tests for %d nonuniform points and eps=%g (error estimates use %d samples per run)' % (num_nonuniform_points,eps,num_samples))

	# for doing the error estimates
	Xest=np.zeros(num_samples,dtype=np.complex128)
	Xtrue=np.zeros(num_samples,dtype=np.complex128)

	###### 1-d cases ........................................................
	ms=int(num_uniform_points)

	xj=np.random.rand(nj)*2*math.pi-math.pi
	cj=np.random.rand(nj)+1j*np.random.rand(nj);
	fk=np.zeros([ms],dtype=np.complex128)
	timer=time.time()
	ret=finufftpy.nufft1d1(xj,cj,iflag,eps,ms,fk)
	elapsed=time.time()-timer

	k=np.arange(-np.floor(ms/2),np.floor((ms-1)/2+1))
	for ii in np.arange(0,num_samples):
		Xest[ii]=np.sum(cj * np.exp(1j*k[ii]*xj))
		Xtrue[ii]=fk[ii]
	print_report('finufft1d1',elapsed,Xest,Xtrue,nj)

	xj=np.random.rand(nj)*2*math.pi-math.pi
	cj=np.zeros([nj],dtype=np.complex128);
	fk=np.random.rand(ms)+1j*np.random.rand(ms);
	timer=time.time()
	ret=finufftpy.nufft1d2(xj,cj,iflag,eps,fk)
	elapsed=time.time()-timer

	k=np.arange(-np.floor(ms/2),np.floor((ms-1)/2+1))
	for ii in np.arange(0,num_samples):
		Xest[ii]=np.sum(fk * np.exp(1j*k*xj[ii]))
		Xtrue[ii]=cj[ii]
	print_report('finufft1d2',elapsed,Xest,Xtrue,nj)

	x=np.random.rand(nj)*2*math.pi-math.pi
	c=np.random.rand(nj)+1j*np.random.rand(nj);
	s=np.random.rand(nk)*2*math.pi-math.pi
	f=np.zeros([nk],dtype=np.complex128)
	timer=time.time()
	ret=finufftpy.nufft1d3(x,c,iflag,eps,s,f)
	elapsed=time.time()-timer

	for ii in np.arange(0,num_samples):
		Xest[ii]=np.sum(c * np.exp(1j*s[ii]*x))
		Xtrue[ii]=f[ii]
	print_report('finufft1d3',elapsed,Xest,Xtrue,nj+nk)

	###### 2-d cases ....................................................
	ms=int(np.ceil(np.sqrt(num_uniform_points)))
	mt=ms

	xj=np.random.rand(nj)*2*math.pi-math.pi
	yj=np.random.rand(nj)*2*math.pi-math.pi
	cj=np.random.rand(nj)+1j*np.random.rand(nj)
	fk=np.zeros([ms,mt],dtype=np.complex128,order='F')
	timer=time.time()
	ret=finufftpy.nufft2d1(xj,yj,cj,iflag,eps,ms,mt,fk)
	elapsed=time.time()-timer

	Ks,Kt=np.mgrid[-np.floor(ms/2):np.floor((ms-1)/2+1),-np.floor(mt/2):np.floor((mt-1)/2+1)]

	for ii in np.arange(0,num_samples):
		Xest[ii]=np.sum(cj * np.exp(1j*(Ks.ravel()[ii]*xj+Kt.ravel()[ii]*yj)))
		Xtrue[ii]=fk.ravel()[ii]
	print_report('finufft2d1',elapsed,Xest,Xtrue,nj)

	## 2d1many:
	ndata = 5       # how many vectors to do
	cj=np.array(np.random.rand(nj,ndata)+1j*np.random.rand(nj,ndata),order='F')
	fk=np.zeros([ms,mt,ndata],dtype=np.complex128,order='F')
	timer=time.time()
	ret=finufftpy.nufft2d1many(xj,yj,cj,iflag,eps,ms,mt,fk)
	elapsed=time.time()-timer

	dtest = ndata-1    # which of the ndata to test (in 0,..,ndata-1)
	for ii in np.arange(0,num_samples):
		Xest[ii]=np.sum(cj[:,dtest] * np.exp(1j*(Ks.ravel(order='F')[ii]*xj+Kt.ravel(order='F')[ii]*yj)))   # note fortran-ravel-order needed throughout - mess.
		Xtrue[ii]=fk.ravel(order='F')[ii + dtest*ms*mt]       # hack the offset in fk array - has to be better way
	print_report('finufft2d1many',elapsed,Xest,Xtrue,ndata*nj)

	# 2d2
	xj=np.random.rand(nj)*2*math.pi-math.pi
	yj=np.random.rand(nj)*2*math.pi-math.pi
	cj=np.zeros([nj],dtype=np.complex128);
	fk=np.random.rand(ms,mt)+1j*np.random.rand(ms,mt);
	timer=time.time()
	ret=finufftpy.nufft2d2(xj,yj,cj,iflag,eps,fk)
	elapsed=time.time()-timer

	Ks,Kt=np.mgrid[-np.floor(ms/2):np.floor((ms-1)/2+1),-np.floor(mt/2):np.floor((mt-1)/2+1)]
	for ii in np.arange(0,num_samples):
		Xest[ii]=np.sum(fk * np.exp(1j*(Ks*xj[ii]+Kt*yj[ii])))
		Xtrue[ii]=cj[ii]
	print_report('finufft2d2',elapsed,Xest,Xtrue,nj)

	# 2d2many (using same ndata and dtest as 2d1many; see above)
	cj=np.zeros([nj,ndata],order='F',dtype=np.complex128);
	fk=np.array(np.random.rand(ms,mt,ndata)+1j*np.random.rand(ms,mt,ndata),order='F')
	timer=time.time()
	ret=finufftpy.nufft2d2many(xj,yj,cj,iflag,eps,fk)
	elapsed=time.time()-timer

	for ii in np.arange(0,num_samples):
		Xest[ii]=np.sum(fk[:,:,dtest] * np.exp(1j*(Ks*xj[ii]+Kt*yj[ii])))
		Xtrue[ii]=cj[ii,dtest]
	print_report('finufft2d2many',elapsed,Xest,Xtrue,ndata*nj)
	
	# 2d3
	x=np.random.rand(nj)*2*math.pi-math.pi
	y=np.random.rand(nj)*2*math.pi-math.pi
	c=np.random.rand(nj)+1j*np.random.rand(nj);
	s=np.random.rand(nk)*2*math.pi-math.pi
	t=np.random.rand(nk)*2*math.pi-math.pi
	f=np.zeros([nk],dtype=np.complex128)
	timer=time.time()
	ret=finufftpy.nufft2d3(x,y,c,iflag,eps,s,t,f)
	elapsed=time.time()-timer

	for ii in np.arange(0,num_samples):
		Xest[ii]=np.sum(c * np.exp(1j*(s[ii]*x+t[ii]*y)))
		Xtrue[ii]=f[ii]
	print_report('finufft2d3',elapsed,Xest,Xtrue,nj+nk)

	###### 3-d cases ............................................................
	ms=int(np.ceil(num_uniform_points**(1.0/3)))
	mt=ms
	mu=ms

	xj=np.random.rand(nj)*2*math.pi-math.pi
	yj=np.random.rand(nj)*2*math.pi-math.pi
	zj=np.random.rand(nj)*2*math.pi-math.pi
	cj=np.random.rand(nj)+1j*np.random.rand(nj);
	fk=np.zeros([ms,mt,mu],dtype=np.complex128,order='F')
	timer=time.time()
	ret=finufftpy.nufft3d1(xj,yj,zj,cj,iflag,eps,ms,mt,mu,fk)
	elapsed=time.time()-timer

	Ks,Kt,Ku=np.mgrid[-np.floor(ms/2):np.floor((ms-1)/2+1),-np.floor(mt/2):np.floor((mt-1)/2+1),-np.floor(mu/2):np.floor((mu-1)/2+1)]
	for ii in np.arange(0,num_samples):
		Xest[ii]=np.sum(cj * np.exp(1j*(Ks.ravel()[ii]*xj+Kt.ravel()[ii]*yj+Ku.ravel()[ii]*zj)))
		Xtrue[ii]=fk.ravel()[ii]
	print_report('finufft3d1',elapsed,Xest,Xtrue,nj)

	xj=np.random.rand(nj)*2*math.pi-math.pi
	yj=np.random.rand(nj)*2*math.pi-math.pi
	zj=np.random.rand(nj)*2*math.pi-math.pi
	cj=np.zeros([nj],dtype=np.complex128);
	fk=np.random.rand(ms,mt,mu)+1j*np.random.rand(ms,mt,mu);
	timer=time.time()
	ret=finufftpy.nufft3d2(xj,yj,zj,cj,iflag,eps,fk)
	elapsed=time.time()-timer

	Ks,Kt,Ku=np.mgrid[-np.floor(ms/2):np.floor((ms-1)/2+1),-np.floor(mt/2):np.floor((mt-1)/2+1),-np.floor(mu/2):np.floor((mu-1)/2+1)]
	for ii in np.arange(0,num_samples):
		Xest[ii]=np.sum(fk * np.exp(1j*(Ks*xj[ii]+Kt*yj[ii]+Ku*zj[ii])))
		Xtrue[ii]=cj[ii]
	print_report('finufft3d2',elapsed,Xest,Xtrue,nj)

	x=np.random.rand(nj)*2*math.pi-math.pi
	y=np.random.rand(nj)*2*math.pi-math.pi
	z=np.random.rand(nj)*2*math.pi-math.pi
	c=np.random.rand(nj)+1j*np.random.rand(nj);
	s=np.random.rand(nk)*2*math.pi-math.pi
	t=np.random.rand(nk)*2*math.pi-math.pi
	u=np.random.rand(nk)*2*math.pi-math.pi
	f=np.zeros([nk],dtype=np.complex128)
	timer=time.time()
	ret=finufftpy.nufft3d3(x,y,z,c,iflag,eps,s,t,u,f)
	elapsed=time.time()-timer

	for ii in np.arange(0,num_samples):
		Xest[ii]=np.sum(c * np.exp(1j*(s[ii]*x+t[ii]*y+u[ii]*z)))
		Xtrue[ii]=f[ii]
	print_report('finufft3d3',elapsed,Xest,Xtrue,nj+nk)
コード例 #5
0
def accuracy_speed_tests(num_nonuniform_points, num_uniform_points, eps):
    nj, nk = int(num_nonuniform_points), int(num_nonuniform_points)
    iflag = 1
    num_samples = int(np.minimum(20, num_uniform_points * 0.5 +
                                 1))  #for estimating accuracy

    print(
        'Accuracy and speed tests for %d nonuniform points and eps=%g (error estimates use %d samples per run)'
        % (num_nonuniform_points, eps, num_samples))

    # for doing the error estimates
    Xest = np.zeros(num_samples, dtype=np.complex128)
    Xtrue = np.zeros(num_samples, dtype=np.complex128)

    ###### 1-d
    ms = int(num_uniform_points)

    xj = np.random.rand(nj) * 2 * math.pi - math.pi
    cj = np.random.rand(nj) + 1j * np.random.rand(nj)
    fk = np.zeros([ms], dtype=np.complex128)
    timer = time.time()
    ret = finufftpy.nufft1d1(xj, cj, iflag, eps, ms, fk)
    elapsed = time.time() - timer

    k = np.arange(-np.floor(ms / 2), np.floor((ms - 1) / 2 + 1))
    for ii in np.arange(0, num_samples):
        Xest[ii] = np.sum(cj * np.exp(1j * k[ii] * xj))
        Xtrue[ii] = fk[ii]
    print_report('finufft1d1', elapsed, Xest, Xtrue, nj)

    xj = np.random.rand(nj) * 2 * math.pi - math.pi
    cj = np.zeros([nj], dtype=np.complex128)
    fk = np.random.rand(ms) + 1j * np.random.rand(ms)
    timer = time.time()
    ret = finufftpy.nufft1d2(xj, cj, iflag, eps, fk)
    elapsed = time.time() - timer

    k = np.arange(-np.floor(ms / 2), np.floor((ms - 1) / 2 + 1))
    for ii in np.arange(0, num_samples):
        Xest[ii] = np.sum(fk * np.exp(1j * k * xj[ii]))
        Xtrue[ii] = cj[ii]
    print_report('finufft1d2', elapsed, Xest, Xtrue, nj)

    x = np.random.rand(nj) * 2 * math.pi - math.pi
    c = np.random.rand(nj) + 1j * np.random.rand(nj)
    s = np.random.rand(nk) * 2 * math.pi - math.pi
    f = np.zeros([nk], dtype=np.complex128)
    timer = time.time()
    ret = finufftpy.nufft1d3(x, c, iflag, eps, s, f)
    elapsed = time.time() - timer

    for ii in np.arange(0, num_samples):
        Xest[ii] = np.sum(c * np.exp(1j * s[ii] * x))
        Xtrue[ii] = f[ii]
    print_report('finufft1d3', elapsed, Xest, Xtrue, nj + nk)

    ###### 2-d
    ms = int(np.ceil(np.sqrt(num_uniform_points)))
    mt = ms

    xj = np.random.rand(nj) * 2 * math.pi - math.pi
    yj = np.random.rand(nj) * 2 * math.pi - math.pi
    cj = np.random.rand(nj) + 1j * np.random.rand(nj)
    fk = np.zeros([ms, mt], dtype=np.complex128, order='F')
    timer = time.time()
    ret = finufftpy.nufft2d1(xj, yj, cj, iflag, eps, ms, mt, fk)
    elapsed = time.time() - timer

    Ks, Kt = np.mgrid[-np.floor(ms / 2):np.floor((ms - 1) / 2 + 1),
                      -np.floor(mt / 2):np.floor((mt - 1) / 2 + 1)]

    for ii in np.arange(0, num_samples):
        Xest[ii] = np.sum(
            cj * np.exp(1j * (Ks.ravel()[ii] * xj + Kt.ravel()[ii] * yj)))
        Xtrue[ii] = fk.ravel()[ii]
    print_report('finufft2d1', elapsed, Xest, Xtrue, nj)

    xj = np.random.rand(nj) * 2 * math.pi - math.pi
    yj = np.random.rand(nj) * 2 * math.pi - math.pi
    cj = np.zeros([nj], dtype=np.complex128)
    fk = np.random.rand(ms, mt) + 1j * np.random.rand(ms, mt)
    timer = time.time()
    ret = finufftpy.nufft2d2(xj, yj, cj, iflag, eps, fk)
    elapsed = time.time() - timer

    Ks, Kt = np.mgrid[-np.floor(ms / 2):np.floor((ms - 1) / 2 + 1),
                      -np.floor(mt / 2):np.floor((mt - 1) / 2 + 1)]
    for ii in np.arange(0, num_samples):
        Xest[ii] = np.sum(fk * np.exp(1j * (Ks * xj[ii] + Kt * yj[ii])))
        Xtrue[ii] = cj[ii]
    print_report('finufft2d2', elapsed, Xest, Xtrue, nj)

    x = np.random.rand(nj) * 2 * math.pi - math.pi
    y = np.random.rand(nj) * 2 * math.pi - math.pi
    c = np.random.rand(nj) + 1j * np.random.rand(nj)
    s = np.random.rand(nk) * 2 * math.pi - math.pi
    t = np.random.rand(nk) * 2 * math.pi - math.pi
    f = np.zeros([nk], dtype=np.complex128)
    timer = time.time()
    ret = finufftpy.nufft2d3(x, y, c, iflag, eps, s, t, f)
    elapsed = time.time() - timer

    for ii in np.arange(0, num_samples):
        Xest[ii] = np.sum(c * np.exp(1j * (s[ii] * x + t[ii] * y)))
        Xtrue[ii] = f[ii]
    print_report('finufft2d3', elapsed, Xest, Xtrue, nj + nk)

    ###### 3-d
    ms = int(np.ceil(num_uniform_points**(1.0 / 3)))
    mt = ms
    mu = ms

    xj = np.random.rand(nj) * 2 * math.pi - math.pi
    yj = np.random.rand(nj) * 2 * math.pi - math.pi
    zj = np.random.rand(nj) * 2 * math.pi - math.pi
    cj = np.random.rand(nj) + 1j * np.random.rand(nj)
    fk = np.zeros([ms, mt, mu], dtype=np.complex128, order='F')
    timer = time.time()
    ret = finufftpy.nufft3d1(xj, yj, zj, cj, iflag, eps, ms, mt, mu, fk)
    elapsed = time.time() - timer

    Ks, Kt, Ku = np.mgrid[-np.floor(ms / 2):np.floor((ms - 1) / 2 + 1),
                          -np.floor(mt / 2):np.floor((mt - 1) / 2 + 1),
                          -np.floor(mu / 2):np.floor((mu - 1) / 2 + 1)]
    for ii in np.arange(0, num_samples):
        Xest[ii] = np.sum(cj * np.exp(
            1j *
            (Ks.ravel()[ii] * xj + Kt.ravel()[ii] * yj + Ku.ravel()[ii] * zj)))
        Xtrue[ii] = fk.ravel()[ii]
    print_report('finufft3d1', elapsed, Xest, Xtrue, nj)

    xj = np.random.rand(nj) * 2 * math.pi - math.pi
    yj = np.random.rand(nj) * 2 * math.pi - math.pi
    zj = np.random.rand(nj) * 2 * math.pi - math.pi
    cj = np.zeros([nj], dtype=np.complex128)
    fk = np.random.rand(ms, mt, mu) + 1j * np.random.rand(ms, mt, mu)
    timer = time.time()
    ret = finufftpy.nufft3d2(xj, yj, zj, cj, iflag, eps, fk)
    elapsed = time.time() - timer

    Ks, Kt, Ku = np.mgrid[-np.floor(ms / 2):np.floor((ms - 1) / 2 + 1),
                          -np.floor(mt / 2):np.floor((mt - 1) / 2 + 1),
                          -np.floor(mu / 2):np.floor((mu - 1) / 2 + 1)]
    for ii in np.arange(0, num_samples):
        Xest[ii] = np.sum(
            fk * np.exp(1j * (Ks * xj[ii] + Kt * yj[ii] + Ku * zj[ii])))
        Xtrue[ii] = cj[ii]
    print_report('finufft3d2', elapsed, Xest, Xtrue, nj)

    x = np.random.rand(nj) * 2 * math.pi - math.pi
    y = np.random.rand(nj) * 2 * math.pi - math.pi
    z = np.random.rand(nj) * 2 * math.pi - math.pi
    c = np.random.rand(nj) + 1j * np.random.rand(nj)
    s = np.random.rand(nk) * 2 * math.pi - math.pi
    t = np.random.rand(nk) * 2 * math.pi - math.pi
    u = np.random.rand(nk) * 2 * math.pi - math.pi
    f = np.zeros([nk], dtype=np.complex128)
    timer = time.time()
    ret = finufftpy.nufft3d3(x, y, z, c, iflag, eps, s, t, u, f)
    elapsed = time.time() - timer

    for ii in np.arange(0, num_samples):
        Xest[ii] = np.sum(c * np.exp(1j * (s[ii] * x + t[ii] * y + u[ii] * z)))
        Xtrue[ii] = f[ii]
    print_report('finufft3d3', elapsed, Xest, Xtrue, nj + nk)
コード例 #6
0
ファイル: FFTgridDSGfile.py プロジェクト: petejan/imos-tools
def FFTgridDSGfile(netCDFfiles):
    ds = Dataset(netCDFfiles[1], 'a')

    vs = ds.get_variables_by_attributes(
        standard_name='sea_water_pressure_due_to_sea_water')
    vs = ds.get_variables_by_attributes(long_name='actual depth')

    pres_var = vs[0]
    pres = pres_var[:]

    #plt.plot(pres)
    #plt.show()

    temp_var = ds.variables["TEMP"]

    print("Read and convert time")
    time_var = ds.variables["TIME"]
    #time = num2date(time_var[:], units=time_var.units, calendar=time_var.calendar)
    #first_hour = time[0].replace(minute=0, second=0, microsecond=0)

    t = time_var[:] * 24
    hours = t

    # scale time to -pi to pi
    hours_min = np.min(hours)
    hours_max = np.max(hours)
    mid_hours = (hours_max + hours_min) / 2

    print(
        "time min, max", hours_min, hours_max,
        num2date(hours_max / 24,
                 units=time_var.units,
                 calendar=time_var.calendar),
        num2date(hours_min / 24,
                 units=time_var.units,
                 calendar=time_var.calendar),
        num2date(mid_hours / 24,
                 units=time_var.units,
                 calendar=time_var.calendar))

    t2pi = 2 * np.pi * (hours - mid_hours) / (hours_max - hours_min)

    # scale pressure to -pi to pi

    pres_min = np.min(pres)
    pres_max = np.max(pres)
    pres_mid = (pres_max + pres_min) / 2

    print("pres min, max", pres_min, pres_max, pres_mid)

    d2pi = 2 * np.pi * (pres - pres_mid) / (pres_max - pres_min)

    #plt.plot(t2pi)
    #plt.show()

    nt_points = int(hours_max - hours_min)
    nd_points = 20
    print(nt_points, nd_points)

    fft = np.full(
        [nt_points, nd_points],
        np.nan,
        dtype=np.complex128,
        order='F',
    )

    print("Calc FFT")

    x = t2pi
    y = d2pi
    c = np.array(temp_var[:])
    #c.real = temp_var[:]
    #c.imag = 0
    print(c)

    print("size ", len(x), len(y), len(c))

    # finufftpy.nufft2d2(x, y, c, isign, eps, f, debug=0, spread_debug=0, spread_sort=2, fftw=0, modeord=0, chkbnds=1, upsampfac=2.0)
    #finufftpy.nufft2d1(x, y, c, isign, eps, ms, mt, f, debug=0, spread_debug=0, spread_sort=2, fftw=0, modeord=0, chkbnds=1, upsampfac=2.0)¶
    res = finufftpy.nufft2d1(x,
                             y,
                             c,
                             0,
                             1e-15,
                             nt_points,
                             nd_points,
                             fft,
                             debug=1,
                             spread_debug=1,
                             spread_sort=0)

    print("fft res", res)
    print(fft)

    for x in range(0, nd_points):
        plt.plot(10 * np.log10(abs(fft[:, x])))
    plt.grid(True)
    plt.show()

    F1 = np.fft.ifft2(fft)
    f2 = np.fft.fftshift(F1)

    print("inverted ", f2.shape, len(hours))
    first_hour = num2date(hours_min / 24,
                          units=time_var.units,
                          calendar=time_var.calendar).replace(minute=0,
                                                              second=0,
                                                              microsecond=0)
    td = [first_hour + timedelta(hours=x) for x in range(nt_points)]

    for x in range(0, nd_points):
        plt.plot(td, abs(f2[:, x]) / (len(hours) / (nt_points)))
    plt.grid(True)
    plt.xticks(fontsize=6)
    plt.show()

    index_var = ds.variables["instrument_index"]
    idx = index_var[:]
    instrument_id_var = ds.variables["instrument_id"]
    #time = num2date(time_var[:], units=time_var.units, calendar=time_var.calendar)

    #print(idx)
    i = 0
    for x in chartostring(instrument_id_var[:]):
        #print (i, x, time[idx == 1], pres[idx == i])
        #plt.plot(time[idx == i], pres[idx == i])  # , marker='.'
        i += 1

    #plt.gca().invert_yaxis()
    #plt.grid(True)

    # close the netCDF file
    ds.close()

    plt.show()

    ncOut = Dataset("fft-bin.nc", 'w', format='NETCDF4')

    # add time
    tDim = ncOut.createDimension("TIME", nt_points)
    ncTimesOut = ncOut.createVariable("TIME", "d", ("TIME", ), zlib=True)
    ncTimesOut.long_name = "time"
    ncTimesOut.units = "days since 1950-01-01 00:00:00 UTC"
    ncTimesOut.calendar = "gregorian"
    ncTimesOut.axis = "T"
    ncTimesOut[:] = hours_min / 24

    bin_dim = ncOut.createDimension("BIN", nd_points)
    bin_var = ncOut.createVariable("BIN", "d", ("BIN", ), zlib=True)
    bin_var[:] = range(0, nd_points)

    # add variables

    nc_var_out = ncOut.createVariable("TEMP",
                                      "f4", ("TIME", "BIN"),
                                      fill_value=np.nan,
                                      zlib=True)
    print("shape ", f2.shape, nc_var_out.shape)

    nc_var_out[:] = abs(f2)

    # add some summary metadata
    ncTimeFormat = "%Y-%m-%dT%H:%M:%SZ"

    # add creating and history entry
    ncOut.setncattr("date_created", datetime.utcnow().strftime(ncTimeFormat))
    ncOut.setncattr(
        "history",
        datetime.utcnow().strftime("%Y-%m-%d") + " created from file " +
        netCDFfiles[1])

    ncOut.close()