Skip to content

Commit

Permalink
Merge pull request #611 from mcara/update-bitfield
Browse files Browse the repository at this point in the history
 Port enhancements to bitfield from stsci.tools
  • Loading branch information
crawfordsm committed Apr 5, 2018
2 parents 913d1a3 + e38eafc commit 7db3cb3
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 6 deletions.
1 change: 1 addition & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Alphabetical list of contributors
* Yoonsoo P. Bach (@ysBach)
* Kyle Barbary (@kbarbary)
* Javier Blasco (@javierblasco)
* Mihai Cara (@mcara)
* Christoph Deil (@cdeil)
* Carlos Gomez (@carlgogo)
* Hans Moritz Günther (@hamogu)
Expand Down
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ New Features
Other Changes and Additions
^^^^^^^^^^^^^^^^^^^^^^^^^^^

- Improved handling of large flags in the ``bitfield`` module. [#610]

- Improved the performance of several ``ImageFileCollection`` methods. [#599]

Bug Fixes
Expand Down
34 changes: 28 additions & 6 deletions ccdproc/extern/bitfield.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@
"""

import numpy as np
import sys
import warnings
import six
import numpy as np


__version__ = '1.0.0'
__vdate__ = '16-March-2017'
__version__ = '1.1.1'
__vdate__ = '30-January-2018'
__author__ = 'Mihai Cara'


Expand All @@ -41,6 +42,22 @@
# and string comma- (or '+') separated lists of bit flags).
# 5. Added 'is_bit_flag()' function to check if an integer number has
# only one bit set (i.e., that it is a power of 2).
# 1.1.0 (29-January-2018) - Multiple enhancements:
# 1. Added support for long type in Python 2.7 in
# `interpret_bit_flags()` and `bitfield_to_boolean_mask()`.
# 2. `interpret_bit_flags()` now always returns `int` (or `int` or `long`
# in Python 2.7). Previously when input was of integer-like type
# (i.e., `numpy.uint64`), it was not converted to Python `int`.
# 3. `bitfield_to_boolean_mask()` will no longer crash when
# `ignore_flags` argument contains bit flags beyond what the type of
# the argument `bitfield` can hold.
# 1.1.1 (30-January-2018) - Improved filtering of high bits in flags.
#
INT_TYPE = (int, long,) if sys.version_info < (3,) else (int,)
MAX_UINT_TYPE = np.maximum_sctype(np.uint)
SUPPORTED_FLAGS = int(np.bitwise_not(
0, dtype=MAX_UINT_TYPE, casting='unsafe'
))


def is_bit_flag(n):
Expand Down Expand Up @@ -68,7 +85,7 @@ def is_bit_flag(n):

def _is_int(n):
return (
(isinstance(n, int) and not isinstance(n, bool)) or
(isinstance(n, INT_TYPE) and not isinstance(n, bool)) or
(isinstance(n, np.generic) and np.issubdtype(n, np.integer))
)

Expand Down Expand Up @@ -136,7 +153,7 @@ def interpret_bit_flags(bit_flags, flip_bits=None):
allow_non_flags = False

if _is_int(bit_flags):
return (~int(bit_flags) if flip_bits else bit_flags)
return (~int(bit_flags) if flip_bits else int(bit_flags))

elif bit_flags is None:
if has_flip_bits:
Expand Down Expand Up @@ -418,7 +435,12 @@ def bitfield_to_boolean_mask(bitfield, ignore_flags=0, flip_bits=None,
mask = np.zeros_like(bitfield, dtype=dtype)
return mask

ignore_mask = np.bitwise_not(bitfield.dtype.type(ignore_mask))
# filter out bits beyond the maximum supported by the data type:
ignore_mask = ignore_mask & SUPPORTED_FLAGS

# invert the "ignore" mask:
ignore_mask = np.bitwise_not(ignore_mask, dtype=bitfield.dtype,
casting='unsafe')

mask = np.empty_like(bitfield, dtype=np.bool_)
np.bitwise_and(bitfield, ignore_mask, out=mask, casting='unsafe')
Expand Down

0 comments on commit 7db3cb3

Please sign in to comment.