Source code for healpix_analyse.ps

import numpy as np

[docs] def ps(data, data_cross=None, plot_2D_fft=False): if data_cross is None: P2D = np.abs(np.fft.fftshift(np.fft.fft2(data))) ** 2 else: P2D = np.abs(np.fft.fftshift(np.fft.fft2(data) * np.conj(np.fft.fft2(data_cross)))) if plot_2D_fft: import matplotlib.pyplot as plt plt.imshow(P2D, norm='log') plt.colorbar(label='Power (log scale)', orientation='horizontal') plt.show() # Spatial frequency grids (cycles per unit length; NOT radians) ny, nx = P2D.shape fx = np.fft.fftshift(np.fft.fftfreq(nx)) # cycles per unit length (e.g., m^-1) fy = np.fft.fftshift(np.fft.fftfreq(ny)) # cycles per unit length (e.g., m^-1) fx2d, fy2d = np.meshgrid(fx, fy, indexing="xy") fr = np.sqrt(fx2d**2 + fy2d**2) # radial spatial frequency (cycles per unit length) # Radial binning nbins = min(nx, ny) // 2 f_bins = np.linspace(0.0, fr.max(), nbins + 1) # Vectorized bin average of P2D over annuli fr_flat = fr.ravel() P_flat = P2D.ravel() bin_idx = np.digitize(fr_flat, f_bins) - 1 # -> [0, nbins-1] valid = (bin_idx >= 0) & (bin_idx < nbins) # Sum and count per bin, then mean sum_per_bin = np.bincount(bin_idx[valid], weights=P_flat[valid], minlength=nbins) cnt_per_bin = np.bincount(bin_idx[valid], minlength=nbins) with np.errstate(invalid="ignore", divide="ignore"): Pk = sum_per_bin / cnt_per_bin Pk[cnt_per_bin == 0] = np.nan # empty bins # Bin centers f_centers = 0.5 * (f_bins[1:] + f_bins[:-1]) return f_centers, Pk / (nx*ny)