oscura 0.0.1__py3-none-any.whl → 0.1.1__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.1.dist-info/METADATA +300 -0
- oscura-0.1.1.dist-info/RECORD +463 -0
- oscura-0.1.1.dist-info/entry_points.txt +2 -0
- {oscura-0.0.1.dist-info → oscura-0.1.1.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.1.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
"""S-Parameter handling and Touchstone file support.
|
|
2
|
+
|
|
3
|
+
This module provides Touchstone file loading and S-parameter
|
|
4
|
+
calculations including return loss and insertion loss.
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Example:
|
|
8
|
+
>>> from oscura.analyzers.signal_integrity.sparams import load_touchstone
|
|
9
|
+
>>> s_params = load_touchstone("cable.s2p")
|
|
10
|
+
>>> rl = return_loss(s_params, frequency=1e9)
|
|
11
|
+
|
|
12
|
+
References:
|
|
13
|
+
Touchstone 2.0 File Format Specification
|
|
14
|
+
IEEE 370-2020: Standard for Electrical Characterization
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import contextlib
|
|
20
|
+
import re
|
|
21
|
+
from dataclasses import dataclass, field
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
from typing import TYPE_CHECKING
|
|
24
|
+
|
|
25
|
+
import numpy as np
|
|
26
|
+
|
|
27
|
+
from oscura.core.exceptions import FormatError, LoaderError
|
|
28
|
+
|
|
29
|
+
if TYPE_CHECKING:
|
|
30
|
+
from numpy.typing import NDArray
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@dataclass
|
|
34
|
+
class SParameterData:
|
|
35
|
+
"""S-parameter data from Touchstone file.
|
|
36
|
+
|
|
37
|
+
Attributes:
|
|
38
|
+
frequencies: Frequency points in Hz.
|
|
39
|
+
s_matrix: Complex S-parameter matrix (n_freq x n_ports x n_ports).
|
|
40
|
+
n_ports: Number of ports.
|
|
41
|
+
z0: Reference impedance in Ohms.
|
|
42
|
+
format: Original format ("db", "ma", "ri").
|
|
43
|
+
source_file: Path to source file.
|
|
44
|
+
comments: Comments from file header.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
frequencies: NDArray[np.float64]
|
|
48
|
+
s_matrix: NDArray[np.complex128]
|
|
49
|
+
n_ports: int
|
|
50
|
+
z0: float = 50.0
|
|
51
|
+
format: str = "ri"
|
|
52
|
+
source_file: str | None = None
|
|
53
|
+
comments: list[str] = field(default_factory=list)
|
|
54
|
+
|
|
55
|
+
def __post_init__(self) -> None:
|
|
56
|
+
"""Validate S-parameter data."""
|
|
57
|
+
if len(self.frequencies) == 0:
|
|
58
|
+
raise ValueError("frequencies cannot be empty")
|
|
59
|
+
|
|
60
|
+
expected_shape = (len(self.frequencies), self.n_ports, self.n_ports)
|
|
61
|
+
if self.s_matrix.shape != expected_shape:
|
|
62
|
+
raise ValueError(
|
|
63
|
+
f"s_matrix shape {self.s_matrix.shape} does not match expected {expected_shape}"
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
def get_s(
|
|
67
|
+
self,
|
|
68
|
+
i: int,
|
|
69
|
+
j: int,
|
|
70
|
+
frequency: float | None = None,
|
|
71
|
+
) -> complex | NDArray[np.complex128]:
|
|
72
|
+
"""Get S-parameter Sij.
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
i: Output port (1-indexed).
|
|
76
|
+
j: Input port (1-indexed).
|
|
77
|
+
frequency: Frequency for interpolation (None = all).
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
Complex S-parameter value(s).
|
|
81
|
+
"""
|
|
82
|
+
# Convert to 0-indexed
|
|
83
|
+
i_idx = i - 1
|
|
84
|
+
j_idx = j - 1
|
|
85
|
+
|
|
86
|
+
if frequency is None:
|
|
87
|
+
return self.s_matrix[:, i_idx, j_idx]
|
|
88
|
+
|
|
89
|
+
# Interpolate
|
|
90
|
+
return np.interp(
|
|
91
|
+
frequency,
|
|
92
|
+
self.frequencies,
|
|
93
|
+
self.s_matrix[:, i_idx, j_idx],
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def load_touchstone(path: str | Path) -> SParameterData:
|
|
98
|
+
"""Load S-parameter data from Touchstone file.
|
|
99
|
+
|
|
100
|
+
Supports .s1p through .s8p formats and both Touchstone 1.0
|
|
101
|
+
and 2.0 file formats.
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
path: Path to Touchstone file.
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
SParameterData with loaded S-parameters.
|
|
108
|
+
|
|
109
|
+
Raises:
|
|
110
|
+
LoaderError: If file cannot be read.
|
|
111
|
+
FormatError: If file format is invalid.
|
|
112
|
+
|
|
113
|
+
Example:
|
|
114
|
+
>>> s_params = load_touchstone("cable.s2p")
|
|
115
|
+
>>> print(f"Loaded {s_params.n_ports}-port, {len(s_params.frequencies)} points")
|
|
116
|
+
|
|
117
|
+
References:
|
|
118
|
+
Touchstone 2.0 File Format Specification
|
|
119
|
+
"""
|
|
120
|
+
path = Path(path)
|
|
121
|
+
|
|
122
|
+
if not path.exists():
|
|
123
|
+
raise LoaderError(f"File not found: {path}")
|
|
124
|
+
|
|
125
|
+
# Determine number of ports from extension
|
|
126
|
+
suffix = path.suffix.lower()
|
|
127
|
+
match = re.match(r"\.s(\d+)p", suffix)
|
|
128
|
+
if not match:
|
|
129
|
+
raise FormatError(f"Unsupported file extension: {suffix}")
|
|
130
|
+
|
|
131
|
+
n_ports = int(match.group(1))
|
|
132
|
+
|
|
133
|
+
try:
|
|
134
|
+
with open(path) as f:
|
|
135
|
+
lines = f.readlines()
|
|
136
|
+
except Exception as e:
|
|
137
|
+
raise LoaderError(f"Failed to read file: {e}") # noqa: B904
|
|
138
|
+
|
|
139
|
+
return _parse_touchstone(lines, n_ports, str(path))
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def _parse_touchstone(
|
|
143
|
+
lines: list[str],
|
|
144
|
+
n_ports: int,
|
|
145
|
+
source_file: str,
|
|
146
|
+
) -> SParameterData:
|
|
147
|
+
"""Parse Touchstone file content.
|
|
148
|
+
|
|
149
|
+
Args:
|
|
150
|
+
lines: File lines.
|
|
151
|
+
n_ports: Number of ports.
|
|
152
|
+
source_file: Source file path.
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
Parsed SParameterData.
|
|
156
|
+
|
|
157
|
+
Raises:
|
|
158
|
+
FormatError: If file format is invalid.
|
|
159
|
+
"""
|
|
160
|
+
comments = []
|
|
161
|
+
option_line = None
|
|
162
|
+
data_lines = []
|
|
163
|
+
|
|
164
|
+
for line in lines:
|
|
165
|
+
line = line.strip()
|
|
166
|
+
|
|
167
|
+
if not line:
|
|
168
|
+
continue
|
|
169
|
+
|
|
170
|
+
if line.startswith("!"):
|
|
171
|
+
comments.append(line[1:].strip())
|
|
172
|
+
elif line.startswith("#"):
|
|
173
|
+
option_line = line
|
|
174
|
+
else:
|
|
175
|
+
data_lines.append(line)
|
|
176
|
+
|
|
177
|
+
# Parse option line
|
|
178
|
+
freq_unit = 1e9 # Default GHz
|
|
179
|
+
format_type = "ma" # Default MA (magnitude/angle)
|
|
180
|
+
z0 = 50.0
|
|
181
|
+
|
|
182
|
+
if option_line:
|
|
183
|
+
option_line = option_line.lower()
|
|
184
|
+
parts = option_line.split()
|
|
185
|
+
|
|
186
|
+
for i, part in enumerate(parts):
|
|
187
|
+
if part in ("hz", "khz", "mhz", "ghz"):
|
|
188
|
+
freq_unit = {
|
|
189
|
+
"hz": 1.0,
|
|
190
|
+
"khz": 1e3,
|
|
191
|
+
"mhz": 1e6,
|
|
192
|
+
"ghz": 1e9,
|
|
193
|
+
}[part]
|
|
194
|
+
elif part in ("db", "ma", "ri"):
|
|
195
|
+
format_type = part
|
|
196
|
+
elif part == "r":
|
|
197
|
+
# Reference impedance follows
|
|
198
|
+
if i + 1 < len(parts):
|
|
199
|
+
with contextlib.suppress(ValueError):
|
|
200
|
+
z0 = float(parts[i + 1])
|
|
201
|
+
|
|
202
|
+
# Parse data
|
|
203
|
+
frequencies = []
|
|
204
|
+
s_data = []
|
|
205
|
+
|
|
206
|
+
# Number of S-parameters per frequency
|
|
207
|
+
n_s_params = n_ports * n_ports
|
|
208
|
+
|
|
209
|
+
i = 0
|
|
210
|
+
while i < len(data_lines):
|
|
211
|
+
# First line has frequency and first S-parameters
|
|
212
|
+
parts = data_lines[i].split()
|
|
213
|
+
|
|
214
|
+
if len(parts) < 1:
|
|
215
|
+
i += 1
|
|
216
|
+
continue
|
|
217
|
+
|
|
218
|
+
freq = float(parts[0]) * freq_unit
|
|
219
|
+
frequencies.append(freq)
|
|
220
|
+
|
|
221
|
+
# Collect all S-parameter values for this frequency
|
|
222
|
+
s_values = []
|
|
223
|
+
|
|
224
|
+
# Add values from first line
|
|
225
|
+
for j in range(1, len(parts), 2):
|
|
226
|
+
if j + 1 < len(parts):
|
|
227
|
+
val1 = float(parts[j])
|
|
228
|
+
val2 = float(parts[j + 1])
|
|
229
|
+
s_values.append((val1, val2))
|
|
230
|
+
|
|
231
|
+
i += 1
|
|
232
|
+
|
|
233
|
+
# Continue collecting from subsequent lines if needed
|
|
234
|
+
while len(s_values) < n_s_params and i < len(data_lines):
|
|
235
|
+
parts = data_lines[i].split()
|
|
236
|
+
|
|
237
|
+
# Check if this is a new frequency (has odd number of values)
|
|
238
|
+
try:
|
|
239
|
+
float(parts[0])
|
|
240
|
+
if len(parts) % 2 == 1:
|
|
241
|
+
break # New frequency line
|
|
242
|
+
except (ValueError, IndexError):
|
|
243
|
+
pass
|
|
244
|
+
|
|
245
|
+
for j in range(0, len(parts), 2):
|
|
246
|
+
if j + 1 < len(parts):
|
|
247
|
+
val1 = float(parts[j])
|
|
248
|
+
val2 = float(parts[j + 1])
|
|
249
|
+
s_values.append((val1, val2))
|
|
250
|
+
|
|
251
|
+
i += 1
|
|
252
|
+
|
|
253
|
+
# Convert to complex based on format
|
|
254
|
+
s_complex = []
|
|
255
|
+
for val1, val2 in s_values:
|
|
256
|
+
if format_type == "ri":
|
|
257
|
+
# Real/Imaginary
|
|
258
|
+
s_complex.append(complex(val1, val2))
|
|
259
|
+
elif format_type == "ma":
|
|
260
|
+
# Magnitude/Angle (degrees)
|
|
261
|
+
mag = val1
|
|
262
|
+
angle_rad = np.radians(val2)
|
|
263
|
+
s_complex.append(mag * np.exp(1j * angle_rad))
|
|
264
|
+
elif format_type == "db":
|
|
265
|
+
# dB/Angle (degrees)
|
|
266
|
+
mag = 10 ** (val1 / 20)
|
|
267
|
+
angle_rad = np.radians(val2)
|
|
268
|
+
s_complex.append(mag * np.exp(1j * angle_rad))
|
|
269
|
+
|
|
270
|
+
# Reshape into matrix
|
|
271
|
+
if len(s_complex) == n_s_params:
|
|
272
|
+
s_matrix = np.array(s_complex).reshape(n_ports, n_ports)
|
|
273
|
+
s_data.append(s_matrix)
|
|
274
|
+
|
|
275
|
+
if len(frequencies) == 0:
|
|
276
|
+
raise FormatError("No valid frequency points found")
|
|
277
|
+
|
|
278
|
+
frequencies_arr = np.array(frequencies, dtype=np.float64)
|
|
279
|
+
s_matrix_arr = np.array(s_data, dtype=np.complex128)
|
|
280
|
+
|
|
281
|
+
return SParameterData(
|
|
282
|
+
frequencies=frequencies_arr,
|
|
283
|
+
s_matrix=s_matrix_arr,
|
|
284
|
+
n_ports=n_ports,
|
|
285
|
+
z0=z0,
|
|
286
|
+
format=format_type,
|
|
287
|
+
source_file=source_file,
|
|
288
|
+
comments=comments,
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def return_loss(
|
|
293
|
+
s_params: SParameterData,
|
|
294
|
+
frequency: float | None = None,
|
|
295
|
+
*,
|
|
296
|
+
port: int = 1,
|
|
297
|
+
) -> float | NDArray[np.float64]:
|
|
298
|
+
"""Calculate return loss from S-parameters.
|
|
299
|
+
|
|
300
|
+
Return loss = -20 * log10(|S11|)
|
|
301
|
+
|
|
302
|
+
Args:
|
|
303
|
+
s_params: S-parameter data.
|
|
304
|
+
frequency: Frequency in Hz (None = all frequencies).
|
|
305
|
+
port: Port number (1-indexed).
|
|
306
|
+
|
|
307
|
+
Returns:
|
|
308
|
+
Return loss in dB.
|
|
309
|
+
|
|
310
|
+
Example:
|
|
311
|
+
>>> rl = return_loss(s_params, frequency=1e9)
|
|
312
|
+
>>> print(f"Return loss: {rl:.1f} dB")
|
|
313
|
+
|
|
314
|
+
References:
|
|
315
|
+
IEEE 370-2020 Section 5.2
|
|
316
|
+
"""
|
|
317
|
+
s11 = s_params.get_s(port, port, frequency)
|
|
318
|
+
magnitude = np.abs(s11)
|
|
319
|
+
|
|
320
|
+
# Avoid log(0)
|
|
321
|
+
magnitude = np.maximum(magnitude, 1e-10)
|
|
322
|
+
|
|
323
|
+
rl = -20 * np.log10(magnitude)
|
|
324
|
+
|
|
325
|
+
if isinstance(rl, np.ndarray):
|
|
326
|
+
return rl
|
|
327
|
+
return float(rl)
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
def insertion_loss(
|
|
331
|
+
s_params: SParameterData,
|
|
332
|
+
frequency: float | None = None,
|
|
333
|
+
*,
|
|
334
|
+
input_port: int = 1,
|
|
335
|
+
output_port: int = 2,
|
|
336
|
+
) -> float | NDArray[np.float64]:
|
|
337
|
+
"""Calculate insertion loss from S-parameters.
|
|
338
|
+
|
|
339
|
+
Insertion loss = -20 * log10(|S21|)
|
|
340
|
+
|
|
341
|
+
Args:
|
|
342
|
+
s_params: S-parameter data.
|
|
343
|
+
frequency: Frequency in Hz (None = all frequencies).
|
|
344
|
+
input_port: Input port number (1-indexed).
|
|
345
|
+
output_port: Output port number (1-indexed).
|
|
346
|
+
|
|
347
|
+
Returns:
|
|
348
|
+
Insertion loss in dB.
|
|
349
|
+
|
|
350
|
+
Example:
|
|
351
|
+
>>> il = insertion_loss(s_params, frequency=1e9)
|
|
352
|
+
>>> print(f"Insertion loss: {il:.2f} dB")
|
|
353
|
+
|
|
354
|
+
References:
|
|
355
|
+
IEEE 370-2020 Section 5.3
|
|
356
|
+
"""
|
|
357
|
+
s21 = s_params.get_s(output_port, input_port, frequency)
|
|
358
|
+
magnitude = np.abs(s21)
|
|
359
|
+
|
|
360
|
+
# Avoid log(0)
|
|
361
|
+
magnitude = np.maximum(magnitude, 1e-10)
|
|
362
|
+
|
|
363
|
+
il = -20 * np.log10(magnitude)
|
|
364
|
+
|
|
365
|
+
if isinstance(il, np.ndarray):
|
|
366
|
+
return il
|
|
367
|
+
return float(il)
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
def s_to_abcd(
|
|
371
|
+
s_params: SParameterData,
|
|
372
|
+
frequency_idx: int | None = None,
|
|
373
|
+
) -> NDArray[np.complex128]:
|
|
374
|
+
"""Convert S-parameters to ABCD (chain) parameters.
|
|
375
|
+
|
|
376
|
+
Used for cascading networks.
|
|
377
|
+
|
|
378
|
+
Args:
|
|
379
|
+
s_params: S-parameter data (2-port only).
|
|
380
|
+
frequency_idx: Index for specific frequency (None = all).
|
|
381
|
+
|
|
382
|
+
Returns:
|
|
383
|
+
ABCD matrix (2x2) or array of matrices.
|
|
384
|
+
|
|
385
|
+
Raises:
|
|
386
|
+
ValueError: If s_params is not a 2-port network.
|
|
387
|
+
|
|
388
|
+
Example:
|
|
389
|
+
>>> abcd = s_to_abcd(s_params)
|
|
390
|
+
|
|
391
|
+
References:
|
|
392
|
+
Pozar, "Microwave Engineering", Chapter 4
|
|
393
|
+
"""
|
|
394
|
+
if s_params.n_ports != 2:
|
|
395
|
+
raise ValueError("ABCD conversion only supported for 2-port networks")
|
|
396
|
+
|
|
397
|
+
z0 = s_params.z0
|
|
398
|
+
|
|
399
|
+
if frequency_idx is not None:
|
|
400
|
+
s = s_params.s_matrix[frequency_idx]
|
|
401
|
+
return _s_to_abcd_single(s, z0)
|
|
402
|
+
|
|
403
|
+
# Convert all frequencies
|
|
404
|
+
n_freq = len(s_params.frequencies)
|
|
405
|
+
abcd = np.zeros((n_freq, 2, 2), dtype=np.complex128)
|
|
406
|
+
|
|
407
|
+
for i in range(n_freq):
|
|
408
|
+
abcd[i] = _s_to_abcd_single(s_params.s_matrix[i], z0)
|
|
409
|
+
|
|
410
|
+
return abcd
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
def _s_to_abcd_single(s: NDArray[np.complex128], z0: float) -> NDArray[np.complex128]:
|
|
414
|
+
"""Convert single frequency S-matrix to ABCD."""
|
|
415
|
+
s11, s12, s21, s22 = s[0, 0], s[0, 1], s[1, 0], s[1, 1]
|
|
416
|
+
|
|
417
|
+
denominator = 2 * s21
|
|
418
|
+
|
|
419
|
+
if abs(denominator) < 1e-12:
|
|
420
|
+
# Singular - return identity-ish
|
|
421
|
+
return np.array([[1, 0], [0, 1]], dtype=np.complex128)
|
|
422
|
+
|
|
423
|
+
A = ((1 + s11) * (1 - s22) + s12 * s21) / denominator
|
|
424
|
+
B = z0 * ((1 + s11) * (1 + s22) - s12 * s21) / denominator
|
|
425
|
+
C = ((1 - s11) * (1 - s22) - s12 * s21) / (z0 * denominator)
|
|
426
|
+
D = ((1 - s11) * (1 + s22) + s12 * s21) / denominator
|
|
427
|
+
|
|
428
|
+
return np.array([[A, B], [C, D]], dtype=np.complex128)
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
def abcd_to_s(
|
|
432
|
+
abcd: NDArray[np.complex128],
|
|
433
|
+
z0: float = 50.0,
|
|
434
|
+
) -> NDArray[np.complex128]:
|
|
435
|
+
"""Convert ABCD parameters to S-parameters.
|
|
436
|
+
|
|
437
|
+
Args:
|
|
438
|
+
abcd: ABCD matrix (2x2) or array of matrices.
|
|
439
|
+
z0: Reference impedance.
|
|
440
|
+
|
|
441
|
+
Returns:
|
|
442
|
+
S-parameter matrix.
|
|
443
|
+
|
|
444
|
+
References:
|
|
445
|
+
Pozar, "Microwave Engineering", Chapter 4
|
|
446
|
+
"""
|
|
447
|
+
if abcd.ndim == 2:
|
|
448
|
+
return _abcd_to_s_single(abcd, z0)
|
|
449
|
+
|
|
450
|
+
# Handle array of matrices
|
|
451
|
+
n_freq = abcd.shape[0]
|
|
452
|
+
s = np.zeros((n_freq, 2, 2), dtype=np.complex128)
|
|
453
|
+
|
|
454
|
+
for i in range(n_freq):
|
|
455
|
+
s[i] = _abcd_to_s_single(abcd[i], z0)
|
|
456
|
+
|
|
457
|
+
return s
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
def _abcd_to_s_single(abcd: NDArray[np.complex128], z0: float) -> NDArray[np.complex128]:
|
|
461
|
+
"""Convert single ABCD matrix to S-parameters."""
|
|
462
|
+
A, B, C, D = abcd[0, 0], abcd[0, 1], abcd[1, 0], abcd[1, 1]
|
|
463
|
+
|
|
464
|
+
denominator = A + B / z0 + C * z0 + D
|
|
465
|
+
|
|
466
|
+
if abs(denominator) < 1e-12:
|
|
467
|
+
return np.zeros((2, 2), dtype=np.complex128)
|
|
468
|
+
|
|
469
|
+
S11 = (A + B / z0 - C * z0 - D) / denominator
|
|
470
|
+
S12 = 2 * (A * D - B * C) / denominator
|
|
471
|
+
S21 = 2 / denominator
|
|
472
|
+
S22 = (-A + B / z0 - C * z0 + D) / denominator
|
|
473
|
+
|
|
474
|
+
return np.array([[S11, S12], [S21, S22]], dtype=np.complex128)
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
__all__ = [
|
|
478
|
+
"SParameterData",
|
|
479
|
+
"abcd_to_s",
|
|
480
|
+
"insertion_loss",
|
|
481
|
+
"load_touchstone",
|
|
482
|
+
"return_loss",
|
|
483
|
+
"s_to_abcd",
|
|
484
|
+
]
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""Spectral analysis module.
|
|
2
|
+
|
|
3
|
+
This module re-exports spectral analysis functions from the waveform package
|
|
4
|
+
for convenient access.
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Example:
|
|
8
|
+
>>> from oscura.analyzers.spectral import fft, psd, thd, snr
|
|
9
|
+
>>> freq, mag = fft(trace)
|
|
10
|
+
>>> thd_db = thd(trace)
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from oscura.analyzers.waveform.spectral import (
|
|
14
|
+
bartlett_psd,
|
|
15
|
+
cwt,
|
|
16
|
+
dwt,
|
|
17
|
+
enob,
|
|
18
|
+
fft,
|
|
19
|
+
fft_chunked,
|
|
20
|
+
hilbert_transform,
|
|
21
|
+
idwt,
|
|
22
|
+
mfcc,
|
|
23
|
+
periodogram,
|
|
24
|
+
psd,
|
|
25
|
+
psd_chunked,
|
|
26
|
+
sfdr,
|
|
27
|
+
sinad,
|
|
28
|
+
snr,
|
|
29
|
+
spectrogram,
|
|
30
|
+
spectrogram_chunked,
|
|
31
|
+
thd,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
__all__ = [
|
|
35
|
+
"bartlett_psd",
|
|
36
|
+
"cwt",
|
|
37
|
+
"dwt",
|
|
38
|
+
"enob",
|
|
39
|
+
"fft",
|
|
40
|
+
"fft_chunked",
|
|
41
|
+
"hilbert_transform",
|
|
42
|
+
"idwt",
|
|
43
|
+
"mfcc",
|
|
44
|
+
"periodogram",
|
|
45
|
+
"psd",
|
|
46
|
+
"psd_chunked",
|
|
47
|
+
"sfdr",
|
|
48
|
+
"sinad",
|
|
49
|
+
"snr",
|
|
50
|
+
"spectrogram",
|
|
51
|
+
"spectrogram_chunked",
|
|
52
|
+
"thd",
|
|
53
|
+
]
|