B
    z‹dÝ  ã            %   @   s²  d Z ddlZddlmZ ddlZe d¡Zddlm	Z	 dZ
yddlmZ ej
Z
W n   e d¡ Y nX d	Zd
dddddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.g%Zd/d0„ Zd1d2„ Zd3d4„ Zd5d-„ Zd6d.„ Zd7d8„ Zd9d:„ Ze
d;d<fd=d„Ze
d;d<fd>d„Ze
d;d<d?fd@d„ZdldBd„ZdmdCd
„ZdndDdE„ZdodFdG„ZdpdHd„ZdqdId„Z drdJd„Z!dsdKd„Z"dLd„ Z#dMd„ Z$edtdNd„ƒZ%dOd „ Z&dPd"„ Z'dudQd&„Z(dvdRd'„Z)dSd!„ Z*dTd#„ Z+dUd$„ Z,dVd%„ Z-dwdWd(„Z.dxdXdY„Z/dZd)„ Z0dyd[d„Z1dzd\d„Z2d{d]d„Z3d|d^d„Z4dAe
dfd_d„Z5e	d`ddaƒdAe
ddAd?d?fdbd„ƒZ6dAe
dfdcd„Z7e	d`ddaƒdAe
ddAd?d?fddd„ƒZ8ded*„ Z9dfd+„ Z:dgd,„ Z;ed}did„ƒZ<d~djdk„Z=dS )a  
=====================================================
pixelfunc.py : Healpix pixelization related functions
=====================================================

This module provides functions related to Healpix pixelization scheme.

conversion from/to sky coordinates
----------------------------------

- :func:`pix2ang` converts pixel number to angular coordinates
- :func:`pix2vec` converts pixel number to unit 3-vector direction
- :func:`ang2pix` converts angular coordinates to pixel number
- :func:`vec2pix` converts 3-vector to pixel number
- :func:`vec2ang` converts 3-vector to angular coordinates
- :func:`ang2vec` converts angular coordinates to unit 3-vector
- :func:`pix2xyf` converts pixel number to coordinates within face
- :func:`xyf2pix` converts coordinates within face to pixel number
- :func:`get_interp_weights` returns the 4 nearest pixels for given
  angular coordinates and the relative weights for interpolation
- :func:`get_all_neighbours` return the 8 nearest pixels for given
  angular coordinates

conversion between NESTED and RING schemes
------------------------------------------

- :func:`nest2ring` converts NESTED scheme pixel numbers to RING
  scheme pixel number
- :func:`ring2nest` converts RING scheme pixel number to NESTED
  scheme pixel number
- :func:`reorder` reorders a healpix map pixels from one scheme to another

nside/npix/resolution
---------------------

- :func:`nside2npix` converts healpix nside parameter to number of pixel
- :func:`npix2nside` converts number of pixel to healpix nside parameter
- :func:`nside2order` converts nside to order
- :func:`order2nside` converts order to nside
- :func:`nside2resol` converts nside to mean angular resolution
- :func:`nside2pixarea` converts nside to pixel area
- :func:`isnsideok` checks the validity of nside
- :func:`isnpixok` checks the validity of npix
- :func:`get_map_size` gives the number of pixel of a map
- :func:`get_min_valid_nside` gives the minimum nside possible for a given
  number of pixel
- :func:`get_nside` returns the nside of a map
- :func:`maptype` checks the type of a map (one map or sequence of maps)
- :func:`ud_grade` upgrades or degrades the resolution (nside) of a map

Masking pixels
--------------

- :const:`UNSEEN` is a constant value interpreted as a masked pixel
- :func:`mask_bad` returns a map with ``True`` where map is :const:`UNSEEN`
- :func:`mask_good` returns a map with ``False`` where map is :const:`UNSEEN`
- :func:`ma` returns a masked array as map, with mask given by :func:`mask_bad`

Map data manipulation
---------------------

- :func:`fit_dipole` fits a monopole+dipole on the map
- :func:`fit_monopole` fits a monopole on the map
- :func:`remove_dipole` fits and removes a monopole+dipole from the map
- :func:`remove_monopole` fits and remove a monopole from the map
- :func:`get_interp_val` computes a bilinear interpolation of the map
  at given angular coordinates, using 4 nearest neighbours
é    N)ÚwrapsZhealpy)Údeprecated_renamed_argumenté   )Ú_healpy_pixel_libz/Warning: cannot import _healpy_pixel_lib modulei    Úpix2angÚpix2vecÚang2pixÚvec2pixÚang2vecÚvec2angÚget_interp_weightsÚget_interp_valÚget_all_neighboursÚ
max_pixradÚ	nest2ringÚ	ring2nestÚreorderÚud_gradeÚUNSEENÚ	mask_goodÚmask_badÚmaÚ
fit_dipoleÚremove_dipoleÚfit_monopoleÚremove_monopoleÚ
nside2npixÚ
npix2nsideÚnside2orderÚorder2nsideÚ
order2npixÚ
npix2orderÚnside2resolÚnside2pixareaÚ	isnsideokÚisnpixokÚget_map_sizeÚget_min_valid_nsideÚ	get_nsideÚmaptypeÚma_to_arrayc             C   s4   t  | ¡} | dk ¡ r(| t jd k ¡ s0tdƒ‚dS )z0Raises exception if theta is not within 0 and pir   gñhãˆµøä>zTHETA is out of range [0,pi]N)ÚnpÚasarrayÚallÚpiÚ
ValueError)Útheta© r1   ú]/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/healpy/pixelfunc.pyÚcheck_theta_valid™   s    
r3   c             C   s   t jd t  |¡ t  | ¡fS )aQ  Transform longitude and latitude (deg) into co-latitude and longitude (rad)

    Parameters
    ----------
    lon : int or array-like
      Longitude in degrees
    lat : int or array-like
      Latitude in degrees

    Returns
    -------
    theta, phi : float, scalar or array-like
      The co-latitude and longitude in radians
    g       @)r+   r.   Úradians)ÚlonÚlatr1   r1   r2   Úlonlat2thetaphi    s    r7   c             C   s   t  |¡dt  | ¡ fS )aQ  Transform co-latitude and longitude (rad) into longitude and latitude (deg)

    Parameters
    ----------
    theta : int or array-like
      Co-latitude in radians
    phi : int or array-like
      Longitude in radians

    Returns
    -------
    lon, lat : float, scalar or array-like
      The longitude and latitude in degrees
    g     €V@)r+   Údegrees)r0   Úphir1   r1   r2   Úthetaphi2lonlat²   s    r:   c             C   sÀ   t | dƒstdƒ‚t| ƒdkr&tdƒ‚yt| d ƒ}W n tk
rN   d}Y nX |dk	r¤x(| dd… D ]}t|ƒ|krftdƒ‚qfW tt| d ƒƒršt| ƒS tdƒ‚ntt| ƒƒr´dS tdƒ‚dS )	a  Describe the type of the map (valid, single, sequence of maps).
    Checks : the number of maps, that all maps have same length and that this
    length is a valid map size (using :func:`isnpixok`).

    Parameters
    ----------
    m : sequence
      the map to get info from

    Returns
    -------
    info : int
      -1 if the given object is not a valid map, 0 if it is a single map,
      *info* > 0 if it is a sequence of maps (*info* is then the number of
      maps)

    Examples
    --------
    >>> import healpy as hp
    >>> hp.pixelfunc.maptype(np.arange(12))
    0
    >>> hp.pixelfunc.maptype([np.arange(12), np.arange(12)])
    2
    Ú__len__zinput map is a scalarr   zinput map has length zeroNr   zinput maps have different npixzbad number of pixels)ÚhasattrÚ	TypeErrorÚlenr%   )ÚmÚnpixÚmmr1   r1   r2   r)   Ä   s$    


