
    IR-e$k                        d Z ddlZddlZddlmZ ddlZg dZdZ e	 ej
        ddd                    Zd	 Zd
 Z G d de          Z G d de	          Z G d de          Z G d de          ZefdZddZdddej        df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uint64unsafedtypecastingc                 ^    | 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ns    6lib/python3.11/site-packages/astropy/nddata/bitmask.py_is_bit_flagr      s/    " 	1uuuq66<<!!    c                     t          | t          j                  rt          | t                     p8t          | t          j                  ot	          j        | t          j                  S N)
isinstancenumbersIntegralboolnpgeneric
issubdtypeintegerr   s    r   _is_intr"   0   sP    q'*++GJq$4G4G0G 1bj!!BbmArz&B&Br   c                       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   6   s        HHDr   r   c                       e Zd ZdZddZdS )BitFlagz/Bit flags: integer values that are powers of 2.Nc                 $   t          |t                    r|t          d          |\  }}t          |          rt	          |          s"t          d                    |                    t                              | |          }|||_	        |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ss       r   r1   zBitFlag.__new__?   s    c5!! 	 !NOOOHC 	c!2!2 	 ,,2F3KK  
 KKS!!?AIr   r   )r%   r&   r'   r(   r1   r)   r   r   r+   r+   <   s.        99     r   r+   c                   R     e Zd Z fdZ fdZd Zd Zd Zd Zd Z	d Z
d	 Z xZS )
BitFlagNameMetac                 h   |                                 D ])\  }}|                    d          st          |          }*d |                                D             }t	          t          t          j        |                    }t          rt                      }|D ]}	|	j
                                         D ]n\  }}|                    d          r|                                }
|
|v r/|                    |
          }t          d||         dd          t          r|||
<   od |                                 D             }t          r=|                    d |                                 D                        dd	d
|d|i}ndd	d
|}t                                          | |||          S )N_c                 <    g | ]}|                     d           |S r9   )
startswith.0ks     r   
<listcomp>z+BitFlagNameMeta.__new__.<locals>.<listcomp>W   s)    CCCac1B1BCCCCr   z
Bit flag 'r5   z' was already defined.c                 b    i | ],\  }}||                     d           r|nt          |          -S r;   )r<   r+   r>   r?   vs      r   
<dictcomp>z+BitFlagNameMeta.__new__.<locals>.<dictcomp>j   sF     
 
 
:>!QAALL%%5qq71::
 
 
r   c                 h    i | ]/\  }}|                     d           |                                |0S r;   )r<   lowerrB   s      r   rD   z+BitFlagNameMeta.__new__.<locals>.<dictcomp>p   s7    SSS$!QcARARSASSSr   T )_locked__version___cache)itemsr<   r+   keyslistmapstrrF   _ENABLE_BITFLAG_CACHINGr   __dict__indexAttributeErrorupdatesuperr1   )mclsnamebasesmembersr?   rC   attrattrlcachebklidx	__class__s               r   r1   zBitFlagNameMeta.__new__R   s   MMOO 	 	DAq<<$$ AJJCC7<<>>CCCSD))**" 	"MME 	" 	"A
((** 
" 
"1<<$$ WWYY;;++b//C(HT#YHHHH   + " !E"I
"
 
BI--//
 
 
 # 	FLLSS'--//SSS   #'rVVWVhPUVVGG"&rEEWEGwwtT5':::r   c                 x   |dk    r"t                                          |d          S |dk    r8| j        rt          d          t                                          ||          S d| }| j        rt          |          |                                }t
          r.|                    d          s|| j        v rt          |          n| j        D ]T}|                    d          s=|t          t          t          j        |j                            v rt          |          U|t          t          t          j        | j                            v rt          |          t          |          }t
          r|                    d          s
