Healpy 插值后的坐标误差:平分线的出现
Healpy coordinate error after interpolation: appearance of bisector
我有一个由 128 个点组成的粗糙天空图,我想从中制作一个平滑的 healpix 地图(见附图,LHS)。文中引用的数字:
我加载我的数据,然后为最终地图制作适当像素长度的新经度和纬度数组(例如 nside=32)。
我的输入数据是:
lats = pi/2 + ths # theta from 0, pi, size 8
lons = phs # phi from 0, 2pi, size 16
data = sky_data[0] # shape (8,16)
新的 lon/lat 数组大小基于来自 nside 的像素数:
nside = 32
pixIdx = hp.nside2npix(nside) # number of pixels I can get from this nside
pixIdx = np.arange(pixIdx) # pixel index numbers
然后我通过插值找到这些像素的新数据值,然后从角度转换回像素。
# new lon/lat
new_lats = hp.pix2ang(nside, pixIdx)[0] # thetas I need to populate with interpolated theta values
new_lons = hp.pix2ang(nside, pixIdx)[1] # phis, same
# interpolation
lut = RectSphereBivariateSpline(lats, lons, data, pole_values=4e-14)
data_interp = lut.ev(new_lats.ravel(), new_lons.ravel()) #interpolate the data
pix = hp.ang2pix(nside, new_lats, new_lons) # convert latitudes and longitudes back to pixels
然后,我用插值构建了一个 healpy 映射:
healpix_map = np.zeros(hp.nside2npix(nside), dtype=np.double) # create empty map
healpix_map[pix] = data_interp # assign pixels to new interpolated values
testmap = hp.mollview(healpix_map)
地图的结果是附图的上部RHS。
(请原谅使用 jet -- viridis 没有 "white" 零,因此使用该颜色图会添加蓝色背景。)
地图看起来不对:从图中的粗图可以看出,下面的RHS应该有一个"hotspot",但是这里却出现在了左上角。
作为完整性检查,我使用 matplotlib 在 mollview 投影中绘制了插值点的散点图,图 2,其中我删除了标记的边缘以使其看起来像地图 ;)
ax = plt.subplot(111, projection='astro mollweide')
ax.grid()
colors = data_interp
sky=plt.scatter(new_lons, new_lats-pi/2, c = colors, edgecolors='none', cmap ='jet')
plt.colorbar(sky, orientation = 'horizontal')
您可以看到这张地图,即附图的右下角,生成的正是我所期望的!所以坐标没问题,我完全糊涂了。
有人遇到过这种情况吗?我能做什么?我想在这张地图和未来的地图上使用 healpy 函数,所以只使用 matplotlib 不是一个选项。
谢谢!
我想通了——我必须将 pi/2 添加到我的 thetas 中才能使插值工作,所以最后需要应用以下转换才能正确渲染图像:
newnew_lats = pi - new_lats
newnew_lons = pi + new_lons
插值似乎还有点问题,虽然现在看起来不那么明显了。我可能会尝试不同的比较。
我不是 healpix 方面的专家(实际上我以前从未使用过它 - 我是一名粒子物理学家),但据我所知这只是一个约定问题:在 Mollweide 投影中,healpy出于某种原因,将北极(正纬度)放在地图的底部。我不确定它为什么会这样做,或者这是否是故意的行为,但很明显这就是正在发生的事情。如果我屏蔽掉赤道以下的所有东西,即只保留正纬度点
mask = new_lats - pi/2 > 0
pix = hp.ang2pix(nside, new_lats[mask], new_lons[mask])
healpix_map = np.zeros(hp.nside2npix(nside), dtype=np.double)
healpix_map[pix] = data_interp[mask]
testmap = hp.mollview(healpix_map)
它得出了一个中心线以上没有数据的图:
至少它很容易修复。 mollview
接受一个 rot
参数,可以在投影之前有效地围绕视轴旋转球体,以及一个 flip
参数,可以设置为 'astro'
(默认)或 'geo'
设置东方显示在左边还是右边。一点点实验表明你得到了你想要的坐标系
hp.mollview(healpix_map, rot=(180, 0, 180), flip='geo')
元组中,前两个元素是要设置在地块中心的点的经度和纬度,第三个元素是旋转。都是度数。没有面具,它给出了这个:
我相信这正是您要找的。
我有一个由 128 个点组成的粗糙天空图,我想从中制作一个平滑的 healpix 地图(见附图,LHS)。文中引用的数字:
我加载我的数据,然后为最终地图制作适当像素长度的新经度和纬度数组(例如 nside=32)。
我的输入数据是:
lats = pi/2 + ths # theta from 0, pi, size 8
lons = phs # phi from 0, 2pi, size 16
data = sky_data[0] # shape (8,16)
新的 lon/lat 数组大小基于来自 nside 的像素数:
nside = 32
pixIdx = hp.nside2npix(nside) # number of pixels I can get from this nside
pixIdx = np.arange(pixIdx) # pixel index numbers
然后我通过插值找到这些像素的新数据值,然后从角度转换回像素。
# new lon/lat
new_lats = hp.pix2ang(nside, pixIdx)[0] # thetas I need to populate with interpolated theta values
new_lons = hp.pix2ang(nside, pixIdx)[1] # phis, same
# interpolation
lut = RectSphereBivariateSpline(lats, lons, data, pole_values=4e-14)
data_interp = lut.ev(new_lats.ravel(), new_lons.ravel()) #interpolate the data
pix = hp.ang2pix(nside, new_lats, new_lons) # convert latitudes and longitudes back to pixels
然后,我用插值构建了一个 healpy 映射:
healpix_map = np.zeros(hp.nside2npix(nside), dtype=np.double) # create empty map
healpix_map[pix] = data_interp # assign pixels to new interpolated values
testmap = hp.mollview(healpix_map)
地图的结果是附图的上部RHS。
(请原谅使用 jet -- viridis 没有 "white" 零,因此使用该颜色图会添加蓝色背景。)
地图看起来不对:从图中的粗图可以看出,下面的RHS应该有一个"hotspot",但是这里却出现在了左上角。
作为完整性检查,我使用 matplotlib 在 mollview 投影中绘制了插值点的散点图,图 2,其中我删除了标记的边缘以使其看起来像地图 ;)
ax = plt.subplot(111, projection='astro mollweide')
ax.grid()
colors = data_interp
sky=plt.scatter(new_lons, new_lats-pi/2, c = colors, edgecolors='none', cmap ='jet')
plt.colorbar(sky, orientation = 'horizontal')
您可以看到这张地图,即附图的右下角,生成的正是我所期望的!所以坐标没问题,我完全糊涂了。
有人遇到过这种情况吗?我能做什么?我想在这张地图和未来的地图上使用 healpy 函数,所以只使用 matplotlib 不是一个选项。
谢谢!
我想通了——我必须将 pi/2 添加到我的 thetas 中才能使插值工作,所以最后需要应用以下转换才能正确渲染图像:
newnew_lats = pi - new_lats
newnew_lons = pi + new_lons
插值似乎还有点问题,虽然现在看起来不那么明显了。我可能会尝试不同的比较。
我不是 healpix 方面的专家(实际上我以前从未使用过它 - 我是一名粒子物理学家),但据我所知这只是一个约定问题:在 Mollweide 投影中,healpy出于某种原因,将北极(正纬度)放在地图的底部。我不确定它为什么会这样做,或者这是否是故意的行为,但很明显这就是正在发生的事情。如果我屏蔽掉赤道以下的所有东西,即只保留正纬度点
mask = new_lats - pi/2 > 0
pix = hp.ang2pix(nside, new_lats[mask], new_lons[mask])
healpix_map = np.zeros(hp.nside2npix(nside), dtype=np.double)
healpix_map[pix] = data_interp[mask]
testmap = hp.mollview(healpix_map)
它得出了一个中心线以上没有数据的图:
至少它很容易修复。 mollview
接受一个 rot
参数,可以在投影之前有效地围绕视轴旋转球体,以及一个 flip
参数,可以设置为 'astro'
(默认)或 'geo'
设置东方显示在左边还是右边。一点点实验表明你得到了你想要的坐标系
hp.mollview(healpix_map, rot=(180, 0, 180), flip='geo')
元组中,前两个元素是要设置在地块中心的点的经度和纬度,第三个元素是旋转。都是度数。没有面具,它给出了这个:
我相信这正是您要找的。