oscura 0.1.0__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 (212) hide show
  1. oscura/__init__.py +14 -14
  2. oscura/__main__.py +9 -9
  3. oscura/analyzers/__init__.py +1 -1
  4. oscura/analyzers/packet/daq.py +1 -1
  5. oscura/analyzers/patterns/__init__.py +2 -2
  6. oscura/analyzers/patterns/clustering.py +1 -1
  7. oscura/analyzers/patterns/discovery.py +1 -1
  8. oscura/analyzers/patterns/periodic.py +1 -1
  9. oscura/analyzers/patterns/sequences.py +1 -1
  10. oscura/analyzers/power/__init__.py +1 -1
  11. oscura/analyzers/power/ac_power.py +1 -1
  12. oscura/analyzers/power/basic.py +1 -1
  13. oscura/analyzers/power/conduction.py +1 -1
  14. oscura/analyzers/power/efficiency.py +1 -1
  15. oscura/analyzers/power/ripple.py +1 -1
  16. oscura/analyzers/power/soa.py +1 -1
  17. oscura/analyzers/power/switching.py +1 -1
  18. oscura/api/__init__.py +1 -1
  19. oscura/automotive/__init__.py +1 -1
  20. oscura/automotive/can/checksum.py +2 -2
  21. oscura/automotive/can/session.py +1 -1
  22. oscura/automotive/can/state_machine.py +1 -1
  23. oscura/automotive/dbc/generator.py +1 -1
  24. oscura/automotive/dbc/parser.py +1 -1
  25. oscura/automotive/loaders/pcap.py +1 -1
  26. oscura/batch/__init__.py +1 -1
  27. oscura/batch/aggregate.py +2 -2
  28. oscura/batch/analyze.py +3 -3
  29. oscura/builders/__init__.py +7 -7
  30. oscura/builders/signal_builder.py +4 -4
  31. oscura/cli/__init__.py +1 -1
  32. oscura/cli/batch.py +1 -1
  33. oscura/cli/characterize.py +2 -2
  34. oscura/cli/compare.py +4 -4
  35. oscura/cli/decode.py +1 -1
  36. oscura/cli/main.py +8 -8
  37. oscura/cli/shell.py +19 -19
  38. oscura/comparison/__init__.py +1 -1
  39. oscura/comparison/compare.py +1 -1
  40. oscura/comparison/golden.py +1 -1
  41. oscura/comparison/limits.py +1 -1
  42. oscura/comparison/mask.py +1 -1
  43. oscura/comparison/trace_diff.py +1 -1
  44. oscura/compliance/__init__.py +2 -2
  45. oscura/compliance/reporting.py +2 -2
  46. oscura/component/__init__.py +1 -1
  47. oscura/component/impedance.py +1 -1
  48. oscura/component/reactive.py +1 -1
  49. oscura/component/transmission_line.py +1 -1
  50. oscura/config/__init__.py +1 -1
  51. oscura/config/loader.py +1 -1
  52. oscura/config/memory.py +3 -3
  53. oscura/config/migration.py +1 -1
  54. oscura/config/preferences.py +1 -1
  55. oscura/config/schema.py +3 -3
  56. oscura/config/settings.py +1 -1
  57. oscura/convenience.py +13 -13
  58. oscura/core/__init__.py +6 -6
  59. oscura/core/cache.py +10 -10
  60. oscura/core/cancellation.py +1 -1
  61. oscura/core/confidence.py +1 -1
  62. oscura/core/config.py +1 -1
  63. oscura/core/correlation.py +1 -1
  64. oscura/core/debug.py +4 -4
  65. oscura/core/edge_cases.py +1 -1
  66. oscura/core/exceptions.py +14 -14
  67. oscura/core/gpu_backend.py +5 -5
  68. oscura/core/lazy.py +3 -3
  69. oscura/core/logging.py +6 -6
  70. oscura/core/logging_advanced.py +1 -1
  71. oscura/core/memoize.py +3 -3
  72. oscura/core/memory_check.py +1 -1
  73. oscura/core/memory_guard.py +1 -1
  74. oscura/core/memory_limits.py +1 -1
  75. oscura/core/memory_monitor.py +1 -1
  76. oscura/core/memory_progress.py +1 -1
  77. oscura/core/memory_warnings.py +1 -1
  78. oscura/core/progress.py +1 -1
  79. oscura/core/provenance.py +5 -5
  80. oscura/core/results.py +3 -3
  81. oscura/core/types.py +1 -1
  82. oscura/core/uncertainty.py +1 -1
  83. oscura/discovery/__init__.py +4 -4
  84. oscura/discovery/comparison.py +1 -1
  85. oscura/dsl/__init__.py +1 -1
  86. oscura/dsl/commands.py +22 -22
  87. oscura/dsl/interpreter.py +4 -4
  88. oscura/dsl/parser.py +4 -4
  89. oscura/dsl/repl.py +4 -4
  90. oscura/exceptions.py +3 -3
  91. oscura/export/__init__.py +2 -2
  92. oscura/export/wireshark/__init__.py +1 -1
  93. oscura/export/wireshark/generator.py +2 -2
  94. oscura/export/wireshark/templates/dissector.lua.j2 +1 -1
  95. oscura/export/wireshark/type_mapping.py +8 -8
  96. oscura/exporters/__init__.py +3 -3
  97. oscura/exporters/csv.py +1 -1
  98. oscura/exporters/html_export.py +5 -5
  99. oscura/exporters/json_export.py +9 -9
  100. oscura/exporters/markdown_export.py +3 -3
  101. oscura/exporters/npz_export.py +1 -1
  102. oscura/exporters/spice_export.py +1 -1
  103. oscura/extensibility/__init__.py +1 -1
  104. oscura/extensibility/docs.py +1 -1
  105. oscura/extensibility/extensions.py +7 -7
  106. oscura/extensibility/measurements.py +12 -12
  107. oscura/extensibility/plugins.py +12 -12
  108. oscura/extensibility/registry.py +12 -12
  109. oscura/extensibility/templates.py +16 -16
  110. oscura/extensibility/validation.py +3 -3
  111. oscura/filtering/__init__.py +1 -1
  112. oscura/filtering/base.py +1 -1
  113. oscura/filtering/convenience.py +1 -1
  114. oscura/filtering/design.py +1 -1
  115. oscura/filtering/introspection.py +1 -1
  116. oscura/guidance/__init__.py +1 -1
  117. oscura/guidance/recommender.py +1 -1
  118. oscura/guidance/wizard.py +1 -1
  119. oscura/inference/__init__.py +1 -1
  120. oscura/inference/adaptive_tuning.py +3 -3
  121. oscura/inference/logic.py +5 -5
  122. oscura/inference/protocol.py +5 -5
  123. oscura/inference/signal_intelligence.py +19 -19
  124. oscura/inference/spectral.py +6 -6
  125. oscura/integrations/__init__.py +1 -1
  126. oscura/integrations/llm.py +6 -6
  127. oscura/jupyter/__init__.py +3 -3
  128. oscura/jupyter/display.py +1 -1
  129. oscura/jupyter/magic.py +31 -31
  130. oscura/loaders/__init__.py +10 -10
  131. oscura/loaders/mmap_loader.py +1 -1
  132. oscura/loaders/pcap.py +1 -1
  133. oscura/math/__init__.py +1 -1
  134. oscura/math/arithmetic.py +1 -1
  135. oscura/math/interpolation.py +1 -1
  136. oscura/onboarding/__init__.py +1 -1
  137. oscura/onboarding/help.py +18 -18
  138. oscura/onboarding/tutorials.py +29 -29
  139. oscura/onboarding/wizard.py +22 -22
  140. oscura/pipeline/composition.py +15 -15
  141. oscura/pipeline/pipeline.py +10 -10
  142. oscura/plugins/__init__.py +2 -2
  143. oscura/plugins/base.py +5 -5
  144. oscura/plugins/discovery.py +6 -6
  145. oscura/plugins/registry.py +6 -6
  146. oscura/plugins/versioning.py +2 -2
  147. oscura/quality/__init__.py +1 -1
  148. oscura/quality/scoring.py +1 -1
  149. oscura/quality/warnings.py +1 -1
  150. oscura/reporting/__init__.py +1 -1
  151. oscura/reporting/advanced.py +1 -1
  152. oscura/reporting/analyze.py +1 -1
  153. oscura/reporting/auto_report.py +2 -2
  154. oscura/reporting/batch.py +3 -3
  155. oscura/reporting/chart_selection.py +1 -1
  156. oscura/reporting/comparison.py +1 -1
  157. oscura/reporting/core.py +4 -4
  158. oscura/reporting/export.py +1 -1
  159. oscura/reporting/formatting.py +1 -1
  160. oscura/reporting/html.py +3 -3
  161. oscura/reporting/multichannel.py +1 -1
  162. oscura/reporting/output.py +1 -1
  163. oscura/reporting/pdf.py +2 -2
  164. oscura/reporting/pptx_export.py +1 -1
  165. oscura/reporting/sections.py +1 -1
  166. oscura/reporting/standards.py +2 -2
  167. oscura/reporting/summary_generator.py +1 -1
  168. oscura/reporting/tables.py +1 -1
  169. oscura/reporting/template_system.py +1 -1
  170. oscura/reporting/templates/index.html +2 -2
  171. oscura/schemas/__init__.py +2 -2
  172. oscura/schemas/bus_configuration.json +1 -1
  173. oscura/schemas/device_mapping.json +1 -1
  174. oscura/schemas/packet_format.json +1 -1
  175. oscura/schemas/protocol_definition.json +1 -1
  176. oscura/search/__init__.py +1 -1
  177. oscura/session/__init__.py +4 -4
  178. oscura/session/history.py +7 -7
  179. oscura/session/session.py +2 -2
  180. oscura/streaming/chunked.py +7 -7
  181. oscura/testing/__init__.py +1 -1
  182. oscura/triggering/__init__.py +1 -1
  183. oscura/triggering/base.py +1 -1
  184. oscura/triggering/edge.py +1 -1
  185. oscura/triggering/pattern.py +1 -1
  186. oscura/triggering/pulse.py +1 -1
  187. oscura/triggering/window.py +1 -1
  188. oscura/ui/__init__.py +1 -1
  189. oscura/ui/formatters.py +1 -1
  190. oscura/ui/progressive_display.py +1 -1
  191. oscura/utils/__init__.py +1 -1
  192. oscura/utils/memory.py +3 -3
  193. oscura/utils/memory_extensions.py +1 -1
  194. oscura/visualization/__init__.py +1 -1
  195. oscura/visualization/accessibility.py +1 -1
  196. oscura/visualization/keyboard.py +1 -1
  197. oscura/visualization/palettes.py +1 -1
  198. oscura/visualization/spectral.py +9 -9
  199. oscura/visualization/waveform.py +4 -4
  200. oscura/workflows/__init__.py +5 -5
  201. oscura/workflows/compliance.py +5 -5
  202. oscura/workflows/digital.py +5 -5
  203. oscura/workflows/multi_trace.py +25 -25
  204. oscura/workflows/power.py +7 -7
  205. oscura/workflows/protocol.py +5 -5
  206. oscura/workflows/reverse_engineering.py +5 -5
  207. oscura/workflows/signal_integrity.py +6 -6
  208. {oscura-0.1.0.dist-info → oscura-0.1.1.dist-info}/METADATA +11 -11
  209. {oscura-0.1.0.dist-info → oscura-0.1.1.dist-info}/RECORD +212 -212
  210. {oscura-0.1.0.dist-info → oscura-0.1.1.dist-info}/WHEEL +0 -0
  211. {oscura-0.1.0.dist-info → oscura-0.1.1.dist-info}/entry_points.txt +0 -0
  212. {oscura-0.1.0.dist-info → oscura-0.1.1.dist-info}/licenses/LICENSE +0 -0
