Skip to content

Commit 88c9cc8

Browse files
committed
Add generic root system_description to all MultiCapture JSON fixtures for consistent visual inputs
- update all visual/PyPNM/MultiCapture JSON fixtures to include a root-level system_description block - place system_description first in each root object for consistent JSON shape across MultiCapture examples - use the PyPNM generic defaults (LANCity / LCPET-3) instead of vendor-specific values - keep the change scoped to the system_description block only without altering other payload fields intentionally - extend sanitize tooling and tests to support lifting/inserting root system_description for capture-style responses - 2026-02-23 14:14:24
1 parent 6a8dabc commit 88c9cc8

67 files changed

Lines changed: 180235 additions & 4361926 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/visual-previews/MultiCapture/ChannelEstimation/ChannelEstimation-Analysis-Echo-Detection-IFFT.html

Lines changed: 2 additions & 2 deletions
Large diffs are not rendered by default.

docs/visual-previews/MultiCapture/ChannelEstimation/ChannelEstimation-Analysis-GroupDelay.html

Lines changed: 2 additions & 2 deletions
Large diffs are not rendered by default.

docs/visual-previews/MultiCapture/ChannelEstimation/ChannelEstimation-Analysis-MIN_AVG_MAX.html

Lines changed: 2 additions & 2 deletions
Large diffs are not rendered by default.

docs/visual-previews/MultiCapture/OfdmaPreEqualization/OfdmaPreEqualization-Analysis-EchoDetection.html

Lines changed: 2 additions & 2 deletions
Large diffs are not rendered by default.

docs/visual-previews/MultiCapture/OfdmaPreEqualization/OfdmaPreEqualization-Analysis-GroupDelay.html

Lines changed: 2 additions & 2 deletions
Large diffs are not rendered by default.

docs/visual-previews/MultiCapture/OfdmaPreEqualization/OfdmaPreEqualization-Analysis-MinAvgMax.html

Lines changed: 2 additions & 2 deletions
Large diffs are not rendered by default.

docs/visual-previews/MultiCapture/RxMER/RxMER-Analysis-MIn-Avg-Max.html

Lines changed: 2 additions & 2 deletions
Large diffs are not rendered by default.

docs/visual-previews/MultiCapture/RxMER/RxMER-Analysis-OFDMA-Profile-Performance-1.html

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

docs/visual-previews/MultiCapture/RxMER/RxMER-Analysis-Rxmer-Heat-Map.html

Lines changed: 2 additions & 2 deletions
Large diffs are not rendered by default.

