news 2026/6/13 3:09:26

基于 Python 的 ADS 自动化仿真框架与 API 使用指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于 Python 的 ADS 自动化仿真框架与 API 使用指南

1. 自动化数据提取工具库详解

为了简化 ADS 仿真程控的开发难度,我提供了一个通用的自动化工具库auto_simulator.py。该工具库封装了从环境配置、参数更新、仿真运行到结果提取的全流程,使得用户只需关注“如何将参数应用到电路”这一核心逻辑。

""" 通用自动化仿真模块 提供通用的ADS仿真自动化框架,支持批量参数扫描和结果提取。 用户只需实现参数更新接口即可使用。 """importpandasaspdimportnumpyasnpimportjsonimportosfrompathlibimportPathfromabcimportABC,abstractmethodfromtypingimportDict,List,Any,Optional,Callablefromkeysight.ads.deimportdb_uuasdbfromkeysight.adsimportdatasetimportutilsclassParameterUpdater(ABC):"""参数更新抽象接口"""@abstractmethoddefupdate_parameters(self,design:db.Design,param_row:pd.Series)->None:""" 更新电路参数 Args: design: ADS设计对象 param_row: 包含参数值的pandas Series """passclassAutoSimulator:"""通用自动化仿真器"""def__init__(self,parameter_updater:ParameterUpdater):""" 初始化仿真器 Args: parameter_updater: 参数更新器实例 """self.parameter_updater=parameter_updater self.design=Nonedefload_parameter_samples(self,filepath:str)->pd.DataFrame:"""加载参数样本数据,仅支持输出JSON格式"""filepath=Path(filepath)ifnotfilepath.exists():raiseFileNotFoundError(f"参数文件不存在:{filepath}")iffilepath.suffix.lower()==".json":withopen(filepath,"r",encoding="utf-8")asf:data=json.load(f)# 如果JSON数据是字典格式,转换为DataFrameifisinstance(data,dict):if"samples"indata:returnpd.DataFrame(data["samples"])else:returnpd.DataFrame([data])elifisinstance(data,list):returnpd.DataFrame(data)else:raiseValueError("JSON数据格式不支持,需要字典或列表格式")eliffilepath.suffix.lower()==".csv":returnpd.read_csv(filepath)eliffilepath.suffix.lower()in[".xlsx",".xls"]:returnpd.read_excel(filepath)else:raiseValueError(f"不支持的文件格式:{filepath.suffix}")defsetup_ads_environment(self,workspace_path:str,library_name:str,design_name:str)->None:"""设置ADS工作环境"""print("设置ADS工作环境...")try:workspace=utils.get_workspace(workspace_path)library=utils.get_library(workspace,library_name)self.design=utils.get_design(library,design_name,utils.ViewType.SCHEMATIC)print("ADS环境设置成功")exceptExceptionase:raiseRuntimeError(f"ADS环境设置失败:{e}")defextract_simulation_results(self,results:dataset.Dataset,target_variables:List[str],debug:bool=True)->Dict[str,Any]:""" 通用的仿真结果提取函数 Args: results: ADS仿真结果对象 target_variables: 目标变量名列表 debug: 是否输出调试信息 Returns: dict: 提取结果字典,格式为 {变量名: 值/数组, ...} """extraction_results={}ifdebug:print(f" 开始提取仿真结果,目标变量:{target_variables}")# 初始化所有目标变量为 Noneforvar_nameintarget_variables:extraction_results[var_name]=Nonetry:# 遍历所有变量块forvb_nameinresults.varblock_names:try:varblock=results[vb_name]dependent_vars=[]independent_vars=[]# 使用 ivars 和 dvars 属性ifhasattr(varblock,"ivars")andhasattr(varblock,"dvars"):try:independent_vars=[ivar.nameforivarinvarblock.ivars]dependent_vars=[dvar.namefordvarinvarblock.dvars]exceptExceptionase:ifdebug:print(f" 使用 ivars/dvars 失败:{e}")ifdebug:print(f" 检查变量块:{vb_name}")print(f" 依赖变量:{dependent_vars}")# 主要在依赖变量中搜索目标变量search_vars=(dependent_varsifdependent_varselse(independent_vars+dependent_vars))# 检查每个目标变量fortarget_varintarget_variables:ifextraction_results[target_var]isnotNone:continueiftarget_varinsearch_vars:try:df=varblock.to_dataframe(dvar_names=[target_var])iftarget_varindf.columnsandlen(df)>0:data_series=df[target_var]iflen(data_series)==1:value=float(data_series.iloc[0])extraction_results[target_var]=valueifdebug:print(f" ✓ 提取单值变量:{vb_name}.{target_var}={value:.3f}")else:value_array=data_series.values.tolist()extraction_results[target_var]=value_arrayifdebug:print(f" ✓ 提取数组变量:{vb_name}.{target_var}(长度:{len(value_array)})")exceptExceptionase:ifdebug:print(f" ❌ 提取{vb_name}.{target_var}失败:{e}")continueexceptExceptionase:ifdebug:print(f" ❌ 访问变量块{vb_name}失败:{e}")continue# 显示提取结果摘要ifdebug:successful_vars=[varforvar,valinextraction_results.items()ifvalisnotNone]failed_vars=[varforvar,valinextraction_results.items()ifvalisNone]print(" === 提取结果摘要 ===")print(f" 成功提取:{successful_vars}")iffailed_vars:print(f" 未找到变量:{failed_vars}")returnextraction_resultsexceptExceptionase:ifdebug:print(f" ❌ 仿真结果提取异常:{e}")returnextraction_resultsdefrun_simulation_and_extract_results(self,target_variables:List[str],debug:bool=True)->Dict[str,Any]:""" 运行仿真并提取多个目标变量的结果 Args: target_variables: 目标变量名列表 debug: 是否输出调试信息 Returns: dict: 提取结果字典 """try:# 创建仿真管理器sim_manager=utils.SimulationManager(self.design)# 运行仿真sim_manager.run_design_simulation()# 提取仿真结果withsim_manager.get_simulation_results()asresults:returnself.extract_simulation_results(results,target_variables,debug=debug)exceptExceptionase:ifdebug:print(f"仿真失败:{e}")return{var:Noneforvarintarget_variables}defrun_batch_simulation(self,data_filepath:str,workspace_path:str,library_name:str,design_name:str,target_variables:List[str],goal_variables:List[str]=None,result_processor:Optional[Callable]=None,max_samples:Optional[int]=None,save_to_original:bool=True,)->pd.DataFrame:""" 运行批量仿真 Args: data_filepath: 参数数据文件路径 workspace_path: ADS工作空间路径 library_name: 库名称 design_name: 设计名称 target_variables: 仿真提取变量列表 goal_variables: 目标变量列表 result_processor: 结果处理函数,接收results字典,返回处理后的结果 max_samples: 最大样本数限制 save_to_original: 是否保存结果到原始数据文件 Returns: 包含仿真结果的DataFrame """print("=== 自动化仿真开始 ===")print(f"数据文件:{data_filepath}")print(f"工作空间:{workspace_path}")print(f"库名称:{library_name}")print(f"设计名称:{design_name}")# 1. 加载参数样本数据print(f"加载参数数据:{data_filepath}")df=self.load_parameter_samples(data_filepath)print(f"成功加载{len(df)}个样本")# 应用样本数限制ifmax_samplesisnotNone:df=df.head(max_samples)print(f"测试模式:只处理前{len(df)}个样本")# 2. 设置ADS工作环境self.setup_ads_environment(workspace_path,library_name,design_name)# 3. 循环处理每个样本simulation_results=[]foridx,rowindf.iterrows():sample_id=row.get("sample_id",idx+1)print(f"\n处理样本{sample_id}({idx+1}/{len(df)})...")try:# 更新电路参数self.parameter_updater.update_parameters(self.design,row)print(" 参数更新完成")ifos.path.exists(os.path.join(self.design.cell.path,"data",design_name+".ds")):os.remove(os.path.join(self.design.cell.path,"data",design_name+".ds"))# 运行仿真并提取结果results=self.run_simulation_and_extract_results(target_variables)# 处理结果ifresult_processor:processed_results=result_processor(results)else:processed_results=results simulation_results.append(processed_results)# 显示结果forvar_name,valueinprocessed_results.items():ifvalueisnotNone:ifisinstance(value,(int,float)):print(f"{var_name}={value:.3f}")else:print(f"{var_name}={type(value).__name__}(长度:{len(value)ifhasattr(value,'__len__')else'N/A'})")exceptExceptionase:print(f" 样本{sample_id}处理失败:{e}")simulation_results.append({var:Noneforvarintarget_variables})ifgoal_variablesisNone:goal_variables=target_variables# 4. 将结果添加到原始数据并保存ifsave_to_original:self._save_results_to_original_file(df,simulation_results,goal_variables,data_filepath)else:df["simulation_results"]=simulation_results# 5. 显示统计信息self._print_simulation_statistics(df,goal_variables)print("=== 自动化仿真完成 ===")returndfdef_save_results_to_original_file(self,df:pd.DataFrame,simulation_results:List[Dict[str,Any]],goal_variables:List[str],data_filepath:str,)->None:""" 将仿真结果保存到原始数据文件中,追加到现有的simulation_results中 Args: df: 原始数据DataFrame simulation_results: 仿真结果列表 goal_variables: 目标变量列表 data_filepath: 原始数据文件路径 """print("\n保存结果...")# 处理新的仿真结果new_formatted_results=[]forresult_dictinsimulation_results:new_result={}forvar_nameingoal_variables:value=result_dict.get(var_name)ifvalueisnotNone:# 处理不同类型的数据processed_value=self._process_value_for_json(value)new_result[f"{var_name}"]=processed_valueelse:new_result[f"{var_name}"]=Nonenew_formatted_results.append(new_result)# 合并现有的simulation_results和新结果merged_results=[]fori,(_,row)inenumerate(df.iterrows()):# 获取现有的simulation_results(如果存在)existing_results=row.get("simulation_results",{})# 如果现有结果不是字典,初始化为空字典ifnotisinstance(existing_results,dict):existing_results={}# 获取对应的新结果new_result=(new_formatted_results[i]ifi<len(new_formatted_results)else{})# 合并结果:新结果会覆盖同名的现有结果merged_result=existing_results.copy()# 保留现有数据merged_result.update(new_result)# 添加/覆盖新数据merged_results.append(merged_result)# 将合并后的结果添加到DataFramedf["simulation_results"]=merged_results# 保存到原始文件withopen(data_filepath,"w",encoding="utf-8")asf:json.dump(df.to_dict(orient="records"),f,indent=2,ensure_ascii=False)print(f"结果已保存到:{data_filepath}")def_process_value_for_json(self,value:Any)->Any:""" 处理值以确保JSON可序列化 Args: value: 要处理的值 Returns: JSON可序列化的值 """# 处理复数ifisinstance(value,complex):return{"real":float(value.real),"imag":float(value.imag),"magnitude":float(abs(value)),"phase_deg":float(np.angle(value,deg=True)),}# 处理numpy数组或列表elifisinstance(value,(list,np.ndarray)):iflen(value)==0:return[]eliflen(value)==1:# 单个值,递归处理returnself._process_value_for_json(value[0])else:# 多个值,处理每个元素processed_list=[]foriteminvalue:processed_list.append(self._process_value_for_json(item))returnprocessed_list# 处理numpy标量elifisinstance(value,np.number):ifnp.iscomplex(value):returnself._process_value_for_json(complex(value))else:returnfloat(value)# 处理NaN和无穷大elifisinstance(value,float):ifnp.isnan(value)ornp.isinf(value):returnNoneelse:returnvalue# 其他类型直接返回else:returnvaluedef_print_simulation_statistics(self,df:pd.DataFrame,target_variables:List[str])->None:"""打印仿真统计信息"""print("\n=== 仿真统计 ===")print(f"总样本数:{len(df)}")# 统计成功的仿真successful_count=0forresultsindf["simulation_results"]:ifany(results.get(var)isnotNoneforvarintarget_variables):successful_count+=1print(f"成功仿真:{successful_count}")print(f"失败样本:{len(df)-successful_count}")# 显示各变量的统计信息forvar_nameintarget_variables:values=[]forresultsindf["simulation_results"]:value=results.get(var_name)ifvalueisnotNoneandisinstance(value,(int,float)):values.append(value)ifvalues:values=np.array(values)print(f"{var_name}范围:{values.min():.3f}~{values.max():.3f}")print(f"{var_name}均值:{values.mean():.3f}")

