Reputation: 11
I have a list of galaxies to plot onto a healpix map (which I'm using healpy to do) each galaxy has a set flux and I need to have them plotted in such a way that the flux for each galaxy is conserved on the map.
This is my code:
import numpy as np
import matplotlib.pyplot as plt
import healpy as hp
pi = np.pi
nside = 8
xsize = 100
ra = np.array([pi/4,pi/3])
dec = np.array([pi/4,pi/3])
flux = np.array([10,20])
hpm = np.zeros(hp.nside2npix(nside)) #Blank healpix map
pixindex = hp.ang2pix(nside, dec, ra)
np.add.at(hpm,pixindex,flux) #Add flux onto correct pixels
img=hp.mollview(hpm,coord=['E'],xsize=xsize,return_projected_map=True)
print(np.sum(img[img>0]))
The result I get is 140 and not 30 which is the true sum of the fluxes.
I get what is going on and that the same flux is being spread over multiple pixels (6 for the first galaxy and 4 pixels for the second) and I'm aware I could just do:
newimg = img * (np.sum(flux)/np.sum(img[img>0]))
and this would conserve the total photon count but it wouldn't necessarily conserve the photon count of each galaxy which is what I need. i.e this method ends up with the first galaxy contributing a flux of 12.86 and the second galaxy a flux of 17.14.
Is there a way of working out before how many pixels each coordinate will take up then altering the amount of flux dumped based on this?
Thanks in advance!
Upvotes: 1
Views: 417
Reputation: 21
The xsize
parameter for the function hp.mollview
should be used for plotting purpose only. If you would like to manipulate the resolution of the map, use hp.pixelfunc.ud_grade
For example, if you want to go from nside=8
to nside=32
,
After the line
np.add.at(hpm, pixindex, flux) #Add flux onto correct pixels
use the ud_grade
function with power=-2
, so the total flux can be conserved:
hpm_nside_32 = hp.pixelfunc.ud_grade(hpm, power=-2, nside_out=32)
the sum
np.sum(hpm_nside_32)
will be conserved at 30
.
I can't offer a solution if you need the mollview to have the flux conserved. The closest I can get is by scaling the img value down based on the ratio of the number of pixels in the mollview image and the number of pixels in the hpm. The first term xsize * xsize / 2.
is the number of pixels in the mollview, the second term 2. * np.pi / 8.
is the ratio of the area of an ellipse with semi-minor axis half the length of the semi-major axis pi * r * 2r
to the area of a rectangle 4r * 2r
.
len(hpm) / ((xsize * xsize / 2.) * (2. * np.pi / 8.)) * np.sum(img[img > 0])
When xsize = 100
, the sum will become 27.380
; when xsize = 1000
, the approximation is much better, at 29.981
; when xsize = 10000
, total flux becomes 29.988
.
An alternative way to give you a good approximation is to compute the ratio of the number of non -inf
pixels in img
to the number of pixel in your map (which is 768
for nside=8
):
float(len(hpm)) / float(np.sum(img>=0)) * np.sum(img[img>0])
At xsize = 100, 1000, 10000
, the flux will be at 28.295, 30.075, 29.998
respectively.
Upvotes: 1