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.
Files changed (465) hide show
  1. oscura/__init__.py +813 -8
  2. oscura/__main__.py +392 -0
  3. oscura/analyzers/__init__.py +37 -0
  4. oscura/analyzers/digital/__init__.py +177 -0
  5. oscura/analyzers/digital/bus.py +691 -0
  6. oscura/analyzers/digital/clock.py +805 -0
  7. oscura/analyzers/digital/correlation.py +720 -0
  8. oscura/analyzers/digital/edges.py +632 -0
  9. oscura/analyzers/digital/extraction.py +413 -0
  10. oscura/analyzers/digital/quality.py +878 -0
  11. oscura/analyzers/digital/signal_quality.py +877 -0
  12. oscura/analyzers/digital/thresholds.py +708 -0
  13. oscura/analyzers/digital/timing.py +1104 -0
  14. oscura/analyzers/eye/__init__.py +46 -0
  15. oscura/analyzers/eye/diagram.py +434 -0
  16. oscura/analyzers/eye/metrics.py +555 -0
  17. oscura/analyzers/jitter/__init__.py +83 -0
  18. oscura/analyzers/jitter/ber.py +333 -0
  19. oscura/analyzers/jitter/decomposition.py +759 -0
  20. oscura/analyzers/jitter/measurements.py +413 -0
  21. oscura/analyzers/jitter/spectrum.py +220 -0
  22. oscura/analyzers/measurements.py +40 -0
  23. oscura/analyzers/packet/__init__.py +171 -0
  24. oscura/analyzers/packet/daq.py +1077 -0
  25. oscura/analyzers/packet/metrics.py +437 -0
  26. oscura/analyzers/packet/parser.py +327 -0
  27. oscura/analyzers/packet/payload.py +2156 -0
  28. oscura/analyzers/packet/payload_analysis.py +1312 -0
  29. oscura/analyzers/packet/payload_extraction.py +236 -0
  30. oscura/analyzers/packet/payload_patterns.py +670 -0
  31. oscura/analyzers/packet/stream.py +359 -0
  32. oscura/analyzers/patterns/__init__.py +266 -0
  33. oscura/analyzers/patterns/clustering.py +1036 -0
  34. oscura/analyzers/patterns/discovery.py +539 -0
  35. oscura/analyzers/patterns/learning.py +797 -0
  36. oscura/analyzers/patterns/matching.py +1091 -0
  37. oscura/analyzers/patterns/periodic.py +650 -0
  38. oscura/analyzers/patterns/sequences.py +767 -0
  39. oscura/analyzers/power/__init__.py +116 -0
  40. oscura/analyzers/power/ac_power.py +391 -0
  41. oscura/analyzers/power/basic.py +383 -0
  42. oscura/analyzers/power/conduction.py +314 -0
  43. oscura/analyzers/power/efficiency.py +297 -0
  44. oscura/analyzers/power/ripple.py +356 -0
  45. oscura/analyzers/power/soa.py +372 -0
  46. oscura/analyzers/power/switching.py +479 -0
  47. oscura/analyzers/protocol/__init__.py +150 -0
  48. oscura/analyzers/protocols/__init__.py +150 -0
  49. oscura/analyzers/protocols/base.py +500 -0
  50. oscura/analyzers/protocols/can.py +620 -0
  51. oscura/analyzers/protocols/can_fd.py +448 -0
  52. oscura/analyzers/protocols/flexray.py +405 -0
  53. oscura/analyzers/protocols/hdlc.py +399 -0
  54. oscura/analyzers/protocols/i2c.py +368 -0
  55. oscura/analyzers/protocols/i2s.py +296 -0
  56. oscura/analyzers/protocols/jtag.py +393 -0
  57. oscura/analyzers/protocols/lin.py +445 -0
  58. oscura/analyzers/protocols/manchester.py +333 -0
  59. oscura/analyzers/protocols/onewire.py +501 -0
  60. oscura/analyzers/protocols/spi.py +334 -0
  61. oscura/analyzers/protocols/swd.py +325 -0
  62. oscura/analyzers/protocols/uart.py +393 -0
  63. oscura/analyzers/protocols/usb.py +495 -0
  64. oscura/analyzers/signal_integrity/__init__.py +63 -0
  65. oscura/analyzers/signal_integrity/embedding.py +294 -0
  66. oscura/analyzers/signal_integrity/equalization.py +370 -0
  67. oscura/analyzers/signal_integrity/sparams.py +484 -0
  68. oscura/analyzers/spectral/__init__.py +53 -0
  69. oscura/analyzers/spectral/chunked.py +273 -0
  70. oscura/analyzers/spectral/chunked_fft.py +571 -0
  71. oscura/analyzers/spectral/chunked_wavelet.py +391 -0
  72. oscura/analyzers/spectral/fft.py +92 -0
  73. oscura/analyzers/statistical/__init__.py +250 -0
  74. oscura/analyzers/statistical/checksum.py +923 -0
  75. oscura/analyzers/statistical/chunked_corr.py +228 -0
  76. oscura/analyzers/statistical/classification.py +778 -0
  77. oscura/analyzers/statistical/entropy.py +1113 -0
  78. oscura/analyzers/statistical/ngrams.py +614 -0
  79. oscura/analyzers/statistics/__init__.py +119 -0
  80. oscura/analyzers/statistics/advanced.py +885 -0
  81. oscura/analyzers/statistics/basic.py +263 -0
  82. oscura/analyzers/statistics/correlation.py +630 -0
  83. oscura/analyzers/statistics/distribution.py +298 -0
  84. oscura/analyzers/statistics/outliers.py +463 -0
  85. oscura/analyzers/statistics/streaming.py +93 -0
  86. oscura/analyzers/statistics/trend.py +520 -0
  87. oscura/analyzers/validation.py +598 -0
  88. oscura/analyzers/waveform/__init__.py +36 -0
  89. oscura/analyzers/waveform/measurements.py +943 -0
  90. oscura/analyzers/waveform/measurements_with_uncertainty.py +371 -0
  91. oscura/analyzers/waveform/spectral.py +1689 -0
  92. oscura/analyzers/waveform/wavelets.py +298 -0
  93. oscura/api/__init__.py +62 -0
  94. oscura/api/dsl.py +538 -0
  95. oscura/api/fluent.py +571 -0
  96. oscura/api/operators.py +498 -0
  97. oscura/api/optimization.py +392 -0
  98. oscura/api/profiling.py +396 -0
  99. oscura/automotive/__init__.py +73 -0
  100. oscura/automotive/can/__init__.py +52 -0
  101. oscura/automotive/can/analysis.py +356 -0
  102. oscura/automotive/can/checksum.py +250 -0
  103. oscura/automotive/can/correlation.py +212 -0
  104. oscura/automotive/can/discovery.py +355 -0
  105. oscura/automotive/can/message_wrapper.py +375 -0
  106. oscura/automotive/can/models.py +385 -0
  107. oscura/automotive/can/patterns.py +381 -0
  108. oscura/automotive/can/session.py +452 -0
  109. oscura/automotive/can/state_machine.py +300 -0
  110. oscura/automotive/can/stimulus_response.py +461 -0
  111. oscura/automotive/dbc/__init__.py +15 -0
  112. oscura/automotive/dbc/generator.py +156 -0
  113. oscura/automotive/dbc/parser.py +146 -0
  114. oscura/automotive/dtc/__init__.py +30 -0
  115. oscura/automotive/dtc/database.py +3036 -0
  116. oscura/automotive/j1939/__init__.py +14 -0
  117. oscura/automotive/j1939/decoder.py +745 -0
  118. oscura/automotive/loaders/__init__.py +35 -0
  119. oscura/automotive/loaders/asc.py +98 -0
  120. oscura/automotive/loaders/blf.py +77 -0
  121. oscura/automotive/loaders/csv_can.py +136 -0
  122. oscura/automotive/loaders/dispatcher.py +136 -0
  123. oscura/automotive/loaders/mdf.py +331 -0
  124. oscura/automotive/loaders/pcap.py +132 -0
  125. oscura/automotive/obd/__init__.py +14 -0
  126. oscura/automotive/obd/decoder.py +707 -0
  127. oscura/automotive/uds/__init__.py +48 -0
  128. oscura/automotive/uds/decoder.py +265 -0
  129. oscura/automotive/uds/models.py +64 -0
  130. oscura/automotive/visualization.py +369 -0
  131. oscura/batch/__init__.py +55 -0
  132. oscura/batch/advanced.py +627 -0
  133. oscura/batch/aggregate.py +300 -0
  134. oscura/batch/analyze.py +139 -0
  135. oscura/batch/logging.py +487 -0
  136. oscura/batch/metrics.py +556 -0
  137. oscura/builders/__init__.py +41 -0
  138. oscura/builders/signal_builder.py +1131 -0
  139. oscura/cli/__init__.py +14 -0
  140. oscura/cli/batch.py +339 -0
  141. oscura/cli/characterize.py +273 -0
  142. oscura/cli/compare.py +775 -0
  143. oscura/cli/decode.py +551 -0
  144. oscura/cli/main.py +247 -0
  145. oscura/cli/shell.py +350 -0
  146. oscura/comparison/__init__.py +66 -0
  147. oscura/comparison/compare.py +397 -0
  148. oscura/comparison/golden.py +487 -0
  149. oscura/comparison/limits.py +391 -0
  150. oscura/comparison/mask.py +434 -0
  151. oscura/comparison/trace_diff.py +30 -0
  152. oscura/comparison/visualization.py +481 -0
  153. oscura/compliance/__init__.py +70 -0
  154. oscura/compliance/advanced.py +756 -0
  155. oscura/compliance/masks.py +363 -0
  156. oscura/compliance/reporting.py +483 -0
  157. oscura/compliance/testing.py +298 -0
  158. oscura/component/__init__.py +38 -0
  159. oscura/component/impedance.py +365 -0
  160. oscura/component/reactive.py +598 -0
  161. oscura/component/transmission_line.py +312 -0
  162. oscura/config/__init__.py +191 -0
  163. oscura/config/defaults.py +254 -0
  164. oscura/config/loader.py +348 -0
  165. oscura/config/memory.py +271 -0
  166. oscura/config/migration.py +458 -0
  167. oscura/config/pipeline.py +1077 -0
  168. oscura/config/preferences.py +530 -0
  169. oscura/config/protocol.py +875 -0
  170. oscura/config/schema.py +713 -0
  171. oscura/config/settings.py +420 -0
  172. oscura/config/thresholds.py +599 -0
  173. oscura/convenience.py +457 -0
  174. oscura/core/__init__.py +299 -0
  175. oscura/core/audit.py +457 -0
  176. oscura/core/backend_selector.py +405 -0
  177. oscura/core/cache.py +590 -0
  178. oscura/core/cancellation.py +439 -0
  179. oscura/core/confidence.py +225 -0
  180. oscura/core/config.py +506 -0
  181. oscura/core/correlation.py +216 -0
  182. oscura/core/cross_domain.py +422 -0
  183. oscura/core/debug.py +301 -0
  184. oscura/core/edge_cases.py +541 -0
  185. oscura/core/exceptions.py +535 -0
  186. oscura/core/gpu_backend.py +523 -0
  187. oscura/core/lazy.py +832 -0
  188. oscura/core/log_query.py +540 -0
  189. oscura/core/logging.py +931 -0
  190. oscura/core/logging_advanced.py +952 -0
  191. oscura/core/memoize.py +171 -0
  192. oscura/core/memory_check.py +274 -0
  193. oscura/core/memory_guard.py +290 -0
  194. oscura/core/memory_limits.py +336 -0
  195. oscura/core/memory_monitor.py +453 -0
  196. oscura/core/memory_progress.py +465 -0
  197. oscura/core/memory_warnings.py +315 -0
  198. oscura/core/numba_backend.py +362 -0
  199. oscura/core/performance.py +352 -0
  200. oscura/core/progress.py +524 -0
  201. oscura/core/provenance.py +358 -0
  202. oscura/core/results.py +331 -0
  203. oscura/core/types.py +504 -0
  204. oscura/core/uncertainty.py +383 -0
  205. oscura/discovery/__init__.py +52 -0
  206. oscura/discovery/anomaly_detector.py +672 -0
  207. oscura/discovery/auto_decoder.py +415 -0
  208. oscura/discovery/comparison.py +497 -0
  209. oscura/discovery/quality_validator.py +528 -0
  210. oscura/discovery/signal_detector.py +769 -0
  211. oscura/dsl/__init__.py +73 -0
  212. oscura/dsl/commands.py +246 -0
  213. oscura/dsl/interpreter.py +455 -0
  214. oscura/dsl/parser.py +689 -0
  215. oscura/dsl/repl.py +172 -0
  216. oscura/exceptions.py +59 -0
  217. oscura/exploratory/__init__.py +111 -0
  218. oscura/exploratory/error_recovery.py +642 -0
  219. oscura/exploratory/fuzzy.py +513 -0
  220. oscura/exploratory/fuzzy_advanced.py +786 -0
  221. oscura/exploratory/legacy.py +831 -0
  222. oscura/exploratory/parse.py +358 -0
  223. oscura/exploratory/recovery.py +275 -0
  224. oscura/exploratory/sync.py +382 -0
  225. oscura/exploratory/unknown.py +707 -0
  226. oscura/export/__init__.py +25 -0
  227. oscura/export/wireshark/README.md +265 -0
  228. oscura/export/wireshark/__init__.py +47 -0
  229. oscura/export/wireshark/generator.py +312 -0
  230. oscura/export/wireshark/lua_builder.py +159 -0
  231. oscura/export/wireshark/templates/dissector.lua.j2 +92 -0
  232. oscura/export/wireshark/type_mapping.py +165 -0
  233. oscura/export/wireshark/validator.py +105 -0
  234. oscura/exporters/__init__.py +94 -0
  235. oscura/exporters/csv.py +303 -0
  236. oscura/exporters/exporters.py +44 -0
  237. oscura/exporters/hdf5.py +219 -0
  238. oscura/exporters/html_export.py +701 -0
  239. oscura/exporters/json_export.py +291 -0
  240. oscura/exporters/markdown_export.py +367 -0
  241. oscura/exporters/matlab_export.py +354 -0
  242. oscura/exporters/npz_export.py +219 -0
  243. oscura/exporters/spice_export.py +210 -0
  244. oscura/extensibility/__init__.py +131 -0
  245. oscura/extensibility/docs.py +752 -0
  246. oscura/extensibility/extensions.py +1125 -0
  247. oscura/extensibility/logging.py +259 -0
  248. oscura/extensibility/measurements.py +485 -0
  249. oscura/extensibility/plugins.py +414 -0
  250. oscura/extensibility/registry.py +346 -0
  251. oscura/extensibility/templates.py +913 -0
  252. oscura/extensibility/validation.py +651 -0
  253. oscura/filtering/__init__.py +89 -0
  254. oscura/filtering/base.py +563 -0
  255. oscura/filtering/convenience.py +564 -0
  256. oscura/filtering/design.py +725 -0
  257. oscura/filtering/filters.py +32 -0
  258. oscura/filtering/introspection.py +605 -0
  259. oscura/guidance/__init__.py +24 -0
  260. oscura/guidance/recommender.py +429 -0
  261. oscura/guidance/wizard.py +518 -0
  262. oscura/inference/__init__.py +251 -0
  263. oscura/inference/active_learning/README.md +153 -0
  264. oscura/inference/active_learning/__init__.py +38 -0
  265. oscura/inference/active_learning/lstar.py +257 -0
  266. oscura/inference/active_learning/observation_table.py +230 -0
  267. oscura/inference/active_learning/oracle.py +78 -0
  268. oscura/inference/active_learning/teachers/__init__.py +15 -0
  269. oscura/inference/active_learning/teachers/simulator.py +192 -0
  270. oscura/inference/adaptive_tuning.py +453 -0
  271. oscura/inference/alignment.py +653 -0
  272. oscura/inference/bayesian.py +943 -0
  273. oscura/inference/binary.py +1016 -0
  274. oscura/inference/crc_reverse.py +711 -0
  275. oscura/inference/logic.py +288 -0
  276. oscura/inference/message_format.py +1305 -0
  277. oscura/inference/protocol.py +417 -0
  278. oscura/inference/protocol_dsl.py +1084 -0
  279. oscura/inference/protocol_library.py +1230 -0
  280. oscura/inference/sequences.py +809 -0
  281. oscura/inference/signal_intelligence.py +1509 -0
  282. oscura/inference/spectral.py +215 -0
  283. oscura/inference/state_machine.py +634 -0
  284. oscura/inference/stream.py +918 -0
  285. oscura/integrations/__init__.py +59 -0
  286. oscura/integrations/llm.py +1827 -0
  287. oscura/jupyter/__init__.py +32 -0
  288. oscura/jupyter/display.py +268 -0
  289. oscura/jupyter/magic.py +334 -0
  290. oscura/loaders/__init__.py +526 -0
  291. oscura/loaders/binary.py +69 -0
  292. oscura/loaders/configurable.py +1255 -0
  293. oscura/loaders/csv.py +26 -0
  294. oscura/loaders/csv_loader.py +473 -0
  295. oscura/loaders/hdf5.py +9 -0
  296. oscura/loaders/hdf5_loader.py +510 -0
  297. oscura/loaders/lazy.py +370 -0
  298. oscura/loaders/mmap_loader.py +583 -0
  299. oscura/loaders/numpy_loader.py +436 -0
  300. oscura/loaders/pcap.py +432 -0
  301. oscura/loaders/preprocessing.py +368 -0
  302. oscura/loaders/rigol.py +287 -0
  303. oscura/loaders/sigrok.py +321 -0
  304. oscura/loaders/tdms.py +367 -0
  305. oscura/loaders/tektronix.py +711 -0
  306. oscura/loaders/validation.py +584 -0
  307. oscura/loaders/vcd.py +464 -0
  308. oscura/loaders/wav.py +233 -0
  309. oscura/math/__init__.py +45 -0
  310. oscura/math/arithmetic.py +824 -0
  311. oscura/math/interpolation.py +413 -0
  312. oscura/onboarding/__init__.py +39 -0
  313. oscura/onboarding/help.py +498 -0
  314. oscura/onboarding/tutorials.py +405 -0
  315. oscura/onboarding/wizard.py +466 -0
  316. oscura/optimization/__init__.py +19 -0
  317. oscura/optimization/parallel.py +440 -0
  318. oscura/optimization/search.py +532 -0
  319. oscura/pipeline/__init__.py +43 -0
  320. oscura/pipeline/base.py +338 -0
  321. oscura/pipeline/composition.py +242 -0
  322. oscura/pipeline/parallel.py +448 -0
  323. oscura/pipeline/pipeline.py +375 -0
  324. oscura/pipeline/reverse_engineering.py +1119 -0
  325. oscura/plugins/__init__.py +122 -0
  326. oscura/plugins/base.py +272 -0
  327. oscura/plugins/cli.py +497 -0
  328. oscura/plugins/discovery.py +411 -0
  329. oscura/plugins/isolation.py +418 -0
  330. oscura/plugins/lifecycle.py +959 -0
  331. oscura/plugins/manager.py +493 -0
  332. oscura/plugins/registry.py +421 -0
  333. oscura/plugins/versioning.py +372 -0
  334. oscura/py.typed +0 -0
  335. oscura/quality/__init__.py +65 -0
  336. oscura/quality/ensemble.py +740 -0
  337. oscura/quality/explainer.py +338 -0
  338. oscura/quality/scoring.py +616 -0
  339. oscura/quality/warnings.py +456 -0
  340. oscura/reporting/__init__.py +248 -0
  341. oscura/reporting/advanced.py +1234 -0
  342. oscura/reporting/analyze.py +448 -0
  343. oscura/reporting/argument_preparer.py +596 -0
  344. oscura/reporting/auto_report.py +507 -0
  345. oscura/reporting/batch.py +615 -0
  346. oscura/reporting/chart_selection.py +223 -0
  347. oscura/reporting/comparison.py +330 -0
  348. oscura/reporting/config.py +615 -0
  349. oscura/reporting/content/__init__.py +39 -0
  350. oscura/reporting/content/executive.py +127 -0
  351. oscura/reporting/content/filtering.py +191 -0
  352. oscura/reporting/content/minimal.py +257 -0
  353. oscura/reporting/content/verbosity.py +162 -0
  354. oscura/reporting/core.py +508 -0
  355. oscura/reporting/core_formats/__init__.py +17 -0
  356. oscura/reporting/core_formats/multi_format.py +210 -0
  357. oscura/reporting/engine.py +836 -0
  358. oscura/reporting/export.py +366 -0
  359. oscura/reporting/formatting/__init__.py +129 -0
  360. oscura/reporting/formatting/emphasis.py +81 -0
  361. oscura/reporting/formatting/numbers.py +403 -0
  362. oscura/reporting/formatting/standards.py +55 -0
  363. oscura/reporting/formatting.py +466 -0
  364. oscura/reporting/html.py +578 -0
  365. oscura/reporting/index.py +590 -0
  366. oscura/reporting/multichannel.py +296 -0
  367. oscura/reporting/output.py +379 -0
  368. oscura/reporting/pdf.py +373 -0
  369. oscura/reporting/plots.py +731 -0
  370. oscura/reporting/pptx_export.py +360 -0
  371. oscura/reporting/renderers/__init__.py +11 -0
  372. oscura/reporting/renderers/pdf.py +94 -0
  373. oscura/reporting/sections.py +471 -0
  374. oscura/reporting/standards.py +680 -0
  375. oscura/reporting/summary_generator.py +368 -0
  376. oscura/reporting/tables.py +397 -0
  377. oscura/reporting/template_system.py +724 -0
  378. oscura/reporting/templates/__init__.py +15 -0
  379. oscura/reporting/templates/definition.py +205 -0
  380. oscura/reporting/templates/index.html +649 -0
  381. oscura/reporting/templates/index.md +173 -0
  382. oscura/schemas/__init__.py +158 -0
  383. oscura/schemas/bus_configuration.json +322 -0
  384. oscura/schemas/device_mapping.json +182 -0
  385. oscura/schemas/packet_format.json +418 -0
  386. oscura/schemas/protocol_definition.json +363 -0
  387. oscura/search/__init__.py +16 -0
  388. oscura/search/anomaly.py +292 -0
  389. oscura/search/context.py +149 -0
  390. oscura/search/pattern.py +160 -0
  391. oscura/session/__init__.py +34 -0
  392. oscura/session/annotations.py +289 -0
  393. oscura/session/history.py +313 -0
  394. oscura/session/session.py +445 -0
  395. oscura/streaming/__init__.py +43 -0
  396. oscura/streaming/chunked.py +611 -0
  397. oscura/streaming/progressive.py +393 -0
  398. oscura/streaming/realtime.py +622 -0
  399. oscura/testing/__init__.py +54 -0
  400. oscura/testing/synthetic.py +808 -0
  401. oscura/triggering/__init__.py +68 -0
  402. oscura/triggering/base.py +229 -0
  403. oscura/triggering/edge.py +353 -0
  404. oscura/triggering/pattern.py +344 -0
  405. oscura/triggering/pulse.py +581 -0
  406. oscura/triggering/window.py +453 -0
  407. oscura/ui/__init__.py +48 -0
  408. oscura/ui/formatters.py +526 -0
  409. oscura/ui/progressive_display.py +340 -0
  410. oscura/utils/__init__.py +99 -0
  411. oscura/utils/autodetect.py +338 -0
  412. oscura/utils/buffer.py +389 -0
  413. oscura/utils/lazy.py +407 -0
  414. oscura/utils/lazy_imports.py +147 -0
  415. oscura/utils/memory.py +836 -0
  416. oscura/utils/memory_advanced.py +1326 -0
  417. oscura/utils/memory_extensions.py +465 -0
  418. oscura/utils/progressive.py +352 -0
  419. oscura/utils/windowing.py +362 -0
  420. oscura/visualization/__init__.py +321 -0
  421. oscura/visualization/accessibility.py +526 -0
  422. oscura/visualization/annotations.py +374 -0
  423. oscura/visualization/axis_scaling.py +305 -0
  424. oscura/visualization/colors.py +453 -0
  425. oscura/visualization/digital.py +337 -0
  426. oscura/visualization/eye.py +420 -0
  427. oscura/visualization/histogram.py +281 -0
  428. oscura/visualization/interactive.py +858 -0
  429. oscura/visualization/jitter.py +702 -0
  430. oscura/visualization/keyboard.py +394 -0
  431. oscura/visualization/layout.py +365 -0
  432. oscura/visualization/optimization.py +1028 -0
  433. oscura/visualization/palettes.py +446 -0
  434. oscura/visualization/plot.py +92 -0
  435. oscura/visualization/power.py +290 -0
  436. oscura/visualization/power_extended.py +626 -0
  437. oscura/visualization/presets.py +467 -0
  438. oscura/visualization/protocols.py +932 -0
  439. oscura/visualization/render.py +207 -0
  440. oscura/visualization/rendering.py +444 -0
  441. oscura/visualization/reverse_engineering.py +791 -0
  442. oscura/visualization/signal_integrity.py +808 -0
  443. oscura/visualization/specialized.py +553 -0
  444. oscura/visualization/spectral.py +811 -0
  445. oscura/visualization/styles.py +381 -0
  446. oscura/visualization/thumbnails.py +311 -0
  447. oscura/visualization/time_axis.py +351 -0
  448. oscura/visualization/waveform.py +367 -0
  449. oscura/workflow/__init__.py +13 -0
  450. oscura/workflow/dag.py +377 -0
  451. oscura/workflows/__init__.py +58 -0
  452. oscura/workflows/compliance.py +280 -0
  453. oscura/workflows/digital.py +272 -0
  454. oscura/workflows/multi_trace.py +502 -0
  455. oscura/workflows/power.py +178 -0
  456. oscura/workflows/protocol.py +492 -0
  457. oscura/workflows/reverse_engineering.py +639 -0
  458. oscura/workflows/signal_integrity.py +227 -0
  459. oscura-0.1.0.dist-info/METADATA +300 -0
  460. oscura-0.1.0.dist-info/RECORD +463 -0
  461. oscura-0.1.0.dist-info/entry_points.txt +2 -0
  462. {oscura-0.0.1.dist-info → oscura-0.1.0.dist-info}/licenses/LICENSE +1 -1
  463. oscura-0.0.1.dist-info/METADATA +0 -63
  464. oscura-0.0.1.dist-info/RECORD +0 -5
  465. {oscura-0.0.1.dist-info → oscura-0.1.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,383 @@
1
+ """Measurement uncertainty propagation and estimation.
2
+
3
+ This module provides data structures and utilities for tracking measurement
4
+ uncertainty through TraceKit analysis operations, following GUM (Guide to the
5
+ Expression of Uncertainty in Measurement) principles.
6
+
7
+ References:
8
+ JCGM 100:2008 - Guide to the Expression of Uncertainty in Measurement (GUM)
9
+ ISO/IEC 17025:2017 - General Requirements for Competence of Testing and Calibration Laboratories
10
+ NIST Technical Note 1297 - Guidelines for Evaluating and Expressing Uncertainty
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from dataclasses import dataclass
16
+ from typing import TYPE_CHECKING, Any
17
+
18
+ import numpy as np
19
+
20
+ if TYPE_CHECKING:
21
+ from numpy.typing import NDArray
22
+
23
+
24
+ @dataclass
25
+ class MeasurementWithUncertainty:
26
+ """Measurement value with uncertainty estimate.
27
+
28
+ Stores a measurement value along with its associated uncertainty,
29
+ following GUM (Guide to the Expression of Uncertainty in Measurement)
30
+ conventions.
31
+
32
+ Attributes:
33
+ value: The measured value (best estimate).
34
+ uncertainty: Standard uncertainty (1-sigma, coverage factor k=1).
35
+ unit: Unit of measurement (e.g., "V", "s", "Hz") (optional).
36
+ coverage_factor: Coverage factor for expanded uncertainty (default 1.0).
37
+ confidence_level: Confidence level for expanded uncertainty (default 68.27% for k=1).
38
+ n_samples: Number of samples used in measurement (optional).
39
+ degrees_of_freedom: Effective degrees of freedom (optional).
40
+
41
+ Properties:
42
+ expanded_uncertainty: Uncertainty * coverage_factor.
43
+ relative_uncertainty: uncertainty / |value| if value != 0.
44
+ lower_bound: value - expanded_uncertainty.
45
+ upper_bound: value + expanded_uncertainty.
46
+
47
+ Example:
48
+ >>> result = MeasurementWithUncertainty(value=1.234, uncertainty=0.005, unit="V")
49
+ >>> print(f"{result.value:.3f} ± {result.uncertainty:.3f} {result.unit}")
50
+ 1.234 ± 0.005 V
51
+
52
+ Example with expanded uncertainty (k=2, 95.45% confidence):
53
+ >>> result = MeasurementWithUncertainty(
54
+ ... value=10.0e6,
55
+ ... uncertainty=1000.0,
56
+ ... unit="Hz",
57
+ ... coverage_factor=2.0,
58
+ ... confidence_level=0.9545
59
+ ... )
60
+ >>> print(f"{result.value/1e6:.3f} ± {result.expanded_uncertainty/1e6:.3f} MHz (95.45%)")
61
+ 10.000 ± 0.002 MHz (95.45%)
62
+
63
+ References:
64
+ JCGM 100:2008 Section 2.3.5 (standard uncertainty)
65
+ JCGM 100:2008 Section 2.3.6 (expanded uncertainty)
66
+ """
67
+
68
+ value: float
69
+ uncertainty: float
70
+ unit: str | None = None
71
+ coverage_factor: float = 1.0
72
+ confidence_level: float = 0.6827 # 68.27% for k=1 (Gaussian)
73
+ n_samples: int | None = None
74
+ degrees_of_freedom: float | None = None
75
+
76
+ def __post_init__(self) -> None:
77
+ """Validate measurement result after initialization."""
78
+ if not np.isfinite(self.value):
79
+ # Allow NaN/Inf but issue warning
80
+ pass
81
+ if self.uncertainty < 0:
82
+ raise ValueError(f"uncertainty must be non-negative, got {self.uncertainty}")
83
+ if self.coverage_factor <= 0:
84
+ raise ValueError(f"coverage_factor must be positive, got {self.coverage_factor}")
85
+ if not 0 < self.confidence_level <= 1.0:
86
+ raise ValueError(f"confidence_level must be in (0, 1], got {self.confidence_level}")
87
+
88
+ @property
89
+ def expanded_uncertainty(self) -> float:
90
+ """Expanded uncertainty (U = k * u).
91
+
92
+ Returns:
93
+ Standard uncertainty multiplied by coverage factor.
94
+
95
+ References:
96
+ JCGM 100:2008 Section 6.2.1
97
+ """
98
+ return self.coverage_factor * self.uncertainty
99
+
100
+ @property
101
+ def relative_uncertainty(self) -> float:
102
+ """Relative standard uncertainty (u_r = u / |value|).
103
+
104
+ Returns:
105
+ Relative uncertainty, or np.inf if value is zero.
106
+
107
+ References:
108
+ JCGM 100:2008 Section 5.1.6
109
+ """
110
+ if self.value == 0:
111
+ return np.inf
112
+ return abs(self.uncertainty / self.value)
113
+
114
+ @property
115
+ def lower_bound(self) -> float:
116
+ """Lower bound of uncertainty interval.
117
+
118
+ Returns:
119
+ value - expanded_uncertainty.
120
+ """
121
+ return self.value - self.expanded_uncertainty
122
+
123
+ @property
124
+ def upper_bound(self) -> float:
125
+ """Upper bound of uncertainty interval.
126
+
127
+ Returns:
128
+ value + expanded_uncertainty.
129
+ """
130
+ return self.value + self.expanded_uncertainty
131
+
132
+ def __str__(self) -> str:
133
+ """String representation of measurement with uncertainty."""
134
+ unit_str = f" {self.unit}" if self.unit else ""
135
+ if self.coverage_factor == 1.0:
136
+ return f"{self.value:.6g} ± {self.uncertainty:.6g}{unit_str}"
137
+ else:
138
+ return (
139
+ f"{self.value:.6g} ± {self.expanded_uncertainty:.6g}{unit_str} "
140
+ f"(k={self.coverage_factor:.2f}, {self.confidence_level * 100:.2f}%)"
141
+ )
142
+
143
+ def __repr__(self) -> str:
144
+ """Detailed representation."""
145
+ return (
146
+ f"MeasurementWithUncertainty(value={self.value:.6g}, "
147
+ f"uncertainty={self.uncertainty:.6g}, "
148
+ f"unit={self.unit!r})"
149
+ )
150
+
151
+
152
+ class UncertaintyEstimator:
153
+ """Utilities for estimating measurement uncertainty.
154
+
155
+ Provides methods for calculating Type A (statistical) and Type B
156
+ (systematic) uncertainties according to GUM principles.
157
+
158
+ References:
159
+ JCGM 100:2008 Section 4 (Evaluating Standard Uncertainty)
160
+ """
161
+
162
+ @staticmethod
163
+ def type_a_standard_deviation(data: NDArray[np.floating[Any]]) -> float:
164
+ """Type A uncertainty from sample standard deviation.
165
+
166
+ Args:
167
+ data: Array of repeated measurements.
168
+
169
+ Returns:
170
+ Standard deviation (Type A uncertainty component).
171
+
172
+ References:
173
+ JCGM 100:2008 Section 4.2 (Type A evaluation)
174
+ """
175
+ if len(data) < 2:
176
+ return np.nan
177
+ return float(np.std(data, ddof=1)) # Sample std (Bessel correction)
178
+
179
+ @staticmethod
180
+ def type_a_standard_error(data: NDArray[np.floating[Any]]) -> float:
181
+ """Type A uncertainty from standard error of the mean.
182
+
183
+ Args:
184
+ data: Array of repeated measurements.
185
+
186
+ Returns:
187
+ Standard error (sigma / sqrt(n)), Type A uncertainty of the mean.
188
+
189
+ References:
190
+ JCGM 100:2008 Section 4.2.3
191
+ """
192
+ if len(data) < 2:
193
+ return np.nan
194
+ return float(np.std(data, ddof=1) / np.sqrt(len(data)))
195
+
196
+ @staticmethod
197
+ def combined_uncertainty(
198
+ uncertainties: list[float], correlation_matrix: NDArray[np.float64] | None = None
199
+ ) -> float:
200
+ """Combine multiple uncertainty sources.
201
+
202
+ Combines uncorrelated or correlated uncertainty components using
203
+ the law of propagation of uncertainty.
204
+
205
+ Args:
206
+ uncertainties: List of standard uncertainties to combine.
207
+ correlation_matrix: Correlation matrix for correlated inputs (optional).
208
+ If None, assumes all inputs are uncorrelated.
209
+
210
+ Returns:
211
+ Combined standard uncertainty.
212
+
213
+ Example (uncorrelated):
214
+ >>> u1, u2, u3 = 0.01, 0.02, 0.005
215
+ >>> u_combined = UncertaintyEstimator.combined_uncertainty([u1, u2, u3])
216
+ >>> print(f"Combined: {u_combined:.4f}")
217
+ Combined: 0.0233
218
+
219
+ Example (correlated):
220
+ >>> import numpy as np
221
+ >>> u = [0.01, 0.02]
222
+ >>> R = np.array([[1.0, 0.5], [0.5, 1.0]]) # 50% correlation
223
+ >>> u_combined = UncertaintyEstimator.combined_uncertainty(u, R)
224
+
225
+ References:
226
+ JCGM 100:2008 Section 5.1.2 (uncorrelated)
227
+ JCGM 100:2008 Section 5.2.2 (correlated)
228
+ """
229
+ u_array = np.array(uncertainties, dtype=np.float64)
230
+
231
+ if correlation_matrix is None:
232
+ # Uncorrelated: u_c² = Σ u_i²
233
+ return float(np.sqrt(np.sum(u_array**2)))
234
+ else:
235
+ # Correlated: u_c² = u^T R u
236
+ u_combined_sq = u_array @ correlation_matrix @ u_array
237
+ return float(np.sqrt(u_combined_sq))
238
+
239
+ @staticmethod
240
+ def type_b_rectangular(half_width: float) -> float:
241
+ """Type B uncertainty from rectangular (uniform) distribution.
242
+
243
+ Used when only min/max bounds are known with equal probability.
244
+
245
+ Args:
246
+ half_width: Half-width of the interval (a).
247
+
248
+ Returns:
249
+ Standard uncertainty u = a / √3.
250
+
251
+ Example:
252
+ >>> # Scope resolution ±0.5 LSB
253
+ >>> lsb = 1.0e-3 # 1 mV per bit
254
+ >>> u = UncertaintyEstimator.type_b_rectangular(0.5 * lsb)
255
+ >>> print(f"Quantization uncertainty: {u*1e6:.3f} µV")
256
+ Quantization uncertainty: 288.675 µV
257
+
258
+ References:
259
+ JCGM 100:2008 Section 4.3.7 (rectangular distribution)
260
+ """
261
+ return float(half_width / np.sqrt(3))
262
+
263
+ @staticmethod
264
+ def type_b_triangular(half_width: float) -> float:
265
+ """Type B uncertainty from triangular distribution.
266
+
267
+ Used when values near the center are more likely than extremes.
268
+
269
+ Args:
270
+ half_width: Half-width of the interval (a).
271
+
272
+ Returns:
273
+ Standard uncertainty u = a / √6.
274
+
275
+ References:
276
+ JCGM 100:2008 Section 4.3.9 (triangular distribution)
277
+ """
278
+ return float(half_width / np.sqrt(6))
279
+
280
+ @staticmethod
281
+ def type_b_from_tolerance(tolerance: float, confidence: float = 0.95) -> float:
282
+ """Type B uncertainty from manufacturer tolerance specification.
283
+
284
+ Assumes Gaussian distribution unless otherwise specified.
285
+
286
+ Args:
287
+ tolerance: Tolerance limit (e.g., ±1% of reading).
288
+ confidence: Confidence level of the tolerance (default 95%).
289
+
290
+ Returns:
291
+ Standard uncertainty.
292
+
293
+ Example:
294
+ >>> # Scope vertical accuracy: ±2% of reading, 95% confidence
295
+ >>> reading = 1.0 # 1V
296
+ >>> tolerance = 0.02 * reading # ±0.02 V
297
+ >>> u = UncertaintyEstimator.type_b_from_tolerance(tolerance, 0.95)
298
+ >>> print(f"Uncertainty: {u:.4f} V")
299
+ Uncertainty: 0.0102 V
300
+
301
+ References:
302
+ JCGM 100:2008 Section 4.3.4
303
+ """
304
+ # For Gaussian, 95% confidence → k ≈ 1.96
305
+ # For 99% confidence → k ≈ 2.58
306
+ if confidence == 0.95:
307
+ k = 1.96
308
+ elif confidence == 0.99:
309
+ k = 2.58
310
+ elif confidence == 0.6827:
311
+ k = 1.0
312
+ else:
313
+ # General case: approximate using normal distribution
314
+ from scipy import stats
315
+
316
+ k = stats.norm.ppf((1 + confidence) / 2)
317
+
318
+ return float(tolerance / k)
319
+
320
+ @staticmethod
321
+ def time_base_uncertainty(sample_rate: float, timebase_accuracy_ppm: float = 50.0) -> float:
322
+ """Calculate time base uncertainty from oscilloscope specification.
323
+
324
+ Args:
325
+ sample_rate: Sample rate in Hz.
326
+ timebase_accuracy_ppm: Timebase accuracy in parts per million (typical: 10-50 ppm).
327
+
328
+ Returns:
329
+ Standard uncertainty in time per sample (seconds).
330
+
331
+ Example:
332
+ >>> # 1 GSa/s scope, 25 ppm timebase (typical for OCXO)
333
+ >>> u_t = UncertaintyEstimator.time_base_uncertainty(1e9, 25.0)
334
+ >>> print(f"Timebase uncertainty: {u_t*1e12:.2f} ps per sample")
335
+ Timebase uncertainty: 25.00 ps per sample
336
+
337
+ References:
338
+ IEEE 181-2011 Annex B (Measurement Uncertainty)
339
+ """
340
+ time_per_sample = 1.0 / sample_rate
341
+ # ppm = parts per million = 1e-6
342
+ relative_uncertainty = timebase_accuracy_ppm * 1e-6
343
+ return time_per_sample * relative_uncertainty
344
+
345
+ @staticmethod
346
+ def vertical_uncertainty(
347
+ reading: float,
348
+ vertical_accuracy_percent: float = 2.0,
349
+ offset_error_volts: float = 0.0,
350
+ ) -> float:
351
+ """Calculate vertical (voltage) uncertainty from oscilloscope specification.
352
+
353
+ Typical scope spec: ±(2% of reading + 0.1% of full scale + 1 mV)
354
+
355
+ Args:
356
+ reading: Measured voltage value.
357
+ vertical_accuracy_percent: Gain accuracy in percent (e.g., 2.0 for ±2%).
358
+ offset_error_volts: Fixed offset error in volts.
359
+
360
+ Returns:
361
+ Standard uncertainty in volts.
362
+
363
+ Example:
364
+ >>> # Tektronix TDS3000 series: ±3% of reading
365
+ >>> reading = 1.5 # 1.5 V
366
+ >>> u_v = UncertaintyEstimator.vertical_uncertainty(reading, 3.0, 0.001)
367
+ >>> print(f"Voltage uncertainty: {u_v*1000:.2f} mV")
368
+ Voltage uncertainty: 45.01 mV
369
+
370
+ References:
371
+ IEEE 1057-2017 Section 4.4 (Amplitude Accuracy)
372
+ """
373
+ # Gain error
374
+ u_gain = abs(reading) * (vertical_accuracy_percent / 100.0)
375
+
376
+ # Offset error
377
+ u_offset = offset_error_volts
378
+
379
+ # Combine (assume uncorrelated)
380
+ return float(np.sqrt(u_gain**2 + u_offset**2))
381
+
382
+
383
+ __all__ = ["MeasurementWithUncertainty", "UncertaintyEstimator"]
@@ -0,0 +1,52 @@
1
+ """Auto-discovery and signal characterization.
2
+
3
+ This module provides intelligent auto-discovery features for non-expert
4
+ users, including signal characterization, anomaly detection, quality
5
+ assessment, and automatic protocol decoding.
6
+
7
+
8
+ Example:
9
+ >>> import oscura as tk
10
+ >>> trace = tk.load("capture.wfm")
11
+ >>> result = tk.discovery.characterize_signal(trace)
12
+ >>> print(f"Signal type: {result.signal_type} (confidence: {result.confidence:.2f})")
13
+
14
+ References:
15
+ TraceKit Auto-Discovery Requirements
16
+ """
17
+
18
+ from oscura.discovery.anomaly_detector import (
19
+ Anomaly,
20
+ find_anomalies,
21
+ )
22
+ from oscura.discovery.auto_decoder import (
23
+ DecodeResult,
24
+ decode_protocol,
25
+ )
26
+ from oscura.discovery.comparison import (
27
+ Difference,
28
+ TraceDiff,
29
+ compare_traces,
30
+ )
31
+ from oscura.discovery.quality_validator import (
32
+ DataQuality,
33
+ assess_data_quality,
34
+ )
35
+ from oscura.discovery.signal_detector import (
36
+ SignalCharacterization,
37
+ characterize_signal,
38
+ )
39
+
40
+ __all__ = [
41
+ "Anomaly",
42
+ "DataQuality",
43
+ "DecodeResult",
44
+ "Difference",
45
+ "SignalCharacterization",
46
+ "TraceDiff",
47
+ "assess_data_quality",
48
+ "characterize_signal",
49
+ "compare_traces",
50
+ "decode_protocol",
51
+ "find_anomalies",
52
+ ]