c             C   sL   y|   ¡ S  tk
rF   yt dd„ | D ƒ¡S  tk
r@   Y nX Y nX | S )aƒ  Converts a masked array or a list of masked arrays to filled numpy arrays

    Parameters
    ----------
    m : a map (may be a sequence of maps)

    Returns
    -------
    m : filled map or tuple of filled maps

    Examples
    --------
    >>> import healpy as hp
    >>> m = hp.ma(np.array([2., 2., 3, 4, 5, 0, 0, 0, 0, 0, 0, 0]))
    >>> m.mask = np.array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=np.bool_)
    >>> print(m.data[1]) # data is not affected by mask
    2.0
    >>> print(m[1]) # shows that the value is masked
    --
    >>> print(ma_to_array(m)[1]) # filled array, masked values replace by UNSEEN
    -1.6375e+30
    c             S   s   g | ]}|  ¡ ‘qS r1   )Úfilled)Ú.0rA   r1   r1   r2   ú
<listcomp>  s    zma_to_array.<locals>.<listcomp>)rB   ÚAttributeErrorr+   Úarray)r?   r1   r1   r2   r*   ö   s    c             C   s   t | dƒpt | d dƒS )zïConverts a masked array or a list of masked arrays to filled numpy arrays

    Parameters
    ----------
    m : a map (may be a sequence of maps)

    Returns
    -------
    is_ma : bool
        whether the input map was a ma or not
    rB   r   )r<   )r?   r1   r1   r2   Úis_ma  s    rG   c                s   t ˆ ƒ‡ fdd„ƒ}|S )z¥Wraps a function in order to convert the input map from
    a masked to a regular numpy array, and convert back the
    output from a regular array to a masked arrayc                s0   t | ƒ}t| ƒ}ˆ |f|ž|Ž}|r,t|ƒS |S )N)rG   r*   r   )Úmap_inÚargsÚkwdsZ	return_mar?   Úout)Úfr1   r2   Úwrapper,  s    zaccept_ma.<locals>.wrapper)r   )rL   rM   r1   )rL   r2   Ú	accept_ma'  s    rN   gñhãˆµøä>g:Œ0âŽyE>c             C   s>   t  | ¡} t  |¡}t  |¡}t  | | ¡||t  |¡  kS )aS  Returns a bool array with ``True`` where m is close to badval.

    Parameters
    ----------
    m : a map (may be a sequence of maps)
    badval : float, optional
        The value of the pixel considered as bad (:const:`UNSEEN` by default)
    rtol : float, optional
        The relative tolerance
    atol : float, optional
        The absolute tolerance

    Returns
    -------
    mask
      a bool array with the same shape as the input map, ``True`` where input map is
      close to badval, and ``False`` elsewhere.

    See Also
    --------
    mask_good, ma

    Examples
    --------
    >>> import healpy as hp
    >>> import numpy as np
    >>> m = np.arange(12.)
    >>> m[3] = hp.UNSEEN
    >>> hp.mask_bad(m)
    array([False, False, False,  True, False, False, False, False, False,
           False, False, False], dtype=bool)
    )r+   r,   Úabsolute)r?   ÚbadvalÚrtolÚatolr1   r1   r2   r   6  s    !


c             C   s>   t  | ¡} t  |¡}t  |¡}t  | | ¡||t  |¡  kS )a,  Returns a bool array with ``False`` where m is close to badval.

    Parameters
    ----------
    m : a map (may be a sequence of maps)
    badval : float, optional
        The value of the pixel considered as bad (:const:`UNSEEN` by default)
    rtol : float, optional
        The relative tolerance
    atol : float, optional
        The absolute tolerance

    Returns
    -------
    a bool array with the same shape as the input map, ``False`` where input map is
    close to badval, and ``True`` elsewhere.

    See Also
    --------
    mask_bad, ma

    Examples
    --------
    >>> import healpy as hp
    >>> m = np.arange(12.)
    >>> m[3] = hp.UNSEEN
    >>> hp.mask_good(m)
    array([ True,  True,  True, False,  True,  True,  True,  True,  True,
            True,  True,  True], dtype=bool)
    )r+   r,   rO   )r?   rP   rQ   rR   r1   r1   r2   r   ]  s    


