oscura 0.0.1__py3-none-any.whl → 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- oscura/__init__.py +813 -8
- oscura/__main__.py +392 -0
- oscura/analyzers/__init__.py +37 -0
- oscura/analyzers/digital/__init__.py +177 -0
- oscura/analyzers/digital/bus.py +691 -0
- oscura/analyzers/digital/clock.py +805 -0
- oscura/analyzers/digital/correlation.py +720 -0
- oscura/analyzers/digital/edges.py +632 -0
- oscura/analyzers/digital/extraction.py +413 -0
- oscura/analyzers/digital/quality.py +878 -0
- oscura/analyzers/digital/signal_quality.py +877 -0
- oscura/analyzers/digital/thresholds.py +708 -0
- oscura/analyzers/digital/timing.py +1104 -0
- oscura/analyzers/eye/__init__.py +46 -0
- oscura/analyzers/eye/diagram.py +434 -0
- oscura/analyzers/eye/metrics.py +555 -0
- oscura/analyzers/jitter/__init__.py +83 -0
- oscura/analyzers/jitter/ber.py +333 -0
- oscura/analyzers/jitter/decomposition.py +759 -0
- oscura/analyzers/jitter/measurements.py +413 -0
- oscura/analyzers/jitter/spectrum.py +220 -0
- oscura/analyzers/measurements.py +40 -0
- oscura/analyzers/packet/__init__.py +171 -0
- oscura/analyzers/packet/daq.py +1077 -0
- oscura/analyzers/packet/metrics.py +437 -0
- oscura/analyzers/packet/parser.py +327 -0
- oscura/analyzers/packet/payload.py +2156 -0
- oscura/analyzers/packet/payload_analysis.py +1312 -0
- oscura/analyzers/packet/payload_extraction.py +236 -0
- oscura/analyzers/packet/payload_patterns.py +670 -0
- oscura/analyzers/packet/stream.py +359 -0
- oscura/analyzers/patterns/__init__.py +266 -0
- oscura/analyzers/patterns/clustering.py +1036 -0
- oscura/analyzers/patterns/discovery.py +539 -0
- oscura/analyzers/patterns/learning.py +797 -0
- oscura/analyzers/patterns/matching.py +1091 -0
- oscura/analyzers/patterns/periodic.py +650 -0
- oscura/analyzers/patterns/sequences.py +767 -0
- oscura/analyzers/power/__init__.py +116 -0
- oscura/analyzers/power/ac_power.py +391 -0
- oscura/analyzers/power/basic.py +383 -0
- oscura/analyzers/power/conduction.py +314 -0
- oscura/analyzers/power/efficiency.py +297 -0
- oscura/analyzers/power/ripple.py +356 -0
- oscura/analyzers/power/soa.py +372 -0
- oscura/analyzers/power/switching.py +479 -0
- oscura/analyzers/protocol/__init__.py +150 -0
- oscura/analyzers/protocols/__init__.py +150 -0
- oscura/analyzers/protocols/base.py +500 -0
- oscura/analyzers/protocols/can.py +620 -0
- oscura/analyzers/protocols/can_fd.py +448 -0
- oscura/analyzers/protocols/flexray.py +405 -0
- oscura/analyzers/protocols/hdlc.py +399 -0
- oscura/analyzers/protocols/i2c.py +368 -0
- oscura/analyzers/protocols/i2s.py +296 -0
- oscura/analyzers/protocols/jtag.py +393 -0
- oscura/analyzers/protocols/lin.py +445 -0
- oscura/analyzers/protocols/manchester.py +333 -0
- oscura/analyzers/protocols/onewire.py +501 -0
- oscura/analyzers/protocols/spi.py +334 -0
- oscura/analyzers/protocols/swd.py +325 -0
- oscura/analyzers/protocols/uart.py +393 -0
- oscura/analyzers/protocols/usb.py +495 -0
- oscura/analyzers/signal_integrity/__init__.py +63 -0
- oscura/analyzers/signal_integrity/embedding.py +294 -0
- oscura/analyzers/signal_integrity/equalization.py +370 -0
- oscura/analyzers/signal_integrity/sparams.py +484 -0
- oscura/analyzers/spectral/__init__.py +53 -0
- oscura/analyzers/spectral/chunked.py +273 -0
- oscura/analyzers/spectral/chunked_fft.py +571 -0
- oscura/analyzers/spectral/chunked_wavelet.py +391 -0
- oscura/analyzers/spectral/fft.py +92 -0
- oscura/analyzers/statistical/__init__.py +250 -0
- oscura/analyzers/statistical/checksum.py +923 -0
- oscura/analyzers/statistical/chunked_corr.py +228 -0
- oscura/analyzers/statistical/classification.py +778 -0
- oscura/analyzers/statistical/entropy.py +1113 -0
- oscura/analyzers/statistical/ngrams.py +614 -0
- oscura/analyzers/statistics/__init__.py +119 -0
- oscura/analyzers/statistics/advanced.py +885 -0
- oscura/analyzers/statistics/basic.py +263 -0
- oscura/analyzers/statistics/correlation.py +630 -0
- oscura/analyzers/statistics/distribution.py +298 -0
- oscura/analyzers/statistics/outliers.py +463 -0
- oscura/analyzers/statistics/streaming.py +93 -0
- oscura/analyzers/statistics/trend.py +520 -0
- oscura/analyzers/validation.py +598 -0
- oscura/analyzers/waveform/__init__.py +36 -0
- oscura/analyzers/waveform/measurements.py +943 -0
- oscura/analyzers/waveform/measurements_with_uncertainty.py +371 -0
- oscura/analyzers/waveform/spectral.py +1689 -0
- oscura/analyzers/waveform/wavelets.py +298 -0
- oscura/api/__init__.py +62 -0
- oscura/api/dsl.py +538 -0
- oscura/api/fluent.py +571 -0
- oscura/api/operators.py +498 -0
- oscura/api/optimization.py +392 -0
- oscura/api/profiling.py +396 -0
- oscura/automotive/__init__.py +73 -0
- oscura/automotive/can/__init__.py +52 -0
- oscura/automotive/can/analysis.py +356 -0
- oscura/automotive/can/checksum.py +250 -0
- oscura/automotive/can/correlation.py +212 -0
- oscura/automotive/can/discovery.py +355 -0
- oscura/automotive/can/message_wrapper.py +375 -0
- oscura/automotive/can/models.py +385 -0
- oscura/automotive/can/patterns.py +381 -0
- oscura/automotive/can/session.py +452 -0
- oscura/automotive/can/state_machine.py +300 -0
- oscura/automotive/can/stimulus_response.py +461 -0
- oscura/automotive/dbc/__init__.py +15 -0
- oscura/automotive/dbc/generator.py +156 -0
- oscura/automotive/dbc/parser.py +146 -0
- oscura/automotive/dtc/__init__.py +30 -0
- oscura/automotive/dtc/database.py +3036 -0
- oscura/automotive/j1939/__init__.py +14 -0
- oscura/automotive/j1939/decoder.py +745 -0
- oscura/automotive/loaders/__init__.py +35 -0
- oscura/automotive/loaders/asc.py +98 -0
- oscura/automotive/loaders/blf.py +77 -0
- oscura/automotive/loaders/csv_can.py +136 -0
- oscura/automotive/loaders/dispatcher.py +136 -0
- oscura/automotive/loaders/mdf.py +331 -0
- oscura/automotive/loaders/pcap.py +132 -0
- oscura/automotive/obd/__init__.py +14 -0
- oscura/automotive/obd/decoder.py +707 -0
- oscura/automotive/uds/__init__.py +48 -0
- oscura/automotive/uds/decoder.py +265 -0
- oscura/automotive/uds/models.py +64 -0
- oscura/automotive/visualization.py +369 -0
- oscura/batch/__init__.py +55 -0
- oscura/batch/advanced.py +627 -0
- oscura/batch/aggregate.py +300 -0
- oscura/batch/analyze.py +139 -0
- oscura/batch/logging.py +487 -0
- oscura/batch/metrics.py +556 -0
- oscura/builders/__init__.py +41 -0
- oscura/builders/signal_builder.py +1131 -0
- oscura/cli/__init__.py +14 -0
- oscura/cli/batch.py +339 -0
- oscura/cli/characterize.py +273 -0
- oscura/cli/compare.py +775 -0
- oscura/cli/decode.py +551 -0
- oscura/cli/main.py +247 -0
- oscura/cli/shell.py +350 -0
- oscura/comparison/__init__.py +66 -0
- oscura/comparison/compare.py +397 -0
- oscura/comparison/golden.py +487 -0
- oscura/comparison/limits.py +391 -0
- oscura/comparison/mask.py +434 -0
- oscura/comparison/trace_diff.py +30 -0
- oscura/comparison/visualization.py +481 -0
- oscura/compliance/__init__.py +70 -0
- oscura/compliance/advanced.py +756 -0
- oscura/compliance/masks.py +363 -0
- oscura/compliance/reporting.py +483 -0
- oscura/compliance/testing.py +298 -0
- oscura/component/__init__.py +38 -0
- oscura/component/impedance.py +365 -0
- oscura/component/reactive.py +598 -0
- oscura/component/transmission_line.py +312 -0
- oscura/config/__init__.py +191 -0
- oscura/config/defaults.py +254 -0
- oscura/config/loader.py +348 -0
- oscura/config/memory.py +271 -0
- oscura/config/migration.py +458 -0
- oscura/config/pipeline.py +1077 -0
- oscura/config/preferences.py +530 -0
- oscura/config/protocol.py +875 -0
- oscura/config/schema.py +713 -0
- oscura/config/settings.py +420 -0
- oscura/config/thresholds.py +599 -0
- oscura/convenience.py +457 -0
- oscura/core/__init__.py +299 -0
- oscura/core/audit.py +457 -0
- oscura/core/backend_selector.py +405 -0
- oscura/core/cache.py +590 -0
- oscura/core/cancellation.py +439 -0
- oscura/core/confidence.py +225 -0
- oscura/core/config.py +506 -0
- oscura/core/correlation.py +216 -0
- oscura/core/cross_domain.py +422 -0
- oscura/core/debug.py +301 -0
- oscura/core/edge_cases.py +541 -0
- oscura/core/exceptions.py +535 -0
- oscura/core/gpu_backend.py +523 -0
- oscura/core/lazy.py +832 -0
- oscura/core/log_query.py +540 -0
- oscura/core/logging.py +931 -0
- oscura/core/logging_advanced.py +952 -0
- oscura/core/memoize.py +171 -0
- oscura/core/memory_check.py +274 -0
- oscura/core/memory_guard.py +290 -0
- oscura/core/memory_limits.py +336 -0
- oscura/core/memory_monitor.py +453 -0
- oscura/core/memory_progress.py +465 -0
- oscura/core/memory_warnings.py +315 -0
- oscura/core/numba_backend.py +362 -0
- oscura/core/performance.py +352 -0
- oscura/core/progress.py +524 -0
- oscura/core/provenance.py +358 -0
- oscura/core/results.py +331 -0
- oscura/core/types.py +504 -0
- oscura/core/uncertainty.py +383 -0
- oscura/discovery/__init__.py +52 -0
- oscura/discovery/anomaly_detector.py +672 -0
- oscura/discovery/auto_decoder.py +415 -0
- oscura/discovery/comparison.py +497 -0
- oscura/discovery/quality_validator.py +528 -0
- oscura/discovery/signal_detector.py +769 -0
- oscura/dsl/__init__.py +73 -0
- oscura/dsl/commands.py +246 -0
- oscura/dsl/interpreter.py +455 -0
- oscura/dsl/parser.py +689 -0
- oscura/dsl/repl.py +172 -0
- oscura/exceptions.py +59 -0
- oscura/exploratory/__init__.py +111 -0
- oscura/exploratory/error_recovery.py +642 -0
- oscura/exploratory/fuzzy.py +513 -0
- oscura/exploratory/fuzzy_advanced.py +786 -0
- oscura/exploratory/legacy.py +831 -0
- oscura/exploratory/parse.py +358 -0
- oscura/exploratory/recovery.py +275 -0
- oscura/exploratory/sync.py +382 -0
- oscura/exploratory/unknown.py +707 -0
- oscura/export/__init__.py +25 -0
- oscura/export/wireshark/README.md +265 -0
- oscura/export/wireshark/__init__.py +47 -0
- oscura/export/wireshark/generator.py +312 -0
- oscura/export/wireshark/lua_builder.py +159 -0
- oscura/export/wireshark/templates/dissector.lua.j2 +92 -0
- oscura/export/wireshark/type_mapping.py +165 -0
- oscura/export/wireshark/validator.py +105 -0
- oscura/exporters/__init__.py +94 -0
- oscura/exporters/csv.py +303 -0
- oscura/exporters/exporters.py +44 -0
- oscura/exporters/hdf5.py +219 -0
- oscura/exporters/html_export.py +701 -0
- oscura/exporters/json_export.py +291 -0
- oscura/exporters/markdown_export.py +367 -0
- oscura/exporters/matlab_export.py +354 -0
- oscura/exporters/npz_export.py +219 -0
- oscura/exporters/spice_export.py +210 -0
- oscura/extensibility/__init__.py +131 -0
- oscura/extensibility/docs.py +752 -0
- oscura/extensibility/extensions.py +1125 -0
- oscura/extensibility/logging.py +259 -0
- oscura/extensibility/measurements.py +485 -0
- oscura/extensibility/plugins.py +414 -0
- oscura/extensibility/registry.py +346 -0
- oscura/extensibility/templates.py +913 -0
- oscura/extensibility/validation.py +651 -0
- oscura/filtering/__init__.py +89 -0
- oscura/filtering/base.py +563 -0
- oscura/filtering/convenience.py +564 -0
- oscura/filtering/design.py +725 -0
- oscura/filtering/filters.py +32 -0
- oscura/filtering/introspection.py +605 -0
- oscura/guidance/__init__.py +24 -0
- oscura/guidance/recommender.py +429 -0
- oscura/guidance/wizard.py +518 -0
- oscura/inference/__init__.py +251 -0
- oscura/inference/active_learning/README.md +153 -0
- oscura/inference/active_learning/__init__.py +38 -0
- oscura/inference/active_learning/lstar.py +257 -0
- oscura/inference/active_learning/observation_table.py +230 -0
- oscura/inference/active_learning/oracle.py +78 -0
- oscura/inference/active_learning/teachers/__init__.py +15 -0
- oscura/inference/active_learning/teachers/simulator.py +192 -0
- oscura/inference/adaptive_tuning.py +453 -0
- oscura/inference/alignment.py +653 -0
- oscura/inference/bayesian.py +943 -0
- oscura/inference/binary.py +1016 -0
- oscura/inference/crc_reverse.py +711 -0
- oscura/inference/logic.py +288 -0
- oscura/inference/message_format.py +1305 -0
- oscura/inference/protocol.py +417 -0
- oscura/inference/protocol_dsl.py +1084 -0
- oscura/inference/protocol_library.py +1230 -0
- oscura/inference/sequences.py +809 -0
- oscura/inference/signal_intelligence.py +1509 -0
- oscura/inference/spectral.py +215 -0
- oscura/inference/state_machine.py +634 -0
- oscura/inference/stream.py +918 -0
- oscura/integrations/__init__.py +59 -0
- oscura/integrations/llm.py +1827 -0
- oscura/jupyter/__init__.py +32 -0
- oscura/jupyter/display.py +268 -0
- oscura/jupyter/magic.py +334 -0
- oscura/loaders/__init__.py +526 -0
- oscura/loaders/binary.py +69 -0
- oscura/loaders/configurable.py +1255 -0
- oscura/loaders/csv.py +26 -0
- oscura/loaders/csv_loader.py +473 -0
- oscura/loaders/hdf5.py +9 -0
- oscura/loaders/hdf5_loader.py +510 -0
- oscura/loaders/lazy.py +370 -0
- oscura/loaders/mmap_loader.py +583 -0
- oscura/loaders/numpy_loader.py +436 -0
- oscura/loaders/pcap.py +432 -0
- oscura/loaders/preprocessing.py +368 -0
- oscura/loaders/rigol.py +287 -0
- oscura/loaders/sigrok.py +321 -0
- oscura/loaders/tdms.py +367 -0
- oscura/loaders/tektronix.py +711 -0
- oscura/loaders/validation.py +584 -0
- oscura/loaders/vcd.py +464 -0
- oscura/loaders/wav.py +233 -0
- oscura/math/__init__.py +45 -0
- oscura/math/arithmetic.py +824 -0
- oscura/math/interpolation.py +413 -0
- oscura/onboarding/__init__.py +39 -0
- oscura/onboarding/help.py +498 -0
- oscura/onboarding/tutorials.py +405 -0
- oscura/onboarding/wizard.py +466 -0
- oscura/optimization/__init__.py +19 -0
- oscura/optimization/parallel.py +440 -0
- oscura/optimization/search.py +532 -0
- oscura/pipeline/__init__.py +43 -0
- oscura/pipeline/base.py +338 -0
- oscura/pipeline/composition.py +242 -0
- oscura/pipeline/parallel.py +448 -0
- oscura/pipeline/pipeline.py +375 -0
- oscura/pipeline/reverse_engineering.py +1119 -0
- oscura/plugins/__init__.py +122 -0
- oscura/plugins/base.py +272 -0
- oscura/plugins/cli.py +497 -0
- oscura/plugins/discovery.py +411 -0
- oscura/plugins/isolation.py +418 -0
- oscura/plugins/lifecycle.py +959 -0
- oscura/plugins/manager.py +493 -0
- oscura/plugins/registry.py +421 -0
- oscura/plugins/versioning.py +372 -0
- oscura/py.typed +0 -0
- oscura/quality/__init__.py +65 -0
- oscura/quality/ensemble.py +740 -0
- oscura/quality/explainer.py +338 -0
- oscura/quality/scoring.py +616 -0
- oscura/quality/warnings.py +456 -0
- oscura/reporting/__init__.py +248 -0
- oscura/reporting/advanced.py +1234 -0
- oscura/reporting/analyze.py +448 -0
- oscura/reporting/argument_preparer.py +596 -0
- oscura/reporting/auto_report.py +507 -0
- oscura/reporting/batch.py +615 -0
- oscura/reporting/chart_selection.py +223 -0
- oscura/reporting/comparison.py +330 -0
- oscura/reporting/config.py +615 -0
- oscura/reporting/content/__init__.py +39 -0
- oscura/reporting/content/executive.py +127 -0
- oscura/reporting/content/filtering.py +191 -0
- oscura/reporting/content/minimal.py +257 -0
- oscura/reporting/content/verbosity.py +162 -0
- oscura/reporting/core.py +508 -0
- oscura/reporting/core_formats/__init__.py +17 -0
- oscura/reporting/core_formats/multi_format.py +210 -0
- oscura/reporting/engine.py +836 -0
- oscura/reporting/export.py +366 -0
- oscura/reporting/formatting/__init__.py +129 -0
- oscura/reporting/formatting/emphasis.py +81 -0
- oscura/reporting/formatting/numbers.py +403 -0
- oscura/reporting/formatting/standards.py +55 -0
- oscura/reporting/formatting.py +466 -0
- oscura/reporting/html.py +578 -0
- oscura/reporting/index.py +590 -0
- oscura/reporting/multichannel.py +296 -0
- oscura/reporting/output.py +379 -0
- oscura/reporting/pdf.py +373 -0
- oscura/reporting/plots.py +731 -0
- oscura/reporting/pptx_export.py +360 -0
- oscura/reporting/renderers/__init__.py +11 -0
- oscura/reporting/renderers/pdf.py +94 -0
- oscura/reporting/sections.py +471 -0
- oscura/reporting/standards.py +680 -0
- oscura/reporting/summary_generator.py +368 -0
- oscura/reporting/tables.py +397 -0
- oscura/reporting/template_system.py +724 -0
- oscura/reporting/templates/__init__.py +15 -0
- oscura/reporting/templates/definition.py +205 -0
- oscura/reporting/templates/index.html +649 -0
- oscura/reporting/templates/index.md +173 -0
- oscura/schemas/__init__.py +158 -0
- oscura/schemas/bus_configuration.json +322 -0
- oscura/schemas/device_mapping.json +182 -0
- oscura/schemas/packet_format.json +418 -0
- oscura/schemas/protocol_definition.json +363 -0
- oscura/search/__init__.py +16 -0
- oscura/search/anomaly.py +292 -0
- oscura/search/context.py +149 -0
- oscura/search/pattern.py +160 -0
- oscura/session/__init__.py +34 -0
- oscura/session/annotations.py +289 -0
- oscura/session/history.py +313 -0
- oscura/session/session.py +445 -0
- oscura/streaming/__init__.py +43 -0
- oscura/streaming/chunked.py +611 -0
- oscura/streaming/progressive.py +393 -0
- oscura/streaming/realtime.py +622 -0
- oscura/testing/__init__.py +54 -0
- oscura/testing/synthetic.py +808 -0
- oscura/triggering/__init__.py +68 -0
- oscura/triggering/base.py +229 -0
- oscura/triggering/edge.py +353 -0
- oscura/triggering/pattern.py +344 -0
- oscura/triggering/pulse.py +581 -0
- oscura/triggering/window.py +453 -0
- oscura/ui/__init__.py +48 -0
- oscura/ui/formatters.py +526 -0
- oscura/ui/progressive_display.py +340 -0
- oscura/utils/__init__.py +99 -0
- oscura/utils/autodetect.py +338 -0
- oscura/utils/buffer.py +389 -0
- oscura/utils/lazy.py +407 -0
- oscura/utils/lazy_imports.py +147 -0
- oscura/utils/memory.py +836 -0
- oscura/utils/memory_advanced.py +1326 -0
- oscura/utils/memory_extensions.py +465 -0
- oscura/utils/progressive.py +352 -0
- oscura/utils/windowing.py +362 -0
- oscura/visualization/__init__.py +321 -0
- oscura/visualization/accessibility.py +526 -0
- oscura/visualization/annotations.py +374 -0
- oscura/visualization/axis_scaling.py +305 -0
- oscura/visualization/colors.py +453 -0
- oscura/visualization/digital.py +337 -0
- oscura/visualization/eye.py +420 -0
- oscura/visualization/histogram.py +281 -0
- oscura/visualization/interactive.py +858 -0
- oscura/visualization/jitter.py +702 -0
- oscura/visualization/keyboard.py +394 -0
- oscura/visualization/layout.py +365 -0
- oscura/visualization/optimization.py +1028 -0
- oscura/visualization/palettes.py +446 -0
- oscura/visualization/plot.py +92 -0
- oscura/visualization/power.py +290 -0
- oscura/visualization/power_extended.py +626 -0
- oscura/visualization/presets.py +467 -0
- oscura/visualization/protocols.py +932 -0
- oscura/visualization/render.py +207 -0
- oscura/visualization/rendering.py +444 -0
- oscura/visualization/reverse_engineering.py +791 -0
- oscura/visualization/signal_integrity.py +808 -0
- oscura/visualization/specialized.py +553 -0
- oscura/visualization/spectral.py +811 -0
- oscura/visualization/styles.py +381 -0
- oscura/visualization/thumbnails.py +311 -0
- oscura/visualization/time_axis.py +351 -0
- oscura/visualization/waveform.py +367 -0
- oscura/workflow/__init__.py +13 -0
- oscura/workflow/dag.py +377 -0
- oscura/workflows/__init__.py +58 -0
- oscura/workflows/compliance.py +280 -0
- oscura/workflows/digital.py +272 -0
- oscura/workflows/multi_trace.py +502 -0
- oscura/workflows/power.py +178 -0
- oscura/workflows/protocol.py +492 -0
- oscura/workflows/reverse_engineering.py +639 -0
- oscura/workflows/signal_integrity.py +227 -0
- oscura-0.1.0.dist-info/METADATA +300 -0
- oscura-0.1.0.dist-info/RECORD +463 -0
- oscura-0.1.0.dist-info/entry_points.txt +2 -0
- {oscura-0.0.1.dist-info → oscura-0.1.0.dist-info}/licenses/LICENSE +1 -1
- oscura-0.0.1.dist-info/METADATA +0 -63
- oscura-0.0.1.dist-info/RECORD +0 -5
- {oscura-0.0.1.dist-info → oscura-0.1.0.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,535 @@
|
|
|
1
|
+
"""TraceKit exception hierarchy with helpful error messages.
|
|
2
|
+
|
|
3
|
+
This module provides custom exception classes that follow a consistent
|
|
4
|
+
template for error messages: WHAT, WHY, HOW TO FIX, DOCUMENTATION LINK.
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Example:
|
|
8
|
+
>>> try:
|
|
9
|
+
... raise UnsupportedFormatError(".xyz", ["wfm", "csv", "npz"])
|
|
10
|
+
... except UnsupportedFormatError as e:
|
|
11
|
+
... print(e)
|
|
12
|
+
Unsupported file format: .xyz
|
|
13
|
+
...
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
from typing import Any
|
|
19
|
+
|
|
20
|
+
# Documentation base URL
|
|
21
|
+
# Points to GitHub repository docs directory as primary documentation source.
|
|
22
|
+
# Update this when official documentation hosting is configured (e.g., ReadTheDocs).
|
|
23
|
+
#
|
|
24
|
+
# To verify/update this URL:
|
|
25
|
+
# 1. Check if https://oscura.readthedocs.io exists and is active
|
|
26
|
+
# 2. If not, use GitHub repository docs: https://github.com/lair-click-bats/oscura/tree/main/docs
|
|
27
|
+
# 3. Or local docs path for development: file:///path/to/docs/
|
|
28
|
+
DOCS_BASE_URL = "https://github.com/lair-click-bats/oscura/tree/main/docs"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class TraceKitError(Exception):
|
|
32
|
+
"""Base exception for all TraceKit errors.
|
|
33
|
+
|
|
34
|
+
All TraceKit exceptions inherit from this class, providing a
|
|
35
|
+
consistent interface for error handling.
|
|
36
|
+
|
|
37
|
+
Attributes:
|
|
38
|
+
message: Brief description of the error.
|
|
39
|
+
details: Additional context about the error.
|
|
40
|
+
fix_hint: Suggestion for how to fix the error.
|
|
41
|
+
docs_path: Path to relevant documentation.
|
|
42
|
+
|
|
43
|
+
Example:
|
|
44
|
+
>>> raise TraceKitError("Something went wrong")
|
|
45
|
+
TraceKitError: Something went wrong
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
docs_path: str = "errors"
|
|
49
|
+
|
|
50
|
+
def __init__(
|
|
51
|
+
self,
|
|
52
|
+
message: str,
|
|
53
|
+
*,
|
|
54
|
+
details: str | None = None,
|
|
55
|
+
fix_hint: str | None = None,
|
|
56
|
+
docs_path: str | None = None,
|
|
57
|
+
) -> None:
|
|
58
|
+
"""Initialize TraceKitError.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
message: Brief description of the error.
|
|
62
|
+
details: Additional context about what caused the error.
|
|
63
|
+
fix_hint: Suggestion for how to fix the error.
|
|
64
|
+
docs_path: Path to relevant documentation (appended to base URL).
|
|
65
|
+
"""
|
|
66
|
+
self.message = message
|
|
67
|
+
self.details = details
|
|
68
|
+
self.fix_hint = fix_hint
|
|
69
|
+
if docs_path is not None:
|
|
70
|
+
self.docs_path = docs_path
|
|
71
|
+
super().__init__(self._format_message())
|
|
72
|
+
|
|
73
|
+
def _format_message(self) -> str:
|
|
74
|
+
"""Format the full error message with template.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
Formatted error message with WHAT, WHY, HOW TO FIX, DOCS.
|
|
78
|
+
"""
|
|
79
|
+
parts = [self.message]
|
|
80
|
+
|
|
81
|
+
if self.details:
|
|
82
|
+
parts.append(f"Details: {self.details}")
|
|
83
|
+
|
|
84
|
+
if self.fix_hint:
|
|
85
|
+
parts.append(f"Fix: {self.fix_hint}")
|
|
86
|
+
|
|
87
|
+
parts.append(f"Docs: {DOCS_BASE_URL}/{self.docs_path}")
|
|
88
|
+
|
|
89
|
+
return "\n".join(parts)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class LoaderError(TraceKitError):
|
|
93
|
+
"""Error loading trace data from file.
|
|
94
|
+
|
|
95
|
+
Raised when a file cannot be read, parsed, or converted to
|
|
96
|
+
a TraceKit data structure.
|
|
97
|
+
|
|
98
|
+
Attributes:
|
|
99
|
+
file_path: Path to the file that failed to load.
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
docs_path: str = "errors#loader"
|
|
103
|
+
|
|
104
|
+
def __init__(
|
|
105
|
+
self,
|
|
106
|
+
message: str,
|
|
107
|
+
*,
|
|
108
|
+
file_path: str | None = None,
|
|
109
|
+
details: str | None = None,
|
|
110
|
+
fix_hint: str | None = None,
|
|
111
|
+
) -> None:
|
|
112
|
+
"""Initialize LoaderError.
|
|
113
|
+
|
|
114
|
+
Args:
|
|
115
|
+
message: Brief description of the error.
|
|
116
|
+
file_path: Path to the file that failed to load.
|
|
117
|
+
details: Additional context about the error.
|
|
118
|
+
fix_hint: Suggestion for how to fix the error.
|
|
119
|
+
"""
|
|
120
|
+
self.file_path = file_path
|
|
121
|
+
if file_path and not details:
|
|
122
|
+
details = f"File: {file_path}"
|
|
123
|
+
elif file_path and details:
|
|
124
|
+
details = f"File: {file_path}. {details}"
|
|
125
|
+
super().__init__(
|
|
126
|
+
message,
|
|
127
|
+
details=details,
|
|
128
|
+
fix_hint=fix_hint,
|
|
129
|
+
docs_path=self.docs_path,
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class UnsupportedFormatError(LoaderError):
|
|
134
|
+
"""File format not recognized or unsupported.
|
|
135
|
+
|
|
136
|
+
Raised when attempting to load a file with an unsupported
|
|
137
|
+
extension or format.
|
|
138
|
+
|
|
139
|
+
Attributes:
|
|
140
|
+
format_ext: The unsupported format extension.
|
|
141
|
+
supported_formats: List of supported format extensions.
|
|
142
|
+
"""
|
|
143
|
+
|
|
144
|
+
docs_path: str = "errors#unsupported-format"
|
|
145
|
+
|
|
146
|
+
def __init__(
|
|
147
|
+
self,
|
|
148
|
+
format_ext: str,
|
|
149
|
+
supported_formats: list[str] | None = None,
|
|
150
|
+
*,
|
|
151
|
+
file_path: str | None = None,
|
|
152
|
+
) -> None:
|
|
153
|
+
"""Initialize UnsupportedFormatError.
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
format_ext: The unsupported format extension (e.g., ".xyz").
|
|
157
|
+
supported_formats: List of supported format extensions.
|
|
158
|
+
file_path: Path to the file that failed to load.
|
|
159
|
+
"""
|
|
160
|
+
self.format_ext = format_ext
|
|
161
|
+
self.supported_formats = supported_formats or []
|
|
162
|
+
|
|
163
|
+
message = f"Unsupported file format: {format_ext}"
|
|
164
|
+
|
|
165
|
+
if self.supported_formats:
|
|
166
|
+
formats_str = ", ".join(self.supported_formats)
|
|
167
|
+
details = f"Supported formats: {formats_str}"
|
|
168
|
+
else:
|
|
169
|
+
details = None
|
|
170
|
+
|
|
171
|
+
fix_hint = "Convert the file to a supported format or use a custom loader."
|
|
172
|
+
|
|
173
|
+
super().__init__(
|
|
174
|
+
message,
|
|
175
|
+
file_path=file_path,
|
|
176
|
+
details=details,
|
|
177
|
+
fix_hint=fix_hint,
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
class FormatError(LoaderError):
|
|
182
|
+
"""File format is invalid or corrupted.
|
|
183
|
+
|
|
184
|
+
Raised when a file has the correct extension but invalid content.
|
|
185
|
+
"""
|
|
186
|
+
|
|
187
|
+
docs_path: str = "errors#format-error"
|
|
188
|
+
|
|
189
|
+
def __init__(
|
|
190
|
+
self,
|
|
191
|
+
message: str,
|
|
192
|
+
*,
|
|
193
|
+
file_path: str | None = None,
|
|
194
|
+
expected: str | None = None,
|
|
195
|
+
got: str | None = None,
|
|
196
|
+
details: str | None = None,
|
|
197
|
+
fix_hint: str | None = None,
|
|
198
|
+
) -> None:
|
|
199
|
+
"""Initialize FormatError.
|
|
200
|
+
|
|
201
|
+
Args:
|
|
202
|
+
message: Brief description of the error.
|
|
203
|
+
file_path: Path to the file that failed to load.
|
|
204
|
+
expected: What was expected in the file.
|
|
205
|
+
got: What was actually found.
|
|
206
|
+
details: Additional context about the error (overrides expected/got).
|
|
207
|
+
fix_hint: Suggestion for how to fix the error.
|
|
208
|
+
"""
|
|
209
|
+
# Build details from expected/got if not provided directly
|
|
210
|
+
if details is None:
|
|
211
|
+
if expected and got:
|
|
212
|
+
details = f"Expected: {expected}. Got: {got}"
|
|
213
|
+
elif expected:
|
|
214
|
+
details = f"Expected: {expected}"
|
|
215
|
+
elif got:
|
|
216
|
+
details = f"Found: {got}"
|
|
217
|
+
|
|
218
|
+
# Use default fix_hint if not provided
|
|
219
|
+
if fix_hint is None:
|
|
220
|
+
fix_hint = "Verify the file is not corrupted and matches the expected format."
|
|
221
|
+
|
|
222
|
+
super().__init__(
|
|
223
|
+
message,
|
|
224
|
+
file_path=file_path,
|
|
225
|
+
details=details,
|
|
226
|
+
fix_hint=fix_hint,
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
class AnalysisError(TraceKitError):
|
|
231
|
+
"""Error during signal analysis.
|
|
232
|
+
|
|
233
|
+
Raised when an analysis function encounters invalid data
|
|
234
|
+
or cannot compute a result.
|
|
235
|
+
"""
|
|
236
|
+
|
|
237
|
+
docs_path: str = "errors#analysis"
|
|
238
|
+
|
|
239
|
+
def __init__(
|
|
240
|
+
self,
|
|
241
|
+
message: str,
|
|
242
|
+
*,
|
|
243
|
+
analysis_type: str | None = None,
|
|
244
|
+
details: str | None = None,
|
|
245
|
+
fix_hint: str | None = None,
|
|
246
|
+
) -> None:
|
|
247
|
+
"""Initialize AnalysisError.
|
|
248
|
+
|
|
249
|
+
Args:
|
|
250
|
+
message: Brief description of the error.
|
|
251
|
+
analysis_type: Type of analysis that failed (e.g., "rise_time").
|
|
252
|
+
details: Additional context about the error.
|
|
253
|
+
fix_hint: Suggestion for how to fix the error.
|
|
254
|
+
"""
|
|
255
|
+
self.analysis_type = analysis_type
|
|
256
|
+
if analysis_type and not details:
|
|
257
|
+
details = f"Analysis: {analysis_type}"
|
|
258
|
+
elif analysis_type and details:
|
|
259
|
+
details = f"Analysis: {analysis_type}. {details}"
|
|
260
|
+
super().__init__(
|
|
261
|
+
message,
|
|
262
|
+
details=details,
|
|
263
|
+
fix_hint=fix_hint,
|
|
264
|
+
docs_path=self.docs_path,
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
class InsufficientDataError(AnalysisError):
|
|
269
|
+
"""Not enough data points for the requested analysis.
|
|
270
|
+
|
|
271
|
+
Raised when a signal is too short or lacks sufficient
|
|
272
|
+
features (edges, periods, etc.) for analysis.
|
|
273
|
+
|
|
274
|
+
Attributes:
|
|
275
|
+
required: Minimum data points or features required.
|
|
276
|
+
available: Actual data points or features available.
|
|
277
|
+
"""
|
|
278
|
+
|
|
279
|
+
docs_path: str = "errors#insufficient-data"
|
|
280
|
+
|
|
281
|
+
def __init__(
|
|
282
|
+
self,
|
|
283
|
+
message: str,
|
|
284
|
+
*,
|
|
285
|
+
required: int | None = None,
|
|
286
|
+
available: int | None = None,
|
|
287
|
+
analysis_type: str | None = None,
|
|
288
|
+
) -> None:
|
|
289
|
+
"""Initialize InsufficientDataError.
|
|
290
|
+
|
|
291
|
+
Args:
|
|
292
|
+
message: Brief description of the error.
|
|
293
|
+
required: Minimum number of samples or features required.
|
|
294
|
+
available: Actual number available.
|
|
295
|
+
analysis_type: Type of analysis that failed.
|
|
296
|
+
"""
|
|
297
|
+
self.required = required
|
|
298
|
+
self.available = available
|
|
299
|
+
|
|
300
|
+
details = None
|
|
301
|
+
if required is not None and available is not None:
|
|
302
|
+
details = f"Required: {required}. Available: {available}"
|
|
303
|
+
elif required is not None:
|
|
304
|
+
details = f"Minimum required: {required}"
|
|
305
|
+
|
|
306
|
+
fix_hint = "Acquire more data or reduce analysis window."
|
|
307
|
+
|
|
308
|
+
super().__init__(
|
|
309
|
+
message,
|
|
310
|
+
analysis_type=analysis_type,
|
|
311
|
+
details=details,
|
|
312
|
+
fix_hint=fix_hint,
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
class SampleRateError(AnalysisError):
|
|
317
|
+
"""Invalid or missing sample rate.
|
|
318
|
+
|
|
319
|
+
Raised when sample rate is invalid (zero, negative) or
|
|
320
|
+
insufficient for the requested analysis.
|
|
321
|
+
|
|
322
|
+
Attributes:
|
|
323
|
+
required_rate: Minimum sample rate required.
|
|
324
|
+
actual_rate: Actual sample rate provided.
|
|
325
|
+
"""
|
|
326
|
+
|
|
327
|
+
docs_path: str = "errors#sample-rate"
|
|
328
|
+
|
|
329
|
+
def __init__(
|
|
330
|
+
self,
|
|
331
|
+
message: str,
|
|
332
|
+
*,
|
|
333
|
+
required_rate: float | None = None,
|
|
334
|
+
actual_rate: float | None = None,
|
|
335
|
+
) -> None:
|
|
336
|
+
"""Initialize SampleRateError.
|
|
337
|
+
|
|
338
|
+
Args:
|
|
339
|
+
message: Brief description of the error.
|
|
340
|
+
required_rate: Minimum sample rate required in Hz.
|
|
341
|
+
actual_rate: Actual sample rate in Hz.
|
|
342
|
+
"""
|
|
343
|
+
self.required_rate = required_rate
|
|
344
|
+
self.actual_rate = actual_rate
|
|
345
|
+
|
|
346
|
+
details = None
|
|
347
|
+
if required_rate is not None and actual_rate is not None:
|
|
348
|
+
details = f"Required: {required_rate:.2e} Hz. Got: {actual_rate:.2e} Hz"
|
|
349
|
+
elif actual_rate is not None:
|
|
350
|
+
details = f"Got: {actual_rate:.2e} Hz"
|
|
351
|
+
|
|
352
|
+
fix_hint = "Ensure sample_rate is positive and sufficient for the analysis."
|
|
353
|
+
|
|
354
|
+
super().__init__(
|
|
355
|
+
message,
|
|
356
|
+
details=details,
|
|
357
|
+
fix_hint=fix_hint,
|
|
358
|
+
)
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
class ConfigurationError(TraceKitError):
|
|
362
|
+
"""Invalid configuration parameters.
|
|
363
|
+
|
|
364
|
+
Raised when configuration is invalid, missing required fields,
|
|
365
|
+
or contains invalid values.
|
|
366
|
+
|
|
367
|
+
Attributes:
|
|
368
|
+
config_key: The configuration key that is invalid.
|
|
369
|
+
expected_type: Expected type or format.
|
|
370
|
+
actual_value: The invalid value that was provided.
|
|
371
|
+
"""
|
|
372
|
+
|
|
373
|
+
docs_path: str = "errors#configuration"
|
|
374
|
+
|
|
375
|
+
def __init__(
|
|
376
|
+
self,
|
|
377
|
+
message: str,
|
|
378
|
+
*,
|
|
379
|
+
config_key: str | None = None,
|
|
380
|
+
expected_type: str | None = None,
|
|
381
|
+
actual_value: Any = None,
|
|
382
|
+
details: str | None = None,
|
|
383
|
+
fix_hint: str | None = None,
|
|
384
|
+
) -> None:
|
|
385
|
+
"""Initialize ConfigurationError.
|
|
386
|
+
|
|
387
|
+
Args:
|
|
388
|
+
message: Brief description of the error.
|
|
389
|
+
config_key: The configuration key that is invalid.
|
|
390
|
+
expected_type: Expected type or format.
|
|
391
|
+
actual_value: The invalid value that was provided.
|
|
392
|
+
details: Additional context about the error.
|
|
393
|
+
fix_hint: Suggestion for how to fix the error.
|
|
394
|
+
"""
|
|
395
|
+
self.config_key = config_key
|
|
396
|
+
self.expected_type = expected_type
|
|
397
|
+
self.actual_value = actual_value
|
|
398
|
+
|
|
399
|
+
# Build details from parts if not provided directly
|
|
400
|
+
if details is None:
|
|
401
|
+
details_parts = []
|
|
402
|
+
if config_key:
|
|
403
|
+
details_parts.append(f"Key: {config_key}")
|
|
404
|
+
if expected_type:
|
|
405
|
+
details_parts.append(f"Expected: {expected_type}")
|
|
406
|
+
if actual_value is not None:
|
|
407
|
+
details_parts.append(f"Got: {actual_value!r}")
|
|
408
|
+
details = ". ".join(details_parts) if details_parts else None
|
|
409
|
+
|
|
410
|
+
if fix_hint is None:
|
|
411
|
+
fix_hint = "Check configuration file and ensure all values are valid."
|
|
412
|
+
|
|
413
|
+
super().__init__(
|
|
414
|
+
message,
|
|
415
|
+
details=details,
|
|
416
|
+
fix_hint=fix_hint,
|
|
417
|
+
docs_path=self.docs_path,
|
|
418
|
+
)
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
class ValidationError(TraceKitError):
|
|
422
|
+
"""Data validation failed.
|
|
423
|
+
|
|
424
|
+
Raised when input data does not meet validation requirements.
|
|
425
|
+
|
|
426
|
+
Attributes:
|
|
427
|
+
field: The field that failed validation.
|
|
428
|
+
constraint: The constraint that was violated.
|
|
429
|
+
value: The value that failed validation.
|
|
430
|
+
"""
|
|
431
|
+
|
|
432
|
+
docs_path: str = "errors#validation"
|
|
433
|
+
|
|
434
|
+
def __init__(
|
|
435
|
+
self,
|
|
436
|
+
message: str,
|
|
437
|
+
*,
|
|
438
|
+
field: str | None = None,
|
|
439
|
+
constraint: str | None = None,
|
|
440
|
+
value: Any = None,
|
|
441
|
+
) -> None:
|
|
442
|
+
"""Initialize ValidationError.
|
|
443
|
+
|
|
444
|
+
Args:
|
|
445
|
+
message: Brief description of the error.
|
|
446
|
+
field: The field that failed validation.
|
|
447
|
+
constraint: The constraint that was violated.
|
|
448
|
+
value: The value that failed validation.
|
|
449
|
+
"""
|
|
450
|
+
self.field = field
|
|
451
|
+
self.constraint = constraint
|
|
452
|
+
self.value = value
|
|
453
|
+
|
|
454
|
+
details_parts = []
|
|
455
|
+
if field:
|
|
456
|
+
details_parts.append(f"Field: {field}")
|
|
457
|
+
if constraint:
|
|
458
|
+
details_parts.append(f"Constraint: {constraint}")
|
|
459
|
+
if value is not None:
|
|
460
|
+
details_parts.append(f"Value: {value!r}")
|
|
461
|
+
|
|
462
|
+
details = ". ".join(details_parts) if details_parts else None
|
|
463
|
+
fix_hint = "Ensure input data meets all validation requirements."
|
|
464
|
+
|
|
465
|
+
super().__init__(
|
|
466
|
+
message,
|
|
467
|
+
details=details,
|
|
468
|
+
fix_hint=fix_hint,
|
|
469
|
+
docs_path=self.docs_path,
|
|
470
|
+
)
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
class ExportError(TraceKitError):
|
|
474
|
+
"""Error exporting data.
|
|
475
|
+
|
|
476
|
+
Raised when data cannot be exported to the requested format.
|
|
477
|
+
|
|
478
|
+
Attributes:
|
|
479
|
+
export_format: The format that failed.
|
|
480
|
+
output_path: Path where export was attempted.
|
|
481
|
+
"""
|
|
482
|
+
|
|
483
|
+
docs_path: str = "errors#export"
|
|
484
|
+
|
|
485
|
+
def __init__(
|
|
486
|
+
self,
|
|
487
|
+
message: str,
|
|
488
|
+
*,
|
|
489
|
+
export_format: str | None = None,
|
|
490
|
+
output_path: str | None = None,
|
|
491
|
+
details: str | None = None,
|
|
492
|
+
) -> None:
|
|
493
|
+
"""Initialize ExportError.
|
|
494
|
+
|
|
495
|
+
Args:
|
|
496
|
+
message: Brief description of the error.
|
|
497
|
+
export_format: The format that failed (e.g., "csv", "hdf5").
|
|
498
|
+
output_path: Path where export was attempted.
|
|
499
|
+
details: Additional context about the error.
|
|
500
|
+
"""
|
|
501
|
+
self.export_format = export_format
|
|
502
|
+
self.output_path = output_path
|
|
503
|
+
|
|
504
|
+
details_parts = []
|
|
505
|
+
if export_format:
|
|
506
|
+
details_parts.append(f"Format: {export_format}")
|
|
507
|
+
if output_path:
|
|
508
|
+
details_parts.append(f"Path: {output_path}")
|
|
509
|
+
if details:
|
|
510
|
+
details_parts.append(details)
|
|
511
|
+
|
|
512
|
+
combined_details = ". ".join(details_parts) if details_parts else None
|
|
513
|
+
fix_hint = "Check output path is writable and data is valid for export."
|
|
514
|
+
|
|
515
|
+
super().__init__(
|
|
516
|
+
message,
|
|
517
|
+
details=combined_details,
|
|
518
|
+
fix_hint=fix_hint,
|
|
519
|
+
docs_path=self.docs_path,
|
|
520
|
+
)
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
__all__ = [
|
|
524
|
+
"DOCS_BASE_URL",
|
|
525
|
+
"AnalysisError",
|
|
526
|
+
"ConfigurationError",
|
|
527
|
+
"ExportError",
|
|
528
|
+
"FormatError",
|
|
529
|
+
"InsufficientDataError",
|
|
530
|
+
"LoaderError",
|
|
531
|
+
"SampleRateError",
|
|
532
|
+
"TraceKitError",
|
|
533
|
+
"UnsupportedFormatError",
|
|
534
|
+
"ValidationError",
|
|
535
|
+
]
|