mcpField
M
matlab-build-simbiology-model

matlab-build-simbiology-model

github.com/matlab其他1.2k52 次安装1 天前更新
代码仓库

关于 matlab-build-simbiology-model

用于创建和修改 SimBiology 模型的 MATLAB 技能,可配置组件、反应、规则和事件,适用于桌面、无界面、批处理及远程环境;仅在需要时处理图示布局。

主要功能

  1. 01创建和修改 SimBiology 模型
  2. 02配置区室、物种和反应
  3. 03添加规则、事件、剂量与观测量
  4. 04加载和保存模型项目
  5. 05排列并检查模型图示

适用场景

  1. 01构建药代动力学模型
  2. 02编辑模型组件和反应
  3. 03加载并保留现有 .sbproj 图示
  4. 04准备供审阅的模型图示

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/matlab/matlab-agentic-toolkit --skill matlab-build-simbiology-model

安装后在 Claude Code 中输入/matlab-build-simbiology-model确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

manifest.yaml
references/
api-cheatsheet-guidance.md
app-lifecycle-guidance.md
diagram-styling-guidance.md
evacuation-procedure-guidance.md
layout-strategy-guidance.md
pbpk-layout-guidance.md
pk-library-guidance.md
scripts/
addAndPositionCompartment.m
buildLayoutContext.m
checkDiagramLayout.m
computeSafeReactionPosition.m
getModelByUUID.m
isAppOpen.m
lineIntersectsRect.m
loadViaBuilder.m
openLiveBuilder.m
positionAncillaryBlocks.m
queryGridForLine.m
repositionAllReactions.m
saveViaBuilder.m
updateContextBlock.m

详细介绍

构建 SimBiology 模型

用于构建、修改和绘制 SimBiology 模型的 API 参考、辅助函数和模式。适用于所有 MATLAB 环境(桌面、无头、批处理、远程)。图表/布局功能需要 Model Builder 应用,并且仅在用户请求可视化输出时启用。

适用场景

  • 构建或修改 SimBiology 模型(区室、物种、反应、参数、规则、事件、剂量、观测量、变体)
  • 在 Model Builder / Analyzer 应用中打开、保存或加载模型
  • 设计或调整图表布局
  • 关键词:“构建”“创建”“修改”“添加区室/物种/反应”“图表”“布局”

不适用场景

  • 仿真和分析(使用 matlab-simulate-simbiology-model)
  • 参数拟合、群体建模、NCA(使用 matlab-fit-simbiology-model)

必须遵循的规则

1. 先将辅助脚本添加到 MATLAB 路径

每次会话开始时运行:

addpath(fullfile('<WORKSPACE_ROOT>', '.claude', 'skills', 'matlab-build-simbiology-model', 'scripts'));
disp('Helper scripts added to path.')
2. 仅在需要时打开 Builder

默认情况下不要打开 Model Builder。在以下情况下打开:

  • 用户明确请求图表、布局或可视化内容
  • 输入文件是 .sbproj 文件——使用 loadViaBuilder 保留图表布局/样式(sbioloadproject 会丢失这些数据)

即使没有图表,模型也完全可用——只需使用 sbioroot 上的模型对象,即可进行仿真、拟合和分析。

3. 模型构建使用标准 SimBiology API

直接使用 addcompartment、addspecies、addreaction 等函数构建模型。此方法适用于所有环境:桌面、无头、批处理、远程。

model = sbiomodel('MyModel'); disp(model.uuid)
comp = addcompartment(model, 'Central', 1);
addspecies(comp, 'Drug', 100);
addparameter(model, 'ke', 0.1);
rx = addreaction(model, 'Central.Drug -> null');
kl = addkineticlaw(rx, 'MassAction');
kl.ParameterVariableNames = {'ke'};

对于标准 PK 模型(采用标准给药和消除方式的 1 或 2 区室模型),请参考 references/pk-library-guidance.md,了解正确的参数化、命名和规则。无需图表时,直接调用 PKModelDesign。用户请求图表时,按照相同的 PK 库约定手动构建模型,但使用 addAndPositionCompartment 控制布局(参见规则 8b)。

4. 按生物学正向方向编写反应

图表会在产物上绘制箭头,在反应物上绘制普通线条(依据反应字符串的正向方向)。反向编写反应会导致箭头错误,即使动力学等效也一样。

% CORRECT — L and R get plain lines, C gets an arrow
addreaction(model, 'cell.L + cell.R <-> cell.C');

