space-packet-parser 4.2.0__tar.gz → 5.0.0__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.
- space_packet_parser-5.0.0/CITATION.cff +33 -0
- {space_packet_parser-4.2.0 → space_packet_parser-5.0.0}/PKG-INFO +5 -7
- {space_packet_parser-4.2.0 → space_packet_parser-5.0.0}/README.md +2 -3
- {space_packet_parser-4.2.0 → space_packet_parser-5.0.0}/pyproject.toml +4 -3
- space_packet_parser-5.0.0/space_packet_parser/calibrators.py +361 -0
- space_packet_parser-5.0.0/space_packet_parser/comparisons.py +553 -0
- space_packet_parser-5.0.0/space_packet_parser/definitions.py +653 -0
- space_packet_parser-5.0.0/space_packet_parser/encodings.py +852 -0
- space_packet_parser-5.0.0/space_packet_parser/exceptions.py +32 -0
- space_packet_parser-5.0.0/space_packet_parser/packets.py +247 -0
- space_packet_parser-5.0.0/space_packet_parser/parameters.py +536 -0
- space_packet_parser-4.2.0/CITATION.cff +0 -32
- space_packet_parser-4.2.0/space_packet_parser/csvdef.py +0 -270
- space_packet_parser-4.2.0/space_packet_parser/parser.py +0 -586
- space_packet_parser-4.2.0/space_packet_parser/xtcedef.py +0 -2511
- {space_packet_parser-4.2.0 → space_packet_parser-5.0.0}/LICENSE.txt +0 -0
- {space_packet_parser-4.2.0 → space_packet_parser-5.0.0}/space_packet_parser/__init__.py +0 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
title: 'space_packet_parser'
|
|
3
|
+
type: software
|
|
4
|
+
version: '5.0.0'
|
|
5
|
+
description: A CCSDS telemetry packet decoding library based on the XTCE packet format description standard.
|
|
6
|
+
license: BSD-3-Clause
|
|
7
|
+
abstract: The Space Packet Parser Python library is a generalized, configurable packet decoding library for CCSDS telemetry
|
|
8
|
+
packets based on the XTCE standard for packet structure definitions. It supports complex and polymorphic
|
|
9
|
+
packet structures, using the XTCE UML model to represent dynamic inheritance structures and conditionals
|
|
10
|
+
based on previously parsed data fields. The core functionality of the library is the
|
|
11
|
+
configuration of an XtcePacketDefinition object from a static XTCE XML document. The configured definition
|
|
12
|
+
object can then iterate over binary data, parsing and yielding parsed Packet objects containing the decoded
|
|
13
|
+
packet field values in a generator pattern. The binary data may originate from an in-memory binary object,
|
|
14
|
+
a buffered file reader opened in binary mode, or a python socket object; in every case, a small buffer is
|
|
15
|
+
used to read chunks of data to reduce memory footprint.
|
|
16
|
+
The space_packet_parser library supports robust error handling, is capable of handling malformed
|
|
17
|
+
packet structures, and can dynamically parse muxed APID packet streams.
|
|
18
|
+
authors:
|
|
19
|
+
- email: gavin.medley@lasp.colorado.edu
|
|
20
|
+
name: Gavin Medley
|
|
21
|
+
orcid: "0000-0002-3520-9715"
|
|
22
|
+
- email: michael.chambliss@lasp.colorado.edu
|
|
23
|
+
name: Michael Chambliss
|
|
24
|
+
orcid: "0009-0003-7493-0542"
|
|
25
|
+
- email: greg.lucas@lasp.colorado.edu
|
|
26
|
+
name: Greg Lucas
|
|
27
|
+
orcid: "0000-0003-1331-1863"
|
|
28
|
+
maintainers:
|
|
29
|
+
- email: gavin.medley@lasp.colorado.edu
|
|
30
|
+
name: Gavin Medley
|
|
31
|
+
orcid: "0000-0002-3520-9715"
|
|
32
|
+
repository-code: "https://github.com/medley56/space_packet_parser"
|
|
33
|
+
url: "https://space-packet-parser.readthedocs.io"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: space_packet_parser
|
|
3
|
-
Version:
|
|
3
|
+
Version: 5.0.0
|
|
4
4
|
Summary: A CCSDS telemetry packet decoding library based on the XTCE packet format description standard.
|
|
5
5
|
Home-page: https://space-packet-parser.readthedocs.io
|
|
6
6
|
License: BSD-3-Clause
|
|
@@ -9,28 +9,26 @@ Author: Gavin Medley
|
|
|
9
9
|
Author-email: gavin.medley@lasp.colorado.edu
|
|
10
10
|
Maintainer: Gavin Medley
|
|
11
11
|
Maintainer-email: gavin.medley@lasp.colorado.edu
|
|
12
|
-
Requires-Python: >=3.
|
|
12
|
+
Requires-Python: >=3.9
|
|
13
13
|
Classifier: License :: OSI Approved :: BSD License
|
|
14
14
|
Classifier: Programming Language :: Python :: 3
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.9
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.10
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
-
Requires-Dist:
|
|
19
|
+
Requires-Dist: lxml (>=4.8.0)
|
|
21
20
|
Project-URL: Repository, https://github.com/medley56/space_packet_parser
|
|
22
21
|
Description-Content-Type: text/markdown
|
|
23
22
|
|
|
24
23
|
# Space Packet Parser
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
[](https://github.com/medley56/space_packet_parser/actions/workflows/tests.yml)
|
|
25
|
+
[](https://github.com/medley56/space_packet_parser/actions/workflows/pr_tests.yml)
|
|
28
26
|
[](https://readthedocs.org/projects/space-packet-parser/)
|
|
29
27
|
[](https://doi.org/10.5281/zenodo.7735001)
|
|
30
28
|
|
|
31
29
|
Documentation: [https://space-packet-parser.readthedocs.io/en/latest/](https://space-packet-parser.readthedocs.io/en/latest/)
|
|
32
30
|
|
|
33
|
-
Space Packet Parser is a package for decoding CCSDS telemetry packets according to an XTCE
|
|
31
|
+
Space Packet Parser is a package for decoding CCSDS telemetry packets according to an XTCE packet structure definition.
|
|
34
32
|
It is based on the UML model of the XTCE spec and aims to support all but the most esoteric elements of the
|
|
35
33
|
XTCE telemetry packet specification.
|
|
36
34
|
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
# Space Packet Parser
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
[](https://github.com/medley56/space_packet_parser/actions/workflows/tests.yml)
|
|
3
|
+
[](https://github.com/medley56/space_packet_parser/actions/workflows/pr_tests.yml)
|
|
5
4
|
[](https://readthedocs.org/projects/space-packet-parser/)
|
|
6
5
|
[](https://doi.org/10.5281/zenodo.7735001)
|
|
7
6
|
|
|
8
7
|
Documentation: [https://space-packet-parser.readthedocs.io/en/latest/](https://space-packet-parser.readthedocs.io/en/latest/)
|
|
9
8
|
|
|
10
|
-
Space Packet Parser is a package for decoding CCSDS telemetry packets according to an XTCE
|
|
9
|
+
Space Packet Parser is a package for decoding CCSDS telemetry packets according to an XTCE packet structure definition.
|
|
11
10
|
It is based on the UML model of the XTCE spec and aims to support all but the most esoteric elements of the
|
|
12
11
|
XTCE telemetry packet specification.
|
|
13
12
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "space_packet_parser"
|
|
3
|
-
version = "
|
|
3
|
+
version = "5.0.0"
|
|
4
4
|
description = "A CCSDS telemetry packet decoding library based on the XTCE packet format description standard."
|
|
5
5
|
license = "BSD-3-Clause"
|
|
6
6
|
readme = "README.md"
|
|
@@ -35,10 +35,11 @@ keywords = [
|
|
|
35
35
|
]
|
|
36
36
|
|
|
37
37
|
[tool.poetry.dependencies]
|
|
38
|
-
python = ">=3.
|
|
39
|
-
|
|
38
|
+
python = ">=3.9"
|
|
39
|
+
lxml = ">=4.8.0"
|
|
40
40
|
|
|
41
41
|
[tool.poetry.group.dev.dependencies]
|
|
42
|
+
pycodestyle = "*"
|
|
42
43
|
pylint = "*"
|
|
43
44
|
pytest = "*"
|
|
44
45
|
pytest-randomly = "*"
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
|
|
2
|
+
"""Calibrator definitions"""
|
|
3
|
+
from abc import ABCMeta, abstractmethod
|
|
4
|
+
from collections import namedtuple
|
|
5
|
+
from typing import List, Union
|
|
6
|
+
|
|
7
|
+
import lxml.etree as ElementTree
|
|
8
|
+
|
|
9
|
+
from space_packet_parser.exceptions import CalibrationError
|
|
10
|
+
from space_packet_parser import comparisons
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Calibrator(comparisons.AttrComparable, metaclass=ABCMeta):
|
|
14
|
+
"""Abstract base class for XTCE calibrators"""
|
|
15
|
+
|
|
16
|
+
@classmethod
|
|
17
|
+
@abstractmethod
|
|
18
|
+
def from_calibrator_xml_element(cls, element: ElementTree.Element, ns: dict) -> 'Calibrator':
|
|
19
|
+
"""Abstract classmethod to create a default_calibrator object from an XML element.
|
|
20
|
+
|
|
21
|
+
Parameters
|
|
22
|
+
----------
|
|
23
|
+
element : ElementTree.Element
|
|
24
|
+
XML element
|
|
25
|
+
ns : dict
|
|
26
|
+
XML namespace dict
|
|
27
|
+
|
|
28
|
+
Returns
|
|
29
|
+
-------
|
|
30
|
+
cls
|
|
31
|
+
"""
|
|
32
|
+
return NotImplemented
|
|
33
|
+
|
|
34
|
+
@abstractmethod
|
|
35
|
+
def calibrate(self, uncalibrated_value: Union[int, float]) -> Union[int, float]:
|
|
36
|
+
"""Takes an integer-encoded or float-encoded value and returns a calibrated version.
|
|
37
|
+
|
|
38
|
+
Parameters
|
|
39
|
+
----------
|
|
40
|
+
uncalibrated_value : Union[int, float]
|
|
41
|
+
The uncalibrated, raw encoded value
|
|
42
|
+
|
|
43
|
+
Returns
|
|
44
|
+
-------
|
|
45
|
+
: Union[int, float]
|
|
46
|
+
Calibrated value
|
|
47
|
+
"""
|
|
48
|
+
raise NotImplementedError
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
SplinePoint = namedtuple('SplinePoint', ['raw', 'calibrated'])
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class SplineCalibrator(Calibrator):
|
|
55
|
+
"""<xtce:SplineCalibrator>"""
|
|
56
|
+
_order_mapping = {'zero': 0, 'first': 1, 'second': 2, 'third': 3}
|
|
57
|
+
|
|
58
|
+
def __init__(self, points: list, order: int = 0, extrapolate: bool = False):
|
|
59
|
+
"""Constructor
|
|
60
|
+
|
|
61
|
+
Parameters
|
|
62
|
+
----------
|
|
63
|
+
points : list
|
|
64
|
+
List of SplinePoint objects. These points are sorted by their raw values on instantiation.
|
|
65
|
+
order : int
|
|
66
|
+
Spline order. Only zero and first order splines are supported.
|
|
67
|
+
extrapolate : bool
|
|
68
|
+
Whether or not to allow extrapolation outside the bounds of the spline points. If False, raises an
|
|
69
|
+
error when calibrate is called for a query point outside the bounds of the spline points.
|
|
70
|
+
"""
|
|
71
|
+
if order > 1:
|
|
72
|
+
raise NotImplementedError("Spline calibrators of order > 1 are not implemented. Consider contributing "
|
|
73
|
+
"if you need this functionality. It does not appear to be commonly used but "
|
|
74
|
+
"it probably would not be too hard to implement.")
|
|
75
|
+
self.order = order
|
|
76
|
+
self.points = sorted(points, key=lambda point: point.raw) # Sort points before storing
|
|
77
|
+
self.extrapolate = extrapolate
|
|
78
|
+
|
|
79
|
+
@classmethod
|
|
80
|
+
def from_calibrator_xml_element(cls, element: ElementTree.Element, ns: dict) -> 'SplineCalibrator':
|
|
81
|
+
"""Create a spline default_calibrator object from an <xtce:SplineCalibrator> XML element."""
|
|
82
|
+
point_elements = element.findall('xtce:SplinePoint', ns)
|
|
83
|
+
spline_points = [
|
|
84
|
+
SplinePoint(raw=float(p.attrib['raw']), calibrated=float(p.attrib['calibrated']))
|
|
85
|
+
for p in point_elements
|
|
86
|
+
]
|
|
87
|
+
order = int(cls._order_mapping[element.attrib['order']]) if 'order' in element.attrib else 0
|
|
88
|
+
extrapolate = element.attrib['extrapolate'].lower() == 'true' if 'extrapolate' in element.attrib else False
|
|
89
|
+
return cls(order=order, points=spline_points, extrapolate=extrapolate)
|
|
90
|
+
|
|
91
|
+
def calibrate(self, uncalibrated_value: float) -> float:
|
|
92
|
+
"""Take an integer-encoded value and returns a calibrated version according to the spline points.
|
|
93
|
+
|
|
94
|
+
Parameters
|
|
95
|
+
----------
|
|
96
|
+
uncalibrated_value : float
|
|
97
|
+
Query point.
|
|
98
|
+
|
|
99
|
+
Returns
|
|
100
|
+
-------
|
|
101
|
+
: float
|
|
102
|
+
Calibrated value
|
|
103
|
+
"""
|
|
104
|
+
if self.order == 0:
|
|
105
|
+
return self._zero_order_spline_interp(uncalibrated_value)
|
|
106
|
+
if self.order == 1:
|
|
107
|
+
return self._first_order_spline_interp(uncalibrated_value)
|
|
108
|
+
raise NotImplementedError(f"SplineCalibrator is not implemented for spline order {self.order}.")
|
|
109
|
+
|
|
110
|
+
def _zero_order_spline_interp(self, query_point: float) -> float:
|
|
111
|
+
"""Abstraction for zero order spline interpolation. If extrapolation is set to a truthy value, we use
|
|
112
|
+
the nearest point to extrapolate outside the range of the given spline points. Within the range of spline
|
|
113
|
+
points, we use nearest lower point interpolation.
|
|
114
|
+
|
|
115
|
+
Parameters
|
|
116
|
+
----------
|
|
117
|
+
query_point : float
|
|
118
|
+
Query point.
|
|
119
|
+
|
|
120
|
+
Returns
|
|
121
|
+
-------
|
|
122
|
+
: float
|
|
123
|
+
Calibrated value.
|
|
124
|
+
"""
|
|
125
|
+
x = [float(p.raw) for p in self.points]
|
|
126
|
+
y = [float(p.calibrated) for p in self.points]
|
|
127
|
+
if min(x) <= query_point <= max(x):
|
|
128
|
+
first_greater = [p.raw > query_point for p in self.points].index(True)
|
|
129
|
+
return y[first_greater - 1]
|
|
130
|
+
if query_point > max(x) and self.extrapolate:
|
|
131
|
+
return y[-1]
|
|
132
|
+
if query_point < min(x) and self.extrapolate:
|
|
133
|
+
return y[0]
|
|
134
|
+
raise CalibrationError(f"Extrapolation is set to a falsy value ({self.extrapolate}) but query value "
|
|
135
|
+
f"{query_point} falls outside the range of spline points {self.points}")
|
|
136
|
+
|
|
137
|
+
def _first_order_spline_interp(self, query_point: float) -> float:
|
|
138
|
+
"""Abstraction for first order spline interpolation. If extrapolation is set to a truthy value, we use the
|
|
139
|
+
end points to make a linear function and use it to extrapolate.
|
|
140
|
+
|
|
141
|
+
Parameters
|
|
142
|
+
----------
|
|
143
|
+
query_point : float
|
|
144
|
+
Query point.
|
|
145
|
+
|
|
146
|
+
Returns
|
|
147
|
+
-------
|
|
148
|
+
float
|
|
149
|
+
Calibrated value.
|
|
150
|
+
"""
|
|
151
|
+
|
|
152
|
+
def linear_func(xq: float, x0: float, x1: float, y0: float, y1: float) -> float:
|
|
153
|
+
"""Evaluate a linear function through points (x0, y0), (x1, y1) at point xq
|
|
154
|
+
|
|
155
|
+
Parameters
|
|
156
|
+
----------
|
|
157
|
+
xq : float
|
|
158
|
+
x0 : float
|
|
159
|
+
x1 : float
|
|
160
|
+
y0 : float
|
|
161
|
+
y1 : float
|
|
162
|
+
|
|
163
|
+
Returns
|
|
164
|
+
-------
|
|
165
|
+
yq : float
|
|
166
|
+
Interpolated point
|
|
167
|
+
"""
|
|
168
|
+
slope = (y1 - y0) / (x1 - x0)
|
|
169
|
+
return (slope * (xq - x0)) + y0
|
|
170
|
+
|
|
171
|
+
x = [p.raw for p in self.points]
|
|
172
|
+
y = [p.calibrated for p in self.points]
|
|
173
|
+
if min(x) <= query_point <= max(x):
|
|
174
|
+
first_greater = [p.raw > query_point for p in self.points].index(True)
|
|
175
|
+
return linear_func(query_point,
|
|
176
|
+
x[first_greater - 1], x[first_greater],
|
|
177
|
+
y[first_greater - 1], y[first_greater])
|
|
178
|
+
if query_point > max(x) and self.extrapolate:
|
|
179
|
+
return linear_func(query_point, x[-2], x[-1], y[-2], y[-1])
|
|
180
|
+
if query_point < min(x) and self.extrapolate:
|
|
181
|
+
return linear_func(query_point, x[0], x[1], y[0], y[1])
|
|
182
|
+
raise CalibrationError(f"Extrapolation is set to a falsy value ({self.extrapolate}) but query value "
|
|
183
|
+
f"{query_point} falls outside the range of spline points {self.points}")
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
PolynomialCoefficient = namedtuple('PolynomialCoefficient', ['coefficient', 'exponent'])
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
class PolynomialCalibrator(Calibrator):
|
|
190
|
+
"""<xtce:PolynomialCalibrator>"""
|
|
191
|
+
|
|
192
|
+
def __init__(self, coefficients: list):
|
|
193
|
+
"""Constructor
|
|
194
|
+
|
|
195
|
+
Parameters
|
|
196
|
+
----------
|
|
197
|
+
coefficients : list
|
|
198
|
+
List of PolynomialCoefficient objects that define the polynomial.
|
|
199
|
+
"""
|
|
200
|
+
self.coefficients = coefficients # Coefficients should be a list of PolynomialCoefficients
|
|
201
|
+
|
|
202
|
+
@classmethod
|
|
203
|
+
def from_calibrator_xml_element(cls, element: ElementTree.Element, ns: dict) -> 'PolynomialCalibrator':
|
|
204
|
+
"""Create a polynomial default_calibrator object from an <xtce:PolynomialCalibrator> XML element.
|
|
205
|
+
|
|
206
|
+
Parameters
|
|
207
|
+
----------
|
|
208
|
+
element : ElementTree.Element
|
|
209
|
+
<xtce:PolynomialCalibrator> XML element
|
|
210
|
+
ns : dict
|
|
211
|
+
Namespace dict
|
|
212
|
+
|
|
213
|
+
Returns
|
|
214
|
+
-------
|
|
215
|
+
|
|
216
|
+
"""
|
|
217
|
+
terms = element.findall('xtce:Term', ns)
|
|
218
|
+
coefficients = [
|
|
219
|
+
PolynomialCoefficient(coefficient=float(term.attrib['coefficient']), exponent=int(term.attrib['exponent']))
|
|
220
|
+
for term in terms
|
|
221
|
+
]
|
|
222
|
+
return cls(coefficients=coefficients)
|
|
223
|
+
|
|
224
|
+
def calibrate(self, uncalibrated_value: float) -> float:
|
|
225
|
+
"""Evaluate the polynomial defined by object coefficients at the specified uncalibrated point.
|
|
226
|
+
|
|
227
|
+
Parameters
|
|
228
|
+
----------
|
|
229
|
+
uncalibrated_value : float
|
|
230
|
+
Query point.
|
|
231
|
+
|
|
232
|
+
Returns
|
|
233
|
+
-------
|
|
234
|
+
float
|
|
235
|
+
Calibrated value
|
|
236
|
+
"""
|
|
237
|
+
return sum(a * (uncalibrated_value ** n) for a, n in self.coefficients)
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
class MathOperationCalibrator(Calibrator):
|
|
241
|
+
"""<xtce:MathOperationCalibrator>"""
|
|
242
|
+
err_msg = "The MathOperationCalibrator element is not supported in this package but pull requests are welcome!"
|
|
243
|
+
|
|
244
|
+
def __init__(self):
|
|
245
|
+
"""Constructor
|
|
246
|
+
|
|
247
|
+
Not implemented.
|
|
248
|
+
"""
|
|
249
|
+
raise NotImplementedError(self.err_msg)
|
|
250
|
+
|
|
251
|
+
@classmethod
|
|
252
|
+
def from_calibrator_xml_element(cls, element: ElementTree.Element, ns: dict) -> 'MathOperationCalibrator':
|
|
253
|
+
"""Create a math operation default_calibrator from an <xtce:MathOperationCalibrator> XML element."""
|
|
254
|
+
raise NotImplementedError(cls.err_msg)
|
|
255
|
+
|
|
256
|
+
def calibrate(self, uncalibrated_value: int):
|
|
257
|
+
"""Stub
|
|
258
|
+
|
|
259
|
+
Parameters
|
|
260
|
+
----------
|
|
261
|
+
uncalibrated_value
|
|
262
|
+
|
|
263
|
+
Returns
|
|
264
|
+
-------
|
|
265
|
+
|
|
266
|
+
"""
|
|
267
|
+
raise NotImplementedError(self.err_msg)
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
class ContextCalibrator(comparisons.AttrComparable):
|
|
271
|
+
"""<xtce:ContextCalibrator>"""
|
|
272
|
+
|
|
273
|
+
def __init__(self, match_criteria: list, calibrator: Calibrator):
|
|
274
|
+
"""Constructor
|
|
275
|
+
|
|
276
|
+
Parameters
|
|
277
|
+
----------
|
|
278
|
+
match_criteria : Union[MatchCriteria, list]
|
|
279
|
+
Object representing the logical operations to be performed to determine whether to use this
|
|
280
|
+
default_calibrator. This can be a Comparison, a ComparsonList (a list of Comparison objects),
|
|
281
|
+
a BooleanExpression (not supported), or a CustomAlgorithm (not supported)
|
|
282
|
+
calibrator : Calibrator
|
|
283
|
+
Calibrator to use if match criteria evaluates to True
|
|
284
|
+
"""
|
|
285
|
+
self.match_criteria = match_criteria
|
|
286
|
+
self.calibrator = calibrator
|
|
287
|
+
|
|
288
|
+
@staticmethod
|
|
289
|
+
def get_context_match_criteria(element: ElementTree.Element, ns: dict) -> List[comparisons.MatchCriteria]:
|
|
290
|
+
"""Parse contextual requirements from a Comparison, ComparisonList, or BooleanExpression
|
|
291
|
+
|
|
292
|
+
Parameters
|
|
293
|
+
----------
|
|
294
|
+
element : ElementTree.Element
|
|
295
|
+
<xtce:ContextCalibrator> XML element from which to parse the ContextCalibrator object.
|
|
296
|
+
ns : dict
|
|
297
|
+
Namespace dict for XML parsing
|
|
298
|
+
|
|
299
|
+
Returns
|
|
300
|
+
-------
|
|
301
|
+
: List[MatchCriteria]
|
|
302
|
+
List of Comparisons that can be evaluated to determine whether this calibrator should be used.
|
|
303
|
+
"""
|
|
304
|
+
context_match_element = element.find('xtce:ContextMatch', ns)
|
|
305
|
+
if context_match_element.find('xtce:ComparisonList', ns) is not None:
|
|
306
|
+
return [comparisons.Comparison.from_match_criteria_xml_element(el, ns)
|
|
307
|
+
for el in context_match_element.findall('xtce:ComparisonList/xtce:Comparison', ns)]
|
|
308
|
+
if context_match_element.find('xtce:Comparison', ns) is not None:
|
|
309
|
+
return [comparisons.Comparison.from_match_criteria_xml_element(
|
|
310
|
+
context_match_element.find('xtce:Comparison', ns), ns)]
|
|
311
|
+
if context_match_element.find('xtce:BooleanExpression', ns) is not None:
|
|
312
|
+
return [comparisons.BooleanExpression.from_match_criteria_xml_element(
|
|
313
|
+
context_match_element.find('xtce:BooleanExpression', ns), ns)]
|
|
314
|
+
raise NotImplementedError("ContextCalibrator doesn't contain Comparison, ComparisonList, or BooleanExpression. "
|
|
315
|
+
"This probably means the match criteria is an unsupported type "
|
|
316
|
+
"(CustomAlgorithm).")
|
|
317
|
+
|
|
318
|
+
@classmethod
|
|
319
|
+
def from_context_calibrator_xml_element(cls, element: ElementTree.Element, ns: dict) -> 'ContextCalibrator':
|
|
320
|
+
"""Create a ContextCalibrator object from an <xtce:ContextCalibrator> XML element
|
|
321
|
+
|
|
322
|
+
Parameters
|
|
323
|
+
----------
|
|
324
|
+
element : ElementTree.Element
|
|
325
|
+
<xtce:ContextCalibrator> XML element from which to parse the ContextCalibrator object.
|
|
326
|
+
ns : dict
|
|
327
|
+
Namespace dict for XML parsing
|
|
328
|
+
|
|
329
|
+
Returns
|
|
330
|
+
-------
|
|
331
|
+
: cls
|
|
332
|
+
"""
|
|
333
|
+
match_criteria = cls.get_context_match_criteria(element, ns)
|
|
334
|
+
|
|
335
|
+
if element.find('xtce:Calibrator/xtce:SplineCalibrator', ns) is not None:
|
|
336
|
+
calibrator = SplineCalibrator.from_calibrator_xml_element(
|
|
337
|
+
element.find('xtce:Calibrator/xtce:SplineCalibrator', ns), ns)
|
|
338
|
+
elif element.find('xtce:Calibrator/xtce:PolynomialCalibrator', ns):
|
|
339
|
+
calibrator = PolynomialCalibrator.from_calibrator_xml_element(
|
|
340
|
+
element.find('xtce:Calibrator/xtce:PolynomialCalibrator', ns), ns)
|
|
341
|
+
else:
|
|
342
|
+
raise NotImplementedError(
|
|
343
|
+
"Unsupported default_calibrator type. space_packet_parser only supports Polynomial and Spline"
|
|
344
|
+
"calibrators for ContextCalibrators.")
|
|
345
|
+
|
|
346
|
+
return cls(match_criteria=match_criteria, calibrator=calibrator)
|
|
347
|
+
|
|
348
|
+
def calibrate(self, parsed_value: Union[int, float]) -> Union[int, float]:
|
|
349
|
+
"""Wrapper method for the internal `Calibrator.calibrate`
|
|
350
|
+
|
|
351
|
+
Parameters
|
|
352
|
+
----------
|
|
353
|
+
parsed_value : Union[int, float]
|
|
354
|
+
Uncalibrated value.
|
|
355
|
+
|
|
356
|
+
Returns
|
|
357
|
+
-------
|
|
358
|
+
: Union[int, float]
|
|
359
|
+
Calibrated value
|
|
360
|
+
"""
|
|
361
|
+
return self.calibrator.calibrate(parsed_value)
|