docs/visual-previews/SingleCapture/Histogram/Histogram.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
<div id="app" class="frame"></div>
5353
<script>
5454
(function() {
55-
const sampleData = {"mac_address": "aabbccddeeff", "status": 0, "message": null, "data": {"analysis": [{"device_details": {"system_description": {"HW_REV": "1.0", "VENDOR": "LANCity", "BOOTR": "NONE", "SW_REV": "1.0.0", "MODEL": "LCPET-3"}}, "pnm_header": {"file_type": "PNN", "file_type_version": 5, "major_version": 1, "minor_version": 0, "capture_time": 1740236465}, "mac_address": "aa:bb:cc:dd:ee:ff", "symmetry": 2, "dwell_counts": [1406249999], "hit_counts": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 20, 111, 215, 552, 1311, 3073, 6881, 15401, 31408, 63828, 123760, 234654, 432294, 764677, 1297511, 2191743, 3491751, 5508147, 8208783, 12140702, 17338270, 23528753, 31530249, 40950495, 51020014, 61428442, 72321749, 82467167, 91065068, 96064371, 100079085, 99864515, 97105477, 90225910, 82343616, 73238688, 61788155, 50576999, 41370050, 31516931, 23989402, 17051591, 12222733, 8385387, 5532446, 3506651, 2202638, 1329581, 767116, 434536, 239625, 126263, 62850, 31553, 14659, 6724, 3068, 1329, 604, 262, 85, 33, 20, 6, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}], "measurement_stats": [{"index": 2, "entry": {"docsPnmCmDsHistEnable": true, "docsPnmCmDsHistTimeOut": 10, "docsPnmCmDsHistMeasStatus": "sample_ready", "docsPnmCmDsHistFileName": "ds_histogram_aabbccddeeff_0_1771803166.bin"}}]}};
55+
const sampleData = {"system_description": {"HW_REV": "1.0", "VENDOR": "LANCity", "BOOTR": "NONE", "SW_REV": "1.0.0", "MODEL": "LCPET-3"}, "mac_address": "aabbccddeeff", "status": 0, "message": null, "data": {"analysis": [{"device_details": {"system_description": {"HW_REV": "1.0", "VENDOR": "LANCity", "BOOTR": "NONE", "SW_REV": "1.0.0", "MODEL": "LCPET-3"}}, "pnm_header": {"file_type": "PNN", "file_type_version": 5, "major_version": 1, "minor_version": 0, "capture_time": 1740236465}, "mac_address": "aa:bb:cc:dd:ee:ff", "symmetry": 2, "dwell_counts": [1406249999], "hit_counts": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 7, 20, 111, 215, 552, 1311, 3073, 6881, 15401, 31408, 63828, 123760, 234654, 432294, 764677, 1297511, 2191743, 3491751, 5508147, 8208783, 12140702, 17338270, 23528753, 31530249, 40950495, 51020014, 61428442, 72321749, 82467167, 91065068, 96064371, 100079085, 99864515, 97105477, 90225910, 82343616, 73238688, 61788155, 50576999, 41370050, 31516931, 23989402, 17051591, 12222733, 8385387, 5532446, 3506651, 2202638, 1329581, 767116, 434536, 239625, 126263, 62850, 31553, 14659, 6724, 3068, 1329, 604, 262, 85, 33, 20, 6, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}], "measurement_stats": [{"index": 2, "entry": {"docsPnmCmDsHistEnable": true, "docsPnmCmDsHistTimeOut": 10, "docsPnmCmDsHistMeasStatus": "sample_ready", "docsPnmCmDsHistFileName": "ds_histogram_aabbccddeeff_0_1771803166.bin"}}]}};
5656
const visualSource = "// Remarks (CODING_AGENTS visual standard)\n// - Device Info uses a separate top block with standardized labels\n// - Histogram chart remains the primary visualization\n// - Missing sysDescr fields render as N/A\nconst template = `\n<style>\n body {\n font-family: Arial, sans-serif;\n padding: 16px;\n background-color: #0b0b0b;\n color: #e8e8e8;\n }\n .container {\n max-width: 1280px;\n margin: 0 auto;\n }\n .header {\n margin-bottom: 12px;\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n align-items: center;\n gap: 8px;\n }\n .header h1 {\n margin: 0;\n font-size: 22px;\n color: #f2f2f2;\n grid-column: 2;\n text-align: center;\n }\n .capture-time {\n grid-column: 3;\n justify-self: end;\n font-size: 12px;\n color: #d7deec;\n background: rgba(255,255,255,0.03);\n border: 1px solid rgba(255,255,255,0.08);\n border-radius: 999px;\n padding: 6px 10px;\n white-space: nowrap;\n }\n .panel {\n background: #151515;\n border: 1px solid #2a2a2a;\n border-radius: 10px;\n padding: 14px;\n margin-bottom: 12px;\n }\n .panel-title {\n margin: 0 0 10px 0;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.7px;\n color: #dbe3ff;\n }\n .table-wrap {\n overflow-x: auto;\n border: 1px solid rgba(255,255,255,0.08);\n border-radius: 10px;\n }\n .table {\n width: 100%;\n min-width: 720px;\n border-collapse: collapse;\n }\n .table th {\n text-align: left;\n white-space: nowrap;\n padding: 9px 12px;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.45px;\n color: #dbe3ff;\n background: rgba(255,255,255,0.03);\n }\n .table td {\n padding: 10px 12px;\n font-size: 12px;\n color: #ffffff;\n white-space: nowrap;\n border-top: 1px solid rgba(255,255,255,0.08);\n }\n .mono {\n font-family: Consolas, \"Liberation Mono\", Menlo, monospace;\n }\n .meta-row {\n display: flex;\n gap: 10px;\n flex-wrap: wrap;\n margin-top: 8px;\n color: #cfd6e5;\n font-size: 12px;\n }\n .meta-pill {\n background: rgba(255,255,255,0.03);\n border: 1px solid rgba(255,255,255,0.08);\n border-radius: 999px;\n padding: 6px 10px;\n }\n canvas {\n max-width: 100%;\n height: auto !important;\n }\n</style>\n\n<div class=\"container\">\n <div class=\"header\">\n <h1>Histogram Capture Analysis</h1>\n <div class=\"capture-time\">Capture Time: {{capture_time}}</div>\n </div>\n\n <div class=\"panel\">\n <div class=\"panel-title\">Device Info</div>\n <div class=\"table-wrap\">\n <table class=\"table\">\n <thead>\n <tr>\n <th>MacAddress</th>\n <th>Model</th>\n <th>Vendor</th>\n <th>SW Version</th>\n <th>HW Version</th>\n <th>Boot ROM</th>\n </tr>\n </thead>\n <tbody>\n <tr>\n <td class=\"mono\">{{device_info.macAddress}}</td>\n <td>{{device_info.MODEL}}</td>\n <td>{{device_info.VENDOR}}</td>\n <td class=\"mono\">{{device_info.SW_REV}}</td>\n <td class=\"mono\">{{device_info.HW_REV}}</td>\n <td class=\"mono\">{{device_info.BOOTR}}</td>\n </tr>\n </tbody>\n </table>\n </div>\n <div class=\"meta-row\">\n <div class=\"meta-pill\">Bins: {{bin_count}}</div>\n </div>\n </div>\n\n <div class=\"panel\">\n <div class=\"panel-title\">Histogram Distribution</div>\n <canvas id=\"histogramChart\"></canvas>\n </div>\n</div>\n\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js\"><\/script>\n<script>\n pm.getData(function (err, data) {\n if (err) {\n console.error('Error getting data:', err);\n return;\n }\n\n const ctx = document.getElementById('histogramChart').getContext('2d');\n \n new Chart(ctx, {\n type: 'bar',\n data: {\n labels: data.chart_labels,\n datasets: [{\n label: 'Hit Count',\n data: data.chart_data,\n backgroundColor: 'rgba(0, 194, 255, 0.45)',\n borderColor: 'rgba(0, 194, 255, 0.95)',\n borderWidth: 1\n }]\n },\n options: {\n responsive: true,\n maintainAspectRatio: true,\n scales: {\n yAxes: [{\n ticks: {\n beginAtZero: true,\n fontColor: '#e0e0e0'\n },\n gridLines: {\n color: 'rgba(255,255,255,0.08)'\n },\n scaleLabel: {\n display: true,\n labelString: 'Hit Count',\n fontColor: '#e0e0e0'\n }\n }],\n xAxes: [{\n ticks: {\n fontColor: '#e0e0e0'\n },\n gridLines: {\n color: 'rgba(255,255,255,0.06)'\n },\n scaleLabel: {\n display: true,\n labelString: 'Bin Index',\n fontColor: '#e0e0e0'\n }\n }]\n },\n legend: {\n labels: {\n fontColor: '#e0e0e0'\n }\n }\n }\n });\n });\n<\/script>\n`;\n\nfunction constructVisualizerPayload() {\n const response = pm.response.json();\n const data = response.data || {};\n const firstAnalysis = (data.analysis && data.analysis[0]) || {};\n const pnmHeader = firstAnalysis.pnm_header || {};\n\n function formatCaptureTime(raw) {\n if (raw === undefined || raw === null || raw === '') return 'N/A';\n if (typeof raw === 'number' && isFinite(raw)) {\n const ms = raw > 1e12 ? raw : raw * 1000;\n const d = new Date(ms);\n if (isNaN(d.getTime())) return 'N/A';\n return d.toISOString().slice(0, 19).replace('T', ' ') + ' UTC';\n }\n const n = Number(raw);\n if (!isNaN(n) && isFinite(n)) {\n return formatCaptureTime(n);\n }\n const d = new Date(raw);\n if (isNaN(d.getTime())) return String(raw);\n return d.toISOString().slice(0, 19).replace('T', ' ') + ' UTC';\n }\n \n // Extract basic info\n const macAddress = firstAnalysis.mac_address || response.mac_address || 'N/A';\n const status = response.status;\n const statusMessage = status === 0 ? 'Success' : 'Failed';\n const captureTime = formatCaptureTime(pnmHeader.capture_time);\n \n // Extract device details\n const sys = ((firstAnalysis.device_details || {}).system_description) || {};\n const deviceInfo = {\n macAddress: macAddress,\n MODEL: (sys.MODEL && String(sys.MODEL).trim()) || 'N/A',\n VENDOR: (sys.VENDOR && String(sys.VENDOR).trim()) || 'N/A',\n SW_REV: (sys.SW_REV && String(sys.SW_REV).trim()) || 'N/A',\n HW_REV: (sys.HW_REV && String(sys.HW_REV).trim()) || 'N/A',\n BOOTR: (sys.BOOTR && String(sys.BOOTR).trim()) || 'N/A'\n };\n \n // Extract histogram data for chart - MODIFIED TO REMOVE \"Bin_\" PREFIX\n let chartLabels = [];\n let chartData = [];\n \n if (data.analysis && data.analysis.length > 0) {\n const analysis = data.analysis[0];\n if (analysis.hit_counts && Array.isArray(analysis.hit_counts)) {\n chartData = analysis.hit_counts;\n // Generate labels as just the numeric index (0, 1, 2, 3, ...)\n chartLabels = analysis.hit_counts.map((_, index) => String(index));\n }\n }\n \n return {\n mac_address: macAddress,\n status_message: statusMessage,\n capture_time: captureTime,\n device_info: deviceInfo,\n chart_labels: chartLabels,\n chart_data: chartData,\n bin_count: chartData.length\n };\n}\n\npm.visualizer.set(template, constructVisualizerPayload());\n";
5757
const app = document.getElementById("app");
5858
let visualizerData = sampleData;

0 commit comments

Comments
 (0)