AutoSimulator采用模板方法模式 (Template Method Pattern)设计:

  • 不变的部分:ADS 工作空间的打开/关闭、仿真器的实例化、结果文件的遍历与读取、异常处理、数据保存(追加到原始 JSON)。这些通用逻辑被封装在基类和工具函数中。
  • 变化的部分:不同的电路有不同的参数需要更新(如电阻值、信号文件路径、偏置电压)。这部分逻辑通过ParameterUpdater接口暴露给用户实现。

1.2 核心类说明

utils.auto_simulator.py中主要包含两个核心类:ParameterUpdaterAutoSimulator

1. ParameterUpdater (抽象基类)

设计意图:这是一个策略接口(Strategy Pattern),将"如何更新电路参数"这一变化点从框架中剥离出来。由于每个 ADS 设计的元件名称、变量控件结构、参数命名规则都不同,这部分逻辑无法通用化,必须由用户根据自己的电路原理图来实现。

类定义

fromabcimportABC,abstractmethodfromkeysight.ads.deimportdb_uuasdbimportpandasaspdclassParameterUpdater(ABC):"""参数更新抽象接口"""@abstractmethoddefupdate_parameters(self,design:db.Design,param_row:pd.Series)->None:""" 更新电路参数(用户必须实现) Args: design: ADS 设计对象,指向当前打开的原理图 param_row: 包含本次仿真所需全部参数的 Pandas Series """pass

