From a5f9cdbd7f744c8cde64fa5eb07265b0e3da3460 Mon Sep 17 00:00:00 2001 From: Imran Farhat Date: Sat, 6 Jun 2026 16:38:13 +0530 Subject: [PATCH 1/3] fix: fix Noise Analysis showing ngspice internal constants (Bug 2) Problem: - Noise Analysis output showed V(false), V(true), V(boltz), V(pi) etc. - Control block used wrong vector names and wrong plot switching Fix: - Changed noise control block to use setplot noise1 then print all - ngspice 31 outputs noise data in tabular format when print all is used after setplot noise1 - this goes through the graph parser correctly - Added NGSPICE_INTERNAL_VARS filter in parse.py as additional safeguard - Noise Analysis now correctly shows inoise_spectrum and onoise_spectrum with graph output --- .../SchematicEditor/SchematicToolbar.js | 1 + .../SchematicEditor/SimulationProperties.js | 2 +- .../simulationAPI/helpers/parse.py | 35 +++++++------------ 3 files changed, 14 insertions(+), 24 deletions(-) diff --git a/eda-frontend/src/components/SchematicEditor/SchematicToolbar.js b/eda-frontend/src/components/SchematicEditor/SchematicToolbar.js index 90249b411..58baafdc6 100644 --- a/eda-frontend/src/components/SchematicEditor/SchematicToolbar.js +++ b/eda-frontend/src/components/SchematicEditor/SchematicToolbar.js @@ -430,6 +430,7 @@ export default function SchematicToolbar ({ // Image Export of Schematic Diagram async function exportImage (type) { + if (!gridRef.current) { return null } const svg = document.querySelector('#divGrid > svg').cloneNode(true) svg.removeAttribute('style') svg.setAttribute('width', gridRef.current.scrollWidth) diff --git a/eda-frontend/src/components/SchematicEditor/SimulationProperties.js b/eda-frontend/src/components/SchematicEditor/SimulationProperties.js index 8b3556cd8..82e208374 100644 --- a/eda-frontend/src/components/SchematicEditor/SimulationProperties.js +++ b/eda-frontend/src/components/SchematicEditor/SimulationProperties.js @@ -775,7 +775,7 @@ export default function SimulationProperties (props) { if (typeSimulation !== 'noiseAnalysis') { controlBlock = `\n.control \nrun \nprint ${cblockline} > data.txt \n.endc \n.end` } else { - controlBlock = `\n.control \nrun \n${noiseMode} \nprint ${cblockline} > data.txt \n.endc \n.end` + controlBlock = `\n.control \nrun \nsetplot noise1\nprint all > data.txt \n.endc \n.end` } // console.log(controlLine) diff --git a/esim-cloud-backend/simulationAPI/helpers/parse.py b/esim-cloud-backend/simulationAPI/helpers/parse.py index 08bd89538..5e16945cf 100644 --- a/esim-cloud-backend/simulationAPI/helpers/parse.py +++ b/esim-cloud-backend/simulationAPI/helpers/parse.py @@ -1,39 +1,43 @@ import re import sys +NGSPICE_INTERNAL_VARS = { + 'false', 'true', 'boltz', 'c', 'pi', 'kelvin', 'e', + 'echarge', 'i', 'infinity', 'nan', 'no', 'yes', 'planck' +} def extract_data_from_ngspice_output(pathToFile): """ Parses the output file generated by ngspice and returns a json containing points to plot graph. """ - try: with open(pathToFile, 'r') as f: f_contents = f.readlines() graph = False - curernt_headers = [] total_number_of_tables = 0 if(len(f_contents) > 3): if('---' in f_contents[2]): graph = True - if(not graph): json_data = {"data": [], "graph": "false"} for line in f_contents: contents_of_line = line.split() + if len(contents_of_line) >= 1: + var_name = contents_of_line[0].lower().rstrip('=').split('(')[-1].rstrip(')') + if var_name in NGSPICE_INTERNAL_VARS: + continue json_data["data"].append(contents_of_line) - else: json_data = {"data": [], "graph": "true"} for line in f_contents: contents_of_line = line.split() - + if len(contents_of_line) >= 1: + var_name = contents_of_line[0].lower().rstrip('=').split('(')[-1].rstrip(')') + if var_name in NGSPICE_INTERNAL_VARS: + continue if('Index' in contents_of_line): - # line_set = remove_duplicate_items_from_list( - # contents_of_line) line_set = contents_of_line - if(line_set != curernt_headers): curernt_headers = line_set json_data["data"].append( @@ -41,40 +45,25 @@ def extract_data_from_ngspice_output(pathToFile): index = len(json_data["data"]) - 1 for x in range(2, len(curernt_headers)): json_data["data"][index]["y"].append([]) - for x in range(1, len(curernt_headers)): json_data["data"][index]["labels"].append( curernt_headers[x]) total_number_of_tables += 1 - else: m = re.match('[0-9]+', line) if(m): index = len(json_data["data"]) - 1 data = json_data["data"][index] data["x"].append(contents_of_line[1]) - for x in range(len(data["y"])): data["y"][x].append(contents_of_line[x+2]) json_data["total_number_of_tables"] = total_number_of_tables -\ len(json_data["data"]) return json_data - except IOError as e: print('Cannot Open File') raise e - -# def remove_duplicate_items_from_list(line_list): -# res = [] -# for i in line_list: -# if i not in res: -# res.append(i) -# return res - - -# for testing provide the filepath as command line argument if __name__ == "__main__": - filePath = sys.argv[1] print(extract_data_from_ngspice_output(filePath)) From 4bc5030cc01aca2eddf77564aeac7f5e5bb8dd29 Mon Sep 17 00:00:00 2001 From: Imran Farhat Date: Sun, 14 Jun 2026 16:58:50 +0530 Subject: [PATCH 2/3] fix: respect Show Noise Spectrum toggle in noise analysis control block After rebasing onto updated develop, the noiseMode variable (setplot noise1 vs noise2 based on outputSpectrum toggle) was introduced but not used in the control block, which was hardcoded to setplot noise1. Use noiseMode so the toggle correctly switches between: - noise1: inoise_spectrum/onoise_spectrum (frequency-domain) - noise2: inoise_total/onoise_total (integrated totals) Both modes verified working with correct vector names and no ngspice internal variable pollution. --- .../src/components/SchematicEditor/SimulationProperties.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eda-frontend/src/components/SchematicEditor/SimulationProperties.js b/eda-frontend/src/components/SchematicEditor/SimulationProperties.js index 82e208374..434de544e 100644 --- a/eda-frontend/src/components/SchematicEditor/SimulationProperties.js +++ b/eda-frontend/src/components/SchematicEditor/SimulationProperties.js @@ -775,7 +775,7 @@ export default function SimulationProperties (props) { if (typeSimulation !== 'noiseAnalysis') { controlBlock = `\n.control \nrun \nprint ${cblockline} > data.txt \n.endc \n.end` } else { - controlBlock = `\n.control \nrun \nsetplot noise1\nprint all > data.txt \n.endc \n.end` + controlBlock = `\n.control \nrun \n${noiseMode}\nprint all > data.txt \n.endc \n.end` } // console.log(controlLine) From 9a84e70484abbb651ba1d21034a0b96d4f293af2 Mon Sep 17 00:00:00 2001 From: Imran Farhat Date: Sun, 14 Jun 2026 17:09:04 +0530 Subject: [PATCH 3/3] chore: remove unrelated Bug 3a carry-over from noise analysis branch This change was a carry-over fix for a different bug (Ctrl+S null crash) that doesn't belong in this PR. Keeping this branch scoped to only the noise analysis fix (Bug 2). --- eda-frontend/src/components/SchematicEditor/SchematicToolbar.js | 1 - 1 file changed, 1 deletion(-) diff --git a/eda-frontend/src/components/SchematicEditor/SchematicToolbar.js b/eda-frontend/src/components/SchematicEditor/SchematicToolbar.js index 58baafdc6..90249b411 100644 --- a/eda-frontend/src/components/SchematicEditor/SchematicToolbar.js +++ b/eda-frontend/src/components/SchematicEditor/SchematicToolbar.js @@ -430,7 +430,6 @@ export default function SchematicToolbar ({ // Image Export of Schematic Diagram async function exportImage (type) { - if (!gridRef.current) { return null } const svg = document.querySelector('#divGrid > svg').cloneNode(true) svg.removeAttribute('style') svg.setAttribute('width', gridRef.current.scrollWidth)