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
|
@@ -165,19 +165,12 @@ class FileSource:
|
|
|
165
165
|
from oscura.core.types import IQTrace
|
|
166
166
|
|
|
167
167
|
# Get sample count based on trace type
|
|
168
|
-
|
|
169
|
-
n_samples = len(trace.i_data)
|
|
170
|
-
else:
|
|
171
|
-
n_samples = len(trace.data)
|
|
168
|
+
n_samples = len(trace.data)
|
|
172
169
|
|
|
173
170
|
for start in range(0, n_samples, chunk_size):
|
|
174
171
|
end = min(start + chunk_size, n_samples)
|
|
175
172
|
# Create chunk trace with sliced data
|
|
176
|
-
|
|
177
|
-
# IQTrace doesn't have .data attribute
|
|
178
|
-
chunk_data = None # Will be handled separately below
|
|
179
|
-
else:
|
|
180
|
-
chunk_data = trace.data[start:end]
|
|
173
|
+
chunk_data = trace.data[start:end]
|
|
181
174
|
|
|
182
175
|
# Import here to avoid circular dependency
|
|
183
176
|
from oscura.core.types import (
|
|
@@ -191,11 +184,7 @@ class FileSource:
|
|
|
191
184
|
sample_rate=trace.metadata.sample_rate,
|
|
192
185
|
vertical_scale=trace.metadata.vertical_scale,
|
|
193
186
|
vertical_offset=trace.metadata.vertical_offset,
|
|
194
|
-
|
|
195
|
-
trigger_info=trace.metadata.trigger_info,
|
|
196
|
-
source_file=str(self.path),
|
|
197
|
-
channel_name=trace.metadata.channel_name,
|
|
198
|
-
calibration_info=trace.metadata.calibration_info,
|
|
187
|
+
channel=trace.metadata.channel,
|
|
199
188
|
)
|
|
200
189
|
|
|
201
190
|
if isinstance(trace, WaveformTrace):
|
|
@@ -206,12 +195,9 @@ class FileSource:
|
|
|
206
195
|
metadata=chunk_metadata,
|
|
207
196
|
)
|
|
208
197
|
elif isinstance(trace, IQTrace):
|
|
209
|
-
# Handle I/Q
|
|
210
|
-
chunk_i = trace.i_data[start:end]
|
|
211
|
-
chunk_q = trace.q_data[start:end]
|
|
198
|
+
# Handle I/Q complex data
|
|
212
199
|
yield IQTrace(
|
|
213
|
-
|
|
214
|
-
q_data=chunk_q,
|
|
200
|
+
data=chunk_data, # type: ignore[arg-type]
|
|
215
201
|
metadata=chunk_metadata,
|
|
216
202
|
)
|
|
217
203
|
|
|
@@ -50,7 +50,7 @@ from typing import TYPE_CHECKING, Any
|
|
|
50
50
|
try:
|
|
51
51
|
import saleae
|
|
52
52
|
except ImportError:
|
|
53
|
-
saleae = None
|
|
53
|
+
saleae = None
|
|
54
54
|
|
|
55
55
|
if TYPE_CHECKING:
|
|
56
56
|
from oscura.core.types import Trace
|
|
@@ -206,7 +206,7 @@ class SaleaeSource:
|
|
|
206
206
|
|
|
207
207
|
from oscura.core.types import DigitalTrace, TraceMetadata, WaveformTrace
|
|
208
208
|
|
|
209
|
-
|
|
209
|
+
acquisition_time = datetime.now()
|
|
210
210
|
|
|
211
211
|
# Start capture
|
|
212
212
|
self.saleae.capture_start()
|
|
@@ -223,11 +223,15 @@ class SaleaeSource:
|
|
|
223
223
|
|
|
224
224
|
n_samples = int(self.sample_rate * self.duration)
|
|
225
225
|
|
|
226
|
+
# Format channel list for display
|
|
227
|
+
channel_list = self.digital_channels or self.analog_channels
|
|
228
|
+
source_file = f"saleae://{self.device_id}" if self.device_id else "saleae://unknown"
|
|
229
|
+
|
|
226
230
|
metadata = TraceMetadata(
|
|
227
231
|
sample_rate=self.sample_rate,
|
|
228
|
-
|
|
229
|
-
source_file=
|
|
230
|
-
|
|
232
|
+
channel=f"Saleae Ch{channel_list}",
|
|
233
|
+
source_file=source_file,
|
|
234
|
+
acquisition_time=acquisition_time,
|
|
231
235
|
)
|
|
232
236
|
|
|
233
237
|
if self.digital_channels:
|
|
@@ -289,11 +293,7 @@ class SaleaeSource:
|
|
|
289
293
|
sample_rate=full_trace.metadata.sample_rate,
|
|
290
294
|
vertical_scale=full_trace.metadata.vertical_scale,
|
|
291
295
|
vertical_offset=full_trace.metadata.vertical_offset,
|
|
292
|
-
|
|
293
|
-
trigger_info=full_trace.metadata.trigger_info,
|
|
294
|
-
source_file=full_trace.metadata.source_file,
|
|
295
|
-
channel_name=full_trace.metadata.channel_name,
|
|
296
|
-
calibration_info=full_trace.metadata.calibration_info,
|
|
296
|
+
channel=full_trace.metadata.channel,
|
|
297
297
|
)
|
|
298
298
|
|
|
299
299
|
if isinstance(full_trace, DigitalTrace):
|
|
@@ -172,8 +172,7 @@ class SocketCANSource:
|
|
|
172
172
|
metadata = TraceMetadata(
|
|
173
173
|
sample_rate=1.0, # Placeholder
|
|
174
174
|
acquisition_time=acquisition_start,
|
|
175
|
-
|
|
176
|
-
channel_name=f"CAN {self.interface}",
|
|
175
|
+
channel=f"CAN {self.interface}",
|
|
177
176
|
)
|
|
178
177
|
return DigitalTrace(data=np.array([], dtype=np.uint8), metadata=metadata)
|
|
179
178
|
|
|
@@ -189,7 +188,7 @@ class SocketCANSource:
|
|
|
189
188
|
sample_rate=effective_rate,
|
|
190
189
|
acquisition_time=acquisition_start,
|
|
191
190
|
source_file=f"socketcan://{self.interface}",
|
|
192
|
-
|
|
191
|
+
channel=f"CAN {self.interface}",
|
|
193
192
|
)
|
|
194
193
|
|
|
195
194
|
# Store CAN IDs as digital data
|
|
@@ -249,7 +248,7 @@ class SocketCANSource:
|
|
|
249
248
|
sample_rate=effective_rate,
|
|
250
249
|
acquisition_time=acquisition_start,
|
|
251
250
|
source_file=f"socketcan://{self.interface}",
|
|
252
|
-
|
|
251
|
+
channel=f"CAN {self.interface}",
|
|
253
252
|
)
|
|
254
253
|
|
|
255
254
|
data_bytes = can_ids.view(np.uint8)
|
|
@@ -268,8 +267,7 @@ class SocketCANSource:
|
|
|
268
267
|
metadata = TraceMetadata(
|
|
269
268
|
sample_rate=effective_rate,
|
|
270
269
|
acquisition_time=acquisition_start,
|
|
271
|
-
|
|
272
|
-
channel_name=f"CAN {self.interface}",
|
|
270
|
+
channel=f"CAN {self.interface}",
|
|
273
271
|
)
|
|
274
272
|
|
|
275
273
|
data_bytes = can_ids.view(np.uint8)
|
|
@@ -176,11 +176,7 @@ class SyntheticSource:
|
|
|
176
176
|
sample_rate=trace.metadata.sample_rate,
|
|
177
177
|
vertical_scale=trace.metadata.vertical_scale,
|
|
178
178
|
vertical_offset=trace.metadata.vertical_offset,
|
|
179
|
-
|
|
180
|
-
trigger_info=trace.metadata.trigger_info,
|
|
181
|
-
source_file=trace.metadata.source_file,
|
|
182
|
-
channel_name=trace.metadata.channel_name,
|
|
183
|
-
calibration_info=trace.metadata.calibration_info,
|
|
179
|
+
channel=trace.metadata.channel,
|
|
184
180
|
)
|
|
185
181
|
|
|
186
182
|
if isinstance(trace, DigitalTrace):
|
|
@@ -256,7 +256,7 @@ class VISASource:
|
|
|
256
256
|
if channel is None:
|
|
257
257
|
channel = self.channels[0]
|
|
258
258
|
|
|
259
|
-
|
|
259
|
+
acquisition_time = datetime.now()
|
|
260
260
|
|
|
261
261
|
try:
|
|
262
262
|
# Single acquisition
|
|
@@ -296,7 +296,7 @@ class VISASource:
|
|
|
296
296
|
except Exception:
|
|
297
297
|
idn = "Unknown Instrument"
|
|
298
298
|
|
|
299
|
-
|
|
299
|
+
calibration = CalibrationInfo(
|
|
300
300
|
instrument=idn,
|
|
301
301
|
coupling="DC", # Default
|
|
302
302
|
vertical_resolution=8, # Typical for oscilloscopes
|
|
@@ -305,10 +305,10 @@ class VISASource:
|
|
|
305
305
|
metadata = TraceMetadata(
|
|
306
306
|
sample_rate=sample_rate,
|
|
307
307
|
vertical_scale=self.vertical_scale,
|
|
308
|
-
|
|
309
|
-
source_file=f"visa://{self.resource}",
|
|
310
|
-
|
|
311
|
-
|
|
308
|
+
channel=f"CH{channel}",
|
|
309
|
+
source_file=f"visa://{self.resource}" if self.resource else "visa://unknown",
|
|
310
|
+
acquisition_time=acquisition_time,
|
|
311
|
+
calibration=calibration,
|
|
312
312
|
)
|
|
313
313
|
|
|
314
314
|
return WaveformTrace(data=data, metadata=metadata)
|