核心方法详解

方法签名update_parameters(self, design: db.Design, param_row: pd.Series) -> None
调用时机AutoSimulator在处理每一行参数样本时,会在执行仿真前调用此方法
design 参数setup_ads_environment打开的设计对象,类型为keysight.ads.de.db_uu.Design。通过它可以访问原理图中的所有元件实例
param_row 参数Pandas Series 对象,键为参数名(如"R1","Vbias"),值为参数数值。这些键名对应输入 JSON/CSV 文件中的列名
返回值无(None)。参数更新通过直接修改design对象完成

实现时需要掌握的 ADS Python API

  1. 获取元件实例

    inst=design.get_instance("VAR1")# 按原理图中的 Instance Name 获取
  2. 更新 VAR 控件中的变量(用于VAR/VAR2等变量定义控件):

    inst.vars.update({"变量名1":"值(字符串)","变量名2":"值(字符串)",})
  3. 更新元件参数(用于电阻、电容、信号源等具体元件):

    inst.parameters["参数名"].value="值(字符串,可带单位)"# 例如:inst.parameters["R"].value = "100 Ohm"# 例如:inst.parameters["File"].value = '"E:/data/signal.txt"' # 文件路径需额外引号
  4. 刷新原理图标注(更新后建议调用):

    inst.update_item_annotation()
  5. 使用事务保证原子性(推荐):

    fromkeysight.ads.de.dbimportTransactionwithTransaction(design)astransaction:# 在此块内进行所有参数修改inst1.vars.update({...})inst2.parameters["C"].value="10 pF"# 提交事务,使修改生效transaction.commit()