Tc             C   s   t jjt  | ¡||||dS )aå  Return map as a masked array, with ``badval`` pixels masked.

    Parameters
    ----------
    m : a map (may be a sequence of maps)
    badval : float, optional
        The value of the pixel considered as bad (:const:`UNSEEN` by default)
    rtol : float, optional
        The relative tolerance
    atol : float, optional
        The absolute tolerance
    copy : bool, optional
        If ``True``, a copy of the input map is made.

    Returns
    -------
    a masked array with the same shape as the input map,
    masked where input map is close to badval.

    See Also
    --------
    mask_good, mask_bad, numpy.ma.masked_values

    Examples
    --------
    >>> import healpy as hp
    >>> m = np.arange(12.)
    >>> m[3] = hp.UNSEEN
    >>> hp.ma(m)
    masked_array(data = [0.0 1.0 2.0 -- 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0],
                 mask = [False False False  True False False False False False False False False],
           fill_value = -1.6375e+30)
    <BLANKLINE>
    )rQ   rR   Úcopy)r+   r   Zmasked_valuesrF   )r?   rP   rQ   rR   rS   r1   r1   r2   r   ‚  s    #Fc             C   sV   t | |d |rt||ƒ\}}t|ƒ t | |d |rDt | ||¡S t | ||¡S dS )aS  ang2pix : nside,theta[rad],phi[rad],nest=False,lonlat=False -> ipix (default:RING)

    Parameters
    ----------
    nside : int, scalar or array-like
      The healpix nside parameter, must be a power of 2, less than 2**30
    theta, phi : float, scalars or array-like
      Angular coordinates of a point on the sphere
    nest : bool, optional
      if True, assume NESTED pixel ordering, otherwise, RING pixel ordering
    lonlat : bool
      If True, input angles are assumed to be longitude and latitude in degree,
      otherwise, they are co-latitude and longitude in radians.

    Returns
    -------
    pix : int or array of int
      The healpix pixel numbers. Scalar if all input are scalar, array otherwise.
      Usual numpy broadcasting rules apply.

    See Also
    --------
    pix2ang, pix2vec, vec2pix

    Examples
    --------
    Note that some of the test inputs below that are on pixel boundaries
    such as theta=pi/2, phi=pi/2, have a tiny value of 1e-15 added to them
    to make them reproducible on i386 machines using x87 floating point
    instruction set (see https://github.com/healpy/healpy/issues/528).

    >>> import healpy as hp
    >>> hp.ang2pix(16, np.pi/2, 0)
    1440

    >>> print(hp.ang2pix(16, [np.pi/2, np.pi/4, np.pi/2, 0, np.pi], [0., np.pi/4, np.pi/2 + 1e-15, 0, 0]))
    [1440  427 1520    0 3068]

    >>> print(hp.ang2pix(16, np.pi/2, [0, np.pi/2 + 1e-15]))
    [1440 1520]

    >>> print(hp.ang2pix([1, 2, 4, 8, 16], np.pi/2, 0))
    [   4   12   72  336 1440]

    >>> print(hp.ang2pix([1, 2, 4, 8, 16], 0, 0, lonlat=True))
    [   4   12   72  336 1440]
    )ÚnestN)Úcheck_nsider7   r3   ÚpixlibZ_ang2pix_nestZ_ang2pix_ring)Únsider0   r9   rT   Úlonlatr1   r1   r2   r   ¨  s    1c             C   sL   t | |d |r"t | |¡\}}nt | |¡\}}|r@t||ƒS ||fS dS )aÁ  pix2ang : nside,ipix,nest=False,lonlat=False -> theta[rad],phi[rad] (default RING)

    Parameters
    ----------
    nside : int or array-like
      The healpix nside parameter, must be a power of 2, less than 2**30
    ipix : int or array-like
      Pixel indices
    nest : bool, optional
      if True, assume NESTED pixel ordering, otherwise, RING pixel ordering
    lonlat : bool, optional
      If True, return angles will be longitude and latitude in degree,
      otherwise, angles will be co-latitude and longitude in radians (default)

    Returns
    -------
    theta, phi : float, scalar or array-like
      The angular coordinates corresponding to ipix. Scalar if all input
      are scalar, array otherwise. Usual numpy broadcasting rules apply.

    See Also
    --------
    ang2pix, vec2pix, pix2vec

    Examples
    --------
    >>> import healpy as hp
    >>> hp.pix2ang(16, 1440)
    (1.5291175943723188, 0.0)

    >>> hp.pix2ang(16, [1440,  427, 1520,    0, 3068])
    (array([ 1.52911759,  0.78550497,  1.57079633,  0.05103658,  3.09055608]), array([ 0.        ,  0.78539816,  1.61988371,  0.78539816,  0.78539816]))

    >>> hp.pix2ang([1, 2, 4, 8], 11)
    (array([ 2.30052398,  0.84106867,  0.41113786,  0.2044802 ]), array([ 5.49778714,  5.89048623,  5.89048623,  5.89048623]))

    >>> hp.pix2ang([1, 2, 4, 8], 11, lonlat=True)
    (array([ 315. ,  337.5,  337.5,  337.5]), array([-41.8103149 ,  41.8103149 ,  66.44353569,  78.28414761]))
    )rT   N)rU   rV   Z_pix2ang_nestZ_pix2ang_ringr:   )rW   ÚipixrT   rX   r0   r9   r1   r1   r2   r   å  s    (
c             C   s4   t | |d |r t | |||¡S t | |||¡S dS )aO  xyf2pix : nside,x,y,face,nest=False -> ipix (default:RING)

    Parameters
    ----------
    nside : int, scalar or array-like
      The healpix nside parameter, must be a power of 2
    x, y : int, scalars or array-like
      Pixel indices within face
    face : int, scalars or array-like
      Face number
    nest : bool, optional
      if True, assume NESTED pixel ordering, otherwise, RING pixel ordering

    Returns
    -------
    pix : int or array of int
      The healpix pixel numbers. Scalar if all input are scalar, array otherwise.
      Usual numpy broadcasting rules apply.

    See Also
    --------
    pix2xyf

    Examples
    --------
    >>> import healpy as hp
    >>> hp.xyf2pix(16, 8, 8, 4)
    1440

    >>> print(hp.xyf2pix(16, [8, 8, 8, 15, 0], [8, 8, 7, 15, 0], [4, 0, 5, 0, 8]))
    [1440  427 1520    0 3068]
    )rT   N)rU   rV   Z_xyf2pix_nestZ_xyf2pix_ring)rW   ÚxÚyZfacerT   r1   r1   r2   Úxyf2pix  s    !r\   c             C   s,   t | |d |rt | |¡S t | |¡S dS )ah  pix2xyf : nside,ipix,nest=False -> x,y,face (default RING)

    Parameters
    ----------
    nside : int or array-like
      The healpix nside parameter, must be a power of 2
    ipix : int or array-like
      Pixel indices
    nest : bool, optional
      if True, assume NESTED pixel ordering, otherwise, RING pixel ordering

    Returns
    -------
    x, y : int, scalars or array-like
      Pixel indices within face
    face : int, scalars or array-like
      Face number

    See Also
    --------
    xyf2pix

    Examples
    --------
    >>> import healpy as hp
    >>> hp.pix2xyf(16, 1440)
    (8, 8, 4)

    >>> hp.pix2xyf(16, [1440,  427, 1520,    0, 3068])
    (array([ 8,  8,  8, 15,  0]), array([ 8,  8,  7, 15,  0]), array([4, 0, 5, 0, 8]))

    >>> hp.pix2xyf([1, 2, 4, 8], 11)
    (array([0, 1, 3, 7]), array([0, 0, 2, 6]), array([11,  3,  3,  3]))
    )rT   N)rU   rV   Z_pix2xyf_nestZ_pix2xyf_ring)rW   rY   rT   r1   r1   r2   Úpix2xyfA  s    #r]   c             C   s(   |rt  | |||¡S t  | |||¡S dS )a€  vec2pix : nside,x,y,z,nest=False -> ipix (default:RING)

    Parameters
    ----------
    nside : int or array-like
      The healpix nside parameter, must be a power of 2, less than 2**30
    x,y,z : floats or array-like
      vector coordinates defining point on the sphere
    nest : bool, optional
      if True, assume NESTED pixel ordering, otherwise, RING pixel ordering

    Returns
    -------
    ipix : int, scalar or array-like
      The healpix pixel number corresponding to input vector. Scalar if all input
      are scalar, array otherwise. Usual numpy broadcasting rules apply.

    See Also
    --------
    ang2pix, pix2ang, pix2vec

    Examples
    --------
    >>> import healpy as hp
    >>> hp.vec2pix(16, 1, 0, 0)
    1504

    >>> print(hp.vec2pix(16, [1, 0], [0, 1], [0, 0]))
    [1504 1520]

    >>> print(hp.vec2pix([1, 2, 4, 8], 1, 0, 0))
    [  4  20  88 368]
    N)rV   Z_vec2pix_nestZ_vec2pix_ring)rW   rZ   r[   ÚzrT   r1   r1   r2   r	   k  s    "c             C   s,   t | |d |rt | |¡S t | |¡S dS )a2  pix2vec : nside,ipix,nest=False -> x,y,z (default RING)

    Parameters
    ----------
    nside : int, scalar or array-like
      The healpix nside parameter, must be a power of 2, less than 2**30
    ipix : int, scalar or array-like
      Healpix pixel number
    nest : bool, optional
      if True, assume NESTED pixel ordering, otherwise, RING pixel ordering

    Returns
    -------
    x, y, z : floats, scalar or array-like
      The coordinates of vector corresponding to input pixels. Scalar if all input
      are scalar, array otherwise. Usual numpy broadcasting rules apply.

    See Also
    --------
    ang2pix, pix2ang, vec2pix

    Examples
    --------
    >>> import healpy as hp
    >>> hp.pix2vec(16, 1504)
    (0.99879545620517241, 0.049067674327418015, 0.0)

    >>> hp.pix2vec(16, [1440,  427])
    (array([ 0.99913157,  0.5000534 ]), array([ 0.       ,  0.5000534]), array([ 0.04166667,  0.70703125]))

    >>> hp.pix2vec([1, 2], 11)
    (array([ 0.52704628,  0.68861915]), array([-0.52704628, -0.28523539]), array([-0.66666667,  0.66666667]))
    )rT   N)rU   rV   Z_pix2vec_nestZ_pix2vec_ring)rW   rY   rT   r1   r1   r2   r   “  s    "c             C   sP   |rt | |ƒ\} }t| ƒ t | ¡}t |t |¡ |t |¡ t | ¡g¡jS )aÆ  ang2vec : convert angles to 3D position vector

    Parameters
    ----------
    theta : float, scalar or arry-like
      colatitude in radians measured southward from north pole (in [0,pi]).
    phi : float, scalar or array-like
      longitude in radians measured eastward (in [0, 2*pi]).
    lonlat : bool
      If True, input angles are assumed to be longitude and latitude in degree,
      otherwise, they are co-latitude and longitude in radians.

    Returns
    -------
    vec : float, array
      if theta and phi are vectors, the result is a 2D array with a vector per row
      otherwise, it is a 1D array of shape (3,)

    See Also
    --------
    vec2ang, rotator.dir2vec, rotator.vec2dir
    )r7   r3   r+   ÚsinrF   ÚcosÚT)r0   r9   rX   Zsinthetar1   r1   r2   r
   ¼  s
    
