2021年7月29日 星期四

如何在ListBox輸出滑鼠點選順序的序列

ListBox預設只能輸出由上而下輸出所選序列,跟滑鼠點選順序無關。如果要輸出滑鼠點選順序的序列,可參考以下程式碼。

# coding=utf-8
import os, re, sys, clr, json, math, logging

os.chdir(os.path.dirname(__file__))
logging.basicConfig(filename='gui.log', filemode='w', encoding='utf-8', level=logging.DEBUG)
clr.AddReference('System.Drawing')
clr.AddReference('System.Windows.Forms')

from System import Drawing, Array, ComponentModel, Diagnostics, IO
from System.Windows import Forms
import System.Object as object
import System.String as string
from System.Windows.Forms import DialogResult, OpenFileDialog, SaveFileDialog, FolderBrowserDialog

# ----------------------------------------------------------------------------
try:
image_path = './ANSYS.png'
oDesktop.ClearMessages("", "", 2)
AddWarningMessage('Welcome')
except:
pass


# ----------------------------------------------------------------------------
class MyForm(Forms.Form):
def __init__(self):
self.listBox1 = Forms.ListBox()
self.textBox1 = Forms.TextBox()
self.SuspendLayout()
# listBox1
self.listBox1.FormattingEnabled = True
self.listBox1.ItemHeight = 19
self.listBox1.Items.Add("a")
self.listBox1.Items.Add("b")
self.listBox1.Items.Add("c")
self.listBox1.Items.Add("d")
self.listBox1.Items.Add("e")
self.listBox1.Items.Add("f")
self.listBox1.Items.Add("g")
self.listBox1.Items.Add("h")
self.listBox1.Items.Add("i")
# self.listBox1.SelectedIndex = 0
self.listBox1.Location = Drawing.Point(12, 12)
self.listBox1.Name = "listBox1"
self.listBox1.SelectionMode = Forms.SelectionMode.MultiExtended
self.listBox1.Size = Drawing.Size(331, 422)
self.listBox1.TabIndex = 0
self.listBox1.SelectedIndexChanged += self.listBox1_SelectedIndexChanged

# textBox1
self.textBox1.Location = Drawing.Point(388, 12)
self.textBox1.Multiline = True
self.textBox1.Name = "textBox1"
self.textBox1.Size = Drawing.Size(400, 426)
self.textBox1.TabIndex = 1
# Form1
self.AutoScaleDimensions = Drawing.SizeF(9, 19)
self.AutoScaleMode = Forms.AutoScaleMode.Font
self.ClientSize = Drawing.Size(800, 450)
self.Controls.Add(self.textBox1)
self.Controls.Add(self.listBox1)
self.Name = "Form1"
self.Text = "Form1"
self.ResumeLayout(False)
self.PerformLayout()
self.selected = []

def listBox1_SelectedIndexChanged(self, sender, e):

sel = [i for i in sender.SelectedItems]
if not set(self.selected).issubset(set(sel)):
self.selected = []

for i in self.selected:
sel.remove(i)
self.selected += list(sel)
self.textBox1.Text = str(self.selected)


if __name__ == '__main__':
try:
form = MyForm()
form.ShowDialog()
form = MyForm()
form.Dispose()
# form.Show()
# oDesktop.PauseScript()
except:
logging.exception('ERROR!')



2021年7月24日 星期六

如何在GUI當中直接顯示圖片

在編寫GUI時,如果我們想要在GUI上面加上圖片,又不希望另外附加圖片檔,那可以將圖片轉成base64格式的字串放在Python檔案當中,透過函數呼叫直接導入到PictureBox。

# coding=utf-8
import os, re, sys, clr, json, math, logging
os.chdir(os.path.dirname(__file__))
logging.basicConfig(filename='gui.log', filemode='w', encoding='utf-8', level=logging.DEBUG)
clr.AddReference('System.Drawing')
clr.AddReference('System.Windows.Forms')

from System import Drawing, Array, ComponentModel, Diagnostics, IO, Convert
from System.Windows import Forms
import System.Object as object
import System.String as string
from System.Windows.Forms import DialogResult, OpenFileDialog ,SaveFileDialog, FolderBrowserDialog
#----------------------------------------------------------------------------
base64_img = '''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
AAAAAAAAAAAAAAAAAAAAAAAH//2Q=='''