% WRONG — same kinetics but L and R get arrows (they're "products" now)
addreaction(model, 'cell.C <-> cell.L + cell.R');

指南:

  • **结合:**编写 A + B -> C(底物在左侧,复合物在右侧)
  • **降解/消除:**编写 Drug -> null(而非 null -> Drug)
  • **合成:**编写 null -> mRNA(而非 mRNA -> null)
  • **转运:**编写 Source.Drug -> Dest.Drug(源在左侧)
5. 始终为物种和反应作用域参数使用限定名称

始终使用物种和反应作用域参数的限定名称进行引用。如果名称中有任何部分不是有效的 MATLAB 变量名,请在构建限定名称前用方括号括起该部分。

  • 物种:CompartmentName.SpeciesName(例如,Central.Drug、Peripheral.[Drug-bound])
  • 反应作用域参数:ReactionName.ParameterName(例如,Elimination.ke)

限定名称始终恰好只有一级——仅包含直接父区室。在反应字符串中,Body.Central.Drug 这类多级路径无效。这绝不会产生歧义,因为区室名称在整个模型中必须唯一(无论嵌套深度如何,SimBiology 都会强制执行此规则)。因此,Central.Drug 始终足够。

区室命名规则:

  • 名称在整个模型中必须唯一——即使位于不同的嵌套层级,也不能有两个区室同名
  • 如果需要层级式命名,请使用下划线:Body_Central(不要将多个嵌套区室都命名为 Central)
  • 物种名称在同一区室内必须唯一,但可在不同区室中重复(通过 Compartment.Species 消除歧义)
6. 使用现代属性名称(Value、Units、Constant)

SimBiology 对象(物种、区室、参数)共用统一的属性接口。请始终使用现代名称:

现代名称已弃用(切勿使用)适用对象
ValueInitialAmount、Capacity物种、区室、参数
UnitsInitialAmountUnits、CapacityUnits、ValueUnits物种、区室、参数
ConstantConstantAmount、ConstantCapacity、ConstantValue物种、区室、参数
sp.Value = 100;       % NOT sp.InitialAmount
sp.Units = 'milligram';  % NOT sp.InitialAmountUnits
sp.Constant = false;  % NOT sp.ConstantAmount

comp.Value = 1;       % NOT comp.Capacity
comp.Units = 'liter'; % NOT comp.CapacityUnits
comp.Constant = true; % NOT comp.ConstantCapacity

p.Value = 0.1;        % NOT redundant, but never use p.ValueUnits or p.ConstantValue
p.Units = '1/hour';
p.Constant = true;
7. 在运行 sbioreset 前关闭 Builder 和 Analyzer

sbioreset 不会关闭这些应用,导致窗口遗留:

try mb = SimBiology.web.desktophandler.getModelBuilder();
    if ~isempty(mb) && isfield(mb,'webWindow') && isvalid(mb.webWindow), mb.webWindow.close(); end
catch, end
try ma = SimBiology.web.desktophandler.getModelAnalyzer();
    if ~isempty(ma) && isfield(ma,'webWindow') && isvalid(ma.webWindow), ma.webWindow.close(); end
catch, end
pause(1); sbioreset;
8. 图示规则(仅在用户要求绘制图示时适用)

以下规则仅在用户要求绘制图示或布局时适用。 纯模型构建时请跳过所有这些规则。

模型大小限制(前置条件): 布局辅助函数在总区块数(物种 + 反应)超过 400 时会退出。对于大型模型,请跳过自动布局,改用简单的网格定位(将反应放在相连物种的中点)。

a. 使用 addAndPositionCompartment 进行图示布局

构建图示时,请使用 addAndPositionCompartment,而不是直接使用 addcompartment + setBlock,因为它会以原子方式创建、定位并验证每个区室。

% speciesInfo: cell array of structs with .Name, .Value, .Position
speciesInfo = {
    struct('Name', 'Drug', 'Value', 100, 'Position', [40, 30, 50, 16]);
    struct('Name', 'DrugBound', 'Value', 0, 'Position', [140, 30, 100, 16])
};
[comp, sp] = addAndPositionCompartment(model, 'Central', 1, [20, 20, 280, 80], speciesInfo);
% sp is a SimBiology Species ARRAY — index with sp(1), sp(2), NOT sp{1}

b. 图示构建顺序

  1. 首先打开 Builder——只有 Builder 创建图示后,图示才会存在。未执行此步骤时,所有 simbio.diagram.* 调用和 addAndPositionCompartment 都会失败。
  2. 提前规划所有区室的 [x y w h] 位置(至少留出 80 px 间距)
  3. 每次构建一个区室,使用 addAndPositionCompartment
  4. 添加所有参数(包括规则 LHS 目标)、反应、规则、剂量和事件
  5. 执行 repositionAllReactions(model),然后执行 checkDiagramLayout(model)——修复问题,直到违规数为零
  6. 执行 positionAncillaryBlocks(model)——将规则/参数区块以网格形式定位在右侧

c. 相连区室之间留出 80 px 间距

repositionAllReactions 会将区室间反应节点(15×15)放置在这些间隙中。间距不足时,反应线会穿过区室区块。对于有许多共用反应(3 个以上)的区室,请将间距增加到 120 px。

d. 必须在放置后进行验证

放置所有区块后:

repositionAllReactions(model);
results = checkDiagramLayout(model);
if results.nTotal > 0
    for i = 1:numel(model.Reactions)
        pos = computeSafeReactionPosition(model, model.Reactions(i));
        simbio.diagram.setBlock(model.Reactions(i), 'Position', pos);
    end
    results = checkDiagramLayout(model);
end
positionAncillaryBlocks(model);  % must run LAST, after all objects exist

e. 始终使用安全打开模式打开 Builder

调用 simBiologyModelBuilder(model) 前,务必先检查 isAppOpen('builder')。如果 Builder 已打开,请将其关闭,等待 2s 后再重新打开。

if isAppOpen('builder')
    try
        mb = SimBiology.web.desktophandler.getModelBuilder();
        if ~isempty(mb) && isfield(mb, 'webWindow') && isvalid(mb.webWindow)
            mb.webWindow.close();
        end
    catch, end
    pause(2);
end
% If Analyzer is open, it already has a model loaded — open Builder
% without an argument so it picks up the Analyzer's active model.
% Passing a model argument when Analyzer is open can cause conflicts.
if isAppOpen('analyzer')
    simBiologyModelBuilder();
else
    simBiologyModelBuilder(model);
end

f. 切勿为了修改而关闭 Builder

模型句柄位于 sbioroot 上——所有代码都会对实时模型进行操作,并实时更新图示。只有在用户明确要求时才关闭。

辅助函数(scripts/)

模型构建(始终可用)
函数签名用途
getModelByUUIDmodel = getModelByUUID(uuid)按 UUID 查找模型
图表与构建器(仅在用户请求图表/布局时使用)
功能签名用途
addAndPositionCompartment[comp,sp] = addAndPositionCompartment(model,name,cap,compPos,speciesInfo,Name=Value)原子式创建区室和物种并设置位置。**sp 是 Species 数组——使用 sp(1) 索引,而非 sp{1}。**选项:FontWeight("bold")、TextLocation("center")、Padding(20)、AutoExpand(true)、AutoFixPositions(true)
checkDiagramLayoutresults = checkDiagramLayout(model)检查包含关系、线条穿过方块以及重叠
computeSafeReactionPositionpos = computeSafeReactionPosition(model,rxn)计算无交叉的反应节点位置
repositionAllReactionsnFixed = repositionAllReactions(model)批量重新定位所有反应(最多 3 轮)
positionAncillaryBlocksn = positionAncillaryBlocks(model)将规则/参数方块按网格排列在区室右侧
openLiveBuilderopenLiveBuilder(model)使用安全打开模式打开 Builder
isAppOpentf = isAppOpen(appName)检查 Builder/Analyzer 是否已打开
loadViaBuildermodel = loadViaBuilder(filePath)加载 .sbproj 并保留图表
saveViaBuildersaveViaBuilder(filePath)从 Builder 保存并保留图表
lineIntersectsRecthit = lineIntersectsRect(x1,y1,x2,y2,rect)共享几何辅助函数(由布局脚本内部使用)
checkDiagramLayout 输出
results.nTotal        % total violations (must be 0 before presenting)
results.nContainment  % species outside parent compartment
results.nLineThrough  % connection lines through unrelated blocks
results.nOverlap      % blocks <10px apart

API 快速参考

模型
  • sbiomodel(name) — 创建模型;model.uuid — 唯一 ID
  • sbioloadproject('file.sbproj') — 返回以模型名称为字段的 struct;动态提取:
    proj = sbioloadproject('file.sbproj');
    fn = fieldnames(proj);
    model = proj.(fn{1});
    
  • copyobj(model) — 深度克隆(不会复制图表布局);verify(model) — 检查一致性
  • sbioreset — 清除所有模型(先关闭应用!)
区室
  • addcompartment(model, name, value)
  • comp.Value、comp.Constant、comp.Units、model.Compartments
  • **单位一致性:**如果任何组件带有单位,则所有组件都必须带有单位(区室、物种、参数)。缺少单位会在仿真/拟合时导致 'Dimensional analysis failed' 错误。
物种
  • addspecies(comp, name, value)
  • sp.Value、sp.Units、sp.BoundaryCondition、sp.Constant
  • sp.Parent.Name — 父区室;model.Species
参数
  • addparameter(model, name, value) — 作用域为模型
  • addparameter(kineticLaw, name, value) — 作用域为反应
  • p.Value、p.Units、p.Constant、model.Parameters
反应
  • addreaction(model, 'A -> B') — 正向;'A <-> B' — 可逆
  • kl = addkineticlaw(rx, 'MassAction'); kl.ParameterVariableNames = {'k1'}(可逆反应使用 {'kf','kr'})
  • 多区室:'Central.Drug -> Peripheral.Drug'
规则、事件、剂量
  • addrule(model, 'x = expr', ruleType) — 'initialAssignment'、'repeatedAssignment'、'rate'
  • **规则/反应互斥:**作为速率规则或重复赋值规则左侧的物种,不能同时作为反应物或产物出现在反应中。应择一控制其动态。
  • **规则左侧要求:**左侧必须是现有的物种、参数或 Constant = false 的区室。应在创建规则之前创建参数(不要创建规则后再补救——这样可确保用于布局的图表方块已存在):
    p = addparameter(model, 'RO', 0); p.Constant = false;
    addrule(model, 'RO = Complex / (Target + Complex)', 'repeatedAssignment');
    
  • addevent(model, 'trigger', {'action1', 'action2'})
  • **事件动作要求:**事件动作中修改的任何参数都必须设置 Constant = false(参数默认为 true):
    p = sbioselect(model, 'Type', 'parameter', 'Name', 'kgrow');
    p.Constant = false;
    addevent(model, 'Tumor.Cancer < 1e6', {'kgrow = kgrow * 0.5'});
    
  • sbiodose(name, 'schedule') / sbiodose(name, 'repeat')
  • Schedule:.TargetName、.Amount、.Time、.Rate
  • Repeat:.TargetName、.Amount、.StartTime、.Interval、.RepeatCount
  • adddose(model, d) / removedose(model, d)
可观测量与变体
  • addobservable(model, name, expression) — 对逐元素运算使用 ./ 和 .*
  • StatesToLog 注意事项: 如果可观测量引用了一个常量参数(例如,'Drug ./ Vd'),请将该参数添加到 StatesToLog,否则记录结果将为 NaN。只要依赖项存在,可观测量本身就会自动记录(不要将可观测量添加到 StatesToLog — 它只接受物种、参数和区室)。
  • v = addvariant(model, name),然后使用 addcontent(v, {'type','name','prop',val})
  • v.Content、getvariant(model, name)
仿真配置
  • cs = getconfigset(model, 'active')
  • cs.StopTime、cs.SolverType('ode15s'、'ode45'、'sundials')
  • cs.RuntimeOptions.StatesToLog — 'all' 或句柄数组
选择
  • sbioselect(model, 'Type', type, 'Name', name)
  • 对于反应:使用 'Reaction' 属性(而不是 'Name')

核心模式

模型创建(标准 — 无图示)
model = sbiomodel('MyModel');
disp(model.uuid)
comp = addcompartment(model, 'Central', 1);
addspecies(comp, 'Drug', 100);
addparameter(model, 'ke', 0.1);
反应
% MassAction (always use qualified species names)
rx = addreaction(model, 'Central.Drug -> null');
kl = addkineticlaw(rx, 'MassAction');
kl.ParameterVariableNames = {'ke'};

% Custom rate
rx = addreaction(model, 'Central.E + Central.S <-> Central.ES');
rx.ReactionRate = 'kf*Central.E*Central.S - kr*Central.ES';

% Multi-compartment transfer
rx = addreaction(model, 'Central.Drug -> Peripheral.Drug');

% Species with invalid MATLAB variable names
rx = addreaction(model, 'Central.[Drug-bound] -> Central.[Drug-free]');
移除组件
delete(sbioselect(model, 'Type', 'species', 'Name', 'Drug'));
delete(sbioselect(model, 'Type', 'reaction', 'Reaction', 'Drug -> null'));
removedose(model, model.Doses(1));  % doses use removedose, not delete
剂量
% Bolus
d = sbiodose('Dose', 'schedule');
d.TargetName = 'Drug'; d.Amount = 100; d.Time = 0;
adddose(model, d);

% Repeat dose
d = sbiodose('RepeatDose', 'repeat');
d.TargetName = 'Drug'; d.Amount = 50;
d.StartTime = 0; d.Interval = 8; d.RepeatCount = 3;
adddose(model, d);
事件、变体、可观测量
% Event modifying a parameter — mark non-constant first
p = sbioselect(model, 'Type', 'parameter', 'Name', 'ke');
p.Constant = false;
ev = addevent(model, 'time >= 10', {'ke = ke * 2'}); ev.Name = 'EnzymeInduction';

% Event modifying a species (species default Constant=false — no extra step)
ev = addevent(model, 'time >= 10', {'Drug = 50'}); ev.Name = 'RescueDose';

v = addvariant(model, 'HighDose'); addcontent(v, {'parameter','ke','Value',0.5});
obs = addobservable(model, 'DrugConc', 'Drug ./ Central');

保存模型

  • 标准方式: save('mymodel.mat', 'model') / loaded = load('mymodel.mat'); model = loaded.model; 不要使用 sbiosaveproject(已弃用,且需要通过基础工作区进行变通处理)。
  • 带图示(.sbproj): saveViaBuilder('name.sbproj') / loadViaBuilder(path)(需要打开 Builder)
  • 切换模型: 先让用户保存 → 关闭 Builder → pause(2) → simBiologyModelBuilder(newModel)
  • 完整的切换/协调模式请参阅 references/app-lifecycle-guidance.md。

图示基础(仅当用户要求图示/布局时)

坐标系

Position = [x y width height],其中 (x, y) 是左上角。

标准块大小
块类型默认大小备注
物种[50, 16]按名称长度缩放宽度:<=5 个字符 → 50,6-12 个字符 → 100,13 个字符以上 → 130
反应[15, 15]
规则[20, 20]
根据内容设置区室大小
物种数量大小备注
1160 x 100单个物种,居中
2(独立)240 x 170垂直排列
2(链式)400 x 100并排排列
3-5160+n*50 x 100+n*35按内容缩放
6+240+n*50 x 220+n*35按行排列,必要时使用多行

内部边距:四周至少 30 px。

按行放置物种(3 个及以上)

在水平行中均匀分布物种,位置为 y + height/2 - 8,与区室边缘相距 40 px。按名称长度缩放物种宽度: <=5 个字符 → 50,6-12 个字符 → 100,13 个字符以上 → 130。

按连接方向排列物种

当一个区室中的 2 个及以上物种连接到不同的外部区室时,应调整排列顺序,使每个物种朝向其连接方向。这样可以避免连接线穿过同级物种。

  • 水平相邻: 将连接到左侧的物种放在左边缘,将连接到右侧的物种放在右边缘。
  • 垂直堆叠: 将连接到上方/左侧的物种放在上方,将连接到下方/右侧的物种放在下方。
  • 示例: Blood 中有 Neutrophil(向左连接到 Transit3)和 Lymphocyte(向左上连接到 Spleen)。将 Lymphocyte 放在上方、Neutrophil 放在下方,避免连接线交叉。
布局规则

硬性要求:

  1. 块之间不得重叠(区室内的物种除外)
  2. 标签清晰可见 — 不与其他块重叠
  3. 同一层级的区室应水平/垂直对齐
  4. 区室间反应应位于两个区室之外(间隙中)
  5. 连接线不得穿过无关的块
  6. 反应与物种之间至少相距 50 px

优先放置方式: 7. 消除/降解反应应放在其所属区室内(表示过程在本地发生,而非跨越边界)

按模型类型划分的流向
模型类型流向
PKPDPD 位于左上方,PK 位于右下方
代谢模型从上到下
PBPK按循环系统分列
简单 PK从左到右或沿对角线

参考资料

按需加载以获取详细指导:

  • references/layout-strategy-guidance.md — 策略选择、构建前检查清单、7 种方案
  • references/pbpk-layout-guidance.md — PBPK 循环系统和 ACAT 链式布局
  • references/evacuation-procedure-guidance.md — 针对现有模型的 5 阶段重排流程
  • references/api-cheatsheet-guidance.md — 完整的 simbio.diagram API(getBlock、setBlock、lines、clones)
  • references/app-lifecycle-guidance.md — 切换模型、协调 Analyzer
  • references/diagram-styling-guidance.md — 颜色、字体、克隆机制
  • references/pk-library-guidance.md — 用于标准 PK 模型的 PKModelDesign

版权所有 2026 The MathWorks, Inc.


评论

支持 Markdown