oscura 0.8.0__py3-none-any.whl → 0.11.0__py3-none-any.whl
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.
- oscura/__init__.py +19 -19
- oscura/__main__.py +4 -0
- oscura/analyzers/__init__.py +2 -0
- oscura/analyzers/digital/extraction.py +2 -3
- oscura/analyzers/digital/quality.py +1 -1
- oscura/analyzers/digital/timing.py +1 -1
- oscura/analyzers/ml/signal_classifier.py +6 -0
- oscura/analyzers/patterns/__init__.py +66 -0
- oscura/analyzers/power/basic.py +3 -3
- oscura/analyzers/power/soa.py +1 -1
- oscura/analyzers/power/switching.py +3 -3
- oscura/analyzers/signal_classification.py +529 -0
- oscura/analyzers/signal_integrity/sparams.py +3 -3
- oscura/analyzers/statistics/basic.py +10 -7
- oscura/analyzers/validation.py +1 -1
- oscura/analyzers/waveform/measurements.py +200 -156
- oscura/analyzers/waveform/measurements_with_uncertainty.py +91 -35
- oscura/analyzers/waveform/spectral.py +182 -84
- oscura/api/dsl/commands.py +15 -6
- oscura/api/server/templates/base.html +137 -146
- oscura/api/server/templates/export.html +84 -110
- oscura/api/server/templates/home.html +248 -267
- oscura/api/server/templates/protocols.html +44 -48
- oscura/api/server/templates/reports.html +27 -35
- oscura/api/server/templates/session_detail.html +68 -78
- oscura/api/server/templates/sessions.html +62 -72
- oscura/api/server/templates/waveforms.html +54 -64
- oscura/automotive/__init__.py +1 -1
- oscura/automotive/can/session.py +1 -1
- oscura/automotive/dbc/generator.py +638 -23
- oscura/automotive/dtc/data.json +17 -102
- oscura/automotive/flexray/fibex.py +9 -1
- oscura/automotive/uds/decoder.py +99 -6
- oscura/cli/analyze.py +8 -2
- oscura/cli/batch.py +36 -5
- oscura/cli/characterize.py +18 -4
- oscura/cli/export.py +47 -5
- oscura/cli/main.py +2 -0
- oscura/cli/onboarding/wizard.py +10 -6
- oscura/cli/pipeline.py +585 -0
- oscura/cli/visualize.py +6 -4
- oscura/convenience.py +400 -32
- oscura/core/measurement_result.py +286 -0
- oscura/core/progress.py +1 -1
- oscura/core/schemas/device_mapping.json +2 -8
- oscura/core/schemas/packet_format.json +4 -24
- oscura/core/schemas/protocol_definition.json +2 -12
- oscura/core/types.py +232 -239
- oscura/correlation/multi_protocol.py +1 -1
- oscura/export/legacy/__init__.py +11 -0
- oscura/export/legacy/wav.py +75 -0
- oscura/exporters/__init__.py +19 -0
- oscura/exporters/wireshark.py +809 -0
- oscura/hardware/acquisition/file.py +5 -19
- oscura/hardware/acquisition/saleae.py +10 -10
- oscura/hardware/acquisition/socketcan.py +4 -6
- oscura/hardware/acquisition/synthetic.py +1 -5
- oscura/hardware/acquisition/visa.py +6 -6
- oscura/hardware/security/side_channel_detector.py +5 -508
- oscura/inference/message_format.py +686 -1
- oscura/jupyter/display.py +2 -2
- oscura/jupyter/magic.py +3 -3
- oscura/loaders/__init__.py +17 -12
- oscura/loaders/binary.py +1 -1
- oscura/loaders/chipwhisperer.py +1 -2
- oscura/loaders/configurable.py +1 -1
- oscura/loaders/csv_loader.py +2 -2
- oscura/loaders/hdf5_loader.py +1 -1
- oscura/loaders/lazy.py +6 -1
- oscura/loaders/mmap_loader.py +0 -1
- oscura/loaders/numpy_loader.py +8 -7
- oscura/loaders/preprocessing.py +3 -5
- oscura/loaders/rigol.py +21 -7
- oscura/loaders/sigrok.py +2 -5
- oscura/loaders/tdms.py +3 -2
- oscura/loaders/tektronix.py +38 -32
- oscura/loaders/tss.py +20 -27
- oscura/loaders/validation.py +17 -10
- oscura/loaders/vcd.py +13 -8
- oscura/loaders/wav.py +1 -6
- oscura/pipeline/__init__.py +76 -0
- oscura/pipeline/handlers/__init__.py +165 -0
- oscura/pipeline/handlers/analyzers.py +1045 -0
- oscura/pipeline/handlers/decoders.py +899 -0
- oscura/pipeline/handlers/exporters.py +1103 -0
- oscura/pipeline/handlers/filters.py +891 -0
- oscura/pipeline/handlers/loaders.py +640 -0
- oscura/pipeline/handlers/transforms.py +768 -0
- oscura/reporting/formatting/measurements.py +55 -14
- oscura/reporting/templates/enhanced/protocol_re.html +504 -503
- oscura/sessions/legacy.py +49 -1
- oscura/side_channel/__init__.py +38 -57
- oscura/utils/builders/signal_builder.py +5 -5
- oscura/utils/comparison/compare.py +7 -9
- oscura/utils/comparison/golden.py +1 -1
- oscura/utils/filtering/convenience.py +2 -2
- oscura/utils/math/arithmetic.py +38 -62
- oscura/utils/math/interpolation.py +20 -20
- oscura/utils/pipeline/__init__.py +4 -17
- oscura/utils/progressive.py +1 -4
- oscura/utils/triggering/edge.py +1 -1
- oscura/utils/triggering/pattern.py +2 -2
- oscura/utils/triggering/pulse.py +2 -2
- oscura/utils/triggering/window.py +3 -3
- oscura/validation/hil_testing.py +11 -11
- oscura/visualization/__init__.py +46 -284
- oscura/visualization/batch.py +72 -433
- oscura/visualization/plot.py +542 -53
- oscura/visualization/styles.py +184 -318
- oscura/workflows/batch/advanced.py +1 -1
- oscura/workflows/batch/aggregate.py +12 -9
- oscura/workflows/complete_re.py +251 -23
- oscura/workflows/digital.py +27 -4
- oscura/workflows/multi_trace.py +136 -17
- oscura/workflows/waveform.py +11 -6
- oscura-0.11.0.dist-info/METADATA +460 -0
- {oscura-0.8.0.dist-info → oscura-0.11.0.dist-info}/RECORD +120 -145
- oscura/side_channel/dpa.py +0 -1025
- oscura/utils/optimization/__init__.py +0 -19
- oscura/utils/optimization/parallel.py +0 -443
- oscura/utils/optimization/search.py +0 -532
- oscura/utils/pipeline/base.py +0 -338
- oscura/utils/pipeline/composition.py +0 -248
- oscura/utils/pipeline/parallel.py +0 -449
- oscura/utils/pipeline/pipeline.py +0 -375
- oscura/utils/search/__init__.py +0 -16
- oscura/utils/search/anomaly.py +0 -424
- oscura/utils/search/context.py +0 -294
- oscura/utils/search/pattern.py +0 -288
- oscura/utils/storage/__init__.py +0 -61
- oscura/utils/storage/database.py +0 -1166
- oscura/visualization/accessibility.py +0 -526
- oscura/visualization/annotations.py +0 -371
- oscura/visualization/axis_scaling.py +0 -305
- oscura/visualization/colors.py +0 -451
- oscura/visualization/digital.py +0 -436
- oscura/visualization/eye.py +0 -571
- oscura/visualization/histogram.py +0 -281
- oscura/visualization/interactive.py +0 -1035
- oscura/visualization/jitter.py +0 -1042
- oscura/visualization/keyboard.py +0 -394
- oscura/visualization/layout.py +0 -400
- oscura/visualization/optimization.py +0 -1079
- oscura/visualization/palettes.py +0 -446
- oscura/visualization/power.py +0 -508
- oscura/visualization/power_extended.py +0 -955
- oscura/visualization/presets.py +0 -469
- oscura/visualization/protocols.py +0 -1246
- oscura/visualization/render.py +0 -223
- oscura/visualization/rendering.py +0 -444
- oscura/visualization/reverse_engineering.py +0 -838
- oscura/visualization/signal_integrity.py +0 -989
- oscura/visualization/specialized.py +0 -643
- oscura/visualization/spectral.py +0 -1226
- oscura/visualization/thumbnails.py +0 -340
- oscura/visualization/time_axis.py +0 -351
- oscura/visualization/waveform.py +0 -454
- oscura-0.8.0.dist-info/METADATA +0 -661
- {oscura-0.8.0.dist-info → oscura-0.11.0.dist-info}/WHEEL +0 -0
- {oscura-0.8.0.dist-info → oscura-0.11.0.dist-info}/entry_points.txt +0 -0
- {oscura-0.8.0.dist-info → oscura-0.11.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -88,13 +88,22 @@ class MeasurementFormatter:
|
|
|
88
88
|
def format_measurement(self, measurement: dict[str, Any]) -> str:
|
|
89
89
|
"""Format complete measurement dict with value, unit, spec, status.
|
|
90
90
|
|
|
91
|
+
Supports both legacy format and MeasurementResult format.
|
|
92
|
+
|
|
91
93
|
Args:
|
|
92
94
|
measurement: Dictionary containing:
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
Legacy format:
|
|
96
|
+
- value: numeric measurement value
|
|
97
|
+
- unit: unit string (optional)
|
|
98
|
+
- spec: specification limit (optional)
|
|
99
|
+
- spec_type: "max", "min", or "exact" (optional)
|
|
100
|
+
- passed: boolean pass/fail status (optional)
|
|
101
|
+
MeasurementResult format:
|
|
102
|
+
- value: float | None
|
|
103
|
+
- unit: str
|
|
104
|
+
- applicable: bool
|
|
105
|
+
- reason: str | None
|
|
106
|
+
- display: str (pre-formatted)
|
|
98
107
|
|
|
99
108
|
Returns:
|
|
100
109
|
Formatted string representation of measurement.
|
|
@@ -110,24 +119,56 @@ class MeasurementFormatter:
|
|
|
110
119
|
... }
|
|
111
120
|
>>> formatter.format_measurement(measurement)
|
|
112
121
|
'2.30 ns (spec: < 10.0 ns) ✓'
|
|
122
|
+
|
|
123
|
+
>>> # MeasurementResult format with inapplicable measurement
|
|
124
|
+
>>> inapplicable = {
|
|
125
|
+
... "value": None,
|
|
126
|
+
... "unit": "Hz",
|
|
127
|
+
... "applicable": False,
|
|
128
|
+
... "reason": "Aperiodic signal",
|
|
129
|
+
... "display": "N/A"
|
|
130
|
+
... }
|
|
131
|
+
>>> formatter.format_measurement(inapplicable)
|
|
132
|
+
'N/A (Aperiodic signal)'
|
|
113
133
|
"""
|
|
114
|
-
|
|
115
|
-
|
|
134
|
+
# Check if this is MeasurementResult format
|
|
135
|
+
if "applicable" in measurement:
|
|
136
|
+
if not measurement["applicable"]:
|
|
137
|
+
# Inapplicable measurement - show N/A with reason
|
|
138
|
+
reason = measurement.get("reason")
|
|
139
|
+
if reason:
|
|
140
|
+
return f"N/A ({reason})"
|
|
141
|
+
return "N/A"
|
|
142
|
+
|
|
143
|
+
# Applicable measurement - use pre-formatted display if available
|
|
144
|
+
if "display" in measurement:
|
|
145
|
+
formatted = str(measurement["display"])
|
|
146
|
+
else:
|
|
147
|
+
# Fallback to manual formatting
|
|
148
|
+
value = measurement.get("value")
|
|
149
|
+
unit = measurement.get("unit", "")
|
|
150
|
+
if value is None:
|
|
151
|
+
return "N/A"
|
|
152
|
+
formatted = self.format_single(value, unit)
|
|
153
|
+
else:
|
|
154
|
+
# Legacy format
|
|
155
|
+
value = measurement.get("value")
|
|
156
|
+
unit = measurement.get("unit", "")
|
|
116
157
|
|
|
117
|
-
|
|
118
|
-
|
|
158
|
+
if value is None:
|
|
159
|
+
return "N/A"
|
|
119
160
|
|
|
120
|
-
|
|
121
|
-
|
|
161
|
+
if not isinstance(value, (int, float)):
|
|
162
|
+
return str(value)
|
|
122
163
|
|
|
123
|
-
|
|
124
|
-
|
|
164
|
+
# Format the value
|
|
165
|
+
formatted = self.format_single(value, unit)
|
|
125
166
|
|
|
126
167
|
# Add spec comparison if requested
|
|
127
168
|
if self.show_specs and "spec" in measurement:
|
|
128
169
|
spec = measurement["spec"]
|
|
129
170
|
spec_type = measurement.get("spec_type", "exact")
|
|
130
|
-
spec_formatted = self.format_single(spec, unit)
|
|
171
|
+
spec_formatted = self.format_single(spec, measurement.get("unit", ""))
|
|
131
172
|
|
|
132
173
|
if spec_type == "max":
|
|
133
174
|
formatted += f" (spec: < {spec_formatted})"
|