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,372 @@
1
+ """Plugin versioning and migration support.
2
+
3
+ This module provides version compatibility checking, migration support
4
+ between plugin versions, and multi-version compatibility layers.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ import logging
10
+ from dataclasses import dataclass
11
+ from typing import TYPE_CHECKING, Any
12
+
13
+ if TYPE_CHECKING:
14
+ from collections.abc import Callable
15
+
16
+ from oscura.plugins.base import PluginBase
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+
21
+ @dataclass
22
+ class VersionRange:
23
+ """Version range specification.
24
+
25
+ Supports version range syntax:
26
+ - "1.0.0" - exact version
27
+ - ">=1.0.0" - greater than or equal
28
+ - "<2.0.0" - less than
29
+ - "^1.5.0" - compatible with (same major)
30
+ - "~1.5.0" - approximately (same major.minor)
31
+ - "*" - any version
32
+
33
+ References:
34
+ PLUG-005: Plugin Dependencies - version range support
35
+ """
36
+
37
+ spec: str
38
+
39
+ def matches(self, version: str) -> bool:
40
+ """Check if version matches this range.
41
+
42
+ Args:
43
+ version: Version string to check (semver format)
44
+
45
+ Returns:
46
+ True if version matches range
47
+
48
+ References:
49
+ PLUG-005: Plugin Dependencies - version range support
50
+ """
51
+ if self.spec == "*":
52
+ return True
53
+
54
+ # Parse version
55
+ try:
56
+ v_major, v_minor, v_patch = self._parse_version(version)
57
+ except ValueError:
58
+ return False
59
+
60
+ # Handle different operators
61
+ if self.spec.startswith(">="):
62
+ target = self.spec[2:].strip()
63
+ t_major, t_minor, t_patch = self._parse_version(target)
64
+ return (v_major, v_minor, v_patch) >= (t_major, t_minor, t_patch)
65
+
66
+ elif self.spec.startswith("<="):
67
+ target = self.spec[2:].strip()
68
+ t_major, t_minor, t_patch = self._parse_version(target)
69
+ return (v_major, v_minor, v_patch) <= (t_major, t_minor, t_patch)
70
+
71
+ elif self.spec.startswith(">"):
72
+ target = self.spec[1:].strip()
73
+ t_major, t_minor, t_patch = self._parse_version(target)
74
+ return (v_major, v_minor, v_patch) > (t_major, t_minor, t_patch)
75
+
76
+ elif self.spec.startswith("<"):
77
+ target = self.spec[1:].strip()
78
+ t_major, t_minor, t_patch = self._parse_version(target)
79
+ return (v_major, v_minor, v_patch) < (t_major, t_minor, t_patch)
80
+
81
+ elif self.spec.startswith("^"):
82
+ # Compatible: same major version
83
+ target = self.spec[1:].strip()
84
+ t_major, t_minor, t_patch = self._parse_version(target)
85
+ return v_major == t_major and (v_minor, v_patch) >= (t_minor, t_patch)
86
+
87
+ elif self.spec.startswith("~"):
88
+ # Approximately: same major.minor version
89
+ target = self.spec[1:].strip()
90
+ t_major, t_minor, t_patch = self._parse_version(target)
91
+ return v_major == t_major and v_minor == t_minor and v_patch >= t_patch
92
+
93
+ else:
94
+ # Exact match
95
+ return version == self.spec
96
+
97
+ def _parse_version(self, version: str) -> tuple[int, int, int]:
98
+ """Parse semver version string.
99
+
100
+ Args:
101
+ version: Version string (e.g., "1.2.3")
102
+
103
+ Returns:
104
+ Tuple of (major, minor, patch)
105
+
106
+ Raises:
107
+ ValueError: If version format is invalid
108
+ """
109
+ # Handle version with metadata (e.g., "1.2.3-beta+build")
110
+ version = version.split("-")[0].split("+")[0]
111
+
112
+ parts = version.split(".")
113
+ if len(parts) != 3:
114
+ raise ValueError(f"Invalid version format: {version}")
115
+
116
+ try:
117
+ major = int(parts[0])
118
+ minor = int(parts[1])
119
+ patch = int(parts[2])
120
+ return (major, minor, patch)
121
+ except ValueError as e:
122
+ raise ValueError(f"Invalid version format: {version}") from e
123
+
124
+
125
+ @dataclass
126
+ class Migration:
127
+ """Plugin migration definition.
128
+
129
+ Defines migration path from one version to another.
130
+
131
+ Attributes:
132
+ from_version: Source version
133
+ to_version: Target version
134
+ migrate_func: Migration function
135
+ description: Migration description
136
+
137
+ References:
138
+ PLUG-003: Plugin Versioning - migration support
139
+ """
140
+
141
+ from_version: str
142
+ to_version: str
143
+ migrate_func: Callable[[dict[str, Any]], dict[str, Any]]
144
+ description: str = ""
145
+
146
+ def apply(self, config: dict[str, Any]) -> dict[str, Any]:
147
+ """Apply migration to configuration.
148
+
149
+ Args:
150
+ config: Plugin configuration
151
+
152
+ Returns:
153
+ Migrated configuration
154
+
155
+ References:
156
+ PLUG-003: Plugin Versioning - migration support
157
+ """
158
+ logger.info(f"Migrating plugin config from v{self.from_version} to v{self.to_version}")
159
+ return self.migrate_func(config)
160
+
161
+
162
+ class VersionCompatibilityLayer:
163
+ """Multi-version compatibility layer for plugins.
164
+
165
+ Allows plugins to support multiple API versions by adapting
166
+ the interface based on the current Oscura API version.
167
+
168
+ References:
169
+ PLUG-003: Plugin Versioning - multi-version compatibility layer
170
+ """
171
+
172
+ def __init__(self, plugin: PluginBase) -> None:
173
+ """Initialize compatibility layer.
174
+
175
+ Args:
176
+ plugin: Plugin instance to wrap
177
+ """
178
+ self._plugin = plugin
179
+ self._api_version = "1.0.0" # Default
180
+ self._adapters: dict[str, Callable] = {} # type: ignore[type-arg]
181
+
182
+ def set_api_version(self, api_version: str) -> None:
183
+ """Set target API version.
184
+
185
+ Args:
186
+ api_version: Oscura API version
187
+
188
+ References:
189
+ PLUG-003: Plugin Versioning - multi-version compatibility
190
+ """
191
+ self._api_version = api_version
192
+ logger.debug(f"Set API version to {api_version} for plugin {self._plugin.name}")
193
+
194
+ def register_adapter(
195
+ self,
196
+ api_version: str,
197
+ method_name: str,
198
+ adapter: Callable, # type: ignore[type-arg]
199
+ ) -> None:
200
+ """Register method adapter for specific API version.
201
+
202
+ Args:
203
+ api_version: API version this adapter is for
204
+ method_name: Method name to adapt
205
+ adapter: Adapter function
206
+
207
+ References:
208
+ PLUG-003: Plugin Versioning - multi-version compatibility
209
+ """
210
+ key = f"{api_version}:{method_name}"
211
+ self._adapters[key] = adapter
212
+
213
+ def call_adapted(self, method_name: str, *args: Any, **kwargs: Any) -> Any:
214
+ """Call plugin method with version adaptation.
215
+
216
+ Args:
217
+ method_name: Method to call
218
+ *args: Positional arguments
219
+ **kwargs: Keyword arguments
220
+
221
+ Returns:
222
+ Method result
223
+
224
+ References:
225
+ PLUG-003: Plugin Versioning - multi-version compatibility
226
+ """
227
+ key = f"{self._api_version}:{method_name}"
228
+
229
+ if key in self._adapters:
230
+ # Use adapter
231
+ adapter = self._adapters[key]
232
+ return adapter(self._plugin, *args, **kwargs)
233
+ else:
234
+ # Call directly
235
+ method = getattr(self._plugin, method_name)
236
+ return method(*args, **kwargs)
237
+
238
+
239
+ class MigrationManager:
240
+ """Manager for plugin configuration migrations.
241
+
242
+ Tracks and applies migrations between plugin versions.
243
+
244
+ References:
245
+ PLUG-003: Plugin Versioning - migration support
246
+ """
247
+
248
+ def __init__(self) -> None:
249
+ """Initialize migration manager."""
250
+ self._migrations: dict[str, list[Migration]] = {}
251
+
252
+ def register_migration(self, plugin_name: str, migration: Migration) -> None:
253
+ """Register a migration for a plugin.
254
+
255
+ Args:
256
+ plugin_name: Plugin name
257
+ migration: Migration definition
258
+
259
+ References:
260
+ PLUG-003: Plugin Versioning - migration support
261
+ """
262
+ if plugin_name not in self._migrations:
263
+ self._migrations[plugin_name] = []
264
+
265
+ self._migrations[plugin_name].append(migration)
266
+ logger.debug(
267
+ f"Registered migration for {plugin_name}: "
268
+ f"v{migration.from_version} -> v{migration.to_version}"
269
+ )
270
+
271
+ def get_migration_path(
272
+ self,
273
+ plugin_name: str,
274
+ from_version: str,
275
+ to_version: str,
276
+ ) -> list[Migration]:
277
+ """Get migration path between versions.
278
+
279
+ Args:
280
+ plugin_name: Plugin name
281
+ from_version: Source version
282
+ to_version: Target version
283
+
284
+ Returns:
285
+ List of migrations in order
286
+
287
+ Raises:
288
+ ValueError: If no migration path exists
289
+
290
+ References:
291
+ PLUG-003: Plugin Versioning - migration support
292
+ """
293
+ if plugin_name not in self._migrations:
294
+ return []
295
+
296
+ # Simple linear path (could be enhanced with graph search)
297
+ migrations = self._migrations[plugin_name]
298
+ path: list[Migration] = []
299
+
300
+ current = from_version
301
+ while current != to_version:
302
+ # Find next migration
303
+ next_migration = None
304
+ for migration in migrations:
305
+ if migration.from_version == current:
306
+ next_migration = migration
307
+ break
308
+
309
+ if next_migration is None:
310
+ raise ValueError(f"No migration path from v{from_version} to v{to_version}")
311
+
312
+ path.append(next_migration)
313
+ current = next_migration.to_version
314
+
315
+ return path
316
+
317
+ def migrate(
318
+ self,
319
+ plugin_name: str,
320
+ config: dict[str, Any],
321
+ from_version: str,
322
+ to_version: str,
323
+ ) -> dict[str, Any]:
324
+ """Migrate configuration between versions.
325
+
326
+ Args:
327
+ plugin_name: Plugin name
328
+ config: Current configuration
329
+ from_version: Source version
330
+ to_version: Target version
331
+
332
+ Returns:
333
+ Migrated configuration
334
+
335
+ References:
336
+ PLUG-003: Plugin Versioning - migration support
337
+ """
338
+ if from_version == to_version:
339
+ return config
340
+
341
+ path = self.get_migration_path(plugin_name, from_version, to_version)
342
+
343
+ result = config
344
+ for migration in path:
345
+ result = migration.apply(result)
346
+
347
+ return result
348
+
349
+
350
+ # Global migration manager
351
+ _migration_manager: MigrationManager | None = None
352
+
353
+
354
+ def get_migration_manager() -> MigrationManager:
355
+ """Get global migration manager.
356
+
357
+ Returns:
358
+ Global MigrationManager instance
359
+ """
360
+ global _migration_manager
361
+ if _migration_manager is None:
362
+ _migration_manager = MigrationManager()
363
+ return _migration_manager
364
+
365
+
366
+ __all__ = [
367
+ "Migration",
368
+ "MigrationManager",
369
+ "VersionCompatibilityLayer",
370
+ "VersionRange",
371
+ "get_migration_manager",
372
+ ]
oscura/py.typed ADDED
File without changes
@@ -0,0 +1,65 @@
1
+ """Signal quality analysis module for Oscura."""
2
+
3
+ from oscura.quality.ensemble import (
4
+ AMPLITUDE_ENSEMBLE,
5
+ EDGE_DETECTION_ENSEMBLE,
6
+ FREQUENCY_ENSEMBLE,
7
+ AggregationMethod,
8
+ EnsembleAggregator,
9
+ EnsembleResult,
10
+ create_edge_ensemble,
11
+ create_frequency_ensemble,
12
+ )
13
+ from oscura.quality.explainer import (
14
+ ResultExplainer,
15
+ ResultExplanation,
16
+ explain_result,
17
+ )
18
+ from oscura.quality.scoring import (
19
+ AnalysisQualityScore,
20
+ DataQualityMetrics,
21
+ ReliabilityCategory,
22
+ assess_data_quality,
23
+ calculate_quality_score,
24
+ combine_quality_scores,
25
+ score_analysis_result,
26
+ )
27
+ from oscura.quality.warnings import (
28
+ QualityWarning,
29
+ SignalQualityAnalyzer,
30
+ check_clipping,
31
+ check_noise,
32
+ check_saturation,
33
+ check_undersampling,
34
+ )
35
+
36
+ __all__ = [
37
+ # Ensemble methods
38
+ "AMPLITUDE_ENSEMBLE",
39
+ "EDGE_DETECTION_ENSEMBLE",
40
+ "FREQUENCY_ENSEMBLE",
41
+ "AggregationMethod",
42
+ # Scoring
43
+ "AnalysisQualityScore",
44
+ "DataQualityMetrics",
45
+ "EnsembleAggregator",
46
+ "EnsembleResult",
47
+ # Warnings
48
+ "QualityWarning",
49
+ "ReliabilityCategory",
50
+ "ResultExplainer",
51
+ # Explainability
52
+ "ResultExplanation",
53
+ "SignalQualityAnalyzer",
54
+ "assess_data_quality",
55
+ "calculate_quality_score",
56
+ "check_clipping",
57
+ "check_noise",
58
+ "check_saturation",
59
+ "check_undersampling",
60
+ "combine_quality_scores",
61
+ "create_edge_ensemble",
62
+ "create_frequency_ensemble",
63
+ "explain_result",
64
+ "score_analysis_result",
65
+ ]