注意事项

  • 所有参数值必须转换为字符串格式,ADS 内部会自行解析单位
  • 文件路径类参数(如DAC1File参数)需要用双引号包裹,即'"path"'
  • 若更新多个元件,建议包裹在Transaction中,确保要么全部成功、要么全部回滚
  • 更新后调用update_item_annotation()可让原理图界面同步显示新值(非必需但推荐)
2. AutoSimulator (核心控制器)

职责:这是自动化仿真的主引擎(Driver)。它不关心电路的具体细节,只负责流程控制:加载数据 -> 设置环境 -> 循环仿真 -> 提取结果 -> 保存文件。

主要方法详解


__init__(self, parameter_updater: ParameterUpdater)

构造函数,负责将用户实现的参数更新器"注册"到控制器中。

参数类型说明
parameter_updaterParameterUpdater用户自定义的参数更新器实例,必须实现update_parameters方法

内部行为:将parameter_updater保存为成员变量,同时初始化self.design = None(后续由setup_ads_environment填充)。


load_parameter_samples(self, filepath: str) -> pd.DataFrame

从文件加载参数样本数据,统一转换为 Pandas DataFrame 供后续遍历使用。

参数类型说明
filepathstr参数数据文件的完整路径

支持的输入格式

扩展名处理逻辑
.json使用json.load读取。支持三种结构:① 纯列表[{...}, {...}];② 字典包裹{"samples": [{...}]};③ 单条记录{...}(自动包装为单行 DataFrame)
.csv调用pd.read_csv(filepath)
.xlsx/.xls调用pd.read_excel(filepath)

异常情况

  • FileNotFoundError:文件路径不存在
  • ValueError:JSON 内容既非 dict 也非 list,或扩展名不在上述列表中

