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,396 @@
1
+ """Performance profiling for signal analysis operations.
2
+
3
+ This module provides profiling utilities for measuring and analyzing
4
+ performance of signal processing operations.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import functools
10
+ import logging
11
+ import statistics
12
+ import time
13
+ from contextlib import contextmanager
14
+ from dataclasses import dataclass, field
15
+ from typing import TYPE_CHECKING, Any
16
+
17
+ if TYPE_CHECKING:
18
+ from collections.abc import Callable, Iterator
19
+
20
+ logger = logging.getLogger(__name__)
21
+
22
+ __all__ = [
23
+ "OperationProfile",
24
+ "ProfileReport",
25
+ "Profiler",
26
+ "profile",
27
+ ]
28
+
29
+
30
+ @dataclass
31
+ class OperationProfile:
32
+ """Profile data for a single operation.
33
+
34
+ Attributes:
35
+ name: Operation name
36
+ calls: Number of calls
37
+ total_time: Total time in seconds
38
+ min_time: Minimum time
39
+ max_time: Maximum time
40
+ times: List of individual times
41
+ memory_peak: Peak memory usage (bytes)
42
+ input_size: Input data size
43
+
44
+ References:
45
+ API-012: Performance Profiling API
46
+ """
47
+
48
+ name: str
49
+ calls: int = 0
50
+ total_time: float = 0.0
51
+ min_time: float = float("inf")
52
+ max_time: float = 0.0
53
+ times: list[float] = field(default_factory=list)
54
+ memory_peak: int = 0
55
+ input_size: int = 0
56
+
57
+ @property
58
+ def mean_time(self) -> float:
59
+ """Average time per call."""
60
+ return self.total_time / self.calls if self.calls > 0 else 0.0
61
+
62
+ @property
63
+ def std_time(self) -> float:
64
+ """Standard deviation of times."""
65
+ if len(self.times) < 2:
66
+ return 0.0
67
+ return statistics.stdev(self.times)
68
+
69
+ @property
70
+ def throughput(self) -> float:
71
+ """Throughput in items per second."""
72
+ if self.total_time > 0 and self.input_size > 0:
73
+ return (self.input_size * self.calls) / self.total_time
74
+ return 0.0
75
+
76
+ def record(self, elapsed: float, size: int = 0) -> None:
77
+ """Record a timing.
78
+
79
+ Args:
80
+ elapsed: Elapsed time in seconds
81
+ size: Input size
82
+ """
83
+ self.calls += 1
84
+ self.total_time += elapsed
85
+ self.min_time = min(self.min_time, elapsed)
86
+ self.max_time = max(self.max_time, elapsed)
87
+ self.times.append(elapsed)
88
+ if size > 0:
89
+ self.input_size = size
90
+
91
+ def to_dict(self) -> dict[str, Any]:
92
+ """Convert to dictionary."""
93
+ return {
94
+ "name": self.name,
95
+ "calls": self.calls,
96
+ "total_time": self.total_time,
97
+ "mean_time": self.mean_time,
98
+ "min_time": self.min_time if self.min_time != float("inf") else 0,
99
+ "max_time": self.max_time,
100
+ "std_time": self.std_time,
101
+ "throughput": self.throughput,
102
+ }
103
+
104
+
105
+ @dataclass
106
+ class ProfileReport:
107
+ """Complete profiling report.
108
+
109
+ Attributes:
110
+ profiles: Dictionary of operation profiles
111
+ start_time: Report start time
112
+ end_time: Report end time
113
+ total_operations: Total number of operations
114
+
115
+ References:
116
+ API-012: Performance Profiling API
117
+ """
118
+
119
+ profiles: dict[str, OperationProfile] = field(default_factory=dict)
120
+ start_time: float = 0.0
121
+ end_time: float = 0.0
122
+ total_operations: int = 0
123
+
124
+ @property
125
+ def total_time(self) -> float:
126
+ """Total profiled time."""
127
+ return sum(p.total_time for p in self.profiles.values())
128
+
129
+ @property
130
+ def wall_time(self) -> float:
131
+ """Wall clock time."""
132
+ return self.end_time - self.start_time if self.end_time > 0 else 0.0
133
+
134
+ def get_slowest(self, n: int = 5) -> list[OperationProfile]:
135
+ """Get slowest operations.
136
+
137
+ Args:
138
+ n: Number of operations
139
+
140
+ Returns:
141
+ List of slowest operation profiles
142
+ """
143
+ sorted_profiles = sorted(self.profiles.values(), key=lambda p: p.total_time, reverse=True)
144
+ return sorted_profiles[:n]
145
+
146
+ def get_most_called(self, n: int = 5) -> list[OperationProfile]:
147
+ """Get most frequently called operations.
148
+
149
+ Args:
150
+ n: Number of operations
151
+
152
+ Returns:
153
+ List of most called operation profiles
154
+ """
155
+ sorted_profiles = sorted(self.profiles.values(), key=lambda p: p.calls, reverse=True)
156
+ return sorted_profiles[:n]
157
+
158
+ def summary(self) -> str:
159
+ """Generate text summary.
160
+
161
+ Returns:
162
+ Summary string
163
+ """
164
+ lines = [
165
+ "Performance Profile Report",
166
+ "=" * 50,
167
+ f"Total operations: {self.total_operations}",
168
+ f"Total profiled time: {self.total_time:.4f}s",
169
+ f"Wall clock time: {self.wall_time:.4f}s",
170
+ "",
171
+ "Slowest Operations:",
172
+ "-" * 30,
173
+ ]
174
+
175
+ for profile in self.get_slowest():
176
+ lines.append(
177
+ f" {profile.name}: "
178
+ f"{profile.total_time:.4f}s ({profile.calls} calls, "
179
+ f"{profile.mean_time * 1000:.2f}ms avg)"
180
+ )
181
+
182
+ return "\n".join(lines)
183
+
184
+ def to_dict(self) -> dict[str, Any]:
185
+ """Convert to dictionary."""
186
+ return {
187
+ "total_time": self.total_time,
188
+ "wall_time": self.wall_time,
189
+ "total_operations": self.total_operations,
190
+ "profiles": {name: profile.to_dict() for name, profile in self.profiles.items()},
191
+ }
192
+
193
+
194
+ class Profiler:
195
+ """Performance profiler for signal analysis operations.
196
+
197
+ Tracks timing and performance metrics for operations.
198
+
199
+ Example:
200
+ >>> profiler = Profiler()
201
+ >>> with profiler.profile("fft"):
202
+ ... result = np.fft.fft(data)
203
+ >>> report = profiler.report()
204
+ >>> print(report.summary())
205
+
206
+ References:
207
+ API-012: Performance Profiling API
208
+ """
209
+
210
+ _instance: Profiler | None = None
211
+
212
+ def __init__(self) -> None:
213
+ """Initialize profiler."""
214
+ self._profiles: dict[str, OperationProfile] = {}
215
+ self._start_time: float = 0.0
216
+ self._enabled: bool = True
217
+ self._stack: list[str] = []
218
+
219
+ @classmethod
220
+ def get_instance(cls) -> Profiler:
221
+ """Get global profiler instance."""
222
+ if cls._instance is None:
223
+ cls._instance = cls()
224
+ return cls._instance
225
+
226
+ def enable(self) -> None:
227
+ """Enable profiling."""
228
+ self._enabled = True
229
+
230
+ def disable(self) -> None:
231
+ """Disable profiling."""
232
+ self._enabled = False
233
+
234
+ def reset(self) -> None:
235
+ """Reset all profiles."""
236
+ self._profiles.clear()
237
+ self._start_time = 0.0
238
+
239
+ @contextmanager
240
+ def profile(self, name: str, input_size: int = 0) -> Iterator[None]:
241
+ """Context manager for profiling code block.
242
+
243
+ Args:
244
+ name: Operation name
245
+ input_size: Input data size
246
+
247
+ Yields:
248
+ None
249
+
250
+ Example:
251
+ >>> with profiler.profile("fft"):
252
+ ... result = compute_fft(data)
253
+ """
254
+ if not self._enabled:
255
+ yield
256
+ return
257
+
258
+ if self._start_time == 0:
259
+ self._start_time = time.perf_counter()
260
+
261
+ if name not in self._profiles:
262
+ self._profiles[name] = OperationProfile(name)
263
+
264
+ self._stack.append(name)
265
+ start = time.perf_counter()
266
+
267
+ try:
268
+ yield
269
+ finally:
270
+ elapsed = time.perf_counter() - start
271
+ self._profiles[name].record(elapsed, input_size)
272
+ self._stack.pop()
273
+
274
+ def record(self, name: str, elapsed: float, input_size: int = 0) -> None:
275
+ """Manually record a timing.
276
+
277
+ Args:
278
+ name: Operation name
279
+ elapsed: Elapsed time
280
+ input_size: Input size
281
+ """
282
+ if not self._enabled:
283
+ return
284
+
285
+ if name not in self._profiles:
286
+ self._profiles[name] = OperationProfile(name)
287
+
288
+ self._profiles[name].record(elapsed, input_size)
289
+
290
+ def get_profile(self, name: str) -> OperationProfile | None:
291
+ """Get profile for operation.
292
+
293
+ Args:
294
+ name: Operation name
295
+
296
+ Returns:
297
+ Operation profile or None
298
+ """
299
+ return self._profiles.get(name)
300
+
301
+ def report(self) -> ProfileReport:
302
+ """Generate profiling report.
303
+
304
+ Returns:
305
+ Profile report
306
+ """
307
+ return ProfileReport(
308
+ profiles=self._profiles.copy(),
309
+ start_time=self._start_time,
310
+ end_time=time.perf_counter(),
311
+ total_operations=sum(p.calls for p in self._profiles.values()),
312
+ )
313
+
314
+
315
+ def profile(name: str | None = None, input_size_arg: str | None = None) -> Callable: # type: ignore[type-arg]
316
+ """Decorator for profiling functions.
317
+
318
+ Args:
319
+ name: Profile name (defaults to function name)
320
+ input_size_arg: Argument name for input size
321
+
322
+ Returns:
323
+ Decorated function
324
+
325
+ Example:
326
+ >>> @profile()
327
+ >>> def compute_fft(data, nfft=None):
328
+ ... return np.fft.fft(data, n=nfft)
329
+
330
+ References:
331
+ API-012: Performance Profiling API
332
+ """
333
+
334
+ def decorator(func: Callable) -> Callable: # type: ignore[type-arg]
335
+ profile_name = name or func.__name__
336
+
337
+ @functools.wraps(func)
338
+ def wrapper(*args: Any, **kwargs: Any) -> Any:
339
+ profiler = Profiler.get_instance()
340
+
341
+ # Determine input size
342
+ input_size = 0
343
+ if input_size_arg:
344
+ if input_size_arg in kwargs:
345
+ data = kwargs[input_size_arg]
346
+ elif args:
347
+ data = args[0]
348
+ else:
349
+ data = None
350
+
351
+ if hasattr(data, "__len__"):
352
+ input_size = len(data)
353
+
354
+ with profiler.profile(profile_name, input_size):
355
+ return func(*args, **kwargs)
356
+
357
+ return wrapper
358
+
359
+ return decorator
360
+
361
+
362
+ # Convenience functions
363
+ def get_profiler() -> Profiler:
364
+ """Get global profiler instance.
365
+
366
+ Returns:
367
+ Global Profiler instance
368
+
369
+ References:
370
+ API-012: Performance Profiling API
371
+ """
372
+ return Profiler.get_instance()
373
+
374
+
375
+ def enable_profiling() -> None:
376
+ """Enable global profiling."""
377
+ get_profiler().enable()
378
+
379
+
380
+ def disable_profiling() -> None:
381
+ """Disable global profiling."""
382
+ get_profiler().disable()
383
+
384
+
385
+ def reset_profiling() -> None:
386
+ """Reset global profiler."""
387
+ get_profiler().reset()
388
+
389
+
390
+ def get_profile_report() -> ProfileReport:
391
+ """Get global profile report.
392
+
393
+ Returns:
394
+ Profile report
395
+ """
396
+ return get_profiler().report()
@@ -0,0 +1,73 @@
1
+ """Automotive signal analysis and reverse engineering.
2
+
3
+ This module provides comprehensive automotive protocol analysis capabilities
4
+ for CAN, CAN-FD, OBD-II, J1939, UDS, DBC-based signal decoding, and diagnostic
5
+ trouble code (DTC) database.
6
+
7
+ Key features:
8
+ - CAN message analysis and discovery (message inventory, byte entropy, pattern detection)
9
+ - Signal boundary detection and hypothesis testing
10
+ - DBC database parsing and generation
11
+ - OBD-II diagnostic protocol support
12
+ - J1939 heavy-duty vehicle protocol support
13
+ - UDS (ISO 14229) diagnostic services decoding
14
+ - DTC database (200+ codes for Powertrain, Chassis, Body, Network)
15
+ - Discovery documentation with evidence tracking (.tkcan format)
16
+ - Integration with Oscura's CRC reverse engineering and state machine learning
17
+
18
+ Example:
19
+ >>> from oscura.automotive.can import CANSession
20
+ >>> # Load automotive log file
21
+ >>> session = CANSession.from_log("capture.blf")
22
+ >>> # View message inventory
23
+ >>> inventory = session.inventory()
24
+ >>> # Analyze specific message
25
+ >>> msg = session.message(0x280)
26
+ >>> analysis = msg.analyze()
27
+ >>> # Test hypothesis about signal
28
+ >>> hypothesis = msg.test_hypothesis(
29
+ ... signal_name="rpm",
30
+ ... start_byte=2,
31
+ ... bit_length=16,
32
+ ... byte_order="big_endian",
33
+ ... scale=0.25
34
+ ... )
35
+ >>>
36
+ >>> # Look up diagnostic trouble codes
37
+ >>> from oscura.automotive.dtc import DTCDatabase
38
+ >>> info = DTCDatabase.lookup("P0420")
39
+ >>> print(f"{info.code}: {info.description}")
40
+ P0420: Catalyst System Efficiency Below Threshold (Bank 1)
41
+ """
42
+
43
+ from __future__ import annotations
44
+
45
+ __version__ = "0.1.0"
46
+
47
+ __all__ = [
48
+ "CANMessage",
49
+ "CANSession",
50
+ "DecodedSignal",
51
+ "DiscoveryDocument",
52
+ "plot_bus_timeline",
53
+ "plot_bus_utilization",
54
+ "plot_message_distribution",
55
+ "plot_message_frequency",
56
+ "plot_signal_timeline",
57
+ ]
58
+
59
+ # Import main classes when module is loaded
60
+ try:
61
+ from oscura.automotive.can.discovery import DiscoveryDocument
62
+ from oscura.automotive.can.models import CANMessage, DecodedSignal
63
+ from oscura.automotive.can.session import CANSession
64
+ from oscura.automotive.visualization import (
65
+ plot_bus_timeline,
66
+ plot_bus_utilization,
67
+ plot_message_distribution,
68
+ plot_message_frequency,
69
+ plot_signal_timeline,
70
+ )
71
+ except ImportError:
72
+ # Optional automotive dependencies not installed
73
+ pass
@@ -0,0 +1,52 @@
1
+ """CAN bus analysis and reverse engineering.
2
+
3
+ This submodule provides CAN-specific analysis tools for reverse engineering
4
+ automotive protocols from captured CAN bus data.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ __all__ = [
10
+ "ByteChange",
11
+ "CANMessage",
12
+ "CANMessageList",
13
+ "CANSession",
14
+ "CANStateMachine",
15
+ "DecodedSignal",
16
+ "FrequencyChange",
17
+ "MessageAnalysis",
18
+ "MessagePair",
19
+ "MessageSequence",
20
+ "PatternAnalyzer",
21
+ "SequenceExtraction",
22
+ "SignalDefinition",
23
+ "StimulusResponseAnalyzer",
24
+ "StimulusResponseReport",
25
+ "TemporalCorrelation",
26
+ ]
27
+
28
+ try:
29
+ from oscura.automotive.can.models import (
30
+ CANMessage,
31
+ CANMessageList,
32
+ DecodedSignal,
33
+ MessageAnalysis,
34
+ SignalDefinition,
35
+ )
36
+ from oscura.automotive.can.patterns import (
37
+ MessagePair,
38
+ MessageSequence,
39
+ PatternAnalyzer,
40
+ TemporalCorrelation,
41
+ )
42
+ from oscura.automotive.can.session import CANSession
43
+ from oscura.automotive.can.state_machine import CANStateMachine, SequenceExtraction
44
+ from oscura.automotive.can.stimulus_response import (
45
+ ByteChange,
46
+ FrequencyChange,
47
+ StimulusResponseAnalyzer,
48
+ StimulusResponseReport,
49
+ )
50
+ except ImportError:
51
+ # Optional dependencies not installed
52
+ pass