我想要平滑一张不能覆盖整个天空的地图。此地图不是高斯分布,也不是零,所以healpy
的默认行为(其中0填充缺失值)会导致偏向此掩码边缘的较低值:
import healpy as hp
nside = 128
npix = hp.nside2npix(nside)
arr = np.ones(npix)
mask = np.zeros(npix, dtype=bool)
mask[:mask.size//2] = True
arr[~mask] = hp.UNSEEN
arr_sm = hp.smoothing(arr, fwhm=np.radians(5.))
hp.mollview(arr, title='Input array')
hp.mollview(arr_sm, title='Smoothed array')
我想通过将屏蔽值的权重设置为零来保留锐边,而不是将值设置为零。这看起来很困难,因为healpy
在谐波空间中执行平滑。
更具体地说,我想模仿scipy.gaussian_filter()
中的mode
关键字。 healpy.smoothing()
隐含地将mode=constant
与cval=0
一起使用,但我需要mode=reflect
之类的内容。
有没有合理的方法来解决这个问题?
答案 0 :(得分:2)
处理此问题的最简单方法是删除地图的平均值,使用hp.smoothing
执行平滑处理,然后再添加偏移量。
这解决了这个问题,因为现在地图是零均值,因此零填充不会产生边界效果。
def masked_smoothing(m, fwhm_deg=5.0):
#make sure m is a masked healpy array
m = hp.ma(m)
offset = m.mean()
smoothed=hp.smoothing(m - offset, fwhm=np.radians(fwhm_deg))
return smoothed + offset
我能想到的另一个选择是在平滑之前以“反射”模式填充地图的迭代算法,可能在cython
或numba
中实现,主要问题是复杂程度如何你的边界。如果它像纬度切割一样容易,那么所有这一切都很容易,因为一般情况非常复杂,并且可能需要处理很多极端情况:
答案 1 :(得分:1)
此问题与以下问答有关(免责声明:来自我):
https://stackoverflow.com/a/36307291/5350621
可以按照以下方式转移到您的案例:
import numpy as np
import healpy as hp
nside = 128
npix = hp.nside2npix(nside)
# using random numbers here to see the actual smoothing
arr = np.random.rand(npix)
mask = np.zeros(npix, dtype=bool)
mask[:mask.size//2] = True
def masked_smoothing(U, rad=5.0):
V=U.copy()
V[U!=U]=0
VV=hp.smoothing(V, fwhm=np.radians(rad))
W=0*U.copy()+1
W[U!=U]=0
WW=hp.smoothing(W, fwhm=np.radians(rad))
return VV/WW
# setting array to np.nan to exclude the pixels in the smoothing
arr[~mask] = np.nan
arr_sm = masked_smoothing(arr)
arr_sm[~mask] = hp.UNSEEN
hp.mollview(arr, title='Input array')
hp.mollview(arr_sm, title='Smoothed array')