c             C   s˜   |   dd¡} t tjt | ¡dd¡}t | dd…df | ¡}t | dd…df | dd…df ¡}||dk   dtj 7  < |rŒt||ƒS ||fS dS )a  vec2ang: vectors [x, y, z] -> theta[rad], phi[rad]

    Parameters
    ----------
    vectors : float, array-like
      the vector(s) to convert, shape is (3,) or (N, 3)
    lonlat : bool, optional
      If True, return angles will be longitude and latitude in degree,
      otherwise, angles will be co-latitude and longitude in radians (default)

    Returns
    -------
    theta, phi : float, tuple of two arrays
      the colatitude and longitude in radians

    See Also
    --------
    ang2vec, rotator.vec2dir, rotator.dir2vec
    éÿÿÿÿé   r   )ÚaxisNé   r   )	Úreshaper+   ÚsqrtÚsumZsquareZarccosZarctan2r.   r:   )ZvectorsrX   Zdnormr0   r9   r1   r1   r2   r   Ú  s    $
c             C   s   t | dd t | |¡S )a  Convert pixel number from RING ordering to NESTED ordering.

    Parameters
    ----------
    nside : int, scalar or array-like
      the healpix nside parameter
    ipix : int, scalar or array-like
      the pixel number in RING scheme

    Returns
    -------
    ipix : int, scalar or array-like
      the pixel number in NESTED scheme

    See Also
    --------
    nest2ring, reorder

    Examples
    --------
    >>> import healpy as hp
    >>> hp.ring2nest(16, 1504)
    1130

    >>> print(hp.ring2nest(2, np.arange(10)))
    [ 3  7 11 15  2  1  6  5 10  9]

    >>> print(hp.ring2nest([1, 2, 4, 8], 11))
    [ 11  13  61 253]
    T)rT   )rU   rV   Z
_ring2nest)rW   rY   r1   r1   r2   r   ù  s    c             C   s   t | dd t | |¡S )a  Convert pixel number from NESTED ordering to RING ordering.

    Parameters
    ----------
    nside : int, scalar or array-like
      the healpix nside parameter
    ipix : int, scalar or array-like
      the pixel number in NESTED scheme

    Returns
    -------
    ipix : int, scalar or array-like
      the pixel number in RING scheme

    See Also
    --------
    ring2nest, reorder

    Examples
    --------
    >>> import healpy as hp
    >>> hp.nest2ring(16, 1130)
    1504

    >>> print(hp.nest2ring(2, np.arange(10)))
    [13  5  4  0 15  7  6  1 17  9]

    >>> print(hp.nest2ring([1, 2, 4, 8], 11))
    [ 11   2  12 211]
    T)rT   )rU   rV   Z
_nest2ring)rW   rY   r1   r1   r2   r     s    c             C   sæ  t | ƒ}|dkrt| ƒ}nt| d ƒ}t|ƒ}|dkr@|d }n|}|rPd}d}|r\d}d}t|ƒ ¡ dd… }t|ƒ ¡ dd… }|dks”|dkrœtdƒ‚|dkr¬| g}	n| }	g }
x|	D ]}||krÖ|
 |¡ q¼|dkrNtj|t	|d ƒd	}xJt
|| ƒD ]:}t || |d
 | ¡}t||ƒ}t |¡| ||< qW |
 |¡ q¼|dkr¼tj|t	|d ƒd	}xJt
|| ƒD ]:}t || |d
 | ¡}t||ƒ}t |¡| ||< qzW |
 |¡ q¼W |dkrØ|
d S t |
¡S dS )aá  Reorder a healpix map from RING/NESTED ordering to NESTED/RING

    Parameters
    ----------
    map_in : array-like
      the input map to reorder, accepts masked arrays
    inp, out : ``'RING'`` or ``'NESTED'``
      define the input and output ordering
    r2n : bool
      if True, reorder from RING to NESTED
    n2r : bool
      if True, reorder from NESTED to RING

    Returns
    -------
    map_out : array-like
      the reordered map, as masked array if the input was a
      masked array

    Notes
    -----
    if ``r2n`` or ``n2r`` is defined, override ``inp`` and ``out``.

    See Also
    --------
    nest2ring, ring2nest

    Examples
    --------
    >>> import healpy as hp
    >>> hp.reorder(np.arange(48), r2n = True)
    array([13,  5,  4,  0, 15,  7,  6,  1, 17,  9,  8,  2, 19, 11, 10,  3, 28,
           20, 27, 12, 30, 22, 21, 14, 32, 24, 23, 16, 34, 26, 25, 18, 44, 37,
           36, 29, 45, 39, 38, 31, 46, 41, 40, 33, 47, 43, 42, 35])
    >>> hp.reorder(np.arange(12), n2r = True)
    array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])
    >>> hp.reorder(hp.ma(np.arange(12.)), n2r = True)
    masked_array(data = [  0.   1.   2.   3.   4.   5.   6.   7.   8.   9.  10.  11.],
                 mask = False,
           fill_value = -1.6375e+30)
    <BLANKLINE>
    >>> m = [np.arange(12.), np.arange(12.), np.arange(12.)]
    >>> m[0][2] = hp.UNSEEN
    >>> m[1][2] = hp.UNSEEN
    >>> m[2][2] = hp.UNSEEN
    >>> m = hp.ma(m)
    >>> hp.reorder(m, n2r = True)
    masked_array(data =
     [[0.0 1.0 -- 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0]
     [0.0 1.0 -- 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0]
     [0.0 1.0 -- 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0]],
                 mask =
     [[False False  True False False False False False False False False False]
     [False False  True False False False False False False False False False]
     [False False  True False False False False False False False False False]],
           fill_value = -1.6375e+30)
    <BLANKLINE>
    r   é€   é   ÚRINGÚNESTé   )rk   rl   z'inp and out must be either RING or NEST)Údtyper   N)r)   r>   r   ÚstrÚupperr/   Úappendr+   ÚzerosÚtypeÚrangeÚaranger   r,   r   rF   )rH   ZinprK   Úr2nÚn2rÚtypr@   rW   Ú	bunchsizeZmapinÚmapoutÚm_inZm_outÚibunchZipix_nZipix_rr1   r1   r2   r   ?  sT    <





