LSSTDESC/healsparse

Default sentinel for integer maps

Closed this issue · 4 comments

Looks like hsp isn't choosing a reasonable default sentinel value for integer maps.

>>> hpxmap = np.arange(hp.nside2npix(512))
>>> hspmap = hsp.HealSparseMap(healpix_map=hpxmap,nside_coverage=32)

ValueError                                Traceback (most recent call last)
<ipython-input-11-ef8690e65e90> in <module>
      1 hpxmap = np.arange(hp.nside2npix(512))
----> 2 hspmap = hsp.HealSparseMap(healpix_map=hpxmap,nside_coverage=32)

/usr/local/anaconda2/envs/carto/lib/python3.7/site-packages/healsparse/healSparseMap.py in __init__(self, cov_map, cov_index_map, sparse_map, nside_sparse, healpix_map, nside_coverage, primary, sentinel, nest, metadata, _is_view)
     99                 self._wide_mask_width = self._sparse_map.shape[1]
    100                 self._wide_mask_maxbits = WIDE_NBIT * self._wide_mask_width
--> 101             self._sentinel = check_sentinel(self._sparse_map.dtype.type, sentinel)
    102 
    103     @classmethod

/usr/local/anaconda2/envs/carto/lib/python3.7/site-packages/healsparse/utils.py in check_sentinel(type, sentinel)
     82             return sentinel
     83         else:
---> 84             raise ValueError("Sentinel not of integer type")
     85 
     86 

ValueError: Sentinel not of integer type

I admit this is not a very sparse-ified example, but I would expect it to work. Note that #36 also asks about sentinel values for integer maps.

So the real issue here is that HEALPix/healpy has no concept of an integer map, and the only valid sentinel value is healpy.UNSEEN. If you hand an integer map in there is no way to infer what the sentinel value should be, because it's undefined. The solution is to explicitly tell the constructor what sentinel value you want. What I think would help here, though, is a more informative error message in this case: if you input a healpix_map of non-float dtype, it will check that the sentinel is matched type (default always healpy.UNSEEN because that's what it must be), and Raise with a more informative error, like "You must explicitly set the sentinel value to an integer when inputting an integer healpix map".

I was thinking that HealSparse should define a default integer sentinel value (maybe using np.iinfo for the dtype).

It does. But only for a native HealSparseMap. If you're inputting a healpix_map then I don't want to assume anything more than it's a valid HEALPix map. (The default is -MAXINT for a regular integer map, and 0 for a mask map.)

I've implemented improved error messaging in this case with #69 . But as I explained above, I don't want to assume what that sentinel should be because it is not a defined quantity.