Skip to content
Back to skills

Fba Simulator

ASecurity

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.

  • 10 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 29, 2026
ai-agentspythongoreact

Security analysis

A100/100

Scanned September 29, 2026

npx -y skills add FOURTEEN1416/academic-agent-toolkit --skill fba-simulator --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Fba Simulator?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Fba Simulator
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/fourteen1416-fba-simulator/badge)](https://www.skillsdirectory.com/skills/fourteen1416-fba-simulator)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
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

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…