oscura 0.4.0__py3-none-any.whl → 0.5.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.
@@ -0,0 +1,247 @@
1
+ """CSV export functions for vintage logic analysis results.
2
+
3
+ This module provides specialized CSV exporters for vintage logic analysis data,
4
+ including timing measurements, IC identification, and bill of materials.
5
+
6
+ Example:
7
+ >>> from oscura.exporters.vintage_logic_csv import export_bom_csv
8
+ >>> export_bom_csv(result, "bom.csv")
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import csv
14
+ from pathlib import Path
15
+ from typing import TYPE_CHECKING
16
+
17
+ if TYPE_CHECKING:
18
+ from oscura.analyzers.digital.vintage_result import VintageLogicAnalysisResult
19
+
20
+
21
+ def export_timing_measurements_csv(
22
+ result: VintageLogicAnalysisResult,
23
+ path: str | Path,
24
+ ) -> None:
25
+ """Export timing measurements to CSV.
26
+
27
+ Creates a CSV file with columns: parameter, measured_value_ns, measurement_type.
28
+
29
+ Args:
30
+ result: Vintage logic analysis result.
31
+ path: Output CSV file path.
32
+
33
+ Example:
34
+ >>> export_timing_measurements_csv(result, "timing.csv")
35
+ """
36
+ path = Path(path)
37
+
38
+ with path.open("w", newline="") as csvfile:
39
+ writer = csv.writer(csvfile)
40
+
41
+ # Write header
42
+ writer.writerow(["parameter", "measured_value_ns", "measurement_type"])
43
+
44
+ # Write timing measurements
45
+ for param_name, value in result.timing_measurements.items():
46
+ # Determine measurement type from parameter name
47
+ if "_t_pd" in param_name:
48
+ meas_type = "propagation_delay"
49
+ elif "_t_su" in param_name:
50
+ meas_type = "setup_time"
51
+ elif "_t_h" in param_name:
52
+ meas_type = "hold_time"
53
+ elif "_t_w" in param_name:
54
+ meas_type = "pulse_width"
55
+ else:
56
+ meas_type = "other"
57
+
58
+ writer.writerow([param_name, f"{value * 1e9:.3f}", meas_type])
59
+
60
+
61
+ def export_ic_identification_csv(
62
+ result: VintageLogicAnalysisResult,
63
+ path: str | Path,
64
+ ) -> None:
65
+ """Export IC identification results to CSV.
66
+
67
+ Creates a CSV file with columns: ic_name, confidence, family, timing_params,
68
+ validation_status.
69
+
70
+ Args:
71
+ result: Vintage logic analysis result.
72
+ path: Output CSV file path.
73
+
74
+ Example:
75
+ >>> export_ic_identification_csv(result, "ic_identification.csv")
76
+ """
77
+ path = Path(path)
78
+
79
+ with path.open("w", newline="") as csvfile:
80
+ writer = csv.writer(csvfile)
81
+
82
+ # Write header
83
+ writer.writerow(
84
+ [
85
+ "ic_name",
86
+ "confidence",
87
+ "family",
88
+ "t_pd_ns",
89
+ "t_su_ns",
90
+ "t_h_ns",
91
+ "t_w_ns",
92
+ "validation_status",
93
+ ]
94
+ )
95
+
96
+ # Write IC identification results
97
+ for ic_result in result.identified_ics:
98
+ # Extract timing parameters
99
+ t_pd = ic_result.timing_params.get("t_pd", 0) * 1e9
100
+ t_su = ic_result.timing_params.get("t_su", 0) * 1e9
101
+ t_h = ic_result.timing_params.get("t_h", 0) * 1e9
102
+ t_w = ic_result.timing_params.get("t_w", 0) * 1e9
103
+
104
+ # Determine validation status
105
+ validation_failed = any(v.get("passes") is False for v in ic_result.validation.values())
106
+ validation_status = "FAIL" if validation_failed else "PASS"
107
+
108
+ writer.writerow(
109
+ [
110
+ ic_result.ic_name,
111
+ f"{ic_result.confidence:.3f}",
112
+ ic_result.family,
113
+ f"{t_pd:.3f}" if t_pd > 0 else "",
114
+ f"{t_su:.3f}" if t_su > 0 else "",
115
+ f"{t_h:.3f}" if t_h > 0 else "",
116
+ f"{t_w:.3f}" if t_w > 0 else "",
117
+ validation_status,
118
+ ]
119
+ )
120
+
121
+
122
+ def export_bom_csv(
123
+ result: VintageLogicAnalysisResult,
124
+ path: str | Path,
125
+ ) -> None:
126
+ """Export bill of materials to CSV.
127
+
128
+ Creates a CSV file compatible with spreadsheet programs and procurement systems.
129
+ Columns: part_number, description, quantity, category, notes.
130
+
131
+ Args:
132
+ result: Vintage logic analysis result.
133
+ path: Output CSV file path.
134
+
135
+ Example:
136
+ >>> export_bom_csv(result, "bom.csv")
137
+ """
138
+ path = Path(path)
139
+
140
+ with path.open("w", newline="") as csvfile:
141
+ writer = csv.writer(csvfile)
142
+
143
+ # Write header
144
+ writer.writerow(["part_number", "description", "quantity", "category", "notes"])
145
+
146
+ # Write BOM entries
147
+ for entry in result.bom:
148
+ writer.writerow(
149
+ [
150
+ entry.part_number,
151
+ entry.description,
152
+ entry.quantity,
153
+ entry.category,
154
+ entry.notes or "",
155
+ ]
156
+ )
157
+
158
+
159
+ def export_voltage_levels_csv(
160
+ result: VintageLogicAnalysisResult,
161
+ path: str | Path,
162
+ ) -> None:
163
+ """Export voltage levels to CSV.
164
+
165
+ Creates a CSV file with measured voltage levels for the detected logic family.
166
+
167
+ Args:
168
+ result: Vintage logic analysis result.
169
+ path: Output CSV file path.
170
+
171
+ Example:
172
+ >>> export_voltage_levels_csv(result, "voltage_levels.csv")
173
+ """
174
+ path = Path(path)
175
+
176
+ with path.open("w", newline="") as csvfile:
177
+ writer = csv.writer(csvfile)
178
+
179
+ # Write header
180
+ writer.writerow(["parameter", "voltage_v", "logic_family"])
181
+
182
+ # Write voltage levels
183
+ for param, value in result.voltage_levels.items():
184
+ writer.writerow([param, f"{value:.3f}", result.detected_family])
185
+
186
+
187
+ def export_all_vintage_logic_csv(
188
+ result: VintageLogicAnalysisResult,
189
+ output_dir: str | Path,
190
+ *,
191
+ prefix: str = "",
192
+ ) -> dict[str, Path]:
193
+ """Export all vintage logic analysis data to CSV files.
194
+
195
+ Convenience function that exports all data types to separate CSV files.
196
+
197
+ Args:
198
+ result: Vintage logic analysis result.
199
+ output_dir: Output directory for CSV files.
200
+ prefix: Optional prefix for file names.
201
+
202
+ Returns:
203
+ Dictionary mapping data type to output file path.
204
+
205
+ Example:
206
+ >>> paths = export_all_vintage_logic_csv(result, "./output", prefix="analysis_")
207
+ >>> print(paths["bom"]) # PosixPath('./output/analysis_bom.csv')
208
+ """
209
+ output_dir = Path(output_dir)
210
+ output_dir.mkdir(parents=True, exist_ok=True)
211
+
212
+ paths: dict[str, Path] = {}
213
+
214
+ # Export timing measurements
215
+ if result.timing_measurements:
216
+ timing_path = output_dir / f"{prefix}timing_measurements.csv"
217
+ export_timing_measurements_csv(result, timing_path)
218
+ paths["timing_measurements"] = timing_path
219
+
220
+ # Export IC identification
221
+ if result.identified_ics:
222
+ ic_path = output_dir / f"{prefix}ic_identification.csv"
223
+ export_ic_identification_csv(result, ic_path)
224
+ paths["ic_identification"] = ic_path
225
+
226
+ # Export BOM
227
+ if result.bom:
228
+ bom_path = output_dir / f"{prefix}bom.csv"
229
+ export_bom_csv(result, bom_path)
230
+ paths["bom"] = bom_path
231
+
232
+ # Export voltage levels
233
+ if result.voltage_levels:
234
+ voltage_path = output_dir / f"{prefix}voltage_levels.csv"
235
+ export_voltage_levels_csv(result, voltage_path)
236
+ paths["voltage_levels"] = voltage_path
237
+
238
+ return paths
239
+
240
+
241
+ __all__ = [
242
+ "export_all_vintage_logic_csv",
243
+ "export_bom_csv",
244
+ "export_ic_identification_csv",
245
+ "export_timing_measurements_csv",
246
+ "export_voltage_levels_csv",
247
+ ]
@@ -138,6 +138,10 @@ from oscura.reporting.template_system import (
138
138
  list_templates,
139
139
  load_template,
140
140
  )
141
+ from oscura.reporting.vintage_logic_report import (
142
+ VintageLogicReport,
143
+ generate_vintage_logic_report,
144
+ )
141
145
 
142
146
  __all__ = [
143
147
  # Comprehensive Analysis Report API (CAR-001 through CAR-007)
@@ -187,6 +191,8 @@ __all__ = [
187
191
  "TemplateEngine",
188
192
  "TemplateSection",
189
193
  "UnsupportedFormatError",
194
+ # Vintage Logic Reporting
195
+ "VintageLogicReport",
190
196
  "VisualEmphasis",
191
197
  "aggregate_batch_measurements",
192
198
  "analyze",
@@ -235,6 +241,7 @@ __all__ = [
235
241
  "generate_presentation_from_report",
236
242
  "generate_report",
237
243
  "generate_summary",
244
+ "generate_vintage_logic_report",
238
245
  "get_available_analyses",
239
246
  "get_axis_scaling",
240
247
  "list_templates",