U
    e»{jêk  ã                   @   sÜ   d Z ddlZddlZddlmZ ddlZdddddgZd	Ze 	ej
¡Zeejded
d�ƒZdd„ Zdd„ ZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ ded�Zefdd„Zddd„Zdddejdfdd„ZdS )z\
A module that provides functions for manipulating bit masks and data quality
(DQ) arrays.

é    N)ÚOrderedDictÚbitfield_to_boolean_maskÚinterpret_bit_flagsÚBitFlagNameMapÚextend_bit_flag_mapÚInvalidBitFlagTÚunsafe©ÚdtypeÚcastingc                 C   s   | dk rdS t | ƒ d¡dkS )al  
    Verifies if the input number is a bit flag (i.e., an integer number that is
    an integer power of 2).

    Parameters
    ----------
    n : int
        A positive integer number. Non-positive integers are considered not to
        be "flags".

    Returns
    -------
    bool
        ``True`` if input ``n`` is a bit flag and ``False`` if it is not.

    é   FÚ1)ÚbinÚcount©Ún© r   úU/var/www/html/bwave/python/venv/lib/python3.8/site-packages/astropy/nddata/bitmask.pyÚ_is_bit_flag   s    r   c                 C   s2   t | tjƒrt | tƒ p0t | tjƒo0t | tj¡S ©N)Ú
