oscura 0.5.1__py3-none-any.whl → 0.7.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 +169 -167
- oscura/analyzers/__init__.py +3 -0
- oscura/analyzers/classification.py +659 -0
- oscura/analyzers/digital/edges.py +325 -65
- oscura/analyzers/digital/quality.py +293 -166
- oscura/analyzers/digital/timing.py +260 -115
- oscura/analyzers/digital/timing_numba.py +334 -0
- oscura/analyzers/entropy.py +605 -0
- oscura/analyzers/eye/diagram.py +176 -109
- oscura/analyzers/eye/metrics.py +5 -5
- oscura/analyzers/jitter/__init__.py +6 -4
- oscura/analyzers/jitter/ber.py +52 -52
- oscura/analyzers/jitter/classification.py +156 -0
- oscura/analyzers/jitter/decomposition.py +163 -113
- oscura/analyzers/jitter/spectrum.py +80 -64
- oscura/analyzers/ml/__init__.py +39 -0
- oscura/analyzers/ml/features.py +600 -0
- oscura/analyzers/ml/signal_classifier.py +604 -0
- oscura/analyzers/packet/daq.py +246 -158
- oscura/analyzers/packet/parser.py +12 -1
- oscura/analyzers/packet/payload.py +50 -2110
- oscura/analyzers/packet/payload_analysis.py +361 -181
- oscura/analyzers/packet/payload_patterns.py +133 -70
- oscura/analyzers/packet/stream.py +84 -23
- oscura/analyzers/patterns/__init__.py +26 -5
- oscura/analyzers/patterns/anomaly_detection.py +908 -0
- oscura/analyzers/patterns/clustering.py +169 -108
- oscura/analyzers/patterns/clustering_optimized.py +227 -0
- oscura/analyzers/patterns/discovery.py +1 -1
- oscura/analyzers/patterns/matching.py +581 -197
- oscura/analyzers/patterns/pattern_mining.py +778 -0
- oscura/analyzers/patterns/periodic.py +121 -38
- oscura/analyzers/patterns/sequences.py +175 -78
- oscura/analyzers/power/conduction.py +1 -1
- oscura/analyzers/power/soa.py +6 -6
- oscura/analyzers/power/switching.py +250 -110
- oscura/analyzers/protocol/__init__.py +17 -1
- oscura/analyzers/protocols/base.py +6 -6
- oscura/analyzers/protocols/ble/__init__.py +38 -0
- oscura/analyzers/protocols/ble/analyzer.py +809 -0
- oscura/analyzers/protocols/ble/uuids.py +288 -0
- oscura/analyzers/protocols/can.py +257 -127
- oscura/analyzers/protocols/can_fd.py +107 -80
- oscura/analyzers/protocols/flexray.py +139 -80
- oscura/analyzers/protocols/hdlc.py +93 -58
- oscura/analyzers/protocols/i2c.py +247 -106
- oscura/analyzers/protocols/i2s.py +138 -86
- oscura/analyzers/protocols/industrial/__init__.py +40 -0
- oscura/analyzers/protocols/industrial/bacnet/__init__.py +33 -0
- oscura/analyzers/protocols/industrial/bacnet/analyzer.py +708 -0
- oscura/analyzers/protocols/industrial/bacnet/encoding.py +412 -0
- oscura/analyzers/protocols/industrial/bacnet/services.py +622 -0
- oscura/analyzers/protocols/industrial/ethercat/__init__.py +30 -0
- oscura/analyzers/protocols/industrial/ethercat/analyzer.py +474 -0
- oscura/analyzers/protocols/industrial/ethercat/mailbox.py +339 -0
- oscura/analyzers/protocols/industrial/ethercat/topology.py +166 -0
- oscura/analyzers/protocols/industrial/modbus/__init__.py +31 -0
- oscura/analyzers/protocols/industrial/modbus/analyzer.py +525 -0
- oscura/analyzers/protocols/industrial/modbus/crc.py +79 -0
- oscura/analyzers/protocols/industrial/modbus/functions.py +436 -0
- oscura/analyzers/protocols/industrial/opcua/__init__.py +21 -0
- oscura/analyzers/protocols/industrial/opcua/analyzer.py +552 -0
- oscura/analyzers/protocols/industrial/opcua/datatypes.py +446 -0
- oscura/analyzers/protocols/industrial/opcua/services.py +264 -0
- oscura/analyzers/protocols/industrial/profinet/__init__.py +23 -0
- oscura/analyzers/protocols/industrial/profinet/analyzer.py +441 -0
- oscura/analyzers/protocols/industrial/profinet/dcp.py +263 -0
- oscura/analyzers/protocols/industrial/profinet/ptcp.py +200 -0
- oscura/analyzers/protocols/jtag.py +180 -98
- oscura/analyzers/protocols/lin.py +219 -114
- oscura/analyzers/protocols/manchester.py +4 -4
- oscura/analyzers/protocols/onewire.py +253 -149
- oscura/analyzers/protocols/parallel_bus/__init__.py +20 -0
- oscura/analyzers/protocols/parallel_bus/centronics.py +92 -0
- oscura/analyzers/protocols/parallel_bus/gpib.py +137 -0
- oscura/analyzers/protocols/spi.py +192 -95
- oscura/analyzers/protocols/swd.py +321 -167
- oscura/analyzers/protocols/uart.py +267 -125
- oscura/analyzers/protocols/usb.py +235 -131
- oscura/analyzers/side_channel/power.py +17 -12
- oscura/analyzers/signal/__init__.py +15 -0
- oscura/analyzers/signal/timing_analysis.py +1086 -0
- oscura/analyzers/signal_integrity/__init__.py +4 -1
- oscura/analyzers/signal_integrity/sparams.py +2 -19
- oscura/analyzers/spectral/chunked.py +129 -60
- oscura/analyzers/spectral/chunked_fft.py +300 -94
- oscura/analyzers/spectral/chunked_wavelet.py +100 -80
- oscura/analyzers/statistical/checksum.py +376 -217
- oscura/analyzers/statistical/classification.py +229 -107
- oscura/analyzers/statistical/entropy.py +78 -53
- oscura/analyzers/statistics/correlation.py +407 -211
- oscura/analyzers/statistics/outliers.py +2 -2
- oscura/analyzers/statistics/streaming.py +30 -5
- oscura/analyzers/validation.py +216 -101
- oscura/analyzers/waveform/measurements.py +9 -0
- oscura/analyzers/waveform/measurements_with_uncertainty.py +31 -15
- oscura/analyzers/waveform/spectral.py +500 -228
- oscura/api/__init__.py +31 -5
- oscura/api/dsl/__init__.py +582 -0
- oscura/{dsl → api/dsl}/commands.py +43 -76
- oscura/{dsl → api/dsl}/interpreter.py +26 -51
- oscura/{dsl → api/dsl}/parser.py +107 -77
- oscura/{dsl → api/dsl}/repl.py +2 -2
- oscura/api/dsl.py +1 -1
- oscura/{integrations → api/integrations}/__init__.py +1 -1
- oscura/{integrations → api/integrations}/llm.py +201 -102
- oscura/api/operators.py +3 -3
- oscura/api/optimization.py +144 -30
- oscura/api/rest_server.py +921 -0
- oscura/api/server/__init__.py +17 -0
- oscura/api/server/dashboard.py +850 -0
- oscura/api/server/static/README.md +34 -0
- oscura/api/server/templates/base.html +181 -0
- oscura/api/server/templates/export.html +120 -0
- oscura/api/server/templates/home.html +284 -0
- oscura/api/server/templates/protocols.html +58 -0
- oscura/api/server/templates/reports.html +43 -0
- oscura/api/server/templates/session_detail.html +89 -0
- oscura/api/server/templates/sessions.html +83 -0
- oscura/api/server/templates/waveforms.html +73 -0
- oscura/automotive/__init__.py +8 -1
- oscura/automotive/can/__init__.py +10 -0
- oscura/automotive/can/checksum.py +3 -1
- oscura/automotive/can/dbc_generator.py +590 -0
- oscura/automotive/can/message_wrapper.py +121 -74
- oscura/automotive/can/patterns.py +98 -21
- oscura/automotive/can/session.py +292 -56
- oscura/automotive/can/state_machine.py +6 -3
- oscura/automotive/can/stimulus_response.py +97 -75
- oscura/automotive/dbc/__init__.py +10 -2
- oscura/automotive/dbc/generator.py +84 -56
- oscura/automotive/dbc/parser.py +6 -6
- oscura/automotive/dtc/data.json +17 -102
- oscura/automotive/dtc/database.py +2 -2
- oscura/automotive/flexray/__init__.py +31 -0
- oscura/automotive/flexray/analyzer.py +504 -0
- oscura/automotive/flexray/crc.py +185 -0
- oscura/automotive/flexray/fibex.py +449 -0
- oscura/automotive/j1939/__init__.py +45 -8
- oscura/automotive/j1939/analyzer.py +605 -0
- oscura/automotive/j1939/spns.py +326 -0
- oscura/automotive/j1939/transport.py +306 -0
- oscura/automotive/lin/__init__.py +47 -0
- oscura/automotive/lin/analyzer.py +612 -0
- oscura/automotive/loaders/blf.py +13 -2
- oscura/automotive/loaders/csv_can.py +143 -72
- oscura/automotive/loaders/dispatcher.py +50 -2
- oscura/automotive/loaders/mdf.py +86 -45
- oscura/automotive/loaders/pcap.py +111 -61
- oscura/automotive/uds/__init__.py +4 -0
- oscura/automotive/uds/analyzer.py +725 -0
- oscura/automotive/uds/decoder.py +140 -58
- oscura/automotive/uds/models.py +7 -1
- oscura/automotive/visualization.py +1 -1
- oscura/cli/analyze.py +348 -0
- oscura/cli/batch.py +142 -122
- oscura/cli/benchmark.py +275 -0
- oscura/cli/characterize.py +137 -82
- oscura/cli/compare.py +224 -131
- oscura/cli/completion.py +250 -0
- oscura/cli/config_cmd.py +361 -0
- oscura/cli/decode.py +164 -87
- oscura/cli/export.py +286 -0
- oscura/cli/main.py +115 -31
- oscura/{onboarding → cli/onboarding}/__init__.py +3 -3
- oscura/{onboarding → cli/onboarding}/help.py +80 -58
- oscura/{onboarding → cli/onboarding}/tutorials.py +97 -72
- oscura/{onboarding → cli/onboarding}/wizard.py +55 -36
- oscura/cli/progress.py +147 -0
- oscura/cli/shell.py +157 -135
- oscura/cli/validate_cmd.py +204 -0
- oscura/cli/visualize.py +158 -0
- oscura/convenience.py +125 -79
- oscura/core/__init__.py +4 -2
- oscura/core/backend_selector.py +3 -3
- oscura/core/cache.py +126 -15
- oscura/core/cancellation.py +1 -1
- oscura/{config → core/config}/__init__.py +20 -11
- oscura/{config → core/config}/defaults.py +1 -1
- oscura/{config → core/config}/loader.py +7 -5
- oscura/{config → core/config}/memory.py +5 -5
- oscura/{config → core/config}/migration.py +1 -1
- oscura/{config → core/config}/pipeline.py +99 -23
- oscura/{config → core/config}/preferences.py +1 -1
- oscura/{config → core/config}/protocol.py +3 -3
- oscura/{config → core/config}/schema.py +426 -272
- oscura/{config → core/config}/settings.py +1 -1
- oscura/{config → core/config}/thresholds.py +195 -153
- oscura/core/correlation.py +5 -6
- oscura/core/cross_domain.py +0 -2
- oscura/core/debug.py +9 -5
- oscura/{extensibility → core/extensibility}/docs.py +158 -70
- oscura/{extensibility → core/extensibility}/extensions.py +160 -76
- oscura/{extensibility → core/extensibility}/logging.py +1 -1
- oscura/{extensibility → core/extensibility}/measurements.py +1 -1
- oscura/{extensibility → core/extensibility}/plugins.py +1 -1
- oscura/{extensibility → core/extensibility}/templates.py +73 -3
- oscura/{extensibility → core/extensibility}/validation.py +1 -1
- oscura/core/gpu_backend.py +11 -7
- oscura/core/log_query.py +101 -11
- oscura/core/logging.py +126 -54
- oscura/core/logging_advanced.py +5 -5
- oscura/core/memory_limits.py +108 -70
- oscura/core/memory_monitor.py +2 -2
- oscura/core/memory_progress.py +7 -7
- oscura/core/memory_warnings.py +1 -1
- oscura/core/numba_backend.py +13 -13
- oscura/{plugins → core/plugins}/__init__.py +9 -9
- oscura/{plugins → core/plugins}/base.py +7 -7
- oscura/{plugins → core/plugins}/cli.py +3 -3
- oscura/{plugins → core/plugins}/discovery.py +186 -106
- oscura/{plugins → core/plugins}/lifecycle.py +1 -1
- oscura/{plugins → core/plugins}/manager.py +7 -7
- oscura/{plugins → core/plugins}/registry.py +3 -3
- oscura/{plugins → core/plugins}/versioning.py +1 -1
- oscura/core/progress.py +16 -1
- oscura/core/provenance.py +8 -2
- oscura/{schemas → core/schemas}/__init__.py +2 -2
- oscura/{schemas → core/schemas}/device_mapping.json +2 -8
- oscura/{schemas → core/schemas}/packet_format.json +4 -24
- oscura/{schemas → core/schemas}/protocol_definition.json +2 -12
- oscura/core/types.py +4 -0
- oscura/core/uncertainty.py +3 -3
- oscura/correlation/__init__.py +52 -0
- oscura/correlation/multi_protocol.py +811 -0
- oscura/discovery/auto_decoder.py +117 -35
- oscura/discovery/comparison.py +191 -86
- oscura/discovery/quality_validator.py +155 -68
- oscura/discovery/signal_detector.py +196 -79
- oscura/export/__init__.py +18 -8
- oscura/export/kaitai_struct.py +513 -0
- oscura/export/scapy_layer.py +801 -0
- oscura/export/wireshark/generator.py +1 -1
- oscura/export/wireshark/templates/dissector.lua.j2 +2 -2
- oscura/export/wireshark_dissector.py +746 -0
- oscura/guidance/wizard.py +207 -111
- oscura/hardware/__init__.py +19 -0
- oscura/{acquisition → hardware/acquisition}/__init__.py +4 -4
- oscura/{acquisition → hardware/acquisition}/file.py +2 -2
- oscura/{acquisition → hardware/acquisition}/hardware.py +7 -7
- oscura/{acquisition → hardware/acquisition}/saleae.py +15 -12
- oscura/{acquisition → hardware/acquisition}/socketcan.py +1 -1
- oscura/{acquisition → hardware/acquisition}/streaming.py +2 -2
- oscura/{acquisition → hardware/acquisition}/synthetic.py +3 -3
- oscura/{acquisition → hardware/acquisition}/visa.py +33 -11
- oscura/hardware/firmware/__init__.py +29 -0
- oscura/hardware/firmware/pattern_recognition.py +874 -0
- oscura/hardware/hal_detector.py +736 -0
- oscura/hardware/security/__init__.py +37 -0
- oscura/hardware/security/side_channel_detector.py +1126 -0
- oscura/inference/__init__.py +4 -0
- oscura/inference/active_learning/observation_table.py +4 -1
- oscura/inference/alignment.py +216 -123
- oscura/inference/bayesian.py +113 -33
- oscura/inference/crc_reverse.py +101 -55
- oscura/inference/logic.py +6 -2
- oscura/inference/message_format.py +342 -183
- oscura/inference/protocol.py +95 -44
- oscura/inference/protocol_dsl.py +180 -82
- oscura/inference/signal_intelligence.py +1439 -706
- oscura/inference/spectral.py +99 -57
- oscura/inference/state_machine.py +810 -158
- oscura/inference/stream.py +270 -110
- oscura/iot/__init__.py +34 -0
- oscura/iot/coap/__init__.py +32 -0
- oscura/iot/coap/analyzer.py +668 -0
- oscura/iot/coap/options.py +212 -0
- oscura/iot/lorawan/__init__.py +21 -0
- oscura/iot/lorawan/crypto.py +206 -0
- oscura/iot/lorawan/decoder.py +801 -0
- oscura/iot/lorawan/mac_commands.py +341 -0
- oscura/iot/mqtt/__init__.py +27 -0
- oscura/iot/mqtt/analyzer.py +999 -0
- oscura/iot/mqtt/properties.py +315 -0
- oscura/iot/zigbee/__init__.py +31 -0
- oscura/iot/zigbee/analyzer.py +615 -0
- oscura/iot/zigbee/security.py +153 -0
- oscura/iot/zigbee/zcl.py +349 -0
- oscura/jupyter/display.py +125 -45
- oscura/{exploratory → jupyter/exploratory}/__init__.py +8 -8
- oscura/{exploratory → jupyter/exploratory}/error_recovery.py +298 -141
- oscura/jupyter/exploratory/fuzzy.py +746 -0
- oscura/{exploratory → jupyter/exploratory}/fuzzy_advanced.py +258 -100
- oscura/{exploratory → jupyter/exploratory}/legacy.py +464 -242
- oscura/{exploratory → jupyter/exploratory}/parse.py +167 -145
- oscura/{exploratory → jupyter/exploratory}/recovery.py +119 -87
- oscura/jupyter/exploratory/sync.py +612 -0
- oscura/{exploratory → jupyter/exploratory}/unknown.py +299 -176
- oscura/jupyter/magic.py +4 -4
- oscura/{ui → jupyter/ui}/__init__.py +2 -2
- oscura/{ui → jupyter/ui}/formatters.py +3 -3
- oscura/{ui → jupyter/ui}/progressive_display.py +153 -82
- oscura/loaders/__init__.py +183 -67
- oscura/loaders/binary.py +88 -1
- oscura/loaders/chipwhisperer.py +153 -137
- oscura/loaders/configurable.py +208 -86
- oscura/loaders/csv_loader.py +458 -215
- oscura/loaders/hdf5_loader.py +278 -119
- oscura/loaders/lazy.py +87 -54
- oscura/loaders/mmap_loader.py +1 -1
- oscura/loaders/numpy_loader.py +253 -116
- oscura/loaders/pcap.py +226 -151
- oscura/loaders/rigol.py +110 -49
- oscura/loaders/sigrok.py +201 -78
- oscura/loaders/tdms.py +81 -58
- oscura/loaders/tektronix.py +291 -174
- oscura/loaders/touchstone.py +182 -87
- oscura/loaders/tss.py +456 -0
- oscura/loaders/vcd.py +215 -117
- oscura/loaders/wav.py +155 -68
- oscura/reporting/__init__.py +9 -0
- oscura/reporting/analyze.py +352 -146
- oscura/reporting/argument_preparer.py +69 -14
- oscura/reporting/auto_report.py +97 -61
- oscura/reporting/batch.py +131 -58
- oscura/reporting/chart_selection.py +57 -45
- oscura/reporting/comparison.py +63 -17
- oscura/reporting/content/executive.py +76 -24
- oscura/reporting/core_formats/multi_format.py +11 -8
- oscura/reporting/engine.py +312 -158
- oscura/reporting/enhanced_reports.py +949 -0
- oscura/reporting/export.py +86 -43
- oscura/reporting/formatting/numbers.py +69 -42
- oscura/reporting/html.py +139 -58
- oscura/reporting/index.py +137 -65
- oscura/reporting/output.py +158 -67
- oscura/reporting/pdf.py +67 -102
- oscura/reporting/plots.py +191 -112
- oscura/reporting/sections.py +88 -47
- oscura/reporting/standards.py +104 -61
- oscura/reporting/summary_generator.py +75 -55
- oscura/reporting/tables.py +138 -54
- oscura/reporting/templates/enhanced/protocol_re.html +525 -0
- oscura/sessions/__init__.py +14 -23
- oscura/sessions/base.py +3 -3
- oscura/sessions/blackbox.py +106 -10
- oscura/sessions/generic.py +2 -2
- oscura/sessions/legacy.py +783 -0
- oscura/side_channel/__init__.py +63 -0
- oscura/side_channel/dpa.py +1025 -0
- oscura/utils/__init__.py +15 -1
- oscura/utils/bitwise.py +118 -0
- oscura/{builders → utils/builders}/__init__.py +1 -1
- oscura/{comparison → utils/comparison}/__init__.py +6 -6
- oscura/{comparison → utils/comparison}/compare.py +202 -101
- oscura/{comparison → utils/comparison}/golden.py +83 -63
- oscura/{comparison → utils/comparison}/limits.py +313 -89
- oscura/{comparison → utils/comparison}/mask.py +151 -45
- oscura/{comparison → utils/comparison}/trace_diff.py +1 -1
- oscura/{comparison → utils/comparison}/visualization.py +147 -89
- oscura/{component → utils/component}/__init__.py +3 -3
- oscura/{component → utils/component}/impedance.py +122 -58
- oscura/{component → utils/component}/reactive.py +165 -168
- oscura/{component → utils/component}/transmission_line.py +3 -3
- oscura/{filtering → utils/filtering}/__init__.py +6 -6
- oscura/{filtering → utils/filtering}/base.py +1 -1
- oscura/{filtering → utils/filtering}/convenience.py +2 -2
- oscura/{filtering → utils/filtering}/design.py +169 -93
- oscura/{filtering → utils/filtering}/filters.py +2 -2
- oscura/{filtering → utils/filtering}/introspection.py +2 -2
- oscura/utils/geometry.py +31 -0
- oscura/utils/imports.py +184 -0
- oscura/utils/lazy.py +1 -1
- oscura/{math → utils/math}/__init__.py +2 -2
- oscura/{math → utils/math}/arithmetic.py +114 -48
- oscura/{math → utils/math}/interpolation.py +139 -106
- oscura/utils/memory.py +129 -66
- oscura/utils/memory_advanced.py +92 -9
- oscura/utils/memory_extensions.py +10 -8
- oscura/{optimization → utils/optimization}/__init__.py +1 -1
- oscura/{optimization → utils/optimization}/search.py +2 -2
- oscura/utils/performance/__init__.py +58 -0
- oscura/utils/performance/caching.py +889 -0
- oscura/utils/performance/lsh_clustering.py +333 -0
- oscura/utils/performance/memory_optimizer.py +699 -0
- oscura/utils/performance/optimizations.py +675 -0
- oscura/utils/performance/parallel.py +654 -0
- oscura/utils/performance/profiling.py +661 -0
- oscura/{pipeline → utils/pipeline}/base.py +1 -1
- oscura/{pipeline → utils/pipeline}/composition.py +1 -1
- oscura/{pipeline → utils/pipeline}/parallel.py +3 -2
- oscura/{pipeline → utils/pipeline}/pipeline.py +1 -1
- oscura/{pipeline → utils/pipeline}/reverse_engineering.py +412 -221
- oscura/{search → utils/search}/__init__.py +3 -3
- oscura/{search → utils/search}/anomaly.py +188 -58
- oscura/utils/search/context.py +294 -0
- oscura/{search → utils/search}/pattern.py +138 -10
- oscura/utils/serial.py +51 -0
- oscura/utils/storage/__init__.py +61 -0
- oscura/utils/storage/database.py +1166 -0
- oscura/{streaming → utils/streaming}/chunked.py +302 -143
- oscura/{streaming → utils/streaming}/progressive.py +1 -1
- oscura/{streaming → utils/streaming}/realtime.py +3 -2
- oscura/{triggering → utils/triggering}/__init__.py +6 -6
- oscura/{triggering → utils/triggering}/base.py +6 -6
- oscura/{triggering → utils/triggering}/edge.py +2 -2
- oscura/{triggering → utils/triggering}/pattern.py +2 -2
- oscura/{triggering → utils/triggering}/pulse.py +115 -74
- oscura/{triggering → utils/triggering}/window.py +2 -2
- oscura/utils/validation.py +32 -0
- oscura/validation/__init__.py +121 -0
- oscura/{compliance → validation/compliance}/__init__.py +5 -5
- oscura/{compliance → validation/compliance}/advanced.py +5 -5
- oscura/{compliance → validation/compliance}/masks.py +1 -1
- oscura/{compliance → validation/compliance}/reporting.py +127 -53
- oscura/{compliance → validation/compliance}/testing.py +114 -52
- oscura/validation/compliance_tests.py +915 -0
- oscura/validation/fuzzer.py +990 -0
- oscura/validation/grammar_tests.py +596 -0
- oscura/validation/grammar_validator.py +904 -0
- oscura/validation/hil_testing.py +977 -0
- oscura/{quality → validation/quality}/__init__.py +4 -4
- oscura/{quality → validation/quality}/ensemble.py +251 -171
- oscura/{quality → validation/quality}/explainer.py +3 -3
- oscura/{quality → validation/quality}/scoring.py +1 -1
- oscura/{quality → validation/quality}/warnings.py +4 -4
- oscura/validation/regression_suite.py +808 -0
- oscura/validation/replay.py +788 -0
- oscura/{testing → validation/testing}/__init__.py +2 -2
- oscura/{testing → validation/testing}/synthetic.py +5 -5
- oscura/visualization/__init__.py +9 -0
- oscura/visualization/accessibility.py +1 -1
- oscura/visualization/annotations.py +64 -67
- oscura/visualization/colors.py +7 -7
- oscura/visualization/digital.py +180 -81
- oscura/visualization/eye.py +236 -85
- oscura/visualization/interactive.py +320 -143
- oscura/visualization/jitter.py +587 -247
- oscura/visualization/layout.py +169 -134
- oscura/visualization/optimization.py +103 -52
- oscura/visualization/palettes.py +1 -1
- oscura/visualization/power.py +427 -211
- oscura/visualization/power_extended.py +626 -297
- oscura/visualization/presets.py +2 -0
- oscura/visualization/protocols.py +495 -181
- oscura/visualization/render.py +79 -63
- oscura/visualization/reverse_engineering.py +171 -124
- oscura/visualization/signal_integrity.py +460 -279
- oscura/visualization/specialized.py +190 -100
- oscura/visualization/spectral.py +670 -255
- oscura/visualization/thumbnails.py +166 -137
- oscura/visualization/waveform.py +150 -63
- oscura/workflows/__init__.py +3 -0
- oscura/{batch → workflows/batch}/__init__.py +5 -5
- oscura/{batch → workflows/batch}/advanced.py +150 -75
- oscura/workflows/batch/aggregate.py +531 -0
- oscura/workflows/batch/analyze.py +236 -0
- oscura/{batch → workflows/batch}/logging.py +2 -2
- oscura/{batch → workflows/batch}/metrics.py +1 -1
- oscura/workflows/complete_re.py +1144 -0
- oscura/workflows/compliance.py +44 -54
- oscura/workflows/digital.py +197 -51
- oscura/workflows/legacy/__init__.py +12 -0
- oscura/{workflow → workflows/legacy}/dag.py +4 -1
- oscura/workflows/multi_trace.py +9 -9
- oscura/workflows/power.py +42 -62
- oscura/workflows/protocol.py +82 -49
- oscura/workflows/reverse_engineering.py +351 -150
- oscura/workflows/signal_integrity.py +157 -82
- oscura-0.7.0.dist-info/METADATA +661 -0
- oscura-0.7.0.dist-info/RECORD +591 -0
- oscura/batch/aggregate.py +0 -300
- oscura/batch/analyze.py +0 -139
- oscura/dsl/__init__.py +0 -73
- oscura/exceptions.py +0 -59
- oscura/exploratory/fuzzy.py +0 -513
- oscura/exploratory/sync.py +0 -384
- oscura/exporters/__init__.py +0 -94
- oscura/exporters/csv.py +0 -303
- oscura/exporters/exporters.py +0 -44
- oscura/exporters/hdf5.py +0 -217
- oscura/exporters/html_export.py +0 -701
- oscura/exporters/json_export.py +0 -291
- oscura/exporters/markdown_export.py +0 -367
- oscura/exporters/matlab_export.py +0 -354
- oscura/exporters/npz_export.py +0 -219
- oscura/exporters/spice_export.py +0 -210
- oscura/search/context.py +0 -149
- oscura/session/__init__.py +0 -34
- oscura/session/annotations.py +0 -289
- oscura/session/history.py +0 -313
- oscura/session/session.py +0 -520
- oscura/workflow/__init__.py +0 -13
- oscura-0.5.1.dist-info/METADATA +0 -583
- oscura-0.5.1.dist-info/RECORD +0 -481
- /oscura/core/{config.py → config/legacy.py} +0 -0
- /oscura/{extensibility → core/extensibility}/__init__.py +0 -0
- /oscura/{extensibility → core/extensibility}/registry.py +0 -0
- /oscura/{plugins → core/plugins}/isolation.py +0 -0
- /oscura/{schemas → core/schemas}/bus_configuration.json +0 -0
- /oscura/{builders → utils/builders}/signal_builder.py +0 -0
- /oscura/{optimization → utils/optimization}/parallel.py +0 -0
- /oscura/{pipeline → utils/pipeline}/__init__.py +0 -0
- /oscura/{streaming → utils/streaming}/__init__.py +0 -0
- {oscura-0.5.1.dist-info → oscura-0.7.0.dist-info}/WHEEL +0 -0
- {oscura-0.5.1.dist-info → oscura-0.7.0.dist-info}/entry_points.txt +0 -0
- {oscura-0.5.1.dist-info → oscura-0.7.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -4,7 +4,7 @@ Provides digital pattern matching for multi-channel logic signals.
|
|
|
4
4
|
Supports exact matches, wildcards, and edge conditions.
|
|
5
5
|
|
|
6
6
|
Example:
|
|
7
|
-
>>> from oscura.triggering.pattern import PatternTrigger, find_pattern
|
|
7
|
+
>>> from oscura.utils.triggering.pattern import PatternTrigger, find_pattern
|
|
8
8
|
>>> # Find pattern 1010 on 4 channels
|
|
9
9
|
>>> trigger = PatternTrigger(pattern=[1, 0, 1, 0])
|
|
10
10
|
>>> events = trigger.find_events(trace)
|
|
@@ -18,7 +18,7 @@ import numpy as np
|
|
|
18
18
|
|
|
19
19
|
from oscura.core.exceptions import AnalysisError
|
|
20
20
|
from oscura.core.types import DigitalTrace, WaveformTrace
|
|
21
|
-
from oscura.triggering.base import (
|
|
21
|
+
from oscura.utils.triggering.base import (
|
|
22
22
|
Trigger,
|
|
23
23
|
TriggerEvent,
|
|
24
24
|
TriggerType,
|
|
@@ -4,7 +4,7 @@ Provides pulse width triggering, glitch detection, and runt pulse
|
|
|
4
4
|
detection for signal integrity analysis.
|
|
5
5
|
|
|
6
6
|
Example:
|
|
7
|
-
>>> from oscura.triggering.pulse import PulseWidthTrigger, find_glitches
|
|
7
|
+
>>> from oscura.utils.triggering.pulse import PulseWidthTrigger, find_glitches
|
|
8
8
|
>>> # Find pulses between 100ns and 200ns
|
|
9
9
|
>>> trigger = PulseWidthTrigger(level=1.5, min_width=100e-9, max_width=200e-9)
|
|
10
10
|
>>> events = trigger.find_events(trace)
|
|
@@ -18,10 +18,11 @@ from dataclasses import dataclass
|
|
|
18
18
|
from typing import Literal
|
|
19
19
|
|
|
20
20
|
import numpy as np
|
|
21
|
+
from numpy.typing import NDArray
|
|
21
22
|
|
|
22
23
|
from oscura.core.exceptions import AnalysisError
|
|
23
24
|
from oscura.core.types import DigitalTrace, WaveformTrace
|
|
24
|
-
from oscura.triggering.base import (
|
|
25
|
+
from oscura.utils.triggering.base import (
|
|
25
26
|
Trigger,
|
|
26
27
|
TriggerEvent,
|
|
27
28
|
TriggerType,
|
|
@@ -307,6 +308,101 @@ class RuntTrigger(Trigger):
|
|
|
307
308
|
self.high_threshold = high_threshold
|
|
308
309
|
self.polarity = polarity
|
|
309
310
|
|
|
311
|
+
def _get_zone(self, value: float) -> int:
|
|
312
|
+
"""Get zone for a signal value.
|
|
313
|
+
|
|
314
|
+
Args:
|
|
315
|
+
value: Signal value
|
|
316
|
+
|
|
317
|
+
Returns:
|
|
318
|
+
Zone index (0=low, 1=middle, 2=high)
|
|
319
|
+
"""
|
|
320
|
+
if value < self.low_threshold:
|
|
321
|
+
return 0
|
|
322
|
+
if value > self.high_threshold:
|
|
323
|
+
return 2
|
|
324
|
+
return 1
|
|
325
|
+
|
|
326
|
+
def _find_positive_runt(
|
|
327
|
+
self,
|
|
328
|
+
zones: NDArray[np.int_],
|
|
329
|
+
data: NDArray[np.float64],
|
|
330
|
+
start_idx: int,
|
|
331
|
+
sample_period: float,
|
|
332
|
+
) -> tuple[TriggerEvent | None, int]:
|
|
333
|
+
"""Find positive runt pulse starting at index.
|
|
334
|
+
|
|
335
|
+
Args:
|
|
336
|
+
zones: Zone classification array
|
|
337
|
+
data: Signal data
|
|
338
|
+
start_idx: Starting index
|
|
339
|
+
sample_period: Sample period
|
|
340
|
+
|
|
341
|
+
Returns:
|
|
342
|
+
Tuple of (event or None, next index)
|
|
343
|
+
"""
|
|
344
|
+
j = start_idx + 1
|
|
345
|
+
while j < len(zones) and zones[j] == 1:
|
|
346
|
+
j += 1
|
|
347
|
+
|
|
348
|
+
if j < len(zones) and zones[j] == 0:
|
|
349
|
+
peak = float(np.max(data[start_idx : j + 1]))
|
|
350
|
+
event = TriggerEvent(
|
|
351
|
+
timestamp=start_idx * sample_period,
|
|
352
|
+
sample_index=start_idx,
|
|
353
|
+
event_type=TriggerType.RUNT,
|
|
354
|
+
level=peak,
|
|
355
|
+
duration=(j - start_idx) * sample_period,
|
|
356
|
+
data={
|
|
357
|
+
"polarity": "positive",
|
|
358
|
+
"expected_high": self.high_threshold,
|
|
359
|
+
"actual_peak": peak,
|
|
360
|
+
},
|
|
361
|
+
)
|
|
362
|
+
return event, j
|
|
363
|
+
|
|
364
|
+
return None, j
|
|
365
|
+
|
|
366
|
+
def _find_negative_runt(
|
|
367
|
+
self,
|
|
368
|
+
zones: NDArray[np.int_],
|
|
369
|
+
data: NDArray[np.float64],
|
|
370
|
+
start_idx: int,
|
|
371
|
+
sample_period: float,
|
|
372
|
+
) -> tuple[TriggerEvent | None, int]:
|
|
373
|
+
"""Find negative runt pulse starting at index.
|
|
374
|
+
|
|
375
|
+
Args:
|
|
376
|
+
zones: Zone classification array
|
|
377
|
+
data: Signal data
|
|
378
|
+
start_idx: Starting index
|
|
379
|
+
sample_period: Sample period
|
|
380
|
+
|
|
381
|
+
Returns:
|
|
382
|
+
Tuple of (event or None, next index)
|
|
383
|
+
"""
|
|
384
|
+
j = start_idx + 1
|
|
385
|
+
while j < len(zones) and zones[j] == 1:
|
|
386
|
+
j += 1
|
|
387
|
+
|
|
388
|
+
if j < len(zones) and zones[j] == 2:
|
|
389
|
+
trough = float(np.min(data[start_idx : j + 1]))
|
|
390
|
+
event = TriggerEvent(
|
|
391
|
+
timestamp=start_idx * sample_period,
|
|
392
|
+
sample_index=start_idx,
|
|
393
|
+
event_type=TriggerType.RUNT,
|
|
394
|
+
level=trough,
|
|
395
|
+
duration=(j - start_idx) * sample_period,
|
|
396
|
+
data={
|
|
397
|
+
"polarity": "negative",
|
|
398
|
+
"expected_low": self.low_threshold,
|
|
399
|
+
"actual_trough": trough,
|
|
400
|
+
},
|
|
401
|
+
)
|
|
402
|
+
return event, j
|
|
403
|
+
|
|
404
|
+
return None, j
|
|
405
|
+
|
|
310
406
|
def find_events(
|
|
311
407
|
self,
|
|
312
408
|
trace: WaveformTrace | DigitalTrace,
|
|
@@ -320,88 +416,33 @@ class RuntTrigger(Trigger):
|
|
|
320
416
|
List of trigger events for each runt pulse.
|
|
321
417
|
"""
|
|
322
418
|
if isinstance(trace, DigitalTrace):
|
|
323
|
-
# Digital traces don't have runts
|
|
324
419
|
return []
|
|
325
420
|
|
|
326
421
|
data = trace.data
|
|
327
422
|
sample_period = trace.metadata.time_base
|
|
328
423
|
events: list[TriggerEvent] = []
|
|
329
424
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
# Zone 1: between thresholds
|
|
333
|
-
# Zone 2: above high_threshold
|
|
334
|
-
def get_zone(value: float) -> int:
|
|
335
|
-
if value < self.low_threshold:
|
|
336
|
-
return 0
|
|
337
|
-
elif value > self.high_threshold:
|
|
338
|
-
return 2
|
|
339
|
-
else:
|
|
340
|
-
return 1
|
|
341
|
-
|
|
342
|
-
zones = np.array([get_zone(v) for v in data])
|
|
343
|
-
|
|
344
|
-
# Find runt pulses: transitions that enter zone 1 but don't reach the other side
|
|
425
|
+
zones = np.array([self._get_zone(v) for v in data])
|
|
426
|
+
|
|
345
427
|
i = 0
|
|
346
428
|
while i < len(zones) - 1:
|
|
347
429
|
curr_zone = zones[i]
|
|
348
430
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
timestamp=start_idx * sample_period,
|
|
365
|
-
sample_index=start_idx,
|
|
366
|
-
event_type=TriggerType.RUNT,
|
|
367
|
-
level=peak,
|
|
368
|
-
duration=(j - start_idx) * sample_period,
|
|
369
|
-
data={
|
|
370
|
-
"polarity": "positive",
|
|
371
|
-
"expected_high": self.high_threshold,
|
|
372
|
-
"actual_peak": peak,
|
|
373
|
-
},
|
|
374
|
-
)
|
|
375
|
-
)
|
|
376
|
-
i = j
|
|
377
|
-
continue
|
|
378
|
-
|
|
379
|
-
elif curr_zone == 2:
|
|
380
|
-
# Starting high - look for negative runt
|
|
381
|
-
if self.polarity in ("negative", "either") and zones[i + 1] == 1:
|
|
382
|
-
start_idx = i
|
|
383
|
-
j = i + 1
|
|
384
|
-
while j < len(zones) and zones[j] == 1:
|
|
385
|
-
j += 1
|
|
386
|
-
if j < len(zones) and zones[j] == 2:
|
|
387
|
-
# Returned to high without reaching low - RUNT
|
|
388
|
-
trough = float(np.min(data[start_idx : j + 1]))
|
|
389
|
-
events.append(
|
|
390
|
-
TriggerEvent(
|
|
391
|
-
timestamp=start_idx * sample_period,
|
|
392
|
-
sample_index=start_idx,
|
|
393
|
-
event_type=TriggerType.RUNT,
|
|
394
|
-
level=trough,
|
|
395
|
-
duration=(j - start_idx) * sample_period,
|
|
396
|
-
data={
|
|
397
|
-
"polarity": "negative",
|
|
398
|
-
"expected_low": self.low_threshold,
|
|
399
|
-
"actual_trough": trough,
|
|
400
|
-
},
|
|
401
|
-
)
|
|
402
|
-
)
|
|
403
|
-
i = j
|
|
404
|
-
continue
|
|
431
|
+
# Check for positive runt (starting from zone 0)
|
|
432
|
+
if curr_zone == 0 and self.polarity in ("positive", "either") and zones[i + 1] == 1:
|
|
433
|
+
event, next_i = self._find_positive_runt(zones, data, i, sample_period)
|
|
434
|
+
if event:
|
|
435
|
+
events.append(event)
|
|
436
|
+
i = next_i
|
|
437
|
+
continue
|
|
438
|
+
|
|
439
|
+
# Check for negative runt (starting from zone 2)
|
|
440
|
+
if curr_zone == 2 and self.polarity in ("negative", "either") and zones[i + 1] == 1:
|
|
441
|
+
event, next_i = self._find_negative_runt(zones, data, i, sample_period)
|
|
442
|
+
if event:
|
|
443
|
+
events.append(event)
|
|
444
|
+
i = next_i
|
|
445
|
+
continue
|
|
405
446
|
|
|
406
447
|
i += 1
|
|
407
448
|
|
|
@@ -4,7 +4,7 @@ Provides window triggering (signal inside/outside voltage window) and
|
|
|
4
4
|
zone triggering (signal enters/exits defined zones) for limit testing.
|
|
5
5
|
|
|
6
6
|
Example:
|
|
7
|
-
>>> from oscura.triggering.window import WindowTrigger, find_window_violations
|
|
7
|
+
>>> from oscura.utils.triggering.window import WindowTrigger, find_window_violations
|
|
8
8
|
>>> # Trigger when signal exits 0-3.3V window
|
|
9
9
|
>>> trigger = WindowTrigger(low_threshold=0, high_threshold=3.3, trigger_on="exit")
|
|
10
10
|
>>> violations = trigger.find_events(trace)
|
|
@@ -18,7 +18,7 @@ from typing import TYPE_CHECKING, Literal
|
|
|
18
18
|
import numpy as np
|
|
19
19
|
|
|
20
20
|
from oscura.core.exceptions import AnalysisError
|
|
21
|
-
from oscura.triggering.base import (
|
|
21
|
+
from oscura.utils.triggering.base import (
|
|
22
22
|
Trigger,
|
|
23
23
|
TriggerEvent,
|
|
24
24
|
TriggerType,
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""Validation utility functions.
|
|
2
|
+
|
|
3
|
+
This module provides validation helpers used across export and other modules.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from oscura.workflows.reverse_engineering import ProtocolSpec
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def validate_protocol_spec(spec: "ProtocolSpec") -> None:
|
|
13
|
+
"""Validate protocol specification.
|
|
14
|
+
|
|
15
|
+
Ensures protocol specification has required fields and is well-formed.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
spec: Protocol specification to validate
|
|
19
|
+
|
|
20
|
+
Raises:
|
|
21
|
+
ValueError: If spec is invalid (missing name or fields)
|
|
22
|
+
|
|
23
|
+
Example:
|
|
24
|
+
>>> from oscura.analyzers.protocols.base import ProtocolSpec
|
|
25
|
+
>>> spec = ProtocolSpec(name="MyProtocol", fields=[...])
|
|
26
|
+
>>> validate_protocol_spec(spec) # No error if valid
|
|
27
|
+
"""
|
|
28
|
+
if not spec.name:
|
|
29
|
+
raise ValueError("Protocol name is required")
|
|
30
|
+
|
|
31
|
+
if not spec.fields:
|
|
32
|
+
raise ValueError("Protocol must have at least one field")
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"""Validation and test generation for protocol specifications.
|
|
2
|
+
|
|
3
|
+
This module provides tools for generating test vectors, validating protocol
|
|
4
|
+
implementations, fuzzing protocol parsers, and replaying messages to verify
|
|
5
|
+
reverse-engineered protocols.
|
|
6
|
+
|
|
7
|
+
Example:
|
|
8
|
+
>>> from oscura.validation import GrammarTestGenerator, TestGenerationConfig
|
|
9
|
+
>>> from oscura.sessions import ProtocolSpec
|
|
10
|
+
>>>
|
|
11
|
+
>>> config = TestGenerationConfig(strategy="coverage", num_tests=100)
|
|
12
|
+
>>> generator = GrammarTestGenerator(config)
|
|
13
|
+
>>> tests = generator.generate_tests(protocol_spec)
|
|
14
|
+
>>> print(f"Generated {len(tests.valid_messages)} valid messages")
|
|
15
|
+
>>>
|
|
16
|
+
>>> # Replay validation
|
|
17
|
+
>>> from oscura.validation import ReplayConfig, ReplayValidator
|
|
18
|
+
>>> replay_config = ReplayConfig(interface="serial", port="/dev/ttyUSB0")
|
|
19
|
+
>>> validator = ReplayValidator(replay_config)
|
|
20
|
+
>>> result = validator.validate_protocol(protocol_spec, test_messages)
|
|
21
|
+
>>>
|
|
22
|
+
>>> # Fuzzing
|
|
23
|
+
>>> from oscura.validation import ProtocolFuzzer, FuzzingConfig
|
|
24
|
+
>>> fuzzer_config = FuzzingConfig(strategy="coverage_guided", max_iterations=1000)
|
|
25
|
+
>>> fuzzer = ProtocolFuzzer(fuzzer_config)
|
|
26
|
+
>>> report = fuzzer.fuzz_protocol(protocol_spec, seed_corpus)
|
|
27
|
+
>>> print(f"Found {report.total_crashes} crashes")
|
|
28
|
+
|
|
29
|
+
Modules:
|
|
30
|
+
grammar_tests: Grammar-based test vector generation and fuzzing
|
|
31
|
+
replay: Protocol replay validation framework
|
|
32
|
+
fuzzer: Advanced protocol fuzzing with coverage-guided mutation
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
from oscura.validation.compliance_tests import (
|
|
36
|
+
ComplianceConfig,
|
|
37
|
+
ComplianceTestGenerator,
|
|
38
|
+
ComplianceTestSuite,
|
|
39
|
+
StandardType,
|
|
40
|
+
TestCase,
|
|
41
|
+
TestType,
|
|
42
|
+
)
|
|
43
|
+
from oscura.validation.fuzzer import (
|
|
44
|
+
FuzzingConfig,
|
|
45
|
+
FuzzingReport,
|
|
46
|
+
FuzzingResult,
|
|
47
|
+
FuzzingStrategy,
|
|
48
|
+
MutationOperator,
|
|
49
|
+
ProtocolFuzzer,
|
|
50
|
+
TestResult,
|
|
51
|
+
)
|
|
52
|
+
from oscura.validation.grammar_tests import (
|
|
53
|
+
GeneratedTests,
|
|
54
|
+
GrammarTestGenerator,
|
|
55
|
+
TestGenerationConfig,
|
|
56
|
+
)
|
|
57
|
+
from oscura.validation.grammar_validator import (
|
|
58
|
+
ErrorSeverity,
|
|
59
|
+
ErrorType,
|
|
60
|
+
ProtocolGrammarValidator,
|
|
61
|
+
ValidationError,
|
|
62
|
+
ValidationReport,
|
|
63
|
+
)
|
|
64
|
+
from oscura.validation.hil_testing import (
|
|
65
|
+
HILConfig,
|
|
66
|
+
HILTester,
|
|
67
|
+
HILTestReport,
|
|
68
|
+
HILTestResult,
|
|
69
|
+
InterfaceType,
|
|
70
|
+
TestStatus,
|
|
71
|
+
)
|
|
72
|
+
from oscura.validation.regression_suite import (
|
|
73
|
+
ComparisonMode,
|
|
74
|
+
RegressionReport,
|
|
75
|
+
RegressionTestResult,
|
|
76
|
+
RegressionTestSuite,
|
|
77
|
+
)
|
|
78
|
+
from oscura.validation.replay import (
|
|
79
|
+
ProtocolSpec,
|
|
80
|
+
ReplayConfig,
|
|
81
|
+
ReplayValidator,
|
|
82
|
+
ValidationResult,
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
__all__ = [
|
|
86
|
+
"ComparisonMode",
|
|
87
|
+
"ComplianceConfig",
|
|
88
|
+
"ComplianceTestGenerator",
|
|
89
|
+
"ComplianceTestSuite",
|
|
90
|
+
"ErrorSeverity",
|
|
91
|
+
"ErrorType",
|
|
92
|
+
"FuzzingConfig",
|
|
93
|
+
"FuzzingReport",
|
|
94
|
+
"FuzzingResult",
|
|
95
|
+
"FuzzingStrategy",
|
|
96
|
+
"GeneratedTests",
|
|
97
|
+
"GrammarTestGenerator",
|
|
98
|
+
"HILConfig",
|
|
99
|
+
"HILTestReport",
|
|
100
|
+
"HILTestResult",
|
|
101
|
+
"HILTester",
|
|
102
|
+
"InterfaceType",
|
|
103
|
+
"MutationOperator",
|
|
104
|
+
"ProtocolFuzzer",
|
|
105
|
+
"ProtocolGrammarValidator",
|
|
106
|
+
"ProtocolSpec",
|
|
107
|
+
"RegressionReport",
|
|
108
|
+
"RegressionTestResult",
|
|
109
|
+
"RegressionTestSuite",
|
|
110
|
+
"ReplayConfig",
|
|
111
|
+
"ReplayValidator",
|
|
112
|
+
"StandardType",
|
|
113
|
+
"TestCase",
|
|
114
|
+
"TestGenerationConfig",
|
|
115
|
+
"TestResult",
|
|
116
|
+
"TestStatus",
|
|
117
|
+
"TestType",
|
|
118
|
+
"ValidationError",
|
|
119
|
+
"ValidationReport",
|
|
120
|
+
"ValidationResult",
|
|
121
|
+
]
|
|
@@ -7,7 +7,7 @@ and MIL-STD standards.
|
|
|
7
7
|
|
|
8
8
|
Example:
|
|
9
9
|
>>> import oscura as osc
|
|
10
|
-
>>> from oscura.compliance import load_limit_mask, check_compliance, generate_compliance_report
|
|
10
|
+
>>> from oscura.validation.compliance import load_limit_mask, check_compliance, generate_compliance_report
|
|
11
11
|
>>>
|
|
12
12
|
>>> trace = osc.load('emissions.wfm')
|
|
13
13
|
>>> mask = load_limit_mask('FCC_Part15_ClassB')
|
|
@@ -15,7 +15,7 @@ Example:
|
|
|
15
15
|
>>> generate_compliance_report(result, 'compliance_report.html')
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
|
-
from oscura.compliance.advanced import (
|
|
18
|
+
from oscura.validation.compliance.advanced import (
|
|
19
19
|
ComplianceTestConfig,
|
|
20
20
|
ComplianceTestRunner,
|
|
21
21
|
ComplianceTestSuite,
|
|
@@ -26,17 +26,17 @@ from oscura.compliance.advanced import (
|
|
|
26
26
|
QuasiPeakDetector,
|
|
27
27
|
interpolate_limit,
|
|
28
28
|
)
|
|
29
|
-
from oscura.compliance.masks import (
|
|
29
|
+
from oscura.validation.compliance.masks import (
|
|
30
30
|
AVAILABLE_MASKS,
|
|
31
31
|
LimitMask,
|
|
32
32
|
create_custom_mask,
|
|
33
33
|
load_limit_mask,
|
|
34
34
|
)
|
|
35
|
-
from oscura.compliance.reporting import (
|
|
35
|
+
from oscura.validation.compliance.reporting import (
|
|
36
36
|
ComplianceReportFormat,
|
|
37
37
|
generate_compliance_report,
|
|
38
38
|
)
|
|
39
|
-
from oscura.compliance.testing import (
|
|
39
|
+
from oscura.validation.compliance.testing import (
|
|
40
40
|
ComplianceResult,
|
|
41
41
|
ComplianceViolation,
|
|
42
42
|
DetectorType,
|
|
@@ -22,7 +22,7 @@ import numpy as np
|
|
|
22
22
|
if TYPE_CHECKING:
|
|
23
23
|
from numpy.typing import NDArray
|
|
24
24
|
|
|
25
|
-
from oscura.compliance.masks import LimitMask
|
|
25
|
+
from oscura.validation.compliance.masks import LimitMask
|
|
26
26
|
|
|
27
27
|
logger = logging.getLogger(__name__)
|
|
28
28
|
|
|
@@ -63,7 +63,7 @@ class LimitInterpolator:
|
|
|
63
63
|
defined frequency points.
|
|
64
64
|
|
|
65
65
|
Example:
|
|
66
|
-
>>> from oscura.compliance import load_limit_mask
|
|
66
|
+
>>> from oscura.validation.compliance import load_limit_mask
|
|
67
67
|
>>> mask = load_limit_mask('FCC_Part15_ClassB')
|
|
68
68
|
>>> interp = LimitInterpolator(mask)
|
|
69
69
|
>>> limit_at_100mhz = interp.interpolate(100e6)
|
|
@@ -339,7 +339,7 @@ class ComplianceTestRunner:
|
|
|
339
339
|
Returns:
|
|
340
340
|
Self for chaining
|
|
341
341
|
"""
|
|
342
|
-
from oscura.compliance.masks import load_limit_mask
|
|
342
|
+
from oscura.validation.compliance.masks import load_limit_mask
|
|
343
343
|
|
|
344
344
|
mask = load_limit_mask(mask_name)
|
|
345
345
|
self._masks.append((mask_name, mask))
|
|
@@ -573,7 +573,7 @@ class QuasiPeakDetector:
|
|
|
573
573
|
"""
|
|
574
574
|
|
|
575
575
|
# CISPR 16-1-1 detector parameters by band
|
|
576
|
-
BAND_PARAMS = {
|
|
576
|
+
BAND_PARAMS = {
|
|
577
577
|
QPDetectorBand.BAND_A: QPDetectorParams(
|
|
578
578
|
bandwidth=200, # 200 Hz
|
|
579
579
|
charge_time=45, # ms
|
|
@@ -601,7 +601,7 @@ class QuasiPeakDetector:
|
|
|
601
601
|
}
|
|
602
602
|
|
|
603
603
|
# Frequency ranges for bands (Hz)
|
|
604
|
-
BAND_RANGES = {
|
|
604
|
+
BAND_RANGES = {
|
|
605
605
|
QPDetectorBand.BAND_A: (9e3, 150e3),
|
|
606
606
|
QPDetectorBand.BAND_B: (150e3, 30e6),
|
|
607
607
|
QPDetectorBand.BAND_C: (30e6, 300e6),
|
|
@@ -4,7 +4,7 @@ This module provides limit mask loading and management for EMC compliance testin
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
Example:
|
|
7
|
-
>>> from oscura.compliance.masks import load_limit_mask, AVAILABLE_MASKS
|
|
7
|
+
>>> from oscura.validation.compliance.masks import load_limit_mask, AVAILABLE_MASKS
|
|
8
8
|
>>> print(AVAILABLE_MASKS)
|
|
9
9
|
>>> mask = load_limit_mask('FCC_Part15_ClassB')
|
|
10
10
|
>>> print(f"Frequency range: {mask.frequency_range}")
|