#----------------------------------------------------------------------------
class MyForm(Forms.Form):
def __init__(self):
self.pictureBox1 = Forms.PictureBox()
((self.pictureBox1)).BeginInit()
self.SuspendLayout()
# pictureBox1
self.pictureBox1.Location = Drawing.Point(95, 46)
self.pictureBox1.Name = "pictureBox1"
self.pictureBox1.Size = Drawing.Size(589, 337)
self.pictureBox1.TabIndex = 0
self.pictureBox1.TabStop = False
x = Drawing.Image.FromStream(IO.MemoryStream(Convert.FromBase64String(base64_img)))
self.pictureBox1.Image = x
# Form1
self.AutoScaleDimensions = Drawing.SizeF(9, 19)
self.AutoScaleMode = Forms.AutoScaleMode.Font
self.ClientSize = Drawing.Size(800, 450)
self.Controls.Add(self.pictureBox1)
self.Name = "Form1"
self.Text = "Form1"
((self.pictureBox1)).EndInit()
self.ResumeLayout(False)

if __name__ == '__main__':
form = MyForm()
form.ShowDialog()
form = MyForm()
form.Dispose()
AddWarningMessage('Good Bye!')
#form.Show()
#oDesktop.PauseScript()



2021年7月4日 星期日

如何將tech檔案轉成控制檔

在手動匯入GDSII檔案的時候,我們是輸入.tech檔案將層數編號轉成一般的名稱,如圖一。但是在錄製腳本的時候,無法設定.tech檔案。這時候我們可以利用控制檔(.xml)來取代,程式碼如下:

oTool = oDesktop.GetTool("ImportExport")
oTool.ImportGDSII(gds_path, aedb_path, control_path, "")

以下函數可以將.tech檔轉成.xml檔:

def techToControlFile(tech_path, unit='mm'):
result = []
with open(tech_path) as f:
for line in f:
try:
layerID, layer_name, color, elevation, layer_height = line.split()
x = ' <Layer Color="#ff0000" GDSIIVia="false" Name="{}" TargetLayer="{}" Thickness="{}" Type="conductor"/>'.format(
layerID, layer_name, layer_height)
result.append(x)
except:
pass

frame = '''<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<c:Control xmlns:c="http://www.ansys.com/control" schemaVersion="1.0">

<Stackup schemaVersion="1.0">
<Layers LengthUnit="{}">
{}
</Layers>
</Stackup>

<ImportOptions Flatten="true" GDSIIConvertPolygonToCircles="false" ImportDummyNet="true"/>

</c:Control>'''

return frame.format(unit, '\n'.join(result))

(圖一) 手動操作時設定.tech檔來選定匯入的GDS層


2021年6月22日 星期二

在Spyder開發演算法,再結合到AEDT當中

 AEDT編程環境不提供除錯的功能,如果算法牽涉到複雜的數學計算,可以先在Spyder當中完成,再將其整合到AEDT當中。以下是在一條線周圍等間距加上vias。因此我先定義線的點位置。在Spyder當中開發算法,並確認工作無誤才整合到AEDT 3D Layout當中。

# -*- coding: utf-8 -*-
"""
Created on Tue Jun 22 06:48:44 2021

@author: mlin
"""

from math import sin, cos, atan, pi, sqrt, degrees, acos
import matplotlib.pyplot as plt

plt.figure(figsize=(6, 6))

distance = 5
line = [(0, 0), (50, 0), (50, 50), (0, 50), (0, 10), (25, 25)]


def getAngle(v1, v2):
v1_mag = sqrt(v1[0] ** 2 + v1[1] ** 2)
v2_mag = sqrt(v2[0] ** 2 + v2[1] ** 2)
dotsum = v1[0] * v2[0] + v1[1] * v2[1]
if v1[0] * v2[1] - v1[1] * v2[0] > 0:
scale = 1
else:
scale = -1
dtheta = scale * acos(dotsum / (v1_mag * v2_mag))
print(v1, v2)
print(degrees(dtheta))

return dtheta


def getParalletLines(pts, distance):
leftline = []
rightline = []

x0, y0 = pts[0]
x1, y1 = pts[1]
vector = (x1 - x0, y1 - y0)
orientation1 = getAngle((1, 0), vector)

leftturn = orientation1 + pi / 2
righrturn = orientation1 - pi / 2
leftPt = (x0 + distance * cos(leftturn), y0 + distance * sin(leftturn))
leftline.append(leftPt)
rightPt = (x0 + distance * cos(righrturn), y0 + distance * sin(righrturn))
rightline.append(rightPt)