oscura/jupyter/magic.py CHANGED
@@ -1,4 +1,4 @@
1
- """IPython magic commands for TraceKit.
1
+ """IPython magic commands for Oscura.
2
2
 
3
3
  This module provides IPython/Jupyter magic commands for convenient
4
4
  trace analysis in notebooks.
@@ -82,8 +82,8 @@ except ImportError:
82
82
 
83
83
 
84
84
  @magics_class
85
- class TracekitMagics(Magics): # type: ignore[misc]
86
- """IPython magics for TraceKit analysis.
85
+ class OscuraMagics(Magics): # type: ignore[misc]
86
+ """IPython magics for Oscura analysis.
87
87
 
88
88
  Provides convenient shortcuts for loading traces, running measurements,
89
89
  and displaying results in Jupyter notebooks.
@@ -91,7 +91,7 @@ class TracekitMagics(Magics): # type: ignore[misc]
91
91
 
92
92
  @line_magic # type: ignore[misc, untyped-decorator]
93
93
  def oscura(self, line: str) -> Any:
94
- """TraceKit line magic for quick operations.
94
+ """Oscura line magic for quick operations.
95
95
 
96
96
  Usage:
97
97
  %oscura load <filename> - Load a trace file
@@ -106,7 +106,7 @@ class TracekitMagics(Magics): # type: ignore[misc]
106
106
  Returns:
