如何使用python调用ads接口(版图仿真)

背景

最近在做射频器件逆向设计,需要使用python调用ads生成数据,于是向师兄请教,在踩了很多坑之后终于成功了,记录一下整个过程

环境介绍

ads 2017(师兄用的是2021,俺估计2017及更新的版本都可以使用)
python3.6(主要是使用os)

具体操作过程

ads帮助文档

请添加图片描述
在ads的官方文档中,这篇文章是完整讲述如何使用ads接口(也就是用命令行的形式进行版图仿真),遇到啥问题找这里。

配置环境以及测试

在调用ads前,需要先修改系统环境变量;windows下的环境变量配置(我修改的是系统变量,不清楚修改用户变量是否有相同的效果)

set HPEESOF_DIR=<path_to_ADS_installation_directory> # for example: set HPEESOF_DIR=C:\Progam Files\Keysight\ADS2014_11
set ADS_LICENSE_FILE=<path_to_ADS_license_file_or_server> # for example: set ADS_LICENSE_FILE=C:\Program Files\Keysight\EEsof_License_Tools\licenses\license.lic
set PATH=%HPEESOF_DIR%\bin;%PATH% 

注:不要直接在cmd控制台中直接使用这些命令,那样只是临时的变量,需要自己到环境变量中配置;
在这里插入图片描述

这里有个小坑是如果你在破解时没有lincense文件,那就不用配置证书的那条,只需配置第一三条就可以使用了(我就是这样,破解时没有lincense)
记得配置完后重启电脑(很重要!!!!)

配置后的测试:adsMomWrapper --version
在这里插入图片描述

em生成仿真初始化文件

在需要仿真的layout文件中打开仿真界面,生成仿真输入文件
打开仿真界面
在这里插入图片描述
生成之后的文件夹长这样
在这里插入图片描述
这个文件夹的路径在工作空间的simulation文件夹里
比如:D:/<your ads workspace>/simulation/*****/*****/layout

开始仿真

这部分就没啥说的,只要cd到指定的目标文件夹下,然后调用命令就可以了,详细见后文的代码部分
不过这个命令有两种

# 命令格式:adsMomWrapper -T proj proj 
Substrate file pre-processing (e.g. expanding substrate for thick conductors)
-T

Substrate database generation (Green function calculation)
-DB

Layout pre-processing and mesh generation
-M

S-parameter model generation
-3D

Far Field calculation
-FF

# 还有一种是这种,也就是连续执行,从-T执行到-3D;-3D也就是我们常用的s参数仿真
adsMomWrapper -O -3D proj proj 

因为俺最近升级了win11,用连续执行的命令会报错。。只能分开写。如下图(python里用os包使用ads的接口命令)
在这里插入图片描述
仿真后的文件变成这样(部分文件)
在这里插入图片描述
其中仿真后s参数的文件保存在 .cti 文件中。
注:不同type的仿真生成的s参数文件不同;
adaptive模式生成的是 .afs 文件,其他没有测过。
在这里插入图片描述
上述情况是单次仿真,如果需要改变器件的参数(比如微带线长度/宽度)进行连续仿真,则需要修改
proj_a和proj.pin文件
proj_a里面是器件的位置,以单条微带线为例,其中一行是微带线矩形四个点的坐标,这点需要按实际需求自己改
proj.pin保存了p针头的坐标,要和proj_a中器件的端口对应起来
其他需求照例子看看文件,俺是一个一个文件找过去的。

完整过程以及补充

梳理一下完整的过程,以及补充一个坑
1.配置环境变量,重启电脑。
2.打开python,open打开文件,修改内部器件参数
3.使用os.system,cd到目标的仿真文件夹,再使用ads命令仿真。
4.如果ads无法连续仿真,也就是仿真第一次后,后面几次执行命令后其实没有仿真而是和第一次的仿真数据一样,说明无法连续仿真,这时可以把文件中多余的文件删掉,这样下一次仿真时才是正常的。
(具体文件对比大家就自己对照写写吧,仿真文件不同生成的文件也不同)

至于怎么保存数据这就看各人的需求了
完整代码下图(作为例子)

import os
import math
import numpy as np
import pandas as pd


# liner对应.cti adapt对应.afs 提取S参数,读取S参数
def read_cti(path: str):
    print(path)
    read_c = open(path + "/proj.cti")
    data = read_c.read()
    read_c.close()
    data = data.split("BEGIN\n")
    s_str = data[2].split("END")
    s11_str = s_str[0].replace("\t", "")
    s11_str = s11_str.split("\n")
    s_str = data[4].split("END")
    s21_str = s_str[0].replace("\t", "")
    s21_str = s21_str.split("\n")

    s11_r = []
    s11_i = []
    s21_r = []
    s21_i = []
    s21_phase = []
    for i in range(len(s11_str) - 1):
        s11_ri = s11_str[i].split(",")
        s21_ri = s21_str[i].split(",")
        s11_r.append(float(s11_ri[0]))
        s11_i.append(float(s11_ri[1]))
        s21_r.append(float(s21_ri[0]))
        s21_i.append(float(s21_ri[1]))
        s21_phase.append(math.atan2(s21_i[i], s21_r[i]) * 180 / math.pi)
    return s21_phase