注意:虽然加载支持多种格式,但目前结果保存仅实现了 JSON 格式(见_save_results_to_original_file)。如需将结果回写到 CSV/Excel,用户可继承AutoSimulator并重写保存逻辑。


setup_ads_environment(self, workspace_path: str, library_name: str, design_name: str) -> None

初始化 ADS 工作环境,完成工作空间 -> 库 -> 设计的三级打开流程。

参数类型说明
workspace_pathstrADS 工作空间目录路径,如E:/ADS2026_wrk/MyProject_wrk
library_namestr库名称,如MyAmplifier_lib
design_namestr原理图设计名称(不含扩展名),如Amp_Sim_Schematic

内部流程

  1. utils.get_workspace(workspace_path)—— 打开/连接工作空间
  2. utils.get_library(workspace, library_name)—— 加载指定库
  3. utils.get_design(library, design_name, ViewType.SCHEMATIC)—— 打开原理图视图

成功后self.design将指向该设计对象,后续的参数更新和仿真都基于此对象进行。

异常情况:路径错误、库/设计不存在时抛出RuntimeError


extract_simulation_results(self, results: dataset.Dataset, target_variables: List[str], debug: bool = True) -> Dict[str, Any]

从仿真结果数据集中智能提取用户指定的目标变量,是本工具库最核心的数据处理函数。

参数类型说明
resultsdataset.DatasetADS 仿真结果对象(由SimulationManager.get_simulation_results()获取)
target_variablesList[str]想要提取的变量名列表,如["S[2,1]", "Gain_dB", "OUT"]
debugbool是否打印调试信息,默认True

提取策略(不依赖硬编码的块名):

  1. 遍历results.varblock_names获取所有 VariableBlock
  2. 对每个块,通过varblock.ivars/varblock.dvars获取其独立变量和依赖变量名列表
  3. 若目标变量出现在dvars中,调用varblock.to_dataframe(dvar_names=[target_var])精准提取该列
  4. 根据数据长度自动判断类型:
    • 长度 = 1 → 标量,转为 Pythonfloat
    • 长度 > 1 → 向量,转为 Pythonlist

返回值Dict[str, Any],格式为{变量名: 值或列表}。未找到的变量对应值为None


run_simulation_and_extract_results(self, target_variables: List[str], debug: bool = True) -> Dict[str, Any]

执行单次仿真并提取结果的快捷方法,内部封装了仿真管理器的创建与结果获取。

参数类型说明
target_variablesList[str]想要提取的变量名列表
debugbool是否打印调试信息

内部流程

  1. 创建SimulationManager(self.design)
  2. 调用sim_manager.run_design_simulation()执行仿真
  3. 使用上下文管理器with sim_manager.get_simulation_results() as results获取结果
  4. 调用extract_simulation_results(results, target_variables, debug)提取数据

异常处理:若仿真过程出错(如不收敛、License 问题),捕获异常并返回{var: None for var in target_variables},不会中断程序。


run_batch_simulation(self, data_filepath, workspace_path, library_name, design_name, target_variables, goal_variables=None, result_processor=None, max_samples=None, save_to_original=True) -> pd.DataFrame

批量仿真的主入口,串联整个自动化流程。大多数情况下用户只需调用此方法。

参数类型默认值说明
data_filepathstr参数数据文件路径
workspace_pathstrADS 工作空间路径
library_namestr库名称
design_namestr设计名称
target_variablesList[str]要提取的仿真结果变量列表
goal_variablesList[str]None写入文件时的字段名集合,若为None则等于target_variables
result_processorCallableNone可选的结果后处理回调函数,签名为(Dict) -> Dict
max_samplesintNone限制处理的样本数量,用于调试;None表示处理全部
save_to_originalboolTrue是否将结果合并回写到原始数据文件

执行流程

  1. 加载数据:调用load_parameter_samples(data_filepath)读取参数表
  2. 限制样本:若设置了max_samples,取前 N 行
  3. 初始化环境:调用setup_ads_environment(...)打开 ADS 设计
  4. 循环处理每个样本
    • 调用parameter_updater.update_parameters(design, row)更新电路参数
    • 删除旧仿真数据:移除{cell_path}/data/{design_name}.ds,防止读到历史缓存
    • 调用run_simulation_and_extract_results(target_variables)执行仿真并提取结果
    • 若提供了result_processor,对结果进行后处理
    • 将结果追加到列表
  5. 保存结果:若save_to_original=True,调用_save_results_to_original_file合并写回
  6. 打印统计:调用_print_simulation_statistics输出成功/失败计数与数值范围