c             C   s   d|  |  S )aË  Give the number of pixels for the given nside.

    Parameters
    ----------
    nside : int
      healpix nside parameter

    Returns
    -------
    npix : int
      corresponding number of pixels

    Examples
    --------
    >>> import healpy as hp
    >>> import numpy as np
    >>> hp.nside2npix(8)
    768

    >>> np.all([hp.nside2npix(nside) == 12 * nside**2 for nside in [2**n for n in range(12)]])
    True

    >>> hp.nside2npix(7)
    588
    é   r1   )rW   r1   r1   r2   r   «  s    c             C   s   t | dd td | ¡ƒd S )aí  Give the resolution order for a given nside.

    Parameters
    ----------
    nside : int
      healpix nside parameter; an exception is raised if nside is not valid
      (nside must be a power of 2, less than 2**30)

    Returns
    -------
    order : int
      corresponding order where nside = 2**(order)

    Notes
    -----
    Raise a ValueError exception if nside is not valid.

    Examples
    --------
    >>> import healpy as hp
    >>> import numpy as np
    >>> hp.nside2order(128)
    7

    >>> np.all([hp.nside2order(2**o) == o for o in range(30)])
    True

    >>> hp.nside2order(7)
    Traceback (most recent call last):
        ...
    ValueError: 7 is not a valid nside parameter (must be a power of 2, less than 2**30)
    T)rT   z{0:b}r   )rU   r>   Úformat)rW   r1   r1   r2   r   È  s    !c             C   s$   t  t| ƒ¡}|r t  |¡d }|S )a4  Give approximate resolution (pixel size in radian or arcmin) for nside.

    Resolution is just the square root of the pixel area, which is a gross
    approximation given the different pixel shapes

    Parameters
    ----------
    nside : int
      healpix nside parameter, must be a power of 2, less than 2**30
    arcmin : bool
      if True, return resolution in arcmin, otherwise in radian

    Returns
    -------
    resol : float
      approximate pixel size in radians or arcmin

    Notes
    -----
    Raise a ValueError exception if nside is not valid.

    Examples
    --------
    >>> import healpy as hp
    >>> hp.nside2resol(128, arcmin = True)  # doctest: +FLOAT_CMP
    27.483891294539248

    >>> hp.nside2resol(256)
    0.0039973699529159707

    >>> hp.nside2resol(7)
    0.1461895297066412
    é<   )r+   rg   r#   Úrad2deg)rW   ZarcminZresolr1   r1   r2   r"   í  s    #c             C   s*   dt j t| ƒ }|r&t  t  |¡¡}|S )aÍ  Give pixel area given nside in square radians or square degrees.

    Parameters
    ----------
    nside : int
      healpix nside parameter, must be a power of 2, less than 2**30
    degrees : bool
      if True, returns pixel area in square degrees, in square radians otherwise

    Returns
    -------
    pixarea : float
      pixel area in square radian or square degree

    Notes
    -----
    Raise a ValueError exception if nside is not valid.

    Examples
    --------
    >>> import healpy as hp
    >>> hp.nside2pixarea(128, degrees = True)  # doctest: +FLOAT_CMP
    0.2098234113027917

    >>> hp.nside2pixarea(256)
    1.5978966540475428e-05

    >>> hp.nside2pixarea(7)
    0.021371378595848933
    rm   )r+   r.   r   r€   )rW   r8   Zpixarear1   r1   r2   r#     s     c             C   s"   t | ƒstdƒ‚tt | d ¡ƒS )aµ  Give the nside parameter for the given number of pixels.

    Parameters
    ----------
    npix : int
      the number of pixels

    Returns
    -------
    nside : int
      the nside parameter corresponding to npix

    Notes
    -----
    Raise a ValueError exception if number of pixel does not correspond to
    the number of pixel of a healpix map.

    Examples
    --------
    >>> import healpy as hp
    >>> hp.npix2nside(768)
    8

    >>> np.all([hp.npix2nside(12 * nside**2) == nside for nside in [2**n for n in range(12)]])
    True

    >>> hp.npix2nside(1000)
    Traceback (most recent call last):
        ...
    ValueError: Wrong pixel number (it is not 12*nside**2)
    z*Wrong pixel number (it is not 12*nside**2)g      (@)r%   r/   Úintr+   rg   )r@   r1   r1   r2   r   @  s     c             C   s   d| > }t |dd |S )a  Give the nside parameter for the given resolution order.

    Parameters
    ----------
    order : int
      the resolution order

    Returns
    -------
    nside : int
      the nside parameter corresponding to order

    Notes
    -----
    Raise a ValueError exception if order produces an nside out of range.

    Examples
    --------
    >>> import healpy as hp
    >>> hp.order2nside(7)
    128

    >>> print(hp.order2nside(np.arange(8)))
    [  1   2   4   8  16  32  64 128]

    >>> hp.order2nside(31)
    Traceback (most recent call last):
        ...
    ValueError: 2147483648 is not a valid nside parameter (must be a power of 2, less than 2**30)
    r   T)rT   )rU   )ÚorderrW   r1   r1   r2   r   e  s    c             C   s   t | ƒ}t|ƒ}|S )aº  Give the number of pixels for the given resolution order.

    Parameters
    ----------
    order : int
      the resolution order

    Returns
    -------
    npix : int
      corresponding number of pixels

    Notes
    -----
    A convenience function that successively applies order2nside then nside2npix to order.

    Examples
    --------
    >>> import healpy as hp
    >>> hp.order2npix(7)
    196608

    >>> print(hp.order2npix(np.arange(8)))
    [    12     48    192    768   3072  12288  49152 196608]

    >>> hp.order2npix(31)
    Traceback (most recent call last):
        ...
    ValueError: 2147483648 is not a valid nside parameter (must be a power of 2, less than 2**30)
    )r   r   )r‚   rW   r@   r1   r1   r2   r    ‰  s    c             C   s   t | ƒ}t|ƒ}|S )a€  Give the resolution order for the given number of pixels.

    Parameters
    ----------
    npix : int
      the number of pixels

    Returns
    -------
    order : int
      corresponding resolution order

    Notes
    -----
    A convenience function that successively applies npix2nside then nside2order to npix.

    Examples
    --------
    >>> import healpy as hp
    >>> hp.npix2order(768)
    3

    >>> np.all([hp.npix2order(12 * 4**order) == order for order in range(12)])
    True

    >>> hp.npix2order(1000)
    Traceback (most recent call last):
        ...
    ValueError: Wrong pixel number (it is not 12*nside**2)
    )r   r   )r@   rW   r‚   r1   r1   r2   r!   ­  s    c             C   s¬   t | dƒrdt| tjƒs t | ¡} | |  t¡k| dk@ | tk@ }|r¨||  t¡|  t¡d @ dkM }nD| t| ƒko†d|   k o‚tkn  }|r¨|o¦t| ƒt| ƒd @ dk}|S )a·  Returns :const:`True` if nside is a valid nside parameter, :const:`False` otherwise.

    NSIDE needs to be a power of 2 only for nested ordering

    Parameters
    ----------
    nside : int, scalar or array-like
      integer value to be tested

    Returns
    -------
    ok : bool, scalar or array-like
      :const:`True` if given value is a valid nside, :const:`False` otherwise.

    Examples
    --------
    >>> import healpy as hp
    >>> hp.isnsideok(13, nest=True)
    False

    >>> hp.isnsideok(13, nest=False)
    True

    >>> hp.isnsideok(32)
    True

    >>> hp.isnsideok([1, 2, 3, 4, 8, 16], nest=True)
    array([ True,  True, False,  True,  True,  True], dtype=bool)
    r;   r   r   )r<   Ú
isinstancer+   Zndarrayr,   Úastyper   Ú	max_nside)rW   rT   Zis_nside_okr1   r1   r2   r$   Ñ  s    

