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,498 @@
|
|
|
1
|
+
"""Context-sensitive help and command suggestions.
|
|
2
|
+
|
|
3
|
+
This module provides plain English help, command suggestions based on
|
|
4
|
+
context, and result explanations for non-expert users.
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Example:
|
|
8
|
+
>>> from oscura.onboarding import get_help, suggest_commands
|
|
9
|
+
>>> get_help("rise_time")
|
|
10
|
+
>>> suggest_commands(trace)
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
from typing import Any
|
|
16
|
+
|
|
17
|
+
# Plain English help database
|
|
18
|
+
HELP_DATABASE: dict[str, dict[str, str | list[str]]] = {
|
|
19
|
+
"rise_time": {
|
|
20
|
+
"summary": "Measures how quickly a signal transitions from low to high",
|
|
21
|
+
"plain_english": """
|
|
22
|
+
Rise time tells you how fast your signal can switch from OFF to ON
|
|
23
|
+
(or from a low voltage to a high voltage). It's measured between
|
|
24
|
+
the 10% and 90% points of the transition by default.
|
|
25
|
+
|
|
26
|
+
In plain terms: A faster rise time means sharper edges on your signal,
|
|
27
|
+
which is important for high-speed digital circuits.
|
|
28
|
+
|
|
29
|
+
Typical values:
|
|
30
|
+
- Slow logic (old TTL): 10-50 nanoseconds
|
|
31
|
+
- Fast logic (modern CMOS): 0.1-2 nanoseconds
|
|
32
|
+
- High-speed serial (USB, PCIe): 50-200 picoseconds
|
|
33
|
+
""",
|
|
34
|
+
"when_to_use": [
|
|
35
|
+
"Characterizing digital buffer performance",
|
|
36
|
+
"Checking if your driver is fast enough for your data rate",
|
|
37
|
+
"Verifying signal integrity (slow rise = possible problems)",
|
|
38
|
+
],
|
|
39
|
+
"related": ["fall_time", "slew_rate", "frequency"],
|
|
40
|
+
},
|
|
41
|
+
"fall_time": {
|
|
42
|
+
"summary": "Measures how quickly a signal transitions from high to low",
|
|
43
|
+
"plain_english": """
|
|
44
|
+
Fall time is the opposite of rise time - it measures how fast your
|
|
45
|
+
signal switches from ON to OFF (high voltage to low voltage).
|
|
46
|
+
|
|
47
|
+
It's measured between the 90% and 10% points of the transition.
|
|
48
|
+
|
|
49
|
+
Ideally, rise time and fall time should be similar. If they're very
|
|
50
|
+
different, it might indicate an issue with your circuit.
|
|
51
|
+
""",
|
|
52
|
+
"when_to_use": [
|
|
53
|
+
"Checking symmetry of your driver",
|
|
54
|
+
"Verifying output stage performance",
|
|
55
|
+
"Diagnosing asymmetric signal issues",
|
|
56
|
+
],
|
|
57
|
+
"related": ["rise_time", "slew_rate", "duty_cycle"],
|
|
58
|
+
},
|
|
59
|
+
"frequency": {
|
|
60
|
+
"summary": "Measures how many times per second your signal repeats",
|
|
61
|
+
"plain_english": """
|
|
62
|
+
Frequency tells you how fast your signal is cycling. It's measured
|
|
63
|
+
in Hertz (Hz), which means 'cycles per second'.
|
|
64
|
+
|
|
65
|
+
Common scales:
|
|
66
|
+
- 1 kHz = 1,000 cycles/second (audio frequencies)
|
|
67
|
+
- 1 MHz = 1,000,000 cycles/second (radio, slow digital)
|
|
68
|
+
- 1 GHz = 1,000,000,000 cycles/second (fast digital, RF)
|
|
69
|
+
|
|
70
|
+
Oscura finds frequency by detecting repeated patterns in your signal.
|
|
71
|
+
""",
|
|
72
|
+
"when_to_use": [
|
|
73
|
+
"Verifying clock frequency",
|
|
74
|
+
"Checking oscillator output",
|
|
75
|
+
"Measuring PWM frequency",
|
|
76
|
+
],
|
|
77
|
+
"related": ["period", "duty_cycle", "fft"],
|
|
78
|
+
},
|
|
79
|
+
"thd": {
|
|
80
|
+
"summary": "Total Harmonic Distortion - measures signal purity",
|
|
81
|
+
"plain_english": """
|
|
82
|
+
THD tells you how 'clean' your signal is. A perfect sine wave has
|
|
83
|
+
0% THD (or -infinity dB). Real signals have some distortion.
|
|
84
|
+
|
|
85
|
+
THD in dB (decibels):
|
|
86
|
+
- -60 dB or lower: Excellent (high-quality audio)
|
|
87
|
+
- -40 to -60 dB: Good (typical electronics)
|
|
88
|
+
- -20 to -40 dB: Fair (some distortion visible)
|
|
89
|
+
- Above -20 dB: Poor (significant distortion)
|
|
90
|
+
|
|
91
|
+
Note: THD is expressed as a negative number in dB.
|
|
92
|
+
More negative = less distortion = better signal.
|
|
93
|
+
""",
|
|
94
|
+
"when_to_use": [
|
|
95
|
+
"Testing audio amplifier quality",
|
|
96
|
+
"Verifying oscillator purity",
|
|
97
|
+
"Characterizing ADC/DAC performance",
|
|
98
|
+
],
|
|
99
|
+
"related": ["snr", "sinad", "enob"],
|
|
100
|
+
},
|
|
101
|
+
"snr": {
|
|
102
|
+
"summary": "Signal-to-Noise Ratio - measures how much signal vs noise",
|
|
103
|
+
"plain_english": """
|
|
104
|
+
SNR tells you how much of your signal is actual signal versus noise.
|
|
105
|
+
Higher SNR = cleaner signal with less interference.
|
|
106
|
+
|
|
107
|
+
SNR in dB:
|
|
108
|
+
- 60+ dB: Excellent (barely any noise visible)
|
|
109
|
+
- 40-60 dB: Good (clean signal, some noise)
|
|
110
|
+
- 20-40 dB: Fair (visible noise)
|
|
111
|
+
- Below 20 dB: Poor (noisy signal)
|
|
112
|
+
|
|
113
|
+
In practical terms: Every 6 dB is roughly doubling the signal level
|
|
114
|
+
relative to noise.
|
|
115
|
+
""",
|
|
116
|
+
"when_to_use": [
|
|
117
|
+
"Evaluating measurement system quality",
|
|
118
|
+
"Testing ADC performance",
|
|
119
|
+
"Comparing different signal sources",
|
|
120
|
+
],
|
|
121
|
+
"related": ["thd", "sinad", "enob"],
|
|
122
|
+
},
|
|
123
|
+
"fft": {
|
|
124
|
+
"summary": "Fast Fourier Transform - shows frequency content of signal",
|
|
125
|
+
"plain_english": """
|
|
126
|
+
FFT transforms your time-domain signal (voltage vs time) into the
|
|
127
|
+
frequency domain (power vs frequency). It's like an equalizer display
|
|
128
|
+
that shows what frequencies are present.
|
|
129
|
+
|
|
130
|
+
Returns two arrays:
|
|
131
|
+
- frequencies: The x-axis values in Hz
|
|
132
|
+
- magnitudes: The strength at each frequency (usually in dB)
|
|
133
|
+
|
|
134
|
+
Peaks in the FFT correspond to dominant frequencies in your signal.
|
|
135
|
+
A pure sine wave shows one peak. Square waves show peaks at odd
|
|
136
|
+
harmonics (1x, 3x, 5x, etc. of the fundamental).
|
|
137
|
+
""",
|
|
138
|
+
"when_to_use": [
|
|
139
|
+
"Finding the frequency of an unknown signal",
|
|
140
|
+
"Looking for interference at specific frequencies",
|
|
141
|
+
"Analyzing modulated signals",
|
|
142
|
+
],
|
|
143
|
+
"related": ["psd", "thd", "snr", "spectrogram"],
|
|
144
|
+
},
|
|
145
|
+
"load": {
|
|
146
|
+
"summary": "Load a trace file - Oscura's starting point",
|
|
147
|
+
"plain_english": """
|
|
148
|
+
load() reads waveform data from a file. It auto-detects the format,
|
|
149
|
+
so you don't need to specify whether it's CSV, WFM, HDF5, etc.
|
|
150
|
+
|
|
151
|
+
Returns a WaveformTrace or DigitalTrace object containing:
|
|
152
|
+
- data: The actual voltage/value samples
|
|
153
|
+
- metadata: Sample rate, channel info, etc.
|
|
154
|
+
- time_vector: Time axis (computed from sample rate)
|
|
155
|
+
|
|
156
|
+
Supported formats: CSV, Tektronix WFM, Rigol WFM, NumPy NPZ,
|
|
157
|
+
HDF5, Sigrok sessions, VCD, TDMS, and more.
|
|
158
|
+
""",
|
|
159
|
+
"when_to_use": [
|
|
160
|
+
"Starting any Oscura analysis",
|
|
161
|
+
"Loading oscilloscope captures",
|
|
162
|
+
"Importing logic analyzer data",
|
|
163
|
+
],
|
|
164
|
+
"related": ["get_supported_formats", "WaveformTrace", "DigitalTrace"],
|
|
165
|
+
},
|
|
166
|
+
"measure": {
|
|
167
|
+
"summary": "Run all standard measurements on a trace",
|
|
168
|
+
"plain_english": """
|
|
169
|
+
measure() is a convenience function that runs many common measurements
|
|
170
|
+
at once and returns them as a dictionary.
|
|
171
|
+
|
|
172
|
+
It's like clicking 'Auto-Measure' on an oscilloscope.
|
|
173
|
+
|
|
174
|
+
Measurements include:
|
|
175
|
+
- Timing: rise_time, fall_time, frequency, period, duty_cycle
|
|
176
|
+
- Amplitude: vpp, vmax, vmin, vmean, vrms
|
|
177
|
+
- Waveform quality: overshoot, undershoot
|
|
178
|
+
|
|
179
|
+
Results are returned in a dictionary for easy access.
|
|
180
|
+
""",
|
|
181
|
+
"when_to_use": [
|
|
182
|
+
"Quick signal characterization",
|
|
183
|
+
"Getting an overview of signal properties",
|
|
184
|
+
"When you're not sure which measurements you need",
|
|
185
|
+
],
|
|
186
|
+
"related": ["rise_time", "frequency", "amplitude", "basic_stats"],
|
|
187
|
+
},
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def get_help(topic: str) -> str | None:
|
|
192
|
+
"""Get plain English help for a Oscura function or concept.
|
|
193
|
+
|
|
194
|
+
Args:
|
|
195
|
+
topic: Function name or concept to get help for
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
Formatted help text or None if topic not found
|
|
199
|
+
|
|
200
|
+
Example:
|
|
201
|
+
>>> print(get_help("rise_time"))
|
|
202
|
+
"""
|
|
203
|
+
topic = topic.lower().strip()
|
|
204
|
+
|
|
205
|
+
if topic in HELP_DATABASE:
|
|
206
|
+
entry = HELP_DATABASE[topic]
|
|
207
|
+
output = []
|
|
208
|
+
output.append(f"Help: {topic}")
|
|
209
|
+
output.append("=" * 50)
|
|
210
|
+
output.append(f"\n{entry['summary']}\n")
|
|
211
|
+
output.append(entry["plain_english"]) # type: ignore[arg-type]
|
|
212
|
+
|
|
213
|
+
if "when_to_use" in entry:
|
|
214
|
+
output.append("\nWhen to use this:")
|
|
215
|
+
for use in entry["when_to_use"]:
|
|
216
|
+
output.append(f" - {use}")
|
|
217
|
+
|
|
218
|
+
if "related" in entry:
|
|
219
|
+
output.append(f"\nRelated: {', '.join(entry['related'])}")
|
|
220
|
+
|
|
221
|
+
return "\n".join(output)
|
|
222
|
+
|
|
223
|
+
# Try to get docstring
|
|
224
|
+
try:
|
|
225
|
+
import oscura as osc
|
|
226
|
+
|
|
227
|
+
if hasattr(osc, topic):
|
|
228
|
+
func = getattr(osc, topic)
|
|
229
|
+
if func.__doc__:
|
|
230
|
+
return f"Help for {topic}:\n\n{func.__doc__}"
|
|
231
|
+
except Exception:
|
|
232
|
+
pass
|
|
233
|
+
|
|
234
|
+
return None
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
def suggest_commands(trace: Any = None, context: str | None = None) -> list[dict[str, str]]:
|
|
238
|
+
"""Suggest next commands based on current context.
|
|
239
|
+
|
|
240
|
+
Args:
|
|
241
|
+
trace: Current trace object (if any)
|
|
242
|
+
context: Description of what user is trying to do
|
|
243
|
+
|
|
244
|
+
Returns:
|
|
245
|
+
List of suggested commands with descriptions
|
|
246
|
+
|
|
247
|
+
Example:
|
|
248
|
+
>>> suggestions = suggest_commands(trace)
|
|
249
|
+
>>> for s in suggestions:
|
|
250
|
+
... print(f"{s['command']}: {s['description']}")
|
|
251
|
+
"""
|
|
252
|
+
suggestions = []
|
|
253
|
+
|
|
254
|
+
if trace is None:
|
|
255
|
+
# No trace loaded - suggest loading
|
|
256
|
+
suggestions.append(
|
|
257
|
+
{
|
|
258
|
+
"command": "trace = load('file.csv')",
|
|
259
|
+
"description": "Load a trace file to get started",
|
|
260
|
+
"reason": "No trace loaded yet",
|
|
261
|
+
}
|
|
262
|
+
)
|
|
263
|
+
suggestions.append(
|
|
264
|
+
{
|
|
265
|
+
"command": "formats = get_supported_formats()",
|
|
266
|
+
"description": "See what file formats are supported",
|
|
267
|
+
"reason": "Helpful for knowing what files you can load",
|
|
268
|
+
}
|
|
269
|
+
)
|
|
270
|
+
return suggestions
|
|
271
|
+
|
|
272
|
+
# Trace is loaded - suggest measurements
|
|
273
|
+
suggestions.append(
|
|
274
|
+
{
|
|
275
|
+
"command": "measure(trace)",
|
|
276
|
+
"description": "Run all standard measurements",
|
|
277
|
+
"reason": "Quick overview of signal properties",
|
|
278
|
+
}
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
# Check if it looks like digital signal
|
|
282
|
+
if hasattr(trace, "data"):
|
|
283
|
+
import numpy as np
|
|
284
|
+
|
|
285
|
+
data = trace.data
|
|
286
|
+
unique_levels = len(np.unique(np.round(data, 2)))
|
|
287
|
+
|
|
288
|
+
if unique_levels < 5:
|
|
289
|
+
# Likely digital
|
|
290
|
+
suggestions.append(
|
|
291
|
+
{
|
|
292
|
+
"command": "digital = to_digital(trace)",
|
|
293
|
+
"description": "Convert to digital trace",
|
|
294
|
+
"reason": "Signal appears to be digital (few voltage levels)",
|
|
295
|
+
}
|
|
296
|
+
)
|
|
297
|
+
suggestions.append(
|
|
298
|
+
{
|
|
299
|
+
"command": "characterize_signal(trace)",
|
|
300
|
+
"description": "Auto-detect signal type and protocol",
|
|
301
|
+
"reason": "May be a protocol like UART, SPI, I2C",
|
|
302
|
+
}
|
|
303
|
+
)
|
|
304
|
+
else:
|
|
305
|
+
# Likely analog
|
|
306
|
+
suggestions.append(
|
|
307
|
+
{
|
|
308
|
+
"command": "freq, mag = fft(trace)",
|
|
309
|
+
"description": "Compute frequency spectrum",
|
|
310
|
+
"reason": "See what frequencies are present",
|
|
311
|
+
}
|
|
312
|
+
)
|
|
313
|
+
suggestions.append(
|
|
314
|
+
{
|
|
315
|
+
"command": "thd(trace)",
|
|
316
|
+
"description": "Measure Total Harmonic Distortion",
|
|
317
|
+
"reason": "Check signal purity",
|
|
318
|
+
}
|
|
319
|
+
)
|
|
320
|
+
|
|
321
|
+
# Always suggest filtering for noisy signals
|
|
322
|
+
suggestions.append(
|
|
323
|
+
{
|
|
324
|
+
"command": "filtered = low_pass(trace, cutoff_hz)",
|
|
325
|
+
"description": "Apply low-pass filter to remove noise",
|
|
326
|
+
"reason": "Clean up high-frequency noise",
|
|
327
|
+
}
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
# Context-specific suggestions
|
|
331
|
+
if context:
|
|
332
|
+
context_lower = context.lower()
|
|
333
|
+
if "uart" in context_lower or "serial" in context_lower:
|
|
334
|
+
suggestions.insert(
|
|
335
|
+
0,
|
|
336
|
+
{
|
|
337
|
+
"command": "packets = decode_uart(trace)",
|
|
338
|
+
"description": "Decode UART serial data",
|
|
339
|
+
"reason": "You mentioned UART/serial",
|
|
340
|
+
},
|
|
341
|
+
)
|
|
342
|
+
elif "spi" in context_lower:
|
|
343
|
+
suggestions.insert(
|
|
344
|
+
0,
|
|
345
|
+
{
|
|
346
|
+
"command": "packets = decode_spi(clk_trace, data_trace)",
|
|
347
|
+
"description": "Decode SPI bus",
|
|
348
|
+
"reason": "You mentioned SPI",
|
|
349
|
+
},
|
|
350
|
+
)
|
|
351
|
+
elif "i2c" in context_lower:
|
|
352
|
+
suggestions.insert(
|
|
353
|
+
0,
|
|
354
|
+
{
|
|
355
|
+
"command": "packets = decode_i2c(scl_trace, sda_trace)",
|
|
356
|
+
"description": "Decode I2C bus",
|
|
357
|
+
"reason": "You mentioned I2C",
|
|
358
|
+
},
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
return suggestions
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
def explain_result(
|
|
365
|
+
value: Any,
|
|
366
|
+
measurement: str,
|
|
367
|
+
context: dict[str, Any] | None = None,
|
|
368
|
+
) -> str:
|
|
369
|
+
"""Explain a measurement result in plain English.
|
|
370
|
+
|
|
371
|
+
Args:
|
|
372
|
+
value: The measurement value
|
|
373
|
+
measurement: Name of the measurement (e.g., "rise_time")
|
|
374
|
+
context: Additional context (e.g., signal type, expected values)
|
|
375
|
+
|
|
376
|
+
Returns:
|
|
377
|
+
Plain English explanation of the result
|
|
378
|
+
|
|
379
|
+
Example:
|
|
380
|
+
>>> print(explain_result(2.5e-9, "rise_time"))
|
|
381
|
+
"Your rise time is 2.5 nanoseconds, which is..."
|
|
382
|
+
"""
|
|
383
|
+
explanations = {
|
|
384
|
+
"rise_time": lambda v: _explain_rise_time(v),
|
|
385
|
+
"fall_time": lambda v: _explain_fall_time(v),
|
|
386
|
+
"frequency": lambda v: _explain_frequency(v),
|
|
387
|
+
"thd": lambda v: _explain_thd(v),
|
|
388
|
+
"snr": lambda v: _explain_snr(v),
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
if measurement.lower() in explanations:
|
|
392
|
+
return explanations[measurement.lower()](value) # type: ignore[no-untyped-call]
|
|
393
|
+
|
|
394
|
+
# Generic explanation
|
|
395
|
+
return f"{measurement}: {value}"
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
def _explain_rise_time(value: float) -> str:
|
|
399
|
+
"""Explain rise time result."""
|
|
400
|
+
if value < 1e-12:
|
|
401
|
+
return f"Rise time: {value * 1e12:.2f} ps - Extremely fast! Sub-picosecond edge."
|
|
402
|
+
elif value < 1e-9:
|
|
403
|
+
return f"Rise time: {value * 1e12:.0f} ps - Very fast, typical of high-speed serial links."
|
|
404
|
+
elif value < 10e-9:
|
|
405
|
+
return f"Rise time: {value * 1e9:.2f} ns - Fast, suitable for most digital circuits."
|
|
406
|
+
elif value < 100e-9:
|
|
407
|
+
return f"Rise time: {value * 1e9:.1f} ns - Moderate, typical of standard logic."
|
|
408
|
+
else:
|
|
409
|
+
return f"Rise time: {value * 1e6:.2f} us - Slow, may limit data rate."
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
def _explain_fall_time(value: float) -> str:
|
|
413
|
+
"""Explain fall time result."""
|
|
414
|
+
if value < 1e-9:
|
|
415
|
+
return f"Fall time: {value * 1e12:.0f} ps - Very fast falling edge."
|
|
416
|
+
elif value < 10e-9:
|
|
417
|
+
return f"Fall time: {value * 1e9:.2f} ns - Fast, good for digital circuits."
|
|
418
|
+
else:
|
|
419
|
+
return f"Fall time: {value * 1e9:.1f} ns - Relatively slow falling edge."
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
def _explain_frequency(value: float) -> str:
|
|
423
|
+
"""Explain frequency result."""
|
|
424
|
+
if value < 1e3:
|
|
425
|
+
return f"Frequency: {value:.1f} Hz - Audio range or very slow signal."
|
|
426
|
+
elif value < 1e6:
|
|
427
|
+
return f"Frequency: {value / 1e3:.2f} kHz - Low frequency signal."
|
|
428
|
+
elif value < 1e9:
|
|
429
|
+
return f"Frequency: {value / 1e6:.2f} MHz - Radio/digital clock range."
|
|
430
|
+
else:
|
|
431
|
+
return f"Frequency: {value / 1e9:.3f} GHz - High-speed digital or RF."
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
def _explain_thd(value: float) -> str:
|
|
435
|
+
"""Explain THD result."""
|
|
436
|
+
if value < -60:
|
|
437
|
+
return f"THD: {value:.1f} dB - Excellent! Very low distortion (high-fidelity)."
|
|
438
|
+
elif value < -40:
|
|
439
|
+
return f"THD: {value:.1f} dB - Good, typical for quality electronics."
|
|
440
|
+
elif value < -20:
|
|
441
|
+
return f"THD: {value:.1f} dB - Fair, some distortion present."
|
|
442
|
+
else:
|
|
443
|
+
return f"THD: {value:.1f} dB - Poor, significant distortion visible."
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
def _explain_snr(value: float) -> str:
|
|
447
|
+
"""Explain SNR result."""
|
|
448
|
+
if value > 60:
|
|
449
|
+
return f"SNR: {value:.1f} dB - Excellent! Very clean signal."
|
|
450
|
+
elif value > 40:
|
|
451
|
+
return f"SNR: {value:.1f} dB - Good signal-to-noise ratio."
|
|
452
|
+
elif value > 20:
|
|
453
|
+
return f"SNR: {value:.1f} dB - Fair, some noise present."
|
|
454
|
+
else:
|
|
455
|
+
return f"SNR: {value:.1f} dB - Poor, noisy signal."
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
def get_example(function_name: str) -> str | None:
|
|
459
|
+
"""Get a code example for a function.
|
|
460
|
+
|
|
461
|
+
Args:
|
|
462
|
+
function_name: Name of the function
|
|
463
|
+
|
|
464
|
+
Returns:
|
|
465
|
+
Example code string or None
|
|
466
|
+
"""
|
|
467
|
+
examples = {
|
|
468
|
+
"load": """
|
|
469
|
+
# Load a trace file
|
|
470
|
+
import oscura as osc
|
|
471
|
+
trace = osc.load("capture.csv")
|
|
472
|
+
print(f"Loaded {len(trace.data)} samples")
|
|
473
|
+
""",
|
|
474
|
+
"rise_time": """
|
|
475
|
+
# Measure rise time
|
|
476
|
+
import oscura as osc
|
|
477
|
+
trace = osc.load("signal.csv")
|
|
478
|
+
rt = osc.rise_time(trace)
|
|
479
|
+
print(f"Rise time: {rt*1e9:.2f} ns")
|
|
480
|
+
""",
|
|
481
|
+
"fft": """
|
|
482
|
+
# Compute FFT spectrum
|
|
483
|
+
import oscura as osc
|
|
484
|
+
trace = osc.load("signal.csv")
|
|
485
|
+
freq, mag = osc.fft(trace)
|
|
486
|
+
print(f"Frequency resolution: {freq[1]:.2f} Hz")
|
|
487
|
+
""",
|
|
488
|
+
"measure": """
|
|
489
|
+
# Run all measurements
|
|
490
|
+
import oscura as osc
|
|
491
|
+
trace = osc.load("signal.csv")
|
|
492
|
+
results = osc.measure(trace)
|
|
493
|
+
for name, value in results.items():
|
|
494
|
+
print(f"{name}: {value}")
|
|
495
|
+
""",
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
return examples.get(function_name.lower())
|