for n in range(1, len(pts) - 1):
print('hello')
x0, y0 = pts[n - 1]
x1, y1 = pts[n]
x2, y2 = pts[n + 1]

v1 = (x1 - x0, y1 - y0)
v2 = (x2 - x1, y2 - y1)
dtheta = getAngle(v1, v2)
orientation1 = getAngle((1, 0), v1)
print(degrees(dtheta))

leftturn = orientation1 + dtheta / 2 + pi / 2
righrturn = orientation1 + dtheta / 2 - pi / 2

distance2 = distance / sin((pi - dtheta) / 2)
leftPt = (x1 + distance2 * cos(leftturn), y1 + distance2 * sin(leftturn))
leftline.append(leftPt)
rightPt = (x1 + distance2 * cos(righrturn), y1 + distance2 * sin(righrturn))
rightline.append(rightPt)

x0, y0 = pts[-2]
x1, y1 = pts[-1]

vector = (x1 - x0, y1 - y0)
orientation1 = getAngle((1, 0), vector)
leftturn = orientation1 + pi / 2
righrturn = orientation1 - pi / 2
leftPt = (x1 + distance * cos(leftturn), y1 + distance * sin(leftturn))
leftline.append(leftPt)
rightPt = (x1 + distance * cos(righrturn), y1 + distance * sin(righrturn))
rightline.append(rightPt)
return leftline, rightline


def getLocations(line, gap):
location = [line[0]]
residual = 0

for n in range(len(line) - 1):
x0, y0 = line[n]
x1, y1 = line[n + 1]
length = sqrt((x1 - x0) ** 2 + (y1 - y0) ** 2)
dx, dy = (x1 - x0) / length, (y1 - y0) / length
x = x0 - dx * residual
y = y0 - dy * residual
length = length + residual
while length >= gap:
x += gap * dx
y += gap * dy
location.append((x, y))
length -= gap

residual = length

return location


plt.plot(*zip(*line), c='black', linewidth=3)
leftline, rightline = getParalletLines(line, 2)
plt.plot(*zip(*leftline), c='r')
plt.plot(*zip(*rightline), c='b')

locations = getLocations(rightline, 8)
plt.scatter(*zip(*locations), s=20)

locations = getLocations(leftline, 8)
plt.scatter(*zip(*locations), s=20)

plt.show()

(圖一) 平行線與Via圍牆


2021年6月16日 星期三

如何在不開啟AEDT執行電路模擬

之前介紹過在Command Window執行nexxim,速度快,缺點是sdf2csv只能轉出S parameter和時域資料。複雜一點的如Z parameter,眼圖統計等就沒辦法了。這邊的做法是將整個包含有netlist的AEDT檔案內容當成字串放在.py當中,修改字串當中的資料即可更改netlist設計或設定。將其輸出成.aedt檔再以ansysedt執行之後輸出所需資料即可。

run.bat

SET PATH=%PATH%;D:\Program Files\AnsysEM\AnsysEM21.1\Win64
ansysedt.exe -features=beta -ng -RunScriptAndExit .\run.py

run.py