107
107
  Command result or None
108
108
  """
109
- import oscura as tk
109
+ import oscura as osc
110
110
 
111
111
  parts = line.strip().split()
112
112
  if not parts:
@@ -129,7 +129,7 @@ class TracekitMagics(Magics): # type: ignore[misc]
129
129
  return self._show_trace_info()
130
130
 
131
131
  elif cmd == "formats":
132
- formats = tk.get_supported_formats()
132
+ formats = osc.get_supported_formats()
133
133
  print("Supported formats:")
134
134
  for fmt in formats:
135
135
  print(f" - {fmt}")
@@ -144,10 +144,10 @@ class TracekitMagics(Magics): # type: ignore[misc]
144
144
 
145
145
  def _load_trace(self, filename: str) -> Any:
146
146
  """Load a trace file and store as current."""
147
- import oscura as tk
147
+ import oscura as osc
148
148
 
149
149
  try:
150
- trace = tk.load(filename)
150
+ trace = osc.load(filename)
151
151
  set_current_trace(trace, filename)
152
152
 
153
153
  # Display summary
@@ -169,7 +169,7 @@ class TracekitMagics(Magics): # type: ignore[misc]
169
169
 
170
170
  def _run_measurements(self, measurement_names: list[str] | None) -> dict[str, Any]:
171
171
  """Run measurements on current trace."""
172
- import oscura as tk
172
+ import oscura as osc
173
173
 
174
174
  trace = get_current_trace()
175
175
  if trace is None:
@@ -180,9 +180,9 @@ class TracekitMagics(Magics): # type: ignore[misc]
180
180
  # Run specific measurements
181
181
  results = {}
182
182
  for name in measurement_names:
183
- if hasattr(tk, name):
183
+ if hasattr(osc, name):
184
184
  try:
185
- func = getattr(tk, name)
185
+ func = getattr(osc, name)
186
186
  results[name] = func(trace)
187
187
  except Exception as e:
188
188
  results[name] = f"Error: {e}"
@@ -191,7 +191,7 @@ class TracekitMagics(Magics): # type: ignore[misc]
191
191
  else:
192
192
  # Run all measurements
193
193
  try:
194
- results = tk.measure(trace)
194
+ results = osc.measure(trace)
195
195
  except Exception as e:
196
196
  print(f"Error running measurements: {e}")
197
197
  return {}
@@ -243,7 +243,7 @@ class TracekitMagics(Magics): # type: ignore[misc]
243
243
  def _show_help(self) -> None:
244
244
  """Show magic command help."""
245
245
  help_text = """
