Skip to content

Commit

Permalink
Fix handling values in digital line scaler data
Browse files Browse the repository at this point in the history
Only use the first bit to represent whether data is one or zero
  • Loading branch information
adamreeve committed Mar 29, 2020
1 parent 167884f commit f1974e7
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 4 deletions.
12 changes: 8 additions & 4 deletions nptdms/daqmx.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ def _read_data_chunk(self, file, data_objects, chunk_index):
# should be correct
this_scaler_data.dtype = (
scaler.data_type.nptype.newbyteorder(self.endianness))
if obj.daqmx_metadata.scaler_type == DIGITAL_LINE_SCALER:
this_scaler_data = np.bitwise_and(this_scaler_data, 1)
scaler_data[obj.path][scaler.scale_id] = this_scaler_data

return RawDataChunk.scaler_data(scaler_data)
Expand Down Expand Up @@ -143,17 +145,19 @@ class DaqMxMetadata(object):

__slots__ = [
'data_type',
'scaler_type',
'dimension',
'chunk_size',
'raw_data_widths',
'scalers',
]

def __init__(self, f, endianness, daqmx_segment_type):
def __init__(self, f, endianness, scaler_type):
"""
Read the metadata for a DAQmx raw segment. This is the raw
DAQmx-specific portion of the raw data index.
"""
self.scaler_type = scaler_type
self.data_type = types.tds_data_types[0xFFFFFFFF]
self.dimension = types.Uint32.read(f, endianness)
# In TDMS format version 2.0, 1 is the only valid value for dimension
Expand All @@ -165,7 +169,7 @@ def __init__(self, f, endianness, daqmx_segment_type):
scaler_vector_length = types.Uint32.read(f, endianness)
log.debug("mxDAQ format scaler vector size '%d'", scaler_vector_length)
self.scalers = [
DaqMxScaler(f, endianness, daqmx_segment_type)
DaqMxScaler(f, endianness, scaler_type)
for _ in range(scaler_vector_length)]

# Read raw data widths.
Expand Down Expand Up @@ -201,14 +205,14 @@ class DaqMxScaler(object):
'sample_format_bitmap',
]

def __init__(self, open_file, endianness, daqmx_segment_type):
def __init__(self, open_file, endianness, scaler_type):
data_type_code = types.Uint32.read(open_file, endianness)
self.data_type = DAQMX_TYPES[data_type_code]

# more info for format changing scaler
self.raw_buffer_index = types.Uint32.read(open_file, endianness)
self.raw_byte_offset = types.Uint32.read(open_file, endianness)
if daqmx_segment_type == DIGITAL_LINE_SCALER:
if scaler_type == DIGITAL_LINE_SCALER:
self.sample_format_bitmap = types.Uint8.read(open_file, endianness)
else:
self.sample_format_bitmap = types.Uint32.read(open_file, endianness)
Expand Down
26 changes: 26 additions & 0 deletions nptdms/test/test_daqmx.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,32 @@ def test_digital_line_scaler_data():
np.testing.assert_array_equal(data, [0, 1, 0, 1])


def test_digital_line_scaler_data_uses_first_bit_of_bytes():
""" Test DAQmx digital line scaler data only uses the first bit in each byte to represent a 1 or 0 value
"""

scaler_metadata = daqmx_scaler_metadata(0, 0, 2, digital_line_scaler=True)
metadata = segment_objects_metadata(
root_metadata(),
group_metadata(),
daqmx_channel_metadata("Channel1", 4, [4], [scaler_metadata], digital_line_scaler=True))
data = (
"00 00 00 00"
"00 00 01 00"
"00 00 02 00"
"00 00 03 00"
)

test_file = GeneratedFile()
test_file.add_segment(segment_toc(), metadata, data)
tdms_data = test_file.load()

data = tdms_data["Group"]["Channel1"].raw_data

assert data.dtype == np.uint8
np.testing.assert_array_equal(data, [0, 1, 0, 1])


def test_lazily_reading_channel():
""" Test loading channels individually from a DAQmx file
"""
Expand Down

0 comments on commit f1974e7

Please sign in to comment.