oscura 0.0.1__py3-none-any.whl → 0.1.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 +813 -8
- oscura/__main__.py +392 -0
- oscura/analyzers/__init__.py +37 -0
- oscura/analyzers/digital/__init__.py +177 -0
- oscura/analyzers/digital/bus.py +691 -0
- oscura/analyzers/digital/clock.py +805 -0
- oscura/analyzers/digital/correlation.py +720 -0
- oscura/analyzers/digital/edges.py +632 -0
- oscura/analyzers/digital/extraction.py +413 -0
- oscura/analyzers/digital/quality.py +878 -0
- oscura/analyzers/digital/signal_quality.py +877 -0
- oscura/analyzers/digital/thresholds.py +708 -0
- oscura/analyzers/digital/timing.py +1104 -0
- oscura/analyzers/eye/__init__.py +46 -0
- oscura/analyzers/eye/diagram.py +434 -0
- oscura/analyzers/eye/metrics.py +555 -0
- oscura/analyzers/jitter/__init__.py +83 -0
- oscura/analyzers/jitter/ber.py +333 -0
- oscura/analyzers/jitter/decomposition.py +759 -0
- oscura/analyzers/jitter/measurements.py +413 -0
- oscura/analyzers/jitter/spectrum.py +220 -0
- oscura/analyzers/measurements.py +40 -0
- oscura/analyzers/packet/__init__.py +171 -0
- oscura/analyzers/packet/daq.py +1077 -0
- oscura/analyzers/packet/metrics.py +437 -0
- oscura/analyzers/packet/parser.py +327 -0
- oscura/analyzers/packet/payload.py +2156 -0
- oscura/analyzers/packet/payload_analysis.py +1312 -0
- oscura/analyzers/packet/payload_extraction.py +236 -0
- oscura/analyzers/packet/payload_patterns.py +670 -0
- oscura/analyzers/packet/stream.py +359 -0
- oscura/analyzers/patterns/__init__.py +266 -0
- oscura/analyzers/patterns/clustering.py +1036 -0
- oscura/analyzers/patterns/discovery.py +539 -0
- oscura/analyzers/patterns/learning.py +797 -0
- oscura/analyzers/patterns/matching.py +1091 -0
- oscura/analyzers/patterns/periodic.py +650 -0
- oscura/analyzers/patterns/sequences.py +767 -0
- oscura/analyzers/power/__init__.py +116 -0
- oscura/analyzers/power/ac_power.py +391 -0
- oscura/analyzers/power/basic.py +383 -0
- oscura/analyzers/power/conduction.py +314 -0
- oscura/analyzers/power/efficiency.py +297 -0
- oscura/analyzers/power/ripple.py +356 -0
- oscura/analyzers/power/soa.py +372 -0
- oscura/analyzers/power/switching.py +479 -0
- oscura/analyzers/protocol/__init__.py +150 -0
- oscura/analyzers/protocols/__init__.py +150 -0
- oscura/analyzers/protocols/base.py +500 -0
- oscura/analyzers/protocols/can.py +620 -0
- oscura/analyzers/protocols/can_fd.py +448 -0
- oscura/analyzers/protocols/flexray.py +405 -0
- oscura/analyzers/protocols/hdlc.py +399 -0
- oscura/analyzers/protocols/i2c.py +368 -0
- oscura/analyzers/protocols/i2s.py +296 -0
- oscura/analyzers/protocols/jtag.py +393 -0
- oscura/analyzers/protocols/lin.py +445 -0
- oscura/analyzers/protocols/manchester.py +333 -0
- oscura/analyzers/protocols/onewire.py +501 -0
- oscura/analyzers/protocols/spi.py +334 -0
- oscura/analyzers/protocols/swd.py +325 -0
- oscura/analyzers/protocols/uart.py +393 -0
- oscura/analyzers/protocols/usb.py +495 -0
- oscura/analyzers/signal_integrity/__init__.py +63 -0
- oscura/analyzers/signal_integrity/embedding.py +294 -0
- oscura/analyzers/signal_integrity/equalization.py +370 -0
- oscura/analyzers/signal_integrity/sparams.py +484 -0
- oscura/analyzers/spectral/__init__.py +53 -0
- oscura/analyzers/spectral/chunked.py +273 -0
- oscura/analyzers/spectral/chunked_fft.py +571 -0
- oscura/analyzers/spectral/chunked_wavelet.py +391 -0
- oscura/analyzers/spectral/fft.py +92 -0
- oscura/analyzers/statistical/__init__.py +250 -0
- oscura/analyzers/statistical/checksum.py +923 -0
- oscura/analyzers/statistical/chunked_corr.py +228 -0
- oscura/analyzers/statistical/classification.py +778 -0
- oscura/analyzers/statistical/entropy.py +1113 -0
- oscura/analyzers/statistical/ngrams.py +614 -0
- oscura/analyzers/statistics/__init__.py +119 -0
- oscura/analyzers/statistics/advanced.py +885 -0
- oscura/analyzers/statistics/basic.py +263 -0
- oscura/analyzers/statistics/correlation.py +630 -0
- oscura/analyzers/statistics/distribution.py +298 -0
- oscura/analyzers/statistics/outliers.py +463 -0
- oscura/analyzers/statistics/streaming.py +93 -0
- oscura/analyzers/statistics/trend.py +520 -0
- oscura/analyzers/validation.py +598 -0
- oscura/analyzers/waveform/__init__.py +36 -0
- oscura/analyzers/waveform/measurements.py +943 -0
- oscura/analyzers/waveform/measurements_with_uncertainty.py +371 -0
- oscura/analyzers/waveform/spectral.py +1689 -0
- oscura/analyzers/waveform/wavelets.py +298 -0
- oscura/api/__init__.py +62 -0
- oscura/api/dsl.py +538 -0
- oscura/api/fluent.py +571 -0
- oscura/api/operators.py +498 -0
- oscura/api/optimization.py +392 -0
- oscura/api/profiling.py +396 -0
- oscura/automotive/__init__.py +73 -0
- oscura/automotive/can/__init__.py +52 -0
- oscura/automotive/can/analysis.py +356 -0
- oscura/automotive/can/checksum.py +250 -0
- oscura/automotive/can/correlation.py +212 -0
- oscura/automotive/can/discovery.py +355 -0
- oscura/automotive/can/message_wrapper.py +375 -0
- oscura/automotive/can/models.py +385 -0
- oscura/automotive/can/patterns.py +381 -0
- oscura/automotive/can/session.py +452 -0
- oscura/automotive/can/state_machine.py +300 -0
- oscura/automotive/can/stimulus_response.py +461 -0
- oscura/automotive/dbc/__init__.py +15 -0
- oscura/automotive/dbc/generator.py +156 -0
- oscura/automotive/dbc/parser.py +146 -0
- oscura/automotive/dtc/__init__.py +30 -0
- oscura/automotive/dtc/database.py +3036 -0
- oscura/automotive/j1939/__init__.py +14 -0
- oscura/automotive/j1939/decoder.py +745 -0
- oscura/automotive/loaders/__init__.py +35 -0
- oscura/automotive/loaders/asc.py +98 -0
- oscura/automotive/loaders/blf.py +77 -0
- oscura/automotive/loaders/csv_can.py +136 -0
- oscura/automotive/loaders/dispatcher.py +136 -0
- oscura/automotive/loaders/mdf.py +331 -0
- oscura/automotive/loaders/pcap.py +132 -0
- oscura/automotive/obd/__init__.py +14 -0
- oscura/automotive/obd/decoder.py +707 -0
- oscura/automotive/uds/__init__.py +48 -0
- oscura/automotive/uds/decoder.py +265 -0
- oscura/automotive/uds/models.py +64 -0
- oscura/automotive/visualization.py +369 -0
- oscura/batch/__init__.py +55 -0
- oscura/batch/advanced.py +627 -0
- oscura/batch/aggregate.py +300 -0
- oscura/batch/analyze.py +139 -0
- oscura/batch/logging.py +487 -0
- oscura/batch/metrics.py +556 -0
- oscura/builders/__init__.py +41 -0
- oscura/builders/signal_builder.py +1131 -0
- oscura/cli/__init__.py +14 -0
- oscura/cli/batch.py +339 -0
- oscura/cli/characterize.py +273 -0
- oscura/cli/compare.py +775 -0
- oscura/cli/decode.py +551 -0
- oscura/cli/main.py +247 -0
- oscura/cli/shell.py +350 -0
- oscura/comparison/__init__.py +66 -0
- oscura/comparison/compare.py +397 -0
- oscura/comparison/golden.py +487 -0
- oscura/comparison/limits.py +391 -0
- oscura/comparison/mask.py +434 -0
- oscura/comparison/trace_diff.py +30 -0
- oscura/comparison/visualization.py +481 -0
- oscura/compliance/__init__.py +70 -0
- oscura/compliance/advanced.py +756 -0
- oscura/compliance/masks.py +363 -0
- oscura/compliance/reporting.py +483 -0
- oscura/compliance/testing.py +298 -0
- oscura/component/__init__.py +38 -0
- oscura/component/impedance.py +365 -0
- oscura/component/reactive.py +598 -0
- oscura/component/transmission_line.py +312 -0
- oscura/config/__init__.py +191 -0
- oscura/config/defaults.py +254 -0
- oscura/config/loader.py +348 -0
- oscura/config/memory.py +271 -0
- oscura/config/migration.py +458 -0
- oscura/config/pipeline.py +1077 -0
- oscura/config/preferences.py +530 -0
- oscura/config/protocol.py +875 -0
- oscura/config/schema.py +713 -0
- oscura/config/settings.py +420 -0
- oscura/config/thresholds.py +599 -0
- oscura/convenience.py +457 -0
- oscura/core/__init__.py +299 -0
- oscura/core/audit.py +457 -0
- oscura/core/backend_selector.py +405 -0
- oscura/core/cache.py +590 -0
- oscura/core/cancellation.py +439 -0
- oscura/core/confidence.py +225 -0
- oscura/core/config.py +506 -0
- oscura/core/correlation.py +216 -0
- oscura/core/cross_domain.py +422 -0
- oscura/core/debug.py +301 -0
- oscura/core/edge_cases.py +541 -0
- oscura/core/exceptions.py +535 -0
- oscura/core/gpu_backend.py +523 -0
- oscura/core/lazy.py +832 -0
- oscura/core/log_query.py +540 -0
- oscura/core/logging.py +931 -0
- oscura/core/logging_advanced.py +952 -0
- oscura/core/memoize.py +171 -0
- oscura/core/memory_check.py +274 -0
- oscura/core/memory_guard.py +290 -0
- oscura/core/memory_limits.py +336 -0
- oscura/core/memory_monitor.py +453 -0
- oscura/core/memory_progress.py +465 -0
- oscura/core/memory_warnings.py +315 -0
- oscura/core/numba_backend.py +362 -0
- oscura/core/performance.py +352 -0
- oscura/core/progress.py +524 -0
- oscura/core/provenance.py +358 -0
- oscura/core/results.py +331 -0
- oscura/core/types.py +504 -0
- oscura/core/uncertainty.py +383 -0
- oscura/discovery/__init__.py +52 -0
- oscura/discovery/anomaly_detector.py +672 -0
- oscura/discovery/auto_decoder.py +415 -0
- oscura/discovery/comparison.py +497 -0
- oscura/discovery/quality_validator.py +528 -0
- oscura/discovery/signal_detector.py +769 -0
- oscura/dsl/__init__.py +73 -0
- oscura/dsl/commands.py +246 -0
- oscura/dsl/interpreter.py +455 -0
- oscura/dsl/parser.py +689 -0
- oscura/dsl/repl.py +172 -0
- oscura/exceptions.py +59 -0
- oscura/exploratory/__init__.py +111 -0
- oscura/exploratory/error_recovery.py +642 -0
- oscura/exploratory/fuzzy.py +513 -0
- oscura/exploratory/fuzzy_advanced.py +786 -0
- oscura/exploratory/legacy.py +831 -0
- oscura/exploratory/parse.py +358 -0
- oscura/exploratory/recovery.py +275 -0
- oscura/exploratory/sync.py +382 -0
- oscura/exploratory/unknown.py +707 -0
- oscura/export/__init__.py +25 -0
- oscura/export/wireshark/README.md +265 -0
- oscura/export/wireshark/__init__.py +47 -0
- oscura/export/wireshark/generator.py +312 -0
- oscura/export/wireshark/lua_builder.py +159 -0
- oscura/export/wireshark/templates/dissector.lua.j2 +92 -0
- oscura/export/wireshark/type_mapping.py +165 -0
- oscura/export/wireshark/validator.py +105 -0
- oscura/exporters/__init__.py +94 -0
- oscura/exporters/csv.py +303 -0
- oscura/exporters/exporters.py +44 -0
- oscura/exporters/hdf5.py +219 -0
- oscura/exporters/html_export.py +701 -0
- oscura/exporters/json_export.py +291 -0
- oscura/exporters/markdown_export.py +367 -0
- oscura/exporters/matlab_export.py +354 -0
- oscura/exporters/npz_export.py +219 -0
- oscura/exporters/spice_export.py +210 -0
- oscura/extensibility/__init__.py +131 -0
- oscura/extensibility/docs.py +752 -0
- oscura/extensibility/extensions.py +1125 -0
- oscura/extensibility/logging.py +259 -0
- oscura/extensibility/measurements.py +485 -0
- oscura/extensibility/plugins.py +414 -0
- oscura/extensibility/registry.py +346 -0
- oscura/extensibility/templates.py +913 -0
- oscura/extensibility/validation.py +651 -0
- oscura/filtering/__init__.py +89 -0
- oscura/filtering/base.py +563 -0
- oscura/filtering/convenience.py +564 -0
- oscura/filtering/design.py +725 -0
- oscura/filtering/filters.py +32 -0
- oscura/filtering/introspection.py +605 -0
- oscura/guidance/__init__.py +24 -0
- oscura/guidance/recommender.py +429 -0
- oscura/guidance/wizard.py +518 -0
- oscura/inference/__init__.py +251 -0
- oscura/inference/active_learning/README.md +153 -0
- oscura/inference/active_learning/__init__.py +38 -0
- oscura/inference/active_learning/lstar.py +257 -0
- oscura/inference/active_learning/observation_table.py +230 -0
- oscura/inference/active_learning/oracle.py +78 -0
- oscura/inference/active_learning/teachers/__init__.py +15 -0
- oscura/inference/active_learning/teachers/simulator.py +192 -0
- oscura/inference/adaptive_tuning.py +453 -0
- oscura/inference/alignment.py +653 -0
- oscura/inference/bayesian.py +943 -0
- oscura/inference/binary.py +1016 -0
- oscura/inference/crc_reverse.py +711 -0
- oscura/inference/logic.py +288 -0
- oscura/inference/message_format.py +1305 -0
- oscura/inference/protocol.py +417 -0
- oscura/inference/protocol_dsl.py +1084 -0
- oscura/inference/protocol_library.py +1230 -0
- oscura/inference/sequences.py +809 -0
- oscura/inference/signal_intelligence.py +1509 -0
- oscura/inference/spectral.py +215 -0
- oscura/inference/state_machine.py +634 -0
- oscura/inference/stream.py +918 -0
- oscura/integrations/__init__.py +59 -0
- oscura/integrations/llm.py +1827 -0
- oscura/jupyter/__init__.py +32 -0
- oscura/jupyter/display.py +268 -0
- oscura/jupyter/magic.py +334 -0
- oscura/loaders/__init__.py +526 -0
- oscura/loaders/binary.py +69 -0
- oscura/loaders/configurable.py +1255 -0
- oscura/loaders/csv.py +26 -0
- oscura/loaders/csv_loader.py +473 -0
- oscura/loaders/hdf5.py +9 -0
- oscura/loaders/hdf5_loader.py +510 -0
- oscura/loaders/lazy.py +370 -0
- oscura/loaders/mmap_loader.py +583 -0
- oscura/loaders/numpy_loader.py +436 -0
- oscura/loaders/pcap.py +432 -0
- oscura/loaders/preprocessing.py +368 -0
- oscura/loaders/rigol.py +287 -0
- oscura/loaders/sigrok.py +321 -0
- oscura/loaders/tdms.py +367 -0
- oscura/loaders/tektronix.py +711 -0
- oscura/loaders/validation.py +584 -0
- oscura/loaders/vcd.py +464 -0
- oscura/loaders/wav.py +233 -0
- oscura/math/__init__.py +45 -0
- oscura/math/arithmetic.py +824 -0
- oscura/math/interpolation.py +413 -0
- oscura/onboarding/__init__.py +39 -0
- oscura/onboarding/help.py +498 -0
- oscura/onboarding/tutorials.py +405 -0
- oscura/onboarding/wizard.py +466 -0
- oscura/optimization/__init__.py +19 -0
- oscura/optimization/parallel.py +440 -0
- oscura/optimization/search.py +532 -0
- oscura/pipeline/__init__.py +43 -0
- oscura/pipeline/base.py +338 -0
- oscura/pipeline/composition.py +242 -0
- oscura/pipeline/parallel.py +448 -0
- oscura/pipeline/pipeline.py +375 -0
- oscura/pipeline/reverse_engineering.py +1119 -0
- oscura/plugins/__init__.py +122 -0
- oscura/plugins/base.py +272 -0
- oscura/plugins/cli.py +497 -0
- oscura/plugins/discovery.py +411 -0
- oscura/plugins/isolation.py +418 -0
- oscura/plugins/lifecycle.py +959 -0
- oscura/plugins/manager.py +493 -0
- oscura/plugins/registry.py +421 -0
- oscura/plugins/versioning.py +372 -0
- oscura/py.typed +0 -0
- oscura/quality/__init__.py +65 -0
- oscura/quality/ensemble.py +740 -0
- oscura/quality/explainer.py +338 -0
- oscura/quality/scoring.py +616 -0
- oscura/quality/warnings.py +456 -0
- oscura/reporting/__init__.py +248 -0
- oscura/reporting/advanced.py +1234 -0
- oscura/reporting/analyze.py +448 -0
- oscura/reporting/argument_preparer.py +596 -0
- oscura/reporting/auto_report.py +507 -0
- oscura/reporting/batch.py +615 -0
- oscura/reporting/chart_selection.py +223 -0
- oscura/reporting/comparison.py +330 -0
- oscura/reporting/config.py +615 -0
- oscura/reporting/content/__init__.py +39 -0
- oscura/reporting/content/executive.py +127 -0
- oscura/reporting/content/filtering.py +191 -0
- oscura/reporting/content/minimal.py +257 -0
- oscura/reporting/content/verbosity.py +162 -0
- oscura/reporting/core.py +508 -0
- oscura/reporting/core_formats/__init__.py +17 -0
- oscura/reporting/core_formats/multi_format.py +210 -0
- oscura/reporting/engine.py +836 -0
- oscura/reporting/export.py +366 -0
- oscura/reporting/formatting/__init__.py +129 -0
- oscura/reporting/formatting/emphasis.py +81 -0
- oscura/reporting/formatting/numbers.py +403 -0
- oscura/reporting/formatting/standards.py +55 -0
- oscura/reporting/formatting.py +466 -0
- oscura/reporting/html.py +578 -0
- oscura/reporting/index.py +590 -0
- oscura/reporting/multichannel.py +296 -0
- oscura/reporting/output.py +379 -0
- oscura/reporting/pdf.py +373 -0
- oscura/reporting/plots.py +731 -0
- oscura/reporting/pptx_export.py +360 -0
- oscura/reporting/renderers/__init__.py +11 -0
- oscura/reporting/renderers/pdf.py +94 -0
- oscura/reporting/sections.py +471 -0
- oscura/reporting/standards.py +680 -0
- oscura/reporting/summary_generator.py +368 -0
- oscura/reporting/tables.py +397 -0
- oscura/reporting/template_system.py +724 -0
- oscura/reporting/templates/__init__.py +15 -0
- oscura/reporting/templates/definition.py +205 -0
- oscura/reporting/templates/index.html +649 -0
- oscura/reporting/templates/index.md +173 -0
- oscura/schemas/__init__.py +158 -0
- oscura/schemas/bus_configuration.json +322 -0
- oscura/schemas/device_mapping.json +182 -0
- oscura/schemas/packet_format.json +418 -0
- oscura/schemas/protocol_definition.json +363 -0
- oscura/search/__init__.py +16 -0
- oscura/search/anomaly.py +292 -0
- oscura/search/context.py +149 -0
- oscura/search/pattern.py +160 -0
- oscura/session/__init__.py +34 -0
- oscura/session/annotations.py +289 -0
- oscura/session/history.py +313 -0
- oscura/session/session.py +445 -0
- oscura/streaming/__init__.py +43 -0
- oscura/streaming/chunked.py +611 -0
- oscura/streaming/progressive.py +393 -0
- oscura/streaming/realtime.py +622 -0
- oscura/testing/__init__.py +54 -0
- oscura/testing/synthetic.py +808 -0
- oscura/triggering/__init__.py +68 -0
- oscura/triggering/base.py +229 -0
- oscura/triggering/edge.py +353 -0
- oscura/triggering/pattern.py +344 -0
- oscura/triggering/pulse.py +581 -0
- oscura/triggering/window.py +453 -0
- oscura/ui/__init__.py +48 -0
- oscura/ui/formatters.py +526 -0
- oscura/ui/progressive_display.py +340 -0
- oscura/utils/__init__.py +99 -0
- oscura/utils/autodetect.py +338 -0
- oscura/utils/buffer.py +389 -0
- oscura/utils/lazy.py +407 -0
- oscura/utils/lazy_imports.py +147 -0
- oscura/utils/memory.py +836 -0
- oscura/utils/memory_advanced.py +1326 -0
- oscura/utils/memory_extensions.py +465 -0
- oscura/utils/progressive.py +352 -0
- oscura/utils/windowing.py +362 -0
- oscura/visualization/__init__.py +321 -0
- oscura/visualization/accessibility.py +526 -0
- oscura/visualization/annotations.py +374 -0
- oscura/visualization/axis_scaling.py +305 -0
- oscura/visualization/colors.py +453 -0
- oscura/visualization/digital.py +337 -0
- oscura/visualization/eye.py +420 -0
- oscura/visualization/histogram.py +281 -0
- oscura/visualization/interactive.py +858 -0
- oscura/visualization/jitter.py +702 -0
- oscura/visualization/keyboard.py +394 -0
- oscura/visualization/layout.py +365 -0
- oscura/visualization/optimization.py +1028 -0
- oscura/visualization/palettes.py +446 -0
- oscura/visualization/plot.py +92 -0
- oscura/visualization/power.py +290 -0
- oscura/visualization/power_extended.py +626 -0
- oscura/visualization/presets.py +467 -0
- oscura/visualization/protocols.py +932 -0
- oscura/visualization/render.py +207 -0
- oscura/visualization/rendering.py +444 -0
- oscura/visualization/reverse_engineering.py +791 -0
- oscura/visualization/signal_integrity.py +808 -0
- oscura/visualization/specialized.py +553 -0
- oscura/visualization/spectral.py +811 -0
- oscura/visualization/styles.py +381 -0
- oscura/visualization/thumbnails.py +311 -0
- oscura/visualization/time_axis.py +351 -0
- oscura/visualization/waveform.py +367 -0
- oscura/workflow/__init__.py +13 -0
- oscura/workflow/dag.py +377 -0
- oscura/workflows/__init__.py +58 -0
- oscura/workflows/compliance.py +280 -0
- oscura/workflows/digital.py +272 -0
- oscura/workflows/multi_trace.py +502 -0
- oscura/workflows/power.py +178 -0
- oscura/workflows/protocol.py +492 -0
- oscura/workflows/reverse_engineering.py +639 -0
- oscura/workflows/signal_integrity.py +227 -0
- oscura-0.1.0.dist-info/METADATA +300 -0
- oscura-0.1.0.dist-info/RECORD +463 -0
- oscura-0.1.0.dist-info/entry_points.txt +2 -0
- {oscura-0.0.1.dist-info → oscura-0.1.0.dist-info}/licenses/LICENSE +1 -1
- oscura-0.0.1.dist-info/METADATA +0 -63
- oscura-0.0.1.dist-info/RECORD +0 -5
- {oscura-0.0.1.dist-info → oscura-0.1.0.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,615 @@
|
|
|
1
|
+
"""Configuration for comprehensive analysis report system.
|
|
2
|
+
|
|
3
|
+
This module defines the simplified configuration schema for the comprehensive
|
|
4
|
+
analysis report generator, combining input/output/analysis specs into a single
|
|
5
|
+
unified configuration.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from collections.abc import Callable
|
|
11
|
+
from dataclasses import dataclass, field
|
|
12
|
+
from enum import Enum
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from typing import Any
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class InputType(str, Enum):
|
|
18
|
+
"""Supported input data types."""
|
|
19
|
+
|
|
20
|
+
WAVEFORM = "waveform" # Analog waveform (WFM, CSV, NPZ, HDF5)
|
|
21
|
+
DIGITAL = "digital" # Digital logic signals
|
|
22
|
+
BINARY = "binary" # Binary packet data
|
|
23
|
+
PCAP = "pcap" # Network capture
|
|
24
|
+
IQ = "iq" # I/Q baseband data
|
|
25
|
+
PACKETS = "packets" # Pre-parsed packets
|
|
26
|
+
SPARAMS = "sparams" # S-parameter/Touchstone data (.s1p-.s8p)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class AnalysisDomain(str, Enum):
|
|
30
|
+
"""Analysis domain categories."""
|
|
31
|
+
|
|
32
|
+
WAVEFORM = "waveform" # Basic waveform measurements
|
|
33
|
+
DIGITAL = "digital" # Digital signal analysis
|
|
34
|
+
TIMING = "timing" # Timing measurements
|
|
35
|
+
SPECTRAL = "spectral" # FFT, PSD, THD, SNR
|
|
36
|
+
STATISTICS = "statistics" # Statistical analysis
|
|
37
|
+
PATTERNS = "patterns" # Pattern detection
|
|
38
|
+
JITTER = "jitter" # Jitter decomposition
|
|
39
|
+
EYE = "eye" # Eye diagram analysis
|
|
40
|
+
POWER = "power" # Power analysis
|
|
41
|
+
PROTOCOLS = "protocols" # Protocol decoding
|
|
42
|
+
SIGNAL_INTEGRITY = "signal_integrity" # S-params, equalization
|
|
43
|
+
INFERENCE = "inference" # Auto-inference
|
|
44
|
+
PACKET = "packet" # Packet metrics
|
|
45
|
+
ENTROPY = "entropy" # Entropy analysis
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@dataclass
|
|
49
|
+
class DomainConfig:
|
|
50
|
+
"""Configuration for a single analysis domain.
|
|
51
|
+
|
|
52
|
+
Attributes:
|
|
53
|
+
enabled: Whether to run this analysis domain.
|
|
54
|
+
parameters: Domain-specific parameters passed to analyzers.
|
|
55
|
+
timeout: Timeout in seconds for this domain (None = use global timeout).
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
enabled: bool = True
|
|
59
|
+
parameters: dict[str, Any] = field(default_factory=dict)
|
|
60
|
+
timeout: float | None = None
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@dataclass
|
|
64
|
+
class DataOutputConfig:
|
|
65
|
+
"""Configuration for data output limits and aggregation.
|
|
66
|
+
|
|
67
|
+
Controls how data is serialized in reports - whether to truncate,
|
|
68
|
+
aggregate similar values, or output complete data.
|
|
69
|
+
|
|
70
|
+
Attributes:
|
|
71
|
+
full_data_mode: If True, output ALL data without truncation.
|
|
72
|
+
max_array_elements: Max array elements (None = unlimited). Ignored if full_data_mode=True.
|
|
73
|
+
max_list_items: Max list items (None = unlimited). Ignored if full_data_mode=True.
|
|
74
|
+
max_bytes_sample: Max bytes to include (None = unlimited). Ignored if full_data_mode=True.
|
|
75
|
+
max_pdf_results_per_domain: Max results per domain in PDF (None = unlimited).
|
|
76
|
+
max_pdf_summary_length: Max summary string length in PDF (None = unlimited).
|
|
77
|
+
smart_aggregation: Enable smart aggregation of repeated/similar values.
|
|
78
|
+
aggregation_threshold: Min identical values to trigger aggregation (default: 5).
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
full_data_mode: bool = True # Default to full data - no truncation
|
|
82
|
+
max_array_elements: int | None = None # None = unlimited
|
|
83
|
+
max_list_items: int | None = None # None = unlimited
|
|
84
|
+
max_bytes_sample: int | None = None # None = unlimited
|
|
85
|
+
max_pdf_results_per_domain: int | None = None # None = unlimited
|
|
86
|
+
max_pdf_summary_length: int | None = None # None = unlimited
|
|
87
|
+
smart_aggregation: bool = True # Enable smart aggregation by default
|
|
88
|
+
aggregation_threshold: int = 5 # Min identical values to trigger aggregation
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
# Default sample rates for different analysis contexts
|
|
92
|
+
# These are used when sample_rate cannot be derived from input data
|
|
93
|
+
DEFAULT_SAMPLE_RATE_HZ: float = 1e9 # 1 GHz - high-speed digital/eye diagram
|
|
94
|
+
DEFAULT_SAMPLE_RATE_GENERAL_HZ: float = 1e6 # 1 MHz - general waveform analysis
|
|
95
|
+
DEFAULT_SAMPLE_RATE_BINARY_HZ: float = 1.0 # 1 Hz (1 sample/s) - binary data
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@dataclass
|
|
99
|
+
class AnalysisConfig:
|
|
100
|
+
"""Unified configuration for comprehensive analysis.
|
|
101
|
+
|
|
102
|
+
Combines input specification, analysis selection, and output options
|
|
103
|
+
into a single simplified configuration.
|
|
104
|
+
|
|
105
|
+
Attributes:
|
|
106
|
+
domains: List of domains to analyze (None = all applicable domains).
|
|
107
|
+
exclude_domains: Domains to explicitly exclude.
|
|
108
|
+
domain_config: Per-domain configuration overrides.
|
|
109
|
+
output_formats: Output formats to generate (e.g., ["json", "yaml"]).
|
|
110
|
+
index_formats: Index formats to generate (e.g., ["html", "md"]).
|
|
111
|
+
generate_plots: Whether to generate visualization plots.
|
|
112
|
+
plot_format: Plot file format (png, svg, pdf).
|
|
113
|
+
plot_dpi: Plot resolution in DPI.
|
|
114
|
+
copy_input_file: Copy input file to output directory.
|
|
115
|
+
save_intermediate_data: Save intermediate analysis data.
|
|
116
|
+
full_data_mode: Output all data without truncation.
|
|
117
|
+
smart_aggregation: Enable smart aggregation of repeated values.
|
|
118
|
+
data_output: Advanced data output configuration.
|
|
119
|
+
timeout_per_analysis: Timeout per analysis function in seconds (None = no timeout).
|
|
120
|
+
continue_on_error: Continue analysis if individual functions fail.
|
|
121
|
+
log_level: Logging level (DEBUG, INFO, WARNING, ERROR).
|
|
122
|
+
parallel_domains: Enable parallel domain execution.
|
|
123
|
+
enable_quality_scoring: Attach quality scores to analysis results.
|
|
124
|
+
max_memory_mb: Maximum memory per analysis in MB (None = auto-detect).
|
|
125
|
+
max_cache_entries: Maximum cached results (prevents cache bloat).
|
|
126
|
+
max_parallel_workers: Maximum parallel threads for analysis.
|
|
127
|
+
chunk_size_mb: Maximum chunk size for large data processing in MB.
|
|
128
|
+
default_sample_rate: Default sample rate (Hz) when not derivable from data.
|
|
129
|
+
Used for analysis functions requiring sample_rate parameter.
|
|
130
|
+
Set to None to require explicit sample_rate in input data.
|
|
131
|
+
title: Report title.
|
|
132
|
+
author: Report author.
|
|
133
|
+
project: Project name.
|
|
134
|
+
notes: Additional notes/description.
|
|
135
|
+
custom_metadata: Custom metadata fields.
|
|
136
|
+
"""
|
|
137
|
+
|
|
138
|
+
# Analysis selection
|
|
139
|
+
domains: list[AnalysisDomain] | None = None # None = all applicable
|
|
140
|
+
exclude_domains: list[AnalysisDomain] = field(default_factory=list)
|
|
141
|
+
domain_config: dict[AnalysisDomain, DomainConfig] = field(default_factory=dict)
|
|
142
|
+
|
|
143
|
+
# Output formats
|
|
144
|
+
output_formats: list[str] = field(default_factory=lambda: ["json", "yaml"])
|
|
145
|
+
index_formats: list[str] = field(default_factory=lambda: ["html", "md"])
|
|
146
|
+
|
|
147
|
+
# Visualization
|
|
148
|
+
generate_plots: bool = True
|
|
149
|
+
plot_format: str = "png"
|
|
150
|
+
plot_dpi: int = 150
|
|
151
|
+
|
|
152
|
+
# Data handling
|
|
153
|
+
copy_input_file: bool = False
|
|
154
|
+
save_intermediate_data: bool = True
|
|
155
|
+
full_data_mode: bool = True
|
|
156
|
+
smart_aggregation: bool = True
|
|
157
|
+
data_output: DataOutputConfig = field(default_factory=DataOutputConfig)
|
|
158
|
+
|
|
159
|
+
# Execution control
|
|
160
|
+
timeout_per_analysis: float | None = 30.0
|
|
161
|
+
continue_on_error: bool = True
|
|
162
|
+
log_level: str = "INFO"
|
|
163
|
+
parallel_domains: bool = True # Enable parallel domain execution
|
|
164
|
+
enable_quality_scoring: bool = True # Attach quality scores to analysis results
|
|
165
|
+
|
|
166
|
+
# Resource limits (MEM-010, MEM-015)
|
|
167
|
+
max_memory_mb: int = 2048 # Max memory per analysis (MB)
|
|
168
|
+
max_cache_entries: int = 100 # Max cached results
|
|
169
|
+
max_parallel_workers: int = 4 # Max parallel threads
|
|
170
|
+
chunk_size_mb: int = 100 # Max chunk size for large data
|
|
171
|
+
|
|
172
|
+
# Sample rate configuration
|
|
173
|
+
# Default sample rate used when not available in input data metadata.
|
|
174
|
+
# This is a fallback; sample_rate is preferably derived from:
|
|
175
|
+
# 1. Input data metadata (e.g., WaveformTrace.metadata.sample_rate)
|
|
176
|
+
# 2. Explicit parameter in domain_config
|
|
177
|
+
# 3. This default value
|
|
178
|
+
default_sample_rate: float | None = DEFAULT_SAMPLE_RATE_GENERAL_HZ
|
|
179
|
+
|
|
180
|
+
# Metadata
|
|
181
|
+
title: str = ""
|
|
182
|
+
author: str = ""
|
|
183
|
+
project: str = ""
|
|
184
|
+
notes: str = ""
|
|
185
|
+
custom_metadata: dict[str, Any] = field(default_factory=dict)
|
|
186
|
+
|
|
187
|
+
def get_domain_config(self, domain: AnalysisDomain) -> DomainConfig:
|
|
188
|
+
"""Get configuration for a specific domain.
|
|
189
|
+
|
|
190
|
+
Args:
|
|
191
|
+
domain: Analysis domain to get configuration for.
|
|
192
|
+
|
|
193
|
+
Returns:
|
|
194
|
+
Domain configuration (default if not specified).
|
|
195
|
+
"""
|
|
196
|
+
return self.domain_config.get(domain, DomainConfig())
|
|
197
|
+
|
|
198
|
+
def is_domain_enabled(self, domain: AnalysisDomain) -> bool:
|
|
199
|
+
"""Check if a domain is enabled.
|
|
200
|
+
|
|
201
|
+
Args:
|
|
202
|
+
domain: Analysis domain to check.
|
|
203
|
+
|
|
204
|
+
Returns:
|
|
205
|
+
True if domain should be analyzed.
|
|
206
|
+
"""
|
|
207
|
+
# Check explicit exclusion
|
|
208
|
+
if domain in self.exclude_domains:
|
|
209
|
+
return False
|
|
210
|
+
|
|
211
|
+
# Check domain-specific config
|
|
212
|
+
if domain in self.domain_config:
|
|
213
|
+
return self.domain_config[domain].enabled
|
|
214
|
+
|
|
215
|
+
# If domains list specified, check membership
|
|
216
|
+
if self.domains is not None:
|
|
217
|
+
return domain in self.domains
|
|
218
|
+
|
|
219
|
+
# Otherwise enabled by default
|
|
220
|
+
return True
|
|
221
|
+
|
|
222
|
+
def get_effective_sample_rate(
|
|
223
|
+
self, data_sample_rate: float | None = None, context: str = "general"
|
|
224
|
+
) -> float:
|
|
225
|
+
"""Get effective sample rate, preferring data metadata over defaults.
|
|
226
|
+
|
|
227
|
+
Priority order:
|
|
228
|
+
1. data_sample_rate (from input data metadata)
|
|
229
|
+
2. self.default_sample_rate (from config)
|
|
230
|
+
3. Context-appropriate default
|
|
231
|
+
|
|
232
|
+
Args:
|
|
233
|
+
data_sample_rate: Sample rate from input data metadata (if available).
|
|
234
|
+
context: Analysis context for selecting appropriate default.
|
|
235
|
+
Options: "general" (1 MHz), "highspeed" (1 GHz), "binary" (1 Hz).
|
|
236
|
+
|
|
237
|
+
Returns:
|
|
238
|
+
Effective sample rate in Hz.
|
|
239
|
+
"""
|
|
240
|
+
if data_sample_rate is not None and data_sample_rate > 0:
|
|
241
|
+
return data_sample_rate
|
|
242
|
+
|
|
243
|
+
if self.default_sample_rate is not None and self.default_sample_rate > 0:
|
|
244
|
+
return self.default_sample_rate
|
|
245
|
+
|
|
246
|
+
# Context-appropriate defaults
|
|
247
|
+
if context == "highspeed":
|
|
248
|
+
return DEFAULT_SAMPLE_RATE_HZ
|
|
249
|
+
elif context == "binary":
|
|
250
|
+
return DEFAULT_SAMPLE_RATE_BINARY_HZ
|
|
251
|
+
else:
|
|
252
|
+
return DEFAULT_SAMPLE_RATE_GENERAL_HZ
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
@dataclass
|
|
256
|
+
class ProgressInfo:
|
|
257
|
+
"""Progress information for callbacks.
|
|
258
|
+
|
|
259
|
+
Attributes:
|
|
260
|
+
phase: Current phase (e.g., "loading", "analyzing", "plotting", "saving").
|
|
261
|
+
domain: Current analysis domain (None during non-domain phases).
|
|
262
|
+
function: Current function name (None during non-function phases).
|
|
263
|
+
percent: Progress percentage (0.0 to 100.0).
|
|
264
|
+
message: Human-readable progress message.
|
|
265
|
+
elapsed_seconds: Time elapsed since analysis started.
|
|
266
|
+
estimated_remaining_seconds: Estimated time remaining (None if unknown).
|
|
267
|
+
"""
|
|
268
|
+
|
|
269
|
+
phase: str
|
|
270
|
+
domain: AnalysisDomain | None
|
|
271
|
+
function: str | None
|
|
272
|
+
percent: float
|
|
273
|
+
message: str
|
|
274
|
+
elapsed_seconds: float
|
|
275
|
+
estimated_remaining_seconds: float | None
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
@dataclass
|
|
279
|
+
class AnalysisError:
|
|
280
|
+
"""Record of an analysis error.
|
|
281
|
+
|
|
282
|
+
Attributes:
|
|
283
|
+
domain: Analysis domain where error occurred.
|
|
284
|
+
function: Function name that failed.
|
|
285
|
+
error_type: Error type/class name.
|
|
286
|
+
error_message: Error message.
|
|
287
|
+
traceback: Full traceback (None if not captured).
|
|
288
|
+
duration_ms: Time spent before error occurred.
|
|
289
|
+
"""
|
|
290
|
+
|
|
291
|
+
domain: AnalysisDomain
|
|
292
|
+
function: str
|
|
293
|
+
error_type: str
|
|
294
|
+
error_message: str
|
|
295
|
+
traceback: str | None
|
|
296
|
+
duration_ms: float
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
@dataclass
|
|
300
|
+
class AnalysisResult:
|
|
301
|
+
"""Result from comprehensive analysis.
|
|
302
|
+
|
|
303
|
+
Contains paths to all generated outputs and summary statistics.
|
|
304
|
+
|
|
305
|
+
Attributes:
|
|
306
|
+
output_dir: Root output directory.
|
|
307
|
+
index_html: Path to HTML index (None if not generated).
|
|
308
|
+
index_md: Path to Markdown index (None if not generated).
|
|
309
|
+
index_pdf: Path to PDF index (None if not generated).
|
|
310
|
+
summary_json: Path to JSON summary.
|
|
311
|
+
summary_yaml: Path to YAML summary (None if not generated).
|
|
312
|
+
metadata_json: Path to metadata file.
|
|
313
|
+
config_yaml: Path to saved configuration.
|
|
314
|
+
domain_dirs: Per-domain output directories.
|
|
315
|
+
plot_paths: List of all generated plot files.
|
|
316
|
+
error_log: Path to error log (None if no errors).
|
|
317
|
+
input_file: Input file path (None if from memory).
|
|
318
|
+
input_type: Input data type.
|
|
319
|
+
total_analyses: Total number of analysis functions attempted.
|
|
320
|
+
successful_analyses: Number of successful analyses.
|
|
321
|
+
failed_analyses: Number of failed analyses.
|
|
322
|
+
skipped_analyses: Number of skipped analyses.
|
|
323
|
+
duration_seconds: Total analysis duration.
|
|
324
|
+
domain_summaries: Per-domain summary data.
|
|
325
|
+
errors: List of errors encountered.
|
|
326
|
+
"""
|
|
327
|
+
|
|
328
|
+
output_dir: Path
|
|
329
|
+
index_html: Path | None
|
|
330
|
+
index_md: Path | None
|
|
331
|
+
index_pdf: Path | None
|
|
332
|
+
summary_json: Path
|
|
333
|
+
summary_yaml: Path | None
|
|
334
|
+
metadata_json: Path
|
|
335
|
+
config_yaml: Path
|
|
336
|
+
domain_dirs: dict[AnalysisDomain, Path]
|
|
337
|
+
plot_paths: list[Path]
|
|
338
|
+
error_log: Path | None
|
|
339
|
+
input_file: str | None
|
|
340
|
+
input_type: InputType
|
|
341
|
+
total_analyses: int
|
|
342
|
+
successful_analyses: int
|
|
343
|
+
failed_analyses: int
|
|
344
|
+
skipped_analyses: int
|
|
345
|
+
duration_seconds: float
|
|
346
|
+
domain_summaries: dict[AnalysisDomain, dict[str, Any]]
|
|
347
|
+
errors: list[AnalysisError]
|
|
348
|
+
|
|
349
|
+
def open_index(self) -> None:
|
|
350
|
+
"""Open the HTML index in the default web browser.
|
|
351
|
+
|
|
352
|
+
Raises:
|
|
353
|
+
FileNotFoundError: If HTML index was not generated.
|
|
354
|
+
"""
|
|
355
|
+
if self.index_html is None:
|
|
356
|
+
raise FileNotFoundError("HTML index was not generated")
|
|
357
|
+
|
|
358
|
+
import webbrowser
|
|
359
|
+
|
|
360
|
+
webbrowser.open(self.index_html.as_uri())
|
|
361
|
+
|
|
362
|
+
def get_domain_results(self, domain: AnalysisDomain) -> dict[str, Any]:
|
|
363
|
+
"""Get results for a specific domain.
|
|
364
|
+
|
|
365
|
+
Args:
|
|
366
|
+
domain: Domain to get results for.
|
|
367
|
+
|
|
368
|
+
Returns:
|
|
369
|
+
Domain summary data.
|
|
370
|
+
|
|
371
|
+
Raises:
|
|
372
|
+
KeyError: If domain was not analyzed.
|
|
373
|
+
"""
|
|
374
|
+
if domain not in self.domain_summaries:
|
|
375
|
+
raise KeyError(f"Domain {domain.value} was not analyzed")
|
|
376
|
+
|
|
377
|
+
return self.domain_summaries[domain]
|
|
378
|
+
|
|
379
|
+
@property
|
|
380
|
+
def success_rate(self) -> float:
|
|
381
|
+
"""Calculate success rate as percentage.
|
|
382
|
+
|
|
383
|
+
Returns:
|
|
384
|
+
Success rate (0.0 to 100.0).
|
|
385
|
+
"""
|
|
386
|
+
if self.total_analyses == 0:
|
|
387
|
+
return 0.0
|
|
388
|
+
return (self.successful_analyses / self.total_analyses) * 100.0
|
|
389
|
+
|
|
390
|
+
def __repr__(self) -> str:
|
|
391
|
+
"""Get string representation."""
|
|
392
|
+
return (
|
|
393
|
+
f"AnalysisResult("
|
|
394
|
+
f"domains={len(self.domain_summaries)}, "
|
|
395
|
+
f"success={self.successful_analyses}/{self.total_analyses}, "
|
|
396
|
+
f"duration={self.duration_seconds:.1f}s, "
|
|
397
|
+
f"output_dir={self.output_dir})"
|
|
398
|
+
)
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
# Analysis capability registry - maps domains to available analyzers
|
|
402
|
+
# NOTE: Each domain now supports MULTIPLE modules to capture all available functions
|
|
403
|
+
# Updated to include all 68 submodules with 318+ total functions across 14 domains
|
|
404
|
+
ANALYSIS_CAPABILITIES: dict[AnalysisDomain, dict[str, Any]] = {
|
|
405
|
+
AnalysisDomain.WAVEFORM: {
|
|
406
|
+
"description": "Basic waveform timing and amplitude measurements",
|
|
407
|
+
"modules": ["oscura.analyzers.waveform.measurements"],
|
|
408
|
+
"requires": ["waveform"],
|
|
409
|
+
},
|
|
410
|
+
AnalysisDomain.SPECTRAL: {
|
|
411
|
+
"description": "FFT, PSD, THD, SNR, SFDR, SINAD, ENOB, wavelet analysis",
|
|
412
|
+
"modules": [
|
|
413
|
+
"oscura.analyzers.waveform.spectral",
|
|
414
|
+
"oscura.analyzers.spectral.chunked",
|
|
415
|
+
"oscura.analyzers.spectral.chunked_fft",
|
|
416
|
+
"oscura.analyzers.spectral.chunked_wavelet",
|
|
417
|
+
"oscura.analyzers.waveform.wavelets",
|
|
418
|
+
],
|
|
419
|
+
"requires": ["waveform"],
|
|
420
|
+
},
|
|
421
|
+
AnalysisDomain.DIGITAL: {
|
|
422
|
+
"description": "Digital signal extraction, edge detection, timing analysis",
|
|
423
|
+
"modules": [
|
|
424
|
+
"oscura.analyzers.digital.extraction",
|
|
425
|
+
"oscura.analyzers.digital.edges",
|
|
426
|
+
"oscura.analyzers.digital.clock",
|
|
427
|
+
"oscura.analyzers.digital.quality",
|
|
428
|
+
"oscura.analyzers.digital.signal_quality",
|
|
429
|
+
"oscura.analyzers.digital.thresholds",
|
|
430
|
+
"oscura.analyzers.digital.bus",
|
|
431
|
+
"oscura.analyzers.digital.correlation",
|
|
432
|
+
],
|
|
433
|
+
"requires": ["waveform", "digital"],
|
|
434
|
+
},
|
|
435
|
+
AnalysisDomain.TIMING: {
|
|
436
|
+
"description": "Setup/hold time, propagation delay, skew, slew rate",
|
|
437
|
+
"modules": ["oscura.analyzers.digital.timing"],
|
|
438
|
+
"requires": ["waveform", "digital"],
|
|
439
|
+
},
|
|
440
|
+
AnalysisDomain.STATISTICS: {
|
|
441
|
+
"description": "Statistical measures, outlier detection, trend analysis",
|
|
442
|
+
"modules": [
|
|
443
|
+
"oscura.analyzers.statistics.basic",
|
|
444
|
+
"oscura.analyzers.statistics.advanced",
|
|
445
|
+
"oscura.analyzers.statistics.correlation",
|
|
446
|
+
"oscura.analyzers.statistics.distribution",
|
|
447
|
+
"oscura.analyzers.statistics.outliers",
|
|
448
|
+
"oscura.analyzers.statistics.trend",
|
|
449
|
+
"oscura.analyzers.statistical.chunked_corr",
|
|
450
|
+
],
|
|
451
|
+
"requires": ["waveform", "digital", "binary"],
|
|
452
|
+
},
|
|
453
|
+
AnalysisDomain.ENTROPY: {
|
|
454
|
+
"description": "Entropy analysis, data classification, checksum detection",
|
|
455
|
+
"modules": [
|
|
456
|
+
"oscura.analyzers.statistical.entropy",
|
|
457
|
+
"oscura.analyzers.statistical.classification",
|
|
458
|
+
"oscura.analyzers.statistical.checksum",
|
|
459
|
+
"oscura.analyzers.statistical.ngrams",
|
|
460
|
+
],
|
|
461
|
+
"requires": ["binary"],
|
|
462
|
+
},
|
|
463
|
+
AnalysisDomain.PATTERNS: {
|
|
464
|
+
"description": "Periodic patterns, motifs, signatures, clustering",
|
|
465
|
+
"modules": [
|
|
466
|
+
"oscura.analyzers.patterns.discovery",
|
|
467
|
+
"oscura.analyzers.patterns.sequences",
|
|
468
|
+
"oscura.analyzers.patterns.periodic",
|
|
469
|
+
"oscura.analyzers.patterns.matching",
|
|
470
|
+
"oscura.analyzers.patterns.clustering",
|
|
471
|
+
"oscura.analyzers.patterns.learning",
|
|
472
|
+
],
|
|
473
|
+
"requires": ["waveform", "binary", "digital"],
|
|
474
|
+
},
|
|
475
|
+
AnalysisDomain.JITTER: {
|
|
476
|
+
"description": "RJ, DJ, PJ, DDJ, DCD, bathtub curve, TJ at BER",
|
|
477
|
+
"modules": [
|
|
478
|
+
"oscura.analyzers.jitter.measurements",
|
|
479
|
+
"oscura.analyzers.jitter.decomposition",
|
|
480
|
+
"oscura.analyzers.jitter.spectrum",
|
|
481
|
+
"oscura.analyzers.jitter.ber",
|
|
482
|
+
],
|
|
483
|
+
"requires": ["waveform", "digital"],
|
|
484
|
+
},
|
|
485
|
+
AnalysisDomain.EYE: {
|
|
486
|
+
"description": "Eye diagram generation and metrics",
|
|
487
|
+
"modules": [
|
|
488
|
+
"oscura.analyzers.eye.diagram",
|
|
489
|
+
"oscura.analyzers.eye.metrics",
|
|
490
|
+
],
|
|
491
|
+
"requires": ["waveform", "digital"],
|
|
492
|
+
},
|
|
493
|
+
AnalysisDomain.POWER: {
|
|
494
|
+
"description": "Power measurements, efficiency, switching loss, ripple",
|
|
495
|
+
"modules": [
|
|
496
|
+
"oscura.analyzers.power.basic",
|
|
497
|
+
"oscura.analyzers.power.ac_power",
|
|
498
|
+
"oscura.analyzers.power.switching",
|
|
499
|
+
"oscura.analyzers.power.conduction",
|
|
500
|
+
"oscura.analyzers.power.efficiency",
|
|
501
|
+
"oscura.analyzers.power.ripple",
|
|
502
|
+
"oscura.analyzers.power.soa",
|
|
503
|
+
],
|
|
504
|
+
"requires": ["waveform"],
|
|
505
|
+
},
|
|
506
|
+
AnalysisDomain.PROTOCOLS: {
|
|
507
|
+
"description": "Serial protocol decoding (UART, SPI, I2C, CAN, etc.)",
|
|
508
|
+
"modules": [
|
|
509
|
+
"oscura.analyzers.protocols.uart",
|
|
510
|
+
"oscura.analyzers.protocols.spi",
|
|
511
|
+
"oscura.analyzers.protocols.i2c",
|
|
512
|
+
"oscura.analyzers.protocols.can",
|
|
513
|
+
"oscura.analyzers.protocols.can_fd",
|
|
514
|
+
"oscura.analyzers.protocols.lin",
|
|
515
|
+
"oscura.analyzers.protocols.flexray",
|
|
516
|
+
"oscura.analyzers.protocols.manchester",
|
|
517
|
+
"oscura.analyzers.protocols.onewire",
|
|
518
|
+
"oscura.analyzers.protocols.usb",
|
|
519
|
+
"oscura.analyzers.protocols.i2s",
|
|
520
|
+
"oscura.analyzers.protocols.jtag",
|
|
521
|
+
"oscura.analyzers.protocols.swd",
|
|
522
|
+
"oscura.analyzers.protocols.hdlc",
|
|
523
|
+
],
|
|
524
|
+
"requires": ["digital", "waveform"],
|
|
525
|
+
},
|
|
526
|
+
AnalysisDomain.SIGNAL_INTEGRITY: {
|
|
527
|
+
"description": "S-parameters, de-embedding, equalization",
|
|
528
|
+
"modules": [
|
|
529
|
+
"oscura.analyzers.signal_integrity.sparams",
|
|
530
|
+
"oscura.analyzers.signal_integrity.equalization",
|
|
531
|
+
"oscura.analyzers.signal_integrity.embedding",
|
|
532
|
+
],
|
|
533
|
+
"requires": ["sparams", "waveform"],
|
|
534
|
+
},
|
|
535
|
+
AnalysisDomain.PACKET: {
|
|
536
|
+
"description": "Packet metrics, throughput, latency, loss, payload analysis",
|
|
537
|
+
"modules": [
|
|
538
|
+
"oscura.analyzers.packet.metrics",
|
|
539
|
+
"oscura.analyzers.packet.parser",
|
|
540
|
+
"oscura.analyzers.packet.payload",
|
|
541
|
+
"oscura.analyzers.packet.stream",
|
|
542
|
+
"oscura.analyzers.packet.daq",
|
|
543
|
+
],
|
|
544
|
+
"requires": ["packets", "binary"],
|
|
545
|
+
},
|
|
546
|
+
AnalysisDomain.INFERENCE: {
|
|
547
|
+
"description": "Auto-inference, protocol detection, signal classification",
|
|
548
|
+
"modules": [
|
|
549
|
+
"oscura.inference.signal_intelligence", # classify_signal, assess_signal_quality, suggest_measurements
|
|
550
|
+
"oscura.inference.logic", # detect_logic_family
|
|
551
|
+
"oscura.inference.protocol", # detect_protocol
|
|
552
|
+
"oscura.inference.spectral", # auto_spectral_config
|
|
553
|
+
"oscura.inference.stream", # reassemble_udp_stream, reassemble_tcp_stream, detect_message_framing
|
|
554
|
+
"oscura.inference.binary", # detect_magic_bytes, detect_alignment, generate_parser
|
|
555
|
+
"oscura.inference.message_format", # infer_format, detect_field_types, find_dependencies
|
|
556
|
+
"oscura.inference.sequences", # detect_sequence_patterns, correlate_requests, find_message_dependencies
|
|
557
|
+
"oscura.inference.alignment", # align_global, align_local, compute_similarity
|
|
558
|
+
"oscura.inference.state_machine", # infer_rpni, minimize_dfa
|
|
559
|
+
"oscura.inference.protocol_dsl", # decode_message, load_protocol
|
|
560
|
+
"oscura.inference.protocol_library", # get_protocol, list_protocols, get_decoder
|
|
561
|
+
],
|
|
562
|
+
"requires": ["waveform", "digital", "binary", "packets"],
|
|
563
|
+
},
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
def get_available_analyses(input_type: InputType) -> list[AnalysisDomain]:
|
|
568
|
+
"""Get list of analyses applicable to input type.
|
|
569
|
+
|
|
570
|
+
Args:
|
|
571
|
+
input_type: Type of input data.
|
|
572
|
+
|
|
573
|
+
Returns:
|
|
574
|
+
List of applicable analysis domains.
|
|
575
|
+
"""
|
|
576
|
+
type_mapping = {
|
|
577
|
+
InputType.WAVEFORM: "waveform",
|
|
578
|
+
InputType.DIGITAL: "digital",
|
|
579
|
+
InputType.BINARY: "binary",
|
|
580
|
+
InputType.PCAP: "packets",
|
|
581
|
+
InputType.IQ: "waveform",
|
|
582
|
+
InputType.PACKETS: "packets",
|
|
583
|
+
InputType.SPARAMS: "sparams",
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
input_category = type_mapping.get(input_type, "waveform")
|
|
587
|
+
|
|
588
|
+
applicable = []
|
|
589
|
+
for domain, config in ANALYSIS_CAPABILITIES.items():
|
|
590
|
+
if input_category in config["requires"]:
|
|
591
|
+
applicable.append(domain)
|
|
592
|
+
|
|
593
|
+
return applicable
|
|
594
|
+
|
|
595
|
+
|
|
596
|
+
# Type alias for progress callbacks
|
|
597
|
+
ProgressCallback = Callable[[ProgressInfo], None]
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
__all__ = [
|
|
601
|
+
"ANALYSIS_CAPABILITIES",
|
|
602
|
+
"DEFAULT_SAMPLE_RATE_BINARY_HZ",
|
|
603
|
+
"DEFAULT_SAMPLE_RATE_GENERAL_HZ",
|
|
604
|
+
"DEFAULT_SAMPLE_RATE_HZ",
|
|
605
|
+
"AnalysisConfig",
|
|
606
|
+
"AnalysisDomain",
|
|
607
|
+
"AnalysisError",
|
|
608
|
+
"AnalysisResult",
|
|
609
|
+
"DataOutputConfig",
|
|
610
|
+
"DomainConfig",
|
|
611
|
+
"InputType",
|
|
612
|
+
"ProgressCallback",
|
|
613
|
+
"ProgressInfo",
|
|
614
|
+
"get_available_analyses",
|
|
615
|
+
]
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""Content generation utilities for reports."""
|
|
2
|
+
|
|
3
|
+
from oscura.reporting.content.executive import (
|
|
4
|
+
ExecutiveSummary,
|
|
5
|
+
generate_executive_summary,
|
|
6
|
+
)
|
|
7
|
+
from oscura.reporting.content.filtering import (
|
|
8
|
+
ContentFilter,
|
|
9
|
+
filter_by_audience,
|
|
10
|
+
filter_by_severity,
|
|
11
|
+
)
|
|
12
|
+
from oscura.reporting.content.minimal import (
|
|
13
|
+
MinimalContent,
|
|
14
|
+
auto_caption,
|
|
15
|
+
generate_compact_text,
|
|
16
|
+
)
|
|
17
|
+
from oscura.reporting.content.verbosity import (
|
|
18
|
+
VerbosityController,
|
|
19
|
+
VerbosityLevel,
|
|
20
|
+
apply_verbosity_level,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
# Filtering
|
|
25
|
+
"ContentFilter",
|
|
26
|
+
# Executive Summary
|
|
27
|
+
"ExecutiveSummary",
|
|
28
|
+
# Minimal
|
|
29
|
+
"MinimalContent",
|
|
30
|
+
# Verbosity
|
|
31
|
+
"VerbosityController",
|
|
32
|
+
"VerbosityLevel",
|
|
33
|
+
"apply_verbosity_level",
|
|
34
|
+
"auto_caption",
|
|
35
|
+
"filter_by_audience",
|
|
36
|
+
"filter_by_severity",
|
|
37
|
+
"generate_compact_text",
|
|
38
|
+
"generate_executive_summary",
|
|
39
|
+
]
|