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,377 +0,0 @@
1
- """High-level vintage logic analysis API.
2
-
3
- This module provides a unified interface for complete vintage logic system analysis,
4
- orchestrating all analysis steps and returning consolidated results.
5
-
6
- Example:
7
- >>> from oscura.analyzers.digital.vintage import analyze_vintage_logic
8
- >>> result = analyze_vintage_logic(
9
- ... traces={"CLK": clk_trace, "DATA": data_trace},
10
- ... target_frequency=2e6
11
- ... )
12
- >>> print(f"Detected: {result.detected_family}")
13
- """
14
-
15
- from __future__ import annotations
16
-
17
- import time
18
- from datetime import datetime
19
- from typing import TYPE_CHECKING, Any, cast
20
-
21
- import numpy as np
22
-
23
- from oscura.analyzers.digital.extraction import (
24
- LOGIC_FAMILIES,
25
- detect_logic_family,
26
- detect_open_collector,
27
- )
28
- from oscura.analyzers.digital.ic_database import identify_ic, validate_ic_timing
29
- from oscura.analyzers.digital.timing import hold_time, propagation_delay, setup_time
30
- from oscura.analyzers.digital.timing_paths import TimingPathResult, analyze_timing_path
31
- from oscura.analyzers.digital.vintage_result import (
32
- BOMEntry,
33
- ICIdentificationResult,
34
- ModernReplacementIC,
35
- VintageLogicAnalysisResult,
36
- )
37
- from oscura.core.types import WaveformTrace
38
-
39
- if TYPE_CHECKING:
40
- from oscura.core.types import DigitalTrace, WaveformTrace
41
-
42
-
43
- # Modern IC replacement recommendations
44
- REPLACEMENT_DATABASE: dict[str, ModernReplacementIC] = {
45
- "7400": ModernReplacementIC(
46
- original_ic="7400",
47
- replacement_ic="74HCT00",
48
- family="74HCTxx",
49
- benefits=["Lower power", "Wider voltage range", "TTL-compatible inputs"],
50
- notes="HCT family maintains TTL compatibility with CMOS benefits",
51
- ),
52
- "7474": ModernReplacementIC(
53
- original_ic="7474",
54
- replacement_ic="74HCT74",
55
- family="74HCTxx",
56
- benefits=["Lower power", "Wider voltage range", "TTL-compatible inputs"],
57
- notes="HCT family maintains TTL compatibility with CMOS benefits",
58
- ),
59
- "74LS00": ModernReplacementIC(
60
- original_ic="74LS00",
61
- replacement_ic="74HCT00",
62
- family="74HCTxx",
63
- benefits=["Lower power", "Similar speed", "Better availability"],
64
- notes="Direct pin-compatible replacement",
65
- ),
66
- "74LS74": ModernReplacementIC(
67
- original_ic="74LS74",
68
- replacement_ic="74HCT74",
69
- family="74HCTxx",
70
- benefits=["Lower power", "Similar speed", "Better availability"],
71
- notes="Direct pin-compatible replacement",
72
- ),
73
- "74LS138": ModernReplacementIC(
74
- original_ic="74LS138",
75
- replacement_ic="74HCT138",
76
- family="74HCTxx",
77
- benefits=["Lower power", "Similar speed", "Better availability"],
78
- notes="Direct pin-compatible replacement",
79
- ),
80
- "74LS244": ModernReplacementIC(
81
- original_ic="74LS244",
82
- replacement_ic="74HCT244",
83
- family="74HCTxx",
84
- benefits=["Lower power", "Similar speed", "Better availability"],
85
- notes="Direct pin-compatible replacement",
86
- ),
87
- "74LS245": ModernReplacementIC(
88
- original_ic="74LS245",
89
- replacement_ic="74HCT245",
90
- family="74HCTxx",
91
- benefits=["Lower power", "Similar speed", "Better availability"],
92
- notes="Direct pin-compatible replacement",
93
- ),
94
- "74LS273": ModernReplacementIC(
95
- original_ic="74LS273",
96
- replacement_ic="74HCT273",
97
- family="74HCTxx",
98
- benefits=["Lower power", "Similar speed", "Better availability"],
99
- notes="Direct pin-compatible replacement",
100
- ),
101
- "74LS374": ModernReplacementIC(
102
- original_ic="74LS374",
103
- replacement_ic="74HCT374",
104
- family="74HCTxx",
105
- benefits=["Lower power", "Similar speed", "Better availability"],
106
- notes="Direct pin-compatible replacement",
107
- ),
108
- }
109
-
110
-
111
- def analyze_vintage_logic(
112
- traces: dict[str, WaveformTrace | DigitalTrace],
113
- *,
114
- target_frequency: float | None = None,
115
- system_description: str | None = None,
116
- enable_protocol_decode: bool = False,
117
- timing_paths: list[tuple[str, WaveformTrace, WaveformTrace]] | None = None,
118
- ) -> VintageLogicAnalysisResult:
119
- """Complete vintage logic system analysis.
120
-
121
- High-level API that orchestrates all vintage logic analysis steps and returns
122
- a comprehensive result object suitable for reporting and export.
123
-
124
- Args:
125
- traces: Dictionary mapping channel names to traces.
126
- target_frequency: Target system clock frequency in Hz.
127
- system_description: Optional description for documentation.
128
- enable_protocol_decode: Enable automatic protocol decoding (GPIB, ISA, etc.).
129
- timing_paths: Optional list of (ic_name, input_trace, output_trace) tuples
130
- for multi-IC timing path analysis.
131
-
132
- Returns:
133
- VintageLogicAnalysisResult object with complete analysis data.
134
-
135
- Example:
136
- >>> result = analyze_vintage_logic(
137
- ... traces={"CLK": clk_trace, "DATA": data_trace},
138
- ... target_frequency=2e6,
139
- ... system_description="1976 Microcomputer System"
140
- ... )
141
- >>> print(f"Detected: {result.detected_family}")
142
- >>> print(f"ICs: {[ic.ic_name for ic in result.identified_ics]}")
143
- """
144
- start_time = time.time()
145
- warnings: list[str] = []
146
- confidence_scores: dict[str, float] = {}
147
-
148
- # Use first trace for logic family detection
149
- first_trace_name = next(iter(traces.keys()))
150
- first_trace = traces[first_trace_name]
151
-
152
- # Ensure we have a WaveformTrace for voltage-based analysis
153
- if not hasattr(first_trace.data, "dtype") or first_trace.data.dtype == bool:
154
- warnings.append(
155
- f"Digital trace provided for {first_trace_name}, "
156
- "logic family detection may be inaccurate"
157
- )
158
- detected_family = "unknown"
159
- family_confidence = 0.0
160
- voltage_levels = {}
161
- else:
162
- # Step 1: Detect logic family
163
- # Type narrowing: we've verified this is a WaveformTrace above
164
- waveform_trace = cast("WaveformTrace", first_trace)
165
- detected_family, family_confidence = detect_logic_family(waveform_trace)
166
- confidence_scores["logic_family"] = family_confidence
167
-
168
- # Get voltage levels from detected family
169
- if detected_family in LOGIC_FAMILIES:
170
- voltage_levels = dict(LOGIC_FAMILIES[detected_family])
171
- else:
172
- voltage_levels = {}
173
- warnings.append(f"Unknown logic family: {detected_family}")
174
-
175
- # Step 2: Detect open-collector outputs
176
- open_collector_detected = False
177
- asymmetry_ratio = 1.0
178
- if hasattr(first_trace.data, "dtype") and first_trace.data.dtype != bool:
179
- waveform_trace = cast("WaveformTrace", first_trace)
180
- open_collector_detected, asymmetry_ratio = detect_open_collector(waveform_trace)
181
- if open_collector_detected:
182
- warnings.append(
183
- "Open-collector output detected - consider 10kΩ pull-up in modern design"
184
- )
185
-
186
- # Step 3: Measure timing parameters and identify ICs
187
- identified_ics: list[ICIdentificationResult] = []
188
- timing_measurements: dict[str, float] = {}
189
-
190
- # Analyze each trace pair for timing
191
- trace_list = list(traces.items())
192
- for i in range(len(trace_list) - 1):
193
- name1, trace1 = trace_list[i]
194
- name2, trace2 = trace_list[i + 1]
195
-
196
- # Measure propagation delay
197
- try:
198
- t_pd_raw = propagation_delay(trace1, trace2)
199
- t_pd = (
200
- float(t_pd_raw)
201
- if isinstance(t_pd_raw, (int, float, np.number))
202
- else float(t_pd_raw.item())
203
- )
204
- if t_pd > 0:
205
- timing_measurements[f"{name1}→{name2}_t_pd"] = t_pd
206
- except Exception as e:
207
- warnings.append(f"Failed to measure propagation delay {name1}→{name2}: {e}")
208
-
209
- # Measure setup and hold times if clock-like signal
210
- try:
211
- t_su_raw = setup_time(trace1, trace2)
212
- t_su = (
213
- float(t_su_raw)
214
- if isinstance(t_su_raw, (int, float, np.number))
215
- else float(t_su_raw.item())
216
- )
217
- if t_su > 0:
218
- timing_measurements[f"{name2}_t_su"] = t_su
219
- except Exception:
220
- pass # Optional measurement
221
-
222
- try:
223
- t_h_raw = hold_time(trace1, trace2)
224
- t_h = (
225
- float(t_h_raw)
226
- if isinstance(t_h_raw, (int, float, np.number))
227
- else float(t_h_raw.item())
228
- )
229
- if t_h > 0:
230
- timing_measurements[f"{name2}_t_h"] = t_h
231
- except Exception:
232
- pass # Optional measurement
233
-
234
- # Attempt IC identification from timing measurements
235
- if timing_measurements:
236
- # Extract core timing parameters
237
- core_params = {}
238
- for key, value in timing_measurements.items():
239
- if "_t_pd" in key:
240
- core_params["t_pd"] = value
241
- elif "_t_su" in key and "t_su" not in core_params:
242
- core_params["t_su"] = value
243
- elif "_t_h" in key and "t_h" not in core_params:
244
- core_params["t_h"] = value
245
-
246
- if core_params:
247
- ic_name, ic_confidence = identify_ic(core_params, tolerance=0.5)
248
- confidence_scores["ic_identification"] = ic_confidence
249
-
250
- if ic_name != "unknown":
251
- # Validate against database
252
- try:
253
- validation = validate_ic_timing(ic_name, core_params, tolerance=0.3)
254
-
255
- identified_ics.append(
256
- ICIdentificationResult(
257
- ic_name=ic_name,
258
- confidence=ic_confidence,
259
- timing_params=core_params,
260
- validation=validation,
261
- family=detected_family,
262
- )
263
- )
264
-
265
- # Check if any parameters fail validation
266
- failed_params = [k for k, v in validation.items() if v.get("passes") is False]
267
- if failed_params:
268
- warnings.append(
269
- f"IC {ic_name} timing validation failed for: {', '.join(failed_params)}"
270
- )
271
- except KeyError:
272
- warnings.append(f"IC {ic_name} not found in database")
273
-
274
- # Step 4: Analyze timing paths if provided
275
- timing_path_results: list[TimingPathResult] | None = None
276
- if timing_paths:
277
- try:
278
- path_result = analyze_timing_path(timing_paths, target_frequency=target_frequency)
279
- timing_path_results = [path_result]
280
-
281
- if not path_result.meets_timing:
282
- warnings.append(
283
- f"Timing path violation detected at stage {path_result.critical_stage_idx}"
284
- )
285
- except Exception as e:
286
- warnings.append(f"Timing path analysis failed: {e}")
287
-
288
- # Step 5: Protocol decoding (if enabled)
289
- decoded_protocols: dict[str, list[Any]] | None = None
290
- if enable_protocol_decode:
291
- # Protocol decoding would be implemented here
292
- # For now, just a placeholder
293
- decoded_protocols = {}
294
-
295
- # Step 6: Generate modern replacement recommendations
296
- modern_replacements: list[ModernReplacementIC] = []
297
- for ic_result in identified_ics:
298
- if ic_result.ic_name in REPLACEMENT_DATABASE:
299
- modern_replacements.append(REPLACEMENT_DATABASE[ic_result.ic_name])
300
-
301
- # Step 7: Generate BOM
302
- bom: list[BOMEntry] = []
303
-
304
- # Add identified ICs
305
- for ic_result in identified_ics:
306
- bom.append(
307
- BOMEntry(
308
- part_number=ic_result.ic_name,
309
- description=f"Original IC from {detected_family} family",
310
- quantity=1,
311
- category="IC",
312
- notes=f"Confidence: {ic_result.confidence * 100:.1f}%",
313
- )
314
- )
315
-
316
- # Add modern replacements
317
- for replacement in modern_replacements:
318
- bom.append(
319
- BOMEntry(
320
- part_number=replacement.replacement_ic,
321
- description=f"Modern replacement for {replacement.original_ic}",
322
- quantity=1,
323
- category="IC",
324
- notes=f"Benefits: {', '.join(replacement.benefits)}",
325
- )
326
- )
327
-
328
- # Add supporting components
329
- if open_collector_detected:
330
- bom.append(
331
- BOMEntry(
332
- part_number="Pull-up resistor",
333
- description="10kΩ resistor for open-collector pull-up",
334
- quantity=len(list(traces.values())),
335
- category="Resistor",
336
- notes="Use for all open-collector outputs",
337
- )
338
- )
339
-
340
- # Add decoupling capacitors (good practice)
341
- bom.append(
342
- BOMEntry(
343
- part_number="0.1µF ceramic capacitor",
344
- description="Decoupling capacitor",
345
- quantity=len(identified_ics) * 2,
346
- category="Capacitor",
347
- notes="One per IC, place close to VCC/GND pins",
348
- )
349
- )
350
-
351
- # Calculate analysis duration
352
- analysis_duration = time.time() - start_time
353
-
354
- return VintageLogicAnalysisResult(
355
- timestamp=datetime.now(),
356
- source_file=system_description,
357
- analysis_duration=analysis_duration,
358
- detected_family=detected_family,
359
- family_confidence=family_confidence,
360
- voltage_levels=voltage_levels,
361
- identified_ics=identified_ics,
362
- timing_measurements=timing_measurements,
363
- timing_paths=timing_path_results,
364
- decoded_protocols=decoded_protocols,
365
- open_collector_detected=open_collector_detected,
366
- asymmetry_ratio=asymmetry_ratio,
367
- modern_replacements=modern_replacements,
368
- bom=bom,
369
- warnings=warnings,
370
- confidence_scores=confidence_scores,
371
- )
372
-
373
-
374
- __all__ = [
375
- "REPLACEMENT_DATABASE",
376
- "analyze_vintage_logic",
377
- ]
@@ -1,148 +0,0 @@
1
- """Vintage logic analysis result data structures.
2
-
3
- This module defines dataclasses for aggregating vintage logic analysis results,
4
- enabling comprehensive reporting and export capabilities.
5
-
6
- Example:
7
- >>> from oscura.analyzers.digital.vintage_result import VintageLogicAnalysisResult
8
- >>> result = VintageLogicAnalysisResult(
9
- ... timestamp=datetime.now(),
10
- ... detected_family="TTL",
11
- ... family_confidence=0.95,
12
- ... # ... more fields ...
13
- ... )
14
- """
15
-
16
- from __future__ import annotations
17
-
18
- from dataclasses import dataclass, field
19
- from datetime import datetime
20
- from typing import TYPE_CHECKING, Any
21
-
22
- if TYPE_CHECKING:
23
- from oscura.analyzers.digital.timing_paths import TimingPathResult
24
-
25
-
26
- @dataclass
27
- class ICIdentificationResult:
28
- """Single IC identification result.
29
-
30
- Attributes:
31
- ic_name: Identified IC part number (e.g., "74LS74").
32
- confidence: Confidence score (0.0-1.0).
33
- timing_params: Measured timing parameters in seconds.
34
- validation: Validation results from validate_ic_timing().
35
- family: Logic family of the IC.
36
- """
37
-
38
- ic_name: str
39
- confidence: float
40
- timing_params: dict[str, float]
41
- validation: dict[str, dict[str, Any]]
42
- family: str
43
-
44
-
45
- @dataclass
46
- class ModernReplacementIC:
47
- """Modern IC recommendation for vintage part.
48
-
49
- Attributes:
50
- original_ic: Original vintage IC part number.
51
- replacement_ic: Recommended modern replacement.
52
- family: Replacement logic family (e.g., "74HCTxx").
53
- benefits: List of benefits (speed, power, availability).
54
- notes: Optional additional notes.
55
- """
56
-
57
- original_ic: str
58
- replacement_ic: str
59
- family: str
60
- benefits: list[str]
61
- notes: str | None = None
62
-
63
-
64
- @dataclass
65
- class BOMEntry:
66
- """Bill of materials entry.
67
-
68
- Attributes:
69
- part_number: Component part number.
70
- description: Component description.
71
- quantity: Number of components needed.
72
- category: Component category ("IC", "Capacitor", "Buffer", etc.).
73
- notes: Optional notes (pinout, alternatives, etc.).
74
- """
75
-
76
- part_number: str
77
- description: str
78
- quantity: int
79
- category: str
80
- notes: str | None = None
81
-
82
-
83
- @dataclass
84
- class VintageLogicAnalysisResult:
85
- """Complete vintage logic analysis result.
86
-
87
- Aggregates all analysis outputs for comprehensive reporting and export.
88
-
89
- Attributes:
90
- timestamp: Analysis timestamp.
91
- source_file: Source file path if loaded from file.
92
- analysis_duration: Analysis execution time in seconds.
93
- detected_family: Detected logic family name.
94
- family_confidence: Logic family detection confidence (0.0-1.0).
95
- voltage_levels: Measured voltage levels (VCC, VIL, VIH, VOL, VOH).
96
- identified_ics: List of identified ICs.
97
- timing_measurements: Dictionary of timing measurements in seconds.
98
- timing_paths: Multi-IC timing path analysis results.
99
- decoded_protocols: Protocol decoder results if applicable.
100
- open_collector_detected: Whether open-collector output detected.
101
- asymmetry_ratio: Rise/fall time asymmetry ratio.
102
- modern_replacements: List of modern IC recommendations.
103
- bom: Bill of materials entries.
104
- warnings: List of warning messages.
105
- confidence_scores: Dictionary of confidence scores by analysis type.
106
- """
107
-
108
- # Analysis metadata
109
- timestamp: datetime
110
- source_file: str | None
111
- analysis_duration: float
112
-
113
- # Logic family detection results
114
- detected_family: str
115
- family_confidence: float
116
- voltage_levels: dict[str, float] # VCC, VIL, VIH, VOL, VOH
117
-
118
- # IC identification results
119
- identified_ics: list[ICIdentificationResult] = field(default_factory=list)
120
-
121
- # Timing measurements
122
- timing_measurements: dict[str, float] = field(default_factory=dict)
123
-
124
- # Multi-IC path analysis
125
- timing_paths: list[TimingPathResult] | None = None
126
-
127
- # Protocol decoder results (if applicable)
128
- decoded_protocols: dict[str, list[Any]] | None = None
129
-
130
- # Open-collector detection
131
- open_collector_detected: bool = False
132
- asymmetry_ratio: float = 1.0
133
-
134
- # Recommendations
135
- modern_replacements: list[ModernReplacementIC] = field(default_factory=list)
136
- bom: list[BOMEntry] = field(default_factory=list)
137
-
138
- # Quality metrics
139
- warnings: list[str] = field(default_factory=list)
140
- confidence_scores: dict[str, float] = field(default_factory=dict)
141
-
142
-
143
- __all__ = [
144
- "BOMEntry",
145
- "ICIdentificationResult",
146
- "ModernReplacementIC",
147
- "VintageLogicAnalysisResult",
148
- ]