Why do I get rows of zeros in my 2D fft?

Posted by Nicholas Pringle on Stack Overflow See other posts from Stack Overflow or by Nicholas Pringle
Published on 2011-11-16T12:17:06Z Indexed on 2011/11/17 1:51 UTC
Read the original article Hit count: 306

I am trying to replicate the results from a paper.

"Two-dimensional Fourier Transform (2D-FT) in space and time along sections of constant latitude (east-west) and longitude (north-south) were used to characterize the spectrum of the simulated flux variability south of 40degS." - Lenton et al(2006) The figures published show "the log of the variance of the 2D-FT".

I have tried to create an array consisting of the seasonal cycle of similar data as well as the noise. I have defined the noise as the original array minus the signal array.

Here is the code that I used to plot the 2D-FT of the signal array averaged in latitude:

import numpy as np

from numpy import ma
from matplotlib import pyplot as plt
from Scientific.IO.NetCDF import NetCDFFile 

### input directory 
indir = '/home/nicholas/data/'

### get the flux data which is in
### [time(5day ave for 10 years),latitude,longitude]
nc = NetCDFFile(indir + 'CFLX_2000_2009.nc','r')
cflux_southern_ocean  = nc.variables['Cflx'][:,10:50,:]
cflux_southern_ocean  = ma.masked_values(cflux_southern_ocean,1e+20) # mask land
nc.close()

cflux = cflux_southern_ocean*1e08 # change units of data from mmol/m^2/s

### create an array that consists of the seasonal signal fro each pixel
year_stack = np.split(cflux, 10, axis=0)
year_stack = np.array(year_stack)
signal_array = np.tile(np.mean(year_stack, axis=0), (10, 1, 1))
signal_array = ma.masked_where(signal_array > 1e20, signal_array) # need to mask
### average the array over latitude(or longitude)
signal_time_lon = ma.mean(signal_array, axis=1)

### do a 2D Fourier Transform of the time/space image
ft = np.fft.fft2(signal_time_lon)
mgft = np.abs(ft)   
ps = mgft**2 
log_ps = np.log(mgft)
log_mgft= np.log(mgft)

Every second row of the ft consists completely of zeros. Why is this? Would it be acceptable to add a randomly small number to the signal to avoid this.

signal_time_lon = signal_time_lon + np.random.randint(0,9,size=(730, 182))*1e-05

EDIT: Adding images and clarify meaning

The output of rfft2 still appears to be a complex array. Using fftshift shifts the edges of the image to the centre; I still have a power spectrum regardless. I expect that the reason that I get rows of zeros is that I have re-created the timeseries for each pixel. The ft[0, 0] pixel contains the mean of the signal. So the ft[1, 0] corresponds to a sinusoid with one cycle over the entire signal in the rows of the starting image.

Here are is the starting image using following code: Starting image

plt.pcolormesh(signal_time_lon); plt.colorbar(); plt.axis('tight')

Here is result using following code: enter image description here

ft = np.fft.rfft2(signal_time_lon)
mgft = np.abs(ft)   
ps = mgft**2                    
log_ps = np.log1p(mgft)
plt.pcolormesh(log_ps); plt.colorbar(); plt.axis('tight')

It may not be clear in the image but it is only every second row that contains completely zeros. Every tenth pixel (log_ps[10, 0]) is a high value. The other pixels (log_ps[2, 0], log_ps[4, 0] etc) have very low values.

© Stack Overflow or respective owner

Related posts about python

Related posts about image-processing