输入文件生成(命令行模式)
PASS 从 JSON 文件读取仿真输入。使用 Python 配置类定义全局参数、束团与晶格序列,再调用 generate_input() 生成文件。图形界面配置方法见 图形界面。
配置对象在构造时检查已声明字段的类型与约束;JSON 输入文件检测 进一步检查完整输入、命令顺序及外部文件。generate_input() 负责写出配置,不能代替完整输入校验。
最小示例
安装 PASS 后,将以下脚本保存为仓库根目录下的 input/generate_beam0.py;若 input 目录不存在,先创建该目录。示例使用 2048 个宏粒子、64 圈 CPU 跟踪、平滑近似线性晶格和高斯分布,无需外部晶格文件。
from pathlib import Path
from PASS.para.api import generate_input
from PASS.para.schema.main import MainConfig
from PASS.para.schema.bunch import BunchConfig, InjectionItem
from PASS.para.schema.sequence import Sequence
from PASS.para.schema.monitors import StatMonitorItem
from PASS.para.smooth import generate_smooth_twiss
from PASS.validation import validate_file
main = MainConfig(
beam_name="proton",
num_proton=1, num_neutron=0, num_electron=1,
gamma_t=4.8, circumference=251.327,
num_turns=64, backend="cpu", output_dir="output", is_plot=False,
)
items, names, circumference = generate_smooth_twiss(
circumference=main.circumference,
qx=4.8, qy=4.4, num_points=17,
longitudinal_transfer="off",
)
bunch = BunchConfig(
kinetic_energy=45e6,
num_real_particles=100_000_000_000,
num_macro_particles=2048,
beta_x=items[0].beta_x, beta_y=items[0].beta_y,
alpha_x=0.0, alpha_y=0.0,
emit_x=2e-6, emit_y=2e-6,
sigma_z=0.1, dp=0.001,
dist_trans="gaussian", dist_longi="gaussian",
)
seq = Sequence()
seq.add("injection", InjectionItem(s=0.0, random_seed=2026, bunches=[bunch]))
for name, item in zip(names, items):
seq.add(name, item)
seq.add("stat1", StatMonitorItem(s=0.0, write_interval_turns=16))
output_path = Path(__file__).resolve().parent / "beam0.json"
generate_input(main, seq, str(output_path))
report = validate_file(str(output_path))
if not report.ok:
raise ValueError(report.text())
print(f"Validated input: {output_path}")
在仓库根目录依次执行:
python input/generate_beam0.py
pass-run input/beam0.json
安装 PASS 会在对应 Python 环境中注册 pass-run。
安装后,python -m PASS 接受完全相同的参数,并明确使用所选 Python 解释器。
两种入口都不需要 Qt 或 PySide6。安装后执行 pass-run --version 或
python -m PASS --version 查看版本号并退出,无需提供输入文件。
可以指定 JSON 输入、.passproj 文件或工程目录:
pass-run input/beam0.json
pass-run input/beam0.json input/beam1.json
pass-run example.passproj
python -m PASS example.passproj
pass-run path/to/project-directory
pass-run .
命名输入选项也支持相同的三种运行方式:
pass-run --beam0 input/beam0.json
pass-run --beam0 input/beam0.json --beam1 input/beam1.json
pass-run --passproj example.passproj
位置参数和命名输入选项只能选择其中一种,不能混用。
--beam0 和 --beam1 要求 JSON 文件,--beam1 必须与 --beam0 一起使用。
--passproj 接受 .passproj 文件或工程目录,不能与任何束流选项组合使用。
相对输入路径以终端当前工作目录为基准,包含空格的路径需要加引号。
一个或两个 JSON 分别用于单束流或双束流运行。.passproj 文件或工程目录使用已保存的
Beam 0 和可选 Beam 1 选择;未保存 Beam 0 时使用当前活动配置,
不会依次执行项目中的全部配置。目录入口优先打开 project.passproj,没有该文件时
打开其中唯一的 .passproj;存在多个候选时需要显式指定文件。同时支持读取
新明文 JSON 工程和旧 ZIP 工程。已保存的选择失效或两束选择重复时会报错。
项目选择和输出路径规则见 可编辑项目。
命令行覆盖 JSON 参数
可在本次运行中覆盖输入字段,不修改原始 JSON 或项目文件:
pass-run beam0.json --backend=gpu --device-id=1 --task-name=test
pass-run beam0.json --number-of-turns=100 --particle-precision=float32
pass-run beam0.json --timing.log-interval=20
pass-run beam0.json '--sequence[QF1_s1.000].length=0.5'
pass-run beam0.json '--device-id[0]=1'
固定字段名称由 JSON key 转换而来:移除括号及其内容,空格替换为连字符,
不区分大小写。数值单位仍按 JSON 字段规定,例如 Circumference (m)
对应 --circumference,数值仍以米为单位。Sigma dp/p 保留斜杠。
嵌套字段使用点号分层,元件或资源名称使用 [完整名称],保留大小写、点号及其他字符。
包含 shell 特殊字符(尤其是 $)的参数需要引用保护。
数组下标从零开始,也可以整体替换数组。
值采用 JSON 类型:数值、true、false、null、数组或对象;字符串字段也接受普通文本。
支持 --path=VALUE 和 --path VALUE,字符串以 -- 开头时使用等号形式。
--device-id=1 与 --device-id="[1]" 等价;单个整数在校验和归档前转换为数组。
不接受 true 或 1.0 等布尔值或小数。选择设备不会自动切换为 GPU 后端。
名称本身含方括号,或规范化字段名存在歧义时,可使用原始 key 构成的 JSON 路径数组:
pass-run beam0.json --set '["Sequence","QF1_s1.000","Length (m)"]' 0.5
无前缀路径作用于 Beam 0。使用 beam0. 或 beam1. 前缀选择输入;
精确路径数组也可用 "beam0" 或 "beam1" 作为首项。
现有双束流一致性检查仍然有效:圈数、后端、精度、设备、计时及绘图设置必须一致,例如:
pass-run beam0.json beam1.json --number-of-turns=100 --beam1.number-of-turns=100
Task name 和 Output directory 作用于整次运行,不允许放在 Beam 1 下。
--output-directory 与 --output 等价。
命令行优先于输入和项目保存的设置,覆盖发生在预检和归档之前。
生效配置写入 input/beam0.json 及可选的 beam1.json,原始配置保存在
configuration*.json。命令行指定的相对文件路径以启动时工作目录为基准;
未覆盖的路径仍以原始输入或项目目录为基准。
允许设置所有 schema 声明的输入字段,包括原文件省略的可选字段。 整体设置配置块时会替换原值,不做合并。 此接口不修改外部文件内容或内部计算变量,不增删命名元件或资源,不删除 key, 也不通过越界下标追加数组元素。未知字段、规范化名称歧义、类型或下标错误、 重复覆盖以及父子路径同时覆盖都会报错。执行前仍须通过完整输入与物理一致性校验。
注入字段现已统一为 RF S Position Refer to Injection Point (m),不再接受原来的缩写名称。
运行旧输入前,请重新生成输入或重命名该 key。
使用 --output DIR 指定本次运行的输出根目录,优先于 JSON 或项目保存的设置,
支持单份 JSON、双份 JSON 或一个项目。命令行指定的相对输出路径以启动时的工作目录
为基准,原始 JSON 和项目文件保持不变:
pass-run input/beam0.json --output results
pass-run input/beam0.json input/beam1.json --output "results/two beams"
python -m PASS example.passproj --output results
不使用此选项时,JSON 运行使用第一份 JSON 的 Output directory,
配置内的相对路径以该 JSON 所在目录为基准。字段缺省或设为 default
(不区分大小写)时,输出根目录为第一份 JSON 旁的 output。
生成输入的默认值仍为 ./output,不再回退到仓库或安装目录。
可选字段 Task name``(``MainConfig.task_name)设置任务名称,并用作输出根目录内的本次运行文件夹名称。
Output directory / output_dir 仍用于指定输出根目录。
例如 output_dir="output", task_name="capture_sc" 写入 output/capture_sc/。
省略字段,或填写 null、空字符串、纯空白或 default 时,使用精确到分钟的
单层文件夹 YYYY_MM_DD_HH_MM,例如 output/2026_10_30_18_39/。
default 在去除首尾空白后不区分大小写,例如 " DEFAULT " 具有相同效果。
不再单独创建日期父目录,也不会自动使用 Beam 0 的名称。
input/、distribution/、particle/、plot/ 等内部子目录及其结构保持不变;
结果文件继续使用原有 HHMM_SS 时间标记,与任务文件夹名称独立。
自动名称和自定义名称重名时均追加不补零的 _1、_2、_3 等后缀,
例如 2026_10_30_18_39_1 或 capture_sc_1,不复用或覆盖之前的结果。
此字段只能填写单个文件夹名称,不能填写路径;路径分隔符、./..、
非法文件名字符和操作系统保留名称会被拒绝,首尾空白会被去除。
允许使用日期形式的自定义名称,YYYY_MMDD 不再是保留名称。
命令行 --task-name NAME 覆盖已保存的名称,但不修改输入。
显式传入空字符串或 --task-name default 可恢复单层时间戳布局:
pass-run input/beam0.json --task-name capture_sc
pass-run example.passproj --output results --task-name capture_sc
pass-run input/beam0.json --task-name ""
pass-run input/beam0.json --task-name default
为兼容已有输入,仍接受原 JSON 字段 Output subdirectory 和 Output name、
Python 参数或项目设置 output_subdirectory 和 output_name,以及命令行选项
--output-subdirectory 和 --output-name。新生成的 JSON、项目文件和执行快照
分别使用规范名称 Task name 或 task_name。同一设置同时提供多个别名时会被拒绝;
迁移时只保留其中一种写法。已有结果目录不会移动或重命名;新运行以及旧输入、
旧快照的重新运行均使用新的单层布局。
以下两条帮助命令均显示输入方式、选项、路径规则和示例,不启动仿真:
pass-run --help
pass-run -h
--stop-file 指定的文件存在时,在初始化前或圈边界停止。
退出码 0 表示完成,1 表示失败,2 表示命令参数错误,3 表示请求停止,
130 表示中断。Python 集成也可直接调用
PASS.main.main('input/beam0.json', raise_errors=True)。
Python 集成可使用
PASS.main.main('input/beam0.json', output_dir='results', raise_errors=True)
覆盖输出根目录;相对 output_dir 路径以调用 main() 时的工作目录为基准。
此覆盖要求保留默认的 archive_inputs=True,不能与供已有快照使用的
archive_inputs=False 组合。
Python 的 task_name 参数同样覆盖配置中的文件夹名称,例如
main('input/beam0.json', task_name='capture_sc')。
task_name=None 沿用已保存设置;task_name='' 或 task_name='default'
显式恢复单层时间戳布局,即使已保存配置使用自定义名称。这里同样先去除首尾空白,再忽略大小写比较。
显式覆盖同样要求 archive_inputs=True。
脚本生成 input/beam0.json,其中的相对输出目录解析为 input/output,每次运行在其下创建独立运行目录。运行目录包含 CSV 与 HDF5 统计表,共 64 行(圈号 0–63);具体目录由日志给出。运行完成后可读取最新统计文件:
from pathlib import Path
from PASS.utils.table_io import read_table
files = list(Path("input/output").rglob("*stat*.h5"))
latest = max(files, key=lambda path: path.stat().st_mtime)
data = read_table(latest)
print(latest)
print(data[["turn", "sigmaX", "sigmaY", "xEmittance", "yEmittance"]].tail())
该非耦合线性模型中,横向 RMS 发射度应在数值舍入误差范围内保持不变;有限采样得到的初始值不必精确等于输入目标。本例关闭纵向输运,不包含同步振荡或集体效应。
执行所用的输入快照
PASS.main.main(beam0_path, beam1_path=None, ...) 默认归档输入
(archive_inputs=True)。检查原始配置后,复制 JSON 配置及引用的输入文件,
校验生成的快照,再从快照初始化跟踪。依赖包括粒子分布、RF 程序、偏移表、
尾场模型和磁铁 ramping 表。之后修改原始文件不会影响本次运行。
JSON、已保存项目和 GUI 运行默认统一使用精确到分钟的单层时间戳结果目录,
输入快照保存在本次结果目录的 input 子目录中:
<output>/<YYYY_MM_DD_HH_MM>/ # 本次仿真结果
input/
configuration0.json # 原始配置值
beam0.json # 执行输入;可选 beam1.json
assets/<filename> # 已复制的输入依赖
run.json # 路径、SHA-256 校验和及运行状态
设置 Task name: capture_sc 后,相同内容改为保存在 <output>/capture_sc/,
取代自动时间戳文件夹;该名称已存在时,按前述规则分配带编号的同级目录。
复制输入前先创建本次结果目录;自动或自定义名称已存在时,均追加 _1、_2 等后缀。
运行 ID 仍保存在 run.json 中,不再单独作为一层目录。
已复制的依赖直接放在 assets/ 中,不创建编号子目录。保留原文件名;
检查重名时不区分大小写,发生冲突就在扩展名前依次追加 1、2 等编号,
例如 rf.tfs、rf1.tfs、rf2.tfs。执行 JSON 和 run.json
记录实际使用的文件名。
双输入运行还保存 configuration1.json。执行 JSON 中的文件引用使用快照内的
相对路径 assets/...,因此可以整体移动输入快照目录。
输出根目录(包括 --output 或 Python output_dir 的覆盖值)在复制前解析,
并以绝对 Output directory 保存到执行快照;移动快照不会改变结果目的地。
覆盖同时改变快照和结果的输出根目录,保留所选布局。原始 JSON 和输入文件保持不变。
configurationN.json 重新序列化原始配置值;依赖文件则逐字节原样复制。
GUI 与命令行项目运行使用相同的依赖复制、哈希和结果目录规则,见 可编辑项目。
结果目录中的参数 JSON 保留原有文件名,并保存绝对输入路径和输出路径。
它从已经载入的配置生成,使用解析路径后、展开命名配置前的内容,不再次读取源 JSON。
主快照中的 beamN.json 仍使用相对依赖路径。
格式版本为 1 的 run.json 记录执行 JSON、比较用配置及可用依赖的 SHA-256 校验和。
依赖记录还包括原始来源路径和复制后的字节数。
未启用资源的缺失文件保留原有校验警告,并列入 unavailable_dependencies;
已启用功能所需输入缺失则阻止运行。缺失引用指向快照内未创建的路径,
之后恢复原始文件也不会使其成为未经归档的运行输入。记录随准备及执行过程更新状态。
output_root 保存选定的输出根目录,output_directory 保存写入执行配置的输出路径。
task_name 保存请求的自定义名称,单层时间戳布局时为空字符串。
results_directory 从准备阶段起保存实际分配的结果目录,包括重名时追加的编号。
on_initialized(cfg) 回调可通过 cfg.input_snapshot_path 定位本次运行的 run.json。
准备失败时,若记录已创建,则状态记为 preparation_failed。
需要最终粒子状态来生成结果摘要时,main() 还接受 on_completed(sim)。
该回调在跟踪成功结束后、运行记录标记为完成前接收 Simulation,
停止或失败的运行不会调用它。回调抛出异常时,运行记为失败,
并遵循通常的 raise_errors 行为。复用命令行解析器的集成程序可通过
cli_main(argv, on_completed=callback) 传入同一回调;
例如,注入涂抹示例的运行包装脚本用它生成 completed.json。
对已保存的 beam0.json 调用 main() 会从初始条件重新运行,
并创建新的输入快照及结果目录。这是输入复现,不是检查点续算。
输入快照不会恢复之前的 Python 环境、源码版本或随机数生成器状态;
Random Seed: null 仍采用非确定性采样。
已有输入快照的集成程序可用 archive_inputs=False 关闭再次复制;GUI 子进程使用此设置。
依赖自动归档由 main() 负责,底层 Config.load_input() 本身不归档依赖。
Python API 显式设置 flat_output=True 时,为兼容已有集成保留原有布局:
结果仍直接写入指定输出目录,
快照则位于该目录的父目录下的 input_snapshots/<run-id>。
若结果目录本身名为 input_snapshots,则改用旁边的 input_snapshots_archive/<run-id>,
使 flat 结果目录不包含快照子目录。
flat_output=True 不能与自定义 Task name 组合;该验证工作流应清空配置名称,
或显式传入 task_name='' 或 task_name='default'。
JSON 文件结构
以下为省略部分字段的结构示意;空束团对象及省略参数仅用于展示层次,不能直接作为完整输入运行。
{
"Beam Name": "proton",
"Number of Protons": 1,
"Number of Neutrons": 0,
"Number of Charges": 1,
"Transition Gamma": 4.8,
"Circumference (m)": 251.327,
"Number of turns": 64,
"Backend (gpu/cpu)": "cpu",
"Number of GPU devices": 1,
"Device Id": [0],
"Output directory": "./output",
"Task name": "",
"Is plot figure": false,
"Sequence": {
"injection": {
"S (m)": 0.0,
"Command": "Injection",
"Harmonic Number": 1,
"Random Seed": 2026,
"bunch0": {}
},
"twiss_0000": {
"S (m)": 0.0,
"Command": "Twiss",
"S previous (m)": 0.0,
"Beta x (m)": 8.333
},
"stat1": {
"S (m)": 0.0,
"Command": "StatMonitor"
}
}
}
Note
JSON 使用固定字段名。配置类通过 pydantic 的 alias 机制将 Python 字段名转换为 JSON 键。
引擎在读取时会先调用 convert_keys_to_lower() 将所有 key 转为小写,因此 JSON key 的大小写不影响读取。
核心组件
MainConfig(全局参数)
Python 字段 |
JSON 键 |
类型 |
默认值 |
说明 |
|---|---|---|---|---|
|
|
|
|
束流粒子种类的显示名称。 |
|
|
|
|
每个粒子的质子数;电子和正电子取 0。 |
|
|
|
|
每个粒子的中子数。 |
|
|
|
|
带符号电荷数 Z(q=Z e),并非电子数;为非零整数。 |
|
|
|
|
晶格的渡越伽马因子 gamma_t。 |
|
|
|
|
正的环周长(m)。 |
|
|
|
|
仿真圈数,正整数。 |
|
|
|
|
计算后端:cpu 或 gpu。 |
|
|
|
|
六维粒子坐标存储精度:float32 或 float64。 |
|
|
|
|
使用的 GPU 数量。 |
|
|
|
|
GPU 设备编号列表。 |
|
|
|
|
输出根目录;相对路径以输入 JSON 所在目录为基准。缺省或 |
|
|
|
|
任务名称,用作 |
|
|
|
|
跟踪正常结束后从已保存结果生成 监视器图片;默认保存在本次运行的 |
|
|
|
|
计时配置;默认 mode=command、log_interval=10、warmup_turns=1、include_io=True。 |
|
|
|
|
已停用的占位字段;true 报错,生成的输入不再输出此字段。 |
束束相互作用使用独立顶层 Beam beam 配置块和两条 sequence 中的显式命令。
调用 generate_input 时传入 beam_beam=BeamBeamConfig(...);
源方法、执行顺序和相关元件见 束束相互作用(BeamBeam)。
空间电荷使用独立的顶层 Space charge
配置块。命名资源 schema 和 Sequence command 引用方式参见 空间电荷效应(SpaceCharge)。
每个资源通过 Method``(``pic、frozen、quasi-frozen)和 Solver
选择计算方式;Solver 名称包含边界条件。命令中的 Aperture type/value
定义粒子损失孔径,并在 Dirichlet 中同时定义导体壁,
网格输入必须完整选择全宽或半宽一组;省略命令孔径时默认使用网格同尺寸矩形。
电子云使用独立顶层 Electron cloud 配置块。
调用 generate_input 时传入 electron_cloud=ElectronCloudConfig(...),
通过 ElectronCloudItem 引用命名配置。frozen 不要求 Slicer;
外驱动 build_up 与 PIC coupled 均要求当前 z_rel SliceSet
和嵌套 ElectronCloudBuildUpConfiguration;耦合模式包含云自场和横向束流响应。
物理约定、参数与限制见 电子云(ElectronCloud)。
束内散射使用独立顶层 Intrabeam scattering 配置块。
调用 generate_input 时传入 intrabeam_scattering=IBSConfig(...),
通过 IBSItem 引用命名模型。高斯增长率诊断和动力学踢要求显式局部
IBSOpticsConfig;二体碰撞使用局部三维网格。
增长率、作用时间和模型限制见 束内散射(IBS)。
自动设计时钟与初始化
PASS 在跟踪前,根据 harmonic ID=0 束团的初始能量、粒子质量与电荷、环周长, 以及各实际位置处启用的 RFCavity 波形,构造共同的理想纯 RF 设计轨迹。 同一位置的 RF 分量在同一个设计通过时刻采样并合计能量增量;飞行时间采用前一踢 之后的参考速度。设计回旋频率为 \(f_{rev}=\beta_{design}c/C\),累计相位 固定以物理时刻零为原点:
在圈边界和 RF 通过前记录频率节点,在物理时间上分段线性插值,区间外保持端点值, 每段积分解析计算。RF 踢只计算请求的圈数;之后以最终设计能量增加一次设计通过, 封闭插值区间,不再施加 RF 踢。没有活动 RF 电压时,设计时钟保持常频。集体效应踢角、粒子损失 及跟踪束团能量的变化不会重新定义这条理想设计时钟。输入 RF 相位仍是波形的附加 相位调制,不会被解释成要求设计粒子达到的同步相位。
不再提供公开 Reference clock 输入或 ReferenceClock schema;旧输入需删除该字段。
仅由初始能量和 RF 数据,一般无法唯一反推出任意外部规定时钟。外部信号源给定实际
RF 频率时,应使用分量的 Frequency (Hz) 或文件 FREQUENCY 列,并保留其
积分相位,包括原有非零时间原点。射频腔(RFCavity) 中的 HIAF 转换器执行这种迁移。
重构已有设计轨迹属于模型计算,不保证频率、能量采样逐位相同;应显式比较通过时间、
相位和能量。
初始 \(T_b=\Psi^{-1}(-h_{id}/h_{group})\),也可由 BunchConfig 的
Reference arrival time (s) 指定。第 n 圈注入使用
\(\Psi^{-1}(n-h_{id}/h_{group})\);显式初始到达时间与名义初始时间的差
平移该注入源的日程。注入粒子的 z 和归一化动量变换到目标束团参考系,保持物理
到达时间和机械动量。
harmonic_id、harmonic_number 表示名义槽位。
名义槽位位置 harmonic_id*C/harmonic_number 在需要输出元数据时计算;
将它加到 z 不能重建实际位置或到达时间。RF 谐波与分组数相互独立。束团重分组(ReorganizeBunch) 说明如何用
自动设计时钟相位重分组,同时保留展开的粒子时间。
InjectionItem(注入与分组)
InjectionItem 在注入层统一声明 harmonic_number (JSON 键 Harmonic Number )。该值是束团分组数,决定:
一圈内建立多少个束团中心,中心间距为 \(C/h_{\mathrm{group}}\)
bunches列表必须包含多少个BunchConfigharmonic_id必须唯一覆盖 \(0,\ldots,h_{\mathrm{group}}-1\)
它不限制 RFComponent.harmonic 。未填充的分组应使用 num_macro_particles=0 的空束团占位。
当需要复现生成的粒子分布时,设置整数 random_seed (JSON 键 Random Seed )。不设置或在 JSON 中设为 null 时采用默认的非确定性种子。该种子属于整个 Injection 命令,因此所有声明的束团和注入轮次共享同一随机数流。
BunchConfig(束团参数)
属性名 |
JSON key |
类型 |
说明 |
|---|---|---|---|
|
|
float |
每核子动能 (eV/u) |
|
|
int |
每束团真实粒子数 |
|
|
int |
每束团宏粒子数 |
|
|
float |
Twiss β 函数 |
|
|
float |
Twiss α 函数 |
|
|
float |
RMS 几何发射度(m rad) |
|
|
float |
束团长度 |
|
|
float |
动量展宽 |
|
|
str |
横向分布: |
|
|
str |
纵向分布: |
|
|
float |
有符号的物理 RF 电压(matchz/matchdp 模式使用) |
|
|
float |
匹配参考事件处的物理 RF 波形相位(matchz/matchdp),见 匹配计算中的射频相位和电荷符号 |
|
|
int |
束团分组编号;中心为 \(z_{\mathrm{center}}=h_{\mathrm{id}}C/h_{\mathrm{group}}\) |
|
|
float |
RF 腔相对注入点的位置,用于把匹配分布线性逆传输到 \(s=0\) |
|
|
float |
束团平均相对动量偏差;与动能偏差互斥 |
|
|
float |
束团平均动能偏差,内部精确转换为相对动量偏差 |
BunchConfig 中手动输入或生成的 z 坐标都是相对束团参考粒子到达时间的 \(z_{\mathrm{rel}}\) ,不是实验室绝对方位。
Sequence(序列容器)
Sequence 是一个有序容器,存储所有按位置 s 排列的序列项。导出时按 (s, command priority) 排序;排序键相同时保留插入次序。执行时还会按位置容差归并邻近位置。
from PASS.para.schema.sequence import Sequence
from PASS.para.schema.bunch import BunchConfig, InjectionItem
from PASS.para.schema.elements import QuadrupoleItem
from PASS.para.schema.monitors import StatMonitorItem
bunch = BunchConfig(kinetic_energy=45e6, num_real_particles=100000000000,
num_macro_particles=2048, emit_x=2e-6, emit_y=2e-6)
seq = Sequence()
seq.add("injection", InjectionItem(s=0.0, bunches=[bunch]))
seq.add("qd1", QuadrupoleItem(s=1.0, k1l=0.2, length=0.5))
seq.add("stat1", StatMonitorItem(s=0.0))
支持的序列项类型:
InjectionItem— 注入点(必须s=0)TwissItem— twiss 传输点DriftItem、QuadrupoleItem、SBendItem等 — 物理元件StatMonitorItem、DistMonitorItem、PhaseAdvanceMonitorItem— 监视器
晶格来源
PASS 支持以下晶格序列生成方式,可根据需要选择或混合使用:
方式一:从 MADX twiss 文件读取
读取 MADX 生成的 twiss TFS 文件,每个元件转为一个 TwissItem 传输点。适用于 逐 twiss 传输 模式。
from PASS.para.madx import read_madx_twiss
items, names, circum = read_madx_twiss(
twiss_file="lattice.tfs",
error_file="errors.tfs", # 可选
muz=0.001, # 纵向 tune
dqx=0.0, # 色品(或 "from_file")
dqy=0.0,
is_field_error=False, # 是否读取场误差
insert_patterns=["QD.*"], # 正则匹配,插入为薄透镜元件
)
绝对场误差的单位、实例匹配规则,以及逐元件分布误差与 Twiss 出口的集中动量增量的区别,见 元件误差。
两个 Twiss 读取函数都会将原生 MAD-X 的动量导数转换为 PASS 的
\(\delta=P/P_0-1\) 约定。MAD-X TWISS 使用
\(\mathrm{PT}=(E-E_0)/(P_0c)\simeq\beta_0\delta\),因此导入的
DX、DPX 以及从文件读取的 DQ1/DQ2 均乘以 \(\beta_0\)。
显式数值参数 dqx/dqy 已表示 \(dQ/d\delta\),保持不变;
原始 TFS 表本身保留原单位。使用文件色品时应以 twiss, chrom 导出。
直接导入 TFS 时要求原生 TWISS 输出。对于可识别的原始 PTC_TWISS 表会明确拒绝:
其导数约定取决于 PTC 的 TIME 模式,而普通 TFS 头信息未记录该模式;相位列也可能不同。
如需计算并导入 PTC 光学,应使用 方式四:直接加载 MAD-X SEQUENCE 或 LINE 中的
load_madx_sequence(..., optics_method="ptc")。其适配器明确掌握计算设置,
并返回兼容的列。该处理不意味着原生 TWISS 与精确 PTC 元件模型等价。
参考速度优先由 GAMMA 计算,缺少时由 ENERGY/MASS 计算。
两种信息均缺失时,为兼容旧表仍允许读取,但发出警告并采用超相对论近似
\(\beta_0=1\);非超相对论束流应补充参考能量头信息。
无效的参考参数会被拒绝。已有输入需要重新生成才能应用此修正;
800 MeV 动能质子的换算因子约为 0.84181。定义参见
MAD-X 坐标与导数约定。
如需均匀基础网格,改用重采样读取函数:
from PASS.para.madx import read_madx_twiss_interpolated
items, names, circum = read_madx_twiss_interpolated(
twiss_file="lattice.tfs",
num_interp_slice=101, # 100 段,包含 0 和 C 两个端点
dqx="from_file", dqy="from_file",
longitudinal_transfer="off",
)
该函数使用唯一支持的 interp_kind="phase_hermite"。
num_interp_slice 表示 基础点数 而非分段数,必须是至少为二的整数。
DQx/DQy 默认 "from_file",Mu z 默认零;纵向相位仅在
longitudinal_transfer="matrix" 时使用。
对长度为 \(h\) 的每个源区间,令 \(t=(s-s_i)/h\),用五次 Hermite 多项式 插值 \(p(t)=\mu(s)-\mu(s_i)\)。以周为相位单位,两端导数约束为:
插值光学函数由此计算:
这在每个区间内保持 \(\beta'=-2\alpha\)、\(\mu'=1/(2\pi\beta)\),
同时在端点匹配源 beta、alpha 和累计相位。相位导数在两端及全部内部极值点接受检查,
排除非正 beta。DX/DPX 使用成对的三次 Hermite 插值,沿用无耦合、参考轨道近轴约定。
插值内部保持源单位,构建 TwissItem 时将色散转换为对 \(\delta\) 的导数。
不进行耦合或闭轨坐标转换。源数据精度与间距限制插值精度。
表中必须包含 S=0、S=LENGTH,光学量有限、beta 为正、相位保持展开。 完整相位差与 Q1/Q2 的核对允许 TFS 输出舍入误差:相对容差 \(2\times10^{-8}\),绝对容差 \(2\times10^{-9}\)。 输出相位保留源值,不按舍入后的头信息重新缩放。分段色品按源相位差的比例分配, 保持用户指定的 DQx/DQy 总和。
原始行不作为额外点保留。零长度 BPM 标记、显式选择的 BPM 监视器、匹配的薄元件、 场误差和重复 S 处的光学跳变增加必要拆分位置。 场误差名称在重采样前与原始表匹配。光学跳变通过零长度 Twiss 传输连接入端和出端状态。 同一位置的附加薄元件或场误差在 Twiss 之后执行,与 command 优先级一致。 若显式插入源光学已包含的设计聚焦,会再次叠加该作用;插入误差不会自动保持受扰机器 的工作点。对应导入控件见 图形界面。
方式二:从 MADX twiss 文件读取为元件
读取 twiss 文件,但每个元件转为对应的物理元件对象( QuadrupoleItem 、 SBendItem 等)。适用于 逐元件跟踪 模式。
from PASS.para.madx import read_madx_elements
items, names, circum = read_madx_elements(
twiss_file="lattice.tfs",
is_merge_drift=True, # 合并相邻漂移节
is_field_error=True,
is_alignment_error=True,
error_file="errors.tfs",
)
两个误差开关独立,均默认为 False。准直从误差 TFS 读取 DX、DY、DPSI,
只移动磁场,孔径和 SC 边界保持固定;非零且不支持的准直分量明确报错。
Twiss 传输及重采样 Twiss 导入拒绝准直误差,应使用这里的逐元件模式。
归一化、实例匹配和执行顺序见 元件误差。
generate_from_tfs 同样接受 is_alignment_error。
方式三:平滑近似 twiss
无需 MADX 文件,用解析公式生成恒定 β 函数的 twiss 点。 \(\beta = C / (2\pi Q)\) 。适用于快速测试。
from PASS.para.smooth import generate_smooth_twiss
items, names, circum = generate_smooth_twiss(
circumference=569.1,
qx=9.47, qy=9.43,
num_points=100,
longitudinal_transfer="off",
)
方式四:直接加载 MAD-X SEQUENCE 或 LINE
PASS.para.madx_sequence.load_madx_sequence 通过 cpymad 加载
.seq 或 .madx 源文件。cpymad 是 PASS 的必选依赖,安装 PASS 时自动安装,
无需单独选择额外组件。
源文件可定义 MAD-X SEQUENCE 或 LINE,使用 sequence_name 指定其名称,
默认为 "ring"。
源文件由 MAD-X 执行,包括其中的 CALL 以及显式光学计算、文件输出命令。
相对引用以入口文件所在目录为基准。建议提供定义晶格及其依赖的入口,
由加载函数按所选方法计算光学。加载函数自身的计算文件放在临时目录中;
所提供源文件内的输出命令仍按 MAD-X 原有行为执行。
源文件中已经施加的 EALIGN/EFCOMP 节点误差会被拒绝,因为重新展开所选晶格会清除它们。
应加载理想晶格,再通过已有的误差 TFS 导入选项添加误差。CORRECT 产生的节点校正踢同样会被拒绝;
应先把所需校正铁强度保存为显式元件参数,再加载该晶格。
加载源文件与转换 PASS command 分为两步。optics_method=None 只导出展开后的元件参数,
不计算光学,适用于逐元件跟踪:
from PASS.para.madx import read_madx_elements
from PASS.para.madx_sequence import load_madx_sequence
from PASS.para.schema.sequence import Sequence
loaded = load_madx_sequence(
"lattice.seq",
sequence_name="ring",
beam_source="file",
optics_method=None,
)
items, names, circumference = read_madx_elements(loaded.elements)
sequence = Sequence()
for name, item in zip(names, items):
sequence.add(name, item)
该示例创建 PASS 序列的晶格部分。生成完整模拟输入时,还需添加常规 Injection、 监视器等命令,并使用返回的周长。
加载结果包含以下属性:
属性 |
含义 |
|---|---|
|
展开后元件参数的 |
|
请求计算时返回光学 |
|
本次导出或光学计算所用参考束流的字典。 |
|
需结合结果表检查的导入警告。 |
|
|
参考束流来源需要明确选择:
beam_source="file"要求源文件或其包含的文件中确实声明BEAM。 缺少声明时会报错,不采用 MAD-X 的隐式默认束流。beam_source="pass"要求提供main和明确选择的一个bunch。 两者接受 PASS schema 对象,或使用 Python 字段名/JSON 别名的字典。 粒子身份来自MainConfig,能量来自所选束团的每核子动能;多束团时不自动猜选。
例如,可复用已有 PASS 配置:
loaded = load_madx_sequence(
"lattice.seq",
sequence_name="ring",
beam_source="pass",
main=main_config,
bunch=selected_bunch,
optics_method="ptc",
)
其中 main_config 和 selected_bunch 是本次模拟实际使用的配置对象或字典。
源文件中的归一化磁铁强度与几何仍作为晶格参数,选择不同束流不会自动重新匹配晶格。
对于 Twiss 传输,选择 optics_method="twiss" 计算普通 MAD-X TWISS,
或选择 optics_method="ptc" 计算 PTC,再把 loaded.twiss 交给任一 Twiss 读取函数。
普通 TWISS 不实现 PTC/SAD 四极 F1/F2 端场分支。
要计算已启用端场模型的光学(包括 fringe_rebuild),应选择 "ptc";
选择普通 TWISS 得到的是不同的物理模型。
例如:
from PASS.para.madx import read_madx_twiss
loaded = load_madx_sequence(
"lattice.seq",
sequence_name="ring",
beam_source="file",
optics_method="ptc",
)
items, names, circumference = read_madx_twiss(
loaded.twiss,
dqx="from_file",
dqy="from_file",
longitudinal_transfer="off",
)
read_madx_elements、read_madx_twiss、read_madx_twiss_interpolated
既接受 TFS 路径,也接受这里的内存表;传递或保存表格时应保留头信息。
PTC 明确使用 MODEL=2、METHOD=6、EXACT=true、全局 NST=1、
TIME=true、FRINGE=false、ICASE=5、NO=2。
端场模型遵循元件的显式设置;全局开关不再替未启用的直磁铁开启内置端场。
源元件自身的正积分步数设置仍属于源模型。适配器转换横向光学列名,
并从累计相位取得完整工作点。返回表中保留对 PT 的导数;现有 Twiss 读取函数
只执行一次参考 beta 因子换算,转为对 delta 的导数。
调用读取函数前不要自行再次乘 beta。
导入范围限于 TwissItem 支持的无耦合光学:非零闭轨、垂直色散和不支持的耦合会被拒绝。
经 PTC 计算的 Twiss 映射可以包含 fringe_rebuild 模型的线性端场光学效果。
逐元件转换保留四极 F1/F2、直磁铁 FRINGE / FRNGMAX 以及入口、出口
屏蔽标志,用于非线性端场跟踪。普通 Twiss 表往往缺少这些参数,因此应使用 sequence
源生成的 loaded.elements。Twiss 映射不重现有限振幅非线性端场跟踪。
参数与全局开关约定见 物理入口和出口端场映射;GUI 中的源文件与参考束流
选择见 图形界面。
逐元件转换复用现有 PASS 跟踪映射,还会拒绝尚不支持的元件类型与非零参数,
例如 TILT、源 aperture、组合功能弯铁梯度,以及不同于 ANGLE/L 的弯铁 K0。
这些检查说明当前转换的支持范围;成功计算源光学不代表 PASS 物理元件已能跟踪每一种源参数。
MAD-X 通用 MULTIPOLE 使用不具备厚直磁铁端场属性的 PTC 薄映射,
因此导入时拒绝其非零端场位 2/4;直接配置的 PASS 厚 Multipole 支持内置端场。
螺线管端场属性和非四极的 F1/F2 仍不支持。sequence 展开只修正共享边界处
不超过四个浮点间隔的位置舍入差;实际重叠和外部 TFS 的严格几何规则保持不变。
MAD-X BPM 标记与监视器
read_madx_elements、read_madx_twiss、read_madx_twiss_interpolated 和
generate_from_tfs 均识别 MONITOR、HMONITOR、VMONITOR。
其 bpm_monitor 参数默认为 None。逐元件跟踪采用以下规则,
其中 TFS S 为元件出口位置,L 为元件长度:
BPM 长度 |
|
导入的元件序列 |
监视器位置 |
|---|---|---|---|
|
|
|
不记录数据 |
|
|
长度为 |
不记录数据 |
|
显式指定监视器模板 |
仅所选监视器 |
|
|
显式指定监视器模板 |
|
|
非零长度 BPM 因此保留完整飞行距离,不额外添加 Marker。
默认的有限长度 BPM 漂移可与相邻漂移合并;启用记录后,合并仍保留监视器所在的中心边界。
两个 Twiss 读取函数使用 Twiss 传输,不额外叠加物理漂移;在准确的监视器位置
插入或拆分传输点,插值网格也保留有限长度 BPM 的中心位置。
零长度 BPM 仅在未启用记录时保留 Marker。
不含 L 列的旧 Twiss 表将 BPM 视为零长度点;如需在有限长度 BPM 中心放置监视器,
应导出 L 列。
如需在全部导入的 BPM 处记录数据,传入含 type 和相应监视器 schema 字段的
配置模板。同一组设置应用于每个 BPM:
from PASS.para.madx import read_madx_elements
items, names, circum = read_madx_elements(
twiss_file="lattice.tfs",
bpm_monitor={
"type": "StatMonitor",
"output_format": "hdf5",
"write_interval_turns": 16,
},
)
同一 bpm_monitor 字典也适用于两个 Twiss 读取函数及 generate_from_tfs。
类型可选 StatMonitor、ParticleMonitor、DistMonitor、
PhaseAdvanceMonitor;字段可使用 Python 名称或 JSON 别名。
位置、命令类型和排序由导入器决定,不应在模板内填写 s、command、order
或其别名。MAD-X 的水平/垂直 BPM 关键字不限制所选 PASS 监视器记录的坐标。
生成的 PASS 命令名省略末尾的数字 MAD-X 实例后缀:例如位于 422.0936762 m 的
bpm:1 生成 bpm_s422.094。同名元件通过位置区分,只有生成名称完全相同时
才追加 _2、_3 等编号。用于 BPM 筛选和磁场误差实例匹配的原始来源名称保持不变。
如需只记录部分 BPM,可传入 bpm_names (精确名称)和/或 bpm_patterns
(正则表达式)。两者均在生成名称后缀和漂移合并之前,对原始 MAD-X NAME
进行不区分大小写的匹配。正则表达式采用搜索匹配;如需匹配整个名称,应使用
^ 和 $。两个列表取并集。两项都为 None 时选择全部 BPM;显式空选择,
例如 bpm_names=[] 且未指定正则表达式时,不选择任何 BPM。没有匹配项是有效配置,
不会插入监视器。选择器必须为字符串列表;直接传入字符串、包含非字符串项或使用无效
正则表达式会抛出 ValueError。源名称重复时会选择其全部出现位置。导入不会修改
监视器模板或选择器列表。
bpm_options = {
"bpm_monitor": {"type": "StatMonitor"},
"bpm_names": ["BPM.01", "BPM.07"],
"bpm_patterns": [r"^BPM\.ARC[12]\."],
}
items, names, circum = read_madx_elements(
"lattice.tfs", is_merge_drift=True, strict_geometry=True, **bpm_options,
)
未选中的 BPM 按默认规则转换为有限长度漂移或零长度 Marker。Twiss 导入不会为未选中的
有限长度 BPM 增加中心传输点。未设置 bpm_monitor 时,选择器不会启用记录。
三个读取函数和 generate_from_tfs 均接受这两个选择器参数。
这四个入口也接受 strict_geometry=False。启用后检查源位置有限且有序、长度有效、
导入后的传输区间以及最终周长。逐元件模式还检查每个入口和出口是否与累计物理长度一致,
避免局部缺口或重叠被相同的总长度掩盖。Twiss 模式检查其传输区间,不要求采样行的 L
之和等于周长。实际 S 必须位于 [0, C] 内并保持非递减,这两项不采用容差放宽。
长度、累计长度及环覆盖范围的比较,包括计算得到的入口 S-L,采用 1e-6 m
的绝对容差。Twiss 模式中的点命令必须与某个传输端点具有相同的运行时位置排序键;
仅相距不超过 1e-6 m 并不足够。严格检查失败时抛出 ValueError,说明不一致之处;
数值比较还会给出预期值、实际值、差值与容差。默认保留宽松导入行为以兼容现有用法。
无论是否启用严格检查,漂移合并都要求物理区间连续;监视器或 Marker 仍会阻止跨越其
所在位置的合并。
如需检查合并后的转换结果,可将原始 TFS 文件、返回的项目及名称,以及相同的 BPM 选项 传给以下函数:
from PASS.para.bpm import describe_madx_bpms
bpm_report = describe_madx_bpms(
"lattice.tfs", items, names, element_mode=True, **bpm_options,
)
报告为每个原始 BPM 出现位置提供一个字典,包含 source_name、occurrence、
keyword、length、source_s、selected、measurement_s、
conversion 和 outputs。出现序号从 1 开始,按完全相同的原始名称统计全部源行,
包括非 BPM 行。selected 表示已启用监视器且该 BPM 匹配。
没有插入监视器时 measurement_s 为 None。
每个输出项列出合并后的 name、command、s、length 和 merged 标志,
因此即使 BPM 已并入更长的漂移,也能追溯其最终项目。两个 Twiss 读取函数的结果应设置
element_mode=False。报告使用的源身份信息不会向生成的跟踪 JSON 添加字段。
ParticleMonitor 必须指定 max_tag。DistMonitor 需要通过 save_turns
选择保存圈数,默认空列表不保存分布。PhaseAdvanceMonitor 需要设置
turn_ranges 才启用分析;未指定的 beta/alpha 从每个 BPM 的
BETX、BETY、ALFX、ALFY 读取。对于有限长度 BPM,源出口光学与色散
沿半个漂移长度反向传输,得到监视器中心处的值。闭轨偏置默认保持零,只有显式配置
才改变;源 X、PX、Y、PY 不会自动作为监视器偏置导入,
因为生成的跟踪模型不一定复现源闭轨。导入的 DX、DPX 乘以 \(\beta_0\),
换算到 PASS 的相对动量偏差约定。显式给出的光学参数覆盖这些逐 BPM 默认值;
显式色散参数应已采用 PASS 单位。各监视器的参数和输出见 监视器与输出。
混合模式
twiss 传输点和物理元件可以在同一个序列中混合使用。例如在 twiss 序列中插入一个 RF 腔:
from PASS.para.schema.elements import RFCavityItem
from PASS.para.schema.sequence import Sequence
from PASS.para.schema.bunch import BunchConfig, InjectionItem
from PASS.para.schema.elements import QuadrupoleItem
from PASS.para.schema.monitors import StatMonitorItem
bunch = BunchConfig(kinetic_energy=45e6, num_real_particles=100000000000,
num_macro_particles=2048, emit_x=2e-6, emit_y=2e-6)
seq = Sequence()
seq.add("injection", InjectionItem(s=0.0, bunches=[bunch]))
from PASS.para.smooth import generate_smooth_twiss
twiss_items, twiss_names, circumference = generate_smooth_twiss(251.327, 4.8, 4.4, 17)
# Twiss 传输点
for i, item in enumerate(twiss_items):
seq.add(f"twiss_{i:04d}", item)
# 插入 RF 腔(在 s=0 处)
seq.add("rf1", RFCavityItem(s=0.0, components=[dict(voltage=100e3, harmonic=1, phase=0.5236)]))
外部数据文件转换
磁铁 ramping、RF 和 exciter 输入采用 TFS 表。四极、六极、八极和多极铁读取以
物理秒为自变量的归一化强度;每个非空 bunch 在元件入口采样一次,整个元件使用该强度。
支持的列和采样模型见 磁铁 ramping。
RF 使用独立的 TIME, VOLTAGE, FREQUENCY, PHASE 接口,见 射频腔(RFCavity)。
生成磁铁程序
可以直接写入时间断点表,跟踪时进行分段线性插值,并在表格区间之外保持端点值:
from PASS.para.tools.ramping import write_magnet_ramping
from PASS.para.schema.elements import QuadrupoleItem
write_magnet_ramping(
"quadrupole_ramp.tfs",
times=[0.0, 0.05, 0.10], # physical seconds
columns={"K1L": [0.20, 0.25, 0.22], "K1SL": [0.01, 0.0, -0.01]},
)
quad = QuadrupoleItem(
s=10.0, length=0.5, num_slices=8,
is_ramping=True, ramping_file="quadrupole_ramp.tfs",
)
写入器校验表格,并加入 TIME_UNIT="s"、
STRENGTH_CONVENTION="normalized" 和强度单位元数据。
输入是绝对强度而非倍率。非积分 K1、K2 等列要求正的磁铁长度;
积分 K1L、K2L 等列也支持薄透镜。正、斜分量可以独立指定,
同一分量不可同时提供 K 和 KL。
转换外部文件
专用转换器读取 CSV、空白分隔 TXT 或 TFS。将源列名映射为所需的强度列名, 并明确指定时间单位换算。转换保留原始采样时刻,不转为圈号或重采样到逐圈网格:
from PASS.para.tools.ramping import convert_magnet_ramping
convert_magnet_ramping(
input_path="external_ramp.csv",
output_path="quadrupole_ramp.tfs",
time_column="time_ms",
time_scale=1e-3, # milliseconds -> seconds
column_mapping={"normal": "K1L", "skew": "K1SL"},
delimiter=",",
)
对于特殊表头或需要跳过行的文件,可使用同一模块的
read_magnet_ramping_source(input_path, delimiter=None, header=0, skiprows=0),
提取所需数值列后调用 write_magnet_ramping。
源 TFS 的时间单位元数据必须与选定的时间换算一致;若提供强度单位元数据,也会校验。
强度不会从实际磁场隐式换算。
GUI 在 工具 → 数据转换 → 磁铁 ramping… 中提供导入转换和时间断点生成, 见 GUI 工具。导出后,在支持的元件中启用 ramping 并选取文件。
旧 convert_external_to_tfs、convert_k1l_ramping 等辅助函数保留历史圈号表
行为。只有包含实际物理秒的旧 TIME_S 列才可以被跟踪器接受;仅含 TURN
的表不能驱动磁铁 ramping。加速过程中不能由行号或瞬时回转频率推断累计时间。
新输入应使用上述物理时间写入器或转换器。
RF 文件使用独立接口:
from PASS.para.tools.rf_data import convert_rf_data
convert_rf_data("llrf.csv", "rf_physical_time.tfs")
参数扫描与校验
model_copy(update=...) 不会重新校验更新值。参数扫描应从字段字典重新构造配置对象,再对生成的完整输入执行校验:
from PASS.para.schema.main import MainConfig
baseline = MainConfig(circumference=251.327)
candidate = {**baseline.model_dump(), "num_turns": 128}
scan_config = MainConfig.model_validate(candidate)
Python 字段 num_electron 沿用历史命名,实际表示带符号电荷数,并非束缚电子数量。因此 num_proton=1, num_neutron=0, num_electron=1 表示质子。Python 字段名用于配置对象构造,JSON 文件使用表中的别名。
架构概览
参数模块分别负责输入对象的构造、校验与序列化:
PASS/para/
├── schema/ 参数定义(字段定义与别名)
│ ├── main.py MainConfig:全局仿真参数
│ ├── bunch.py BunchConfig + OffsetConfig + InjectionItem
│ ├── twiss.py TwissItem:twiss 传输点
│ ├── elements.py 元件配置类
│ ├── monitors.py StatMonitor / DistMonitor / PhaseAdvanceMonitor
│ ├── space_charge.py SpaceChargeConfig + SpaceChargeResourceConfig + SpaceCharge
│ ├── electron_cloud.py ElectronCloudConfig + ElectronCloudConfiguration + ElectronCloudItem
│ ├── ibs.py IBSConfig + IBSConfiguration + IBSOpticsConfig + IBSItem
│ └── sequence.py Sequence:有序容器 + 自动排序
├── madx.py MADX TFS → schema 对象(element / twiss / error)
├── madx_sequence.py MAD-X 源文件 → cpymad 元件/光学表
├── smooth.py 解析平滑近似 twiss
├── tools/ 外部数据 → PASS TFS
│ ├── data_converter.py 通用数据转换流水线
│ ├── ramping.py 元件 ramping 文件生成
│ ├── rf_data.py RF 数据文件生成
│ └── exciter_data.py Exciter 数据文件生成
├── toolkit.py sort_sequence + class_map + apply_element_settings + build_sequence
└── api.py 高级 API(generate_input / load_input / generate_from_tfs)
数据流如下:
MADX TFS / 用户参数 / 外部数据文件
│
▼
madx.py / smooth.py + tools/ → schema 对象 / TFS 文件
│
▼
schema/ (pydantic) ← 字段定义与别名:验证 + 别名
│
▼
api.py (generate_input) → beam0.json
│
▼
PASS 引擎 (Config → Beam → CommandSequence → Executor)
API 入口
PASS.para.api 提供 generate_input、build_sequence、generate_from_tfs 和 load_input。load_input(path) 返回 (MainConfig, raw_sequence_dict),不会重建带类型的命令对象,也不返回顶层 Space charge/Wake field/Electron cloud/Intrabeam scattering 配置块;返回前会校验电子云和 IBS 配置及其引用。编辑现有完整文件时应单独保留这些配置块。
generate_from_tfs 为未指定 kinetic_energy 的束团自动填值时,MAD-X
ENERGY 和 MASS 分别表示完整粒子的总能量和静能,单位为 GeV。
质量数取解析后的 MainConfig 中的
A = main_cfg.num_proton + main_cfg.num_neutron,不由 beam_name 或电荷数决定。
当 A > 0 时,导入动能为 (ENERGY - MASS) * 1e9 / A,单位为 eV/u。
电子和正电子的 A = 0,采用 (ENERGY - MASS) * 1e9,单位为每粒子 eV。
显式提供的 kinetic_energy 按相应的 PASS 单位保留。
此换算保留 TFS 动能,运行时仍采用 PASS 既有的粒子质量约定,详见 注入与粒子生成(Injection)。 如果 TFS 静质量与 PASS 使用的质量不同,所得参考粒子的 gamma 和 beta 不保证与 TFS 值相同。