Back to skills
SKILL.md
Fba Simulator
ASecurityRun Flux Balance Analysis (FBA) and related constraint-based simulations using COBRApy. Covers standard FBA, parsimonious FBA (pFBA), Flux Variability Analysis (FVA), loopless FBA, gene/reaction knockouts, and carbon source swapping. Outputs flux distributions and CSV files.
- 10 stars
- 0 votes
- 0 copies
- 0 views
- Added September 29, 2026
Security analysis
100/100npx -y skills add FOURTEEN1416/academic-agent-toolkit --skill fba-simulator --agent claude-codeAre you the author of Fba Simulator?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/fourteen1416-fba-simulator)---
name: fba-simulator
description: >
Run Flux Balance Analysis (FBA) and related constraint-based simulations
using COBRApy. Covers standard FBA, parsimonious FBA (pFBA), Flux
Variability Analysis (FVA), loopless FBA, gene/reaction knockouts, and
carbon source swapping. Outputs flux distributions and CSV files.
metadata:
category: domain
trigger-keywords: "metabolic,FBA,pFBA,FVA,Flux Balance Analysis,COBRApy,knockout,carbon source,medium swap,flux distribution,growth rate"
applicable-stages: "9,10,11,12,13,14,15"
priority: "1"
---
## Overview
The `fba-simulator` skill executes constraint-based metabolic simulations on
a validated COBRApy model. FBA solves a linear program to find the flux
distribution that maximizes (or minimizes) the objective function subject to
stoichiometric and thermodynamic constraints.
This skill sits between model construction (`gsmm-builder`) and biological
interpretation (`flux-analyzer`). All simulations are non-destructive: COBRApy
context managers restore model state after each perturbation.
---
## Workflow
### Step 1 — Load Validated Model
```python
import cobra
import cobra.io
import cobra.flux_analysis
import pandas as pd
model = cobra.io.load_json_model("my_model.json")
print(f"Model: {model.id} Solver: {model.solver}")
```
### Step 2 — Standard FBA
FBA maximizes the objective (typically biomass) subject to stoichiometric
steady-state constraints: `S·v = 0`, `lb ≤ v ≤ ub`.
```python
# Run FBA
solution = model.optimize()
print(f"Status : {solution.status}")
print(f"Growth rate : {solution.objective_value:.4f} h^-1")
print(f"Glucose uptake : "
f"{solution.fluxes['EX_glc__D_e']:.4f} mmol/gDW/h")
print(f"O2 uptake : "
f"{solution.fluxes.get('EX_o2_e', 0):.4f} mmol/gDW/h")
print(f"Acetate sec. : "
f"{solution.fluxes.get('EX_ac_e', 0):.4f} mmol/gDW/h")
# Save full flux distribution
solution.fluxes.to_csv("fba_fluxes.csv", header=["flux_mmol_gDW_h"])
```
### Step 3 — Parsimonious FBA (pFBA)
pFBA first maximizes growth, then minimizes total absolute flux, producing
the most "economical" solution consistent with maximum growth. This avoids
biologically unrealistic high-flux split cycles.
```python
pfba_solution = cobra.flux_analysis.pfba(model)
print(f"pFBA growth rate : {pfba_solution.objective_value:.4f} h^-1")
print(f"Total flux norm : {pfba_solution.fluxes.abs().sum():.2f}")
pfba_solution.fluxes.to_csv("pfba_fluxes.csv", header=["flux_mmol_gDW_h"])
```
### Step 4 — Flux Variability Analysis (FVA)
FVA computes the minimum and maximum flux each reaction can carry while
maintaining at least `fraction_of_optimum` of the maximum growth rate. This
reveals which fluxes are uniquely determined vs. flexible.
```python
from cobra.flux_analysis import flux_variability_analysis
# FVA at 90% of maximum growth
fva_result = flux_variability_analysis(
model,
fraction_of_optimum=0.90,
processes=4, # parallel workers
)
# fva_result is a DataFrame with columns "minimum" and "maximum"
print(fva_result.head(10))
# Identify rigidly constrained reactions (min ≈ max)
TOLERANCE = 1e-6
rigid = fva_result[
(fva_result["maximum"] - fva_result["minimum"]).abs() < TOLERANCE
]
print(f"\nRigid reactions (min=max): {len(rigid)}")
fva_result.to_csv("fva_result.csv")
```
### Step 5 — Loopless FBA
Standard FBA may route flux through thermodynamically infeasible energy-
generating cycles. Loopless FBA enforces thermodynamic feasibility.
```python
loopless_sol = cobra.flux_analysis.loopless_solution(model)
print(f"Loopless growth : {loopless_sol.objective_value:.4f} h^-1")
loopless_sol.fluxes.to_csv("loopless_fluxes.csv",
header=["flux_mmol_gDW_h"])
```
### Step 6 — Gene Knockout Simulations
```python
# Single gene knockout (context manager — model is restored after)
gene_id = "b0720" # pgi in E. coli iJO1366
with model:
model.genes.get_by_id(gene_id).knock_out()
ko_solution = model.optimize()
print(f"KO {gene_id} growth: {ko_solution.objective_value:.4f} h^-1")
# Batch single gene deletions
from cobra.flux_analysis import single_gene_deletion
deletion_results = single_gene_deletion(model)
# Returns DataFrame: index = frozenset({gene_id}), columns = [growth, status]
deletion_results.to_csv("gene_deletions.csv")
# Essential genes: growth < 5% of wild-type
wt_growth = model.optimize().objective_value
essential = deletion_results[
deletion_results["growth"] < 0.05 * wt_growth
]
print(f"\nEssential genes: {len(essential)}")
print(essential.head())
```
### Step 7 — Reaction Knockout Simulations
```python
from cobra.flux_analysis import single_reaction_deletion
rxn_deletion_results = single_reaction_deletion(model)
rxn_deletion_results.to_csv("reaction_deletions.csv")
essential_rxns = rxn_deletion_results[
rxn_deletion_results["growth"] < 0.05 * wt_growth
]
print(f"Essential reactions: {len(essential_rxns)}")
```
### Step 8 — Carbon Source Swapping
```python
CARBON_SOURCES = {
"glucose": ("EX_glc__D_e", -10.0),
"fructose": ("EX_fru_e", -10.0),
"acetate": ("EX_ac_e", -10.0),
"glycerol": ("EX_glyc_e", -10.0),
"succinate": ("EX_succ_e", -10.0),
}
results = []
for carbon, (rxn_id, bound) in CARBON_SOURCES.items():
with model:
# Close all carbon exchange reactions first
for r in model.exchanges:
if r.lower_bound < 0 and r.id != "EX_o2_e":
r.lower_bound = 0.0
# Open the target carbon source
if rxn_id in model.reactions:
model.reactions.get_by_id(rxn_id).lower_bound = bound
sol = model.optimize()
results.append({
"carbon_source": carbon,
"growth_rate": sol.objective_value,
"status": sol.status,
})
else:
results.append({
"carbon_source": carbon,
"growth_rate": None,
"status": "reaction_not_in_model",
})
carbon_df = pd.DataFrame(results)
print(carbon_df)
carbon_df.to_csv("carbon_source_comparison.csv", index=False)
```
### Step 9 — Aggregate and Save Results
```python
summary = {
"model_id": model.id,
"wt_growth_fba": wt_growth,
"wt_growth_pfba": pfba_solution.objective_value,
"wt_growth_loopless": loopless_sol.objective_value,
"n_essential_genes": len(essential),
"n_essential_reactions": len(essential_rxns),
}
import json
with open("simulation_summary.json", "w") as f:
json.dump(summary, f, indent=2)
print("Summary written to simulation_summary.json")
```
---
## Key Conventions
| Parameter | Recommended Value | Rationale |
|---|---|---|
| `fraction_of_optimum` (FVA) | 0.9 | 10% growth slack — realistic variability |
| Essentiality threshold | growth < 5% WT | Standard in metabolic engineering |
| pFBA norm | L1 (sum abs fluxes) | COBRApy default; correlates with enzyme cost |
| Loopless FBA | Use for publication | Standard FBA may inflate central metabolism |
| `processes` (FVA) | 4 or CPU count | Scales near-linearly; avoid >8 for small models |
### Output File Conventions
| File | Content |
|---|---|
| `fba_fluxes.csv` | Standard FBA flux vector |
| `pfba_fluxes.csv` | pFBA flux vector (minimum total flux) |
| `fva_result.csv` | FVA minimum/maximum per reaction |
| `loopless_fluxes.csv` | Loopless-constrained flux vector |
| `gene_deletions.csv` | Growth rate for each single gene KO |
| `reaction_deletions.csv` | Growth rate for each single reaction KO |
| `carbon_source_comparison.csv` | Growth across different carbon sources |
| `simulation_summary.json` | Scalar summary of all simulation runs |
### Common Failure Modes
- **`solution.status = "infeasible"`**: medium is too restrictive or objective
reaction bounds are wrong. Run `gsmm-validator` first.
- **Negative growth in pFBA**: can occur if `cobra.flux_analysis.pfba` is
called on an infeasible model — always check `model.optimize()` first.
- **FVA hangs**: reduce `processes` or set `loopless=False`; large models
(>10,000 reactions) may require HPC clusters.
- **Carbon source absent from model**: check BIGG ID spelling carefully;
use `model.reactions.query("EX_")` to list available exchanges.
Attribution
Comments
Loading comments…