isinstanceÚnumbersÚIntegralÚboolÚnpZgenericÚ
issubdtypeÚintegerr   r   r   r   Ú_is_int1   s    ÿr   c                   @   s   e Zd ZdZdS )r   z>Indicates that a value is not an integer that is a power of 2.N©Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   7   s   c                   @   s   e Zd ZdZddd„ZdS )ÚBitFlagz/Bit flags: integer values that are powers of 2.Nc                 C   s^   t |tƒr"|d k	rtdƒ‚|\}}t|ƒr2t|ƒs@td |¡ƒ‚t | |¡}|d k	rZ||_	|S )Nz+Flag's doc string cannot be provided twice.zTValue '{}' is not a valid bit flag: bit flag value must be an integral power of two.)
r   ÚtupleÚ
ValueErrorr   r   r   ÚformatÚintÚ__new__r"   )ÚclsÚvalÚdocÚsr   r   r   r(   @   s    
ÿÿzBitFlag.__new__)N)r   r    r!   r"   r(   r   r   r   r   r#   =   s   r#   c                       s`   e Zd Z‡ fdd„Z‡ fdd„Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dd„ Z
dd„ Z‡  ZS )ÚBitFlagNameMetac                    s  |  ¡ D ]\}}| d¡st|ƒ}qdd„ | ¡ D ƒ}tttj|ƒƒ}trPt	ƒ }|D ]`}	|	j
  ¡ D ]P\}}| d¡rvqb| ¡ }
|
|kr¦| |
¡}td|| d›d�ƒ‚trb|||
< qbqTdd„ |  ¡ D ƒ}trú| d	d„ |  ¡ D ƒ¡ d
ddœ|d|i–}nd
ddœ|–}tƒ  | |||¡S )NÚ_c                 S   s   g | ]}|  d ¡s|‘qS ©r.   )Ú
startswith©Ú.0Úkr   r   r   Ú
<listcomp>X   s     
 z+BitFlagNameMeta.__new__.<locals>.<listcomp>z
Bit flag 'r,   z' was already defined.c                 S   s(   i | ] \}}||  d ¡r|nt|ƒ“qS r/   )r0   r#   ©r2   r3   Úvr   r   r   Ú
<dictcomp>k   s     z+BitFlagNameMeta.__new__.<locals>.<dictcomp>c                 S   s$   i | ]\}}|  d ¡s| ¡ |“qS r/   )r0   Úlowerr5   r   r   r   r7   q   s     
  TÚ )Ú_lockedÚ__version__Ú_cache)Úitemsr0   r#   ÚkeysÚlistÚmapÚstrr8   Ú_ENABLE_BITFLAG_CACHINGr   Ú__dict__ÚindexÚAttributeErrorÚupdateÚsuperr(   )ÚmclsÚnameÚbasesÚmembersr3   r6   ÚattrZattrlÚcacheÚbÚklÚidx©Ú	__class__r   r   r(   S   s:    



ÿÿÿzBitFlagNameMeta.__new__c                    sü   |dkrt ƒ  |d¡S |dkr:| jr,tdƒ‚t ƒ  ||¡S d|› �}| jrRt|ƒ‚| ¡ }tr|| d¡sÎ|| jkrÎt|ƒ‚nR| jD ],}| d¡s‚|t	t
tj|jƒƒkr‚t|ƒ‚q‚|t	t
tj| jƒƒkrÎt|ƒ‚t|ƒ}trî| d¡sî|| j|< t ƒ  ||¡S )Nr:   Tr;   zVersion cannot be modified.z6Bit flags are read-only. Unable to reassign attribute r.   )rG   Ú__setattr__r:   rE   r8   rB   r0   r<   Ú	__bases__r?   r@   rA   rC   r#   )r)   rI   r*   Úerr_msgZnamelrN   rQ   r   r   rS   y   s0    


ÿ

zBitFlagNameMeta.__setattr__c                 C   sn   t r| j}n*dd„ | j ¡ D ƒ}| dd„ | jD ƒ¡ z|| ¡  W S  tk
rh   td|› d�ƒ‚Y nX d S )Nc                 S   s   i | ]\}}|  ¡ |“qS r   )r8   r5   r   r   r   r7       s      z/BitFlagNameMeta.__getattr__.<locals>.<dictcomp>c                 S   s*   i | ]"}|j  ¡ D ]\}}| ¡ |“qqS r   )rC   r=   r8   )r2   rN   r3   r6   r   r   r   r7   ¢   s
        zFlag 'z' not defined)	rB   r<   rC   r=   rF   rT   r8   ÚKeyErrorrE   )r)   rI   Z	flagnamesr   r   r   Ú__getattr__œ   s    ÿzBitFlagNameMeta.__getattr__c                 C   s
   |   |¡S r   )rW   )r)   Úkeyr   r   r   Ú__getitem__©   s    zBitFlagNameMeta.__getitem__c                 C   sR   t |tƒs*t |d ttfƒs"|g}t|ƒ}t| jd d dd„ |D ƒ¡ | f|ŽS )Nr   r.   c                 S   s   g | ]}|‘qS r   r   r1   r   r   r   r4   ³   s     z+BitFlagNameMeta.__add__.<locals>.<listcomp>)r   Údictr$   r?   r   r   Újoin)r)   r=   r   r   r   Ú__add__¬   s    
 ÿÿzBitFlagNameMeta.__add__c                 C   s   t dƒ‚d S )Nz8Unary '+' is not supported. Use binary operator instead.)ÚNotImplementedError)r)   Úotherr   r   r   Ú__iadd__¶   s    ÿzBitFlagNameMeta.__iadd__c                 C   s    t d | j|  ¡ d j¡ƒ‚d S ©Nz {:s}: cannot delete {:s} member.éþÿÿÿ©rE   r&   r   Úmro©r)   rI   r   r   r   Ú__delattr__»   s     ÿÿzBitFlagNameMeta.__delattr__c                 C   s    t d | j|  ¡ d j¡ƒ‚d S r`   rb   rd   r   r   r   Ú__delitem__Â   s     ÿÿzBitFlagNameMeta.__delitem__c                 C   s"   d|   ¡ d jd›d| jd›d�S )Nú<ra   r,   z 'z'>)rc   r   )r)   r   r   r   Ú__repr__É   s    zBitFlagNameMeta.__repr__)r   r    r!   r(   rS   rW   rY   r\   r_   re   rf   rh   Ú__classcell__r   r   rQ   r   r-   R   s   &#
r-   c                   @   s   e Zd ZdZdS )r   a<  
    A base class for bit flag name maps used to describe data quality (DQ)
    flags of images by provinding a mapping from a mnemonic flag name to a flag
    value.

    Mapping for a specific instrument should subclass this class.
    Subclasses should define flags as class attributes with integer values
    that are powers of 2. Each bit flag may also contain a string
    comment following the flag value.

    Examples
    --------

        >>> from astropy.nddata.bitmask import BitFlagNameMap
        >>> class ST_DQ(BitFlagNameMap):
        ...     __version__ = '1.0.0'  # optional
        ...     CR = 1, 'Cosmic Ray'
        ...     CLOUDY = 4  # no docstring comment
        ...     RAINY = 8, 'Dome closed'
        ...
        >>> class ST_CAM1_DQ(ST_DQ):
        ...     HOT = 16
        ...     DEAD = 32

    Nr   r   r   r   r   r   Í   s   )Ú	metaclassc                 K   sz   t  t | |fddi¡}| ¡ D ]P\}}zt|||ƒ W q tk