246
- TraceKit Magic Commands
246
+ Oscura Magic Commands
247
247
  =======================
248
248
 
249
249
  %oscura load <filename> Load a trace file
@@ -282,23 +282,23 @@ Example:
282
282
 
283
283
  All oscura functions are auto-imported in the cell namespace.
284
284
  """
285
- import oscura as tk
285
+ import oscura as osc
286
286
 
287
287
  # Build execution namespace with oscura imports
288
288
  namespace = {
289
- "tk": tk,
290
- "load": tk.load,
291
- "measure": tk.measure,
292
- "fft": tk.fft,
293
- "psd": tk.psd,
294
- "thd": tk.thd,
295
- "snr": tk.snr,
296
- "rise_time": tk.rise_time,
297
- "fall_time": tk.fall_time,
298
- "frequency": tk.frequency,
299
- "amplitude": tk.amplitude,
300
- "low_pass": tk.low_pass,
301
- "high_pass": tk.high_pass,
289
+ "osc": osc,
290
+ "load": osc.load,
291
+ "measure": osc.measure,
292
+ "fft": osc.fft,
293
+ "psd": osc.psd,
294
+ "thd": osc.thd,
295
+ "snr": osc.snr,
296
+ "rise_time": osc.rise_time,
297
+ "fall_time": osc.fall_time,
298
+ "frequency": osc.frequency,
299
+ "amplitude": osc.amplitude,
300
+ "low_pass": osc.low_pass,
301
+ "high_pass": osc.high_pass,
302
302
  }
303
303
 
304
304
  # Add current trace if available
@@ -314,19 +314,19 @@ Example:
314
314
 
315
315
 
316
316
  def load_ipython_extension(ipython: InteractiveShell) -> None:
317
- """Load TraceKit IPython extension.
317
+ """Load Oscura IPython extension.
318
318
 
319
319
  Called when user runs: %load_ext oscura
320
320
 
321
321
  Args:
322
322
  ipython: The IPython shell instance
323
323
  """
324
- ipython.register_magics(TracekitMagics)
325
- print("TraceKit magics loaded. Type '%oscura help' for usage.")
324
+ ipython.register_magics(OscuraMagics)
325
+ print("Oscura magics loaded. Type '%oscura help' for usage.")
326
326
 
327
327
 
328
328
  def unload_ipython_extension(ipython: InteractiveShell) -> None:
329
- """Unload TraceKit IPython extension.
329
+ """Unload Oscura IPython extension.
330
330
 
331
331
  Args:
332
332
  ipython: The IPython shell instance
@@ -1,16 +1,16 @@
1
- """TraceKit data loaders for various file formats.
1
+ """Oscura data loaders for various file formats.
2
2
 
3
3
  This module provides a unified load() function that auto-detects file formats
4
4
  and delegates to the appropriate loader.
5
5
 
6
6
 
7
7
  Example:
8
- >>> import oscura as tk
9
- >>> trace = tk.load("capture.wfm")
8
+ >>> import oscura as osc
9
+ >>> trace = osc.load("capture.wfm")
10
10
  >>> print(f"Loaded {len(trace.data)} samples")
11
11
 
12
12
  >>> # Load all channels from multi-channel file
13
- >>> channels = tk.load_all_channels("multi_channel.wfm")
13
+ >>> channels = osc.load_all_channels("multi_channel.wfm")
14
14
  >>> for name, trace in channels.items():
15
15
  ... print(f"{name}: {len(trace.data)} samples")
