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,456 @@
|
|
|
1
|
+
"""Signal quality warnings for TraceKit.
|
|
2
|
+
|
|
3
|
+
This module provides automated detection and warning of signal quality issues
|
|
4
|
+
including clipping, noise, saturation, and undersampling.
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Example:
|
|
8
|
+
>>> from oscura.quality.warnings import SignalQualityAnalyzer
|
|
9
|
+
>>> analyzer = SignalQualityAnalyzer()
|
|
10
|
+
>>> warnings = analyzer.analyze(trace)
|
|
11
|
+
>>> for warning in warnings:
|
|
12
|
+
... print(warning)
|
|
13
|
+
|
|
14
|
+
References:
|
|
15
|
+
- IEEE 1057: Standard for Digitizing Waveform Recorders
|
|
16
|
+
- Nyquist sampling theorem
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
from dataclasses import dataclass
|
|
22
|
+
from typing import TYPE_CHECKING, Literal
|
|
23
|
+
|
|
24
|
+
import numpy as np
|
|
25
|
+
|
|
26
|
+
if TYPE_CHECKING:
|
|
27
|
+
from numpy.typing import NDArray
|
|
28
|
+
|
|
29
|
+
from oscura.core.types import WaveformTrace
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass
|
|
33
|
+
class QualityWarning:
|
|
34
|
+
"""Signal quality warning.
|
|
35
|
+
|
|
36
|
+
Attributes:
|
|
37
|
+
severity: Warning severity (error, warning, info)
|
|
38
|
+
category: Warning category (clipping, noise, saturation, undersampling)
|
|
39
|
+
message: Human-readable warning message
|
|
40
|
+
value: Numeric value associated with warning
|
|
41
|
+
threshold: Threshold that triggered warning
|
|
42
|
+
suggestion: Suggested action to fix issue
|
|
43
|
+
|
|
44
|
+
Example:
|
|
45
|
+
>>> warning = QualityWarning(
|
|
46
|
+
... severity="warning",
|
|
47
|
+
... category="clipping",
|
|
48
|
+
... message="Signal clipping detected",
|
|
49
|
+
... value=5.2,
|
|
50
|
+
... threshold=5.0,
|
|
51
|
+
... suggestion="Reduce input amplitude or increase ADC range"
|
|
52
|
+
... )
|
|
53
|
+
>>> print(warning)
|
|
54
|
+
|
|
55
|
+
References:
|
|
56
|
+
EDGE-001: Signal Quality Warnings
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
severity: Literal["error", "warning", "info"]
|
|
60
|
+
category: Literal["clipping", "noise", "saturation", "undersampling", "dc_offset"]
|
|
61
|
+
message: str
|
|
62
|
+
value: float
|
|
63
|
+
threshold: float
|
|
64
|
+
suggestion: str = ""
|
|
65
|
+
|
|
66
|
+
def __str__(self) -> str:
|
|
67
|
+
"""Format warning as string.
|
|
68
|
+
|
|
69
|
+
Returns:
|
|
70
|
+
Formatted warning message
|
|
71
|
+
"""
|
|
72
|
+
prefix = {"error": "ERROR", "warning": "WARNING", "info": "INFO"}[self.severity]
|
|
73
|
+
msg = f"[{prefix}] {self.message}"
|
|
74
|
+
if self.value is not None:
|
|
75
|
+
msg += f" (value: {self.value:.3f}, threshold: {self.threshold:.3f})"
|
|
76
|
+
if self.suggestion:
|
|
77
|
+
msg += f"\n Suggestion: {self.suggestion}"
|
|
78
|
+
return msg
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class SignalQualityAnalyzer:
|
|
82
|
+
"""Analyzer for signal quality issues.
|
|
83
|
+
|
|
84
|
+
: Detect clipping, undersampling, noise, and saturation.
|
|
85
|
+
Performs comprehensive signal quality checks and generates warnings.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
clip_threshold: Clipping detection threshold (fraction of range, default: 0.99)
|
|
89
|
+
noise_threshold_db: Noise floor threshold in dB (default: -40)
|
|
90
|
+
saturation_threshold: ADC saturation threshold (default: 0.98)
|
|
91
|
+
nyquist_factor: Factor for Nyquist frequency check (default: 2.0)
|
|
92
|
+
|
|
93
|
+
Example:
|
|
94
|
+
>>> from oscura.quality.warnings import SignalQualityAnalyzer
|
|
95
|
+
>>> analyzer = SignalQualityAnalyzer(clip_threshold=0.95)
|
|
96
|
+
>>> warnings = analyzer.analyze(trace)
|
|
97
|
+
>>> if warnings:
|
|
98
|
+
... for w in warnings:
|
|
99
|
+
... print(w)
|
|
100
|
+
|
|
101
|
+
References:
|
|
102
|
+
EDGE-001: Signal Quality Warnings
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
def __init__(
|
|
106
|
+
self,
|
|
107
|
+
*,
|
|
108
|
+
clip_threshold: float = 0.99,
|
|
109
|
+
noise_threshold_db: float = -40.0,
|
|
110
|
+
saturation_threshold: float = 0.98,
|
|
111
|
+
nyquist_factor: float = 2.0,
|
|
112
|
+
) -> None:
|
|
113
|
+
"""Initialize signal quality analyzer.
|
|
114
|
+
|
|
115
|
+
Args:
|
|
116
|
+
clip_threshold: Clipping detection threshold
|
|
117
|
+
noise_threshold_db: Noise floor threshold in dB
|
|
118
|
+
saturation_threshold: ADC saturation threshold
|
|
119
|
+
nyquist_factor: Nyquist frequency factor
|
|
120
|
+
"""
|
|
121
|
+
self.clip_threshold = clip_threshold
|
|
122
|
+
self.noise_threshold_db = noise_threshold_db
|
|
123
|
+
self.saturation_threshold = saturation_threshold
|
|
124
|
+
self.nyquist_factor = nyquist_factor
|
|
125
|
+
|
|
126
|
+
def analyze(
|
|
127
|
+
self,
|
|
128
|
+
trace: WaveformTrace | NDArray[np.float64],
|
|
129
|
+
*,
|
|
130
|
+
sample_rate: float | None = None,
|
|
131
|
+
adc_range: tuple[float, float] | None = None,
|
|
132
|
+
) -> list[QualityWarning]:
|
|
133
|
+
"""Analyze signal quality and generate warnings.
|
|
134
|
+
|
|
135
|
+
: Comprehensive signal quality detection.
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
trace: Input trace or signal array
|
|
139
|
+
sample_rate: Sample rate in Hz (required for undersampling check)
|
|
140
|
+
adc_range: ADC range as (min, max) tuple
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
List of QualityWarning objects
|
|
144
|
+
|
|
145
|
+
Example:
|
|
146
|
+
>>> warnings = analyzer.analyze(trace, sample_rate=1e9)
|
|
147
|
+
>>> for warning in warnings:
|
|
148
|
+
... print(warning)
|
|
149
|
+
|
|
150
|
+
References:
|
|
151
|
+
EDGE-001: Signal Quality Warnings
|
|
152
|
+
"""
|
|
153
|
+
# Extract data and sample rate
|
|
154
|
+
if hasattr(trace, "data"):
|
|
155
|
+
data = trace.data # type: ignore[ignore-without-code]
|
|
156
|
+
if sample_rate is None and hasattr(trace, "metadata"):
|
|
157
|
+
sample_rate = trace.metadata.sample_rate # type: ignore[ignore-without-code]
|
|
158
|
+
else:
|
|
159
|
+
data = trace # type: ignore[assignment]
|
|
160
|
+
|
|
161
|
+
# Ensure data is NDArray[np.float64]
|
|
162
|
+
data_array: NDArray[np.float64] = np.asarray(data, dtype=np.float64)
|
|
163
|
+
|
|
164
|
+
warnings: list[QualityWarning] = []
|
|
165
|
+
|
|
166
|
+
# Check clipping
|
|
167
|
+
warnings.extend(
|
|
168
|
+
check_clipping(
|
|
169
|
+
data_array,
|
|
170
|
+
threshold=self.clip_threshold,
|
|
171
|
+
adc_range=adc_range,
|
|
172
|
+
)
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
# Check saturation
|
|
176
|
+
warnings.extend(
|
|
177
|
+
check_saturation(
|
|
178
|
+
data_array,
|
|
179
|
+
threshold=self.saturation_threshold,
|
|
180
|
+
adc_range=adc_range,
|
|
181
|
+
)
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
# Check noise
|
|
185
|
+
warnings.extend(
|
|
186
|
+
check_noise(
|
|
187
|
+
data_array,
|
|
188
|
+
threshold_db=self.noise_threshold_db,
|
|
189
|
+
)
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
# Check undersampling (requires sample rate)
|
|
193
|
+
if sample_rate is not None:
|
|
194
|
+
warnings.extend(
|
|
195
|
+
check_undersampling(
|
|
196
|
+
data_array,
|
|
197
|
+
sample_rate=sample_rate,
|
|
198
|
+
nyquist_factor=self.nyquist_factor,
|
|
199
|
+
)
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
return warnings
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def check_clipping(
|
|
206
|
+
signal: NDArray[np.float64],
|
|
207
|
+
*,
|
|
208
|
+
threshold: float = 0.99,
|
|
209
|
+
adc_range: tuple[float, float] | None = None,
|
|
210
|
+
) -> list[QualityWarning]:
|
|
211
|
+
"""Detect signal clipping.
|
|
212
|
+
|
|
213
|
+
: Detect clipping (signal hits rail).
|
|
214
|
+
|
|
215
|
+
Args:
|
|
216
|
+
signal: Input signal array
|
|
217
|
+
threshold: Fraction of range for clipping detection (default: 0.99)
|
|
218
|
+
adc_range: ADC range as (min, max) tuple
|
|
219
|
+
|
|
220
|
+
Returns:
|
|
221
|
+
List of clipping warnings
|
|
222
|
+
|
|
223
|
+
Example:
|
|
224
|
+
>>> import numpy as np
|
|
225
|
+
>>> signal = np.clip(np.random.randn(1000), -1, 1)
|
|
226
|
+
>>> warnings = check_clipping(signal)
|
|
227
|
+
>>> if warnings:
|
|
228
|
+
... print("Clipping detected!")
|
|
229
|
+
|
|
230
|
+
References:
|
|
231
|
+
EDGE-001: Detect clipping
|
|
232
|
+
"""
|
|
233
|
+
warnings: list[QualityWarning] = []
|
|
234
|
+
|
|
235
|
+
# Determine signal range
|
|
236
|
+
if adc_range is not None:
|
|
237
|
+
min_val, max_val = adc_range
|
|
238
|
+
else:
|
|
239
|
+
min_val = float(np.min(signal))
|
|
240
|
+
max_val = float(np.max(signal))
|
|
241
|
+
|
|
242
|
+
signal_range = max_val - min_val
|
|
243
|
+
if signal_range == 0:
|
|
244
|
+
return warnings
|
|
245
|
+
|
|
246
|
+
# Count samples near limits
|
|
247
|
+
upper_limit = min_val + signal_range * threshold
|
|
248
|
+
lower_limit = min_val + signal_range * (1 - threshold)
|
|
249
|
+
|
|
250
|
+
n_upper: int = int(np.sum(signal >= upper_limit))
|
|
251
|
+
n_lower: int = int(np.sum(signal <= lower_limit))
|
|
252
|
+
n_clipped = n_upper + n_lower
|
|
253
|
+
clip_percent = float(100.0 * n_clipped / len(signal))
|
|
254
|
+
|
|
255
|
+
if clip_percent > 1.0: # More than 1% clipped
|
|
256
|
+
severity: Literal["error", "warning"] = "error" if clip_percent > 5.0 else "warning"
|
|
257
|
+
warnings.append(
|
|
258
|
+
QualityWarning(
|
|
259
|
+
severity=severity,
|
|
260
|
+
category="clipping",
|
|
261
|
+
message=f"Signal clipping detected at {clip_percent:.1f}% of samples",
|
|
262
|
+
value=clip_percent,
|
|
263
|
+
threshold=1.0,
|
|
264
|
+
suggestion="Reduce input amplitude or increase ADC range",
|
|
265
|
+
)
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
return warnings
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def check_saturation(
|
|
272
|
+
signal: NDArray[np.float64],
|
|
273
|
+
*,
|
|
274
|
+
threshold: float = 0.98,
|
|
275
|
+
adc_range: tuple[float, float] | None = None,
|
|
276
|
+
) -> list[QualityWarning]:
|
|
277
|
+
"""Detect ADC saturation.
|
|
278
|
+
|
|
279
|
+
: Detect saturation (ADC range utilization).
|
|
280
|
+
|
|
281
|
+
Args:
|
|
282
|
+
signal: Input signal array
|
|
283
|
+
threshold: Saturation threshold as fraction of range (default: 0.98)
|
|
284
|
+
adc_range: ADC range as (min, max) tuple
|
|
285
|
+
|
|
286
|
+
Returns:
|
|
287
|
+
List of saturation warnings
|
|
288
|
+
|
|
289
|
+
Example:
|
|
290
|
+
>>> warnings = check_saturation(signal, threshold=0.95)
|
|
291
|
+
|
|
292
|
+
References:
|
|
293
|
+
EDGE-001: Detect saturation
|
|
294
|
+
"""
|
|
295
|
+
warnings: list[QualityWarning] = []
|
|
296
|
+
|
|
297
|
+
# Determine signal range
|
|
298
|
+
if adc_range is not None:
|
|
299
|
+
adc_min, adc_max = adc_range
|
|
300
|
+
adc_span = adc_max - adc_min
|
|
301
|
+
else:
|
|
302
|
+
# Assume signal uses full observed range as ADC range
|
|
303
|
+
adc_min = float(np.min(signal))
|
|
304
|
+
adc_max = float(np.max(signal))
|
|
305
|
+
adc_span = adc_max - adc_min
|
|
306
|
+
|
|
307
|
+
if adc_span == 0:
|
|
308
|
+
return warnings
|
|
309
|
+
|
|
310
|
+
# Calculate range utilization
|
|
311
|
+
signal_min = float(np.min(signal))
|
|
312
|
+
signal_max = float(np.max(signal))
|
|
313
|
+
signal_span = signal_max - signal_min
|
|
314
|
+
utilization = signal_span / adc_span
|
|
315
|
+
|
|
316
|
+
if utilization > threshold:
|
|
317
|
+
warnings.append(
|
|
318
|
+
QualityWarning(
|
|
319
|
+
severity="warning",
|
|
320
|
+
category="saturation",
|
|
321
|
+
message=f"High ADC range utilization: {utilization * 100:.1f}%",
|
|
322
|
+
value=utilization * 100,
|
|
323
|
+
threshold=threshold * 100,
|
|
324
|
+
suggestion="Consider increasing ADC range or reducing signal amplitude",
|
|
325
|
+
)
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
return warnings
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
def check_noise(
|
|
332
|
+
signal: NDArray[np.float64],
|
|
333
|
+
*,
|
|
334
|
+
threshold_db: float = -40.0,
|
|
335
|
+
) -> list[QualityWarning]:
|
|
336
|
+
"""Detect excessive noise.
|
|
337
|
+
|
|
338
|
+
: Detect noise (SNR below threshold warning).
|
|
339
|
+
|
|
340
|
+
Args:
|
|
341
|
+
signal: Input signal array
|
|
342
|
+
threshold_db: Noise threshold in dB (default: -40)
|
|
343
|
+
|
|
344
|
+
Returns:
|
|
345
|
+
List of noise warnings
|
|
346
|
+
|
|
347
|
+
Example:
|
|
348
|
+
>>> warnings = check_noise(signal, threshold_db=-50)
|
|
349
|
+
|
|
350
|
+
References:
|
|
351
|
+
EDGE-001: Detect noise
|
|
352
|
+
"""
|
|
353
|
+
warnings: list[QualityWarning] = []
|
|
354
|
+
|
|
355
|
+
# Estimate SNR
|
|
356
|
+
signal_power = float(np.mean(signal**2))
|
|
357
|
+
if signal_power == 0:
|
|
358
|
+
return warnings
|
|
359
|
+
|
|
360
|
+
# Estimate noise from high-frequency components
|
|
361
|
+
# Simple approach: use standard deviation as noise estimate
|
|
362
|
+
noise_power = float(np.var(signal))
|
|
363
|
+
if noise_power == 0:
|
|
364
|
+
return warnings
|
|
365
|
+
|
|
366
|
+
snr_linear = signal_power / noise_power
|
|
367
|
+
snr_db = 10 * np.log10(snr_linear) if snr_linear > 0 else -np.inf
|
|
368
|
+
|
|
369
|
+
if snr_db < threshold_db:
|
|
370
|
+
warnings.append(
|
|
371
|
+
QualityWarning(
|
|
372
|
+
severity="warning",
|
|
373
|
+
category="noise",
|
|
374
|
+
message=f"High noise level detected: SNR = {snr_db:.1f} dB",
|
|
375
|
+
value=snr_db,
|
|
376
|
+
threshold=threshold_db,
|
|
377
|
+
suggestion="Check signal source, grounding, and shielding",
|
|
378
|
+
)
|
|
379
|
+
)
|
|
380
|
+
|
|
381
|
+
return warnings
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
def check_undersampling(
|
|
385
|
+
signal: NDArray[np.float64],
|
|
386
|
+
*,
|
|
387
|
+
sample_rate: float,
|
|
388
|
+
nyquist_factor: float = 2.0,
|
|
389
|
+
) -> list[QualityWarning]:
|
|
390
|
+
"""Detect undersampling (Nyquist violation).
|
|
391
|
+
|
|
392
|
+
: Detect undersampling (Nyquist violation warning).
|
|
393
|
+
|
|
394
|
+
Args:
|
|
395
|
+
signal: Input signal array
|
|
396
|
+
sample_rate: Sample rate in Hz
|
|
397
|
+
nyquist_factor: Required factor above Nyquist (default: 2.0)
|
|
398
|
+
|
|
399
|
+
Returns:
|
|
400
|
+
List of undersampling warnings
|
|
401
|
+
|
|
402
|
+
Example:
|
|
403
|
+
>>> warnings = check_undersampling(signal, sample_rate=1e9)
|
|
404
|
+
|
|
405
|
+
References:
|
|
406
|
+
EDGE-001: Detect undersampling
|
|
407
|
+
Nyquist-Shannon sampling theorem
|
|
408
|
+
"""
|
|
409
|
+
warnings: list[QualityWarning] = []
|
|
410
|
+
|
|
411
|
+
# Estimate highest frequency component using FFT
|
|
412
|
+
fft = np.fft.rfft(signal)
|
|
413
|
+
freqs = np.fft.rfftfreq(len(signal), d=1 / sample_rate)
|
|
414
|
+
power = np.abs(fft) ** 2
|
|
415
|
+
|
|
416
|
+
# Find frequency where power drops to 1% of peak
|
|
417
|
+
peak_power: float = float(np.max(power))
|
|
418
|
+
threshold_power = peak_power * 0.01
|
|
419
|
+
|
|
420
|
+
# Find highest significant frequency
|
|
421
|
+
significant_freqs = freqs[power > threshold_power]
|
|
422
|
+
if len(significant_freqs) > 0:
|
|
423
|
+
max_freq = float(np.max(significant_freqs))
|
|
424
|
+
nyquist_freq = sample_rate / 2.0
|
|
425
|
+
required_nyquist = max_freq * nyquist_factor
|
|
426
|
+
|
|
427
|
+
if required_nyquist > nyquist_freq:
|
|
428
|
+
warnings.append(
|
|
429
|
+
QualityWarning(
|
|
430
|
+
severity="error",
|
|
431
|
+
category="undersampling",
|
|
432
|
+
message=(
|
|
433
|
+
f"Undersampling detected: signal contains "
|
|
434
|
+
f"{max_freq / 1e6:.1f} MHz, but Nyquist frequency is "
|
|
435
|
+
f"{nyquist_freq / 1e6:.1f} MHz"
|
|
436
|
+
),
|
|
437
|
+
value=max_freq,
|
|
438
|
+
threshold=nyquist_freq / nyquist_factor,
|
|
439
|
+
suggestion=(
|
|
440
|
+
f"Increase sample rate to at least "
|
|
441
|
+
f"{required_nyquist * 2 / 1e6:.1f} MS/s or apply anti-aliasing filter"
|
|
442
|
+
),
|
|
443
|
+
)
|
|
444
|
+
)
|
|
445
|
+
|
|
446
|
+
return warnings
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
__all__ = [
|
|
450
|
+
"QualityWarning",
|
|
451
|
+
"SignalQualityAnalyzer",
|
|
452
|
+
"check_clipping",
|
|
453
|
+
"check_noise",
|
|
454
|
+
"check_saturation",
|
|
455
|
+
"check_undersampling",
|
|
456
|
+
]
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"""Report generation module for TraceKit.
|
|
2
|
+
|
|
3
|
+
This module provides professional report generation including PDF/HTML
|
|
4
|
+
output, templates, formatting, and multi-format export.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
# Comprehensive Analysis Report API (CAR-001 through CAR-007)
|
|
8
|
+
from oscura.reporting.analyze import (
|
|
9
|
+
UnsupportedFormatError,
|
|
10
|
+
analyze,
|
|
11
|
+
)
|
|
12
|
+
from oscura.reporting.auto_report import (
|
|
13
|
+
Report as AutoReport,
|
|
14
|
+
)
|
|
15
|
+
from oscura.reporting.auto_report import (
|
|
16
|
+
ReportMetadata,
|
|
17
|
+
)
|
|
18
|
+
from oscura.reporting.auto_report import (
|
|
19
|
+
generate_report as generate_auto_report,
|
|
20
|
+
)
|
|
21
|
+
from oscura.reporting.batch import (
|
|
22
|
+
BatchReportResult,
|
|
23
|
+
aggregate_batch_measurements,
|
|
24
|
+
batch_report,
|
|
25
|
+
generate_batch_report,
|
|
26
|
+
)
|
|
27
|
+
from oscura.reporting.chart_selection import (
|
|
28
|
+
ChartType,
|
|
29
|
+
auto_select_chart,
|
|
30
|
+
get_axis_scaling,
|
|
31
|
+
recommend_chart_with_reasoning,
|
|
32
|
+
)
|
|
33
|
+
from oscura.reporting.comparison import (
|
|
34
|
+
compare_waveforms,
|
|
35
|
+
generate_comparison_report,
|
|
36
|
+
)
|
|
37
|
+
from oscura.reporting.config import (
|
|
38
|
+
ANALYSIS_CAPABILITIES,
|
|
39
|
+
AnalysisConfig,
|
|
40
|
+
AnalysisDomain,
|
|
41
|
+
AnalysisError,
|
|
42
|
+
AnalysisResult,
|
|
43
|
+
DataOutputConfig,
|
|
44
|
+
DomainConfig,
|
|
45
|
+
InputType,
|
|
46
|
+
ProgressCallback,
|
|
47
|
+
ProgressInfo,
|
|
48
|
+
get_available_analyses,
|
|
49
|
+
)
|
|
50
|
+
from oscura.reporting.core import ( # core.py module
|
|
51
|
+
Report,
|
|
52
|
+
ReportConfig,
|
|
53
|
+
Section,
|
|
54
|
+
generate_report,
|
|
55
|
+
)
|
|
56
|
+
from oscura.reporting.core_formats import ( # core_formats/ directory
|
|
57
|
+
MultiFormatRenderer,
|
|
58
|
+
detect_format_from_extension,
|
|
59
|
+
render_all_formats,
|
|
60
|
+
)
|
|
61
|
+
from oscura.reporting.engine import (
|
|
62
|
+
AnalysisEngine,
|
|
63
|
+
)
|
|
64
|
+
from oscura.reporting.export import (
|
|
65
|
+
batch_export_formats,
|
|
66
|
+
export_multiple_reports,
|
|
67
|
+
export_report,
|
|
68
|
+
)
|
|
69
|
+
from oscura.reporting.formatting import (
|
|
70
|
+
NumberFormatter,
|
|
71
|
+
format_margin,
|
|
72
|
+
format_pass_fail,
|
|
73
|
+
format_value,
|
|
74
|
+
format_with_context,
|
|
75
|
+
format_with_locale,
|
|
76
|
+
format_with_units,
|
|
77
|
+
)
|
|
78
|
+
from oscura.reporting.html import (
|
|
79
|
+
generate_html_report,
|
|
80
|
+
save_html_report,
|
|
81
|
+
)
|
|
82
|
+
from oscura.reporting.index import (
|
|
83
|
+
IndexGenerator,
|
|
84
|
+
TemplateEngine,
|
|
85
|
+
)
|
|
86
|
+
from oscura.reporting.multichannel import (
|
|
87
|
+
generate_multichannel_report,
|
|
88
|
+
)
|
|
89
|
+
from oscura.reporting.output import OutputManager
|
|
90
|
+
from oscura.reporting.pdf import (
|
|
91
|
+
generate_pdf_report,
|
|
92
|
+
save_pdf_report,
|
|
93
|
+
)
|
|
94
|
+
from oscura.reporting.plots import (
|
|
95
|
+
PLOT_REGISTRY,
|
|
96
|
+
PlotGenerator,
|
|
97
|
+
register_plot,
|
|
98
|
+
)
|
|
99
|
+
from oscura.reporting.pptx_export import (
|
|
100
|
+
PPTXPresentation,
|
|
101
|
+
PPTXSlide,
|
|
102
|
+
export_pptx,
|
|
103
|
+
generate_presentation_from_report,
|
|
104
|
+
)
|
|
105
|
+
from oscura.reporting.sections import (
|
|
106
|
+
create_conclusions_section,
|
|
107
|
+
create_executive_summary_section,
|
|
108
|
+
create_measurement_results_section,
|
|
109
|
+
create_methodology_section,
|
|
110
|
+
create_plots_section,
|
|
111
|
+
create_standard_report_sections,
|
|
112
|
+
create_title_section,
|
|
113
|
+
create_violations_section,
|
|
114
|
+
)
|
|
115
|
+
from oscura.reporting.standards import (
|
|
116
|
+
ColorScheme,
|
|
117
|
+
ExecutiveSummary,
|
|
118
|
+
FormatStandards,
|
|
119
|
+
Severity,
|
|
120
|
+
VisualEmphasis,
|
|
121
|
+
format_executive_summary_html,
|
|
122
|
+
generate_executive_summary,
|
|
123
|
+
)
|
|
124
|
+
from oscura.reporting.summary_generator import (
|
|
125
|
+
Finding,
|
|
126
|
+
Summary,
|
|
127
|
+
generate_summary,
|
|
128
|
+
)
|
|
129
|
+
from oscura.reporting.tables import (
|
|
130
|
+
create_comparison_table,
|
|
131
|
+
create_measurement_table,
|
|
132
|
+
create_statistics_table,
|
|
133
|
+
format_batch_summary_table,
|
|
134
|
+
)
|
|
135
|
+
from oscura.reporting.template_system import (
|
|
136
|
+
ReportTemplate,
|
|
137
|
+
TemplateSection,
|
|
138
|
+
list_templates,
|
|
139
|
+
load_template,
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
__all__ = [
|
|
143
|
+
# Comprehensive Analysis Report API (CAR-001 through CAR-007)
|
|
144
|
+
"ANALYSIS_CAPABILITIES",
|
|
145
|
+
"PLOT_REGISTRY",
|
|
146
|
+
"AnalysisConfig",
|
|
147
|
+
"AnalysisDomain",
|
|
148
|
+
"AnalysisEngine",
|
|
149
|
+
"AnalysisError",
|
|
150
|
+
"AnalysisResult",
|
|
151
|
+
# Auto Report
|
|
152
|
+
"AutoReport",
|
|
153
|
+
# Batch (REPORT-009, RPT-003)
|
|
154
|
+
"BatchReportResult",
|
|
155
|
+
# Chart Selection (REPORT-028)
|
|
156
|
+
"ChartType",
|
|
157
|
+
# Standards (REPORT-001, REPORT-002, REPORT-004)
|
|
158
|
+
"ColorScheme",
|
|
159
|
+
"DataOutputConfig",
|
|
160
|
+
"DomainConfig",
|
|
161
|
+
"ExecutiveSummary",
|
|
162
|
+
# Summary Generation
|
|
163
|
+
"Finding",
|
|
164
|
+
"FormatStandards",
|
|
165
|
+
"IndexGenerator",
|
|
166
|
+
"InputType",
|
|
167
|
+
# Multi-format (REPORT-010)
|
|
168
|
+
"MultiFormatRenderer",
|
|
169
|
+
# Formatting (REPORT-026)
|
|
170
|
+
"NumberFormatter",
|
|
171
|
+
"OutputManager",
|
|
172
|
+
# PPTX Export (REPORT-023)
|
|
173
|
+
"PPTXPresentation",
|
|
174
|
+
"PPTXSlide",
|
|
175
|
+
"PlotGenerator",
|
|
176
|
+
"ProgressCallback",
|
|
177
|
+
"ProgressInfo",
|
|
178
|
+
# Core
|
|
179
|
+
"Report",
|
|
180
|
+
"ReportConfig",
|
|
181
|
+
"ReportMetadata",
|
|
182
|
+
# Templates (RPT-002)
|
|
183
|
+
"ReportTemplate",
|
|
184
|
+
"Section",
|
|
185
|
+
"Severity",
|
|
186
|
+
"Summary",
|
|
187
|
+
"TemplateEngine",
|
|
188
|
+
"TemplateSection",
|
|
189
|
+
"UnsupportedFormatError",
|
|
190
|
+
"VisualEmphasis",
|
|
191
|
+
"aggregate_batch_measurements",
|
|
192
|
+
"analyze",
|
|
193
|
+
"auto_select_chart",
|
|
194
|
+
# Export
|
|
195
|
+
"batch_export_formats",
|
|
196
|
+
"batch_report",
|
|
197
|
+
# Comparison
|
|
198
|
+
"compare_waveforms",
|
|
199
|
+
# Tables
|
|
200
|
+
"create_comparison_table",
|
|
201
|
+
# Sections
|
|
202
|
+
"create_conclusions_section",
|
|
203
|
+
"create_executive_summary_section",
|
|
204
|
+
"create_measurement_results_section",
|
|
205
|
+
"create_measurement_table",
|
|
206
|
+
"create_methodology_section",
|
|
207
|
+
"create_plots_section",
|
|
208
|
+
"create_standard_report_sections",
|
|
209
|
+
"create_statistics_table",
|
|
210
|
+
"create_title_section",
|
|
211
|
+
"create_violations_section",
|
|
212
|
+
# Multi-format (REPORT-010)
|
|
213
|
+
"detect_format_from_extension",
|
|
214
|
+
"export_multiple_reports",
|
|
215
|
+
"export_pptx",
|
|
216
|
+
"export_report",
|
|
217
|
+
"format_batch_summary_table",
|
|
218
|
+
"format_executive_summary_html",
|
|
219
|
+
"format_margin",
|
|
220
|
+
"format_pass_fail",
|
|
221
|
+
"format_value",
|
|
222
|
+
"format_with_context",
|
|
223
|
+
"format_with_locale",
|
|
224
|
+
"format_with_units",
|
|
225
|
+
"generate_auto_report",
|
|
226
|
+
"generate_batch_report",
|
|
227
|
+
"generate_comparison_report",
|
|
228
|
+
"generate_executive_summary",
|
|
229
|
+
# HTML Generation
|
|
230
|
+
"generate_html_report",
|
|
231
|
+
# Multi-Channel
|
|
232
|
+
"generate_multichannel_report",
|
|
233
|
+
# PDF Generation
|
|
234
|
+
"generate_pdf_report",
|
|
235
|
+
"generate_presentation_from_report",
|
|
236
|
+
"generate_report",
|
|
237
|
+
"generate_summary",
|
|
238
|
+
"get_available_analyses",
|
|
239
|
+
"get_axis_scaling",
|
|
240
|
+
"list_templates",
|
|
241
|
+
"load_template",
|
|
242
|
+
"recommend_chart_with_reasoning",
|
|
243
|
+
"register_plot",
|
|
244
|
+
# Multi-format (REPORT-010)
|
|
245
|
+
"render_all_formats",
|
|
246
|
+
"save_html_report",
|
|
247
|
+
"save_pdf_report",
|
|
248
|
+
]
|