"$c             C   s&   t  t| |d¡s"tdt| ƒ ƒ‚dS )z&Raises exception is nside is not valid)rT   zI%s is not a valid nside parameter (must be a power of 2, less than 2**30)N)r+   r-   r$   r/   ro   )rW   rT   r1   r1   r2   rU   ÿ  s    rU   c             C   s"   t  t  | ¡d ¡}|t  |¡kS )a*  Return :const:`True` if npix is a valid value for healpix map size, :const:`False` otherwise.

    Parameters
    ----------
    npix : int, scalar or array-like
      integer value to be tested

    Returns
    -------
    ok : bool, scalar or array-like
      :const:`True` if given value is a valid number of pixel, :const:`False` otherwise

    Examples
    --------
    >>> import healpy as hp
    >>> hp.isnpixok(12)
    True

    >>> hp.isnpixok(768)
    True

    >>> hp.isnpixok([12, 768, 1002])
    array([ True,  True, False], dtype=bool)
    g      (@)r+   rg   r,   Úfloor)r@   rW   r1   r1   r2   r%     s    c       
      C   s€   |   ¡ }t|jƒ}|r$t||ƒ\}}|r8t |||¡}nt |||¡}t |dd… ¡}t |dd… ¡}	~t 	|| |	 d¡S )a­  Return the bi-linear interpolation value of a map using 4 nearest neighbours.

    Parameters
    ----------
    m : array-like
      a healpix map, accepts masked arrays
    theta, phi : float, scalar or array-like
      angular coordinates of point at which to interpolate the map
    nest : bool
      if True, the is assumed to be in NESTED ordering.
    lonlat : bool
      If True, input angles are assumed to be longitude and latitude in degree,
      otherwise, they are co-latitude and longitude in radians.

    Returns
    -------
      val : float, scalar or arry-like
        the interpolated value(s), usual numpy broadcasting rules apply.

    See Also
    --------
    get_interp_weights, get_all_neighbours

    Examples
    --------
    >>> import healpy as hp
    >>> hp.get_interp_val(np.arange(12.), np.pi/2, 0)
    4.0
    >>> hp.get_interp_val(np.arange(12.), np.pi/2, np.pi/2)
    5.0
    >>> hp.get_interp_val(np.arange(12.), np.pi/2, np.pi/2 + 2*np.pi)
    5.0
    >>> hp.get_interp_val(np.arange(12.), np.linspace(0, np.pi, 10), 0)
    array([ 1.5       ,  1.5       ,  1.5       ,  2.20618428,  3.40206143,
            5.31546486,  7.94639458,  9.5       ,  9.5       ,  9.5       ])
    >>> hp.get_interp_val(np.arange(12.), 0, np.linspace(90, -90, 10), lonlat=True)
    array([ 1.5       ,  1.5       ,  1.5       ,  2.20618428,  3.40206143,
            5.31546486,  7.94639458,  9.5       ,  9.5       ,  9.5       ])
    r   rm   é   )
Zravelr   Úsizer7   rV   Ú_get_interpol_nestÚ_get_interpol_ringr+   rF   rh   )
r?   r0   r9   rT   rX   Úm2rW   ÚrÚpÚwr1   r1   r2   r   %  s    (
c             C   sˆ   t | |d |dkr(t| ||d\}}n|r:t||ƒ\}}|rNt | ||¡}nt | ||¡}t |dd… ¡}t |dd… ¡}||fS )a  Return the 4 closest pixels on the two rings above and below the
    location and corresponding weights.
    Weights are provided for bilinear interpolation along latitude and longitude

    Parameters
    ----------
    nside : int
      the healpix nside
    theta, phi : float, scalar or array-like
      if phi is not given, theta is interpreted as pixel number,
      otherwise theta[rad],phi[rad] are angular coordinates
    nest : bool
      if ``True``, NESTED ordering, otherwise RING ordering.
    lonlat : bool
      If True, input angles are assumed to be longitude and latitude in degree,
      otherwise, they are co-latitude and longitude in radians.

    Returns
    -------
    res : tuple of length 2
      contains pixel numbers in res[0] and weights in res[1].
      Usual numpy broadcasting rules apply.

    See Also
    --------
    get_interp_val, get_all_neighbours

    Examples
    --------
    Note that some of the test inputs below that are on pixel boundaries
    such as theta=pi/2, phi=pi/2, have a tiny value of 1e-15 added to them
    to make them reproducible on i386 machines using x87 floating point
    instruction set (see https://github.com/healpy/healpy/issues/528).

    >>> import healpy as hp
    >>> pix, weights = hp.get_interp_weights(1, 0)
    >>> print(pix)
    [0 1 4 5]
    >>> weights
    array([ 1.,  0.,  0.,  0.])

    >>> pix, weights = hp.get_interp_weights(1, 0, 0)
    >>> print(pix)
    [1 2 3 0]
    >>> weights
    array([ 0.25,  0.25,  0.25,  0.25])

    >>> pix, weights = hp.get_interp_weights(1, 0, 90, lonlat=True)
    >>> print(pix)
    [1 2 3 0]
    >>> weights
    array([ 0.25,  0.25,  0.25,  0.25])

    >>> pix, weights = hp.get_interp_weights(1, [0, np.pi/2 + 1e-15], 0)
    >>> print(pix)
    [[ 1  4]
     [ 2  5]
     [ 3 11]
     [ 0  8]]
    >>> np.testing.assert_allclose(
    ...     weights,
    ...     np.array([[ 0.25,  1.  ],
    ...               [ 0.25,  0.  ],
    ...               [ 0.25,  0.  ],
    ...               [ 0.25,  0.  ]]), rtol=0, atol=1e-14)
    )rT   Nr   rm   r‡   )rU   r   r7   rV   r‰   rŠ   r+   rF   )rW   r0   r9   rT   rX   rŒ   r   rŽ   r1   r1   r2   r   [  s    Cc             C   sZ   t | |d |dk	r&t| ||||d}|r8t | |¡}nt | |¡}t |dd… ¡}|S )aÜ  Return the 8 nearest pixels.

    Parameters
    ----------
    nside : int
      the nside to work with
    theta, phi : scalar or array-like
      if phi is not given or None, theta is interpreted as pixel number,
      otherwise, theta[rad],phi[rad] are angular coordinates
    nest : bool
      if ``True``, pixel number will be NESTED ordering, otherwise RING ordering.
    lonlat : bool
      If True, input angles are assumed to be longitude and latitude in degree,
      otherwise, they are co-latitude and longitude in radians.

    Returns
    -------
    ipix : int, array
      pixel number of the SW, W, NW, N, NE, E, SE and S neighbours,
      shape is (8,) if input is scalar, otherwise shape is (8, N) if input is
      of length N. If a neighbor does not exist (it can be the case for W, N, E and S)
      the corresponding pixel number will be -1.

    See Also
    --------
    get_interp_weights, get_interp_val

    Examples
    --------
    >>> import healpy as hp
    >>> print(hp.get_all_neighbours(1, 4))
    [11  7  3 -1  0  5  8 -1]

    >>> print(hp.get_all_neighbours(1, np.pi/2, np.pi/2))
    [ 8  4  0 -1  1  6  9 -1]

    >>> print(hp.get_all_neighbours(1, 90, 0, lonlat=True))
    [ 8  4  0 -1  1  6  9 -1]
    )rT   N)rT   rX   r   r‡   )rU   r   rV   Z_get_neighbors_nestZ_get_neighbors_ringr+   rF   )rW   r0   r9   rT   rX   rŒ   Úresr1   r1   r2   r   ¬  s    (c             C   s*   t | dd |r t t | ¡¡S t | ¡S )aÎ  Maximum angular distance between any pixel center and its corners

    Parameters
    ----------
    nside : int
      the nside to work with
    degrees : bool
      if True, returns pixel radius in degrees, in radians otherwise

    Returns
    -------
    rads: double
       angular distance (in radians or degrees)

    Examples
    --------
    >>> '%.14f' % max_pixrad(1)
    '0.84106867056793'
    >>> '%.14f' % max_pixrad(16)
    '0.06601476143251'
    F)rT   )rU   r+   r€   rV   Z_max_pixrad)rW   r8   r1   r1   r2   r   ß  s    c             C   sÐ  t | ƒ} t | ¡} | j}t|ƒ}|dkr2|d }n|}tjdtjd}tjdtjd}xþt|| ƒD ]ì}	t |	| |	d | ¡}
|
| j	|
 |kt 
| j	|
 ¡@  }
t||
|ƒ\}}}|dkrt |¡t |tj d ¡k}|
| }
|| }|| }|| }~|d	  |
j7  < |d
  | ¡ 7  < |d  | ¡ 7  < |d  | ¡ 7  < |d  |d  ¡ 7  < |d  ||  ¡ 7  < |d  ||  ¡ 7  < |d  |d  ¡ 7  < |d  ||  ¡ 7  < |d  |d  ¡ 7  < |d  | j	|
  ¡ 7  < |d  | j	|
 |  ¡ 7  < |d  | j	|
 |  ¡ 7  < |d  | j	|
 |  ¡ 7  < qfW |d
 |d< |d |d< |d |d< |d |d< |d |d< |d |d< t tj |¡|¡}|d }|dd… }||fS )a¨  Fit a dipole and a monopole to the map, excluding bad pixels.

    Parameters
    ----------
    m : float, array-like
      the map to which a dipole is fitted and subtracted, accepts masked maps
    nest : bool
      if ``False`` m is assumed in RING scheme, otherwise map is NESTED
    bad : float
      bad values of pixel, default to :const:`UNSEEN`.
    gal_cut : float [degrees]
      pixels at latitude in [-gal_cut;+gal_cut] degrees are not taken into account

    Returns
    -------
    res : tuple of length 2
      the monopole value in res[0] and the dipole vector (as array) in res[1]

    See Also
    --------
    remove_dipole, fit_monopole, remove_monopole
    ri   rj   )rm   rm   )rn   rm   r   r   é´   )r   r   )r   r   )re   r   )rc   r   )r   r   re   )re   r   )rc   r   )re   re   )rc   re   )rc   rc   rc   )r   r   )r   re   )r   rc   )r   re   )r   rc   )re   rc   )r*   r+   r,   rˆ   r   rr   Zfloat64rt   ru   ÚflatÚisfiniter   Úabsr_   r.   rh   ÚdotZlinalgÚinv)r?   rT   ÚbadÚgal_cutr@   rW   ry   ÚaaÚvr|   rY   rZ   r[   r^   rŽ   r   ÚmonoÚdipoler1   r1   r2   r   ý  sX    

"
"Úverbosez1.15.0c             C   s€  t | ƒ}t| ƒ} tj| |d} | j}t|ƒ}	|	dkr>|d }
n|}
t| |||d\}}xÀt||
 ƒD ]°}t ||
 |d |
 ¡}|| j	| |kt 
| j	| ¡@  }t|	||ƒ\}}}| j	|  |d | 8  < | j	|  |d | 8  < | j	|  |d | 8  < | j	|  |8  < qdW ddlm} |j|d	d
\}}t ||  ¡ ¡}t d||||¡ t rht| ƒ} |rx| ||fS | S dS )aû  Fit and subtract the dipole and the monopole from the given map m.

    Parameters
    ----------
    m : float, array-like
      the map to which a dipole is fitted and subtracted, accepts masked arrays
    nest : bool
      if ``False`` m is assumed in RING scheme, otherwise map is NESTED
    bad : float
      bad values of pixel, default to :const:`UNSEEN`.
    gal_cut : float [degrees]
      pixels at latitude in [-gal_cut;+gal_cut] are not taken into account
    fitval : bool
      whether to return or not the fitted values of monopole and dipole
    copy : bool
      whether to modify input map or not (by default, make a copy)
    verbose : bool
      deprecated, no effect

    Returns
    -------
    res : array or tuple of length 3
      if fitval is False, returns map with monopole and dipole subtracted,
      otherwise, returns map (array, in res[0]), monopole (float, in res[1]),
      dipole_vector (array, in res[2])

    See Also
    --------
    fit_dipole, fit_monopole, remove_monopole
    )rS   ri   rj   )rT   r–   r—   r   r   re   )ÚrotatorT)rX   z9monopole: %.2g  dipole: lon: %.2g}, lat: %.2g}, amp: %.2gN)rG   r*   r+   rF   rˆ   r   r   rt   ru   r‘   r’   r   Ú r   Zvec2dirrg   rh   ÚlogÚinfor   )r?   rT   r–   r—   ÚfitvalrS   rœ   Úinput_mar@   rW   ry   rš   r›   r|   rY   rZ   r[   r^   ÚRr5   r6   Úampr1   r1   r2   r   C  s6    "
"
c             C   s  t | ƒ} t | ¡} | j}t|ƒ}|dkr2|d }n|}d }}xÄt|| ƒD ]´}	t |	| |	d | ¡}
|
| j|
 |kt | j|
 ¡@  }
t	||
|ƒ\}}}|dkrät 
|¡t |tj d ¡k}|
| }
|| }|| }|| }~||
j7 }|| j|
  ¡ 7 }qLW || }|S )aa  Fit a monopole to the map, excluding unseen pixels.

    Parameters
    ----------
    m : float, array-like
      the map to which a dipole is fitted and subtracted, accepts masked arrays
    nest : bool
      if ``False`` m is assumed in RING scheme, otherwise map is NESTED
    bad : float
      bad values of pixel, default to :const:`UNSEEN`.
    gal_cut : float [degrees]
      pixels at latitude in [-gal_cut;+gal_cut] degrees are not taken into account

    Returns
    -------
    res: float
      fitted monopole value

    See Also
    --------
    fit_dipole, remove_monopole, remove_monopole
    ri   rj   g        r   r   r   )r*   r+   r,   rˆ   r   rt   ru   r‘   r’   r   r“   r_   r.   rh   )r?   rT   r–   r—   r@   rW   ry   r˜   r™   r|   rY   rZ   r[   r^   rŽ   rš   r1   r1   r2   r   ˆ  s.    

"
c             C   sò   t | ƒ}t| ƒ} tj| |d} | j}t|ƒ}	|	dkr>|d }
n|}
t| |||d}xrt||
 ƒD ]b}t ||
 |d |
 ¡}|| j	| |kt 
