Skip to content

Commit

Permalink
fix: read bits from least-significat to most, not left-to-right
Browse files Browse the repository at this point in the history
  • Loading branch information
jokasimr committed Oct 26, 2023
1 parent 6f9ec49 commit e272be9
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 13 deletions.
8 changes: 2 additions & 6 deletions src/scippnexus/nxdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -614,23 +614,19 @@ def transform_bitmask_to_dict_of_masks(bitmask: sc.Variable, suffix: str = ''):
}

number_of_bits_in_dtype = 8 * bitmask.values.dtype.itemsize
# Special case, treat bool as if it only stores a single bit
if bitmask.dtype == 'bool':
number_of_bits_in_dtype = 1

# Bitwise indicator of what masks are present
masks_present = np.bitwise_or.reduce(bitmask.values)

masks = {}
for bit in range(number_of_bits_in_dtype):
steps_to_first_bit = number_of_bits_in_dtype - bit - 1
# Check if the mask associated with the current `bit` is present
mask_is_present = (masks_present >> steps_to_first_bit) % 2
mask_is_present = (masks_present >> bit) % 2
if mask_is_present:
name = bit_to_mask_name.get(bit, f'undefined_bit{bit}') + suffix
masks[name] = sc.array(
dims=bitmask.dims,
values=(bitmask.values >> (steps_to_first_bit)) % 2,
values=(bitmask.values >> bit) % 2,
dtype='bool',
)
return masks
Expand Down
23 changes: 16 additions & 7 deletions tests/nxdetector_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -689,13 +689,21 @@ def test_falls_back_to_hdf5_dim_labels_given_partially_axes(h5root):
assert_identical(dg['z'], z)


@pytest.mark.parametrize('bits,dtype', ((1, 'bool'), (32, 'int32'), (64, 'int64')))
def test_pixel_masks_interpreted_correctly(bits, dtype):
@pytest.mark.parametrize('dtype', ('bool', 'int8', 'int16', 'int32', 'int64'))
def test_pixel_masks_interpreted_correctly(dtype):
bitmask = sc.array(
dims=['detector_pixel'],
# Set mask 0, 1, 2, and 4 but not 3.
values=1 << (bits - np.array([1, 2, 3, bits + 1, 5])),
dtype=dtype,
values=(
# Set mask 0, 1, 2, and 4 but not 3.
1 << np.array([0, 1, 2, -1, 4])
if dtype != 'bool'
else
# Set mask 0 only.
np.array([1, 0, 0, 0, 0])
)
.astype(dtype)
.astype('int64'),
dtype='int64',
)
masks = snx.NXdetector.transform_bitmask_to_dict_of_masks(bitmask)

Expand All @@ -712,17 +720,18 @@ def test_pixel_masks_interpreted_correctly(bits, dtype):
def test_pixel_masks_adds_suffix():
bitmask = sc.array(
dims=['detector_pixel'],
values=1 << (32 - np.array([1, 2, 3, 0, 5])),
values=(1 << np.array([0, 1, 2, -1, 4])),
dtype='int32',
)
masks = snx.NXdetector.transform_bitmask_to_dict_of_masks(bitmask, '_test')
assert len(masks) == 4
assert all(k.endswith('_test') for k in masks.keys())


def test_pixel_masks_undefined_are_included():
bitmask = sc.array(
dims=['detector_pixel'],
values=1 << (32 - np.array([10, 0])),
values=1 << np.array([9, 0]),
dtype='int32',
)
masks = snx.NXdetector.transform_bitmask_to_dict_of_masks(bitmask)
Expand Down

0 comments on commit e272be9

Please sign in to comment.