text = r"""$begin 'AnsoftProject'
Created='Wed Jun 16 06:35:01 2021'
Product='ElectronicsDesktop'
FileOwnedByWorkbench=false
$begin 'Desktop'
Version(2021, 1)
InfrastructureVersion(1, 0)
$begin 'FactoryHeader'
$end 'FactoryHeader'
$end 'Desktop'
UsesAdvancedFeatures=false
NextUniqueID=0
MoveBackwards=false
$begin 'HFSSEnvironment'
Version(1, 0)
$end 'HFSSEnvironment'
$begin 'PlanarEMEnvironment'
Version(1, 0)
$end 'PlanarEMEnvironment'
$begin 'Q3DEnvironment'
Version(1, 0)
$end 'Q3DEnvironment'
$begin '2DExtractorEnvironment'
Version(1, 0)
$end '2DExtractorEnvironment'
$begin 'NexximEnvironment'
Version(1, 0)
$end 'NexximEnvironment'
$begin 'NexximNetlistEnvironment'
Version(1, 0)
$end 'NexximNetlistEnvironment'
$begin 'EmitEnvironment'
Version(1, 0)
$end 'EmitEnvironment'
$begin 'Maxwell3DEnvironment'
Version(1, 0)
$end 'Maxwell3DEnvironment'
$begin 'Maxwell2DEnvironment'
Version(1, 0)
$end 'Maxwell2DEnvironment'
$begin 'RMxprtEnvironment'
Version(1, 0)
$end 'RMxprtEnvironment'
$begin 'MaxCirEnvironment'
Version(1, 0)
$end 'MaxCirEnvironment'
$begin 'SimplorerEnvironment'
Version(1, 0)
$end 'SimplorerEnvironment'
$begin 'IcepakEnvironment'
Version(1, 0)
$end 'IcepakEnvironment'
$begin 'MechanicalEnvironment'
Version(1, 0)
$end 'MechanicalEnvironment'
$begin 'FilterDesignEnvironment'
$end 'FilterDesignEnvironment'
$begin 'SchematicEnvironment'
Version(1, 0)
$end 'SchematicEnvironment'
$begin 'geometry3deditor'
Version(1, 0)
$end 'geometry3deditor'
ReadVersion=8
$begin 'DesignMgrEnvironment'
CompInstCounter=1
GPortCounter=0
NetCounter=0
Alias('Ieee;Simplorer Elements\\Ieee', 'Std;Simplorer Elements\\Std', 'Basic_VHDLAMS;Simplorer Elements\\Basic Elements VHDLAMS\\Basic Elements VHDLAMS', 'Digital_Elements;Simplorer Elements\\Digital Elements\\Digital Elements', 'Transformations;Simplorer Elements\\Tools\\Transformations\\Transformations', 'HEV_VHDLAMS;Simplorer Elements\\HEV VHDLAMS\\HEV VHDLAMS', 'automotive_vda;Simplorer Elements\\VDALibs VHDLAMS\\automotive_vda', 'example_boardnet;Simplorer Elements\\VDALibs VHDLAMS\\example_boardnet', 'example_ecar;Simplorer Elements\\VDALibs VHDLAMS\\example_ecar', 'fundamentals_vda;Simplorer Elements\\VDALibs VHDLAMS\\fundamentals_vda', 'hybrid_emc_vda;Simplorer Elements\\VDALibs VHDLAMS\\hybrid_emc_vda', 'megma;Simplorer Elements\\VDALibs VHDLAMS\\megma', 'modelica_rotational;Simplorer Elements\\VDALibs VHDLAMS\\modelica_rotational', 'modelica_thermal;Simplorer Elements\\VDALibs VHDLAMS\\modelica_thermal', 'modelica_translational;Simplorer Elements\\VDALibs VHDLAMS\\modelica_translational', 'spice2vhd;Simplorer Elements\\VDALibs VHDLAMS\\spice2vhd', 'spice2vhd_devices;Simplorer Elements\\VDALibs VHDLAMS\\spice2vhd_devices', 'aircraft_electrical_vhdlams;Simplorer Elements\\Aircraft Electrical VHDLAMS\\Aircraft Electrical VHDLAMS', 'power_system_vhdlams;Simplorer Elements\\Power System VHDLAMS\\Power System VHDLAMS')
$end 'DesignMgrEnvironment'
$begin 'ProjectDatasets'
NextUniqueID=0
MoveBackwards=false
DatasetType='ProjectDatasetType'
$begin 'DatasetDefinitions'
$end 'DatasetDefinitions'
$end 'ProjectDatasets'
VariableOrders[0:]
$begin 'Definitions'
$begin 'Folders'
Definitions(1604, 10000, 1, 1, 0, false, false)
Materials(1604, 9500, 9, 2, 1, false, false)
'Surface Materials'(1604, 9501, 33503, 3, 1, false, false)
Scripts(1604, 9502, 33500, 4, 1, false, false)
Padstacks(1604, 9003, 12, 105, 1, false, false)
Symbols(1604, 9001, 10, 103, 1, false, false)
Footprints(1604, 9002, 11, 104, 1, false, false)
Bondwires(1604, 9006, 12, 108, 1, false, false)
Components(1604, 9000, 8, 102, 1, false, false)
Models(1604, 9004, 13, 106, 1, false, false)
Packages(1604, 9005, 33502, 107, 1, false, false)
$end 'Folders'
$begin 'Materials'
$end 'Materials'
$begin 'SurfaceMaterials'
$end 'SurfaceMaterials'
$begin 'Scripts'
$end 'Scripts'
$begin 'Symbols'
$begin 'CircuitNetlist1'
ModTime=1623796486
Library=''
ModSinceLib=false
LibLocation='Project'
HighestLevel=1
Normalize=true
InitialLevels(0, 1)
$begin 'Graphics'
Rect(0, 0, 0, 0, 0.00254, 0.00254, 0.00508, 0.00508, 0, 0, 0)
Rect(0, 1, 0, 0, 0.000423333333333333, 0.00254, 0.000423333333333333, 0.000423333333333334, 0, 0, 0)
$end 'Graphics'
$end 'CircuitNetlist1'
$end 'Symbols'
$begin 'DefInfo'
CircuitNetlist1(1002, 0, 17, 0, '', 1623796486, '', 'CircuitNetlist1', '', '', '', '', '', 'Design.bmp', '', 'Project', '', '', 1623796486, '', 0, 0)
$end 'DefInfo'
$begin 'Compdefs'
$begin 'CircuitNetlist1'
Library=''
CircuitEnv=0
Refbase='U'
NumParts=1
ModSinceLib=true
$begin 'Properties'
TextProp('Representation', 'SRD', '', 'CircuitNetlist1')
TextProp('Owner', 'SRD', '', 'Circuit Netlist')
$end 'Properties'
CompExtID=6
$end 'CircuitNetlist1'
$end 'Compdefs'
$end 'Definitions'
DesignIDServer=3
MoveBackwards=false
$begin 'NexximNetlist'
RepRewriteV2=true
Name='CircuitNetlist1'
DesignID=1
$begin 'DesignDatasets'
NextUniqueID=0
MoveBackwards=false
DatasetType='DesignDatasetType'
$begin 'DatasetDefinitions'
$end 'DatasetDefinitions'
$end 'DesignDatasets'
VariableOrders[0:]
Language='HSPICE'
$begin 'Netlist'
Text='* 0;Circuit1.sph\
**************************************************************************************************\
* Circuit Design netlist *\
* created by ANSYS Electronics Desktop *\
**************************************************************************************************\
\
.option PARHIER=\'local\'\
.option max_messages=1\
\
* begin toplevel circuit\
\
C1 Port1 Port2 1e-12\
RPort1 Port1 0 PORTNUM=1 RZ={0} IZ=0 \
.PORT Port1 0 1 RPort1 \
RPort2 Port2 0 PORTNUM=2 RZ={0} IZ=0 \
.PORT Port2 0 2 RPort2 \
\
* end toplevel circuit\
.LNA\
+ LIN 10 0 1000000000\
+ FLAG=\'LNA\'\
\
.end'
$end 'Netlist'
$begin 'OutputVariable'
NextUniqueID=0
MoveBackwards=false
$end 'OutputVariable'
$begin 'SolutionManager'
$begin 'SimDataExtractors'
$begin 'Version ID Map'
V=1
$end 'Version ID Map'
$end 'SimDataExtractors'
$begin 'Variations'
$end 'Variations'
$end 'SolutionManager'
IntegrationMethod='FFT'
InvisibleFlag=false
OwnerDesignInstance=0
OwnerSetup=''
OwnerSolutionID=0
DefaultSetupID=-1
$begin 'UserDefinedSolutionMgr'
NextUniqueID=1000000
MoveBackwards=false
$end 'UserDefinedSolutionMgr'
$begin 'DatasetSolutionMgr'
NextUniqueID=2000000
MoveBackwards=false
$end 'DatasetSolutionMgr'
Notes=$begin_cdata$ $end_cdata$
$begin 'AnimationSetups'
$end 'AnimationSetups'
CacheHeaderFile='HDR4E7B1498016237965015.tmp'
$end 'NexximNetlist'
$begin 'DataInstances'
DesignEditor='TopLevel'
Refdes('0', 'U1')
$begin 'CompInstances'
$begin 'Compinst'
ID='0'
Status='Status'
CompName='CircuitNetlist1'
GatesInUse()
$begin 'Properties'
TextProp('ID', 'SRID', '', '0')
$end 'Properties'
$end 'Compinst'
$end 'CompInstances'
$begin 'Instance'
DesignEditor='CircuitNetlist1'
ID='0'
$begin 'NexximNetlist'
DesignInstanceID=2
$begin 'WindowPosition'
$begin 'EditorWindow'
Netlist(Netlist(View(WindowPos(3, -1, -1, -9, -38, 32, 32, 1231, 390))))
$end 'EditorWindow'
$end 'WindowPosition'
$begin 'ReportSetup'
$begin 'ReportManager'
$begin 'Reports'
$end 'Reports'
NextUniqueID=0
MoveBackwards=false
$begin 'NextVersID'
NextUniqueID=0
MoveBackwards=false
$end 'NextVersID'
$end 'ReportManager'
$begin 'Reports'
$end 'Reports'
$begin 'ReportsWindowInfoList'
$end 'ReportsWindowInfoList'
$end 'ReportSetup'
$begin 'Properties'
$end 'Properties'
$begin 'UserDefinedDocument'
$begin 'Data'
$end 'Data'
$end 'UserDefinedDocument'
$end 'NexximNetlist'
$end 'Instance'
$begin 'SODInfo'
$end 'SODInfo'
$end 'DataInstances'
$begin 'WBSystemIDToDesignInstanceIDMap'
$end 'WBSystemIDToDesignInstanceIDMap'
$begin 'WBSysIDSysDetails'
$end 'WBSysIDSysDetails'
$begin 'WBConnIDConnDetails'
$end 'WBConnIDConnDetails'
$begin 'WBMaterialGuidDetails'
WBMaterialGuidMap()
$end 'WBMaterialGuidDetails'
$begin 'MinervaProjectSettingsBlk'
MinervaRemoteFilePath=''
FolderContainerString=''
$end 'MinervaProjectSettingsBlk'
$end 'AnsoftProject'
$begin 'AllReferencedFilesForProject'
$end 'AllReferencedFilesForProject'
$begin 'ProjectPreview'
IsEncrypted=false
Thumbnail64=''
$begin 'DesignInfo'
DesignName='CircuitNetlist1'
Notes=''
Factory='Circuit Netlist'
IsSolved=false
'Nominal Setups'[0:]
'Nominal Setup Types'[0:]
'Optimetrics Setups'[0:]
'Optimetrics Experiment Types'[0:]
Image64=''
$end 'DesignInfo'
$end 'ProjectPreview'
"""
with open('d:/demo/x5.aedt', 'w') as f:
f.write(text.format(50))

