space-packet-parser 5.0.1__tar.gz → 6.0.0.dev1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. {space_packet_parser-5.0.1 → space_packet_parser-6.0.0.dev1}/CITATION.cff +5 -2
  2. space_packet_parser-6.0.0.dev1/PKG-INFO +97 -0
  3. space_packet_parser-6.0.0.dev1/README.md +47 -0
  4. space_packet_parser-6.0.0.dev1/pyproject.toml +153 -0
  5. space_packet_parser-6.0.0.dev1/space_packet_parser/__init__.py +20 -0
  6. space_packet_parser-6.0.0.dev1/space_packet_parser/cli.py +189 -0
  7. space_packet_parser-6.0.0.dev1/space_packet_parser/common.py +249 -0
  8. space_packet_parser-6.0.0.dev1/space_packet_parser/definitions.py +17 -0
  9. {space_packet_parser-5.0.1 → space_packet_parser-6.0.0.dev1}/space_packet_parser/exceptions.py +14 -1
  10. space_packet_parser-6.0.0.dev1/space_packet_parser/packets.py +465 -0
  11. space_packet_parser-6.0.0.dev1/space_packet_parser/xarr.py +215 -0
  12. space_packet_parser-6.0.0.dev1/space_packet_parser/xtce/__init__.py +21 -0
  13. {space_packet_parser-5.0.1/space_packet_parser → space_packet_parser-6.0.0.dev1/space_packet_parser/xtce}/calibrators.py +223 -58
  14. {space_packet_parser-5.0.1/space_packet_parser → space_packet_parser-6.0.0.dev1/space_packet_parser/xtce}/comparisons.py +228 -84
  15. space_packet_parser-6.0.0.dev1/space_packet_parser/xtce/containers.py +299 -0
  16. space_packet_parser-6.0.0.dev1/space_packet_parser/xtce/definitions.py +559 -0
  17. {space_packet_parser-5.0.1/space_packet_parser → space_packet_parser-6.0.0.dev1/space_packet_parser/xtce}/encodings.py +327 -146
  18. space_packet_parser-5.0.1/space_packet_parser/parameters.py → space_packet_parser-6.0.0.dev1/space_packet_parser/xtce/parameter_types.py +251 -109
  19. space_packet_parser-6.0.0.dev1/space_packet_parser/xtce/parameters.py +117 -0
  20. space_packet_parser-5.0.1/PKG-INFO +0 -52
  21. space_packet_parser-5.0.1/README.md +0 -29
  22. space_packet_parser-5.0.1/pyproject.toml +0 -63
  23. space_packet_parser-5.0.1/space_packet_parser/__init__.py +0 -0
  24. space_packet_parser-5.0.1/space_packet_parser/definitions.py +0 -653
  25. space_packet_parser-5.0.1/space_packet_parser/packets.py +0 -247
  26. {space_packet_parser-5.0.1 → space_packet_parser-6.0.0.dev1}/LICENSE.txt +0 -0
@@ -1,7 +1,7 @@
1
1
  cff-version: 1.2.0
2
2
  title: 'space_packet_parser'
3
3
  type: software
4
- version: '5.0.1'
4
+ version: '6.0.0dev1'
5
5
  description: A CCSDS telemetry packet decoding library based on the XTCE packet format description standard.
6
6
  license: BSD-3-Clause
7
7
  abstract: The Space Packet Parser Python library is a generalized, configurable packet decoding library for CCSDS telemetry
@@ -29,5 +29,8 @@ maintainers:
29
29
  - email: gavin.medley@lasp.colorado.edu
30
30
  name: Gavin Medley
31
31
  orcid: "0000-0002-3520-9715"
32
- repository-code: "https://github.com/medley56/space_packet_parser"
32
+ - email: greg.lucas@lasp.colorado.edu
33
+ name: Greg Lucas
34
+ orcid: "0000-0003-1331-1863"
35
+ repository-code: "https://github.com/lasp/space_packet_parser"
33
36
  url: "https://space-packet-parser.readthedocs.io"
