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,415 @@
1
+ """Automatic protocol decoding without user configuration.
2
+
3
+ This module provides one-shot protocol decode that auto-detects parameters
4
+ (baud rate, polarity, bit order) and decodes common protocols.
5
+
6
+
7
+ Example:
8
+ >>> from oscura.discovery import decode_protocol
9
+ >>> result = decode_protocol(trace)
10
+ >>> print(f"Protocol: {result.protocol}")
11
+ >>> print(f"Decoded {len(result.data)} bytes")
12
+ >>> for byte_data in result.data[:10]:
13
+ ... print(f"0x{byte_data.value:02X} (confidence: {byte_data.confidence:.2f})")
14
+
15
+ References:
16
+ Protocol specifications: UART (EIA/TIA-232), SPI (Motorola), I2C (NXP)
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ from dataclasses import dataclass, field
22
+ from typing import TYPE_CHECKING, Any, Literal
23
+
24
+ import numpy as np
25
+
26
+ from oscura.core.types import DigitalTrace, WaveformTrace
27
+ from oscura.discovery.signal_detector import characterize_signal
28
+
29
+ if TYPE_CHECKING:
30
+ from numpy.typing import NDArray
31
+
32
+ ProtocolType = Literal["UART", "SPI", "I2C", "unknown"]
33
+
34
+
35
+ @dataclass
36
+ class DecodedByte:
37
+ """Single decoded byte with confidence.
38
+
39
+ Attributes:
40
+ value: Byte value (0-255).
41
+ offset: Byte offset in decoded stream.
42
+ confidence: Decode confidence (0.0-1.0).
43
+ has_error: Whether byte has detected errors.
44
+ error_type: Type of error if present.
45
+ error_description: Plain-language error description.
46
+
47
+ Example:
48
+ >>> byte_data = DecodedByte(value=0x48, offset=0, confidence=0.95)
49
+ >>> print(f"Byte: 0x{byte_data.value:02X}, char: {chr(byte_data.value)}")
50
+ """
51
+
52
+ value: int
53
+ offset: int
54
+ confidence: float
55
+ has_error: bool = False
56
+ error_type: str | None = None
57
+ error_description: str | None = None
58
+
59
+ def __post_init__(self) -> None:
60
+ """Validate byte data."""
61
+ if not 0 <= self.value <= 255:
62
+ raise ValueError(f"Byte value must be 0-255, got {self.value}")
63
+ if not 0.0 <= self.confidence <= 1.0:
64
+ raise ValueError(f"Confidence must be 0.0-1.0, got {self.confidence}")
65
+
66
+
67
+ @dataclass
68
+ class DecodeResult:
69
+ """Protocol decode result with auto-detected parameters.
70
+
71
+ Attributes:
72
+ protocol: Detected protocol name.
73
+ overall_confidence: Overall decode confidence (0.0-1.0).
74
+ detected_params: Auto-detected protocol parameters.
75
+ data: List of decoded bytes with per-byte confidence.
76
+ frame_count: Number of frames/packets decoded.
77
+ error_count: Number of errors detected.
78
+
79
+ Example:
80
+ >>> result = decode_protocol(trace)
81
+ >>> print(f"Protocol: {result.protocol}")
82
+ >>> print(f"Confidence: {result.overall_confidence:.2f}")
83
+ >>> print(f"Parameters: {result.detected_params}")
84
+ >>> print(f"Decoded {len(result.data)} bytes with {result.error_count} errors")
85
+ """
86
+
87
+ protocol: ProtocolType
88
+ overall_confidence: float
89
+ detected_params: dict[str, Any] = field(default_factory=dict)
90
+ data: list[DecodedByte] = field(default_factory=list)
91
+ frame_count: int = 0
92
+ error_count: int = 0
93
+
94
+
95
+ def decode_protocol(
96
+ trace: WaveformTrace | DigitalTrace,
97
+ *,
98
+ protocol_hint: ProtocolType | None = None,
99
+ params_hint: dict[str, Any] | None = None,
100
+ confidence_threshold: float = 0.7,
101
+ return_errors: bool = True,
102
+ ) -> DecodeResult:
103
+ """Automatically decode protocol without user configuration.
104
+
105
+ Auto-detects protocol type, parameters (baud rate, polarity, bit order),
106
+ and decodes data with per-byte confidence scores.
107
+
108
+ Supported protocols:
109
+ - UART: Auto-detects baud rate, parity, stop bits
110
+ - SPI: Auto-detects mode (CPOL/CPHA), bit order
111
+ - I2C: Auto-detects clock rate, addressing mode
112
+
113
+ Args:
114
+ trace: Input waveform or digital trace.
115
+ protocol_hint: Optional protocol hint to narrow detection.
116
+ params_hint: Optional parameter hints (e.g., approximate clock freq).
117
+ confidence_threshold: Minimum confidence for valid bytes.
118
+ return_errors: Whether to include error information.
119
+
120
+ Returns:
121
+ DecodeResult with protocol, parameters, and decoded data.
122
+
123
+ Raises:
124
+ ValueError: If trace is empty or invalid.
125
+
126
+ Example:
127
+ >>> # Automatic decode with no configuration
128
+ >>> result = decode_protocol(trace)
129
+ >>> if result.overall_confidence >= 0.8:
130
+ ... print(f"High confidence {result.protocol} decode")
131
+ ... for byte_data in result.data:
132
+ ... print(f"0x{byte_data.value:02X}")
133
+
134
+ >>> # Decode with hint to speed up detection
135
+ >>> result = decode_protocol(trace, protocol_hint='UART')
136
+ >>> print(f"Baud rate: {result.detected_params['baud_rate']}")
137
+
138
+ References:
139
+ DISC-010: One-Shot Protocol Decode
140
+ """
141
+ # Validate input
142
+ if len(trace) == 0:
143
+ raise ValueError("Cannot decode empty trace")
144
+
145
+ # Auto-detect protocol if no hint provided
146
+ if protocol_hint is None:
147
+ char_result = characterize_signal(trace)
148
+
149
+ # Map signal types to protocols
150
+ if char_result.signal_type == "uart":
151
+ protocol_hint = "UART"
152
+ elif char_result.signal_type == "spi":
153
+ protocol_hint = "SPI"
154
+ elif char_result.signal_type == "i2c":
155
+ protocol_hint = "I2C"
156
+ # Try UART as default for digital signals
157
+ elif char_result.signal_type == "digital":
158
+ protocol_hint = "UART"
159
+ else:
160
+ return DecodeResult(
161
+ protocol="unknown",
162
+ overall_confidence=0.0,
163
+ detected_params={},
164
+ data=[],
165
+ )
166
+
167
+ # Decode based on detected/hinted protocol
168
+ if protocol_hint == "UART":
169
+ return _decode_uart_auto(trace, params_hint, confidence_threshold, return_errors)
170
+ elif protocol_hint == "SPI":
171
+ return _decode_spi_auto(trace, params_hint, confidence_threshold, return_errors)
172
+ elif protocol_hint == "I2C":
173
+ return _decode_i2c_auto(trace, params_hint, confidence_threshold, return_errors)
174
+ else:
175
+ return DecodeResult(
176
+ protocol="unknown",
177
+ overall_confidence=0.0,
178
+ detected_params={},
179
+ data=[],
180
+ )
181
+
182
+
183
+ def _decode_uart_auto(
184
+ trace: WaveformTrace | DigitalTrace,
185
+ params_hint: dict[str, Any] | None,
186
+ confidence_threshold: float,
187
+ return_errors: bool,
188
+ ) -> DecodeResult:
189
+ """Auto-decode UART with parameter detection.
190
+
191
+ Args:
192
+ trace: Input trace.
193
+ params_hint: Optional parameter hints.
194
+ confidence_threshold: Minimum confidence threshold.
195
+ return_errors: Whether to include errors.
196
+
197
+ Returns:
198
+ DecodeResult for UART.
199
+ """
200
+ from oscura.analyzers.protocols.uart import UARTDecoder
201
+
202
+ # Get data array
203
+ if isinstance(trace, WaveformTrace):
204
+ data = trace.data
205
+ sample_rate = trace.metadata.sample_rate
206
+ else:
207
+ data = trace.data.astype(np.float64)
208
+ sample_rate = trace.metadata.sample_rate
209
+
210
+ # Auto-detect baud rate if not provided
211
+ if params_hint and "baud_rate" in params_hint:
212
+ baud_rate = params_hint["baud_rate"]
213
+ else:
214
+ baud_rate = _detect_baud_rate(data, sample_rate)
215
+
216
+ # Default UART parameters (8N1)
217
+ data_bits = params_hint.get("data_bits", 8) if params_hint else 8
218
+ parity = params_hint.get("parity", "none") if params_hint else "none"
219
+ stop_bits = params_hint.get("stop_bits", 1) if params_hint else 1
220
+
221
+ # Create decoder with detected parameters
222
+ decoder = UARTDecoder(
223
+ baudrate=baud_rate,
224
+ data_bits=data_bits,
225
+ parity=parity, # type: ignore[arg-type]
226
+ stop_bits=stop_bits,
227
+ )
228
+
229
+ # Decode
230
+ try:
231
+ packets = list(decoder.decode(trace))
232
+ except Exception:
233
+ # Decode failed
234
+ return DecodeResult(
235
+ protocol="UART",
236
+ overall_confidence=0.3,
237
+ detected_params={"baud_rate": baud_rate},
238
+ data=[],
239
+ )
240
+
241
+ # Convert to DecodedByte format
242
+ decoded_bytes: list[DecodedByte] = []
243
+ error_count = 0
244
+
245
+ for i, packet in enumerate(packets):
246
+ for byte_val in packet.data:
247
+ # Calculate confidence based on errors
248
+ has_error = len(packet.errors) > 0
249
+ if has_error:
250
+ confidence = 0.65
251
+ error_count += 1
252
+ else:
253
+ confidence = 0.95
254
+
255
+ decoded_bytes.append(
256
+ DecodedByte(
257
+ value=byte_val,
258
+ offset=i,
259
+ confidence=confidence,
260
+ has_error=has_error,
261
+ error_type=packet.errors[0] if packet.errors else None,
262
+ error_description=packet.errors[0] if packet.errors else None,
263
+ )
264
+ )
265
+
266
+ # Calculate overall confidence
267
+ if decoded_bytes:
268
+ avg_confidence = np.mean([b.confidence for b in decoded_bytes])
269
+ overall_confidence = float(round(float(avg_confidence), 2))
270
+ else:
271
+ overall_confidence = 0.0
272
+
273
+ return DecodeResult(
274
+ protocol="UART",
275
+ overall_confidence=overall_confidence,
276
+ detected_params={
277
+ "baud_rate": baud_rate,
278
+ "data_bits": data_bits,
279
+ "parity": parity,
280
+ "stop_bits": stop_bits,
281
+ },
282
+ data=decoded_bytes,
283
+ frame_count=len(packets),
284
+ error_count=error_count,
285
+ )
286
+
287
+
288
+ def _decode_spi_auto(
289
+ trace: WaveformTrace | DigitalTrace,
290
+ params_hint: dict[str, Any] | None,
291
+ confidence_threshold: float,
292
+ return_errors: bool,
293
+ ) -> DecodeResult:
294
+ """Auto-decode SPI with parameter detection.
295
+
296
+ Args:
297
+ trace: Input trace.
298
+ params_hint: Optional parameter hints.
299
+ confidence_threshold: Minimum confidence threshold.
300
+ return_errors: Whether to include errors.
301
+
302
+ Returns:
303
+ DecodeResult for SPI.
304
+ """
305
+ # SPI requires multiple channels (clock, MOSI, optionally MISO)
306
+ # Single-channel auto-decode is limited
307
+ # Return low-confidence result indicating more channels needed
308
+
309
+ return DecodeResult(
310
+ protocol="SPI",
311
+ overall_confidence=0.4,
312
+ detected_params={"note": "SPI requires clock and data channels"},
313
+ data=[],
314
+ frame_count=0,
315
+ error_count=0,
316
+ )
317
+
318
+
319
+ def _decode_i2c_auto(
320
+ trace: WaveformTrace | DigitalTrace,
321
+ params_hint: dict[str, Any] | None,
322
+ confidence_threshold: float,
323
+ return_errors: bool,
324
+ ) -> DecodeResult:
325
+ """Auto-decode I2C with parameter detection.
326
+
327
+ Args:
328
+ trace: Input trace.
329
+ params_hint: Optional parameter hints.
330
+ confidence_threshold: Minimum confidence threshold.
331
+ return_errors: Whether to include errors.
332
+
333
+ Returns:
334
+ DecodeResult for I2C.
335
+ """
336
+ # I2C requires both SDA and SCL channels
337
+ # Single-channel auto-decode is limited
338
+ # Return low-confidence result indicating more channels needed
339
+
340
+ return DecodeResult(
341
+ protocol="I2C",
342
+ overall_confidence=0.4,
343
+ detected_params={"note": "I2C requires SDA and SCL channels"},
344
+ data=[],
345
+ frame_count=0,
346
+ error_count=0,
347
+ )
348
+
349
+
350
+ def _detect_baud_rate(data: NDArray[np.floating[Any]], sample_rate: float) -> int:
351
+ """Auto-detect UART baud rate from signal.
352
+
353
+ Args:
354
+ data: Signal data array.
355
+ sample_rate: Sample rate in Hz.
356
+
357
+ Returns:
358
+ Detected baud rate in bps.
359
+ """
360
+ # Threshold signal to digital
361
+ threshold = (np.max(data) + np.min(data)) / 2
362
+ digital = data > threshold
363
+
364
+ # Find edges
365
+ edges = np.where(np.diff(digital.astype(int)) != 0)[0]
366
+
367
+ if len(edges) < 10:
368
+ return 115200 # Default fallback
369
+
370
+ # Analyze edge intervals to find bit period
371
+ intervals = np.diff(edges)
372
+
373
+ # Use histogram to find most common interval (bit period)
374
+ hist, bin_edges = np.histogram(intervals, bins=50)
375
+ peak_bin = np.argmax(hist)
376
+ bit_period_samples = (bin_edges[peak_bin] + bin_edges[peak_bin + 1]) / 2
377
+
378
+ # Calculate baud rate
379
+ estimated_baud = int(sample_rate / bit_period_samples)
380
+
381
+ # Snap to common baud rates
382
+ common_bauds = [
383
+ 300,
384
+ 600,
385
+ 1200,
386
+ 2400,
387
+ 4800,
388
+ 9600,
389
+ 14400,
390
+ 19200,
391
+ 28800,
392
+ 38400,
393
+ 57600,
394
+ 115200,
395
+ 230400,
396
+ 460800,
397
+ 921600,
398
+ ]
399
+
400
+ closest_baud = min(common_bauds, key=lambda x: abs(x - estimated_baud))
401
+
402
+ # Validate: should be within 5% of detected rate
403
+ if abs(closest_baud - estimated_baud) / estimated_baud < 0.05:
404
+ return closest_baud
405
+ else:
406
+ # Use estimated rate if no close match
407
+ return estimated_baud
408
+
409
+
410
+ __all__ = [
411
+ "DecodeResult",
412
+ "DecodedByte",
413
+ "ProtocolType",
414
+ "decode_protocol",
415
+ ]