# 修改仿真前配置文件,即修改器件设计参数
def generate_s21(proj_path: str, w1):
    i_hang = 0
    with open(proj_path + r"\proj_a") as read_f, open(proj_path + r"\.proj_a", 'w') as write_f:
        for line in read_f:
            if i_hang == 2:
                print(line)
                line = "ADD P1 :W0.000000  -0.9500,-0.2750 %.4f,-0.2750 %.4f,0.4350 -0.9500,0.4350;\r" % (w1, w1)
                write_f.write(line)
            else:
                write_f.write(line)
            i_hang = i_hang + 1

    os.remove(proj_path + r"\proj_a")
    os.rename(proj_path + r"\.proj_a", proj_path + r"\proj_a")

    i_hang = 0
    w1_p = w1 * math.pow(10, -3)
    with open(proj_path + r"\proj.pin") as read_f_1, open(proj_path + r"\.proj.swap.pin", 'w') as write_f_1:
        for line in read_f_1:
            if i_hang == 25:
                print(line)
                line = "          <x>%.5f</x>\r" % w1_p
                write_f_1.write(line)
            else:
                write_f_1.write(line)
            i_hang = i_hang + 1

    os.remove(proj_path + r"\proj.pin")
    os.rename(proj_path + r"\.proj.swap.pin", proj_path + r"\proj.pin")

    # os.system("cd %s && adsMomWrapper -O -3D proj proj" % proj_path)
    os.chdir(proj_path)
    print(os.getcwd())
    # 仿真命令
    os.system("adsMomWrapper -T proj proj")
    os.system("adsMomWrapper -DB proj proj")
    os.system("adsMomWrapper -M proj proj")
    os.system("adsMomWrapper -3D proj proj")


# 删除上一次的仿真文件,才能进行下一次的(这里的功能是抄了一位博客园老哥的代码,链接放到最后)
def Delete_S21(proj_path: str, fileList):
    for parent, dirnames, filenames in os.walk(proj_path):
        goodfilelist = []
        fullfilelist = []
        for x in fileList:
            goodfile = proj_path + x
            goodfilelist.append(goodfile)

        for filename in filenames:
            fullpath = parent + '/' + filename
            fullfilelist.append(fullpath)

        for xlist in fullfilelist:
            if xlist not in goodfilelist:
                os.remove(xlist)
    pass


if __name__ == '__main__':
    # proj_path = "D:/project_all/ADS/Myfirstlayout_wrk/simulation/Myfirstlayout_lib/uniform_line/layout/emSetup_MoM"
    proj_path = "D:/em"
    w1 = 4.0500
    s21_csv = pd.DataFrame()
    S21_Phase = np.zeros([1, 402])
    w1_list = np.arange(0.65, 139.05, 0.01)
    # 仿真需保留的文件,不在此list中的文件将被删除
    fileList = [r'/emStateFile.xml', r'/momentum.cfg', r'/proj.cfg', r'/proj.lcf', r'/proj.ltd', r'/proj.opt',
                r'/proj.params', r'/proj.pin', r'/proj.plan', r'/proj.prt', r'/proj.sti', r'/proj_a']

    for i in range(len(w1_list)):
        generate_s21(proj_path, w1_list[i])
        S21_Phase_hang = read_cti(proj_path)
        S21_Freq = np.array(w1_list[i])
        S21_Freq = np.reshape(np.append(S21_Freq, np.reshape(np.array(S21_Phase_hang), [1, 401])), [1, 402])
        S21_Phase = np.append(S21_Phase, S21_Freq, axis=0)
        Delete_S21(proj_path, fileList)

    S21_data = pd.DataFrame(S21_Phase)
    S21_data.to_csv("D:/project_all/python/phase/0.65-139.05mm-phase.csv")
    print("save complete")

最后一点建议

整个的仿真文件可以复制出来,单独在某个文件夹里也是可以正常运行的;
比如生成仿真input文件后,把所有文件复制出来,放到 D:/em (自己随便创建的)文件路径下,cd到目标路径后使用ads命令仿真,最后的仿真数据也会保存在em文件夹中,减小文件夹深度,也算是一点小优化吧。

python保留指定文件/删除目录其他文件的功能:
https://www.cnblogs.com/chub/p/4509921.html

2022.3.9更新

一个小bug

如果第一次在pycham(python的编辑器,俺用的是这个)无法运行ads的接口命令(卡在层叠数据加载那)。需先对仿真文件夹进行一次引导,如下图
即先cd到对应文件夹下,然后运行一次即可,中途记得输入“y”确定。(连续运行记得删除文件)
在这里插入图片描述

改了改过程,把整体过程写的详细了些

  • 11
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值