16
16
  """
@@ -135,12 +135,12 @@ def load(
135
135
  FileNotFoundError: If the file does not exist.
136
136
 
137
137
  Example:
138
- >>> import oscura as tk
139
- >>> trace = tk.load("oscilloscope_capture.wfm")
138
+ >>> import oscura as osc
139
+ >>> trace = osc.load("oscilloscope_capture.wfm")
140
140
  >>> print(f"Loaded {len(trace.data)} samples at {trace.metadata.sample_rate} Hz")
141
141
 
142
142
  >>> # Force specific loader
143
- >>> trace = tk.load("data.bin", format="tektronix")
143
+ >>> trace = osc.load("data.bin", format="tektronix")
144
144
 
145
145
  >>> # Check if digital trace
146
146
  >>> if isinstance(trace, DigitalTrace):
@@ -306,8 +306,8 @@ def load_all_channels(
306
306
  FileNotFoundError: If the file does not exist.
307
307
 
308
308
  Example:
309
- >>> import oscura as tk
310
- >>> channels = tk.load_all_channels("multi_channel.wfm")
309
+ >>> import oscura as osc
310
+ >>> channels = osc.load_all_channels("multi_channel.wfm")
311
311
  >>> for name, trace in channels.items():
312
312
  ... print(f"{name}: {len(trace.data)} samples")
313
313
  ch1: 10000 samples
@@ -472,7 +472,7 @@ def load_lazy(path: str | PathLike[str], **kwargs: Any) -> LazyWaveformTrace | W
472
472
  LazyWaveformTrace or WaveformTrace.
473
473
 
474
474
  Example:
475
- >>> trace = tk.loaders.load_lazy("huge_trace.npy", sample_rate=1e9)
475
+ >>> trace = osc.loaders.load_lazy("huge_trace.npy", sample_rate=1e9)
476
476
  >>> print(f"Length: {trace.length}") # Metadata available immediately
477
477
 
478
478
  References:
@@ -7,7 +7,7 @@ file into memory but access it in chunks on-demand via the OS page cache.
7
7
  Key features:
8
8
  - Zero-copy data access via numpy.memmap
9
9
  - Chunked iteration for processing huge files
10
- - Integration with existing TraceKit loader infrastructure
10
+ - Integration with existing Oscura loader infrastructure
11
11
  - Support for common binary formats (raw, NPY, structured)
12
12
  - Automatic fallback to regular loading for small files
13
13
 
oscura/loaders/pcap.py CHANGED
@@ -27,7 +27,7 @@ if TYPE_CHECKING:
27
27
 
28
28
  # Try to import dpkt for full PCAP support
29
29
  try:
30
- import dpkt # type: ignore[import-not-found]
30
+ import dpkt # type: ignore[import-untyped]
31
31
 
32
32
  DPKT_AVAILABLE = True
33
33
  except ImportError:
oscura/math/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- """Math and arithmetic operations module for TraceKit.
1
+ """Math and arithmetic operations module for Oscura.
2
2
 
3
3
  This module provides waveform math operations including arithmetic,
4
4
  interpolation, and mathematical transformations.
oscura/math/arithmetic.py CHANGED
@@ -1,4 +1,4 @@
1
- """Signal arithmetic operations for TraceKit.
1
+ """Signal arithmetic operations for Oscura.
2
2
 
3
3
  This module provides element-wise arithmetic operations for waveform traces
4
4
  including addition, subtraction, multiplication, division, differentiation,
@@ -1,4 +1,4 @@
1
- """Interpolation and resampling operations for TraceKit.
1
+ """Interpolation and resampling operations for Oscura.
2
2
 
3
3
  This module provides interpolation, resampling, and trace alignment
4
4
  functions for waveform data.
@@ -1,4 +1,4 @@
1
- """Onboarding and help system for TraceKit.
1
+ """Onboarding and help system for Oscura.
2
2
 
3
3
  This package provides interactive tutorials, context-sensitive help,
4
4
  and guided analysis features for new users.
oscura/onboarding/help.py CHANGED
@@ -67,7 +67,7 @@ Common scales:
67
67
  - 1 MHz = 1,000,000 cycles/second (radio, slow digital)
68
68
  - 1 GHz = 1,000,000,000 cycles/second (fast digital, RF)
69
69
 
70
- TraceKit finds frequency by detecting repeated patterns in your signal.
70
+ Oscura finds frequency by detecting repeated patterns in your signal.
71
71
  """,
72
72
  "when_to_use": [
73
73
  "Verifying clock frequency",
@@ -143,7 +143,7 @@ harmonics (1x, 3x, 5x, etc. of the fundamental).
143
143
  "related": ["psd", "thd", "snr", "spectrogram"],
144
144
  },
