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,116 @@
1
+ """Power analysis module for Oscura.
2
+
3
+ Provides comprehensive power analysis capabilities including:
4
+ - Basic power measurements (instantaneous, average, RMS, peak)
5
+ - AC power analysis (reactive, apparent, power factor)
6
+ - Switching loss analysis for power electronics
7
+ - Safe Operating Area (SOA) analysis
8
+ - Ripple measurement
9
+ - Efficiency calculations
10
+
11
+
12
+ Example:
13
+ >>> from oscura.analyzers.power import instantaneous_power, power_statistics
14
+ >>> power_trace = instantaneous_power(voltage_trace, current_trace)
15
+ >>> stats = power_statistics(power_trace)
16
+ >>> print(f"Average power: {stats['average']:.2f} W")
17
+ """
18
+
19
+ from oscura.analyzers.power.ac_power import (
20
+ apparent_power,
21
+ displacement_power_factor,
22
+ distortion_power_factor,
23
+ phase_angle,
24
+ power_factor,
25
+ reactive_power,
26
+ total_harmonic_distortion_power,
27
+ )
28
+ from oscura.analyzers.power.basic import (
29
+ average_power,
30
+ energy,
31
+ instantaneous_power,
32
+ peak_power,
33
+ power_statistics,
34
+ rms_power,
35
+ )
36
+ from oscura.analyzers.power.conduction import (
37
+ conduction_loss,
38
+ duty_cycle_weighted_loss,
39
+ forward_voltage,
40
+ mosfet_conduction_loss,
41
+ on_resistance,
42
+ )
43
+ from oscura.analyzers.power.efficiency import (
44
+ efficiency,
45
+ multi_output_efficiency,
46
+ power_conversion_efficiency,
47
+ )
48
+ from oscura.analyzers.power.ripple import (
49
+ extract_ripple,
50
+ ripple,
51
+ ripple_frequency,
52
+ ripple_percentage,
53
+ ripple_statistics,
54
+ )
55
+ from oscura.analyzers.power.soa import (
56
+ SOALimit,
57
+ check_soa_violations,
58
+ create_mosfet_soa,
59
+ plot_soa,
60
+ soa_analysis,
61
+ )
62
+ from oscura.analyzers.power.switching import (
63
+ switching_energy,
64
+ switching_frequency,
65
+ switching_loss,
66
+ total_switching_loss,
67
+ turn_off_loss,
68
+ turn_on_loss,
69
+ )
70
+
71
+ __all__ = [
72
+ "SOALimit",
73
+ "apparent_power",
74
+ "average_power",
75
+ "check_soa_violations",
76
+ # Conduction
77
+ "conduction_loss",
78
+ "create_mosfet_soa",
79
+ "displacement_power_factor",
80
+ "distortion_power_factor",
81
+ "duty_cycle_weighted_loss",
82
+ # Efficiency
83
+ "efficiency",
84
+ "energy",
85
+ "extract_ripple",
86
+ "forward_voltage",
87
+ # Basic power
88
+ "instantaneous_power",
89
+ "mosfet_conduction_loss",
90
+ "multi_output_efficiency",
91
+ "on_resistance",
92
+ "peak_power",
93
+ "phase_angle",
94
+ "plot_soa",
95
+ "power_conversion_efficiency",
96
+ "power_factor",
97
+ "power_statistics",
98
+ # AC power
99
+ "reactive_power",
100
+ # Ripple
101
+ "ripple",
102
+ "ripple_frequency",
103
+ "ripple_percentage",
104
+ "ripple_statistics",
105
+ "rms_power",
106
+ # SOA
107
+ "soa_analysis",
108
+ "switching_energy",
109
+ "switching_frequency",
110
+ # Switching
111
+ "switching_loss",
112
+ "total_harmonic_distortion_power",
113
+ "total_switching_loss",
114
+ "turn_off_loss",
115
+ "turn_on_loss",
116
+ ]
@@ -0,0 +1,391 @@
1
+ """AC power analysis for Oscura.
2
+
3
+ Provides AC power calculations including reactive power, apparent power,
4
+ power factor, and harmonic analysis.
5
+
6
+
7
+ Example:
8
+ >>> from oscura.analyzers.power.ac_power import power_factor, reactive_power
9
+ >>> pf = power_factor(voltage_trace, current_trace)
10
+ >>> q = reactive_power(voltage_trace, current_trace)
11
+ >>> print(f"Power factor: {pf:.3f}, Reactive power: {q:.2f} VAR")
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import numpy as np
17
+
18
+ from oscura.analyzers.power.basic import average_power
19
+ from oscura.core.types import WaveformTrace
20
+
21
+
22
+ def phase_angle(
23
+ voltage: WaveformTrace,
24
+ current: WaveformTrace,
25
+ ) -> float:
26
+ """Calculate phase angle between voltage and current.
27
+
28
+ Uses cross-correlation to determine the phase shift.
29
+
30
+ Args:
31
+ voltage: Voltage waveform trace.
32
+ current: Current waveform trace.
33
+
34
+ Returns:
35
+ Phase angle in radians (positive = current lags voltage).
36
+
37
+ Example:
38
+ >>> phi = phase_angle(v_trace, i_trace)
39
+ >>> print(f"Phase angle: {np.degrees(phi):.1f} degrees")
40
+ """
41
+ v_data = voltage.data
42
+ i_data = current.data
43
+
44
+ # Ensure same length
45
+ min_len = min(len(v_data), len(i_data))
46
+ v_data = v_data[:min_len]
47
+ i_data = i_data[:min_len]
48
+
49
+ # Remove DC offset
50
+ v_ac = v_data - np.mean(v_data)
51
+ i_ac = i_data - np.mean(i_data)
52
+
53
+ # Cross-correlation to find phase shift
54
+ # correlate(v, i) tells us how much to shift i to align with v
55
+ # A positive lag means i needs to be shifted right (i lags v)
56
+ correlation = np.correlate(v_ac, i_ac, mode="full")
57
+ lags = np.arange(-len(i_ac) + 1, len(v_ac))
58
+
59
+ # Find peak correlation
60
+ peak_idx = np.argmax(np.abs(correlation))
61
+ lag_samples = lags[peak_idx]
62
+
63
+ # Convert lag to phase angle
64
+ # Estimate frequency using zero crossings
65
+ v_crossings = np.where(np.diff(np.signbit(v_ac)))[0]
66
+ if len(v_crossings) >= 2:
67
+ period_samples = 2 * np.mean(np.diff(v_crossings))
68
+ # Negative lag because correlation gives us how much to shift i to align with v
69
+ # If lag is negative, i is ahead of v (capacitive), phase should be negative
70
+ # If lag is positive, i is behind v (inductive), phase should be positive
71
+ phase = -2 * np.pi * lag_samples / period_samples
72
+ else:
73
+ # Fallback: use FFT to find fundamental frequency
74
+ fft_v = np.fft.rfft(v_ac)
75
+ freq_idx = np.argmax(np.abs(fft_v[1:])) + 1
76
+ period_samples = len(v_ac) / freq_idx
77
+ phase = -2 * np.pi * lag_samples / period_samples
78
+
79
+ return float(phase)
80
+
81
+
82
+ def reactive_power(
83
+ voltage: WaveformTrace,
84
+ current: WaveformTrace,
85
+ *,
86
+ frequency: float | None = None,
87
+ ) -> float:
88
+ """Calculate reactive power (Q) in VAR.
89
+
90
+ Q = V_rms * I_rms * sin(phi)
91
+
92
+ Args:
93
+ voltage: Voltage waveform trace.
94
+ current: Current waveform trace.
95
+ frequency: Fundamental frequency in Hz. If None, auto-detect.
96
+
97
+ Returns:
98
+ Reactive power in VAR (positive = inductive, negative = capacitive).
99
+
100
+ Example:
101
+ >>> q = reactive_power(v_trace, i_trace)
102
+ >>> print(f"Reactive power: {q:.2f} VAR")
103
+
104
+ References:
105
+ IEEE 1459-2010 (Power quality definitions)
106
+ """
107
+ v_data = voltage.data
108
+ i_data = current.data
109
+
110
+ # Ensure same length
111
+ min_len = min(len(v_data), len(i_data))
112
+ v_data = v_data[:min_len]
113
+ i_data = i_data[:min_len]
114
+
115
+ # Calculate RMS values
116
+ v_rms = float(np.sqrt(np.mean(v_data**2)))
117
+ i_rms = float(np.sqrt(np.mean(i_data**2)))
118
+
119
+ # Calculate phase angle
120
+ phi = phase_angle(voltage, current)
121
+
122
+ return v_rms * i_rms * np.sin(phi) # type: ignore[no-any-return]
123
+
124
+
125
+ def apparent_power(
126
+ voltage: WaveformTrace,
127
+ current: WaveformTrace,
128
+ ) -> float:
129
+ """Calculate apparent power (S) in VA.
130
+
131
+ S = V_rms * I_rms
132
+
133
+ Args:
134
+ voltage: Voltage waveform trace.
135
+ current: Current waveform trace.
136
+
137
+ Returns:
138
+ Apparent power in VA.
139
+
140
+ Example:
141
+ >>> s = apparent_power(v_trace, i_trace)
142
+ >>> print(f"Apparent power: {s:.2f} VA")
143
+
144
+ References:
145
+ IEEE 1459-2010 (Power quality definitions)
146
+ """
147
+ v_data = voltage.data
148
+ i_data = current.data
149
+
150
+ # Ensure same length
151
+ min_len = min(len(v_data), len(i_data))
152
+ v_data = v_data[:min_len]
153
+ i_data = i_data[:min_len]
154
+
155
+ v_rms = float(np.sqrt(np.mean(v_data**2)))
156
+ i_rms = float(np.sqrt(np.mean(i_data**2)))
157
+
158
+ return v_rms * i_rms
159
+
160
+
161
+ def power_factor(
162
+ voltage: WaveformTrace,
163
+ current: WaveformTrace,
164
+ ) -> float:
165
+ """Calculate power factor (PF = P / S).
166
+
167
+ For sinusoidal waveforms, PF = cos(phi).
168
+ For non-sinusoidal waveforms, includes distortion effects.
169
+
170
+ Args:
171
+ voltage: Voltage waveform trace.
172
+ current: Current waveform trace.
173
+
174
+ Returns:
175
+ Power factor (0 to 1, can be negative for regeneration).
176
+
177
+ Example:
178
+ >>> pf = power_factor(v_trace, i_trace)
179
+ >>> print(f"Power factor: {pf:.3f}")
180
+
181
+ References:
182
+ IEEE 1459-2010
183
+ """
184
+ p = average_power(voltage=voltage, current=current)
185
+ s = apparent_power(voltage, current)
186
+
187
+ if s == 0:
188
+ return 0.0
189
+
190
+ return p / s
191
+
192
+
193
+ def displacement_power_factor(
194
+ voltage: WaveformTrace,
195
+ current: WaveformTrace,
196
+ ) -> float:
197
+ """Calculate displacement power factor (DPF).
198
+
199
+ DPF = cos(phi) where phi is the phase angle between fundamental
200
+ components of voltage and current.
201
+
202
+ Args:
203
+ voltage: Voltage waveform trace.
204
+ current: Current waveform trace.
205
+
206
+ Returns:
207
+ Displacement power factor.
208
+
209
+ Example:
210
+ >>> dpf = displacement_power_factor(v_trace, i_trace)
211
+ """
212
+ # Extract fundamental components
213
+ v_fund = _extract_fundamental(voltage)
214
+ i_fund = _extract_fundamental(current)
215
+
216
+ # Calculate phase angle of fundamentals
217
+ phi = phase_angle(v_fund, i_fund)
218
+
219
+ return float(np.cos(phi))
220
+
221
+
222
+ def distortion_power_factor(
223
+ voltage: WaveformTrace,
224
+ current: WaveformTrace,
225
+ ) -> float:
226
+ """Calculate distortion power factor.
227
+
228
+ Distortion PF = True PF / Displacement PF
229
+ = sqrt(1 / (1 + THD_i^2)) (for sinusoidal voltage)
230
+
231
+ Args:
232
+ voltage: Voltage waveform trace.
233
+ current: Current waveform trace.
234
+
235
+ Returns:
236
+ Distortion power factor.
237
+
238
+ Example:
239
+ >>> dist_pf = distortion_power_factor(v_trace, i_trace)
240
+ """
241
+ pf = power_factor(voltage, current)
242
+ dpf = displacement_power_factor(voltage, current)
243
+
244
+ if dpf == 0:
245
+ return 0.0
246
+
247
+ return pf / dpf
248
+
249
+
250
+ def total_harmonic_distortion_power(
251
+ trace: WaveformTrace,
252
+ fundamental_freq: float | None = None,
253
+ max_harmonic: int = 50,
254
+ ) -> float:
255
+ """Calculate Total Harmonic Distortion for power analysis.
256
+
257
+ THD = sqrt(sum(V_h^2 for h=2..N)) / V_1
258
+
259
+ Args:
260
+ trace: Voltage or current waveform.
261
+ fundamental_freq: Fundamental frequency. If None, auto-detect.
262
+ max_harmonic: Maximum harmonic order to include.
263
+
264
+ Returns:
265
+ THD as a ratio (not percentage).
266
+
267
+ Example:
268
+ >>> thd = total_harmonic_distortion_power(current_trace)
269
+ >>> print(f"Current THD: {thd*100:.1f}%")
270
+ """
271
+ data = trace.data
272
+ sample_rate = trace.metadata.sample_rate
273
+
274
+ # FFT
275
+ n = len(data)
276
+ fft_result = np.fft.rfft(data)
277
+ freqs = np.fft.rfftfreq(n, 1 / sample_rate)
278
+
279
+ # Find fundamental
280
+ if fundamental_freq is None:
281
+ # Auto-detect: find largest peak above DC
282
+ magnitudes = np.abs(fft_result[1:])
283
+ fund_idx = int(np.argmax(magnitudes)) + 1
284
+ fundamental_freq = freqs[fund_idx]
285
+ else:
286
+ fund_idx = int(np.round(fundamental_freq * n / sample_rate))
287
+
288
+ # Get fundamental magnitude
289
+ v1 = np.abs(fft_result[fund_idx])
290
+ if v1 == 0:
291
+ return 0.0
292
+
293
+ # Sum harmonic magnitudes
294
+ harmonic_sum_sq = 0.0
295
+ for h in range(2, max_harmonic + 1):
296
+ h_idx = h * fund_idx
297
+ if h_idx < len(fft_result):
298
+ harmonic_sum_sq += np.abs(fft_result[h_idx]) ** 2
299
+
300
+ return float(np.sqrt(harmonic_sum_sq) / v1)
301
+
302
+
303
+ def _extract_fundamental(trace: WaveformTrace) -> WaveformTrace:
304
+ """Extract fundamental component of a waveform."""
305
+ data = trace.data
306
+ n = len(data)
307
+
308
+ # FFT
309
+ fft_result = np.fft.rfft(data)
310
+
311
+ # Find fundamental peak
312
+ magnitudes = np.abs(fft_result[1:])
313
+ fund_idx = np.argmax(magnitudes) + 1
314
+
315
+ # Zero out all but fundamental
316
+ filtered_fft = np.zeros_like(fft_result)
317
+ filtered_fft[fund_idx] = fft_result[fund_idx]
318
+
319
+ # Inverse FFT
320
+ fundamental = np.fft.irfft(filtered_fft, n=n)
321
+
322
+ return WaveformTrace(
323
+ data=fundamental.astype(np.float64),
324
+ metadata=trace.metadata,
325
+ )
326
+
327
+
328
+ def three_phase_power(
329
+ v_a: WaveformTrace,
330
+ v_b: WaveformTrace,
331
+ v_c: WaveformTrace,
332
+ i_a: WaveformTrace,
333
+ i_b: WaveformTrace,
334
+ i_c: WaveformTrace,
335
+ ) -> dict[str, float]:
336
+ """Calculate three-phase power quantities.
337
+
338
+ Args:
339
+ v_a: Phase A voltage trace.
340
+ v_b: Phase B voltage trace.
341
+ v_c: Phase C voltage trace.
342
+ i_a: Phase A current trace.
343
+ i_b: Phase B current trace.
344
+ i_c: Phase C current trace.
345
+
346
+ Returns:
347
+ Dictionary with:
348
+ - total_active: Total active power (W)
349
+ - total_reactive: Total reactive power (VAR)
350
+ - total_apparent: Total apparent power (VA)
351
+ - power_factor: Three-phase power factor
352
+ - phase_a_power: Phase A active power
353
+ - phase_b_power: Phase B active power
354
+ - phase_c_power: Phase C active power
355
+ """
356
+ # Calculate per-phase powers
357
+ p_a = average_power(voltage=v_a, current=i_a)
358
+ p_b = average_power(voltage=v_b, current=i_b)
359
+ p_c = average_power(voltage=v_c, current=i_c)
360
+
361
+ q_a = reactive_power(v_a, i_a)
362
+ q_b = reactive_power(v_b, i_b)
363
+ q_c = reactive_power(v_c, i_c)
364
+
365
+ total_p = p_a + p_b + p_c
366
+ total_q = q_a + q_b + q_c
367
+ total_s = np.sqrt(total_p**2 + total_q**2)
368
+
369
+ pf = total_p / total_s if total_s != 0 else 0.0
370
+
371
+ return {
372
+ "total_active": total_p,
373
+ "total_reactive": total_q,
374
+ "total_apparent": total_s,
375
+ "power_factor": pf,
376
+ "phase_a_power": p_a,
377
+ "phase_b_power": p_b,
378
+ "phase_c_power": p_c,
379
+ }
380
+
381
+
382
+ __all__ = [
383
+ "apparent_power",
384
+ "displacement_power_factor",
385
+ "distortion_power_factor",
386
+ "phase_angle",
387
+ "power_factor",
388
+ "reactive_power",
389
+ "three_phase_power",
390
+ "total_harmonic_distortion_power",
391
+ ]