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,35 @@
1
+ """Automotive file format loaders.
2
+
3
+ This module provides loaders for common automotive logging file formats:
4
+ - BLF (Vector Binary Logging Format)
5
+ - ASC (Vector ASCII Format)
6
+ - MDF/MF4 (ASAM Measurement Data Format)
7
+ - CSV (Comma-Separated Values)
8
+ - PCAP (Packet Capture - SocketCAN)
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ __all__ = [
14
+ "detect_format",
15
+ "load_asc",
16
+ "load_automotive_log",
17
+ "load_blf",
18
+ "load_csv_can",
19
+ "load_mdf",
20
+ "load_pcap",
21
+ ]
22
+
23
+ try:
24
+ from oscura.automotive.loaders.asc import load_asc
25
+ from oscura.automotive.loaders.blf import load_blf
26
+ from oscura.automotive.loaders.csv_can import load_csv_can
27
+ from oscura.automotive.loaders.dispatcher import (
28
+ detect_format,
29
+ load_automotive_log,
30
+ )
31
+ from oscura.automotive.loaders.mdf import load_mdf
32
+ from oscura.automotive.loaders.pcap import load_pcap
33
+ except ImportError:
34
+ # Optional dependencies not installed
35
+ pass
@@ -0,0 +1,98 @@
1
+ """Vector ASC (ASCII Format) file loader.
2
+
3
+ This module provides loading of Vector ASC files. ASC is a human-readable
4
+ text format used by Vector tools for logging CAN bus data.
5
+
6
+ ASC format example:
7
+ date Mon Jul 15 10:30:45.123 2024
8
+ 0.000000 1 123 Rx d 8 01 02 03 04 05 06 07 08
9
+ 0.010000 1 280 Rx d 8 0A 0B 0C 0D 0E 0F 10 11
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import re
15
+ from pathlib import Path
16
+
17
+ from oscura.automotive.can.models import CANMessage, CANMessageList
18
+
19
+ __all__ = ["load_asc"]
20
+
21
+
22
+ def load_asc(file_path: Path | str) -> CANMessageList:
23
+ """Load CAN messages from a Vector ASC file.
24
+
25
+ Args:
26
+ file_path: Path to the ASC file.
27
+
28
+ Returns:
29
+ CANMessageList containing all parsed CAN messages.
30
+
31
+ Raises:
32
+ FileNotFoundError: If file doesn't exist.
33
+ ValueError: If file cannot be parsed.
34
+
35
+ Example:
36
+ >>> messages = load_asc("capture.asc")
37
+ >>> print(f"Loaded {len(messages)} messages")
38
+ """
39
+ path = Path(file_path)
40
+ if not path.exists():
41
+ raise FileNotFoundError(f"ASC file not found: {path}")
42
+
43
+ messages = CANMessageList()
44
+
45
+ # Regex pattern for CAN message lines
46
+ # Format: <timestamp> <channel> <ID> <direction> <type> <DLC> <data bytes>
47
+ # Example: 0.123456 1 123 Rx d 8 01 02 03 04 05 06 07 08
48
+ pattern = re.compile(
49
+ r"^\s*(\d+\.\d+)\s+" # timestamp
50
+ r"(\d+)\s+" # channel
51
+ r"([0-9A-Fa-f]+)\s+" # CAN ID (hex)
52
+ r"(Rx|Tx)\s+" # direction
53
+ r"d\s+" # type (d = data frame)
54
+ r"(\d+)\s+" # DLC
55
+ r"((?:[0-9A-Fa-f]{2}\s*)*)" # data bytes
56
+ )
57
+
58
+ try:
59
+ with open(path, encoding="utf-8", errors="ignore") as f:
60
+ for line in f:
61
+ # Skip comments and header lines
62
+ if line.startswith("//") or line.startswith("date"):
63
+ continue
64
+
65
+ # Try to parse as CAN message
66
+ match = pattern.match(line)
67
+ if match:
68
+ timestamp_str, channel_str, id_str, direction, dlc_str, data_str = (
69
+ match.groups()
70
+ )
71
+
72
+ # Parse components
73
+ timestamp = float(timestamp_str)
74
+ channel = int(channel_str)
75
+ arb_id = int(id_str, 16)
76
+ int(dlc_str)
77
+
78
+ # Parse data bytes
79
+ data_bytes = bytes.fromhex(data_str.replace(" ", ""))
80
+
81
+ # Determine if extended ID (typically > 0x7FF)
82
+ is_extended = arb_id > 0x7FF
83
+
84
+ # Create message
85
+ can_msg = CANMessage(
86
+ arbitration_id=arb_id,
87
+ timestamp=timestamp,
88
+ data=data_bytes,
89
+ is_extended=is_extended,
90
+ is_fd=False, # ASC typically doesn't indicate FD
91
+ channel=channel,
92
+ )
93
+ messages.append(can_msg)
94
+
95
+ except Exception as e:
96
+ raise ValueError(f"Failed to parse ASC file {path}: {e}") from e
97
+
98
+ return messages
@@ -0,0 +1,77 @@
1
+ """Vector BLF (Binary Logging Format) file loader.
2
+
3
+ This module provides loading of Vector BLF files using the python-can library.
4
+ BLF is a proprietary binary format used by Vector tools (CANoe, CANalyzer, etc.)
5
+ for logging CAN bus data.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from pathlib import Path
11
+
12
+ from oscura.automotive.can.models import CANMessage, CANMessageList
13
+
14
+ __all__ = ["load_blf"]
15
+
16
+
17
+ def load_blf(file_path: Path | str) -> CANMessageList:
18
+ """Load CAN messages from a Vector BLF file.
19
+
20
+ Args:
21
+ file_path: Path to the BLF file.
22
+
23
+ Returns:
24
+ CANMessageList containing all parsed CAN messages.
25
+
26
+ Raises:
27
+ ImportError: If python-can is not installed.
28
+ FileNotFoundError: If file doesn't exist.
29
+ ValueError: If file cannot be parsed.
30
+
31
+ Example:
32
+ >>> messages = load_blf("capture.blf")
33
+ >>> print(f"Loaded {len(messages)} messages")
34
+ >>> print(f"Unique IDs: {len(messages.unique_ids())}")
35
+ """
36
+ try:
37
+ import can # type: ignore[import-untyped]
38
+ except ImportError as e:
39
+ raise ImportError(
40
+ "python-can is required for BLF file support. "
41
+ "Install with: pip install 'oscura[automotive]'"
42
+ ) from e
43
+
44
+ path = Path(file_path)
45
+ if not path.exists():
46
+ raise FileNotFoundError(f"BLF file not found: {path}")
47
+
48
+ messages = CANMessageList()
49
+
50
+ try:
51
+ # Open BLF file using python-can
52
+ with can.BLFReader(str(path)) as reader:
53
+ for msg in reader:
54
+ # Convert python-can Message to our CANMessage
55
+ # Extract channel number (python-can may return various types)
56
+ channel = 0
57
+ if hasattr(msg, "channel"):
58
+ ch = msg.channel
59
+ if isinstance(ch, int):
60
+ channel = ch
61
+ elif ch is not None:
62
+ channel = int(ch) # type: ignore[arg-type]
63
+
64
+ can_msg = CANMessage(
65
+ arbitration_id=msg.arbitration_id,
66
+ timestamp=msg.timestamp,
67
+ data=bytes(msg.data),
68
+ is_extended=msg.is_extended_id,
69
+ is_fd=msg.is_fd,
70
+ channel=channel,
71
+ )
72
+ messages.append(can_msg)
73
+
74
+ except Exception as e:
75
+ raise ValueError(f"Failed to parse BLF file {path}: {e}") from e
76
+
77
+ return messages
@@ -0,0 +1,136 @@
1
+ """CSV CAN log file loader.
2
+
3
+ This module provides loading of CAN data from CSV files.
4
+ Supports various CSV formats commonly used for CAN logging.
5
+
6
+ Common CSV format:
7
+ timestamp,id,data
8
+ 0.000000,0x123,0102030405060708
9
+ 0.010000,0x280,0A0B0C0D0E0F1011
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import csv
15
+ from pathlib import Path
16
+
17
+ from oscura.automotive.can.models import CANMessage, CANMessageList
18
+
19
+ __all__ = ["load_csv_can"]
20
+
21
+
22
+ def load_csv_can(file_path: Path | str, delimiter: str = ",") -> CANMessageList:
23
+ """Load CAN messages from a CSV file.
24
+
25
+ This function attempts to automatically detect the CSV column layout
26
+ and parse CAN messages accordingly.
27
+
28
+ Expected columns (case-insensitive, order-independent):
29
+ - timestamp or time: Message timestamp
30
+ - id or can_id or arbitration_id: CAN ID (hex or decimal)
31
+ - data or payload: Data bytes (hex string)
32
+ - Optional: channel, dlc, extended, etc.
33
+
34
+ Args:
35
+ file_path: Path to the CSV file.
36
+ delimiter: CSV delimiter character.
37
+
38
+ Returns:
39
+ CANMessageList containing all parsed CAN messages.
40
+
41
+ Raises:
42
+ FileNotFoundError: If file doesn't exist.
43
+ ValueError: If file cannot be parsed or has unexpected format.
44
+
45
+ Example:
46
+ >>> messages = load_csv_can("capture.csv")
47
+ >>> print(f"Loaded {len(messages)} messages")
48
+ """
49
+ path = Path(file_path)
50
+ if not path.exists():
51
+ raise FileNotFoundError(f"CSV file not found: {path}")
52
+
53
+ messages = CANMessageList()
54
+
55
+ try:
56
+ with open(path, encoding="utf-8") as f:
57
+ reader = csv.DictReader(f, delimiter=delimiter)
58
+
59
+ # Try to detect column names
60
+ if not reader.fieldnames:
61
+ raise ValueError("CSV file has no header row")
62
+
63
+ # Normalize column names to lowercase for easier matching
64
+ fieldnames = [name.lower().strip() for name in reader.fieldnames]
65
+
66
+ # Find required columns
67
+ timestamp_col = None
68
+ id_col = None
69
+ data_col = None
70
+
71
+ for col in fieldnames:
72
+ if "timestamp" in col or col == "time" or col == "t":
73
+ timestamp_col = col
74
+ elif "id" in col or col == "can_id" or col == "arbitration_id":
75
+ id_col = col
76
+ elif "data" in col or col == "payload" or col == "bytes":
77
+ data_col = col
78
+
79
+ if not all([timestamp_col, id_col, data_col]):
80
+ raise ValueError(
81
+ f"CSV file missing required columns. "
82
+ f"Found: {fieldnames}. "
83
+ f"Need: timestamp, id, data"
84
+ )
85
+
86
+ # Parse messages
87
+ for row_dict in reader:
88
+ # Create lowercase dict for case-insensitive access
89
+ row = {k.lower().strip(): v for k, v in row_dict.items()}
90
+
91
+ try:
92
+ # Parse timestamp
93
+ timestamp = float(row[timestamp_col])
94
+
95
+ # Parse ID (handle hex or decimal)
96
+ id_str = row[id_col].strip()
97
+ if id_str.startswith("0x") or id_str.startswith("0X"):
98
+ arb_id = int(id_str, 16)
99
+ else:
100
+ # Try as int first, then hex
101
+ try:
102
+ arb_id = int(id_str)
103
+ except ValueError:
104
+ arb_id = int(id_str, 16)
105
+
106
+ # Parse data bytes
107
+ data_str = row[data_col].strip()
108
+ # Remove common separators and spaces
109
+ data_str = data_str.replace(" ", "").replace(":", "").replace("-", "")
110
+ # Remove 0x prefix if present
111
+ if data_str.startswith("0x") or data_str.startswith("0X"):
112
+ data_str = data_str[2:]
113
+ data_bytes = bytes.fromhex(data_str)
114
+
115
+ # Determine if extended (>11 bits = 0x7FF)
116
+ is_extended = arb_id > 0x7FF
117
+
118
+ # Create message
119
+ can_msg = CANMessage(
120
+ arbitration_id=arb_id,
121
+ timestamp=timestamp,
122
+ data=data_bytes,
123
+ is_extended=is_extended,
124
+ is_fd=False,
125
+ channel=0,
126
+ )
127
+ messages.append(can_msg)
128
+
129
+ except (ValueError, KeyError):
130
+ # Skip malformed rows
131
+ continue
132
+
133
+ except Exception as e:
134
+ raise ValueError(f"Failed to parse CSV file {path}: {e}") from e
135
+
136
+ return messages
@@ -0,0 +1,136 @@
1
+ """Automatic file format detection and loading dispatcher.
2
+
3
+ This module provides automatic detection of automotive log file formats
4
+ and dispatching to the appropriate loader.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from pathlib import Path
10
+ from typing import TYPE_CHECKING
11
+
12
+ if TYPE_CHECKING:
13
+ from oscura.automotive.can.models import CANMessageList
14
+
15
+ __all__ = ["detect_format", "load_automotive_log"]
16
+
17
+
18
+ def detect_format(file_path: Path | str) -> str:
19
+ """Detect automotive log file format.
20
+
21
+ Args:
22
+ file_path: Path to the file.
23
+
24
+ Returns:
25
+ str: Format name: 'blf', 'asc', 'mdf', 'csv', 'pcap', or 'unknown'.
26
+ """
27
+ path = Path(file_path)
28
+
29
+ # Check extension first
30
+ ext = path.suffix.lower()
31
+
32
+ if ext == ".blf":
33
+ return "blf"
34
+ elif ext == ".asc":
35
+ return "asc"
36
+ elif ext in [".mdf", ".mf4", ".dat"]:
37
+ return "mdf"
38
+ elif ext == ".csv":
39
+ return "csv"
40
+ elif ext in [".pcap", ".pcapng"]:
41
+ return "pcap"
42
+
43
+ # If extension is ambiguous, check file contents
44
+ try:
45
+ with open(path, "rb") as f:
46
+ header = f.read(16)
47
+
48
+ # BLF magic: "LOGG"
49
+ if header[:4] == b"LOGG":
50
+ return "blf"
51
+
52
+ # MDF magic: "MDF" or "HDBlock"
53
+ if b"MDF" in header or b"HD" in header[:8]:
54
+ return "mdf"
55
+
56
+ # PCAP magic
57
+ if header[:4] in [b"\xd4\xc3\xb2\xa1", b"\xa1\xb2\xc3\xd4"]:
58
+ return "pcap"
59
+
60
+ except Exception:
61
+ pass
62
+
63
+ # Try as text file
64
+ try:
65
+ with open(path, encoding="utf-8") as f:
66
+ first_line = f.readline().strip()
67
+
68
+ # ASC files typically start with "date" or timestamp
69
+ if first_line.startswith("date") or "CAN" in first_line:
70
+ return "asc"
71
+
72
+ # CSV with CAN data
73
+ if "," in first_line and ("id" in first_line.lower() or "can" in first_line.lower()):
74
+ return "csv"
75
+
76
+ except Exception:
77
+ pass
78
+
79
+ return "unknown"
80
+
81
+
82
+ def load_automotive_log(file_path: Path | str) -> CANMessageList:
83
+ """Load automotive log file, automatically detecting format.
84
+
85
+ This function automatically detects the file format and uses the
86
+ appropriate loader.
87
+
88
+ Args:
89
+ file_path: Path to the automotive log file.
90
+
91
+ Returns:
92
+ CANMessageList containing all parsed messages.
93
+
94
+ Raises:
95
+ FileNotFoundError: If the specified file does not exist.
96
+ ValueError: If file format cannot be determined or is unsupported.
97
+ """
98
+ path = Path(file_path)
99
+
100
+ if not path.exists():
101
+ raise FileNotFoundError(f"File not found: {path}")
102
+
103
+ # Detect format
104
+ fmt = detect_format(path)
105
+
106
+ if fmt == "unknown":
107
+ raise ValueError(f"Unknown or unsupported file format: {path}")
108
+
109
+ # Import and dispatch
110
+ if fmt == "blf":
111
+ from oscura.automotive.loaders.blf import load_blf
112
+
113
+ return load_blf(path)
114
+
115
+ elif fmt == "asc":
116
+ from oscura.automotive.loaders.asc import load_asc
117
+
118
+ return load_asc(path)
119
+
120
+ elif fmt == "mdf":
121
+ from oscura.automotive.loaders.mdf import load_mdf
122
+
123
+ return load_mdf(path)
124
+
125
+ elif fmt == "csv":
126
+ from oscura.automotive.loaders.csv_can import load_csv_can
127
+
128
+ return load_csv_can(path)
129
+
130
+ elif fmt == "pcap":
131
+ from oscura.automotive.loaders.pcap import load_pcap
132
+
133
+ return load_pcap(path)
134
+
135
+ else:
136
+ raise ValueError(f"Unsupported format: {fmt}")