返回值:带有simulation_results列的 DataFrame。


_save_results_to_original_file(self, df, simulation_results, goal_variables, data_filepath) -> None

将当前批次的仿真结果与原文件中已有的simulation_results字段合并后写回,支持增量覆盖(新结果覆盖同名旧结果,旧结果中不重名的字段保留)。

内部逻辑

  1. 遍历simulation_results列表,对每条记录中的goal_variables调用_process_value_for_json转换
  2. 遍历原 DataFrame,取出每行的simulation_results(若不存在则初始化为空字典)
  3. 使用dict.update()将新结果合并进去
  4. 最终以json.dump(df.to_dict(orient="records"), ...)写回文件

限制:目前仅支持 JSON 格式输出。如需 CSV/Excel 输出,可重写此方法或在调用后手动导出。


_process_value_for_json(self, value) -> Any

递归处理各种数据类型,确保最终结果可被json.dump序列化。

输入类型输出格式
complex{"real": float, "imag": float, "magnitude": float, "phase_deg": float}
list/np.ndarray递归处理每个元素;若长度为 1 则解包为标量
np.number转为 Pythonfloat(复数走 complex 分支)
float且为NaN/Inf转为None
其他原样返回

_print_simulation_statistics(self, df, target_variables) -> None

在批量仿真结束后打印统计摘要,便于快速评估整体质量。

输出内容包括:

  • 总样本数 / 成功数 / 失败数
  • 对于每个target_variable,若为数值型则显示最小值、最大值、均值

1.3 实战示例:开发一个自定义仿真器

本节以一个射频放大器增益仿真为例,完整演示从数据准备到结果提取的全流程。


1.3.1 输入数据格式

首先准备参数样本文件(JSON 格式),每条记录代表一组待仿真的电路参数:

[{"sample_id":1,"Vbias":3.3,"R_source":50,"C_coupling":100,"L_match":2.2},{"sample_id":2,"Vbias":3.0,"R_source":75,"C_coupling":150,"L_match":1.8}]

字段说明

  • sample_id:样本编号,用于日志输出和结果追踪(可选,若不提供则自动使用行索引)
  • 其余字段:与原理图中需要更新的变量/参数一一对应

1.3.2 实现参数更新器

根据你的 ADS 原理图结构,继承ParameterUpdater并实现update_parameters方法:

""" amplifier_simulator.py 射频放大器批量仿真脚本 """importsysfrompathlibimportPath# 将项目根目录加入 Python 路径(确保能 import 该工具库)project_root=Path(__file__).parent.parent# 根据实际目录层级调整sys.path.append(str(project_root))importpandasaspdfromutils.auto_simulatorimportAutoSimulator,ParameterUpdaterfromkeysight.ads.deimportdb_uuasdbfromkeysight.ads.de.dbimportTransactionclassAmplifierUpdater(ParameterUpdater):""" 放大器参数更新器 假设原理图中包含: - VAR1 控件:定义 Vbias(偏置电压)、R_source(源阻抗) - C1 元件:耦合电容 - L1 元件:匹配电感 """defupdate_parameters(self,design:db.Design,param_row:pd.Series)->None:""" 将 param_row 中的参数值写入 ADS 原理图 Args: design: ADS 设计对象 param_row: 当前样本的参数(Pandas Series) """# 使用 Transaction 确保所有修改原子性提交withTransaction(design)astransaction:# ========== 1. 更新 VAR 控件中的变量 ==========# 获取名为 "VAR1" 的变量控件实例inst_var=design.get_instance("VAR1")# 批量更新变量值(必须转为字符串)inst_var.vars.update({"Vbias":str(param_row["Vbias"]),"R_source":str(param_row["R_source"]),})# 刷新原理图标注(可选,但推荐)inst_var.update_item_annotation()# ========== 2. 更新具体元件的参数 ==========# 更新耦合电容 C1 的电容值inst_c1=design.get_instance("C1")inst_c1.parameters["C"].value=f"{param_row['C_coupling']}pF"inst_c1.update_item_annotation()# 更新匹配电感 L1 的电感值inst_l1=design.get_instance("L1")inst_l1.parameters["L"].value=f"{param_row['L_match']}nH"inst_l1.update_item_annotation()# ========== 3. 提交事务 ==========transaction.commit()