rl } z|| t|ƒkr\|‚W 5 d}~X Y qX qd|_|S )aõ  
    A convenience function for creating bit flags maps by subclassing an
    existing map and adding additional flags supplied as keyword arguments.

    Parameters
    ----------
    cls_name : str
        Class name of the bit flag map to be created.

    base_cls : BitFlagNameMap, optional
        Base class for the new bit flag map.

    **kwargs : int
        Each supplied keyword argument will be used to define bit flag
        names in the new map. In addition to bit flag names, ``__version__`` is
        allowed to indicate the version of the newly created map.

    Examples
    --------

        >>> from astropy.nddata.bitmask import extend_bit_flag_map
        >>> ST_DQ = extend_bit_flag_map('ST_DQ', __version__='1.0.0', CR=1, CLOUDY=4, RAINY=8)
        >>> ST_CAM1_DQ = extend_bit_flag_map('ST_CAM1_DQ', ST_DQ, HOT=16, DEAD=32)
        >>> ST_CAM1_DQ['HOT']  # <-- Access flags as dictionary keys
        16
        >>> ST_CAM1_DQ.HOT  # <-- Access flags as class attributes
        16

    r:   FNT)r-   r(   r=   ÚsetattrrE   r'   r:   )Úcls_nameZbase_clsÚkwargsZnew_clsr3   r6   Úer   r   r   r   ë   s       ÿc                    sà  |dk	}t |ƒ}d}tˆ ƒr2|r*tˆ ƒ S tˆ ƒS ˆ dkrJ|rFtdƒ‚dS tˆ tƒ�r|rbtdƒ‚tˆ ƒ ¡ ‰ ˆ  ¡ dkr~dS ˆ  d¡}|dkr¦d}ˆ d	d…  	¡ ‰ n|dkr¶t
d
ƒ‚d}ˆ  d¡}ˆ  d¡}|dkrâ|dkrâ�q<||kròt
dƒ‚ˆ  d¡}ˆ  d¡}	|dk�s"|	tˆ ƒd	 k �r*t
dƒ‚ˆ d	d…  ¡ ‰ qºt‡ fdd„dD ƒƒd	k�r`t
dƒ‚dˆ k�rvˆ  d¡‰ nDdˆ k�rŒˆ  d¡‰ n.dˆ k�r¢ˆ  d¡‰ nˆ dk�r´t
dƒ‚ˆ g‰ ˆdk	�rþztˆ d ƒ W n( t
k
�rü   ‡fdd„ˆ D ƒ‰ Y nX tˆ ƒd	k}ndtˆ dƒ�rhtdd„ ˆ D ƒƒ�spˆdk	�r^tdd„ ˆ D ƒƒ�r^‡fdd„ˆ D ƒ‰ ntdƒ‚ntd ƒ‚tttˆ ƒƒ}
t|
ƒtˆ ƒk�ršt d!¡ d}|
D ],}t|ƒ�sÄ|�sÄt
d" |¡ƒ‚||7 }�q¢|�rÜ| }|S )#a  
    Converts input bit flags to a single integer value (bit mask) or `None`.

    When input is a list of flags (either a Python list of integer flags or a
    string of comma-, ``'|'``-, or ``'+'``-separated list of flags),
    the returned bit mask is obtained by summing input flags.

    .. note::
        In order to flip the bits of the returned bit mask,
        for input of `str` type, prepend '~' to the input string. '~' must
        be prepended to the *entire string* and not to each bit flag! For
        input that is already a bit mask or a Python list of bit flags, set
        ``flip_bits`` for `True` in order to flip the bits of the returned
        bit mask.

    Parameters
    ----------
    bit_flags : int, str, list, None
        An integer bit mask or flag, `None`, a string of comma-, ``'|'``- or
        ``'+'``-separated list of integer bit flags or mnemonic flag names,
        or a Python list of integer bit flags. If ``bit_flags`` is a `str`
        and if it is prepended with '~', then the output bit mask will have
        its bits flipped (compared to simple sum of input flags).
        For input ``bit_flags`` that is already a bit mask or a Python list
        of bit flags, bit-flipping can be controlled through ``flip_bits``
        parameter.

        .. note::
            When ``bit_flags`` is a list of flag names, the ``flag_name_map``
            parameter must be provided.

        .. note::
            Only one flag separator is supported at a time. ``bit_flags``
            string should not mix ``','``, ``'+'``, and ``'|'`` separators.

    flip_bits : bool, None
        Indicates whether or not to flip the bits of the returned bit mask
        obtained from input bit flags. This parameter must be set to `None`
        when input ``bit_flags`` is either `None` or a Python list of flags.

    flag_name_map : BitFlagNameMap
         A `BitFlagNameMap` object that provides mapping from mnemonic
         bit flag names to integer bit values in order to translate mnemonic
         flags to numeric values when ``bit_flags`` that are comma- or
         '+'-separated list of menmonic bit flag names.

    Returns
    -------
    bitmask : int or None
        Returns an integer bit mask formed from the input bit value or `None`
        if input ``bit_flags`` parameter is `None` or an empty string.
        If input string value was prepended with '~' (or ``flip_bits`` was set
        to `True`), then returned value will have its bits flipped
        (inverse mask).

    Examples
    --------

        >>> from astropy.nddata.bitmask import interpret_bit_flags, extend_bit_flag_map
        >>> ST_DQ = extend_bit_flag_map('ST_DQ', CR=1, CLOUDY=4, RAINY=8, HOT=16, DEAD=32)
        >>> "{0:016b}".format(0xFFFF & interpret_bit_flags(28))
        '0000000000011100'
        >>> "{0:016b}".format(0xFFFF & interpret_bit_flags('4,8,16'))
        '0000000000011100'
        >>> "{0:016b}".format(0xFFFF & interpret_bit_flags('CLOUDY,RAINY,HOT', flag_name_map=ST_DQ))
        '0000000000011100'
        >>> "{0:016b}".format(0xFFFF & interpret_bit_flags('~4,8,16'))
        '1111111111100011'
        >>> "{0:016b}".format(0xFFFF & interpret_bit_flags('~(4+8+16)'))
        '1111111111100011'
        >>> "{0:016b}".format(0xFFFF & interpret_bit_flags('~(CLOUDY+RAINY+HOT)',
        ... flag_name_map=ST_DQ))
        '1111111111100011'
        >>> "{0:016b}".format(0xFFFF & interpret_bit_flags([4, 8, 16]))
        '0000000000011100'
        >>> "{0:016b}".format(0xFFFF & interpret_bit_flags([4, 8, 16], flip_bits=True))
        '1111111111100011'

    NFzRKeyword argument 'flip_bits' must be set to 'None' when input 'bit_flags' is None.z�Keyword argument 'flip_bits' is not permitted for comma-separated string lists of bit flags. Prepend '~' to the string to indicate bit-flipping.)r9   ÚNONEZINDEFú~r   Tr   z'Bitwise-NOT must precede bit flag list.ú(ú)z(Unbalanced parentheses in bit flag list.zAIncorrect syntax (incorrect use of parenthesis) in bit flag list.éÿÿÿÿc                 3   s   | ]}|ˆ kV  qd S r   r   r1   )Ú	bit_flagsr   r   Ú	<genexpr>¢  s     z&interpret_bit_flags.<locals>.<genexpr>z+,|zlOnly one type of bit flag separator may be used in one expression. Allowed separators are: '+', '|', or ','.ú,ú+ú|r9   zTEmpty bit flag lists not allowed when either bitwise-NOT or parenthesis are present.c                    s   g | ]}ˆ | ‘qS r   r   ©r2   Úf©Úflag_name_mapr   r   r4   ½  s     z'interpret_bit_flags.<locals>.<listcomp>Ú__iter__c                 S   s   g | ]}t |ƒ‘qS r   )r   ©r2   Úflagr   r   r   r4   Â  s     c                 S   s   g | ]}t |tƒ‘qS r   )r   rA   r~   r   r   r   r4   Ä  s     c                    s   g | ]}ˆ | ‘qS r   r   ry   r{   r   r   r4   Æ  s     zSEvery bit flag in a list must be either an integer flag value or a 'str' flag name.z*Unsupported type for argument 'bit_flags'.z#Duplicate bit flags will be ignoredz>Input list contains invalid (not powers of two) bit flag: {:d})r   r   r'   Ú	TypeErrorr   rA   ÚstripÚupperÚfindÚlstripr%   r   ÚrfindÚlenÚsumÚsplitÚhasattrÚallÚsetr@   ÚwarningsÚwarnr   r&   )rt   Ú	flip_bitsr|   Zhas_flip_bitsZallow_non_flagsZbitflip_posZnlparZnrparZlpar_posZrpar_posZbitsetZbitmaskr6   r   )rt   r|   r   r     sª    Pÿÿ




ÿÿ



ÿ
ÿÿ
ÿÿFc                 C   s¾   t  | ¡} t  | jt j¡s"tdƒ‚t|||d�}|dkr^|rLt j| |d�}nt j| |d�}|S |t	@ }t j
|| jjdd�}t j| t jd�}t j| ||dd� |r®t j||d� |j|d	d	d
�S )a])  
    bitfield_to_boolean_mask(bitfield, ignore_flags=None, flip_bits=None, good_mask_value=False, dtype=numpy.bool_)
    Converts an array of bit fields to a boolean (or integer) mask array
    according to a bit mask constructed from the supplied bit flags (see
    ``ignore_flags`` parameter).

    This function is particularly useful to convert data quality arrays to
    boolean masks with selective filtering of DQ flags.

    Parameters
    ----------
    bitfield : ndarray
        An array of bit flags. By default, values different from zero are
        interpreted as "bad" values and values equal to zero are considered
        as "good" values. However, see ``ignore_flags`` parameter on how to
        selectively ignore some bits in the ``bitfield`` array data.

    ignore_flags : int, str, list, None (default = 0)
        An integer bit mask, `None`, a Python list of bit flags, a comma-,
        or ``'|'``-separated, ``'+'``-separated string list of integer
        bit flags or mnemonic flag names that indicate what bits in the input
        ``bitfield`` should be *ignored* (i.e., zeroed), or `None`.

        .. note::
            When ``bit_flags`` is a list of flag names, the ``flag_name_map``
            parameter must be provided.

        | Setting ``ignore_flags`` to `None` effectively will make
          `bitfield_to_boolean_mask` interpret all ``bitfield`` elements
          as "good" regardless of their value.

        | When ``ignore_flags`` argument is an integer bit mask, it will be
          combined using bitwise-NOT and bitwise-AND with each element of the
          input ``bitfield`` array (``~ignore_flags & bitfield``). If the
          resultant bitfield element is non-zero, that element will be
          interpreted as a "bad" in the output boolean mask and it will be
          interpreted as "good" otherwise. ``flip_bits`` parameter may be used
          to flip the bits (``bitwise-NOT``) of the bit mask thus effectively
          changing the meaning of the ``ignore_flags`` parameter from "ignore"
          to "use only" these flags.

        .. note::

            Setting ``ignore_flags`` to 0 effectively will assume that all
            non-zero elements in the input ``bitfield`` array are to be
            interpreted as "bad".

        | When ``ignore_flags`` argument is a Python list of integer bit
          flags, these flags are added together to create an integer bit mask.
          Each item in the list must be a flag, i.e., an integer that is an
          integer power of 2. In order to flip the bits of the resultant
          bit mask, use ``flip_bits`` parameter.

        | Alternatively, ``ignore_flags`` may be a string of comma- or
          ``'+'``(or ``'|'``)-separated list of integer bit flags that should
          be added (bitwise OR) together to create an integer bit mask.
          For example, both ``'4,8'``, ``'4|8'``, and ``'4+8'`` are equivalent
          and indicate that bit flags 4 and 8 in the input ``bitfield``
          array should be ignored when generating boolean mask.

        .. note::

            ``'None'``, ``'INDEF'``, and empty (or all white space) strings
            are special values of string ``ignore_flags`` that are
            interpreted as `None`.

        .. note::

            Each item in the list must be a flag, i.e., an integer that is an
            integer power of 2. In addition, for convenience, an arbitrary
            **single** integer is allowed and it will be interpreted as an
            integer bit mask. For example, instead of ``'4,8'`` one could
            simply provide string ``'12'``.

        .. note::
            Only one flag separator is supported at a time. ``ignore_flags``
            string should not mix ``','``, ``'+'``, and ``'|'`` separators.

        .. note::

            When ``ignore_flags`` is a `str` and when it is prepended with
            '~', then the meaning of ``ignore_flags`` parameters will be
            reversed: now it will be interpreted as a list of bit flags to be
            *used* (or *not ignored*) when deciding which elements of the
            input ``bitfield`` array are "bad". Following this convention,
            an ``ignore_flags`` string value of ``'~0'`` would be equivalent
            to setting ``ignore_flags=None``.

        .. warning::

            Because prepending '~' to a string ``ignore_flags`` is equivalent
            to setting ``flip_bits`` to `True`, ``flip_bits`` cannot be used
            with string ``ignore_flags`` and it must be set to `None`.

    flip_bits : bool, None (default = None)
        Specifies whether or not to invert the bits of the bit mask either
        supplied directly through ``ignore_flags`` parameter or built from the
        bit flags passed through ``ignore_flags`` (only when bit flags are
        passed as Python lists of integer bit flags). Occasionally, it may be
        useful to *consider only specific bit flags* in the ``bitfield``
        array when creating a boolean mask as opposed to *ignoring* specific
        bit flags as ``ignore_flags`` behaves by default. This can be achieved
        by inverting/flipping the bits of the bit mask created from
        ``ignore_flags`` flags which effectively changes the meaning of the
        ``ignore_flags`` parameter from "ignore" to "use only" these flags.
        Setting ``flip_bits`` to `None` means that no bit flipping will be
        performed. Bit flipping for string lists of bit flags must be
        specified by prepending '~' to string bit flag lists
        (see documentation for ``ignore_flags`` for more details).

        .. warning::
            This parameter can be set to either `True` or `False` **ONLY** when
            ``ignore_flags`` is either an integer bit mask or a Python
            list of integer bit flags. When ``ignore_flags`` is either
            `None` or a string list of flags, ``flip_bits`` **MUST** be set
            to `None`.

    good_mask_value : int, bool (default = False)
        This parameter is used to derive the values that will be assigned to
        the elements in the output boolean mask array that correspond to the
        "good" bit fields (that are 0 after zeroing bits specified by
        ``ignore_flags``) in the input ``bitfield`` array. When
        ``good_mask_value`` is non-zero or ``numpy.True_`` then values in the
        output boolean mask array corresponding to "good" bit fields in
        ``bitfield`` will be ``numpy.True_`` (if ``dtype`` is ``numpy.bool_``)
        or 1 (if ``dtype`` is of numerical type) and values of corresponding
        to "bad" flags will be ``numpy.False_`` (or 0). When
        ``good_mask_value`` is zero or ``numpy.False_`` then the values
        in the output boolean mask array corresponding to "good" bit fields
        in ``bitfield`` will be ``numpy.False_`` (if ``dtype`` is
        ``numpy.bool_``) or 0 (if ``dtype`` is of numerical type) and values
        of corresponding to "bad" flags will be ``numpy.True_`` (or 1).

    dtype : data-type (default = ``numpy.bool_``)
        The desired data-type for the output binary mask array.

    flag_name_map : BitFlagNameMap
         A `BitFlagNameMap` object that provides mapping from mnemonic
         bit flag names to integer bit values in order to translate mnemonic
         flags to numeric values when ``bit_flags`` that are comma- or
         '+'-separated list of menmonic bit flag names.

    Returns
    -------
    mask : ndarray
        Returns an array of the same dimensionality as the input ``bitfield``
        array whose elements can have two possible values,
        e.g., ``numpy.True_`` or ``numpy.False_`` (or 1 or 0 for integer
        ``dtype``) according to values of to the input ``bitfield`` elements,
        ``ignore_flags`` parameter, and the ``good_mask_value`` parameter.

    Examples
    --------

        >>> from astropy.nddata import bitmask
        >>> import numpy as np
        >>> dqarr = np.asarray([[0, 0, 1, 2, 0, 8, 12, 0],
        ...                     [10, 4, 0, 0, 0, 16, 6, 0]])
        >>> flag_map = bitmask.extend_bit_flag_map(
        ...     'ST_DQ', CR=2, CLOUDY=4, RAINY=8, HOT=16, DEAD=32
        ... )
        >>> bitmask.bitfield_to_boolean_mask(dqarr, ignore_flags=0,
        ...                                  dtype=int)
        array([[0, 0, 1, 1, 0, 1, 1, 0],
               [1, 1, 0, 0, 0, 1, 1, 0]])
        >>> bitmask.bitfield_to_boolean_mask(dqarr, ignore_flags=0,
        ...                                  dtype=bool)
        array([[False, False,  True,  True, False,  True,  True, False],
               [ True,  True, False, False, False,  True,  True, False]]...)
        >>> bitmask.bitfield_to_boolean_mask(dqarr, ignore_flags=6,
        ...                                  good_mask_value=0, dtype=int)
        array([[0, 0, 1, 0, 0, 1, 1, 0],
               [1, 0, 0, 0, 0, 1, 0, 0]])
        >>> bitmask.bitfield_to_boolean_mask(dqarr, ignore_flags=~6,
        ...                                  good_mask_value=0, dtype=int)
        array([[0, 0, 0, 1, 0, 0, 1, 0],
               [1, 1, 0, 0, 0, 0, 1, 0]])
        >>> bitmask.bitfield_to_boolean_mask(dqarr, ignore_flags=6, dtype=int,
        ...                                  flip_bits=True, good_mask_value=0)
        array([[0, 0, 0, 1, 0, 0, 1, 0],
               [1, 1, 0, 0, 0, 0, 1, 0]])
        >>> bitmask.bitfield_to_boolean_mask(dqarr, ignore_flags='~(2+4)',
        ...                                  good_mask_value=0, dtype=int)
        array([[0, 0, 0, 1, 0, 0, 1, 0],
               [1, 1, 0, 0, 0, 0, 1, 0]])
        >>> bitmask.bitfield_to_boolean_mask(dqarr, ignore_flags=[2, 4],
        ...                                  flip_bits=True, good_mask_value=0,
        ...                                  dtype=int)
        array([[0, 0, 0, 1, 0, 0, 1, 0],
               [1, 1, 0, 0, 0, 0, 1, 0]])
        >>> bitmask.bitfield_to_boolean_mask(dqarr, ignore_flags='~(CR,CLOUDY)',
        ...                                  good_mask_value=0, dtype=int,
        ...                                  flag_name_map=flag_map)
        array([[0, 0, 0, 1, 0, 0, 1, 0],
               [1, 1, 0, 0, 0, 0, 1, 0]])
        >>> bitmask.bitfield_to_boolean_mask(dqarr, ignore_flags='~(CR+CLOUDY)',
        ...                                  good_mask_value=0, dtype=int,
        ...                                  flag_name_map=flag_map)
        array([[0, 0, 0, 1, 0, 0, 1, 0],
               [1, 1, 0, 0, 0, 0, 1, 0]])

    z-Input bitfield array must be of integer type.)rŽ   r|   N)r
   r   r	   )Úoutr   )r�   F)r
   ZsubokÚcopy)r   Zasarrayr   r
   r   r€   r   Z	ones_likeZ
zeros_likeÚ_SUPPORTED_FLAGSÚbitwise_notÚtypeZ
empty_likeÚbool_Zbitwise_andZlogical_notZastype)ZbitfieldZignore_flagsrŽ   Zgood_mask_valuer
   r|   Zignore_maskÚmaskr   r   r   r   ä  s2     T
  ÿ  ÿ)NN)r"   r   rŒ   Úcollectionsr   Únumpyr   Ú__all__rB   Zmaximum_sctypeZuintZ_MAX_UINT_TYPEr'   r’   r‘   r   r   r%   r   r#   r“   r-   r   r   r   r”   r   r   r   r   r   Ú<module>   s8   û	{,
 Pú