oDesktop.OpenProject("D:/demo/x5.aedt")
oProject = oDesktop.SetActiveProject("x5")
oDesign = oProject.SetActiveDesign("CircuitNetlist1")
oDesign.AnalyzeAll()
oModule = oDesign.GetModule("ReportSetup")
oModule.CreateReport("Z Parameter Plot 1", "Standard", "Rectangular Plot", "LNA",
[
"NAME:Context",
"SimValueContext:=" , [3,0,2,0,False,False,-1,1,0,1,1,"",0,0]
],
[
"Freq:=" , ["All"]
],
[
"X Component:=" , "Freq",
"Y Component:=" , ["dB(Z(1,1))","dB(Z(2,1))","dB(Z(1,2))","dB(Z(2,2))"]
])
oModule.ExportToFile("Z Parameter Plot 1", "D:/demo/sss.csv", False)


2021年6月15日 星期二

DataGridView資料儲存與載入

 按鈕將資料保存到Json檔案當中,下次執行程式自動載入。

def Form1_Load(self, sender, e):
try:
with open('./data.json') as f:
data = json.load(f)
AddWarningMessage(str(data))
for i in data:
self.dataGridView1.Rows.Add(*i)
except:
return None


def button1_Click(self, sender, e):
data = []
try:
for i in range(len(self.dataGridView1.Rows)):
data.append([])
for j in range(len(self.dataGridView1.Rows[i].Cells)):
x = self.dataGridView1.Rows[i].Cells[j].Value
if j == 3:
data[i].append(True if x else False)
continue
if not string.IsNullOrEmpty(x):
data[i].append(x)
else:
data[i].append("")
except:
raise
with open('./data.json', 'w') as f:
json.dump(data, f)



2021年6月10日 星期四

如何將.sdf.csv檔轉成sNp檔

如何利用Python呼叫nexxim.exe執行電路模擬當中,我們介紹了如何在command line環境執行nexxim.exe完成電路網表模擬。如果網表做的是S參數模擬,該如何將輸出的.sdf.csv檔轉成S參數檔案?以下代碼即可將.sdf.csv轉成.sNp檔:

with open ('netlist.cir.sdf.csv') as f:
header = next(f)
N = int(math.sqrt(((len(header.split(','))-2)/2)))
with open('result.s{}p'.format(N), 'w') as fsnp:
fsnp.writelines('# Hz S RI R 50.000000\n\n')
for line in f:
data = line.split(',')
fsnp.write(' '.join(data[1:]))