CCSDSPy / ccsdspy

I/O interface and utilities for CCSDS binary spacecraft data in Python. Library used in flight missions at NASA, NOAA, and SWRI
https://ccsdspy.org
BSD 3-Clause "New" or "Revised" License
74 stars 18 forks source link

StringifyBytesConverter - converts byte arrays or multi-byte numbers to numeric representations such as binary, hexidecimal, or octal #75

Closed ddasilva closed 1 year ago

ddasilva commented 1 year ago

This implements the change requested in #73.

A new converter class is added, called ccsdspy.converters.StringifyBytesConverter, which will convert an array to number representations such as binary, hexidecimal, or octal. The full docstring of the class is quoted below:

class StringifyBytesConverter(Converter):
    """Post-processing conversion which converts byte arrays or multi-byte 
    numbers to strings in numeric representations such as binary, hexidecimal, 
    or octal. 

    To convert individual bytes, the input field should be defined as a
    `~ccsdspy.PacketArray` constructed with `data_type="uint"` and 
    `bit_length=8`. Otherwise, each element is converted as a single entity.

    If the field is an array, the shape of the array is retained. The strings
    generated are not padded to a fixed length.

    The converted strings contain prefixes such as `0b` (binary), `0x` (hex),
    or `0o` (octal). If the number is signed and negative, the prefixes change
    to `-0b` (binary), `-0x` (hex), or `-0o` (octal).
    """
    def __init__(self, format="hex"):

An example of the usage follows.



from ccsdspy import VariableLength, PacketArray
from ccsdspy.converters import StringifyBytesConverter

pkt = VariableLength([
    PacketField(name="MyField",  data_type="uint", bit_length=8),
])

pkt.add_converted_field(
    "MyField"
    "MyField_Binary",
     StringifyBytesConverter(format="binary")
)
result = pkt.load("MyCCSDS.bin")
print(result['MyField_Binary'])

# prints the following array, when the actual data is populated with np.arange(0, 60, 10, dtype=np.uint8)
np.array([
    "0b0",  
    "0b1010",  
    "0b10100",  
    "0b11110", 
    "0b101000",  
    "0b110010",
 ], dtype=object)
nischayn99 commented 1 year ago

Hi @ddasilva,

Thank you for StringifyBytesConverter. It's working fine with most conversions. However, when I try to convert the "REG" packet array in the ECM Packet Structure, I get an error with the conversion saying, TypeError: only integer scalar arrays can be converted to a scalar index. Just wanted to know if the conversion can only be applied to PacketFields or even PacketArrays. I've attached the code and the test dataset for your reference.

Thanks, Nischay Test Code + Data.zip

ddasilva commented 1 year ago

Thanks @nischayn99, I'll take a look. I'm on travel so it will probably be next week.

codecov[bot] commented 1 year ago

Codecov Report

Merging #75 (2efe53a) into main (c1a50c0) will increase coverage by 0.21%. The diff coverage is 100.00%.

@@            Coverage Diff             @@
##             main      #75      +/-   ##
==========================================
+ Coverage   95.52%   95.74%   +0.21%     
==========================================
  Files           7        7              
  Lines         604      635      +31     
==========================================
+ Hits          577      608      +31     
  Misses         27       27              
Impacted Files Coverage Δ
ccsdspy/converters.py 100.00% <100.00%> (ø)

:mega: We’re building smart automated test selection to slash your CI/CD build times. Learn more

ddasilva commented 1 year ago

Hi @ddasilva,

Thank you for StringifyBytesConverter. It's working fine with most conversions. However, when I try to convert the "REG" packet array in the ECM Packet Structure, I get an error with the conversion saying, TypeError: only integer scalar arrays can be converted to a scalar index. Just wanted to know if the conversion can only be applied to PacketFields or even PacketArrays. I've attached the code and the test dataset for your reference.

Thanks, Nischay Test Code + Data.zip

Thanks for sending this test data and code. I had forgotten to handle the case of expanding arrays. I pushed a new commit to this branch which fixes the issue, and your code now runs for me. I also added a test to make sure there isn't a regression in the future.

nischayn99 commented 1 year ago

Hi @ddasilva, Thank you for StringifyBytesConverter. It's working fine with most conversions. However, when I try to convert the "REG" packet array in the ECM Packet Structure, I get an error with the conversion saying, TypeError: only integer scalar arrays can be converted to a scalar index. Just wanted to know if the conversion can only be applied to PacketFields or even PacketArrays. I've attached the code and the test dataset for your reference. Thanks, Nischay Test Code + Data.zip

Thanks for sending this test data and code. I had forgotten to handle the case of expanding arrays. I pushed a new commit to this branch which fixes the issue, and your code now runs for me. I also added a test to make sure there isn't a regression in the future.

Thank you, @ddasilva.