145
145
  "load": {
146
- "summary": "Load a trace file - TraceKit's starting point",
146
+ "summary": "Load a trace file - Oscura's starting point",
147
147
  "plain_english": """
148
148
  load() reads waveform data from a file. It auto-detects the format,
149
149
  so you don't need to specify whether it's CSV, WFM, HDF5, etc.
@@ -157,7 +157,7 @@ Supported formats: CSV, Tektronix WFM, Rigol WFM, NumPy NPZ,
157
157
  HDF5, Sigrok sessions, VCD, TDMS, and more.
158
158
  """,
159
159
  "when_to_use": [
160
- "Starting any TraceKit analysis",
160
+ "Starting any Oscura analysis",
161
161
  "Loading oscilloscope captures",
162
162
  "Importing logic analyzer data",
163
163
  ],
@@ -189,7 +189,7 @@ Results are returned in a dictionary for easy access.
189
189
 
190
190
 
191
191
  def get_help(topic: str) -> str | None:
192
- """Get plain English help for a TraceKit function or concept.
192
+ """Get plain English help for a Oscura function or concept.
193
193
 
194
194
  Args:
195
195
  topic: Function name or concept to get help for
@@ -222,10 +222,10 @@ def get_help(topic: str) -> str | None:
222
222
 
223
223
  # Try to get docstring
224
224
  try:
225
- import oscura as tk
225
+ import oscura as osc
226
226
 
227
- if hasattr(tk, topic):
228
- func = getattr(tk, topic)
227
+ if hasattr(osc, topic):
228
+ func = getattr(osc, topic)
229
229
  if func.__doc__:
230
230
  return f"Help for {topic}:\n\n{func.__doc__}"
231
231
  except Exception:
@@ -467,29 +467,29 @@ def get_example(function_name: str) -> str | None:
467
467
  examples = {
468
468
  "load": """
469
469
  # Load a trace file
470
- import oscura as tk
471
- trace = tk.load("capture.csv")
470
+ import oscura as osc
471
+ trace = osc.load("capture.csv")
472
472
  print(f"Loaded {len(trace.data)} samples")
473
473
  """,
474
474
  "rise_time": """
475
475
  # Measure rise time
476
- import oscura as tk
477
- trace = tk.load("signal.csv")
478
- rt = tk.rise_time(trace)
476
+ import oscura as osc
477
+ trace = osc.load("signal.csv")
478
+ rt = osc.rise_time(trace)
479
479
  print(f"Rise time: {rt*1e9:.2f} ns")
480
480
  """,
481
481
  "fft": """
482
482
  # Compute FFT spectrum
483
- import oscura as tk
484
- trace = tk.load("signal.csv")
485
- freq, mag = tk.fft(trace)
483
+ import oscura as osc
484
+ trace = osc.load("signal.csv")
485
+ freq, mag = osc.fft(trace)
486
486
  print(f"Frequency resolution: {freq[1]:.2f} Hz")
487
487
  """,
488
488
  "measure": """
489
489
  # Run all measurements
490
- import oscura as tk
491
- trace = tk.load("signal.csv")
492
- results = tk.measure(trace)
490
+ import oscura as osc
491
+ trace = osc.load("signal.csv")
492
+ results = osc.measure(trace)
493
493
  for name, value in results.items():
494
494
  print(f"{name}: {value}")
495
495
  """,
@@ -1,4 +1,4 @@
1
- """Interactive tutorial system for TraceKit.
1
+ """Interactive tutorial system for Oscura.
2
2
 
3
3
  This module provides step-by-step interactive tutorials for new users,
4
4
  covering common analysis workflows.
@@ -11,7 +11,7 @@ covering common analysis workflows.
11
11
  Example:
12
12
  >>> from oscura.onboarding import run_tutorial
13
13
  >>> run_tutorial("getting_started")
14
- Welcome to TraceKit!
14
+ Welcome to Oscura!
15
15
  Step 1/5: Loading a trace file
16
16
  ...
17
17
  """
@@ -74,17 +74,17 @@ def _register_getting_started() -> None:
74
74
  TutorialStep(
75
75
  title="Loading a Trace File",
76
76
  description="""
77
- TraceKit can load waveform data from many file formats.
77
+ Oscura can load waveform data from many file formats.
78
78
  The simplest way is to use the load() function, which auto-detects the format.
79
79
 
80
80
  Think of a trace like a recording of an electrical signal over time -
81
81
  similar to how an audio file stores sound waves.
82
82
  """,
83
83
  code="""
84
- import oscura as tk
84
+ import oscura as osc
85
85
 
86
86
  # Load a waveform file (replace with your file path)
87
- trace = tk.load("signal.csv")
87
+ trace = osc.load("signal.csv")
88
88
 
89
89
  # See basic info
90
90
  print(f"Loaded {len(trace.data)} samples")
@@ -107,20 +107,20 @@ Once you have a trace, you can measure things like:
107
107
  These are the same measurements an oscilloscope would show you!
108
108
  """,
109
109
  code="""
110
- import oscura as tk
110
+ import oscura as osc
111
111
 
112
- trace = tk.load("signal.csv")
112
+ trace = osc.load("signal.csv")
113
113
 
114
114
  # Measure rise time (10% to 90% transition)
115
- rt = tk.rise_time(trace)
115
+ rt = osc.rise_time(trace)
116
116
  print(f"Rise time: {rt*1e9:.2f} nanoseconds")
117
117
 
118
118
  # Measure frequency
119
- freq = tk.frequency(trace)
119
+ freq = osc.frequency(trace)
120
120
  print(f"Frequency: {freq/1e6:.2f} MHz")
121
121
 
122
122
  # Get all measurements at once
123
- results = tk.measure(trace)
123
+ results = osc.measure(trace)
124
124
  for name, value in results.items():
125
125
  print(f"{name}: {value}")
126
126
  """,
@@ -142,12 +142,12 @@ This is useful for:
142
142
  It's like looking at a music equalizer that shows bass, mid, and treble!
143
143
  """,
144
144
  code="""
145
- import oscura as tk
145
+ import oscura as osc
146
146
 
147
- trace = tk.load("signal.csv")
147
+ trace = osc.load("signal.csv")
148
148
 
149
149
  # Compute FFT (Fast Fourier Transform)
150
- freq, magnitude = tk.fft(trace)
150
+ freq, magnitude = osc.fft(trace)
151
151
 
152
152
  # Find the dominant frequency
153
153
  import numpy as np
@@ -155,8 +155,8 @@ peak_idx = np.argmax(magnitude)
155
155
  print(f"Dominant frequency: {freq[peak_idx]/1e6:.2f} MHz")
156
156
 
157
157
  # Measure signal quality
158
- thd_value = tk.thd(trace)
159
- snr_value = tk.snr(trace)
158
+ thd_value = osc.thd(trace)
159
+ snr_value = osc.snr(trace)
160
160
  print(f"THD: {thd_value:.1f} dB")
161
161
  print(f"SNR: {snr_value:.1f} dB")
162
162
  """,
@@ -170,15 +170,15 @@ print(f"SNR: {snr_value:.1f} dB")
170
170
  title="Protocol Decoding",
171
171
  description="""
172
172
  If your signal is a digital communication protocol like UART, SPI, or I2C,
173
- TraceKit can decode it to show you the actual data being transmitted.
173
+ Oscura can decode it to show you the actual data being transmitted.
174
174
 
175
175
  Think of it like translating Morse code back into text!
176
176
  """,
177
177
  code="""
178
- import oscura as tk
178
+ import oscura as osc
179
179
 
180
180
  # Load a UART signal
181
- trace = tk.load("uart_signal.csv")
181
+ trace = osc.load("uart_signal.csv")
182
182
 
183
183
  # Decode UART (auto-detects baud rate!)
184
184
  from oscura.analyzers.protocols import decode_uart
@@ -197,7 +197,7 @@ for pkt in packets[:5]: # First 5 packets
197
197
  TutorialStep(
198
198
  title="Auto-Discovery for Beginners",
199
199
  description="""
200
- Not sure what your signal is? TraceKit can analyze it automatically!
200
+ Not sure what your signal is? Oscura can analyze it automatically!
201
201
 
202
202
  The characterize_signal() function examines your trace and tells you:
203
203
  - What type of signal it likely is
@@ -207,10 +207,10 @@ The characterize_signal() function examines your trace and tells you:
207
207
  It's like having an expert look at your signal and give you hints!
208
208
  """,
209
209
  code="""
210
- import oscura as tk
210
+ import oscura as osc
211
211
  from oscura.discovery import characterize_signal
212
212
 
213
- trace = tk.load("mystery_signal.csv")
213
+ trace = osc.load("mystery_signal.csv")
214
214
 
215
215
  # Auto-characterize the signal
216
216
  result = characterize_signal(trace)
@@ -236,9 +236,9 @@ else:
236
236
 
237
237
  tutorial = Tutorial(
238
238
  id="getting_started",
239
- title="Getting Started with TraceKit",
239
+ title="Getting Started with Oscura",
240
240
  description="""
241
- Welcome to TraceKit! This tutorial will teach you the basics of
241
+ Welcome to Oscura! This tutorial will teach you the basics of
242
242
  signal analysis in 5 easy steps:
243
243
 
244
244
  1. Loading trace files
@@ -266,11 +266,11 @@ The Fast Fourier Transform (FFT) converts a time-domain signal into
266
266
  its frequency components. Think of it as breaking a chord into individual notes.
267
267
  """,
268
268
  code="""
269
- import oscura as tk
269
+ import oscura as osc
270
270
  import numpy as np
271
271
 
272
- trace = tk.load("signal.csv")
273
- freq, mag = tk.fft(trace)
272
+ trace = osc.load("signal.csv")
273
+ freq, mag = osc.fft(trace)
274
274
 
275
275
  # Magnitude is in dB (decibels)
276
276
  # 0 dB = full scale, -20 dB = 10x smaller, -40 dB = 100x smaller
@@ -287,10 +287,10 @@ PSD is normalized per Hz, making it easier to compare signals with
287
287
  different durations or sample rates.
288
288
  """,
289
289
  code="""
290
- import oscura as tk
290
+ import oscura as osc
291
291
 
292
- trace = tk.load("signal.csv")
293
- freq, psd = tk.psd(trace)
292
+ trace = osc.load("signal.csv")
293
+ freq, psd = osc.psd(trace)
294
294
 
295
295
  # Find where most power is concentrated
296
296
  import numpy as np
@@ -99,7 +99,7 @@ class AnalysisWizard:
99
99
  title="Signal Type Detection",
100
100
  question="What type of analysis do you want to perform?",
101
101
  options=[
102
- "Auto-detect (let TraceKit figure it out)",
102
+ "Auto-detect (let Oscura figure it out)",
103
103
  "Digital signal analysis",
104
104
  "Analog/waveform analysis",
105
105
  "Protocol decoding",
@@ -157,7 +157,7 @@ class AnalysisWizard:
157
157
  WizardResult with all collected data
158
158
  """
159
159
  print("\n" + "=" * 60)
160
- print("TraceKit Analysis Wizard")
160
+ print("Oscura Analysis Wizard")
161
161
  print("=" * 60)
162
162
  print("Let's analyze your signal step by step.\n")
163
163
 
@@ -287,7 +287,7 @@ class AnalysisWizard:
287
287
 
288
288
  def _handle_measurements(self, choice: int) -> None:
289
289
  """Handle measurement selection."""
290
- import oscura as tk
290
+ import oscura as osc
291
291
 
292
292
  if choice == 4: # Skip
293
293
  print("\nSkipping measurements.")
@@ -297,22 +297,22 @@ class AnalysisWizard:
297
297
 
298
298
  try:
299
299
  if choice == 1: # All
300
- results = tk.measure(self.trace)
300
+ results = osc.measure(self.trace)
301
301
  elif choice == 2: # Timing only
302
302
  results = {
303
- "rise_time": tk.rise_time(self.trace),
304
- "fall_time": tk.fall_time(self.trace),
305
- "frequency": tk.frequency(self.trace),
306
- "period": tk.period(self.trace),
307
- "duty_cycle": tk.duty_cycle(self.trace),
303
+ "rise_time": osc.rise_time(self.trace),
304
+ "fall_time": osc.fall_time(self.trace),
305
+ "frequency": osc.frequency(self.trace),
306
+ "period": osc.period(self.trace),
307
+ "duty_cycle": osc.duty_cycle(self.trace),
308
308
  }
309
309
  elif choice == 3: # Amplitude only
310
310
  results = {
311
- "amplitude": tk.amplitude(self.trace),
312
- "rms": tk.rms(self.trace),
313
- "mean": tk.mean(self.trace),
314
- "overshoot": tk.overshoot(self.trace),
315
- "undershoot": tk.undershoot(self.trace),
311
+ "amplitude": osc.amplitude(self.trace),
312
+ "rms": osc.rms(self.trace),
313
+ "mean": osc.mean(self.trace),
314
+ "overshoot": osc.overshoot(self.trace),
315
+ "undershoot": osc.undershoot(self.trace),
316
316
  }
317
317
 
318
318
  self.result.measurements.update(results)
@@ -331,7 +331,7 @@ class AnalysisWizard:
331
331
  """Handle spectral analysis selection."""
332
332
  import numpy as np
333
333
 
334
- import oscura as tk
334
+ import oscura as osc
335
335
 
336
336
  if choice == 4: # Skip
337
337
  print("\nSkipping spectral analysis.")
@@ -341,14 +341,14 @@ class AnalysisWizard:
341
341
 
342
342
  try:
343
343
  if choice in (1, 3): # FFT
344
- freq, mag = tk.fft(self.trace) # type: ignore[misc]
344
+ freq, mag = osc.fft(self.trace) # type: ignore[misc]
345
345
  peak_idx = np.argmax(mag)
346
346
  self.result.measurements["fft_peak_freq"] = freq[peak_idx]
347
347
  self.result.measurements["fft_peak_mag"] = mag[peak_idx]
348
348
  print(f" FFT peak: {freq[peak_idx] / 1e6:.3f} MHz at {mag[peak_idx]:.1f} dB")
349
349
 
350
350
  if choice in (2, 3): # PSD
351
- freq, _psd_vals = tk.psd(self.trace)
351
+ freq, _psd_vals = osc.psd(self.trace)
352
352
  self.result.measurements["psd_computed"] = True
353
353
  print(f" PSD computed over {len(freq)} frequency bins")
354
354
 
@@ -357,7 +357,7 @@ class AnalysisWizard:
357
357
 
358
358
  def _handle_quality(self, choice: int) -> None:
359
359
  """Handle quality assessment selection."""
360
- import oscura as tk
360
+ import oscura as osc
361
361
 
362
362
  if choice == 4: # Skip
363
363
  print("\nSkipping quality assessment.")
@@ -367,8 +367,8 @@ class AnalysisWizard:
367
367
 
368
368
  try:
369
369
  if choice in (1, 3): # THD and SNR
370
- thd_val = tk.thd(self.trace)
371
- snr_val = tk.snr(self.trace)
370
+ thd_val = osc.thd(self.trace)
371
+ snr_val = osc.snr(self.trace)
372
372
  self.result.measurements["thd"] = thd_val
373
373
  self.result.measurements["snr"] = snr_val
374
374
  print(f" THD: {thd_val:.1f} dB")
@@ -457,9 +457,9 @@ def run_wizard(trace: Any, interactive: bool = True) -> WizardResult:
457
457
  WizardResult with measurements, recommendations, and summary
458
458
 
459
459
  Example:
460
- >>> import oscura as tk
460
+ >>> import oscura as osc
461
461
  >>> from oscura.onboarding import run_wizard
462
- >>> trace = tk.load("signal.csv")
462
+ >>> trace = osc.load("signal.csv")
463
463
  >>> result = run_wizard(trace)
464
464
  """
465
465
  wizard = AnalysisWizard(trace)