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,680 @@
1
+ """Professional formatting standards and visual emphasis for reports.
2
+
3
+ This module provides professional formatting standards, visual emphasis
4
+ systems, and executive summary generation for Oscura reports.
5
+
6
+
7
+ Example:
8
+ >>> from oscura.reporting.standards import FormatStandards, VisualEmphasis
9
+ >>> standards = FormatStandards()
10
+ >>> emphasis = VisualEmphasis()
11
+ >>> formatted_text = emphasis.format_pass_fail(True)
12
+
13
+ References:
14
+ REPORT-001, REPORT-002,
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ from dataclasses import dataclass, field
20
+ from enum import Enum
21
+ from typing import Any, Literal
22
+
23
+
24
+ class Severity(Enum):
25
+ """Severity levels for findings and violations."""
26
+
27
+ CRITICAL = "critical"
28
+ WARNING = "warning"
29
+ INFO = "info"
30
+
31
+
32
+ class ColorScheme(Enum):
33
+ """Available colorblind-safe color schemes."""
34
+
35
+ VIRIDIS = "viridis"
36
+ CIVIDIS = "cividis"
37
+ PLASMA = "plasma"
38
+ INFERNO = "inferno"
39
+ OKABE_ITO = "okabe_ito" # Colorblind-safe palette
40
+
41
+
42
+ @dataclass
43
+ class FormatStandards:
44
+ """Professional formatting standards configuration.
45
+
46
+ Defines typography, page layout, color schemes, and section hierarchy
47
+ for professional report output.
48
+
49
+ Attributes:
50
+ heading_font: Font family for headings.
51
+ body_font: Font family for body text.
52
+ code_font: Font family for code and data.
53
+ page_size: Page size (letter or A4).
54
+ margins_inches: Page margins in inches.
55
+ color_scheme: Colorblind-safe color palette.
56
+ line_spacing: Line spacing multiplier.
57
+ logo_max_height_inches: Maximum logo height.
58
+ watermark_opacity: Watermark opacity (0.0-1.0).
59
+
60
+ References:
61
+ REPORT-001: Professional Formatting Standards
62
+ """
63
+
64
+ heading_font: str = "Arial, Helvetica, sans-serif"
65
+ body_font: str = "Georgia, Times New Roman, serif"
66
+ code_font: str = "Consolas, Courier New, monospace"
67
+ page_size: Literal["letter", "A4"] = "letter"
68
+ margins_inches: float = 1.0
69
+ color_scheme: ColorScheme = ColorScheme.VIRIDIS
70
+ line_spacing: float = 1.5
71
+ logo_max_height_inches: float = 2.0
72
+ watermark_opacity: float = 0.3
73
+
74
+ # Font sizes in points
75
+ title_size: int = 24
76
+ h1_size: int = 18
77
+ h2_size: int = 14
78
+ h3_size: int = 12
79
+ body_size: int = 10
80
+
81
+ def to_css(self) -> str:
82
+ """Generate CSS stylesheet from format standards.
83
+
84
+ Returns:
85
+ CSS stylesheet string.
86
+
87
+ References:
88
+ REPORT-001: Professional Formatting Standards
89
+ """
90
+ return f"""
91
+ /* Oscura Professional Report Styles - REPORT-001 */
92
+ :root {{
93
+ --heading-font: {self.heading_font};
94
+ --body-font: {self.body_font};
95
+ --code-font: {self.code_font};
96
+ --title-size: {self.title_size}pt;
97
+ --h1-size: {self.h1_size}pt;
98
+ --h2-size: {self.h2_size}pt;
99
+ --h3-size: {self.h3_size}pt;
100
+ --body-size: {self.body_size}pt;
101
+ --line-spacing: {self.line_spacing};
102
+ --margin: {self.margins_inches}in;
103
+
104
+ /* Colorblind-safe palette */
105
+ --color-pass: #2e7d32;
106
+ --color-fail: #c62828;
107
+ --color-warning: #f57c00;
108
+ --color-info: #1565c0;
109
+ --color-critical-bg: #ffebee;
110
+ --color-warning-bg: #fff3e0;
111
+ --color-info-bg: #e3f2fd;
112
+ }}
113
+
114
+ body {{
115
+ font-family: var(--body-font);
116
+ font-size: var(--body-size);
117
+ line-height: var(--line-spacing);
118
+ margin: var(--margin);
119
+ max-width: 8.5in;
120
+ color: #333;
121
+ }}
122
+
123
+ h1, h2, h3, h4 {{
124
+ font-family: var(--heading-font);
125
+ line-height: 1.2;
126
+ margin-top: 1.5em;
127
+ margin-bottom: 0.5em;
128
+ }}
129
+
130
+ h1 {{ font-size: var(--h1-size); }}
131
+ h2 {{ font-size: var(--h2-size); }}
132
+ h3 {{ font-size: var(--h3-size); }}
133
+
134
+ .report-title {{
135
+ font-size: var(--title-size);
136
+ text-align: center;
137
+ margin-bottom: 2em;
138
+ }}
139
+
140
+ code, pre {{
141
+ font-family: var(--code-font);
142
+ font-size: 0.9em;
143
+ background-color: #f5f5f5;
144
+ padding: 2px 4px;
145
+ border-radius: 3px;
146
+ }}
147
+
148
+ /* Table styles */
149
+ table {{
150
+ border-collapse: collapse;
151
+ width: 100%;
152
+ margin: 1em 0;
153
+ }}
154
+
155
+ th, td {{
156
+ border: 1px solid #ddd;
157
+ padding: 8px;
158
+ text-align: left;
159
+ }}
160
+
161
+ th {{
162
+ background-color: #f2f2f2;
163
+ font-weight: bold;
164
+ }}
165
+
166
+ tr:nth-child(even) {{
167
+ background-color: #f9f9f9;
168
+ }}
169
+
170
+ /* Pass/Fail indicators (REPORT-002) */
171
+ .pass {{
172
+ color: var(--color-pass);
173
+ }}
174
+
175
+ .fail {{
176
+ color: var(--color-fail);
177
+ }}
178
+
179
+ .warning {{
180
+ color: var(--color-warning);
181
+ }}
182
+
183
+ /* Severity indicators (REPORT-002) */
184
+ .severity-critical {{
185
+ background-color: var(--color-critical-bg);
186
+ border-left: 4px solid var(--color-fail);
187
+ padding: 10px;
188
+ margin: 10px 0;
189
+ }}
190
+
191
+ .severity-warning {{
192
+ background-color: var(--color-warning-bg);
193
+ border-left: 4px solid var(--color-warning);
194
+ padding: 10px;
195
+ margin: 10px 0;
196
+ }}
197
+
198
+ .severity-info {{
199
+ background-color: var(--color-info-bg);
200
+ border-left: 4px solid var(--color-info);
201
+ padding: 10px;
202
+ margin: 10px 0;
203
+ }}
204
+
205
+ /* Callout box (REPORT-002) */
206
+ .callout {{
207
+ border: 1px solid #ddd;
208
+ border-radius: 4px;
209
+ padding: 15px;
210
+ margin: 15px 0;
211
+ background-color: #fafafa;
212
+ }}
213
+
214
+ .callout.key-finding {{
215
+ border-color: var(--color-info);
216
+ background-color: var(--color-info-bg);
217
+ }}
218
+
219
+ /* Highlighting for out-of-spec values */
220
+ .out-of-spec {{
221
+ background-color: rgba(255, 235, 59, 0.15);
222
+ padding: 2px 4px;
223
+ border-radius: 2px;
224
+ }}
225
+
226
+ /* Executive summary styles (REPORT-004) */
227
+ .executive-summary {{
228
+ background-color: #f5f5f5;
229
+ padding: 20px;
230
+ margin: 20px 0;
231
+ border-radius: 4px;
232
+ }}
233
+
234
+ .executive-summary h2 {{
235
+ margin-top: 0;
236
+ }}
237
+
238
+ .key-findings {{
239
+ list-style-type: none;
240
+ padding-left: 0;
241
+ }}
242
+
243
+ .key-findings li {{
244
+ padding: 5px 0;
245
+ padding-left: 25px;
246
+ position: relative;
247
+ }}
248
+
249
+ .key-findings li::before {{
250
+ content: "";
251
+ position: absolute;
252
+ left: 0;
253
+ top: 8px;
254
+ width: 16px;
255
+ height: 16px;
256
+ }}
257
+
258
+ .key-findings li.critical::before {{
259
+ content: "!";
260
+ color: var(--color-fail);
261
+ font-weight: bold;
262
+ }}
263
+
264
+ /* Watermark */
265
+ .watermark {{
266
+ position: fixed;
267
+ top: 50%;
268
+ left: 50%;
269
+ transform: translate(-50%, -50%) rotate(-45deg);
270
+ font-size: 72pt;
271
+ color: rgba(0, 0, 0, {self.watermark_opacity});
272
+ pointer-events: none;
273
+ z-index: 1000;
274
+ }}
275
+
276
+ /* Print styles */
277
+ @media print {{
278
+ body {{
279
+ margin: 0;
280
+ }}
281
+ .page-break {{
282
+ page-break-before: always;
283
+ }}
284
+ .no-print {{
285
+ display: none;
286
+ }}
287
+ }}
288
+ """
289
+
290
+
291
+ @dataclass
292
+ class VisualEmphasis:
293
+ """Visual emphasis system for pass/fail indicators and severity levels.
294
+
295
+ Provides WCAG-compliant visual indicators using both symbols and colors
296
+ for accessibility.
297
+
298
+ Attributes:
299
+ use_unicode_symbols: Use Unicode check/X marks.
300
+ colorblind_safe: Always use symbols + colors (never color alone).
301
+ highlight_violations: Highlight out-of-spec values.
302
+ severity_icons: Show icons for severity levels.
303
+
304
+ References:
305
+ REPORT-002: Visual Emphasis System
306
+ """
307
+
308
+ use_unicode_symbols: bool = True
309
+ colorblind_safe: bool = True
310
+ highlight_violations: bool = True
311
+ severity_icons: bool = True
312
+
313
+ # Unicode symbols for status indicators
314
+ CHECK_SYMBOL = "\u2713" # Check mark
315
+ CROSS_SYMBOL = "\u2717" # X mark
316
+ WARNING_SYMBOL = "\u26a0" # Warning triangle
317
+ INFO_SYMBOL = "\u2139" # Info circle
318
+ CRITICAL_SYMBOL = "\u2757" # Exclamation mark
319
+
320
+ def format_pass_fail(
321
+ self,
322
+ passed: bool,
323
+ *,
324
+ with_text: bool = True,
325
+ html: bool = False,
326
+ ) -> str:
327
+ """Format pass/fail status with visual emphasis.
328
+
329
+ Args:
330
+ passed: Whether the test passed.
331
+ with_text: Include PASS/FAIL text.
332
+ html: Output as HTML with styling.
333
+
334
+ Returns:
335
+ Formatted status string.
336
+
337
+ References:
338
+ REPORT-002: Visual Emphasis System
339
+ """
340
+ if passed:
341
+ symbol = self.CHECK_SYMBOL if self.use_unicode_symbols else "[PASS]"
342
+ text = "PASS" if with_text else ""
343
+ css_class = "pass"
344
+ else:
345
+ symbol = self.CROSS_SYMBOL if self.use_unicode_symbols else "[FAIL]"
346
+ text = "FAIL" if with_text else ""
347
+ css_class = "fail"
348
+
349
+ result = f"{symbol} {text}".strip() if with_text else symbol
350
+
351
+ if html:
352
+ return f'<span class="{css_class}">{result}</span>'
353
+ return result
354
+
355
+ def format_severity(
356
+ self,
357
+ severity: Severity | str,
358
+ message: str,
359
+ *,
360
+ html: bool = False,
361
+ ) -> str:
362
+ """Format message with severity indicator.
363
+
364
+ Args:
365
+ severity: Severity level.
366
+ message: Message text.
367
+ html: Output as HTML with styling.
368
+
369
+ Returns:
370
+ Formatted message string.
371
+
372
+ References:
373
+ REPORT-002: Visual Emphasis System
374
+ """
375
+ if isinstance(severity, str):
376
+ severity = Severity(severity.lower())
377
+
378
+ if severity == Severity.CRITICAL:
379
+ symbol = self.CRITICAL_SYMBOL if self.severity_icons else ""
380
+ css_class = "severity-critical"
381
+ elif severity == Severity.WARNING:
382
+ symbol = self.WARNING_SYMBOL if self.severity_icons else ""
383
+ css_class = "severity-warning"
384
+ else:
385
+ symbol = self.INFO_SYMBOL if self.severity_icons else ""
386
+ css_class = "severity-info"
387
+
388
+ text = f"{symbol} {message}".strip() if symbol else message
389
+
390
+ if html:
391
+ return f'<div class="{css_class}">{text}</div>'
392
+ return text
393
+
394
+ def format_margin(
395
+ self,
396
+ value: float,
397
+ limit: float,
398
+ *,
399
+ limit_type: Literal["upper", "lower"] = "upper",
400
+ html: bool = False,
401
+ ) -> str:
402
+ """Format margin with color-coded indicator.
403
+
404
+ Color coding:
405
+ - Green: margin > 20%
406
+ - Yellow: 10% < margin <= 20%
407
+ - Red: margin <= 10%
408
+
409
+ Args:
410
+ value: Measured value.
411
+ limit: Limit value.
412
+ limit_type: Whether limit is upper or lower bound.
413
+ html: Output as HTML with styling.
414
+
415
+ Returns:
416
+ Formatted margin string.
417
+
418
+ References:
419
+ REPORT-002: Visual Emphasis System
420
+ """
421
+ if limit_type == "upper":
422
+ margin = limit - value
423
+ margin_pct = (margin / limit * 100) if limit != 0 else 0
424
+ else:
425
+ margin = value - limit
426
+ margin_pct = (margin / limit * 100) if limit != 0 else 0
427
+
428
+ # Determine status
429
+ if margin_pct > 20:
430
+ status = "good"
431
+ css_class = "pass"
432
+ symbol = self.PASS_SYMBOL # type: ignore[attr-defined]
433
+ elif margin_pct > 10:
434
+ status = "marginal"
435
+ css_class = "warning"
436
+ symbol = self.WARNING_SYMBOL
437
+ elif margin_pct > 0:
438
+ status = "tight"
439
+ css_class = "warning"
440
+ symbol = self.WARNING_SYMBOL
441
+ else:
442
+ status = "violation"
443
+ css_class = "fail"
444
+ symbol = self.CROSS_SYMBOL
445
+
446
+ text = f"{symbol} margin: {margin_pct:.1f}% ({status})"
447
+
448
+ if html:
449
+ return f'<span class="{css_class}">{text}</span>'
450
+ return text
451
+
452
+ def create_callout_box(
453
+ self,
454
+ title: str,
455
+ content: str,
456
+ *,
457
+ is_key_finding: bool = False,
458
+ ) -> str:
459
+ """Create a callout box for key findings.
460
+
461
+ Args:
462
+ title: Box title.
463
+ content: Box content.
464
+ is_key_finding: Style as key finding.
465
+
466
+ Returns:
467
+ HTML callout box string.
468
+
469
+ References:
470
+ REPORT-002: Visual Emphasis System
471
+ """
472
+ css_class = "callout key-finding" if is_key_finding else "callout"
473
+ return f"""<div class="{css_class}">
474
+ <h4>{title}</h4>
475
+ <p>{content}</p>
476
+ </div>"""
477
+
478
+
479
+ @dataclass
480
+ class ExecutiveSummary:
481
+ """Executive summary of analysis results.
482
+
483
+ Attributes:
484
+ overall_status: Pass/fail status.
485
+ pass_count: Number of passing tests.
486
+ total_count: Total number of tests.
487
+ key_findings: List of key findings.
488
+ critical_violations: List of critical violations.
489
+ min_margin_pct: Minimum margin percentage.
490
+ summary_text: Generated summary text.
491
+
492
+ References:
493
+ REPORT-004: Executive Summary Auto-Generation
494
+ """
495
+
496
+ overall_status: bool
497
+ pass_count: int
498
+ total_count: int
499
+ key_findings: list[str] = field(default_factory=list)
500
+ critical_violations: list[str] = field(default_factory=list)
501
+ min_margin_pct: float | None = None
502
+ summary_text: str = ""
503
+
504
+
505
+ def _extract_key_findings(
506
+ results: dict[str, Any],
507
+ critical_violations: list[Any],
508
+ max_findings: int,
509
+ ) -> tuple[list[str], float | None]:
510
+ """Extract key findings from results."""
511
+ key_findings: list[str] = []
512
+ violations = results.get("violations", [])
513
+
514
+ # Add violation summary
515
+ if critical_violations:
516
+ key_findings.append(
517
+ f"{len(critical_violations)} critical violation(s) require immediate attention"
518
+ )
519
+ elif violations:
520
+ key_findings.append(f"{len(violations)} violation(s) detected")
521
+
522
+ # Add margin information
523
+ margins = results.get("margins", [])
524
+ min_margin = min(margins) if margins else results.get("min_margin")
525
+
526
+ if min_margin is not None and min_margin < 20:
527
+ status = "critical" if min_margin < 10 else "marginal"
528
+ key_findings.append(f"Minimum margin is {min_margin:.1f}% ({status})")
529
+
530
+ # Extract from failed measurements
531
+ for name, meas in results.get("measurements", {}).items():
532
+ if not meas.get("passed", True):
533
+ key_findings.append(f"{name}: FAIL - {meas.get('message', 'violation')}")
534
+
535
+ return key_findings[:max_findings], min_margin
536
+
537
+
538
+ def _build_summary_text(
539
+ overall_status: bool,
540
+ total_count: int,
541
+ fail_count: int,
542
+ critical_violations: list[Any],
543
+ min_margin: float | None,
544
+ key_findings: list[str],
545
+ length: str,
546
+ ) -> str:
547
+ """Build the summary text."""
548
+ parts: list[str] = []
549
+ pass_count = total_count - fail_count
550
+
551
+ # First sentence: overall status
552
+ if overall_status and total_count > 0:
553
+ parts.append(f"All {pass_count} tests passed.")
554
+ elif overall_status:
555
+ parts.append("Analysis completed successfully.")
556
+ elif total_count > 0:
557
+ pct = fail_count / total_count * 100
558
+ parts.append(f"{fail_count} of {total_count} tests failed ({pct:.0f}% failure rate).")
559
+ else:
560
+ parts.append("Analysis completed with failures.")
561
+
562
+ # Add critical violations
563
+ if critical_violations:
564
+ parts.append(f"Critical: {len(critical_violations)} violation(s) require immediate action.")
565
+
566
+ # Add margin note
567
+ if min_margin is not None and min_margin < 10:
568
+ parts.append(f"Warning: Minimum margin is only {min_margin:.1f}%.")
569
+
570
+ # Key findings (for detailed mode)
571
+ if length == "detailed" and key_findings:
572
+ parts.append("\nKey Findings:")
573
+ parts.extend(f" - {finding}" for finding in key_findings)
574
+
575
+ return " ".join(parts)
576
+
577
+
578
+ def generate_executive_summary(
579
+ results: dict[str, Any],
580
+ *,
581
+ max_findings: int = 5,
582
+ length: Literal["short", "detailed"] = "short",
583
+ ) -> ExecutiveSummary:
584
+ """Generate executive summary from analysis results.
585
+
586
+ Automatically extracts key findings, pass/fail status, and critical
587
+ violations from analysis results.
588
+
589
+ Args:
590
+ results: Analysis results dictionary.
591
+ max_findings: Maximum number of key findings to include.
592
+ length: Summary length (short = 1 paragraph, detailed = 1 page).
593
+
594
+ Returns:
595
+ ExecutiveSummary with generated content.
596
+
597
+ Example:
598
+ >>> results = {"pass_count": 10, "total_count": 12, "violations": [...]}
599
+ >>> summary = generate_executive_summary(results)
600
+ >>> print(summary.summary_text)
601
+
602
+ References:
603
+ REPORT-004: Executive Summary Auto-Generation
604
+ """
605
+ # Extract basic counts
606
+ pass_count = results.get("pass_count", 0)
607
+ total_count = results.get("total_count", 0)
608
+ fail_count = total_count - pass_count if total_count else 0
609
+ overall_status = fail_count == 0
610
+
611
+ # Extract violations
612
+ violations = results.get("violations", [])
613
+ critical_violations = [v for v in violations if v.get("severity", "").lower() == "critical"]
614
+
615
+ # Extract key findings
616
+ key_findings, min_margin = _extract_key_findings(results, critical_violations, max_findings)
617
+
618
+ # Generate summary text
619
+ summary_text = _build_summary_text(
620
+ overall_status,
621
+ total_count,
622
+ fail_count,
623
+ critical_violations,
624
+ min_margin,
625
+ key_findings,
626
+ length,
627
+ )
628
+
629
+ return ExecutiveSummary(
630
+ overall_status=overall_status,
631
+ pass_count=pass_count,
632
+ total_count=total_count,
633
+ key_findings=key_findings,
634
+ critical_violations=[str(v) for v in critical_violations],
635
+ min_margin_pct=min_margin,
636
+ summary_text=summary_text,
637
+ )
638
+
639
+
640
+ def format_executive_summary_html(summary: ExecutiveSummary) -> str:
641
+ """Format executive summary as HTML.
642
+
643
+ Args:
644
+ summary: ExecutiveSummary to format.
645
+
646
+ Returns:
647
+ HTML string.
648
+
649
+ References:
650
+ REPORT-004: Executive Summary Auto-Generation
651
+ """
652
+ emphasis = VisualEmphasis()
653
+
654
+ status_html = emphasis.format_pass_fail(summary.overall_status, html=True)
655
+
656
+ findings_html = ""
657
+ if summary.key_findings:
658
+ items = []
659
+ for finding in summary.key_findings:
660
+ css_class = "critical" if "critical" in finding.lower() else ""
661
+ items.append(f'<li class="{css_class}">{finding}</li>')
662
+ findings_html = f'<ul class="key-findings">{"".join(items)}</ul>'
663
+
664
+ return f"""<div class="executive-summary">
665
+ <h2>Executive Summary</h2>
666
+ <p><strong>Overall Status:</strong> {status_html}</p>
667
+ <p>{summary.summary_text}</p>
668
+ {findings_html}
669
+ </div>"""
670
+
671
+
672
+ __all__ = [
673
+ "ColorScheme",
674
+ "ExecutiveSummary",
675
+ "FormatStandards",
676
+ "Severity",
677
+ "VisualEmphasis",
678
+ "format_executive_summary_html",
679
+ "generate_executive_summary",
680
+ ]