代码要点

  1. Transaction 上下文管理器:将所有修改包裹在事务中,调用commit()后才真正生效
  2. VAR 控件 vs 元件参数:VAR 控件用.vars.update(),普通元件用.parameters["名称"].value
  3. 单位处理:电容用pF、电感用nH,ADS 会自动解析
  4. 字符串转换:所有值必须是字符串,使用str()或 f-string

1.3.3 编写主控制脚本
defmain():"""主函数:配置参数并启动批量仿真"""# ========== 配置区 ==========config={# 输入:参数样本文件路径"data_filepath":"E:/project/data/amplifier_samples.json",# ADS 环境配置"workspace_path":"E:/ADS2026_wrk/MyAmplifier_wrk","library_name":"MyAmplifier_lib","design_name":"Amp_Gain_Schematic",# 原理图名称(不含 .dsn后缀)# 输出:要提取的仿真结果变量# 这些变量名需与 ADS 仿真结果中的变量名完全一致"target_variables":["S[2,1]",# S21 参数(增益)"S[1,1]",# S11 参数(输入反射)"Gain_dB",# 测量方程计算的增益(dB)"NF_dB",# 噪声系数],# 可选:限制处理样本数(调试时使用)"max_samples":None,# None 表示处理全部,设为 5 则只跑前 5 个}print("="*60)print("射频放大器批量仿真")print("="*60)print(f"参数文件:{config['data_filepath']}")print(f"目标变量:{config['target_variables']}")print()# ========== 执行仿真 ==========try:# 1. 创建参数更新器实例updater=AmplifierUpdater()# 2. 创建自动仿真器,注入更新器simulator=AutoSimulator(updater)# 3. 运行批量仿真final_df=simulator.run_batch_simulation(data_filepath=config["data_filepath"],workspace_path=config["workspace_path"],library_name=config["library_name"],design_name=config["design_name"],target_variables=config["target_variables"],max_samples=config["max_samples"],save_to_original=True,# 结果追加写回原 JSON 文件)print()print("="*60)print(f"仿真完成!共处理{len(final_df)}个样本")print(f"结果已保存到:{config['data_filepath']}")print("="*60)exceptExceptionase:print(f"\n❌ 仿真过程发生错误:{e}")importtraceback traceback.print_exc()if__name__=="__main__":main()

1.3.4 输出结果格式

仿真完成后,原始 JSON 文件会被追加simulation_results字段:

[{"sample_id":1,"Vbias":3.3,"R_source":50,"C_coupling":100,"L_match":2.2,"simulation_results":{"S[2,1]":{"real":2.51,"imag":1.33,"magnitude":2.84,"phase_deg":27.9},"S[1,1]":{"real":-0.12,"imag":0.05,"magnitude":0.13,"phase_deg":157.4},"Gain_dB":9.07,"NF_dB":2.3}},{"sample_id":2,"Vbias":3.0,"R_source":75,"C_coupling":150,"L_match":1.8,"simulation_results":{"S[2,1]":{...},"S[1,1]":{...},"Gain_dB":8.45,"NF_dB":null}}]

结果字段说明

  • 复数类型(如 S 参数):自动拆分为realimagmagnitudephase_deg
  • 标量类型(如Gain_dB):直接存储数值
  • 提取失败:对应字段值为null

1.3.5 进阶:自定义结果后处理

若需要对原始提取结果进行计算(如将复数 S21 转为 dB),可传入result_processor回调:

importnumpyasnpdefprocess_results(raw_results:dict)->dict:""" 自定义结果后处理函数 Args: raw_results: extract_simulation_results 返回的原始字典 Returns: 处理后的结果字典 """processed=raw_results.copy()# 示例:将复数 S21 转为 dBs21=raw_results.get("S[2,1]")ifs21isnotNoneandisinstance(s21,complex):processed["S21_dB"]=20*np.log10(abs(s21))returnprocessed# 在 run_batch_simulation 中使用final_df=simulator.run_batch_simulation(...,result_processor=process_results,# 传入回调)

1.4 为什么推荐使用此模式?

  1. 稳健性:内部统一捕获仿真异常,单个样本失败不会拖垮全流程。
  2. 断点续传:结果实时写回原始文件,结合简单的跳过逻辑即可实现增量仿真。
  3. 结果对齐:自动将输入参数与输出结果一一对应,便于后续数据分析与模型训练。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!