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,615 @@
1
+ """Configuration for comprehensive analysis report system.
2
+
3
+ This module defines the simplified configuration schema for the comprehensive
4
+ analysis report generator, combining input/output/analysis specs into a single
5
+ unified configuration.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from collections.abc import Callable
11
+ from dataclasses import dataclass, field
12
+ from enum import Enum
13
+ from pathlib import Path
14
+ from typing import Any
15
+
16
+
17
+ class InputType(str, Enum):
18
+ """Supported input data types."""
19
+
20
+ WAVEFORM = "waveform" # Analog waveform (WFM, CSV, NPZ, HDF5)
21
+ DIGITAL = "digital" # Digital logic signals
22
+ BINARY = "binary" # Binary packet data
23
+ PCAP = "pcap" # Network capture
24
+ IQ = "iq" # I/Q baseband data
25
+ PACKETS = "packets" # Pre-parsed packets
26
+ SPARAMS = "sparams" # S-parameter/Touchstone data (.s1p-.s8p)
27
+
28
+
29
+ class AnalysisDomain(str, Enum):
30
+ """Analysis domain categories."""
31
+
32
+ WAVEFORM = "waveform" # Basic waveform measurements
33
+ DIGITAL = "digital" # Digital signal analysis
34
+ TIMING = "timing" # Timing measurements
35
+ SPECTRAL = "spectral" # FFT, PSD, THD, SNR
36
+ STATISTICS = "statistics" # Statistical analysis
37
+ PATTERNS = "patterns" # Pattern detection
38
+ JITTER = "jitter" # Jitter decomposition
39
+ EYE = "eye" # Eye diagram analysis
40
+ POWER = "power" # Power analysis
41
+ PROTOCOLS = "protocols" # Protocol decoding
42
+ SIGNAL_INTEGRITY = "signal_integrity" # S-params, equalization
43
+ INFERENCE = "inference" # Auto-inference
44
+ PACKET = "packet" # Packet metrics
45
+ ENTROPY = "entropy" # Entropy analysis
46
+
47
+
48
+ @dataclass
49
+ class DomainConfig:
50
+ """Configuration for a single analysis domain.
51
+
52
+ Attributes:
53
+ enabled: Whether to run this analysis domain.
54
+ parameters: Domain-specific parameters passed to analyzers.
55
+ timeout: Timeout in seconds for this domain (None = use global timeout).
56
+ """
57
+
58
+ enabled: bool = True
59
+ parameters: dict[str, Any] = field(default_factory=dict)
60
+ timeout: float | None = None
61
+
62
+
63
+ @dataclass
64
+ class DataOutputConfig:
65
+ """Configuration for data output limits and aggregation.
66
+
67
+ Controls how data is serialized in reports - whether to truncate,
68
+ aggregate similar values, or output complete data.
69
+
70
+ Attributes:
71
+ full_data_mode: If True, output ALL data without truncation.
72
+ max_array_elements: Max array elements (None = unlimited). Ignored if full_data_mode=True.
73
+ max_list_items: Max list items (None = unlimited). Ignored if full_data_mode=True.
74
+ max_bytes_sample: Max bytes to include (None = unlimited). Ignored if full_data_mode=True.
75
+ max_pdf_results_per_domain: Max results per domain in PDF (None = unlimited).
76
+ max_pdf_summary_length: Max summary string length in PDF (None = unlimited).
77
+ smart_aggregation: Enable smart aggregation of repeated/similar values.
78
+ aggregation_threshold: Min identical values to trigger aggregation (default: 5).
79
+ """
80
+
81
+ full_data_mode: bool = True # Default to full data - no truncation
82
+ max_array_elements: int | None = None # None = unlimited
83
+ max_list_items: int | None = None # None = unlimited
84
+ max_bytes_sample: int | None = None # None = unlimited
85
+ max_pdf_results_per_domain: int | None = None # None = unlimited
86
+ max_pdf_summary_length: int | None = None # None = unlimited
87
+ smart_aggregation: bool = True # Enable smart aggregation by default
88
+ aggregation_threshold: int = 5 # Min identical values to trigger aggregation
89
+
90
+
91
+ # Default sample rates for different analysis contexts
92
+ # These are used when sample_rate cannot be derived from input data
93
+ DEFAULT_SAMPLE_RATE_HZ: float = 1e9 # 1 GHz - high-speed digital/eye diagram
94
+ DEFAULT_SAMPLE_RATE_GENERAL_HZ: float = 1e6 # 1 MHz - general waveform analysis
95
+ DEFAULT_SAMPLE_RATE_BINARY_HZ: float = 1.0 # 1 Hz (1 sample/s) - binary data
96
+
97
+
98
+ @dataclass
99
+ class AnalysisConfig:
100
+ """Unified configuration for comprehensive analysis.
101
+
102
+ Combines input specification, analysis selection, and output options
103
+ into a single simplified configuration.
104
+
105
+ Attributes:
106
+ domains: List of domains to analyze (None = all applicable domains).
107
+ exclude_domains: Domains to explicitly exclude.
108
+ domain_config: Per-domain configuration overrides.
109
+ output_formats: Output formats to generate (e.g., ["json", "yaml"]).
110
+ index_formats: Index formats to generate (e.g., ["html", "md"]).
111
+ generate_plots: Whether to generate visualization plots.
112
+ plot_format: Plot file format (png, svg, pdf).
113
+ plot_dpi: Plot resolution in DPI.
114
+ copy_input_file: Copy input file to output directory.
115
+ save_intermediate_data: Save intermediate analysis data.
116
+ full_data_mode: Output all data without truncation.
117
+ smart_aggregation: Enable smart aggregation of repeated values.
118
+ data_output: Advanced data output configuration.
119
+ timeout_per_analysis: Timeout per analysis function in seconds (None = no timeout).
120
+ continue_on_error: Continue analysis if individual functions fail.
121
+ log_level: Logging level (DEBUG, INFO, WARNING, ERROR).
122
+ parallel_domains: Enable parallel domain execution.
123
+ enable_quality_scoring: Attach quality scores to analysis results.
124
+ max_memory_mb: Maximum memory per analysis in MB (None = auto-detect).
125
+ max_cache_entries: Maximum cached results (prevents cache bloat).
126
+ max_parallel_workers: Maximum parallel threads for analysis.
127
+ chunk_size_mb: Maximum chunk size for large data processing in MB.
128
+ default_sample_rate: Default sample rate (Hz) when not derivable from data.
129
+ Used for analysis functions requiring sample_rate parameter.
130
+ Set to None to require explicit sample_rate in input data.
131
+ title: Report title.
132
+ author: Report author.
133
+ project: Project name.
134
+ notes: Additional notes/description.
135
+ custom_metadata: Custom metadata fields.
136
+ """
137
+
138
+ # Analysis selection
139
+ domains: list[AnalysisDomain] | None = None # None = all applicable
140
+ exclude_domains: list[AnalysisDomain] = field(default_factory=list)
141
+ domain_config: dict[AnalysisDomain, DomainConfig] = field(default_factory=dict)
142
+
143
+ # Output formats
144
+ output_formats: list[str] = field(default_factory=lambda: ["json", "yaml"])
145
+ index_formats: list[str] = field(default_factory=lambda: ["html", "md"])
146
+
147
+ # Visualization
148
+ generate_plots: bool = True
149
+ plot_format: str = "png"
150
+ plot_dpi: int = 150
151
+
152
+ # Data handling
153
+ copy_input_file: bool = False
154
+ save_intermediate_data: bool = True
155
+ full_data_mode: bool = True
156
+ smart_aggregation: bool = True
157
+ data_output: DataOutputConfig = field(default_factory=DataOutputConfig)
158
+
159
+ # Execution control
160
+ timeout_per_analysis: float | None = 30.0
161
+ continue_on_error: bool = True
162
+ log_level: str = "INFO"
163
+ parallel_domains: bool = True # Enable parallel domain execution
164
+ enable_quality_scoring: bool = True # Attach quality scores to analysis results
165
+
166
+ # Resource limits (MEM-010, MEM-015)
167
+ max_memory_mb: int = 2048 # Max memory per analysis (MB)
168
+ max_cache_entries: int = 100 # Max cached results
169
+ max_parallel_workers: int = 4 # Max parallel threads
170
+ chunk_size_mb: int = 100 # Max chunk size for large data
171
+
172
+ # Sample rate configuration
173
+ # Default sample rate used when not available in input data metadata.
174
+ # This is a fallback; sample_rate is preferably derived from:
175
+ # 1. Input data metadata (e.g., WaveformTrace.metadata.sample_rate)
176
+ # 2. Explicit parameter in domain_config
177
+ # 3. This default value
178
+ default_sample_rate: float | None = DEFAULT_SAMPLE_RATE_GENERAL_HZ
179
+
180
+ # Metadata
181
+ title: str = ""
182
+ author: str = ""
183
+ project: str = ""
184
+ notes: str = ""
185
+ custom_metadata: dict[str, Any] = field(default_factory=dict)
186
+
187
+ def get_domain_config(self, domain: AnalysisDomain) -> DomainConfig:
188
+ """Get configuration for a specific domain.
189
+
190
+ Args:
191
+ domain: Analysis domain to get configuration for.
192
+
193
+ Returns:
194
+ Domain configuration (default if not specified).
195
+ """
196
+ return self.domain_config.get(domain, DomainConfig())
197
+
198
+ def is_domain_enabled(self, domain: AnalysisDomain) -> bool:
199
+ """Check if a domain is enabled.
200
+
201
+ Args:
202
+ domain: Analysis domain to check.
203
+
204
+ Returns:
205
+ True if domain should be analyzed.
206
+ """
207
+ # Check explicit exclusion
208
+ if domain in self.exclude_domains:
209
+ return False
210
+
211
+ # Check domain-specific config
212
+ if domain in self.domain_config:
213
+ return self.domain_config[domain].enabled
214
+
215
+ # If domains list specified, check membership
216
+ if self.domains is not None:
217
+ return domain in self.domains
218
+
219
+ # Otherwise enabled by default
220
+ return True
221
+
222
+ def get_effective_sample_rate(
223
+ self, data_sample_rate: float | None = None, context: str = "general"
224
+ ) -> float:
225
+ """Get effective sample rate, preferring data metadata over defaults.
226
+
227
+ Priority order:
228
+ 1. data_sample_rate (from input data metadata)
229
+ 2. self.default_sample_rate (from config)
230
+ 3. Context-appropriate default
231
+
232
+ Args:
233
+ data_sample_rate: Sample rate from input data metadata (if available).
234
+ context: Analysis context for selecting appropriate default.
235
+ Options: "general" (1 MHz), "highspeed" (1 GHz), "binary" (1 Hz).
236
+
237
+ Returns:
238
+ Effective sample rate in Hz.
239
+ """
240
+ if data_sample_rate is not None and data_sample_rate > 0:
241
+ return data_sample_rate
242
+
243
+ if self.default_sample_rate is not None and self.default_sample_rate > 0:
244
+ return self.default_sample_rate
245
+
246
+ # Context-appropriate defaults
247
+ if context == "highspeed":
248
+ return DEFAULT_SAMPLE_RATE_HZ
249
+ elif context == "binary":
250
+ return DEFAULT_SAMPLE_RATE_BINARY_HZ
251
+ else:
252
+ return DEFAULT_SAMPLE_RATE_GENERAL_HZ
253
+
254
+
255
+ @dataclass
256
+ class ProgressInfo:
257
+ """Progress information for callbacks.
258
+
259
+ Attributes:
260
+ phase: Current phase (e.g., "loading", "analyzing", "plotting", "saving").
261
+ domain: Current analysis domain (None during non-domain phases).
262
+ function: Current function name (None during non-function phases).
263
+ percent: Progress percentage (0.0 to 100.0).
264
+ message: Human-readable progress message.
265
+ elapsed_seconds: Time elapsed since analysis started.
266
+ estimated_remaining_seconds: Estimated time remaining (None if unknown).
267
+ """
268
+
269
+ phase: str
270
+ domain: AnalysisDomain | None
271
+ function: str | None
272
+ percent: float
273
+ message: str
274
+ elapsed_seconds: float
275
+ estimated_remaining_seconds: float | None
276
+
277
+
278
+ @dataclass
279
+ class AnalysisError:
280
+ """Record of an analysis error.
281
+
282
+ Attributes:
283
+ domain: Analysis domain where error occurred.
284
+ function: Function name that failed.
285
+ error_type: Error type/class name.
286
+ error_message: Error message.
287
+ traceback: Full traceback (None if not captured).
288
+ duration_ms: Time spent before error occurred.
289
+ """
290
+
291
+ domain: AnalysisDomain
292
+ function: str
293
+ error_type: str
294
+ error_message: str
295
+ traceback: str | None
296
+ duration_ms: float
297
+
298
+
299
+ @dataclass
300
+ class AnalysisResult:
301
+ """Result from comprehensive analysis.
302
+
303
+ Contains paths to all generated outputs and summary statistics.
304
+
305
+ Attributes:
306
+ output_dir: Root output directory.
307
+ index_html: Path to HTML index (None if not generated).
308
+ index_md: Path to Markdown index (None if not generated).
309
+ index_pdf: Path to PDF index (None if not generated).
310
+ summary_json: Path to JSON summary.
311
+ summary_yaml: Path to YAML summary (None if not generated).
312
+ metadata_json: Path to metadata file.
313
+ config_yaml: Path to saved configuration.
314
+ domain_dirs: Per-domain output directories.
315
+ plot_paths: List of all generated plot files.
316
+ error_log: Path to error log (None if no errors).
317
+ input_file: Input file path (None if from memory).
318
+ input_type: Input data type.
319
+ total_analyses: Total number of analysis functions attempted.
320
+ successful_analyses: Number of successful analyses.
321
+ failed_analyses: Number of failed analyses.
322
+ skipped_analyses: Number of skipped analyses.
323
+ duration_seconds: Total analysis duration.
324
+ domain_summaries: Per-domain summary data.
325
+ errors: List of errors encountered.
326
+ """
327
+
328
+ output_dir: Path
329
+ index_html: Path | None
330
+ index_md: Path | None
331
+ index_pdf: Path | None
332
+ summary_json: Path
333
+ summary_yaml: Path | None
334
+ metadata_json: Path
335
+ config_yaml: Path
336
+ domain_dirs: dict[AnalysisDomain, Path]
337
+ plot_paths: list[Path]
338
+ error_log: Path | None
339
+ input_file: str | None
340
+ input_type: InputType
341
+ total_analyses: int
342
+ successful_analyses: int
343
+ failed_analyses: int
344
+ skipped_analyses: int
345
+ duration_seconds: float
346
+ domain_summaries: dict[AnalysisDomain, dict[str, Any]]
347
+ errors: list[AnalysisError]
348
+
349
+ def open_index(self) -> None:
350
+ """Open the HTML index in the default web browser.
351
+
352
+ Raises:
353
+ FileNotFoundError: If HTML index was not generated.
354
+ """
355
+ if self.index_html is None:
356
+ raise FileNotFoundError("HTML index was not generated")
357
+
358
+ import webbrowser
359
+
360
+ webbrowser.open(self.index_html.as_uri())
361
+
362
+ def get_domain_results(self, domain: AnalysisDomain) -> dict[str, Any]:
363
+ """Get results for a specific domain.
364
+
365
+ Args:
366
+ domain: Domain to get results for.
367
+
368
+ Returns:
369
+ Domain summary data.
370
+
371
+ Raises:
372
+ KeyError: If domain was not analyzed.
373
+ """
374
+ if domain not in self.domain_summaries:
375
+ raise KeyError(f"Domain {domain.value} was not analyzed")
376
+
377
+ return self.domain_summaries[domain]
378
+
379
+ @property
380
+ def success_rate(self) -> float:
381
+ """Calculate success rate as percentage.
382
+
383
+ Returns:
384
+ Success rate (0.0 to 100.0).
385
+ """
386
+ if self.total_analyses == 0:
387
+ return 0.0
388
+ return (self.successful_analyses / self.total_analyses) * 100.0
389
+
390
+ def __repr__(self) -> str:
391
+ """Get string representation."""
392
+ return (
393
+ f"AnalysisResult("
394
+ f"domains={len(self.domain_summaries)}, "
395
+ f"success={self.successful_analyses}/{self.total_analyses}, "
396
+ f"duration={self.duration_seconds:.1f}s, "
397
+ f"output_dir={self.output_dir})"
398
+ )
399
+
400
+
401
+ # Analysis capability registry - maps domains to available analyzers
402
+ # NOTE: Each domain now supports MULTIPLE modules to capture all available functions
403
+ # Updated to include all 68 submodules with 318+ total functions across 14 domains
404
+ ANALYSIS_CAPABILITIES: dict[AnalysisDomain, dict[str, Any]] = {
405
+ AnalysisDomain.WAVEFORM: {
406
+ "description": "Basic waveform timing and amplitude measurements",
407
+ "modules": ["oscura.analyzers.waveform.measurements"],
408
+ "requires": ["waveform"],
409
+ },
410
+ AnalysisDomain.SPECTRAL: {
411
+ "description": "FFT, PSD, THD, SNR, SFDR, SINAD, ENOB, wavelet analysis",
412
+ "modules": [
413
+ "oscura.analyzers.waveform.spectral",
414
+ "oscura.analyzers.spectral.chunked",
415
+ "oscura.analyzers.spectral.chunked_fft",
416
+ "oscura.analyzers.spectral.chunked_wavelet",
417
+ "oscura.analyzers.waveform.wavelets",
418
+ ],
419
+ "requires": ["waveform"],
420
+ },
421
+ AnalysisDomain.DIGITAL: {
422
+ "description": "Digital signal extraction, edge detection, timing analysis",
423
+ "modules": [
424
+ "oscura.analyzers.digital.extraction",
425
+ "oscura.analyzers.digital.edges",
426
+ "oscura.analyzers.digital.clock",
427
+ "oscura.analyzers.digital.quality",
428
+ "oscura.analyzers.digital.signal_quality",
429
+ "oscura.analyzers.digital.thresholds",
430
+ "oscura.analyzers.digital.bus",
431
+ "oscura.analyzers.digital.correlation",
432
+ ],
433
+ "requires": ["waveform", "digital"],
434
+ },
435
+ AnalysisDomain.TIMING: {
436
+ "description": "Setup/hold time, propagation delay, skew, slew rate",
437
+ "modules": ["oscura.analyzers.digital.timing"],
438
+ "requires": ["waveform", "digital"],
439
+ },
440
+ AnalysisDomain.STATISTICS: {
441
+ "description": "Statistical measures, outlier detection, trend analysis",
442
+ "modules": [
443
+ "oscura.analyzers.statistics.basic",
444
+ "oscura.analyzers.statistics.advanced",
445
+ "oscura.analyzers.statistics.correlation",
446
+ "oscura.analyzers.statistics.distribution",
447
+ "oscura.analyzers.statistics.outliers",
448
+ "oscura.analyzers.statistics.trend",
449
+ "oscura.analyzers.statistical.chunked_corr",
450
+ ],
451
+ "requires": ["waveform", "digital", "binary"],
452
+ },
453
+ AnalysisDomain.ENTROPY: {
454
+ "description": "Entropy analysis, data classification, checksum detection",
455
+ "modules": [
456
+ "oscura.analyzers.statistical.entropy",
457
+ "oscura.analyzers.statistical.classification",
458
+ "oscura.analyzers.statistical.checksum",
459
+ "oscura.analyzers.statistical.ngrams",
460
+ ],
461
+ "requires": ["binary"],
462
+ },
463
+ AnalysisDomain.PATTERNS: {
464
+ "description": "Periodic patterns, motifs, signatures, clustering",
465
+ "modules": [
466
+ "oscura.analyzers.patterns.discovery",
467
+ "oscura.analyzers.patterns.sequences",
468
+ "oscura.analyzers.patterns.periodic",
469
+ "oscura.analyzers.patterns.matching",
470
+ "oscura.analyzers.patterns.clustering",
471
+ "oscura.analyzers.patterns.learning",
472
+ ],
473
+ "requires": ["waveform", "binary", "digital"],
474
+ },
475
+ AnalysisDomain.JITTER: {
476
+ "description": "RJ, DJ, PJ, DDJ, DCD, bathtub curve, TJ at BER",
477
+ "modules": [
478
+ "oscura.analyzers.jitter.measurements",
479
+ "oscura.analyzers.jitter.decomposition",
480
+ "oscura.analyzers.jitter.spectrum",
481
+ "oscura.analyzers.jitter.ber",
482
+ ],
483
+ "requires": ["waveform", "digital"],
484
+ },
485
+ AnalysisDomain.EYE: {
486
+ "description": "Eye diagram generation and metrics",
487
+ "modules": [
488
+ "oscura.analyzers.eye.diagram",
489
+ "oscura.analyzers.eye.metrics",
490
+ ],
491
+ "requires": ["waveform", "digital"],
492
+ },
493
+ AnalysisDomain.POWER: {
494
+ "description": "Power measurements, efficiency, switching loss, ripple",
495
+ "modules": [
496
+ "oscura.analyzers.power.basic",
497
+ "oscura.analyzers.power.ac_power",
498
+ "oscura.analyzers.power.switching",
499
+ "oscura.analyzers.power.conduction",
500
+ "oscura.analyzers.power.efficiency",
501
+ "oscura.analyzers.power.ripple",
502
+ "oscura.analyzers.power.soa",
503
+ ],
504
+ "requires": ["waveform"],
505
+ },
506
+ AnalysisDomain.PROTOCOLS: {
507
+ "description": "Serial protocol decoding (UART, SPI, I2C, CAN, etc.)",
508
+ "modules": [
509
+ "oscura.analyzers.protocols.uart",
510
+ "oscura.analyzers.protocols.spi",
511
+ "oscura.analyzers.protocols.i2c",
512
+ "oscura.analyzers.protocols.can",
513
+ "oscura.analyzers.protocols.can_fd",
514
+ "oscura.analyzers.protocols.lin",
515
+ "oscura.analyzers.protocols.flexray",
516
+ "oscura.analyzers.protocols.manchester",
517
+ "oscura.analyzers.protocols.onewire",
518
+ "oscura.analyzers.protocols.usb",
519
+ "oscura.analyzers.protocols.i2s",
520
+ "oscura.analyzers.protocols.jtag",
521
+ "oscura.analyzers.protocols.swd",
522
+ "oscura.analyzers.protocols.hdlc",
523
+ ],
524
+ "requires": ["digital", "waveform"],
525
+ },
526
+ AnalysisDomain.SIGNAL_INTEGRITY: {
527
+ "description": "S-parameters, de-embedding, equalization",
528
+ "modules": [
529
+ "oscura.analyzers.signal_integrity.sparams",
530
+ "oscura.analyzers.signal_integrity.equalization",
531
+ "oscura.analyzers.signal_integrity.embedding",
532
+ ],
533
+ "requires": ["sparams", "waveform"],
534
+ },
535
+ AnalysisDomain.PACKET: {
536
+ "description": "Packet metrics, throughput, latency, loss, payload analysis",
537
+ "modules": [
538
+ "oscura.analyzers.packet.metrics",
539
+ "oscura.analyzers.packet.parser",
540
+ "oscura.analyzers.packet.payload",
541
+ "oscura.analyzers.packet.stream",
542
+ "oscura.analyzers.packet.daq",
543
+ ],
544
+ "requires": ["packets", "binary"],
545
+ },
546
+ AnalysisDomain.INFERENCE: {
547
+ "description": "Auto-inference, protocol detection, signal classification",
548
+ "modules": [
549
+ "oscura.inference.signal_intelligence", # classify_signal, assess_signal_quality, suggest_measurements
550
+ "oscura.inference.logic", # detect_logic_family
551
+ "oscura.inference.protocol", # detect_protocol
552
+ "oscura.inference.spectral", # auto_spectral_config
553
+ "oscura.inference.stream", # reassemble_udp_stream, reassemble_tcp_stream, detect_message_framing
554
+ "oscura.inference.binary", # detect_magic_bytes, detect_alignment, generate_parser
555
+ "oscura.inference.message_format", # infer_format, detect_field_types, find_dependencies
556
+ "oscura.inference.sequences", # detect_sequence_patterns, correlate_requests, find_message_dependencies
557
+ "oscura.inference.alignment", # align_global, align_local, compute_similarity
558
+ "oscura.inference.state_machine", # infer_rpni, minimize_dfa
559
+ "oscura.inference.protocol_dsl", # decode_message, load_protocol
560
+ "oscura.inference.protocol_library", # get_protocol, list_protocols, get_decoder
561
+ ],
562
+ "requires": ["waveform", "digital", "binary", "packets"],
563
+ },
564
+ }
565
+
566
+
567
+ def get_available_analyses(input_type: InputType) -> list[AnalysisDomain]:
568
+ """Get list of analyses applicable to input type.
569
+
570
+ Args:
571
+ input_type: Type of input data.
572
+
573
+ Returns:
574
+ List of applicable analysis domains.
575
+ """
576
+ type_mapping = {
577
+ InputType.WAVEFORM: "waveform",
578
+ InputType.DIGITAL: "digital",
579
+ InputType.BINARY: "binary",
580
+ InputType.PCAP: "packets",
581
+ InputType.IQ: "waveform",
582
+ InputType.PACKETS: "packets",
583
+ InputType.SPARAMS: "sparams",
584
+ }
585
+
586
+ input_category = type_mapping.get(input_type, "waveform")
587
+
588
+ applicable = []
589
+ for domain, config in ANALYSIS_CAPABILITIES.items():
590
+ if input_category in config["requires"]:
591
+ applicable.append(domain)
592
+
593
+ return applicable
594
+
595
+
596
+ # Type alias for progress callbacks
597
+ ProgressCallback = Callable[[ProgressInfo], None]
598
+
599
+
600
+ __all__ = [
601
+ "ANALYSIS_CAPABILITIES",
602
+ "DEFAULT_SAMPLE_RATE_BINARY_HZ",
603
+ "DEFAULT_SAMPLE_RATE_GENERAL_HZ",
604
+ "DEFAULT_SAMPLE_RATE_HZ",
605
+ "AnalysisConfig",
606
+ "AnalysisDomain",
607
+ "AnalysisError",
608
+ "AnalysisResult",
609
+ "DataOutputConfig",
610
+ "DomainConfig",
611
+ "InputType",
612
+ "ProgressCallback",
613
+ "ProgressInfo",
614
+ "get_available_analyses",
615
+ ]
@@ -0,0 +1,39 @@
1
+ """Content generation utilities for reports."""
2
+
3
+ from oscura.reporting.content.executive import (
4
+ ExecutiveSummary,
5
+ generate_executive_summary,
6
+ )
7
+ from oscura.reporting.content.filtering import (
8
+ ContentFilter,
9
+ filter_by_audience,
10
+ filter_by_severity,
11
+ )
12
+ from oscura.reporting.content.minimal import (
13
+ MinimalContent,
14
+ auto_caption,
15
+ generate_compact_text,
16
+ )
17
+ from oscura.reporting.content.verbosity import (
18
+ VerbosityController,
19
+ VerbosityLevel,
20
+ apply_verbosity_level,
21
+ )
22
+
23
+ __all__ = [
24
+ # Filtering
25
+ "ContentFilter",
26
+ # Executive Summary
27
+ "ExecutiveSummary",
28
+ # Minimal
29
+ "MinimalContent",
30
+ # Verbosity
31
+ "VerbosityController",
32
+ "VerbosityLevel",
33
+ "apply_verbosity_level",
34
+ "auto_caption",
35
+ "filter_by_audience",
36
+ "filter_by_severity",
37
+ "generate_compact_text",
38
+ "generate_executive_summary",
39
+ ]