| j	| ¡@  }t|	||ƒ\}}}| j	|  |8  < q`W t d|¡ |rÞt| ƒ} |rê| |fS | S dS )a˜  Fit and subtract the monopole from the given map m.

    Parameters
    ----------
    m : float, array-like
      the map to which a monopole is fitted and subtracted
    nest : bool
      if ``False`` m is assumed in RING scheme, otherwise map is NESTED
    bad : float
      bad values of pixel, default to :const:`UNSEEN`.
    gal_cut : float [degrees]
      pixels at latitude in [-gal_cut;+gal_cut] are not taken into account
    fitval : bool
      whether to return or not the fitted value of monopole
    copy : bool
      whether to modify input map or not (by default, make a copy)
    verbose: bool
      deprecated, no effect

    Returns
    -------
    res : array or tuple of length 3
      if fitval is False, returns map with monopole subtracted,
      otherwise, returns map (array, in res[0]) and monopole (float, in res[1])

    See Also
    --------
    fit_dipole, fit_monopole, remove_dipole
    )rS   ri   rj   )rT   r–   r—   r   zmonopole: %.3gN)rG   r*   r+   rF   rˆ   r   r   rt   ru   r‘   r’   r   rŸ   r    r   )r?   rT   r–   r—   r¡   rS   rœ   r¢   r@   rW   ry   rš   r|   rY   rZ   r[   r^   r1   r1   r2   r   ¹  s(    !
"c             C   sp   t | tƒrPd| krt| d ƒS ttdƒr2t| jƒS tt|  ¡ ƒd ƒ}t|ƒS nt	t
| ƒƒrdt
| ƒS tdƒ‚dS )aÎ  Returns the npix of a given map (implicit or explicit pixelization).

     If map is a dict type, assumes explicit pixelization: use nside key if present, or use
     nside attribute if present, otherwise use the smallest valid npix given the maximum key value.
     otherwise assumes implicit pixelization and returns len(m).

     Parameters
     ----------
     m : array-like or dict-like
       a map with implicit (array-like) or explicit (dict-like) pixellization

     Returns
     -------
     npix : int
       a valid number of pixel

     Notes
     -----
     In implicit pixellization, raise a ValueError exception if the size of the input
     is not a valid pixel number.

     Examples
     --------
    >>> import healpy as hp
     >>> m = {0: 1, 1: 1, 2: 1, 'nside': 1}
     >>> print(hp.get_map_size(m))
     12

     >>> m = {0: 1, 767: 1}
     >>> print(hp.get_map_size(m))
     768

     >>> print(hp.get_map_size(np.zeros(12 * 8 ** 2)))
     768
    rW   r   z*Wrong pixel number (it is not 12*nside**2)N)rƒ   Údictr   r<   r   rW   r'   ÚmaxÚkeysr%   r>   r/   )r?   rW   r1   r1   r2   r&   ò  s    $



c             C   s$   dt  | d ¡ }dtt  |¡ƒ> S )až  Returns the minimum acceptable nside so that npix <= nside2npix(nside).

    Parameters
    ----------
    npix : int
      a minimal number of pixel

    Returns
    -------
    nside : int
      a valid healpix nside so that 12 * nside ** 2 >= npix

    Examples
    --------
    >>> import healpy as hp
    >>> hp.pixelfunc.get_min_valid_nside(355)
    8
    >>> hp.pixelfunc.get_min_valid_nside(768)
    8
    g      à?g      (@r   )r+   Úlog2r   Úceil)r@   r‚   r1   r1   r2   r'   %  s    c             C   s0   t | ƒ}|dkrtt| ƒƒS tt| d ƒƒS dS )a»  Return the nside of the given map.

    Parameters
    ----------
    m : sequence
      the map to get the nside from.

    Returns
    -------
    nside : int
      the healpix nside parameter of the map (or sequence of maps)

    Notes
    -----
    If the input is a sequence of maps, all of them must have same size.
    If the input is not a valid map (not a sequence, unvalid number of pixels),
    a TypeError exception is raised.
    r   N)r)   r   r>   )r?   rx   r1   r1   r2   r(   >  s    rk   c             C   sÜ   t ||dkd t| ƒ}|dk r(tdƒ‚|dkr8| g}n| }g }	|dkrL|}xp|D ]h}
t|ƒ ¡ dd… dkrzt|
dd}
t|
||||d	}t|ƒ ¡ dd… dkr°t|dd
}|	 |¡ qRW |dkrÎ|	d S t 	|	¡S dS )a  Upgrade or degrade resolution of a map (or list of maps).

    in degrading the resolution, ud_grade sets the value of the superpixel
    as the mean of the children pixels.

    Parameters
    ----------
    map_in : array-like or sequence of array-like
      the input map(s) (if a sequence of maps, all must have same size)
    nside_out : int
      the desired nside of the output map(s)
    pess : bool
      if ``True``, in degrading, reject pixels which contains
      a bad sub_pixel. Otherwise, estimate average with good pixels
    order_in, order_out : str
      pixel ordering of input and output ('RING' or 'NESTED')
    power : float
      if non-zero, divide the result by (nside_in/nside_out)**power
      Examples:
      power=-2 keeps the sum of the map invariant (useful for hitmaps),
      power=2 divides the mean by another factor of (nside_in/nside_out)**2
      (useful for variance maps)
    dtype : type
      the type of the output map

    Returns
    -------
    map_out : array-like or sequence of array-like
      the upgraded or degraded map(s)

    Examples
    --------
    >>> import healpy as hp
    >>> hp.ud_grade(np.arange(48.), 1)
    array([  5.5 ,   7.25,   9.  ,  10.75,  21.75,  21.75,  23.75,  25.75,
            36.5 ,  38.25,  40.  ,  41.75])
    rk   )rT   r   zInvalid mapNrm   T)rv   )ÚpessÚpowerrn   )rw   )
rU   r)   r=   ro   rp   r   Ú_ud_grade_corerq   r+   rF   )rH   Ú	nside_outrª   Zorder_inZ	order_outr«   rn   rx   r{   rz   r?   Zmoutr1   r1   r2   r   X  s(    /
c             C   st  t | ƒ}|r|}nt| d ƒ}t|dd t|ƒ}t|ƒ}|r\t|ƒ}t|ƒt|ƒ | }	nd}	||kr–|| }
tj|
|d|	 }t | |¡ |¡}nÔ||k rf|| }
|  ||
¡}t	|ƒt 
|¡ B  }tj|| dd |¡}|jdd}|rt ||
k¡}nt |dk¡}|r ||	 }||dk ||dk  ||dk< yt||< W n tk
rb   Y nX n| }| |¡S )zmInternal routine used by ud_grade. It assumes that the map is NESTED
    and single (not a list of maps)
    r   T)rT   r   )rn   )rd   )r(   rs   rU   r   Úfloatr+   ZonesÚouterrf   r   r’   rh   r„   Úwherer   ÚOverflowError)r?   r­   rª   r«   rn   Znside_inZtype_outZnpix_inZnpix_outÚratioZrat2ZfactZmap_outÚmrZgoodsZnhitZbadoutr1   r1   r2   r¬   Ÿ  sB    
 r¬   )FF)FF)F)F)F)F)F)F)NNNN)F)F)F)F)FF)NFF)NFF)F)Frk   NNN)FNN)>Ú__doc__Únumpyr+   Ú	functoolsr   ÚloggingÚ	getLoggerrŸ   Zastropy.utils.decoratorsr   r   rž   r   rV   Úwarningr…   Ú__all__r3   r7   r:   r)   r*   rG   rN   r   r   r   r   r   r\   r]   r	   r   r
   r   r   r   r   r   r   r"   r#   r   r   r    r!   r$   rU   r%   r   r   r   r   r   r   r   r   r&   r'   r(   r   r¬   r1   r1   r1   r2   Ú<module>W   sÌ   

2"'%&
=
4
(
*
(
)

##k%
+
(%$$$
.
	
6
Q
3
F
C1
73    ?