|| j        |<   t                                          ||          S )NrH   TrI   zVersion cannot be modified.z6Bit flags are read-only. Unable to reassign attribute r9   )rU   __setattr__rH   rS   rF   rP   r<   rJ   	__bases__rM   rN   rO   rQ   r+   )r2   rW   r3   err_msgnamelr]   r`   s         r   rb   zBitFlagNameMeta.__setattr__x   s   977&&tT222 }$$; H()FGGGww**4555UtUUG{ .$W---

" 	.##C(( .Ucj-@-@$W--- ] 2 2'',, 2$	1:..; ; 2 2 )111SCL99::::$W---cll" 	$5+;+;C+@+@ 	$ #CJuww""4---r   c                 &   t           r| j        }nGd | j                                        D             }|                    d | j        D                        	 ||                                         S # t          $ r t          d| d          w xY w)Nc                 >    i | ]\  }}|                                 |S r)   )rF   rB   s      r   rD   z/BitFlagNameMeta.__getattr__.<locals>.<dictcomp>   s&    GGG$!QAGGGr   c                 v    i | ]6}|j                                         D ]\  }}|                                |7S r)   )rQ   rK   rF   )r>   r]   r?   rC   s       r   rD   z/BitFlagNameMeta.__getattr__.<locals>.<dictcomp>   sA    TTT!AQAQASASTTAATTTTr   zFlag 'z' not defined)	rP   rJ   rQ   rK   rT   rc   rF   KeyErrorrS   )r2   rW   	flagnamess      r   __getattr__zBitFlagNameMeta.__getattr__   s    " 	
IIGG#,2D2D2F2FGGGITTs}TTT  	?TZZ\\** 	? 	? 	? !=$!=!=!=>>>	?s   A2 2Bc                 ,    |                      |          S r   )rk   )r2   keys     r   __getitem__zBitFlagNameMeta.__getitem__   s    s###r   c                     t          |t                    s4t          |d         t          t          f          s|g}t          |          }t	          | j        dz   d                    d |D                       z   | fi |S )Nr   r9   c                     g | ]}|S r)   r)   r=   s     r   r@   z+BitFlagNameMeta.__add__.<locals>.<listcomp>   s    *<*<*<1*<*<*<r   )r   dictr-   rM   r   r%   join)r2   rK   s     r   __add__zBitFlagNameMeta.__add__   s    %&& 	 eAh66  KKE"L3*<*<e*<*<*<!=!==s
 
FK
 
 	
r   c                      t          d          )Nz8Unary '+' is not supported. Use binary operator instead.)NotImplementedError)r2   others     r   __iadd__zBitFlagNameMeta.__iadd__   s    !F
 
 	
r   c                 p    t          | j         d|                                 d         j         d          Nz: cannot delete z member.rS   r%   mror2   rW   s     r   __delattr__zBitFlagNameMeta.__delattr__   9    |MMSWWYYr]-CMMM
 
 	
r   c                 p    t          | j         d|                                 d         j         d          ry   r{   r}   s     r   __delitem__zBitFlagNameMeta.__delitem__   r   r   c                 X    d|                                  d         j         d| j         dS )N<rz   z 'z'>)r|   r%   )r2   s    r   __repr__zBitFlagNameMeta.__repr__   s,    =37799R=)==S\====r   )r%   r&   r'   r1   rb   rk   rn   rs   rw   r~   r   r   __classcell__)r`   s   @r   r7   r7   Q   s        $; $; $; $; $;L!. !. !. !. !.F? ? ?$ $ $
 
 

 
 


 
 


 
 