@@ -0,0 +1,97 @@
1
+ Metadata-Version: 2.3
2
+ Name: space_packet_parser
3
+ Version: 6.0.0.dev1
4
+ Summary: A CCSDS telemetry packet decoding library based on the XTCE packet format description standard.
5
+ License: BSD-3-Clause
6
+ Keywords: ccsds,xtce,space data systems,space packet protocol,packet parsing,lasp,university of colorado,data processing,data extraction,data manipulation,data transformation,data encoding,data decoding,packet inspection,binary data,python
7
+ Author: Gavin Medley
8
+ Author-email: gavin.medley@lasp.colorado.edu
9
+ Maintainer: Gavin Medley
10
+ Maintainer-email: gavin.medley@lasp.colorado.edu
11
+ Requires-Python: >=3.9
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Topic :: Scientific/Engineering
16
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Operating System :: OS Independent
19
+ Classifier: License :: OSI Approved :: BSD License
20
+ Provides-Extra: docs
21
+ Provides-Extra: examples
22
+ Provides-Extra: test
23
+ Provides-Extra: xarray
24
+ Requires-Dist: click (>=8.0)
25
+ Requires-Dist: lxml (>=4.8.0)
26
+ Requires-Dist: matplotlib (>=3.4) ; extra == "examples"
27
+ Requires-Dist: myst-parser ; extra == "docs"
28
+ Requires-Dist: numpy (>=2.0.0) ; extra == "xarray"
29
+ Requires-Dist: numpy ; extra == "test"
30
+ Requires-Dist: pre-commit ; extra == "test"
31
+ Requires-Dist: pytest ; extra == "test"
32
+ Requires-Dist: pytest-benchmark ; extra == "test"
33
+ Requires-Dist: pytest-cov ; extra == "test"
34
+ Requires-Dist: pytest-randomly ; extra == "test"
35
+ Requires-Dist: pyyaml ; extra == "docs"
36
+ Requires-Dist: pyyaml ; extra == "test"
37
+ Requires-Dist: rich (>=13.0)
38
+ Requires-Dist: ruff ; extra == "test"
39
+ Requires-Dist: sphinx ; extra == "docs"
40
+ Requires-Dist: sphinx-autoapi ; extra == "docs"
41
+ Requires-Dist: sphinx-rtd-theme ; extra == "docs"
42
+ Requires-Dist: tomli ; extra == "test"
43
+ Requires-Dist: xarray (>2024.0.0) ; extra == "xarray"
44
+ Requires-Dist: xarray ; extra == "test"
45
+ Project-URL: Documentation, https://space-packet-parser.readthedocs.io
46
+ Project-URL: Homepage, https://github.com/lasp/space_packet_parser
47
+ Project-URL: Repository, https://github.com/lasp/space_packet_parser
48
+ Description-Content-Type: text/markdown
49
+
50
+ # Space Packet Parser
51
+
52
+ [![Conda](https://img.shields.io/conda/vn/lasp/space_packet_parser?color=42B029&logo=anaconda&logoColor=white)](https://anaconda.org/lasp/space_packet_parser)
53
+ [![PyPI](https://img.shields.io/pypi/v/space_packet_parser?color=blue&logo=pypi&logoColor=white)](https://pypi.org/project/space-packet-parser/)
54
+ [![DOI](https://zenodo.org/badge/612253190.svg)](https://doi.org/10.5281/zenodo.7735001)
55
+
56
+ [![Test Status](https://github.com/lasp/space_packet_parser/actions/workflows/tests.yml/badge.svg)](https://github.com/lasp/space_packet_parser/actions/workflows/tests.yml)
57
+ [![codecov](https://codecov.io/gh/lasp/space_packet_parser/graph/badge.svg?token=VUFIN94O05)](https://codecov.io/gh/lasp/space_packet_parser)
58
+
59
+ **Documentation:** [https://space-packet-parser.readthedocs.io/en/latest/](https://space-packet-parser.readthedocs.io/en/latest/)
60
+
61
+ | **Stable ReadTheDocs Build** | [![Stable Docs](https://readthedocs.org/projects/space-packet-parser/badge/?version=stable)](https://app.readthedocs.org/projects/space-packet-parser/builds/?version__slug=stable) |
62
+ |------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
63
+ | **Latest ReadTheDocs Build** | [!["Latest Docs"](https://readthedocs.org/projects/space-packet-parser/badge/?version=latest)](https://app.readthedocs.org/projects/space-packet-parser/builds/?version__slug=latest) |
64
+
65
+
66
+ Space Packet Parser is a package for decoding CCSDS telemetry packets according to an XTCE packet structure definition.
67
+ It is based on the UML model of the XTCE spec and aims to support all but the most esoteric elements of the
68
+ XTCE telemetry packet specification.
69
+
70
+ Resources:
71
+ - [XTCE (Green Book - Informational Report)](https://public.ccsds.org/Pubs/660x2g2.pdf)
72
+ - [XTCE Element Description (Green Book - Informational Report)](https://public.ccsds.org/Pubs/660x1g2.pdf)
73
+ - [XTCE (Blue Book - Recommended Standard)](https://public.ccsds.org/Pubs/660x0b2.pdf)
74
+
75
+ ## Installation
76
+ From PyPI
77
+ ```bash
78
+ pip install space_packet_parser
79
+ ```
80
+
81
+ From Anaconda (distributed on the `lasp` channel):
82
+ ```bash
83
+ conda install -c lasp space_packet_parser
84
+ ```
85
+
86
+ ## Proud Member of the Python in Heliophysics Community (PyHC)
87
+
88
+ [<img src="https://heliopython.org/img/PyHC%20header%20logo%20500x500.png" alt="PyHC" height="70"/>](https://heliopython.org)
89
+
90
+ ## Missions using Space Packet Parser
91
+
92
+ [<img src="https://imap.princeton.edu/sites/g/files/toruqf7171/files/imap-mark-hor-multicolor-dark.png" alt="IMAP" height="70"/>](https://imap.princeton.edu/)
93
+ [<img src="https://clarreo-pathfinder.larc.nasa.gov/wp-content/uploads/sites/133/2019/08/clarreo_pathfinder_mission_patch_design_v4_decal_1_24_17.png" alt="CLARREO" height="140"/>](https://clarreo-pathfinder.larc.nasa.gov/)
94
+ [<img src="https://lasp.colorado.edu/libera/files/2021/02/Libera-Logo-HiRes.png" alt="Libera" height="70"/>](https://lasp.colorado.edu/libera/)
95
+ [<img src="https://lasp.colorado.edu/ctim/files/2023/01/CTIM_LOGO_350x100_centered_transparent.png" alt="CTIM-FD" height="70"/>](https://lasp.colorado.edu/ctim/)
96
+ [<img src="https://mms.gsfc.nasa.gov/images/promotional_materials/mms_decal_rgb_4in_trabk_72dpi.png" alt="MMS-FEEPS" height="140"/>](https://lasp.colorado.edu/mms/sdc/public/)
97
+
@@ -0,0 +1,47 @@
1
+ # Space Packet Parser
2
+
3
+ [![Conda](https://img.shields.io/conda/vn/lasp/space_packet_parser?color=42B029&logo=anaconda&logoColor=white)](https://anaconda.org/lasp/space_packet_parser)
4
+ [![PyPI](https://img.shields.io/pypi/v/space_packet_parser?color=blue&logo=pypi&logoColor=white)](https://pypi.org/project/space-packet-parser/)
5
+ [![DOI](https://zenodo.org/badge/612253190.svg)](https://doi.org/10.5281/zenodo.7735001)
6
+
7
+ [![Test Status](https://github.com/lasp/space_packet_parser/actions/workflows/tests.yml/badge.svg)](https://github.com/lasp/space_packet_parser/actions/workflows/tests.yml)
8
+ [![codecov](https://codecov.io/gh/lasp/space_packet_parser/graph/badge.svg?token=VUFIN94O05)](https://codecov.io/gh/lasp/space_packet_parser)
9
+
10
+ **Documentation:** [https://space-packet-parser.readthedocs.io/en/latest/](https://space-packet-parser.readthedocs.io/en/latest/)
11
+
12
+ | **Stable ReadTheDocs Build** | [![Stable Docs](https://readthedocs.org/projects/space-packet-parser/badge/?version=stable)](https://app.readthedocs.org/projects/space-packet-parser/builds/?version__slug=stable) |
13
+ |------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
14
+ | **Latest ReadTheDocs Build** | [!["Latest Docs"](https://readthedocs.org/projects/space-packet-parser/badge/?version=latest)](https://app.readthedocs.org/projects/space-packet-parser/builds/?version__slug=latest) |
15
+
16
+
17
+ Space Packet Parser is a package for decoding CCSDS telemetry packets according to an XTCE packet structure definition.
18
+ It is based on the UML model of the XTCE spec and aims to support all but the most esoteric elements of the
19
+ XTCE telemetry packet specification.
20
+
21
+ Resources:
22
+ - [XTCE (Green Book - Informational Report)](https://public.ccsds.org/Pubs/660x2g2.pdf)
23
+ - [XTCE Element Description (Green Book - Informational Report)](https://public.ccsds.org/Pubs/660x1g2.pdf)
24
+ - [XTCE (Blue Book - Recommended Standard)](https://public.ccsds.org/Pubs/660x0b2.pdf)
25
+
26
+ ## Installation
27
+ From PyPI
28
+ ```bash
29
+ pip install space_packet_parser
30
+ ```
31
+
32
+ From Anaconda (distributed on the `lasp` channel):
33
+ ```bash
34
+ conda install -c lasp space_packet_parser
35
+ ```
36
+
37
+ ## Proud Member of the Python in Heliophysics Community (PyHC)
38
+
39
+ [<img src="https://heliopython.org/img/PyHC%20header%20logo%20500x500.png" alt="PyHC" height="70"/>](https://heliopython.org)
40
+
41
+ ## Missions using Space Packet Parser
42
+
43
+ [<img src="https://imap.princeton.edu/sites/g/files/toruqf7171/files/imap-mark-hor-multicolor-dark.png" alt="IMAP" height="70"/>](https://imap.princeton.edu/)
44
+ [<img src="https://clarreo-pathfinder.larc.nasa.gov/wp-content/uploads/sites/133/2019/08/clarreo_pathfinder_mission_patch_design_v4_decal_1_24_17.png" alt="CLARREO" height="140"/>](https://clarreo-pathfinder.larc.nasa.gov/)
45
+ [<img src="https://lasp.colorado.edu/libera/files/2021/02/Libera-Logo-HiRes.png" alt="Libera" height="70"/>](https://lasp.colorado.edu/libera/)
46
+ [<img src="https://lasp.colorado.edu/ctim/files/2023/01/CTIM_LOGO_350x100_centered_transparent.png" alt="CTIM-FD" height="70"/>](https://lasp.colorado.edu/ctim/)
47
+ [<img src="https://mms.gsfc.nasa.gov/images/promotional_materials/mms_decal_rgb_4in_trabk_72dpi.png" alt="MMS-FEEPS" height="140"/>](https://lasp.colorado.edu/mms/sdc/public/)
@@ -0,0 +1,153 @@
1
+ [project]
2
+ name = "space_packet_parser"
3
+ version = "6.0.0dev1"
4
+ description = "A CCSDS telemetry packet decoding library based on the XTCE packet format description standard."
5
+ license = { text = "BSD-3-Clause" }
6
+ readme = "README.md"
7
+ requires-python = ">=3.9"
8
+ authors = [
9
+ { name = "Gavin Medley", email = "gavin.medley@lasp.colorado.edu" },
10
+ { name = "Greg Lucas", email = "greg.lucas@lasp.colorado.edu" },
11
+ { name = "Michael Chambliss", email = "michael.chambliss@lasp.colorado.edu" }
12
+ ]
13
+ maintainers = [
14
+ { name = "Gavin Medley", email = "gavin.medley@lasp.colorado.edu" },
15
+ { name = "Greg Lucas", email = "greg.lucas@lasp.colorado.edu" }
16
+ ]
17
+ keywords = [
18
+ "ccsds",
19
+ "xtce",
20
+ "space data systems",
21
+ "space packet protocol",
22
+ "packet parsing",
23
+ "lasp",
24
+ "university of colorado",
25
+ "data processing",
26
+ "data extraction",
27
+ "data manipulation",
28
+ "data transformation",
29
+ "data encoding",
30
+ "data decoding",
31
+ "packet inspection",
32
+ "binary data",
33
+ "python"
34
+ ]
35
+ classifiers = [
36
+ "Development Status :: 5 - Production/Stable",
37
+ "Intended Audience :: Science/Research",
38
+ "Intended Audience :: Developers",
39
+ "Topic :: Scientific/Engineering",
40
+ "Topic :: Software Development :: Libraries :: Python Modules",
41
+ "Programming Language :: Python :: 3",
42
+ "Operating System :: OS Independent",
43
+ "License :: OSI Approved :: BSD License"
44
+ ]
45
+ # These are the dependencies used for metadata when building the project
46
+ dependencies = [
47
+ "lxml>=4.8.0",
48
+ "click>=8.0",
49
+ "rich>=13.0"
50
+ ]
51
+
52
+ [project.urls]
53
+ repository = "https://github.com/lasp/space_packet_parser"
54
+ homepage = "https://github.com/lasp/space_packet_parser"
55
+ documentation = "https://space-packet-parser.readthedocs.io"
56
+
57
+ [project.scripts]
58
+ spp = "space_packet_parser.cli:spp"
59
+
60
+ # These are the project extras used for metadata when building the project
61
+ [project.optional-dependencies]
62
+ xarray = [
63
+ "xarray>2024.0.0",
64
+ "numpy>=2.0.0"
65
+ ]
66
+ examples = [
67
+ "matplotlib>=3.4"
68
+ ]
69
+ test = [
70
+ "pre-commit",
71
+ "pytest",
72
+ "pytest-benchmark",
73
+ "pytest-randomly",
74
+ "pytest-cov",
75
+ "pyyaml", # needed by check_metadata.py
76
+ "ruff",
77
+ "tomli", # for support of python<3.11 toml parsing in check_metadata.py
78
+ "xarray", # for testing extra
79
+ "numpy" # for testing extra
80
+ ]
81
+ docs = [
82
+ "pyyaml",
83
+ "sphinx",
84
+ "myst-parser",
85
+ "sphinx-autoapi",
86
+ "sphinx-rtd-theme"
87
+ ]
88
+
89
+ [tool.poetry]
90
+ packages = [
91
+ { include = "space_packet_parser" }
92
+ ]
93
+ include = [
94
+ "LICENSE.txt",
95
+ "CITATION.cff"
96
+ ]
97
+
98
+ [tool.poetry.group.xarray.dependencies]
99
+ xarray = ">2024.0.0"
100
+ numpy = ">=2.0.0"
101
+
102
+ [tool.poetry.group.examples.dependencies]
103
+ matplotlib = ">=3.4"
104
+
105
+ [tool.poetry.group.test.dependencies]
106
+ pre-commit = "*"
107
+ pytest = "*"
108
+ pytest-benchmark = "*"
109
+ pytest-randomly = "*"
110
+ pytest-cov = "*"
111
+ pyyaml = "*"
112
+ ruff = "*"
113
+ tomli = "*"
114
+
115
+ [tool.poetry.group.docs.dependencies]
116
+ pyyaml = "*"
117
+ sphinx = "*"
118
+ myst-parser = "*"
119
+ sphinx-autoapi = "*"
120
+ sphinx-rtd-theme = "*"
121
+
122
+ [build-system]
123
+ requires = ["poetry-core>=2.0.1"]
124
+ build-backend = "poetry.core.masonry.api"
125
+
126
+ [tool.pytest.ini_options]
127
+ filterwarnings = [
128
+ "error",
129
+ "ignore:You are encoding a BooleanParameterType:UserWarning"
130
+ ]
131
+
132
+ # Note: Ruff uses the "nearest" configuration file at runtime so configurations may be overridden
133
+ # e.g. see ruff.toml in the tests directory
134
+ [tool.ruff]
135
+ line-length = 120
136
+ extend-include = [
137
+ "space_packet_parser/**/*.py",
138
+ "examples/**/*.py",
139
+ "tests/**/*.py"
140
+ ]
141
+ extend-exclude = []
142
+
143
+ [tool.ruff.lint]
144
+ select = [
145
+ "E", # pycodestyle errors
146
+ "W", # pycodestyle warnings
147
+ "F", # pyflakes
148
+ "I", # isort import sorting
149
+ "S", # flake8-bandit security
150
+ "PT", # flake8-pytest-style
151
+ "UP" # pyupgrade syntax upgrader
152
+ ]
153
+ per-file-ignores = { "tests/*" = ["S"] }
@@ -0,0 +1,20 @@
1
+ """Space Packet Parser"""
2
+ from pathlib import Path
3
+ from typing import Union
4
+
5
+ from space_packet_parser.xtce.definitions import XtcePacketDefinition
6
+
7
+
8
+ def load_xml(filename: Union[str, Path]) -> XtcePacketDefinition:
9
+ """Create an XtcePacketDefinition object from an XTCE XML file
10
+
11
+ Parameters
12
+ ----------
13
+ filename : Union[str, Path]
14
+ XTCE XML file
15
+
16
+ Returns
17
+ -------
18
+ : definitions.XtcePacketDefinition
19
+ """
20
+ return XtcePacketDefinition.from_xtce(filename)
@@ -0,0 +1,189 @@
1
+ #!/usr/bin/env python3
2
+
3
+ """Command line interface to the Space Packet Parsing library.
4
+
5
+ This module serves as a command line utility to inspect and process packet data.
6
+
7
+ Use
8
+ ---
9
+ spp <command> [<args>]
10
+ spp --help
11
+ spp --describe <packet_file>
12
+ """
13
+ import logging
14
+ from pathlib import Path
15
+ from typing import Optional
16
+
17
+ import click
18
+ from rich import pretty
19
+ from rich.console import Console
20
+ from rich.logging import RichHandler
21
+ from rich.panel import Panel
22
+ from rich.table import Table
23
+ from rich.tree import Tree
24
+
25
+ from space_packet_parser.packets import ccsds_generator
26
+ from space_packet_parser.xtce.definitions import DEFAULT_ROOT_CONTAINER, XtcePacketDefinition
27
+
28
+ # Initialize a console instance for rich output
29
+ console = Console()
30
+
31
+ # Maximum number of rows to display
32
+ MAX_ROWS = 10
33
+ HEAD_ROWS = 5
34
+ # Standard names for header field values when inspecting packets without an XTCE definition
35
+ DISPLAY_HEADER_FIELDS = ("VER", "TYPE", "SHFLG", "APID", "SEQFLG", "SEQCNT", "PKTLEN")
36
+
37
+
38
+ @click.group(context_settings={'show_default': True})
39
+ @click.version_option(message="Space Packet Parser CLI (%(prog)s) v%(version)s")
40
+ @click.option("-v", "--verbose", is_flag=True, help="Enable verbose output (DEBUG logging)")
41
+ @click.option("-q", "--quiet", is_flag=True, help="Disable logging output entirely")
42
+ @click.option("--log-level", default="INFO", help="Log level, e.g. WARNING, INFO, DEBUG. Ignored if -q or -v is set.")
43
+ def spp(verbose, quiet, log_level):
44
+ """Command line utility for working with CCSDS packets."""
45
+ # Set logging level
46
+ loglevel = logging.getLevelNamesMapping()[log_level]
47
+ if verbose:
48
+ loglevel = logging.DEBUG
49
+ elif quiet:
50
+ loglevel = logging.CRITICAL
51
+
52
+ # Configure logging with RichHandler for colorized output
53
+ logging.basicConfig(
54
+ level=loglevel,
55
+ format="%(message)s",
56
+ datefmt="[%X]",
57
+ handlers=[RichHandler(console=console, rich_tracebacks=True)]
58
+ )
59
+ logging.getLogger("rich").setLevel(loglevel)
60
+
61
+
62
+ @spp.command()
63
+ @click.argument("file_path", type=click.Path(exists=True, path_type=Path))
64
+ @click.option("--sequence-containers", is_flag=True, help="Display sequence containers")
65
+ @click.option("--parameters", is_flag=True, help="Display parameters")
66
+ @click.option("--parameter-types", is_flag=True, help="Display parameter types")
67
+ @click.option("--root-container", default=DEFAULT_ROOT_CONTAINER,
68
+ help=f"Name of root SequenceContainer element. Default is {DEFAULT_ROOT_CONTAINER}.")
69
+ def describe_xtce(
70
+ file_path: Path,
71
+ sequence_containers: bool,
72
+ parameters: bool,
73
+ parameter_types: bool,
74
+ root_container: str
75
+ ) -> None:
76
+ """Describe the contents and structure of an XTCE packet definition file."""
77
+ logging.debug(f"Describing XTCE file: {file_path}")
78
+ definition = XtcePacketDefinition.from_xtce(file_path, root_container_name=root_container)
79
+ tree = Tree(definition.root_container_name)
80
+
81
+ # Recursively add nodes based on the inheritors of each container
82
+ def add_nodes(tree_node, parent_key):
83
+ children = definition.containers[parent_key].inheritors
84
+ for child_key in children:
85
+ # Create a new child node (name + comparisons used to distinguish between containers)
86
+ child_node = tree_node.add(
87
+ f"{child_key} {definition.containers[child_key].restriction_criteria}")
88
+ # Recursively add any children of this child
89
+ add_nodes(child_node, child_key)
90
+
91
+ add_nodes(tree, definition.root_container_name)
92
+
93
+ console.print(Panel(tree, title="XTCE Container Layout", border_style="cyan", expand=False))
94
+ if sequence_containers:
95
+ console.print(Panel(pretty.Pretty(definition.containers),
96
+ title=f"Sequence Containers ({len(definition.containers)})",
97
+ border_style="blue", expand=False))
98
+ if parameters:
99
+ console.print(Panel(pretty.Pretty(definition.parameters),
100
+ title=f"Parameters ({len(definition.parameters)})",
101
+ border_style="green", expand=False))
102
+ if parameter_types:
103
+ console.print(Panel(pretty.Pretty(definition.parameter_types),
104
+ title=f"Parameter Types ({len(definition.parameter_types)})",
105
+ border_style="magenta", expand=False))
106
+
107
+
108
+ @spp.command()
109
+ @click.argument("file_path", type=click.Path(exists=True, path_type=Path))
110
+ # TODO: Allow multiple file paths, ordered
111
+ # TODO: Allow filtering by header values
112
+ def describe_packets(file_path: Path) -> None:
113
+ """Describe the header contents of a packet file, no packet definition required."""
114
+ logging.debug(f"Describing packet file: {file_path}")
115
+ with open(file_path, "rb") as f:
116
+ packets = list(ccsds_generator(f))
117
+
118
+ npackets = len(packets)
119
+ if npackets == 0:
120
+ console.print(f"No packets found in {file_path}")
121
+ return
122
+
123
+ # Create table for packet data display
124
+ table = Table(title=f"[bold magenta]{file_path}: {npackets} packets[/bold magenta]",
125
+ show_header=True,
126
+ header_style="bold magenta")
127
+
128
+ # Add columns for header fields only
129
+ for key in DISPLAY_HEADER_FIELDS:
130
+ table.add_column(key)
131
+
132
+ # Determine rows to display (head and tail with ellipsis if necessary)
133
+ if npackets > MAX_ROWS:
134
+ packets_to_show = packets[:HEAD_ROWS] + packets[-HEAD_ROWS:]
135
+ else:
136
+ packets_to_show = packets
137
+
138
+ # Add rows to the table
139
+ for packet in packets_to_show[:HEAD_ROWS]:
140
+ table.add_row(*[str(value) for value in packet.header_values])
141
+
142
+ # Add ellipsis if there are more packets
143
+ if npackets > MAX_ROWS:
144
+ table.add_row(*["..." for _ in packets[0].header_values])
145
+
146
+ for packet in packets_to_show[-HEAD_ROWS:]:
147
+ table.add_row(*[str(value) for value in packet.header_values])
148
+
149
+ # Print the table
150
+ console.print(table, overflow="ellipsis")
151
+
152
+
153
+ @spp.command()
154
+ @click.argument("packet_file", type=click.Path(exists=True, path_type=Path))
155
+ @click.argument("definition_file", type=click.Path(exists=True, path_type=Path))
156
+ @click.option("--packet", type=int, default=None, help="Display the packet at the given index (0-indexed)")
157
+ @click.option("--max-items", type=int, default=20, help="Maximum number of items to display")
158
+ @click.option("--max-string", type=int, default=40, help="Maximum length of string data")
159
+ @click.option("--skip-header-bytes", type=int, default=0, help="Number of bytes to skip before each packet")
160
+ def parse(
161
+ packet_file: Path,
162
+ definition_file: Path,
163
+ packet: Optional[int],
164
+ max_items: int,
165
+ max_string: int,
166
+ skip_header_bytes: int
167
+ ) -> None:
168
+ """Parse a packet file using the provided XTCE definition."""
169
+ logging.debug(f"Parsing packet file: {packet_file}")
170
+ logging.debug(f"Using packet definition file: {definition_file}")
171
+
172
+ with open(packet_file, "rb") as f:
173
+ packets = list(
174
+ XtcePacketDefinition.from_xtce(
175
+ definition_file
176
+ ).packet_generator(
177
+ f,
178
+ skip_header_bytes=skip_header_bytes
179
+ )
180
+ )
181
+
182
+ if packet is not None:
183
+ if packet > len(packets):
184
+ console.print(f"Packet index {packet} out of range with only {len(packets)} packets in the file")
185
+ return
186
+ packets = packets[packet]
187
+ # Limit the number of packets and variables printed
188
+ # also limit the length of strings (binary data can be long)
189
+ pretty.pprint(packets, indent_guides=False, max_length=max_items, max_string=max_string)