oscura 0.5.0__py3-none-any.whl → 0.6.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (513) hide show
  1. oscura/__init__.py +169 -167
  2. oscura/analyzers/__init__.py +3 -0
  3. oscura/analyzers/classification.py +659 -0
  4. oscura/analyzers/digital/__init__.py +0 -48
  5. oscura/analyzers/digital/edges.py +325 -65
  6. oscura/analyzers/digital/extraction.py +0 -195
  7. oscura/analyzers/digital/quality.py +293 -166
  8. oscura/analyzers/digital/timing.py +260 -115
  9. oscura/analyzers/digital/timing_numba.py +334 -0
  10. oscura/analyzers/entropy.py +605 -0
  11. oscura/analyzers/eye/diagram.py +176 -109
  12. oscura/analyzers/eye/metrics.py +5 -5
  13. oscura/analyzers/jitter/__init__.py +6 -4
  14. oscura/analyzers/jitter/ber.py +52 -52
  15. oscura/analyzers/jitter/classification.py +156 -0
  16. oscura/analyzers/jitter/decomposition.py +163 -113
  17. oscura/analyzers/jitter/spectrum.py +80 -64
  18. oscura/analyzers/ml/__init__.py +39 -0
  19. oscura/analyzers/ml/features.py +600 -0
  20. oscura/analyzers/ml/signal_classifier.py +604 -0
  21. oscura/analyzers/packet/daq.py +246 -158
  22. oscura/analyzers/packet/parser.py +12 -1
  23. oscura/analyzers/packet/payload.py +50 -2110
  24. oscura/analyzers/packet/payload_analysis.py +361 -181
  25. oscura/analyzers/packet/payload_patterns.py +133 -70
  26. oscura/analyzers/packet/stream.py +84 -23
  27. oscura/analyzers/patterns/__init__.py +26 -5
  28. oscura/analyzers/patterns/anomaly_detection.py +908 -0
  29. oscura/analyzers/patterns/clustering.py +169 -108
  30. oscura/analyzers/patterns/clustering_optimized.py +227 -0
  31. oscura/analyzers/patterns/discovery.py +1 -1
  32. oscura/analyzers/patterns/matching.py +581 -197
  33. oscura/analyzers/patterns/pattern_mining.py +778 -0
  34. oscura/analyzers/patterns/periodic.py +121 -38
  35. oscura/analyzers/patterns/sequences.py +175 -78
  36. oscura/analyzers/power/conduction.py +1 -1
  37. oscura/analyzers/power/soa.py +6 -6
  38. oscura/analyzers/power/switching.py +250 -110
  39. oscura/analyzers/protocol/__init__.py +17 -1
  40. oscura/analyzers/protocols/__init__.py +1 -22
  41. oscura/analyzers/protocols/base.py +6 -6
  42. oscura/analyzers/protocols/ble/__init__.py +38 -0
  43. oscura/analyzers/protocols/ble/analyzer.py +809 -0
  44. oscura/analyzers/protocols/ble/uuids.py +288 -0
  45. oscura/analyzers/protocols/can.py +257 -127
  46. oscura/analyzers/protocols/can_fd.py +107 -80
  47. oscura/analyzers/protocols/flexray.py +139 -80
  48. oscura/analyzers/protocols/hdlc.py +93 -58
  49. oscura/analyzers/protocols/i2c.py +247 -106
  50. oscura/analyzers/protocols/i2s.py +138 -86
  51. oscura/analyzers/protocols/industrial/__init__.py +40 -0
  52. oscura/analyzers/protocols/industrial/bacnet/__init__.py +33 -0
  53. oscura/analyzers/protocols/industrial/bacnet/analyzer.py +708 -0
  54. oscura/analyzers/protocols/industrial/bacnet/encoding.py +412 -0
  55. oscura/analyzers/protocols/industrial/bacnet/services.py +622 -0
  56. oscura/analyzers/protocols/industrial/ethercat/__init__.py +30 -0
  57. oscura/analyzers/protocols/industrial/ethercat/analyzer.py +474 -0
  58. oscura/analyzers/protocols/industrial/ethercat/mailbox.py +339 -0
  59. oscura/analyzers/protocols/industrial/ethercat/topology.py +166 -0
  60. oscura/analyzers/protocols/industrial/modbus/__init__.py +31 -0
  61. oscura/analyzers/protocols/industrial/modbus/analyzer.py +525 -0
  62. oscura/analyzers/protocols/industrial/modbus/crc.py +79 -0
  63. oscura/analyzers/protocols/industrial/modbus/functions.py +436 -0
  64. oscura/analyzers/protocols/industrial/opcua/__init__.py +21 -0
  65. oscura/analyzers/protocols/industrial/opcua/analyzer.py +552 -0
  66. oscura/analyzers/protocols/industrial/opcua/datatypes.py +446 -0
  67. oscura/analyzers/protocols/industrial/opcua/services.py +264 -0
  68. oscura/analyzers/protocols/industrial/profinet/__init__.py +23 -0
  69. oscura/analyzers/protocols/industrial/profinet/analyzer.py +441 -0
  70. oscura/analyzers/protocols/industrial/profinet/dcp.py +263 -0
  71. oscura/analyzers/protocols/industrial/profinet/ptcp.py +200 -0
  72. oscura/analyzers/protocols/jtag.py +180 -98
  73. oscura/analyzers/protocols/lin.py +219 -114
  74. oscura/analyzers/protocols/manchester.py +4 -4
  75. oscura/analyzers/protocols/onewire.py +253 -149
  76. oscura/analyzers/protocols/parallel_bus/__init__.py +20 -0
  77. oscura/analyzers/protocols/parallel_bus/centronics.py +92 -0
  78. oscura/analyzers/protocols/parallel_bus/gpib.py +137 -0
  79. oscura/analyzers/protocols/spi.py +192 -95
  80. oscura/analyzers/protocols/swd.py +321 -167
  81. oscura/analyzers/protocols/uart.py +267 -125
  82. oscura/analyzers/protocols/usb.py +235 -131
  83. oscura/analyzers/side_channel/power.py +17 -12
  84. oscura/analyzers/signal/__init__.py +15 -0
  85. oscura/analyzers/signal/timing_analysis.py +1086 -0
  86. oscura/analyzers/signal_integrity/__init__.py +4 -1
  87. oscura/analyzers/signal_integrity/sparams.py +2 -19
  88. oscura/analyzers/spectral/chunked.py +129 -60
  89. oscura/analyzers/spectral/chunked_fft.py +300 -94
  90. oscura/analyzers/spectral/chunked_wavelet.py +100 -80
  91. oscura/analyzers/statistical/checksum.py +376 -217
  92. oscura/analyzers/statistical/classification.py +229 -107
  93. oscura/analyzers/statistical/entropy.py +78 -53
  94. oscura/analyzers/statistics/correlation.py +407 -211
  95. oscura/analyzers/statistics/outliers.py +2 -2
  96. oscura/analyzers/statistics/streaming.py +30 -5
  97. oscura/analyzers/validation.py +216 -101
  98. oscura/analyzers/waveform/measurements.py +9 -0
  99. oscura/analyzers/waveform/measurements_with_uncertainty.py +31 -15
  100. oscura/analyzers/waveform/spectral.py +500 -228
  101. oscura/api/__init__.py +31 -5
  102. oscura/api/dsl/__init__.py +582 -0
  103. oscura/{dsl → api/dsl}/commands.py +43 -76
  104. oscura/{dsl → api/dsl}/interpreter.py +26 -51
  105. oscura/{dsl → api/dsl}/parser.py +107 -77
  106. oscura/{dsl → api/dsl}/repl.py +2 -2
  107. oscura/api/dsl.py +1 -1
  108. oscura/{integrations → api/integrations}/__init__.py +1 -1
  109. oscura/{integrations → api/integrations}/llm.py +201 -102
  110. oscura/api/operators.py +3 -3
  111. oscura/api/optimization.py +144 -30
  112. oscura/api/rest_server.py +921 -0
  113. oscura/api/server/__init__.py +17 -0
  114. oscura/api/server/dashboard.py +850 -0
  115. oscura/api/server/static/README.md +34 -0
  116. oscura/api/server/templates/base.html +181 -0
  117. oscura/api/server/templates/export.html +120 -0
  118. oscura/api/server/templates/home.html +284 -0
  119. oscura/api/server/templates/protocols.html +58 -0
  120. oscura/api/server/templates/reports.html +43 -0
  121. oscura/api/server/templates/session_detail.html +89 -0
  122. oscura/api/server/templates/sessions.html +83 -0
  123. oscura/api/server/templates/waveforms.html +73 -0
  124. oscura/automotive/__init__.py +8 -1
  125. oscura/automotive/can/__init__.py +10 -0
  126. oscura/automotive/can/checksum.py +3 -1
  127. oscura/automotive/can/dbc_generator.py +590 -0
  128. oscura/automotive/can/message_wrapper.py +121 -74
  129. oscura/automotive/can/patterns.py +98 -21
  130. oscura/automotive/can/session.py +292 -56
  131. oscura/automotive/can/state_machine.py +6 -3
  132. oscura/automotive/can/stimulus_response.py +97 -75
  133. oscura/automotive/dbc/__init__.py +10 -2
  134. oscura/automotive/dbc/generator.py +84 -56
  135. oscura/automotive/dbc/parser.py +6 -6
  136. oscura/automotive/dtc/data.json +2763 -0
  137. oscura/automotive/dtc/database.py +2 -2
  138. oscura/automotive/flexray/__init__.py +31 -0
  139. oscura/automotive/flexray/analyzer.py +504 -0
  140. oscura/automotive/flexray/crc.py +185 -0
  141. oscura/automotive/flexray/fibex.py +449 -0
  142. oscura/automotive/j1939/__init__.py +45 -8
  143. oscura/automotive/j1939/analyzer.py +605 -0
  144. oscura/automotive/j1939/spns.py +326 -0
  145. oscura/automotive/j1939/transport.py +306 -0
  146. oscura/automotive/lin/__init__.py +47 -0
  147. oscura/automotive/lin/analyzer.py +612 -0
  148. oscura/automotive/loaders/blf.py +13 -2
  149. oscura/automotive/loaders/csv_can.py +143 -72
  150. oscura/automotive/loaders/dispatcher.py +50 -2
  151. oscura/automotive/loaders/mdf.py +86 -45
  152. oscura/automotive/loaders/pcap.py +111 -61
  153. oscura/automotive/uds/__init__.py +4 -0
  154. oscura/automotive/uds/analyzer.py +725 -0
  155. oscura/automotive/uds/decoder.py +140 -58
  156. oscura/automotive/uds/models.py +7 -1
  157. oscura/automotive/visualization.py +1 -1
  158. oscura/cli/analyze.py +348 -0
  159. oscura/cli/batch.py +142 -122
  160. oscura/cli/benchmark.py +275 -0
  161. oscura/cli/characterize.py +137 -82
  162. oscura/cli/compare.py +224 -131
  163. oscura/cli/completion.py +250 -0
  164. oscura/cli/config_cmd.py +361 -0
  165. oscura/cli/decode.py +164 -87
  166. oscura/cli/export.py +286 -0
  167. oscura/cli/main.py +115 -31
  168. oscura/{onboarding → cli/onboarding}/__init__.py +3 -3
  169. oscura/{onboarding → cli/onboarding}/help.py +80 -58
  170. oscura/{onboarding → cli/onboarding}/tutorials.py +97 -72
  171. oscura/{onboarding → cli/onboarding}/wizard.py +55 -36
  172. oscura/cli/progress.py +147 -0
  173. oscura/cli/shell.py +157 -135
  174. oscura/cli/validate_cmd.py +204 -0
  175. oscura/cli/visualize.py +158 -0
  176. oscura/convenience.py +125 -79
  177. oscura/core/__init__.py +4 -2
  178. oscura/core/backend_selector.py +3 -3
  179. oscura/core/cache.py +126 -15
  180. oscura/core/cancellation.py +1 -1
  181. oscura/{config → core/config}/__init__.py +20 -11
  182. oscura/{config → core/config}/defaults.py +1 -1
  183. oscura/{config → core/config}/loader.py +7 -5
  184. oscura/{config → core/config}/memory.py +5 -5
  185. oscura/{config → core/config}/migration.py +1 -1
  186. oscura/{config → core/config}/pipeline.py +99 -23
  187. oscura/{config → core/config}/preferences.py +1 -1
  188. oscura/{config → core/config}/protocol.py +3 -3
  189. oscura/{config → core/config}/schema.py +426 -272
  190. oscura/{config → core/config}/settings.py +1 -1
  191. oscura/{config → core/config}/thresholds.py +195 -153
  192. oscura/core/correlation.py +5 -6
  193. oscura/core/cross_domain.py +0 -2
  194. oscura/core/debug.py +9 -5
  195. oscura/{extensibility → core/extensibility}/docs.py +158 -70
  196. oscura/{extensibility → core/extensibility}/extensions.py +160 -76
  197. oscura/{extensibility → core/extensibility}/logging.py +1 -1
  198. oscura/{extensibility → core/extensibility}/measurements.py +1 -1
  199. oscura/{extensibility → core/extensibility}/plugins.py +1 -1
  200. oscura/{extensibility → core/extensibility}/templates.py +73 -3
  201. oscura/{extensibility → core/extensibility}/validation.py +1 -1
  202. oscura/core/gpu_backend.py +11 -7
  203. oscura/core/log_query.py +101 -11
  204. oscura/core/logging.py +126 -54
  205. oscura/core/logging_advanced.py +5 -5
  206. oscura/core/memory_limits.py +108 -70
  207. oscura/core/memory_monitor.py +2 -2
  208. oscura/core/memory_progress.py +7 -7
  209. oscura/core/memory_warnings.py +1 -1
  210. oscura/core/numba_backend.py +13 -13
  211. oscura/{plugins → core/plugins}/__init__.py +9 -9
  212. oscura/{plugins → core/plugins}/base.py +7 -7
  213. oscura/{plugins → core/plugins}/cli.py +3 -3
  214. oscura/{plugins → core/plugins}/discovery.py +186 -106
  215. oscura/{plugins → core/plugins}/lifecycle.py +1 -1
  216. oscura/{plugins → core/plugins}/manager.py +7 -7
  217. oscura/{plugins → core/plugins}/registry.py +3 -3
  218. oscura/{plugins → core/plugins}/versioning.py +1 -1
  219. oscura/core/progress.py +16 -1
  220. oscura/core/provenance.py +8 -2
  221. oscura/{schemas → core/schemas}/__init__.py +2 -2
  222. oscura/core/schemas/bus_configuration.json +322 -0
  223. oscura/core/schemas/device_mapping.json +182 -0
  224. oscura/core/schemas/packet_format.json +418 -0
  225. oscura/core/schemas/protocol_definition.json +363 -0
  226. oscura/core/types.py +4 -0
  227. oscura/core/uncertainty.py +3 -3
  228. oscura/correlation/__init__.py +52 -0
  229. oscura/correlation/multi_protocol.py +811 -0
  230. oscura/discovery/auto_decoder.py +117 -35
  231. oscura/discovery/comparison.py +191 -86
  232. oscura/discovery/quality_validator.py +155 -68
  233. oscura/discovery/signal_detector.py +196 -79
  234. oscura/export/__init__.py +18 -20
  235. oscura/export/kaitai_struct.py +513 -0
  236. oscura/export/scapy_layer.py +801 -0
  237. oscura/export/wireshark/README.md +15 -15
  238. oscura/export/wireshark/generator.py +1 -1
  239. oscura/export/wireshark/templates/dissector.lua.j2 +2 -2
  240. oscura/export/wireshark_dissector.py +746 -0
  241. oscura/guidance/wizard.py +207 -111
  242. oscura/hardware/__init__.py +19 -0
  243. oscura/{acquisition → hardware/acquisition}/__init__.py +4 -4
  244. oscura/{acquisition → hardware/acquisition}/file.py +2 -2
  245. oscura/{acquisition → hardware/acquisition}/hardware.py +7 -7
  246. oscura/{acquisition → hardware/acquisition}/saleae.py +15 -12
  247. oscura/{acquisition → hardware/acquisition}/socketcan.py +1 -1
  248. oscura/{acquisition → hardware/acquisition}/streaming.py +2 -2
  249. oscura/{acquisition → hardware/acquisition}/synthetic.py +3 -3
  250. oscura/{acquisition → hardware/acquisition}/visa.py +33 -11
  251. oscura/hardware/firmware/__init__.py +29 -0
  252. oscura/hardware/firmware/pattern_recognition.py +874 -0
  253. oscura/hardware/hal_detector.py +736 -0
  254. oscura/hardware/security/__init__.py +37 -0
  255. oscura/hardware/security/side_channel_detector.py +1126 -0
  256. oscura/inference/__init__.py +4 -0
  257. oscura/inference/active_learning/README.md +7 -7
  258. oscura/inference/active_learning/observation_table.py +4 -1
  259. oscura/inference/alignment.py +216 -123
  260. oscura/inference/bayesian.py +113 -33
  261. oscura/inference/crc_reverse.py +101 -55
  262. oscura/inference/logic.py +6 -2
  263. oscura/inference/message_format.py +342 -183
  264. oscura/inference/protocol.py +95 -44
  265. oscura/inference/protocol_dsl.py +180 -82
  266. oscura/inference/signal_intelligence.py +1439 -706
  267. oscura/inference/spectral.py +99 -57
  268. oscura/inference/state_machine.py +810 -158
  269. oscura/inference/stream.py +270 -110
  270. oscura/iot/__init__.py +34 -0
  271. oscura/iot/coap/__init__.py +32 -0
  272. oscura/iot/coap/analyzer.py +668 -0
  273. oscura/iot/coap/options.py +212 -0
  274. oscura/iot/lorawan/__init__.py +21 -0
  275. oscura/iot/lorawan/crypto.py +206 -0
  276. oscura/iot/lorawan/decoder.py +801 -0
  277. oscura/iot/lorawan/mac_commands.py +341 -0
  278. oscura/iot/mqtt/__init__.py +27 -0
  279. oscura/iot/mqtt/analyzer.py +999 -0
  280. oscura/iot/mqtt/properties.py +315 -0
  281. oscura/iot/zigbee/__init__.py +31 -0
  282. oscura/iot/zigbee/analyzer.py +615 -0
  283. oscura/iot/zigbee/security.py +153 -0
  284. oscura/iot/zigbee/zcl.py +349 -0
  285. oscura/jupyter/display.py +125 -45
  286. oscura/{exploratory → jupyter/exploratory}/__init__.py +8 -8
  287. oscura/{exploratory → jupyter/exploratory}/error_recovery.py +298 -141
  288. oscura/jupyter/exploratory/fuzzy.py +746 -0
  289. oscura/{exploratory → jupyter/exploratory}/fuzzy_advanced.py +258 -100
  290. oscura/{exploratory → jupyter/exploratory}/legacy.py +464 -242
  291. oscura/{exploratory → jupyter/exploratory}/parse.py +167 -145
  292. oscura/{exploratory → jupyter/exploratory}/recovery.py +119 -87
  293. oscura/jupyter/exploratory/sync.py +612 -0
  294. oscura/{exploratory → jupyter/exploratory}/unknown.py +299 -176
  295. oscura/jupyter/magic.py +4 -4
  296. oscura/{ui → jupyter/ui}/__init__.py +2 -2
  297. oscura/{ui → jupyter/ui}/formatters.py +3 -3
  298. oscura/{ui → jupyter/ui}/progressive_display.py +153 -82
  299. oscura/loaders/__init__.py +171 -63
  300. oscura/loaders/binary.py +88 -1
  301. oscura/loaders/chipwhisperer.py +153 -137
  302. oscura/loaders/configurable.py +208 -86
  303. oscura/loaders/csv_loader.py +458 -215
  304. oscura/loaders/hdf5_loader.py +278 -119
  305. oscura/loaders/lazy.py +87 -54
  306. oscura/loaders/mmap_loader.py +1 -1
  307. oscura/loaders/numpy_loader.py +253 -116
  308. oscura/loaders/pcap.py +226 -151
  309. oscura/loaders/rigol.py +110 -49
  310. oscura/loaders/sigrok.py +201 -78
  311. oscura/loaders/tdms.py +81 -58
  312. oscura/loaders/tektronix.py +291 -174
  313. oscura/loaders/touchstone.py +182 -87
  314. oscura/loaders/vcd.py +215 -117
  315. oscura/loaders/wav.py +155 -68
  316. oscura/reporting/__init__.py +9 -7
  317. oscura/reporting/analyze.py +352 -146
  318. oscura/reporting/argument_preparer.py +69 -14
  319. oscura/reporting/auto_report.py +97 -61
  320. oscura/reporting/batch.py +131 -58
  321. oscura/reporting/chart_selection.py +57 -45
  322. oscura/reporting/comparison.py +63 -17
  323. oscura/reporting/content/executive.py +76 -24
  324. oscura/reporting/core_formats/multi_format.py +11 -8
  325. oscura/reporting/engine.py +312 -158
  326. oscura/reporting/enhanced_reports.py +949 -0
  327. oscura/reporting/export.py +86 -43
  328. oscura/reporting/formatting/numbers.py +69 -42
  329. oscura/reporting/html.py +139 -58
  330. oscura/reporting/index.py +137 -65
  331. oscura/reporting/output.py +158 -67
  332. oscura/reporting/pdf.py +67 -102
  333. oscura/reporting/plots.py +191 -112
  334. oscura/reporting/sections.py +88 -47
  335. oscura/reporting/standards.py +104 -61
  336. oscura/reporting/summary_generator.py +75 -55
  337. oscura/reporting/tables.py +138 -54
  338. oscura/reporting/templates/enhanced/protocol_re.html +525 -0
  339. oscura/reporting/templates/index.md +13 -13
  340. oscura/sessions/__init__.py +14 -23
  341. oscura/sessions/base.py +3 -3
  342. oscura/sessions/blackbox.py +106 -10
  343. oscura/sessions/generic.py +2 -2
  344. oscura/sessions/legacy.py +783 -0
  345. oscura/side_channel/__init__.py +63 -0
  346. oscura/side_channel/dpa.py +1025 -0
  347. oscura/utils/__init__.py +15 -1
  348. oscura/utils/autodetect.py +1 -5
  349. oscura/utils/bitwise.py +118 -0
  350. oscura/{builders → utils/builders}/__init__.py +1 -1
  351. oscura/{comparison → utils/comparison}/__init__.py +6 -6
  352. oscura/{comparison → utils/comparison}/compare.py +202 -101
  353. oscura/{comparison → utils/comparison}/golden.py +83 -63
  354. oscura/{comparison → utils/comparison}/limits.py +313 -89
  355. oscura/{comparison → utils/comparison}/mask.py +151 -45
  356. oscura/{comparison → utils/comparison}/trace_diff.py +1 -1
  357. oscura/{comparison → utils/comparison}/visualization.py +147 -89
  358. oscura/{component → utils/component}/__init__.py +3 -3
  359. oscura/{component → utils/component}/impedance.py +122 -58
  360. oscura/{component → utils/component}/reactive.py +165 -168
  361. oscura/{component → utils/component}/transmission_line.py +3 -3
  362. oscura/{filtering → utils/filtering}/__init__.py +6 -6
  363. oscura/{filtering → utils/filtering}/base.py +1 -1
  364. oscura/{filtering → utils/filtering}/convenience.py +2 -2
  365. oscura/{filtering → utils/filtering}/design.py +169 -93
  366. oscura/{filtering → utils/filtering}/filters.py +2 -2
  367. oscura/{filtering → utils/filtering}/introspection.py +2 -2
  368. oscura/utils/geometry.py +31 -0
  369. oscura/utils/imports.py +184 -0
  370. oscura/utils/lazy.py +1 -1
  371. oscura/{math → utils/math}/__init__.py +2 -2
  372. oscura/{math → utils/math}/arithmetic.py +114 -48
  373. oscura/{math → utils/math}/interpolation.py +139 -106
  374. oscura/utils/memory.py +129 -66
  375. oscura/utils/memory_advanced.py +92 -9
  376. oscura/utils/memory_extensions.py +10 -8
  377. oscura/{optimization → utils/optimization}/__init__.py +1 -1
  378. oscura/{optimization → utils/optimization}/search.py +2 -2
  379. oscura/utils/performance/__init__.py +58 -0
  380. oscura/utils/performance/caching.py +889 -0
  381. oscura/utils/performance/lsh_clustering.py +333 -0
  382. oscura/utils/performance/memory_optimizer.py +699 -0
  383. oscura/utils/performance/optimizations.py +675 -0
  384. oscura/utils/performance/parallel.py +654 -0
  385. oscura/utils/performance/profiling.py +661 -0
  386. oscura/{pipeline → utils/pipeline}/base.py +1 -1
  387. oscura/{pipeline → utils/pipeline}/composition.py +11 -3
  388. oscura/{pipeline → utils/pipeline}/parallel.py +3 -2
  389. oscura/{pipeline → utils/pipeline}/pipeline.py +1 -1
  390. oscura/{pipeline → utils/pipeline}/reverse_engineering.py +412 -221
  391. oscura/{search → utils/search}/__init__.py +3 -3
  392. oscura/{search → utils/search}/anomaly.py +188 -58
  393. oscura/utils/search/context.py +294 -0
  394. oscura/{search → utils/search}/pattern.py +138 -10
  395. oscura/utils/serial.py +51 -0
  396. oscura/utils/storage/__init__.py +61 -0
  397. oscura/utils/storage/database.py +1166 -0
  398. oscura/{streaming → utils/streaming}/chunked.py +302 -143
  399. oscura/{streaming → utils/streaming}/progressive.py +1 -1
  400. oscura/{streaming → utils/streaming}/realtime.py +3 -2
  401. oscura/{triggering → utils/triggering}/__init__.py +6 -6
  402. oscura/{triggering → utils/triggering}/base.py +6 -6
  403. oscura/{triggering → utils/triggering}/edge.py +2 -2
  404. oscura/{triggering → utils/triggering}/pattern.py +2 -2
  405. oscura/{triggering → utils/triggering}/pulse.py +115 -74
  406. oscura/{triggering → utils/triggering}/window.py +2 -2
  407. oscura/utils/validation.py +32 -0
  408. oscura/validation/__init__.py +121 -0
  409. oscura/{compliance → validation/compliance}/__init__.py +5 -5
  410. oscura/{compliance → validation/compliance}/advanced.py +5 -5
  411. oscura/{compliance → validation/compliance}/masks.py +1 -1
  412. oscura/{compliance → validation/compliance}/reporting.py +127 -53
  413. oscura/{compliance → validation/compliance}/testing.py +114 -52
  414. oscura/validation/compliance_tests.py +915 -0
  415. oscura/validation/fuzzer.py +990 -0
  416. oscura/validation/grammar_tests.py +596 -0
  417. oscura/validation/grammar_validator.py +904 -0
  418. oscura/validation/hil_testing.py +977 -0
  419. oscura/{quality → validation/quality}/__init__.py +4 -4
  420. oscura/{quality → validation/quality}/ensemble.py +251 -171
  421. oscura/{quality → validation/quality}/explainer.py +3 -3
  422. oscura/{quality → validation/quality}/scoring.py +1 -1
  423. oscura/{quality → validation/quality}/warnings.py +4 -4
  424. oscura/validation/regression_suite.py +808 -0
  425. oscura/validation/replay.py +788 -0
  426. oscura/{testing → validation/testing}/__init__.py +2 -2
  427. oscura/{testing → validation/testing}/synthetic.py +5 -5
  428. oscura/visualization/__init__.py +9 -0
  429. oscura/visualization/accessibility.py +1 -1
  430. oscura/visualization/annotations.py +64 -67
  431. oscura/visualization/colors.py +7 -7
  432. oscura/visualization/digital.py +180 -81
  433. oscura/visualization/eye.py +236 -85
  434. oscura/visualization/interactive.py +320 -143
  435. oscura/visualization/jitter.py +587 -247
  436. oscura/visualization/layout.py +169 -134
  437. oscura/visualization/optimization.py +103 -52
  438. oscura/visualization/palettes.py +1 -1
  439. oscura/visualization/power.py +427 -211
  440. oscura/visualization/power_extended.py +626 -297
  441. oscura/visualization/presets.py +2 -0
  442. oscura/visualization/protocols.py +495 -181
  443. oscura/visualization/render.py +79 -63
  444. oscura/visualization/reverse_engineering.py +171 -124
  445. oscura/visualization/signal_integrity.py +460 -279
  446. oscura/visualization/specialized.py +190 -100
  447. oscura/visualization/spectral.py +670 -255
  448. oscura/visualization/thumbnails.py +166 -137
  449. oscura/visualization/waveform.py +150 -63
  450. oscura/workflows/__init__.py +3 -0
  451. oscura/{batch → workflows/batch}/__init__.py +5 -5
  452. oscura/{batch → workflows/batch}/advanced.py +150 -75
  453. oscura/workflows/batch/aggregate.py +531 -0
  454. oscura/workflows/batch/analyze.py +236 -0
  455. oscura/{batch → workflows/batch}/logging.py +2 -2
  456. oscura/{batch → workflows/batch}/metrics.py +1 -1
  457. oscura/workflows/complete_re.py +1144 -0
  458. oscura/workflows/compliance.py +44 -54
  459. oscura/workflows/digital.py +197 -51
  460. oscura/workflows/legacy/__init__.py +12 -0
  461. oscura/{workflow → workflows/legacy}/dag.py +4 -1
  462. oscura/workflows/multi_trace.py +9 -9
  463. oscura/workflows/power.py +42 -62
  464. oscura/workflows/protocol.py +82 -49
  465. oscura/workflows/reverse_engineering.py +351 -150
  466. oscura/workflows/signal_integrity.py +157 -82
  467. oscura-0.6.0.dist-info/METADATA +643 -0
  468. oscura-0.6.0.dist-info/RECORD +590 -0
  469. oscura/analyzers/digital/ic_database.py +0 -498
  470. oscura/analyzers/digital/timing_paths.py +0 -339
  471. oscura/analyzers/digital/vintage.py +0 -377
  472. oscura/analyzers/digital/vintage_result.py +0 -148
  473. oscura/analyzers/protocols/parallel_bus.py +0 -449
  474. oscura/batch/aggregate.py +0 -300
  475. oscura/batch/analyze.py +0 -139
  476. oscura/dsl/__init__.py +0 -73
  477. oscura/exceptions.py +0 -59
  478. oscura/exploratory/fuzzy.py +0 -513
  479. oscura/exploratory/sync.py +0 -384
  480. oscura/export/wavedrom.py +0 -430
  481. oscura/exporters/__init__.py +0 -94
  482. oscura/exporters/csv.py +0 -303
  483. oscura/exporters/exporters.py +0 -44
  484. oscura/exporters/hdf5.py +0 -217
  485. oscura/exporters/html_export.py +0 -701
  486. oscura/exporters/json_export.py +0 -338
  487. oscura/exporters/markdown_export.py +0 -367
  488. oscura/exporters/matlab_export.py +0 -354
  489. oscura/exporters/npz_export.py +0 -219
  490. oscura/exporters/spice_export.py +0 -210
  491. oscura/exporters/vintage_logic_csv.py +0 -247
  492. oscura/reporting/vintage_logic_report.py +0 -523
  493. oscura/search/context.py +0 -149
  494. oscura/session/__init__.py +0 -34
  495. oscura/session/annotations.py +0 -289
  496. oscura/session/history.py +0 -313
  497. oscura/session/session.py +0 -520
  498. oscura/visualization/digital_advanced.py +0 -718
  499. oscura/visualization/figure_manager.py +0 -156
  500. oscura/workflow/__init__.py +0 -13
  501. oscura-0.5.0.dist-info/METADATA +0 -407
  502. oscura-0.5.0.dist-info/RECORD +0 -486
  503. /oscura/core/{config.py → config/legacy.py} +0 -0
  504. /oscura/{extensibility → core/extensibility}/__init__.py +0 -0
  505. /oscura/{extensibility → core/extensibility}/registry.py +0 -0
  506. /oscura/{plugins → core/plugins}/isolation.py +0 -0
  507. /oscura/{builders → utils/builders}/signal_builder.py +0 -0
  508. /oscura/{optimization → utils/optimization}/parallel.py +0 -0
  509. /oscura/{pipeline → utils/pipeline}/__init__.py +0 -0
  510. /oscura/{streaming → utils/streaming}/__init__.py +0 -0
  511. {oscura-0.5.0.dist-info → oscura-0.6.0.dist-info}/WHEEL +0 -0
  512. {oscura-0.5.0.dist-info → oscura-0.6.0.dist-info}/entry_points.txt +0 -0
  513. {oscura-0.5.0.dist-info → oscura-0.6.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,210 +0,0 @@
1
- """SPICE PWL export functionality for Oscura.
2
-
3
- This module provides export to SPICE Piece-Wise Linear (PWL) format for
4
- use in circuit simulation tools like LTspice, ngspice, Cadence, etc.
5
-
6
-
7
- Example:
8
- >>> from oscura.exporters.spice_export import export_pwl
9
- >>> export_pwl(trace, "stimulus.pwl")
10
- >>> # Use in SPICE: V1 in 0 PWL file=stimulus.pwl
11
- """
12
-
13
- from __future__ import annotations
14
-
15
- from pathlib import Path
16
- from typing import TYPE_CHECKING, Any
17
-
18
- import numpy as np
19
-
20
- from oscura.core.types import DigitalTrace, WaveformTrace
21
-
22
- if TYPE_CHECKING:
23
- from numpy.typing import NDArray
24
-
25
-
26
- def export_pwl(
27
- data: WaveformTrace | DigitalTrace | NDArray[Any] | tuple[NDArray[Any], NDArray[Any]],
28
- path: str | Path,
29
- *,
30
- time_scale: float = 1.0,
31
- amplitude_scale: float = 1.0,
32
- time_offset: float = 0.0,
33
- amplitude_offset: float = 0.0,
34
- precision: int = 12,
35
- comment: str | None = None,
36
- downsample: int = 1,
37
- format_style: str = "ltspice",
38
- ) -> None:
39
- """Export data to SPICE PWL (Piece-Wise Linear) format.
40
-
41
- Creates a PWL file that can be used as a stimulus source in SPICE
42
- circuit simulators. The format consists of time-value pairs.
43
-
44
- Args:
45
- data: Data to export. Can be:
46
- - WaveformTrace or DigitalTrace
47
- - NumPy array (uses trace.time_vector or generates index-based time)
48
- - Tuple of (time_array, value_array)
49
- path: Output file path.
50
- time_scale: Scaling factor for time values (e.g., 1e-9 for ns).
51
- amplitude_scale: Scaling factor for amplitude values.
52
- time_offset: Offset to add to all time values.
53
- amplitude_offset: Offset to add to all amplitude values.
54
- precision: Decimal precision for output values.
55
- comment: Optional comment to include at top of file.
56
- downsample: Downsample factor to reduce file size (1 = no downsampling).
57
- format_style: Output format style:
58
- - "ltspice": LTspice compatible (time value pairs)
59
- - "ngspice": ngspice compatible (same as ltspice)
60
- - "hspice": HSPICE compatible (with header)
61
-
62
- Raises:
63
- TypeError: If data type is not supported.
64
-
65
- Example:
66
- >>> # Export as stimulus for simulation
67
- >>> export_pwl(trace, "input.pwl")
68
- >>> # In LTspice: V1 in 0 PWL file=input.pwl
69
-
70
- >>> # Scale time to nanoseconds for display
71
- >>> export_pwl(trace, "input.pwl", time_scale=1e9)
72
-
73
- References:
74
- EXP-005
75
- """
76
- path = Path(path)
77
-
78
- # Extract time and value arrays
79
- if isinstance(data, WaveformTrace | DigitalTrace):
80
- time = data.time_vector
81
- values = data.data
82
- elif isinstance(data, tuple) and len(data) == 2:
83
- time, values = data
84
- elif isinstance(data, np.ndarray):
85
- # Generate time based on array index (assume 1 unit per sample)
86
- time = np.arange(len(data), dtype=np.float64)
87
- values = data
88
- else:
89
- raise TypeError(f"Unsupported data type: {type(data)}")
90
-
91
- # Apply downsampling
92
- if downsample > 1:
93
- time = time[::downsample]
94
- values = values[::downsample]
95
-
96
- # Apply scaling and offset
97
- time = time * time_scale + time_offset
98
- values = values * amplitude_scale + amplitude_offset
99
-
100
- # Write to file
101
- with open(path, "w") as f:
102
- # Write comment/header
103
- if format_style == "hspice":
104
- f.write("* HSPICE PWL Data\n")
105
- if comment:
106
- f.write(f"* {comment}\n")
107
- f.write(f"* Points: {len(time)}\n")
108
- f.write("*\n")
109
- elif comment:
110
- f.write(f"; {comment}\n")
111
-
112
- # Write time-value pairs
113
- fmt = f"{{:.{precision}g}} {{:.{precision}g}}\n"
114
- f.writelines(fmt.format(t, v) for t, v in zip(time, values, strict=False))
115
-
116
-
117
- def export_pwl_multi(
118
- traces: dict[str, WaveformTrace | DigitalTrace | NDArray[Any]],
119
- path: str | Path,
120
- *,
121
- time_scale: float = 1.0,
122
- amplitude_scale: float = 1.0,
123
- precision: int = 12,
124
- downsample: int = 1,
125
- ) -> None:
126
- """Export multiple traces to individual PWL files.
127
-
128
- Creates separate PWL files for each trace in the dictionary,
129
- with filenames based on the dictionary keys.
130
-
131
- Args:
132
- traces: Dictionary mapping signal names to trace data.
133
- path: Output directory path.
134
- time_scale: Scaling factor for time values.
135
- amplitude_scale: Scaling factor for amplitude values.
136
- precision: Decimal precision for output values.
137
- downsample: Downsample factor to reduce file size.
138
-
139
- Example:
140
- >>> traces = {
141
- ... "clk": clock_trace,
142
- ... "data": data_trace,
143
- ... "reset": reset_trace,
144
- ... }
145
- >>> export_pwl_multi(traces, "stimuli/")
146
- >>> # Creates: stimuli/clk.pwl, stimuli/data.pwl, stimuli/reset.pwl
147
-
148
- References:
149
- EXP-005
150
- """
151
- path = Path(path)
152
- path.mkdir(parents=True, exist_ok=True)
153
-
154
- for name, data in traces.items():
155
- # Sanitize filename
156
- safe_name = "".join(c if c.isalnum() or c in "_-" else "_" for c in name)
157
- file_path = path / f"{safe_name}.pwl"
158
-
159
- export_pwl(
160
- data,
161
- file_path,
162
- time_scale=time_scale,
163
- amplitude_scale=amplitude_scale,
164
- precision=precision,
165
- downsample=downsample,
166
- comment=f"Signal: {name}",
167
- )
168
-
169
-
170
- def generate_spice_source(
171
- pwl_path: str | Path,
172
- node_positive: str = "in",
173
- node_negative: str = "0",
174
- source_name: str = "V1",
175
- source_type: str = "voltage",
176
- ) -> str:
177
- """Generate SPICE source definition for a PWL file.
178
-
179
- Args:
180
- pwl_path: Path to PWL file.
181
- node_positive: Positive node name.
182
- node_negative: Negative node name (usually "0" for ground).
183
- source_name: Source instance name.
184
- source_type: Source type ("voltage" or "current").
185
-
186
- Returns:
187
- SPICE source definition string.
188
-
189
- Example:
190
- >>> line = generate_spice_source("input.pwl", "in", "0", "V1")
191
- >>> print(line)
192
- V1 in 0 PWL file=input.pwl
193
-
194
- References:
195
- EXP-005
196
- """
197
- prefix = "V" if source_type == "voltage" else "I"
198
-
199
- # Ensure source name starts with correct prefix
200
- if not source_name.upper().startswith(prefix):
201
- source_name = f"{prefix}{source_name}"
202
-
203
- return f"{source_name} {node_positive} {node_negative} PWL file={pwl_path}"
204
-
205
-
206
- __all__ = [
207
- "export_pwl",
208
- "export_pwl_multi",
209
- "generate_spice_source",
210
- ]
@@ -1,247 +0,0 @@
1
- """CSV export functions for vintage logic analysis results.
2
-
3
- This module provides specialized CSV exporters for vintage logic analysis data,
4
- including timing measurements, IC identification, and bill of materials.
5
-
6
- Example:
7
- >>> from oscura.exporters.vintage_logic_csv import export_bom_csv
8
- >>> export_bom_csv(result, "bom.csv")
9
- """
10
-
11
- from __future__ import annotations
12
-
13
- import csv
14
- from pathlib import Path
15
- from typing import TYPE_CHECKING
16
-
17
- if TYPE_CHECKING:
18
- from oscura.analyzers.digital.vintage_result import VintageLogicAnalysisResult
19
-
20
-
21
- def export_timing_measurements_csv(
22
- result: VintageLogicAnalysisResult,
23
- path: str | Path,
24
- ) -> None:
25
- """Export timing measurements to CSV.
26
-
27
- Creates a CSV file with columns: parameter, measured_value_ns, measurement_type.
28
-
29
- Args:
30
- result: Vintage logic analysis result.
31
- path: Output CSV file path.
32
-
33
- Example:
34
- >>> export_timing_measurements_csv(result, "timing.csv")
35
- """
36
- path = Path(path)
37
-
38
- with path.open("w", newline="") as csvfile:
39
- writer = csv.writer(csvfile)
40
-
41
- # Write header
42
- writer.writerow(["parameter", "measured_value_ns", "measurement_type"])
43
-
44
- # Write timing measurements
45
- for param_name, value in result.timing_measurements.items():
46
- # Determine measurement type from parameter name
47
- if "_t_pd" in param_name:
48
- meas_type = "propagation_delay"
49
- elif "_t_su" in param_name:
50
- meas_type = "setup_time"
51
- elif "_t_h" in param_name:
52
- meas_type = "hold_time"
53
- elif "_t_w" in param_name:
54
- meas_type = "pulse_width"
55
- else:
56
- meas_type = "other"
57
-
58
- writer.writerow([param_name, f"{value * 1e9:.3f}", meas_type])
59
-
60
-
61
- def export_ic_identification_csv(
62
- result: VintageLogicAnalysisResult,
63
- path: str | Path,
64
- ) -> None:
65
- """Export IC identification results to CSV.
66
-
67
- Creates a CSV file with columns: ic_name, confidence, family, timing_params,
68
- validation_status.
69
-
70
- Args:
71
- result: Vintage logic analysis result.
72
- path: Output CSV file path.
73
-
74
- Example:
75
- >>> export_ic_identification_csv(result, "ic_identification.csv")
76
- """
77
- path = Path(path)
78
-
79
- with path.open("w", newline="") as csvfile:
80
- writer = csv.writer(csvfile)
81
-
82
- # Write header
83
- writer.writerow(
84
- [
85
- "ic_name",
86
- "confidence",
87
- "family",
88
- "t_pd_ns",
89
- "t_su_ns",
90
- "t_h_ns",
91
- "t_w_ns",
92
- "validation_status",
93
- ]
94
- )
95
-
96
- # Write IC identification results
97
- for ic_result in result.identified_ics:
98
- # Extract timing parameters
99
- t_pd = ic_result.timing_params.get("t_pd", 0) * 1e9
100
- t_su = ic_result.timing_params.get("t_su", 0) * 1e9
101
- t_h = ic_result.timing_params.get("t_h", 0) * 1e9
102
- t_w = ic_result.timing_params.get("t_w", 0) * 1e9
103
-
104
- # Determine validation status
105
- validation_failed = any(v.get("passes") is False for v in ic_result.validation.values())
106
- validation_status = "FAIL" if validation_failed else "PASS"
107
-
108
- writer.writerow(
109
- [
110
- ic_result.ic_name,
111
- f"{ic_result.confidence:.3f}",
112
- ic_result.family,
113
- f"{t_pd:.3f}" if t_pd > 0 else "",
114
- f"{t_su:.3f}" if t_su > 0 else "",
115
- f"{t_h:.3f}" if t_h > 0 else "",
116
- f"{t_w:.3f}" if t_w > 0 else "",
117
- validation_status,
118
- ]
119
- )
120
-
121
-
122
- def export_bom_csv(
123
- result: VintageLogicAnalysisResult,
124
- path: str | Path,
125
- ) -> None:
126
- """Export bill of materials to CSV.
127
-
128
- Creates a CSV file compatible with spreadsheet programs and procurement systems.
129
- Columns: part_number, description, quantity, category, notes.
130
-
131
- Args:
132
- result: Vintage logic analysis result.
133
- path: Output CSV file path.
134
-
135
- Example:
136
- >>> export_bom_csv(result, "bom.csv")
137
- """
138
- path = Path(path)
139
-
140
- with path.open("w", newline="") as csvfile:
141
- writer = csv.writer(csvfile)
142
-
143
- # Write header
144
- writer.writerow(["part_number", "description", "quantity", "category", "notes"])
145
-
146
- # Write BOM entries
147
- for entry in result.bom:
148
- writer.writerow(
149
- [
150
- entry.part_number,
151
- entry.description,
152
- entry.quantity,
153
- entry.category,
154
- entry.notes or "",
155
- ]
156
- )
157
-
158
-
159
- def export_voltage_levels_csv(
160
- result: VintageLogicAnalysisResult,
161
- path: str | Path,
162
- ) -> None:
163
- """Export voltage levels to CSV.
164
-
165
- Creates a CSV file with measured voltage levels for the detected logic family.
166
-
167
- Args:
168
- result: Vintage logic analysis result.
169
- path: Output CSV file path.
170
-
171
- Example:
172
- >>> export_voltage_levels_csv(result, "voltage_levels.csv")
173
- """
174
- path = Path(path)
175
-
176
- with path.open("w", newline="") as csvfile:
177
- writer = csv.writer(csvfile)
178
-
179
- # Write header
180
- writer.writerow(["parameter", "voltage_v", "logic_family"])
181
-
182
- # Write voltage levels
183
- for param, value in result.voltage_levels.items():
184
- writer.writerow([param, f"{value:.3f}", result.detected_family])
185
-
186
-
187
- def export_all_vintage_logic_csv(
188
- result: VintageLogicAnalysisResult,
189
- output_dir: str | Path,
190
- *,
191
- prefix: str = "",
192
- ) -> dict[str, Path]:
193
- """Export all vintage logic analysis data to CSV files.
194
-
195
- Convenience function that exports all data types to separate CSV files.
196
-
197
- Args:
198
- result: Vintage logic analysis result.
199
- output_dir: Output directory for CSV files.
200
- prefix: Optional prefix for file names.
201
-
202
- Returns:
203
- Dictionary mapping data type to output file path.
204
-
205
- Example:
206
- >>> paths = export_all_vintage_logic_csv(result, "./output", prefix="analysis_")
207
- >>> print(paths["bom"]) # PosixPath('./output/analysis_bom.csv')
208
- """
209
- output_dir = Path(output_dir)
210
- output_dir.mkdir(parents=True, exist_ok=True)
211
-
212
- paths: dict[str, Path] = {}
213
-
214
- # Export timing measurements
215
- if result.timing_measurements:
216
- timing_path = output_dir / f"{prefix}timing_measurements.csv"
217
- export_timing_measurements_csv(result, timing_path)
218
- paths["timing_measurements"] = timing_path
219
-
220
- # Export IC identification
221
- if result.identified_ics:
222
- ic_path = output_dir / f"{prefix}ic_identification.csv"
223
- export_ic_identification_csv(result, ic_path)
224
- paths["ic_identification"] = ic_path
225
-
226
- # Export BOM
227
- if result.bom:
228
- bom_path = output_dir / f"{prefix}bom.csv"
229
- export_bom_csv(result, bom_path)
230
- paths["bom"] = bom_path
231
-
232
- # Export voltage levels
233
- if result.voltage_levels:
234
- voltage_path = output_dir / f"{prefix}voltage_levels.csv"
235
- export_voltage_levels_csv(result, voltage_path)
236
- paths["voltage_levels"] = voltage_path
237
-
238
- return paths
239
-
240
-
241
- __all__ = [
242
- "export_all_vintage_logic_csv",
243
- "export_bom_csv",
244
- "export_ic_identification_csv",
245
- "export_timing_measurements_csv",
246
- "export_voltage_levels_csv",
247
- ]