输入文件生成(命令行模式)
简介
PASS 采用 JSON 文件 作为仿真输入。引擎( Config 、 Beam 、 CommandSequence )从 JSON 文件读取全部参数,包括粒子种类、束团分布、Lattice序列、监测器等。
参数系统 PASS/para/ 提供了一套基于 pydantic v2 的 schema 定义,用户通过 Python 脚本组装参数对象,调用 generate_input() 即可输出引擎兼容的 JSON 文件。这种方式相比手写 JSON 有以下优势:
类型安全 :参数类型、范围在 schema 中声明,非法值在生成时即被拦截;
别名映射 :Python 代码使用简洁属性名(如
circumference),JSON 输出自动使用引擎期望的 key(如"Circumference (m)");可复用 :schema 对象可
model_copy(update={...})快速派生变体,适合参数扫描;GUI 可扩展 :schema 自带 JSON Schema 导出,未来 GUI 可自动渲染表单。
Note
本文档介绍命令行模式下的输入文件生成方式。GUI 模式将在未来版本中提供。
架构概览
参数系统分为五层,各层职责清晰、互不依赖:
PASS/para/
├── schema/ 参数定义(唯一数据源)
│ ├── main.py MainConfig:全局仿真参数
│ ├── bunch.py BunchConfig + OffsetConfig + InjectionItem
│ ├── twiss.py TwissPoint:twiss 传输点
│ ├── elements.py 12 种元件(Drift→RFCavity)
│ ├── monitors.py StatMonitor / DistMonitor / PhaseMonitor
│ ├── space_charge.py SpaceChargeConfig
│ └── sequence.py Sequence:有序容器 + 自动排序
├── readers/ 外部格式 → schema 对象
│ ├── madx_twiss.py MADX twiss TFS → TwissPoint 列表
│ ├── madx_element.py MADX twiss TFS → Element 列表
│ ├── madx_error.py MADX error TFS → 场误差
│ └── smooth_approx.py 解析平滑近似 twiss
├── writers/ schema → 输出
│ └── json_writer.py schema → 引擎兼容 JSON
├── tools/ 外部数据 → PASS TFS
│ ├── data_converter.py 通用数据转换流水线
│ ├── ramping.py 元件 ramping 文件生成
│ ├── rf_data.py RF 数据文件生成
│ └── exciter_data.py Exciter 数据文件生成
├── toolkit.py sort_sequence + class_map
└── api.py 高级 API
数据流如下:
MADX TFS / 用户参数 / 外部数据文件
│
▼
readers/ + tools/ → schema 对象 / TFS 文件
│
▼
schema/ (pydantic) ← 唯一数据源:验证 + 别名
│
▼
writers/json_writer → beam0.json
│
▼
PASS 引擎 (Config → Beam → CommandSequence → Executor)
快速开始
最简示例
以下脚本生成一个包含注入 + 平滑近似 twiss + 统计监测器的完整输入文件:
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 StatMonitor
from PASS.para.readers.smooth_approx import generate_smooth_twiss
# 1. 全局参数
main = MainConfig(
beam_name="proton",
num_proton=1, num_neutron=0, num_electron=1,
gamma_t=4.8, circumference=251.327,
num_turns=1000, backend="cpu",
)
# 2. 束团
bunch = BunchConfig(
kinetic_energy=45e6,
num_real_particles=int(1e11),
num_macro_particles=int(1e5),
beta_x=0.5, beta_y=0.5,
alpha_x=-2.61, alpha_y=1.57,
emit_x=200e-6, emit_y=100e-6,
sigma_z=30, dp=0.005,
dist_trans="gaussian", dist_longi="matchz",
rf_voltage=100e3, rf_phase=0.5236,
)
# 3. Lattice序列
items, circum = generate_smooth_twiss(
circumference=main.circumference,
qx=4.8, qy=4.4, num_points=100,
)
main.circumference = circum
seq = Sequence()
seq.add("injection", InjectionItem(s=0.0, bunches=[bunch]))
for i, item in enumerate(items):
seq.add(f"twiss_{i:04d}", item)
seq.add("stat1", StatMonitor(s=0.0))
# 4. 生成 JSON
generate_input(main, seq, "beam0.json")
运行方式:
cd C:\Users\changmx\Documents\PASS
python input/generate_beam0.py
输出文件: input/beam0.json
JSON 文件结构
生成的 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": 1000,
"Backend (gpu/cpu)": "cpu",
"Number of GPU devices": 1,
"Device Id": [0],
"Output directory": "./output",
"Is plot figure": true,
"Is space charge": false,
"Is beam-beam": false,
"Sequence": {
"injection": {
"S (m)": 0.0,
"Command": "Injection",
"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 的 key 名称是引擎的硬性契约。schema 层通过 pydantic 的 alias 机制自动处理 Python 属性名到 JSON key 的映射,用户无需手写。
引擎在读取时会先调用 convert_keys_to_lower() 将所有 key 转为小写,因此 JSON key 的大小写不影响读取。
核心组件
MainConfig(全局参数)
属性名 |
JSON key |
类型 |
说明 |
|---|---|---|---|
|
|
str |
束流标签 |
|
|
int |
每粒子质子数(0 表示电子/正电子) |
|
|
int |
每粒子中子数(>0 表示离子) |
|
|
int |
每粒子电荷数(可负,不可为 0) |
|
|
float |
过渡 gamma |
|
|
float |
环周长 (m) |
|
|
int |
仿真圈数 |
|
|
str |
计算后端: |
|
|
int |
GPU 数量 |
|
|
list[int] |
GPU 设备 ID 列表 |
|
|
str |
输出目录 |
|
|
bool |
是否生成图表 |
|
|
bool |
是否启用空间电荷 |
|
|
bool |
是否启用束流-束流相互作用 |
BunchConfig(束团参数)
属性名 |
JSON key |
类型 |
说明 |
|---|---|---|---|
|
|
float |
每核子动能 (eV/u) |
|
|
int |
每束团真实粒子数 |
|
|
int |
每束团宏粒子数 |
|
|
float |
Twiss β 函数 |
|
|
float |
Twiss α 函数 |
|
|
float |
发射度 |
|
|
float |
束团长度 |
|
|
float |
动量展宽 |
|
|
str |
横向分布: |
|
|
str |
纵向分布: |
|
|
float |
RF 电压(matchz/matchdp 模式使用) |
|
|
float |
RF 相位 |
Sequence(序列容器)
Sequence 是一个有序容器,存储所有按位置 s 排列的序列项。添加顺序不影响最终结果——导出时自动按 (s, command priority) 排序。
seq = Sequence()
seq.add("injection", InjectionItem(s=0.0, bunches=[bunch]))
seq.add("qd1", QuadrupoleElement(s=1.0, k1l=0.2, length=0.5))
seq.add("stat1", StatMonitor(s=0.0))
支持的序列项类型:
InjectionItem— 注入点(必须s=0)TwissPoint— twiss 传输点DriftElement、QuadrupoleElement、SBendElement等 — 物理元件StatMonitor、DistMonitor、PhaseMonitor— 监测器
Lattice来源
PASS 支持三种Lattice序列生成方式,可根据需要选择或混合使用:
方式一:从 MADX twiss 文件读取
读取 MADX 生成的 twiss TFS 文件,每个元件转为一个 TwissPoint 传输点。适用于 逐 twiss 传输 模式。
from PASS.para.readers.madx_twiss import read_madx_twiss
items, 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.*"], # 正则匹配,插入为薄透镜元件
)
方式二:从 MADX twiss 文件读取为元件
读取 twiss 文件,但每个元件转为对应的物理元件对象( QuadrupoleElement 、 SBendElement 等)。适用于 逐元件追踪 模式。
from PASS.para.readers.madx_element import read_madx_elements
items, circum = read_madx_elements(
twiss_file="lattice.tfs",
is_merge_drift=True, # 合并相邻漂移节
is_field_error=True,
error_file="errors.tfs",
)
方式三:平滑近似 twiss
无需 MADX 文件,用解析公式生成恒定 β 函数的 twiss 点。 \(\beta = C / (2\pi Q)\) 。适用于快速测试。
from PASS.para.readers.smooth_approx import generate_smooth_twiss
items, circum = generate_smooth_twiss(
circumference=569.1,
qx=9.47, qy=9.43,
num_points=100,
muz=0.001,
)
混合模式
twiss 传输点和物理元件可以在同一个序列中混合使用。例如在 twiss 序列中插入一个 RF 腔:
from PASS.para.schema.elements import RFCavityElement
seq = Sequence()
seq.add("injection", InjectionItem(s=0.0, bunches=[bunch]))
# twiss 传输点
for i, item in enumerate(twiss_items):
seq.add(f"twiss_{i:04d}", item)
# 插入 RF 腔(在 s=0 处)
seq.add("rf1", RFCavityElement(s=0.0, voltage=100e3, harmonic=1, phase=0.5236))
外部数据文件转换
PASS 使用 TFS 格式 作为所有 ramping/RF/exciter 数据文件的统一格式。 tools/data_converter.py 提供了通用转换流水线,将各种外部文件(CSV/TXT/TFS)转为 PASS TFS。
四步流水线
外部文件 → load_raw_data → time_to_turn → interpolate → write_tfs
load_raw_data :读取外部文件,自动检测 turn/time 列
time_to_turn :如外部文件给的是时间而非圈数,用回旋频率转换
interpolate_to_continuous_turns :圈数不连续时自动插值
write_tfs_ramping :写入 PASS 统一 TFS 格式
一步到位
from PASS.para.tools.data_converter import convert_external_to_tfs
convert_external_to_tfs(
input_path="external_ramp.csv", # 外部文件
output_path="k1l_ramping.tfs", # PASS TFS
data_cols=["k1l", "k1sl"], # 数据列名
revolution_freq=1.76e6, # 回旋频率 (Hz)
num_turns=5000, # 目标圈数
method="linear", # 插值方法
)
预置封装
针对常见元件类型的薄封装:
from PASS.para.tools.ramping import convert_k1l_ramping, convert_k2l_ramping
from PASS.para.tools.rf_data import convert_rf_data
# 四极铁 ramping
convert_k1l_ramping("external.csv", "k1l_ramping.tfs", revolution_freq=1.76e6)
# RF 数据
convert_rf_data("llrf.csv", "rf_data.tfs", revolution_freq=1.76e6)
分步调用
外部文件格式特殊时,可分步调用各函数:
from PASS.para.tools.data_converter import (
interpolate_to_continuous_turns, write_tfs_ramping,
)
import numpy as np
# 自行准备数据
turn_arr = np.array([1, 50, 100, 500, 1000])
k2l = np.array([0.0, 0.5, 1.0, 2.5, 4.4])
turn_cont, data_cont = interpolate_to_continuous_turns(
turn_arr, {"K2L": k2l},
start_turn=1, end_turn=1000, method="linear",
)
write_tfs_ramping("k2l_ramping.tfs", turn_cont, None, data_cont)
API 参考
from PASS.para.api import generate_input, load_input
# 生成 JSON
generate_input(
main: MainConfig,
sequence: Sequence,
output_path: str,
space_charge: SpaceChargeConfig | None = None,
extra_modules: dict | None = None,
) -> str
# 加载已有 JSON(用于修改后重新生成)
main, seq_dict = load_input("beam0.json")
完整示例
项目内置的示例脚本位于 input/generate_beam0.py ,可直接运行:
cd C:\Users\changmx\Documents\PASS
python input/generate_beam0.py
该脚本演示了完整的端到端流程:全局参数 → 多束团配置 → 平滑近似 twiss → Lattice 序列组装 → JSON 输出。生成的 beam0.json 可直接被 PASS 引擎读取执行。