> > > > > > >r   r7   c                       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         2 	Dr   r   )	metaclassc                    t                               t           | |fddi          }|                                D ]I\  }}	 t          |||           # t          $ r%}||         t          |          k    r|Y d}~Bd}~ww xY w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

    rH   FNT)r7   r1   rK   setattrrS   r0   rH   )cls_namebase_clskwargsnew_clsr?   rC   es          r   r   r      s    : %%H;E0B G   1	GQ"""" 	 	 	qzSVV## $####	 GONs    A
BA<<Bc                 T    |du}t          |          }d}t                     r!|rt                      nt                     S  |rt          d          dS t	           t
                    r9|rt          d          t                                                                                       dv 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n||k    rt          d                               d          }                     d          }	|dk    s|	t                     d	z
  k     rt          d           d	d                                          t           fddD                       d	k    rt          d          d v r                     d           nLd v r                     d           n2d v r                     d           n dk    rt          d           g 5	 t           d                    n# t          $ r fd D              Y nw xY wt                     d	k    }nrt!           d          rSt#          d  D                       s9(t#          d  D                       rfd D              nt          d          nt          d          t%          t'          t                               }
t          |
          t                     k    rt)          j        d           d}|
D ]*}t-          |          s|st          d |           ||z  }+|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.zKeyword argument 'flip_bits' is not permitted for comma-separated string lists of bit flags. Prepend '~' to the string to indicate bit-flipping.)rG   NONE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       K   | ]}|v V  	d S r   r)   )r>   r?   	bit_flagss     r   	<genexpr>z&interpret_bit_flags.<locals>.<genexpr>  s'      --!qI~------r   z+,|zlOnly one type of bit flag separator may be used in one expression. Allowed separators are: '+', '|', or ','.,+|rG   zTEmpty bit flag lists not allowed when either bitwise-NOT or parenthesis are present.c                      g | ]
}|         S r)   r)   r>   fflag_name_maps     r   r@   z'interpret_bit_flags.<locals>.<listcomp>      AAA!]1-AAAr   __iter__c              3   4   K   | ]}t          |          V  d S r   )r"   r>   flags     r   r   z&interpret_bit_flags.<locals>.<genexpr>  s(      77T74==777777r   c              3   @   K   | ]}t          |t                    V  d S r   )r   rO   r   s     r   r   z&interpret_bit_flags.<locals>.<genexpr>  s=       1 1*.
4%%1 1 1 1 1 1r   c                      g | ]
}|         S r)   r)   r   s     r   r@   z'interpret_bit_flags.<locals>.<listcomp>  r   r   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: )r   r"   r0   	TypeErrorr   rO   stripupperfindlstripr.   r   rfindlensumsplithasattrallsetrN   warningswarnr   )r   	flip_bitsr   has_flip_bitsallow_non_flagsbitflip_posnlparnrparlpar_posrpar_posbitsetbitmaskrC   s   ` `          r   r   r     s   ^ T)MYIOy cF"+?IY?		 	-   t	Is	#	# XF 	7   	NN((**	?? 5554  nnS))!I!!"",,..IIQ !JKKKI	0OOC((EOOC((Ezzeqjj~~ !KLLL ~~c**H s++H!||x3y>>A+=>> W   "!B$--//I#	0& ----u-----11H  
 )!,,III!,,III!,,II B 2   #I$BIaL!!!! B B BAAAAyAAA			B i..A-	J	'	' F77Y77777 		(S 1 12;1 1 1 . .( BAAAyAAA		?  		 DEEES)$$%%F
6{{c)nn$$;<<<G  A 	 	PQPP   	1 (Ns   $I: :JJFc                 @   t          j        |           } t          j        | j        t           j                  st          d          t          |||          }|1|rt          j        | |          }nt          j        | |          }|S |t          z  }t          j
        || j        j        d          }t          j        | t           j                  }t          j        | ||d           |rt          j        ||           |                    |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   subokcopy)r   asarrayr    r   r!   r   r   	ones_like
zeros_like_SUPPORTED_FLAGSbitwise_nottype
empty_likebool_bitwise_andlogical_notastype)bitfieldignore_flagsr   good_mask_valuer   r   ignore_maskmasks           r   r   r     s-   d z(##H=44 IGHHH%	  K  	8<666DD=777D  00K .8>.  K =222DN8[dHEEEE '
t&&&&;;U%e;<<<r   )NN)r(   r   r   collectionsr   numpyr   __all__rP   r0   r   r   r   r"   r.   r   r+   r   r7   r   r   r   r   r   r)   r   r   <module>r      s   
   # # # # # #        3~r~axJJJKK " " ".  	 	 	 	 	Z 	 	 	    c   *t> t> t> t> t>d t> t> t>n	 	 	 	 	 	 	 	 	: ,: ( ( ( (VG G G GX 
(o= o= o= o= o= o=r   