oscura 0.0.1__py3-none-any.whl → 0.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.1.dist-info/METADATA +300 -0
  460. oscura-0.1.1.dist-info/RECORD +463 -0
  461. oscura-0.1.1.dist-info/entry_points.txt +2 -0
  462. {oscura-0.0.1.dist-info → oscura-0.1.1.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.1.dist-info}/WHEEL +0 -0
@@ -0,0 +1,405 @@
1
+ """Interactive tutorial system for Oscura.
2
+
3
+ This module provides step-by-step interactive tutorials for new users,
4
+ covering common analysis workflows.
5
+
6
+ - Interactive tutorial system
7
+ - Step-by-step guidance
8
+ - Code examples with explanations
9
+ - Progress tracking
10
+
11
+ Example:
12
+ >>> from oscura.onboarding import run_tutorial
13
+ >>> run_tutorial("getting_started")
14
+ Welcome to Oscura!
15
+ Step 1/5: Loading a trace file
16
+ ...
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ from dataclasses import dataclass, field
22
+ from typing import TYPE_CHECKING
23
+
24
+ if TYPE_CHECKING:
25
+ from collections.abc import Callable
26
+
27
+
28
+ @dataclass
29
+ class TutorialStep:
30
+ """A single step in a tutorial.
31
+
32
+ Attributes:
33
+ title: Step title
34
+ description: Detailed description with plain English explanation
35
+ code: Example code to run
36
+ expected_output: What the user should see
37
+ hints: Optional hints if stuck
38
+ """
39
+
40
+ title: str
41
+ description: str
42
+ code: str
43
+ expected_output: str = ""
44
+ hints: list[str] = field(default_factory=list)
45
+ validation_fn: Callable[..., bool] | None = None
46
+
47
+
48
+ @dataclass
49
+ class Tutorial:
50
+ """An interactive tutorial.
51
+
52
+ Attributes:
53
+ id: Unique tutorial identifier
54
+ title: Human-readable title
55
+ description: Tutorial overview
56
+ steps: List of tutorial steps
57
+ difficulty: beginner, intermediate, or advanced
58
+ """
59
+
60
+ id: str
61
+ title: str
62
+ description: str
63
+ steps: list[TutorialStep]
64
+ difficulty: str = "beginner"
65
+
66
+
67
+ # Built-in tutorials
68
+ TUTORIALS: dict[str, Tutorial] = {}
69
+
70
+
71
+ def _register_getting_started() -> None:
72
+ """Register the getting started tutorial."""
73
+ steps = [
74
+ TutorialStep(
75
+ title="Loading a Trace File",
76
+ description="""
77
+ Oscura can load waveform data from many file formats.
78
+ The simplest way is to use the load() function, which auto-detects the format.
79
+
80
+ Think of a trace like a recording of an electrical signal over time -
81
+ similar to how an audio file stores sound waves.
82
+ """,
83
+ code="""
84
+ import oscura as osc
85
+
86
+ # Load a waveform file (replace with your file path)
87
+ trace = osc.load("signal.csv")
88
+
89
+ # See basic info
90
+ print(f"Loaded {len(trace.data)} samples")
91
+ print(f"Sample rate: {trace.metadata.sample_rate} Hz")
92
+ """,
93
+ expected_output="Loaded 10000 samples\nSample rate: 1000000.0 Hz",
94
+ hints=[
95
+ "Try loading a CSV file with two columns: time and voltage",
96
+ "Supported formats: .csv, .wfm, .npz, .hdf5, and more",
97
+ ],
98
+ ),
99
+ TutorialStep(
100
+ title="Making Basic Measurements",
101
+ description="""
102
+ Once you have a trace, you can measure things like:
103
+ - Rise time: How fast a signal goes from low to high
104
+ - Frequency: How many times per second the signal repeats
105
+ - Amplitude: The voltage difference between high and low
106
+
107
+ These are the same measurements an oscilloscope would show you!
108
+ """,
109
+ code="""
110
+ import oscura as osc
111
+
112
+ trace = osc.load("signal.csv")
113
+
114
+ # Measure rise time (10% to 90% transition)
115
+ rt = osc.rise_time(trace)
116
+ print(f"Rise time: {rt*1e9:.2f} nanoseconds")
117
+
118
+ # Measure frequency
119
+ freq = osc.frequency(trace)
120
+ print(f"Frequency: {freq/1e6:.2f} MHz")
121
+
122
+ # Get all measurements at once
123
+ results = osc.measure(trace)
124
+ for name, value in results.items():
125
+ print(f"{name}: {value}")
126
+ """,
127
+ expected_output="Rise time: 2.50 nanoseconds\nFrequency: 10.00 MHz",
128
+ hints=[
129
+ "rise_time() measures 10%-90% transition by default",
130
+ "Use measure() to get all measurements in one call",
131
+ ],
132
+ ),
133
+ TutorialStep(
134
+ title="Spectral Analysis (Frequency Domain)",
135
+ description="""
136
+ Spectral analysis shows you what frequencies are present in your signal.
137
+ This is useful for:
138
+ - Finding the main frequency of a clock signal
139
+ - Detecting noise at specific frequencies
140
+ - Measuring signal quality (THD, SNR)
141
+
142
+ It's like looking at a music equalizer that shows bass, mid, and treble!
143
+ """,
144
+ code="""
145
+ import oscura as osc
146
+
147
+ trace = osc.load("signal.csv")
148
+
149
+ # Compute FFT (Fast Fourier Transform)
150
+ freq, magnitude = osc.fft(trace)
151
+
152
+ # Find the dominant frequency
153
+ import numpy as np
154
+ peak_idx = np.argmax(magnitude)
155
+ print(f"Dominant frequency: {freq[peak_idx]/1e6:.2f} MHz")
156
+
157
+ # Measure signal quality
158
+ thd_value = osc.thd(trace)
159
+ snr_value = osc.snr(trace)
160
+ print(f"THD: {thd_value:.1f} dB")
161
+ print(f"SNR: {snr_value:.1f} dB")
162
+ """,
163
+ expected_output="Dominant frequency: 10.00 MHz\nTHD: -45.2 dB\nSNR: 52.3 dB",
164
+ hints=[
165
+ "THD (Total Harmonic Distortion) should be negative in dB - more negative is better",
166
+ "SNR (Signal-to-Noise Ratio) should be positive - higher is better",
167
+ ],
168
+ ),
169
+ TutorialStep(
170
+ title="Protocol Decoding",
171
+ description="""
172
+ If your signal is a digital communication protocol like UART, SPI, or I2C,
173
+ Oscura can decode it to show you the actual data being transmitted.
174
+
175
+ Think of it like translating Morse code back into text!
176
+ """,
177
+ code="""
178
+ import oscura as osc
179
+
180
+ # Load a UART signal
181
+ trace = osc.load("uart_signal.csv")
182
+
183
+ # Decode UART (auto-detects baud rate!)
184
+ from oscura.analyzers.protocols import decode_uart
185
+ packets = decode_uart(trace)
186
+
187
+ # Show decoded bytes
188
+ for pkt in packets[:5]: # First 5 packets
189
+ print(f"Time: {pkt.timestamp:.6f}s, Data: 0x{pkt.data:02X} ('{chr(pkt.data)}')")
190
+ """,
191
+ expected_output="Time: 0.000001s, Data: 0x48 ('H')\nTime: 0.000086s, Data: 0x65 ('e')",
192
+ hints=[
193
+ "UART baud rate is auto-detected by default",
194
+ "Supported protocols: UART, SPI, I2C, CAN, and many more",
195
+ ],
196
+ ),
197
+ TutorialStep(
198
+ title="Auto-Discovery for Beginners",
199
+ description="""
200
+ Not sure what your signal is? Oscura can analyze it automatically!
201
+
202
+ The characterize_signal() function examines your trace and tells you:
203
+ - What type of signal it likely is
204
+ - Key parameters (voltage, frequency, etc.)
205
+ - Suggestions for further analysis
206
+
207
+ It's like having an expert look at your signal and give you hints!
208
+ """,
209
+ code="""
210
+ import oscura as osc
211
+ from oscura.discovery import characterize_signal
212
+
213
+ trace = osc.load("mystery_signal.csv")
214
+
215
+ # Auto-characterize the signal
216
+ result = characterize_signal(trace)
217
+
218
+ print(f"Signal type: {result.signal_type}")
219
+ print(f"Confidence: {result.confidence:.1%}")
220
+ print(f"Voltage range: {result.voltage_low:.2f}V to {result.voltage_high:.2f}V")
221
+
222
+ if result.confidence >= 0.8:
223
+ print("High confidence - proceed with suggested analysis")
224
+ else:
225
+ print("Consider alternatives:")
226
+ for alt in result.alternatives:
227
+ print(f" - {alt.signal_type}: {alt.confidence:.1%}")
228
+ """,
229
+ expected_output="Signal type: digital\nConfidence: 94.0%",
230
+ hints=[
231
+ "Confidence >= 80% means high confidence in the detection",
232
+ "Low confidence? Check the alternatives for other possibilities",
233
+ ],
234
+ ),
235
+ ]
236
+
237
+ tutorial = Tutorial(
238
+ id="getting_started",
239
+ title="Getting Started with Oscura",
240
+ description="""
241
+ Welcome to Oscura! This tutorial will teach you the basics of
242
+ signal analysis in 5 easy steps:
243
+
244
+ 1. Loading trace files
245
+ 2. Making basic measurements
246
+ 3. Spectral analysis
247
+ 4. Protocol decoding
248
+ 5. Auto-discovery
249
+
250
+ No prior signal analysis experience required!
251
+ """,
252
+ steps=steps,
253
+ difficulty="beginner",
254
+ )
255
+
256
+ TUTORIALS[tutorial.id] = tutorial
257
+
258
+
259
+ def _register_spectral_analysis() -> None:
260
+ """Register the spectral analysis tutorial."""
261
+ steps = [
262
+ TutorialStep(
263
+ title="Understanding FFT",
264
+ description="""
265
+ The Fast Fourier Transform (FFT) converts a time-domain signal into
266
+ its frequency components. Think of it as breaking a chord into individual notes.
267
+ """,
268
+ code="""
269
+ import oscura as osc
270
+ import numpy as np
271
+
272
+ trace = osc.load("signal.csv")
273
+ freq, mag = osc.fft(trace)
274
+
275
+ # Magnitude is in dB (decibels)
276
+ # 0 dB = full scale, -20 dB = 10x smaller, -40 dB = 100x smaller
277
+ print(f"Frequency range: 0 to {freq[-1]/1e6:.1f} MHz")
278
+ print(f"Peak magnitude: {np.max(mag):.1f} dB")
279
+ """,
280
+ expected_output="Frequency range: 0 to 50.0 MHz\nPeak magnitude: -3.2 dB",
281
+ ),
282
+ TutorialStep(
283
+ title="Power Spectral Density",
284
+ description="""
285
+ PSD shows power distribution across frequencies. Unlike FFT magnitude,
286
+ PSD is normalized per Hz, making it easier to compare signals with
287
+ different durations or sample rates.
288
+ """,
289
+ code="""
290
+ import oscura as osc
291
+
292
+ trace = osc.load("signal.csv")
293
+ freq, psd = osc.psd(trace)
294
+
295
+ # Find where most power is concentrated
296
+ import numpy as np
297
+ total_power = np.sum(psd)
298
+ cumsum = np.cumsum(psd) / total_power
299
+
300
+ # 90% of power is below this frequency
301
+ idx_90 = np.searchsorted(cumsum, 0.9)
302
+ print(f"90% of signal power below {freq[idx_90]/1e6:.1f} MHz")
303
+ """,
304
+ expected_output="90% of signal power below 15.2 MHz",
305
+ ),
306
+ ]
307
+
308
+ tutorial = Tutorial(
309
+ id="spectral_analysis",
310
+ title="Spectral Analysis Deep Dive",
311
+ description="Learn advanced spectral analysis techniques.",
312
+ steps=steps,
313
+ difficulty="intermediate",
314
+ )
315
+
316
+ TUTORIALS[tutorial.id] = tutorial
317
+
318
+
319
+ # Register built-in tutorials
320
+ _register_getting_started()
321
+ _register_spectral_analysis()
322
+
323
+
324
+ def list_tutorials() -> list[dict[str, str]]:
325
+ """List all available tutorials.
326
+
327
+ Returns:
328
+ List of tutorial info dictionaries with id, title, difficulty
329
+ """
330
+ return [
331
+ {
332
+ "id": t.id,
333
+ "title": t.title,
334
+ "difficulty": t.difficulty,
335
+ "steps": len(t.steps), # type: ignore[dict-item]
336
+ }
337
+ for t in TUTORIALS.values()
338
+ ]
339
+
340
+
341
+ def get_tutorial(tutorial_id: str) -> Tutorial | None:
342
+ """Get a tutorial by ID.
343
+
344
+ Args:
345
+ tutorial_id: Tutorial identifier
346
+
347
+ Returns:
348
+ Tutorial object or None if not found
349
+ """
350
+ return TUTORIALS.get(tutorial_id)
351
+
352
+
353
+ def run_tutorial(tutorial_id: str, interactive: bool = True) -> None:
354
+ """Run an interactive tutorial.
355
+
356
+ Args:
357
+ tutorial_id: Tutorial to run (e.g., "getting_started")
358
+ interactive: If True, pause between steps for user input
359
+
360
+ Example:
361
+ >>> run_tutorial("getting_started")
362
+ """
363
+ tutorial = get_tutorial(tutorial_id)
364
+ if tutorial is None:
365
+ print(f"Tutorial '{tutorial_id}' not found.")
366
+ print("Available tutorials:")
367
+ for t in list_tutorials():
368
+ print(f" - {t['id']}: {t['title']}")
369
+ return
370
+
371
+ print("=" * 60)
372
+ print(f"Tutorial: {tutorial.title}")
373
+ print(f"Difficulty: {tutorial.difficulty}")
374
+ print("=" * 60)
375
+ print(tutorial.description)
376
+ print()
377
+
378
+ for i, step in enumerate(tutorial.steps, 1):
379
+ print(f"\n{'=' * 60}")
380
+ print(f"Step {i}/{len(tutorial.steps)}: {step.title}")
381
+ print("=" * 60)
382
+ print(step.description)
383
+ print("\nCode:")
384
+ print("-" * 40)
385
+ print(step.code)
386
+ print("-" * 40)
387
+
388
+ if step.expected_output:
389
+ print(f"\nExpected output:\n{step.expected_output}")
390
+
391
+ if step.hints:
392
+ print("\nHints:")
393
+ for hint in step.hints:
394
+ print(f" - {hint}")
395
+
396
+ if interactive:
397
+ input("\nPress Enter to continue...")
398
+
399
+ print("\n" + "=" * 60)
400
+ print("Tutorial Complete!")
401
+ print("=" * 60)
402
+ print("Next steps:")
403
+ print(" - Try the examples with your own data")
404
+ print(" - Run 'list_tutorials()' to see more tutorials")
405
+ print(" - Use 'get_help(function_name)' for detailed help")