内容
# EIS ECM DRT MCP
[English](#eis-ecm-drt-mcp) | [中文](#eis-ecm-drt-mcp-中文)
这是一个用于 EIS 数据批量分析的 MCP 服务。输入为 EIS 文件或文件夹,输出为 ECM 参数、DRT 曲线、拟合重构数据和图。
项目保持两层结构:
- `eis_ecm_drt/`:核心算法,包括列识别、ECM 拟合、DRT 反演、批量输出。
- `eis_ecm_drt/mcp_server.py`:MCP 薄接口层,只负责接收参数、校验用户选择、调用核心算法。
后续如果发现算法问题,直接改 `eis_ecm_drt/` 里的源码,然后重启 MCP 服务即可。
## 功能
- 批量处理 `.xlsx`、`.xls`、`.csv`、`.tsv`、`.txt`
- 自动识别频率列、实部列、虚部列
- 自动统一虚部符号,输出采用 `-Zimag` 口径,同时保留物理虚部列
- ECM 支持四个主模型,也支持用户自定义等效电路表达式
- DRT 参数必须由用户显式选择
- 输出每个样本的 ECM 参数、DRT 曲线、拟合曲线、汇总 CSV 和可选 PNG 图
- 默认输出到桌面 `EIS Analysis output` 下的新子文件夹,不污染输入数据目录
## 从 GitHub 到安装
如果项目已经上传到 GitHub,先把代码克隆到本地:
```powershell
git clone <你的 GitHub 仓库地址>
cd <项目文件夹>
```
如果已经有本地源码,直接进入项目根目录,例如:
```powershell
cd C:\Users\wzd\Documents\电池软件
```
建议使用 Python 3.10 或更高版本:
```powershell
py -3.10 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -U pip
.\.venv\Scripts\python.exe -m pip install -e ".[mcp]"
```
也可以直接使用仓库自带的一键脚本。第一次运行会自动创建 `.venv` 并安装依赖:
```powershell
.\run_mcp.cmd
```
命令行分析可以用:
```powershell
.\eis-analysis.cmd "test_cases/demo_eis/demo_eis.csv" --ecm-model L-R0-RQ-W --no-plots
```
## 启动 MCP
安装后可以直接启动:
```powershell
.\.venv\Scripts\eis-ecm-drt-mcp.exe
```
也可以用模块方式启动:
```powershell
.\.venv\Scripts\python.exe -m eis_ecm_drt.mcp_server
```
MCP 客户端配置示例:
```json
{
"mcpServers": {
"eis-ecm-drt": {
"command": "C:\\path\\to\\EIS-Analysis-mcp\\run_mcp.cmd",
"args": []
}
}
}
```
仓库里也提供了可复制修改的配置文件:
- `examples/mcp_config_windows.json`
- `examples/mcp_config_macos_linux.json`
配置完成后,在 MCP 客户端里刷新或重启连接。看到 `eis-ecm-drt` 这个 MCP 服务可用,就说明已经连上。
## MCP 已连接后怎么用
连接成功以后,不需要手动运行命令行。你在支持 MCP 的客户端里提出需求,客户端会调用本项目暴露的 MCP 工具。
推荐使用流程:
1. 先调用 `list_ecm_models`,让用户选择 ECM 模型。
2. 再调用 `list_drt_options`,让用户选择或确认 DRT 参数。
3. 如果不确定输入文件格式,先调用 `validate_eis` 或 `validate_eis_batch` 检查列识别结果。
4. 单文件分析调用 `analyze_eis_file`。
5. 批量分析调用 `analyze_eis_batch`。
6. 打开输出目录里的 `README_输出说明.txt` 和 `batch_summary.csv` 查看结果。
最终结果默认在桌面:
```text
D:\desktop\EIS Analysis output\batch_YYYYMMDD_HHMMSS\
```
每次分析都会在 `EIS Analysis output` 里面新建一个子文件夹。MCP 返回结果里也会包含 `output_dir`、`readme_path` 和 `summary_path`,其中 `readme_path` 是最推荐先打开看的说明文件。
用户可以这样对 MCP 客户端说:
```text
请使用 eis-ecm-drt 分析 D:\desktop\EIS验证\温度估计_基础电池_txt。
ECM 模型我选择 L-R0-RQ-W。
DRT 参数使用推荐配置。
批量处理,自动识别频率、实部、虚部列,最终结果输出到桌面 EIS Analysis output 文件夹,并生成图。
```
如果想比较多个 ECM 模型,可以这样说:
```text
请批量分析 D:\desktop\EIS验证\温度估计_基础电池_txt。
ECM 模型选择 L-R0-RQ、L-R0-2RQ、L-R0-RQ-W、L-R0-2RQ-W 四个都拟合并比较。
DRT 参数使用推荐配置。
最终结果输出到桌面 EIS Analysis output 文件夹。
```
注意:正式分析前必须明确 ECM 模型和 DRT 参数。MCP 不会自动替用户选择;如果调用时没有传确认字段,会直接报错。
## MCP 工具
正式 MCP 暴露这些工具:
- `list_ecm_models`:列出四个主 ECM 模型和自定义模型写法。
- `list_drt_options`:列出 DRT 必选参数和推荐配置。
- `validate_eis`:验证单个文件或数组数据,并返回自动识别的列和清洗后的 EIS。
- `validate_eis_batch`:批量验证文件夹、通配符或文件列表。
- `fit_ecm`:对数组数据拟合一个用户已选择的 ECM 模型。
- `calculate_drt`:对数组数据按用户已选择的 DRT 参数计算 DRT。
- `analyze_eis_file`:分析一个 EIS 文件。
- `analyze_eis_batch`:批量分析文件、文件夹或通配符。
重要规则:
`analyze_eis_file` 和 `analyze_eis_batch` 不会替用户选择 ECM 或 DRT。调用前必须让用户选择:
- `ecm_models`:一个或多个 ECM 模型 ID 或自定义表达式
- `drt_config`:完整 DRT 参数字典
- `ecm_models_confirmed_by_user: true`:确认 ECM 模型是用户刚刚选择的
- `drt_config_confirmed_by_user: true`:确认 DRT 参数是用户刚刚选择或批准的
如果缺少这些选择或确认字段,MCP 会直接报错。
## ECM 模型选择
主模型如下:
| 模型 ID | 模型名称 | 等效电路表达式 | 主要组成 |
| --- | --- | --- | --- |
| `L-R0-RQ` | CPE 单弧模型 | `L1-R0-(R1||CPE1)` | 电感、欧姆内阻、一个非理想极化弧 |
| `L-R0-2RQ` | 双 CPE 模型 | `L1-R0-(R1||CPE1)-(R2||CPE2)` | 电感、欧姆内阻、两个非理想极化弧 |
| `L-R0-RQ-W` | 含扩散单弧模型 | `L1-R0-(R1-W1||CPE1)` | 电感、欧姆内阻、一个极化弧和扩散过程 |
| `L-R0-2RQ-W` | 含扩散双弧模型 | `L1-R0-(R1||CPE1)-(R2-W1||CPE2)` | 电感、欧姆内阻、两个极化弧,其中低频弧包含扩散过程 |
其中:
- `L1`:高频电感
- `R0`:欧姆内阻
- `R1/R2`:极化或电荷转移电阻
- `CPE1/CPE2`:常相位元件,输出参数为 `CPE*_Q` 和 `CPE*_n`
- `W1`:Warburg 扩散阻抗,当前实现只有一个参数
- `||`:并联
- `-`:代码表达式中的串联分隔符,等价于电路图里的 `+`
用户也可以传自定义表达式,例如:
```text
L1-R0-(R1||CPE1)-(R2-W1||CPE2)
## DRT 参数选择
先调用 `list_drt_options`,让用户确认 DRT 参数。当前商业软件对齐后的推荐配置为:
```json
{
"lambda_value": 0.01,
"n_tau": 750,
"regularization_order": 1,
"basis_function": "gaussian",
"shape_factor": 0.72,
"n_basis": 220,
"polarization_removal": "ignore_polarization",
"boundary_suppression_factor": 0.10,
"nonnegative": true,
"fit_r_inf": true,
"fit_inductance": true,
"weighting": "modulus"
}
```
说明:
- `lambda_value`:正则化强度
- `n_tau`:DRT 输出点数
- `regularization_order": 1,
"basis_function": "gaussian",
"shape_factor": 0.72,
"n_basis": 220,
"polarization_removal": "ignore_polarization",
"boundary_suppression_factor": 0.10,
"nonnegative": true,
"fit_r_inf": true,
"fit_inductance": true,
"weighting": "modulus"
}
```
## 批量分析示例
MCP 调用 `analyze_eis_batch` 的参数示例:
```json
{
"inputs": ["D:/desktop/EIS验证/温度估计_基础电池_txt"],
"recursive": false,
"ecm_models": ["L-R0-RQ-W"],
"ecm_models_confirmed_by_user": true,
"drt_config": {
"lambda_value": 0.01,
"n_tau": 750,
"regularization_order": 1,
"basis_function": "gaussian",
"shape_factor": 0.72,
"n_basis": 220,
"polarization_removal": "ignore_polarization",
"boundary_suppression_factor": 0.10,
"nonnegative": true,
"fit_r_inf": true,
"fit_inductance": true,
"weighting": "modulus"
},
"drt_config_confirmed_by_user": true,
"make_plots": true,
"continue_on_error": true
}
```
一次比较多个 ECM 模型:
```json
{
"inputs": ["D:/desktop/EIS验证/温度估计_基础电池_txt"],
"ecm_models": ["L-R0-RQ", "L-R0-2RQ", "L-R0-RQ-W", "L-R0-2RQ-W"],
"ecm_models_confirmed_by_user": true,
"drt_config": {
"lambda_value": 0.01,
"n_tau": 750,
"regularization_order": 1,
"basis_function": "gaussian",
"shape_factor": 0.72,
"n_basis": 220,
"polarization_removal": "ignore_polarization",
"boundary_suppression_factor": 0.10,
"nonnegative": true,
"fit_r_inf": true,
"fit_inductance": true,
"weighting": "modulus"
},
"drt_config_confirmed_by_user": true,
"recursive": false,
"make_plots": false
}
```
如果不传 `output_dir`,结果会写到:
```text
D:\desktop\EIS Analysis output\batch_YYYYMMDD_HHMMSS\
```
如果没有 `D:\desktop`,会尝试用户桌面目录。总之默认不会写进输入数据文件夹,最终结果会放在桌面的 `EIS Analysis output` 目录下。
## 输入数据规则
推荐文件至少包含三列:
| 频率 | 实部 | 虚部 |
| --- | --- | --- |
| `freq_hz` | `z_real_ohm` | `z_imag_ohm` |
没有表头也可以。程序会根据数值特征识别频率列:
- 频率列通常全为正数
- 跨多个数量级
- 大致单调,例如 `0.01` 到 `1000`
- 找到频率列后,优先把后面相邻两列作为实部和虚部
虚部会统一成 `-Zimag` 输出口径:
- 低频处虚部为正:认为源数据已经是 `-Zimag`
- 低频处虚部为负:认为源数据是物理 `Zimag`,自动乘以 `-1`
内部计算仍使用物理复阻抗 `Z = Zreal + j Zimag`。
## 输出文件
每个样本会输出:
- `README_输出说明.txt`:输出目录说明,建议先打开这个文件
- `*_ecm_params.csv`:ECM 参数
- `*_ecm_compare.csv`:多个 ECM 候选模型的拟合误差对比
- `*_drt.csv`:DRT 曲线
- `*_fit.csv`:原始 EIS、ECM 重构、DRT 重构
- `*_summary.csv`:单样本摘要
- `*_nyquist.png`:Nyquist 图
- `*_bode.png`:Bode 图
- `*_drt.png`:DRT 图
批量任务额外输出:
- `batch_summary.csv`
文件名前缀来自原始 EIS 文件名。示例里的 `cell_a` 和 `cell_b` 只是 demo 假样本名,不代表真实电池编号。
## 本地调试
生成示例数据:
```powershell
C:\ProgramData\Anaconda3\python.exe examples\make_demo_data.py
```
运行 smoke test:
```powershell
C:\ProgramData\Anaconda3\python.exe tests\smoke_test.py
```
模拟 MCP 批量调用:
```powershell
C:\ProgramData\Anaconda3\python.exe examples\debug_mcp_batch.py
```
直接命令行运行核心算法:
```powershell
C:\ProgramData\Anaconda3\python.exe -m eis_ecm_drt "examples/data/*.csv" `
--ecm-model L-R0-RQ-W `
--drt-lambda 0.01 `
--n-tau 750 `
--regularization-order 1 `
--basis-function gaussian `
--shape-factor 0.72 `
--n-basis 220 `
--boundary-suppression-factor 0.10 `
--polarization-removal ignore_polarization `
--fit-inductance `
--no-plots
```
## 商业软件对齐 loop
开发用脚本:
[tools/commercial_alignment_loop.py](tools/commercial_alignment_loop.py)
它会读取商业 DRT Excel,批量搜索 DRT 参数,并输出最佳配置:
```powershell
C:\ProgramData\Anaconda3\python.exe tools\commercial_alignment_loop.py `
--input-dir "D:\desktop\EIS验证\温度估计_基础电池_txt" `
--commercial-drt "D:\desktop\EIS验证\基础电池_DRT_原始数据.xlsx" `
--commercial-ecm "D:\desktop\EIS验证\2.ECM数据.xlsx" `
--max-samples 60 `
--candidate-preset refine `
--evaluate-all
```
当前默认 DRT 参数来自该 loop 的 200 样本验证结果。
## Python API
```python
from eis_ecm_drt import DRTConfig, ECMConfig, analyze_file
result = analyze_file(
"examples/data/cell_a.csv",
ecm_config=[ECMConfig(model="L-R0-RQ-W")],
drt_config=DRTConfig(
lambda_value=0.01,
n_tau=750,
regularization_order=1,
basis_function="gaussian",
shape_factor=0.72,
n_basis=220,
polarization_removal="ignore_polarization",
boundary_suppression_factor=0.10,
fit_inductance=True,
),
make_plots=False,
)
print(result["ecm"].parameters)
print(result["drt"].tau, result["drt"].gamma)
```
## 许可证
本项目使用 MIT License,见 [LICENSE](LICENSE)。