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,298 @@
|
|
|
1
|
+
"""Wavelet transform analysis for waveform data.
|
|
2
|
+
|
|
3
|
+
This module provides continuous and discrete wavelet transforms,
|
|
4
|
+
including chunked implementations for memory-efficient processing.
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Example:
|
|
8
|
+
>>> from oscura.analyzers.waveform.wavelets import cwt_chunked, dwt_chunked
|
|
9
|
+
>>> # Process large file with chunked CWT
|
|
10
|
+
>>> coeffs, scales = cwt_chunked('large_file.bin', scales=np.arange(1, 128))
|
|
11
|
+
|
|
12
|
+
References:
|
|
13
|
+
Mallat, S. (2008). A Wavelet Tour of Signal Processing
|
|
14
|
+
Torrence, C., & Compo, G. P. (1998). A practical guide to wavelet analysis
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
from typing import TYPE_CHECKING, Any
|
|
21
|
+
|
|
22
|
+
import numpy as np
|
|
23
|
+
|
|
24
|
+
if TYPE_CHECKING:
|
|
25
|
+
from collections.abc import Generator
|
|
26
|
+
from os import PathLike
|
|
27
|
+
|
|
28
|
+
from numpy.typing import NDArray
|
|
29
|
+
|
|
30
|
+
try:
|
|
31
|
+
import pywt
|
|
32
|
+
|
|
33
|
+
PYWT_AVAILABLE = True
|
|
34
|
+
except ImportError:
|
|
35
|
+
PYWT_AVAILABLE = False
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def cwt_chunked(
|
|
39
|
+
file_path: str | PathLike[str],
|
|
40
|
+
scales: NDArray[np.floating[Any]],
|
|
41
|
+
wavelet: str = "morl",
|
|
42
|
+
*,
|
|
43
|
+
chunk_size: int = 10_000_000,
|
|
44
|
+
overlap_factor: float = 2.0,
|
|
45
|
+
dtype: type = np.float64,
|
|
46
|
+
) -> Generator[tuple[NDArray[np.float64], NDArray[np.float64]], None, None]:
|
|
47
|
+
"""Compute continuous wavelet transform on large files using chunked processing.
|
|
48
|
+
|
|
49
|
+
Processes file in overlapping chunks to handle files larger than memory.
|
|
50
|
+
Uses overlap to ensure continuity at chunk boundaries.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
file_path: Path to binary file containing signal data.
|
|
54
|
+
scales: Array of scales for CWT computation.
|
|
55
|
+
wavelet: Wavelet name (default 'morl' - Morlet).
|
|
56
|
+
chunk_size: Number of samples per chunk (default 10M).
|
|
57
|
+
overlap_factor: Overlap as multiple of max scale (default 2.0).
|
|
58
|
+
dtype: Data type for file reading (default float64).
|
|
59
|
+
|
|
60
|
+
Yields:
|
|
61
|
+
Tuple of (coefficients, valid_scales) for each chunk:
|
|
62
|
+
- coefficients: CWT coefficients [scales x time]
|
|
63
|
+
- valid_scales: Scales used (same as input)
|
|
64
|
+
|
|
65
|
+
Raises:
|
|
66
|
+
ImportError: If PyWavelets is not available.
|
|
67
|
+
FileNotFoundError: If file does not exist.
|
|
68
|
+
|
|
69
|
+
Example:
|
|
70
|
+
>>> import numpy as np
|
|
71
|
+
>>> scales = np.arange(1, 128)
|
|
72
|
+
>>> for coeffs, scales_out in cwt_chunked('signal.bin', scales):
|
|
73
|
+
... # Process each chunk
|
|
74
|
+
... print(f"Chunk shape: {coeffs.shape}")
|
|
75
|
+
|
|
76
|
+
References:
|
|
77
|
+
MEM-007: Chunked Wavelet Transform
|
|
78
|
+
Torrence & Compo (1998): Practical guide to wavelet analysis
|
|
79
|
+
"""
|
|
80
|
+
if not PYWT_AVAILABLE:
|
|
81
|
+
raise ImportError("PyWavelets not available. Install with: pip install PyWavelets")
|
|
82
|
+
|
|
83
|
+
path = Path(file_path)
|
|
84
|
+
if not path.exists():
|
|
85
|
+
raise FileNotFoundError(f"File not found: {file_path}")
|
|
86
|
+
|
|
87
|
+
# Get file size and calculate total samples
|
|
88
|
+
file_size = path.stat().st_size
|
|
89
|
+
bytes_per_sample = np.dtype(dtype).itemsize
|
|
90
|
+
total_samples = file_size // bytes_per_sample
|
|
91
|
+
|
|
92
|
+
# Calculate overlap based on maximum scale
|
|
93
|
+
max_scale = int(np.max(scales))
|
|
94
|
+
overlap = int(max_scale * overlap_factor)
|
|
95
|
+
|
|
96
|
+
# Process file in chunks
|
|
97
|
+
offset = 0
|
|
98
|
+
with open(path, "rb") as f:
|
|
99
|
+
while offset < total_samples:
|
|
100
|
+
# Read chunk with overlap
|
|
101
|
+
f.seek(offset * bytes_per_sample)
|
|
102
|
+
chunk_samples = min(chunk_size, total_samples - offset)
|
|
103
|
+
read_samples = min(chunk_samples + overlap, total_samples - offset)
|
|
104
|
+
|
|
105
|
+
chunk_data: NDArray[np.float64] = np.fromfile(f, dtype=dtype, count=read_samples)
|
|
106
|
+
|
|
107
|
+
if len(chunk_data) == 0:
|
|
108
|
+
break
|
|
109
|
+
|
|
110
|
+
# Compute CWT on chunk
|
|
111
|
+
coefficients, _frequencies = pywt.cwt(chunk_data, scales, wavelet, sampling_period=1.0)
|
|
112
|
+
|
|
113
|
+
# Extract valid portion (exclude overlap region for continuity)
|
|
114
|
+
if offset + chunk_samples < total_samples:
|
|
115
|
+
# Not the last chunk - exclude overlap from end
|
|
116
|
+
valid_coeffs = coefficients[:, :chunk_samples]
|
|
117
|
+
else:
|
|
118
|
+
# Last chunk - include everything
|
|
119
|
+
valid_coeffs = coefficients
|
|
120
|
+
|
|
121
|
+
yield valid_coeffs.astype(np.float64), scales.astype(np.float64)
|
|
122
|
+
|
|
123
|
+
# Move to next chunk
|
|
124
|
+
offset += chunk_samples
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def dwt_chunked(
|
|
128
|
+
file_path: str | PathLike[str],
|
|
129
|
+
wavelet: str = "db4",
|
|
130
|
+
level: int | None = None,
|
|
131
|
+
*,
|
|
132
|
+
chunk_size: int = 10_000_000,
|
|
133
|
+
mode: str = "symmetric",
|
|
134
|
+
dtype: type = np.float64,
|
|
135
|
+
) -> Generator[dict[str, NDArray[np.float64]], None, None]:
|
|
136
|
+
"""Compute discrete wavelet transform on large files using chunked processing.
|
|
137
|
+
|
|
138
|
+
Processes file in chunks with boundary handling for DWT reconstruction.
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
file_path: Path to binary file containing signal data.
|
|
142
|
+
wavelet: Wavelet name (default 'db4' - Daubechies 4).
|
|
143
|
+
level: Decomposition level. If None, uses maximum possible.
|
|
144
|
+
chunk_size: Number of samples per chunk (default 10M).
|
|
145
|
+
mode: Signal extension mode (default 'symmetric').
|
|
146
|
+
dtype: Data type for file reading (default float64).
|
|
147
|
+
|
|
148
|
+
Yields:
|
|
149
|
+
Dictionary with DWT coefficients for each chunk:
|
|
150
|
+
- 'cA{level}': Approximation coefficients at level
|
|
151
|
+
- 'cD{level}', 'cD{level-1}', ..., 'cD1': Detail coefficients
|
|
152
|
+
|
|
153
|
+
Raises:
|
|
154
|
+
ImportError: If PyWavelets is not available.
|
|
155
|
+
FileNotFoundError: If file does not exist.
|
|
156
|
+
|
|
157
|
+
Example:
|
|
158
|
+
>>> for coeffs in dwt_chunked('signal.bin', wavelet='db4', level=3):
|
|
159
|
+
... # Process each chunk's wavelet decomposition
|
|
160
|
+
... print(f"Approximation shape: {coeffs['cA3'].shape}")
|
|
161
|
+
... print(f"Details: {[k for k in coeffs if k.startswith('cD')]}")
|
|
162
|
+
|
|
163
|
+
References:
|
|
164
|
+
MEM-007: Chunked Wavelet Transform
|
|
165
|
+
Mallat (2008): Wavelet Tour of Signal Processing
|
|
166
|
+
"""
|
|
167
|
+
if not PYWT_AVAILABLE:
|
|
168
|
+
raise ImportError("PyWavelets not available. Install with: pip install PyWavelets")
|
|
169
|
+
|
|
170
|
+
path = Path(file_path)
|
|
171
|
+
if not path.exists():
|
|
172
|
+
raise FileNotFoundError(f"File not found: {file_path}")
|
|
173
|
+
|
|
174
|
+
# Get file size
|
|
175
|
+
file_size = path.stat().st_size
|
|
176
|
+
bytes_per_sample = np.dtype(dtype).itemsize
|
|
177
|
+
total_samples = file_size // bytes_per_sample
|
|
178
|
+
|
|
179
|
+
# Calculate filter length for boundary handling
|
|
180
|
+
wavelet_obj = pywt.Wavelet(wavelet)
|
|
181
|
+
filter_len = wavelet_obj.dec_len
|
|
182
|
+
|
|
183
|
+
# Overlap needed for boundary continuity
|
|
184
|
+
if level is None:
|
|
185
|
+
level = pywt.dwt_max_level(chunk_size, filter_len)
|
|
186
|
+
|
|
187
|
+
overlap = filter_len * (2**level)
|
|
188
|
+
|
|
189
|
+
# Process file in chunks
|
|
190
|
+
offset = 0
|
|
191
|
+
with open(path, "rb") as f:
|
|
192
|
+
while offset < total_samples:
|
|
193
|
+
# Read chunk with overlap
|
|
194
|
+
f.seek(offset * bytes_per_sample)
|
|
195
|
+
chunk_samples = min(chunk_size, total_samples - offset)
|
|
196
|
+
read_samples = min(chunk_samples + overlap, total_samples - offset)
|
|
197
|
+
|
|
198
|
+
chunk_data: NDArray[np.float64] = np.fromfile(f, dtype=dtype, count=read_samples)
|
|
199
|
+
|
|
200
|
+
if len(chunk_data) == 0:
|
|
201
|
+
break
|
|
202
|
+
|
|
203
|
+
# Compute DWT on chunk
|
|
204
|
+
coeffs = pywt.wavedec(chunk_data, wavelet, mode=mode, level=level)
|
|
205
|
+
|
|
206
|
+
# Build result dictionary
|
|
207
|
+
result = {}
|
|
208
|
+
result[f"cA{level}"] = coeffs[0].astype(np.float64)
|
|
209
|
+
for i, detail in enumerate(coeffs[1:], 1):
|
|
210
|
+
result[f"cD{level - i + 1}"] = detail.astype(np.float64)
|
|
211
|
+
|
|
212
|
+
yield result
|
|
213
|
+
|
|
214
|
+
# Move to next chunk
|
|
215
|
+
offset += chunk_samples
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def cwt(
|
|
219
|
+
signal: NDArray[np.floating[Any]],
|
|
220
|
+
scales: NDArray[np.floating[Any]],
|
|
221
|
+
wavelet: str = "morl",
|
|
222
|
+
*,
|
|
223
|
+
sampling_period: float = 1.0,
|
|
224
|
+
) -> tuple[NDArray[np.complex128], NDArray[np.float64]]:
|
|
225
|
+
"""Compute continuous wavelet transform.
|
|
226
|
+
|
|
227
|
+
Wrapper around PyWavelets CWT for in-memory processing.
|
|
228
|
+
|
|
229
|
+
Args:
|
|
230
|
+
signal: Input signal array.
|
|
231
|
+
scales: Array of scales for CWT computation.
|
|
232
|
+
wavelet: Wavelet name (default 'morl' - Morlet).
|
|
233
|
+
sampling_period: Sampling period (default 1.0).
|
|
234
|
+
|
|
235
|
+
Returns:
|
|
236
|
+
Tuple of (coefficients, frequencies):
|
|
237
|
+
- coefficients: Complex CWT coefficients [scales x time]
|
|
238
|
+
- frequencies: Corresponding frequencies for each scale
|
|
239
|
+
|
|
240
|
+
Raises:
|
|
241
|
+
ImportError: If PyWavelets is not available.
|
|
242
|
+
|
|
243
|
+
Example:
|
|
244
|
+
>>> import numpy as np
|
|
245
|
+
>>> signal = np.sin(2 * np.pi * 10 * np.linspace(0, 1, 1000))
|
|
246
|
+
>>> scales = np.arange(1, 128)
|
|
247
|
+
>>> coeffs, freqs = cwt(signal, scales)
|
|
248
|
+
>>> print(f"CWT shape: {coeffs.shape}")
|
|
249
|
+
"""
|
|
250
|
+
if not PYWT_AVAILABLE:
|
|
251
|
+
raise ImportError("PyWavelets not available. Install with: pip install PyWavelets")
|
|
252
|
+
|
|
253
|
+
coefficients, frequencies = pywt.cwt(signal, scales, wavelet, sampling_period=sampling_period)
|
|
254
|
+
|
|
255
|
+
return coefficients.astype(np.complex128), frequencies.astype(np.float64)
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def dwt(
|
|
259
|
+
signal: NDArray[np.floating[Any]],
|
|
260
|
+
wavelet: str = "db4",
|
|
261
|
+
level: int | None = None,
|
|
262
|
+
*,
|
|
263
|
+
mode: str = "symmetric",
|
|
264
|
+
) -> list[NDArray[np.float64]]:
|
|
265
|
+
"""Compute discrete wavelet transform.
|
|
266
|
+
|
|
267
|
+
Wrapper around PyWavelets DWT for in-memory processing.
|
|
268
|
+
|
|
269
|
+
Args:
|
|
270
|
+
signal: Input signal array.
|
|
271
|
+
wavelet: Wavelet name (default 'db4' - Daubechies 4).
|
|
272
|
+
level: Decomposition level. If None, uses maximum possible.
|
|
273
|
+
mode: Signal extension mode (default 'symmetric').
|
|
274
|
+
|
|
275
|
+
Returns:
|
|
276
|
+
List of wavelet coefficients [cA_n, cD_n, cD_n-1, ..., cD1]:
|
|
277
|
+
- cA_n: Approximation coefficients at level n
|
|
278
|
+
- cD_i: Detail coefficients at level i
|
|
279
|
+
|
|
280
|
+
Raises:
|
|
281
|
+
ImportError: If PyWavelets is not available.
|
|
282
|
+
|
|
283
|
+
Example:
|
|
284
|
+
>>> import numpy as np
|
|
285
|
+
>>> signal = np.random.randn(1024)
|
|
286
|
+
>>> coeffs = dwt(signal, wavelet='db4', level=3)
|
|
287
|
+
>>> print(f"Approximation: {coeffs[0].shape}")
|
|
288
|
+
>>> print(f"Details: {[c.shape for c in coeffs[1:]]}")
|
|
289
|
+
"""
|
|
290
|
+
if not PYWT_AVAILABLE:
|
|
291
|
+
raise ImportError("PyWavelets not available. Install with: pip install PyWavelets")
|
|
292
|
+
|
|
293
|
+
coeffs = pywt.wavedec(signal, wavelet, mode=mode, level=level)
|
|
294
|
+
|
|
295
|
+
return [c.astype(np.float64) for c in coeffs]
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
__all__ = ["cwt", "cwt_chunked", "dwt", "dwt_chunked"]
|
oscura/api/__init__.py
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""Expert API module for Oscura.
|
|
2
|
+
|
|
3
|
+
This module provides advanced APIs for power users including DSL,
|
|
4
|
+
fluent interfaces, performance profiling, and advanced workflow control.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from oscura.api.dsl import (
|
|
8
|
+
DSLExpression,
|
|
9
|
+
DSLParser,
|
|
10
|
+
analyze,
|
|
11
|
+
parse_expression,
|
|
12
|
+
)
|
|
13
|
+
from oscura.api.fluent import (
|
|
14
|
+
FluentResult,
|
|
15
|
+
FluentTrace,
|
|
16
|
+
trace,
|
|
17
|
+
)
|
|
18
|
+
from oscura.api.operators import (
|
|
19
|
+
TimeIndex,
|
|
20
|
+
UnitConverter,
|
|
21
|
+
convert_units,
|
|
22
|
+
make_pipeable,
|
|
23
|
+
)
|
|
24
|
+
from oscura.api.optimization import (
|
|
25
|
+
GridSearch,
|
|
26
|
+
OptimizationResult,
|
|
27
|
+
ParameterSpace,
|
|
28
|
+
optimize_parameters,
|
|
29
|
+
)
|
|
30
|
+
from oscura.api.profiling import (
|
|
31
|
+
OperationProfile,
|
|
32
|
+
Profiler,
|
|
33
|
+
ProfileReport,
|
|
34
|
+
profile,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
__all__ = [
|
|
38
|
+
# DSL (API-010)
|
|
39
|
+
"DSLExpression",
|
|
40
|
+
"DSLParser",
|
|
41
|
+
# Fluent (API-019)
|
|
42
|
+
"FluentResult",
|
|
43
|
+
"FluentTrace",
|
|
44
|
+
# Optimization (API-014)
|
|
45
|
+
"GridSearch",
|
|
46
|
+
# Profiling (API-012)
|
|
47
|
+
"OperationProfile",
|
|
48
|
+
"OptimizationResult",
|
|
49
|
+
"ParameterSpace",
|
|
50
|
+
"ProfileReport",
|
|
51
|
+
"Profiler",
|
|
52
|
+
# Operators (API-015, API-016, API-018)
|
|
53
|
+
"TimeIndex",
|
|
54
|
+
"UnitConverter",
|
|
55
|
+
"analyze",
|
|
56
|
+
"convert_units",
|
|
57
|
+
"make_pipeable",
|
|
58
|
+
"optimize_parameters",
|
|
59
|
+
"parse_expression",
|
|
60
|
+
"profile",
|
|
61
|
+
"trace",
|
|
62
|
+
]
|