Skip to content

A support for parsing compressed data products in fprime-dp#309

Open
kubiak-jpl wants to merge 8 commits into
nasa:develfrom
kubiak-jpl:dev/compressed_data_products
Open

A support for parsing compressed data products in fprime-dp#309
kubiak-jpl wants to merge 8 commits into
nasa:develfrom
kubiak-jpl:dev/compressed_data_products

Conversation

@kubiak-jpl

Copy link
Copy Markdown
Contributor
Related Issue(s) nasa/fprime#4941
Has Unit Tests (y/n) n
Documentation Included (y/n) n

Change Description

The PR adds support for decoding compressed data products alongside this PR
nasa/fprime#5235

If fprime-dp decode encounters a compressed data product it will attempt to decompress it and output a JSON for the decompressed product. The new -z,--disable-decompression flag will disable this behavior and output the raw byte arrays from the compressed product as a JSON.

Rationale

Enables F Prime tooling to seamlessly deal with compressed data products.

Testing/Review Recommendations

Using this example data product file, generated by the TestDeployment
Dp_00002576_1780687868_00728225.fdp.txt

Running the following command will generate the proper decompressed records

fprime-dp decode -d ../build-artifacts/Linux/Ref/dict/RefTopologyDictionary.json -b Dp_00002576_1780687868_00728225.fdp

Dp_00002576_1780687868_00728225.json

Adding the -z flag will generate raw compression records

fprime-dp decode -d ../build-artifacts/Linux/Ref/dict/RefTopologyDictionary.json -b Dp_00002576_1780687868_00728225.fdp -z

Dp_00002576_1780687868_00728225_compressed.json

Future Work

None

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support in the F Prime GDS fprime-dp decode tool to detect compressed data product records and automatically decompress them before emitting JSON, with an option to disable decompression and emit the raw compression records instead. This extends the existing ConfigManager-based DP decoder to handle the compression record format produced by dpCompressProc.

Changes:

  • Added -z/--disable-decompression flag to the fprime-dp decode CLI.
  • Extended DataProductDecoder to detect compression records, decompress them (UNCOMPRESSED and ZLIB_DEFLATE), and re-decode the resulting byte stream.
  • Refactored record decoding into a reusable decode_records helper.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
src/fprime_gds/executables/data_products.py Adds CLI flag and threads decompression option into the decoder invocation.
src/fprime_gds/common/dp/decoder.py Implements compression-record detection + decompression, and factors out record-loop logic.
Comments suppressed due to low confidence (1)

src/fprime_gds/common/dp/decoder.py:95

  • DataProductDecoder.__init__ now requires disable_decompression as a positional argument, which is a breaking change for any existing callers importing this class. Make the new parameter optional (defaulting to False) and document it in the docstring so older call sites continue to work.
    def __init__(self, dictionaries: Dictionaries, binary_file_path: str, disable_decompression: bool, output_json_path: Optional[str] = None):
        """Initialize the decoder.
        
        Args:
            dictionaries: Dictionaries object containing dictionary information

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +207 to +212
while (r_io.tell() - position_at_start) < data_size:
# Read record ID
record_id_bin = r_io.read(ConfigManager().get_type("FwDpIdType").getSize())
record_id_obj = ConfigManager().get_type("FwDpIdType")()
record_id_obj.deserialize(record_id_bin, 0)
record_id = record_id_obj.val

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idk about that error message but this seems like a good check to add

Comment on lines +237 to +240
if record_meta.val['algorithm'] == 'UNCOMPRESSED':
uncomp_bytes.extend(record_io.read())
elif record_meta.val['algorithm'] == 'ZLIB_DEFLATE':
uncomp_bytes.extend(zlib.decompress(record_io.read()))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts on also adding an else case to log an INFO/WARNING if algorithm is neither of the two supported ones? Later we could even make it a GDS plugin

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. That makes sense

if computed_crc != dp_crc.val:
raise CRCError("Data", dp_crc.val, computed_crc)

if not self.disable_decompression and self.is_compression_record(results["Records"][0]):
Comment on lines +288 to +296
if not self.disable_decompression and self.is_compression_record(results["Records"][0]):

# Compressed records. Decompress and re-process
uncomp_bytes = self.decompress_records(results["Records"])
if uncomp_bytes is not None:
uncomp_io = BytesIO(uncomp_bytes)
uncomp_records = self.decode_records(uncomp_io, len(uncomp_bytes))
if uncomp_records is not None:
results["Records"] = uncomp_records

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not required, but would be appreciated (AI can write the test scripts if you provide test inputs/outputs)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I missed the test_decoder.py script. I'll add a test case for the compressed products

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants