{"id":49563190,"url":"https://github.com/madsondeluna/bilbo","last_synced_at":"2026-05-03T10:47:16.474Z","repository":{"id":354934437,"uuid":"1225766726","full_name":"madsondeluna/bilbo","owner":"madsondeluna","description":"BILBO is a command-line tool for building lipid bilayer membrane models intended for preparation of molecular dynamics simulations. ","archived":false,"fork":false,"pushed_at":"2026-05-03T04:28:58.000Z","size":4953,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-03T10:47:15.189Z","etag":null,"topics":["bioinformatics","cli-tool","membrane","parametrization","structural-biology"],"latest_commit_sha":null,"homepage":"https://madsondeluna.com","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/madsondeluna.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-30T16:05:54.000Z","updated_at":"2026-05-03T04:29:02.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/madsondeluna/bilbo","commit_stats":null,"previous_names":["madsondeluna/bilbo"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/madsondeluna/bilbo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madsondeluna%2Fbilbo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madsondeluna%2Fbilbo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madsondeluna%2Fbilbo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madsondeluna%2Fbilbo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/madsondeluna","download_url":"https://codeload.github.com/madsondeluna/bilbo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madsondeluna%2Fbilbo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32566444,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T06:36:36.687Z","status":"ssl_error","status_checked_at":"2026-05-03T06:36:09.306Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bioinformatics","cli-tool","membrane","parametrization","structural-biology"],"created_at":"2026-05-03T10:47:15.907Z","updated_at":"2026-05-03T10:47:16.464Z","avatar_url":"https://github.com/madsondeluna.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# BILBO: Bilayer Lipid Builder and Organizer\n\n```\n  · · · · · · · · · · · · · · · · · · · · · · ·\n  | | | | | | | | | | | | | | | | | | | | | | |\n  | | | | | | | | | | | | | | | | | | | | | | |\n  | | | | | | | | | | | | | | | | | | | | | | |\n  | | | | | | | | | | | | | | | | | | | | | | |\n\n                  BILBO  v0.1.0\n     Bilayer  Lipid  Builder and  Organizer\n\n  | | | | | | | | | | | | | | | | | | | | | | |\n  | | | | | | | | | | | | | | | | | | | | | | |\n  | | | | | | | | | | | | | | | | | | | | | | |\n  | | | | | | | | | | | | | | | | | | | | | | |\n  · · · · · · · · · · · · · · · · · · · · · · ·\n```\n\nBILBO builds flat lipid bilayer membranes from all-atom PDB templates and places proteins or peptides on or inside them. The output is a starting-point structure for molecular dynamics (MD) preparation. BILBO does not run energy minimization, assign force field parameters, or solvate the system.\n\n## Requirements\n\n- Python 3.11 or newer\n- [uv](https://docs.astral.sh/uv/) (recommended) or pip\n\n## Installation\n\n```bash\ngit clone \u003crepository-url\u003e\ncd bilbo\nuv sync\nuv pip install -e .\n```\n\nVerify the installation:\n\n```bash\nbilbo --version\nbilbo drytest\n```\n\nFor development (adds pytest, ruff, mypy):\n\n```bash\npip install -e \".[dev]\"\n```\n\n## How BILBO works\n\nBuilding a membrane in BILBO takes two inputs:\n\n1. **Lipid PDB templates**: one all-atom PDB file per lipid species. BILBO uses the 3D coordinates in each file as the structural template for that species. You supply these files; BILBO does not generate them.\n2. **Counts per leaflet**: how many of each species go in the upper leaflet and the lower leaflet.\n\nBILBO then:\n\n- Arranges the lipids on a 2D rectangular grid, one cell per lipid.\n- Gives each lipid a random azimuthal rotation around the membrane normal (Z axis).\n- Stacks the two leaflets back-to-back to form the bilayer, with the tails pointing toward the center.\n- Writes the coordinates as a PDB file, a CSV of lateral positions, and a JSON build report.\n\nThe result is an unminimized structure. It will have steric clashes and is not suitable for simulation without energy minimization. This is normal and expected: BILBO provides a starting configuration, not an equilibrated system.\n\n### Where to get lipid PDB templates\n\nThe most common source is [CHARMM-GUI](https://charmm-gui.org) (Membrane Builder, \"Download single lipid\" option). Each downloaded file provides one lipid species in the CHARMM36 force field. Alternatively, use any all-atom lipid structure from the PDB, Lipid21 (AMBER), or Slipids (GROMOS). The filename stem becomes the lipid ID: `POPE.pdb` is loaded as `POPE`.\n\nBILBO rejects a template if it has fewer than 10 ATOM/HETATM records or if its Z-coordinate extent is outside 5-60 Å (too flat or implausibly long for a single lipid).\n\n## Quick start\n\n```bash\n# Build a symmetric bilayer with two lipid species\nbilbo membrane build \\\n  --upper-pdb POPE.pdb:50 \\\n  --upper-pdb POPG.pdb:14 \\\n  --seed 42 \\\n  --output builds/my_membrane\n\n# Place a peptide on the upper leaflet surface\nbilbo membrane place builds/my_membrane \\\n  --peptide MELITTIN.pdb \\\n  --leaflet upper \\\n  --orientation parallel \\\n  --x 2.8 --y 2.8 \\\n  --depth 0.0 \\\n  --output builds/my_membrane\n\n# Visualize\npymol builds/my_membrane/system.pdb\n```\n\nExpected terminal output after `membrane build`:\n\n```\nAPL-weighted grid spacing: 0.796 nm\nAll-atom preview: builds/my_membrane/preview_allatom.pdb (8064 atoms)\nBuild complete (symmetric): builds/my_membrane\n  upper: 64 lipids  lower: 64 lipids\n```\n\nExpected terminal output after `membrane place`:\n\n```\nSystem PDB: builds/my_membrane/system.pdb (8072 atoms)\nPeptide 'MELITTIN' placed in builds/my_membrane\n```\n\n## bilbo membrane build\n\nBuilds a bilayer directly from PDB files. No database or library is required.\n\n```\nbilbo membrane build [OPTIONS]\n```\n\n| Flag | Type | Default | Description |\n|---|---|---|---|\n| `--upper-pdb FILE.pdb:N` | TEXT | required | One lipid species for the upper leaflet with count N. Repeat for each species. |\n| `--lower-pdb FILE.pdb:N` | TEXT | mirrors upper | One lipid species for the lower leaflet. If omitted, the lower leaflet is identical to the upper. |\n| `--seed` | INTEGER | 42 | Random seed for grid placement and per-lipid azimuthal rotation. Same seed reproduces an identical structure. |\n| `--sorting` | TEXT | random | Lipid arrangement: `random` (uniform random placement), `domain_enriched` (same species grouped in contiguous blocks), or `stripe` (alternating horizontal bands, A-B-A-B). |\n| `--spacing` | FLOAT | APL-weighted | Lateral distance between lipid centers in nm. Computed automatically from composition when omitted. |\n| `--bilayer-gap` | FLOAT | 2.5 | Total gap at the bilayer center between tail terminals of opposing leaflets, in Angstroms. |\n| `--output` | PATH | required | Output directory. Created if it does not exist. |\n\n**Output files:**\n\n| File | Description |\n|---|---|\n| `preview_allatom.pdb` | All-atom bilayer (visual inspection only, not minimized) |\n| `upper_leaflet.csv` | x, y positions (nm) and lipid ID for each lipid in the upper leaflet |\n| `lower_leaflet.csv` | x, y positions (nm) and lipid ID for each lipid in the lower leaflet |\n| `build_report.json` | Build parameters, realized counts, SHA-256 hashes of templates |\n| `manifest.json` | List of all files written |\n\n**About `--bilayer-gap`:** this parameter sets the vacuum gap between the terminal tail atoms of the two opposing leaflets before minimization. A value of 2.5 Å (default) gives a compact starting structure. Larger values (up to 10 Å) increase separation and reduce initial clashes at the bilayer center. The final equilibrated bilayer thickness is determined by the simulation force field, not by this parameter.\n\n**About `--sorting`:** `random` distributes species uniformly across the grid, which is the physically correct starting configuration for a well-mixed bilayer. `domain_enriched` groups identical species in blocks, suitable as a starting point for domain segregation studies. `stripe` arranges species in alternating horizontal bands (A-B-A-B row pattern), useful for Lo/Ld phase separation studies where multiple domain interfaces are desired.\n\n## bilbo membrane place\n\nPlaces a protein or peptide on or inside an existing bilayer built with `membrane build`. The molecule is anchored to the actual headgroup surface extracted from `preview_allatom.pdb`, not to a hard-coded Z value.\n\n```\nbilbo membrane place BUILD_DIR [OPTIONS]\n```\n\n| Flag | Type | Default | Description |\n|---|---|---|---|\n| `BUILD_DIR` | PATH | required | Directory from `membrane build`. Must contain `build_report.json` and `preview_allatom.pdb`. |\n| `--peptide` | PATH | required* | PDB file of the molecule to place. |\n| `--placement` | PATH | | YAML file with a full placement descriptor. Overrides all geometric flags. |\n| `--leaflet` | TEXT | upper | Target leaflet: `upper`, `lower`, `center`, or `transmembrane`. |\n| `--orientation` | TEXT | parallel | Orientation of the molecular principal axis: `parallel` (along X), `perpendicular` (along Z), `tilted`, or `transmembrane`. |\n| `--x` | FLOAT | 0.0 | Lateral position in nm along X. |\n| `--y` | FLOAT | 0.0 | Lateral position in nm along Y. |\n| `--depth` | FLOAT | 0.0 | Insertion depth in nm. `0.0` places the bottommost atom at the headgroup surface. Positive values push the molecule deeper into the membrane; negative values lift it above the surface. |\n| `--rotation-deg` | FLOAT | 0.0 | In-plane rotation around Z in degrees, applied after axis alignment. |\n| `--tilt-deg` | FLOAT | 0.0 | Tilt angle in degrees away from the membrane plane. Only applies when `--orientation tilted`. |\n| `--azimuth-deg` | FLOAT | 0.0 | Rotation around the molecular principal axis in degrees. |\n| `--allow-overlap` | flag | off | Suppress the collision warning when the molecule overlaps membrane atoms. |\n| `--output` | PATH | BUILD_DIR | Output directory. |\n\n*Required unless `--placement` is given.\n\n**Output files:**\n\n| File | Description |\n|---|---|\n| `system.pdb` | Combined bilayer and placed molecule |\n| `geometry_report.json` | Translation vector, rotation matrix, tilt/rotation angles, collision count |\n| `build_report.json` | Updated with placement metadata |\n\n**How orientations work:**\n\n- `parallel`: the molecular principal axis (longest dimension, computed by SVD) is aligned with X. The molecule lies flat on the membrane surface. Use this for amphipathic helices, beta-sheets, or any molecule that binds laterally.\n- `perpendicular`: the principal axis is aligned with Z. The molecule stands upright, normal to the membrane. Use this for single-pass transmembrane helices or rod-shaped molecules.\n- `tilted`: the principal axis is first aligned with X, then tilted by `--tilt-deg` toward Z. Use this for helices that insert at an angle.\n- `transmembrane`: equivalent to `perpendicular`, intended for full transmembrane proteins.\n\n**How depth works:**\n\n`--depth 0.0` places the bottommost atom of the rotated molecule exactly at the headgroup surface ($z_\\text{max}$ of upper-leaflet atoms in `preview_allatom.pdb`). Positive depth values push the molecule downward by that many nanometers, into the hydrophobic core. A typical shallow amphipathic helix uses `--depth 0.0` to `--depth 0.3`. A deeply inserted helix may use `--depth 1.0` or more.\n\n**Placing multiple copies:**\n\nEach `membrane place` invocation adds one molecule. To place multiple copies, run the command once per copy with different `--x` and `--y` values pointing to the same `BUILD_DIR`. Each run overwrites `system.pdb` with all placed molecules accumulated so far and appends a record to `build_report.json`.\n\n## Examples\n\n### Example 1: single-lipid pure DPPC membrane\n\nThe simplest possible case: one species, symmetric bilayer, 128 lipids per leaflet.\n\n```bash\nbilbo membrane build \\\n  --upper-pdb DPPC.pdb:128 \\\n  --seed 42 \\\n  --output builds/dppc_pure\n```\n\nThe lower leaflet is automatically set to 128 DPPC molecules, mirroring the upper. Grid spacing is computed from the DPPC reference APL of 64.3 Å², giving $d = \\sqrt{64.3}/10 = 0.802$ nm.\n\n```\nAPL-weighted grid spacing: 0.802 nm\nAll-atom preview: builds/dppc_pure/preview_allatom.pdb (46208 atoms)\nBuild complete (symmetric): builds/dppc_pure\n  upper: 128 lipids  lower: 128 lipids\n```\n\n### Example 2: four-species asymmetric bilayer\n\nAn asymmetric bilayer has different compositions in the two leaflets. This is biologically common: for example, in eukaryotic plasma membranes the outer leaflet is enriched in PC and sphingomyelin while the inner leaflet contains PE, PS, and PI. Each species is specified with its own `--upper-pdb` or `--lower-pdb` flag.\n\n```bash\nbilbo membrane build \\\n  --upper-pdb POPC.pdb:50 \\\n  --upper-pdb POPE.pdb:20 \\\n  --upper-pdb DPPC.pdb:20 \\\n  --upper-pdb CHOL.pdb:10 \\\n  --lower-pdb POPE.pdb:40 \\\n  --lower-pdb POPS.pdb:25 \\\n  --lower-pdb POPG.pdb:20 \\\n  --lower-pdb CL.pdb:15 \\\n  --seed 42 \\\n  --bilayer-gap 1.0 \\\n  --output builds/asymmetric_euk\n```\n\nBecause the two leaflets have different mean APL values, BILBO will report a projected-area mismatch warning in the terminal if the difference exceeds 10%. This is informational: it means the two leaflets have different lateral packing densities, which generates curvature stress in the unminimized structure and will relax during equilibration.\n\n### Example 3: membrane with multiple peptide copies at controlled positions and depths\n\nThis example sets up a study of three copies of an antimicrobial peptide (melittin) at different lateral positions, insertion depths, and in-plane rotations.\n\n```bash\n# Step 1: build the membrane\nbilbo membrane build \\\n  --upper-pdb POPE.pdb:45 \\\n  --upper-pdb POPG.pdb:13 \\\n  --upper-pdb CL.pdb:6 \\\n  --seed 42 \\\n  --bilayer-gap 1.0 \\\n  --output builds/melittin_study\n\n# Step 2: surface-bound copy at the center of the box\nbilbo membrane place builds/melittin_study \\\n  --peptide MELITTIN.pdb \\\n  --leaflet upper \\\n  --orientation parallel \\\n  --x 3.2 --y 3.2 \\\n  --depth 0.0 \\\n  --rotation-deg 0 \\\n  --output builds/melittin_study\n\n# Step 3: second copy shifted laterally, rotated 120 degrees\nbilbo membrane place builds/melittin_study \\\n  --peptide MELITTIN.pdb \\\n  --leaflet upper \\\n  --orientation parallel \\\n  --x 1.5 --y 1.5 \\\n  --depth 0.0 \\\n  --rotation-deg 120 \\\n  --output builds/melittin_study\n\n# Step 4: third copy inserted 0.5 nm into the hydrophobic core\nbilbo membrane place builds/melittin_study \\\n  --peptide MELITTIN.pdb \\\n  --leaflet upper \\\n  --orientation parallel \\\n  --x 5.0 --y 2.0 \\\n  --depth 0.5 \\\n  --rotation-deg 240 \\\n  --output builds/melittin_study\n```\n\nAfter step 4, `builds/melittin_study/system.pdb` contains the bilayer with all three copies. `build_report.json` has three `peptide_placements` entries, each recording the translation vector, rotation matrix, depth, and collision count with membrane atoms.\n\n### Example 4: transmembrane helix\n\nPlace a helix perpendicular to the membrane, spanning from the lower to the upper leaflet. Use `--leaflet transmembrane` with `--orientation transmembrane` and set depth to position the helix at the center of the bilayer.\n\n```bash\nbilbo membrane build \\\n  --upper-pdb POPC.pdb:64 \\\n  --seed 42 \\\n  --output builds/tm_study\n\nbilbo membrane place builds/tm_study \\\n  --peptide TM_HELIX.pdb \\\n  --leaflet transmembrane \\\n  --orientation transmembrane \\\n  --x 3.0 --y 3.0 \\\n  --depth 0.0 \\\n  --output builds/tm_study\n```\n\n## Complete workflow with visualization\n\n```bash\n# 1. Build the membrane\nbilbo membrane build \\\n  --upper-pdb POPE.pdb:45 \\\n  --upper-pdb POPG.pdb:13 \\\n  --upper-pdb CL.pdb:6 \\\n  --seed 42 \\\n  --bilayer-gap 1.0 \\\n  --output builds/ecoli\n\n# 2. Check the layout before placing anything\nbilbo view leaflet-map builds/ecoli\nbilbo view composition builds/ecoli\n\n# 3. Place a peptide\nbilbo membrane place builds/ecoli \\\n  --peptide MELITTIN.pdb \\\n  --leaflet upper \\\n  --orientation parallel \\\n  --x 3.0 --y 3.0 \\\n  --depth 0.0 \\\n  --output builds/ecoli\n\n# 4. Open in PyMOL\npymol builds/ecoli/system.pdb\n```\n\nPyMOL commands for a quick colored view by lipid species:\n\n```python\nhide everything\nshow spheres, resn POPE or resn POPG or resn CL\ncolor orange, resn POPE\ncolor red, resn POPG\ncolor marine, resn CL\nshow surface, chain P\ncolor lime, chain P\nzoom all\n```\n\nAfter visual inspection, the typical MD preparation pipeline is:\n\n1. Energy minimization (e.g. `gmx mdrun -maxh 1 -until 5000`).\n2. Solvation and counterion addition (`gmx solvate`, `gmx genion`).\n3. NPT equilibration with position restraints on lipid headgroups.\n4. Production simulation.\n\n## Web interface\n\nBILBO ships a browser-based interface that runs the same build pipeline as the CLI but requires no terminal commands. It is useful for exploring compositions interactively before committing to a script.\n\n### Running locally\n\n```bash\npip install -e \".[web]\"\nuvicorn web.app:app --host 0.0.0.0 --port 8000\n```\n\nOpen `http://localhost:8000` in a browser.\n\n### Deploying on Render\n\nThe repository includes a `render.yaml` that configures a Docker-based web service.\n\n1. In the Render dashboard, click **New + \u003e Web Service**.\n2. Select **Build and deploy from a Git repository** and connect the `bilbo` repository.\n3. Render detects `render.yaml` automatically and fills in all fields. Confirm: runtime Docker, plan Free, region Oregon.\n4. Click **Create Web Service**. The first build takes 3-5 minutes. The service is ready when the logs show `Your service is live`.\n\nThe deployed URL has the form `https://\u003cservice-name\u003e.onrender.com`. To change it: open the service in the Render dashboard, go to **Settings**, and edit the **Service Name** field. The new name must be globally unique across Render. For a custom domain (e.g. `bilbo.yourdomain.com`), add it under **Custom Domain** and point a CNAME record in your DNS to the current `onrender.com` address.\n\nSubsequent deploys are automatic: every push to `main` triggers a new build.\n\n### Inputs\n\n**Leaflet composition**\n\nAdd one row per lipid species. Each row has three fields:\n\n- **Library select**: pick a lipid ID from the bundled library (POPE, POPC, POPG, POPS, DPPC, DPPE, DPPG, DPPS, CHOL, CHL1, CL). BILBO uses its own PDB template for the selected species.\n- **Upload PDB**: alternatively, upload a custom PDB template. The filename stem becomes the lipid ID.\n- **Count**: number of molecules for that species in that leaflet.\n\nThe **Symmetric** checkbox copies the upper leaflet composition to the lower leaflet automatically. Uncheck it to define an asymmetric bilayer.\n\n**Build settings**\n\n| Field | Default | Description |\n|---|---|---|\n| Seed | 42 | Random seed for grid placement and azimuthal rotation. |\n| Bilayer gap (A) | 2.5 | Vacuum gap at the bilayer center between opposing tail terminals. |\n| Sorting | random | `random`: uniform placement. `domain_enriched`: species grouped in blocks. `stripe`: alternating horizontal bands (A-B-A-B). |\n| Tilt angle (deg) | 0 | Global tilt of each lipid away from the membrane normal. 0 = upright. Use 10-30 for gel-phase or tilt-defect studies. Each lipid receives a random azimuthal tilt direction. |\n| Spacing (nm) | auto | Grid spacing. Leave blank to compute automatically from APL-weighted composition. |\n| Box side (nm) | auto | X and Y box dimensions. Leave blank to compute from the grid. |\n\n**Peptide/protein (optional)**\n\nUpload a PDB file to place a molecule on or inside the membrane. Options:\n\n| Field | Default | Description |\n|---|---|---|\n| Leaflet | upper | Target leaflet: `upper`, `lower`, `center`, or `transmembrane`. |\n| Orientation | parallel | Axis alignment: `parallel` (along X), `perpendicular` (along Z), `tilted`, `transmembrane`. |\n| X / Y (nm) | center | Lateral position. Defaults to box center for a single replica. |\n| Depth (nm) | 0.0 | Insertion depth from the headgroup surface. Positive values push into the hydrophobic core. |\n| Rotation (deg) | 0 | In-plane rotation around Z after axis alignment. |\n| Replicas | 1 | Number of copies to place. Multiple copies are distributed randomly in XY. |\n\n**Solvation (optional)**\n\nCheck **Solvate** to add explicit water and bulk ions around the membrane. Options:\n\n| Field | Default | Description |\n|---|---|---|\n| Water model | TIP3P | Water geometry: TIP3P, SPC, SPC/E, or TIP4P. |\n| Box Z (nm) | auto | Total simulation box height. Leave blank to use the default water layer thickness of 3 nm per side. Minimum enforced: membrane thickness + 2 nm per side. |\n| Ion conc. (mM) | 150 | NaCl concentration for bulk solvation ions (Na+ and Cl-). |\n| Peptide charge | 0 | Net charge of the placed peptide, used to compute the neutralizing ion count. Upload a peptide PDB to calculate this automatically. |\n\n**Counter-ions at headgroup (optional)**\n\nThis checkbox adds cation counter-ions positioned at the phosphate plane of anionic lipids. The ion count is computed automatically from the anionic lipid composition: for each anionic lipid (POPG, POPS, CL, etc.) the stoichiometric number of cations needed to neutralize the leaflet charge is calculated. The checkbox is disabled when the composition contains no anionic lipids.\n\nAvailable ions: Na+, Ca2+, Mg2+, K+.\n\n### Outputs\n\nAfter clicking **Build membrane**, BILBO returns:\n\n- **Download PDB**: all-atom bilayer, with optional peptide and water/ions. Input for `gmx editconf` and subsequent GROMACS steps.\n- **Download GRO**: the same structure in GROMACS GRO format, with coordinates in nm and the periodic box dimensions on the last line. Use this file directly with `gmx grompp` without running `gmx editconf`.\n- **Download topology**: a `topol.top` skeleton with `#include` directives for each lipid species. Edit the force field path and verify lipid `.itp` includes before running `gmx grompp`.\n\nA build summary panel shows atom counts, water molecule count, ion counts, and any warnings (e.g., box Z too small, leaflet area mismatch).\n\n### Force field and topology notes\n\nThe standard GROMACS installation does not include individual lipid `.itp` files. You must obtain them separately:\n\n- **CHARMM36**: download `charmm36-jul2022.ff.tgz` from [mackerell.umaryland.edu](http://mackerell.umaryland.edu/charmm_ff.shtml). The lipid parameters are in `charmm36-jul2022.ff/`. Copy the `.ff` directory into your simulation folder alongside `topol.top`.\n- **Lipid21 (AMBER)**: parameters ship with AmberTools.\n- **Slipids**: download from [liphop.fos.su.se](http://www.fos.su.se/~sasha/SLipids/).\n\nMDP files (energy minimization, NVT, NPT, production) are not generated by BILBO. Prepare them according to your force field and simulation conditions.\n\n### Typical GROMACS pipeline after BILBO\n\n```bash\n# 1. Convert PDB to GRO (skip if you downloaded the GRO directly from the web interface)\ngmx editconf -f system.pdb -o system.gro -box 8.0 8.0 15.0\n\n# 2. Solvate (skip if you used BILBO solvation)\ngmx solvate -cp system.gro -cs spc216.gro -o solvated.gro -p topol.top\n\n# 3. Add ions to neutralize\ngmx genion -s ions.tpr -o ionized.gro -p topol.top -pname NA -nname CL -neutral\n\n# 4. Energy minimization\ngmx grompp -f em.mdp -c ionized.gro -p topol.top -o em.tpr\ngmx mdrun -v -deffnm em\n\n# 5. NVT equilibration with position restraints\ngmx grompp -f nvt.mdp -c em.gro -r em.gro -p topol.top -o nvt.tpr\ngmx mdrun -deffnm nvt\n\n# 6. NPT equilibration\ngmx grompp -f npt.mdp -c nvt.gro -r nvt.gro -t nvt.cpt -p topol.top -o npt.tpr\ngmx mdrun -deffnm npt\n\n# 7. Production\ngmx grompp -f md.mdp -c npt.gro -t npt.cpt -p topol.top -o md.tpr\ngmx mdrun -deffnm md\n```\n\n## Secondary build modes\n\n`bilbo membrane build` requires no library. The two modes below use a local SQLite database of lipid metadata and preset compositions.\n\n### bilbo membrane compose\n\nSpecify composition as percentages rather than absolute counts. BILBO converts percentages to integer counts using the largest-remainder method (see Scientific background). Lipid IDs must be registered with `bilbo lipid add`.\n\n```bash\nbilbo membrane compose \\\n  --upper POPE:70,POPG:20,CL:10 \\\n  --lipids-per-leaflet 64 \\\n  --output builds/ecoli_compose\n```\n\nAsymmetric example:\n\n```bash\nbilbo membrane compose \\\n  --upper POPE:70,POPG:20,CL:10 \\\n  --lower POPE:50,POPG:30,CL:20 \\\n  --lipids-per-leaflet 64 \\\n  --output builds/ecoli_asym\n```\n\n| Flag | Type | Default | Description |\n|---|---|---|---|\n| `--upper` | TEXT | required | Upper leaflet as `LIPID:PCT,...`. Percentages normalize to 100. |\n| `--lower` | TEXT | mirrors upper | Lower leaflet composition. |\n| `--force-field` | TEXT | charmm36 | Force field name for topology output. |\n| `--lipids-per-leaflet` | INTEGER | required | Lipids per leaflet. |\n| `--seed` | INTEGER | 42 | Random seed. |\n| `--spacing` | FLOAT | APL-weighted | Grid spacing in nm. |\n| `--bilayer-gap` | FLOAT | 6.0 | Inter-leaflet gap in Angstroms. |\n| `--allatom-dir` | PATH | data/examples/charmm_gui/ | Directory with PDB templates. |\n| `--output` | PATH | required | Output directory. |\n\n### bilbo membrane build-preset\n\nBuild from a named preset stored in the library. Produces a `topol.top` GROMACS topology skeleton in addition to the structural files.\n\n```bash\n# First register the preset\nbilbo preset add data/examples/presets/ecoli_inner_membrane_default.yaml\n\n# Then build\nbilbo membrane build-preset \\\n  --preset ecoli_inner_membrane_default \\\n  --force-field charmm36 \\\n  --lipids-per-leaflet 128 \\\n  --seed 42 \\\n  --output builds/ecoli_preset\n```\n\n| Flag | Type | Default | Description |\n|---|---|---|---|\n| `--preset` | TEXT | required | Preset ID as registered with `bilbo preset add`. |\n| `--force-field` | TEXT | required | Force field name. |\n| `--engine` | TEXT | gromacs | Simulation engine. Currently `gromacs` only. |\n| `--lipids-per-leaflet` | INTEGER | required | Lipids per leaflet. |\n| `--seed` | INTEGER | 42 | Random seed. |\n| `--spacing` | FLOAT | APL-weighted | Grid spacing in nm. |\n| `--bilayer-gap` | FLOAT | 6.0 | Inter-leaflet gap in Angstroms. |\n| `--ff-dir` | TEXT | charmm36.ff | GROMACS force field directory (e.g. `charmm36-jul2022.ff`). |\n| `--allatom-dir` | PATH | | Directory with PDB templates. |\n| `--output` | PATH | required | Output directory. |\n\nThis command also writes `topol.top` and `report.md`. The topology skeleton includes `#include` directives for the force field and one `.itp` file per unique lipid species. It requires solvation, ion addition, and correct paths before `gmx grompp` can process it.\n\n## Lipid library\n\nThe lipid library stores metadata for each species: IUPAC name, lipid class, headgroup, tail composition, net charge, force field mappings, curation status, and literature references. Library entries are only needed for `membrane compose` and `membrane build-preset`. For `membrane build` from PDB files, no library is required.\n\n### bilbo lipid add\n\n```bash\nbilbo lipid add data/examples/lipids/POPE.yaml\n```\n\nA lipid YAML descriptor:\n\n```yaml\nid: POPE\nname: 1-palmitoyl-2-oleoyl-sn-glycero-3-phosphoethanolamine\nlipid_class: glycerophospholipid\nheadgroup: PE\nnet_charge: 0\ncuration_status: validated\nsource: charmm_gui\ntails:\n  sn1:\n    carbon: 16\n    unsaturation: 0\n  sn2:\n    carbon: 18\n    unsaturation: 1\nforce_fields:\n  charmm36:\n    force_field: charmm36\n    lipid_id: POPE\n    residue_name: POPE\n    topology_file: lipid36.itp\n    status: validated\nreferences:\n  - id: klauda2010\n    doi: 10.1021/jp101759q\n    source_type: doi\n```\n\n`curation_status` controls build eligibility: only `validated` lipids enter a preset build. Valid values: `pending_review`, `curated`, `validated`.\n\n### Other lipid commands\n\n```bash\nbilbo lipid list                                    # list all lipids in the library\nbilbo lipid show POPE                               # show metadata for one species\nbilbo lipid validate data/examples/lipids/POPE.yaml # validate without writing to database\n```\n\n## Membrane presets\n\nA preset is a named composition with per-leaflet lipid percentages and biological metadata (organism, membrane type, evidence level, references).\n\n### bilbo preset add\n\n```bash\nbilbo preset add data/examples/presets/ecoli_inner_membrane_default.yaml\n```\n\n```yaml\nid: ecoli_inner_membrane_default\ndescription: Generic Escherichia coli inner membrane model\norganism: Escherichia coli\nmembrane_type: bacterial_inner_membrane\nsymmetry: symmetric\nleaflets:\n  upper:\n    POPE: 70\n    POPG: 20\n    CL: 10\n  lower:\n    POPE: 70\n    POPG: 20\n    CL: 10\nevidence_level: curated\nreferences:\n  - id: dowhan1997\n    doi: 10.1146/annurev.biochem.66.1.199\n    source_type: doi\n```\n\n### Other preset commands\n\n```bash\nbilbo preset list                                                      # list all presets\nbilbo preset show ecoli_inner_membrane_default                         # show one preset\nbilbo preset validate data/examples/presets/ecoli_inner_membrane_default.yaml\n```\n\n## Force field compatibility\n\n```bash\nbilbo compatibility matrix                          # which lipids have mappings per force field\nbilbo compatibility check \\\n  --preset ecoli_inner_membrane_default \\\n  --force-field charmm36\n```\n\n## Extract commands\n\nBatch-import data into the library from files on disk.\n\n```bash\nbilbo extract lipids    data/examples/lipids/         # import all lipid YAMLs\nbilbo extract presets   data/examples/presets/        # import all preset YAMLs\nbilbo extract mappings  data/examples/forcefields/charmm36_mapping.csv\nbilbo extract topologies data/examples/topologies/\nbilbo extract audit                                   # report library state\nbilbo extract all       data/examples/               # run all of the above\n```\n\nThe force field mapping CSV must have columns `lipid_id`, `force_field`, `residue_name`. Optional columns: `topology_file`, `status`, `notes`.\n\n## Visualization\n\n```bash\nbilbo view leaflet-map  builds/my_membrane   # 2D grid colored by species in the terminal\nbilbo view composition  builds/my_membrane   # realized counts per leaflet in the terminal\n```\n\nOpen in PyMOL:\n\n```bash\npymol builds/my_membrane/system.pdb\n```\n\nOpen in VMD:\n\n```bash\nvmd builds/my_membrane/system.pdb\n```\n\n## Environment variables\n\n`BILBO_DB_PATH`: path to the SQLite database. Default: `~/.bilbo/bilbo.db`. Set this to keep different projects in separate databases.\n\n```bash\nexport BILBO_DB_PATH=./my_project.db\n```\n\n## Drytest\n\nRuns a complete end-to-end pipeline with bundled example data and reports pass or fail for each stage.\n\n```bash\nbilbo drytest\nbilbo drytest --templates-dir /path/to/charmm_gui_pdbs\n```\n\n## Scientific background\n\n### Grid construction\n\nFor each leaflet BILBO constructs a 2D rectangular grid of $N$ lipid positions. The grid has $n_x = \\lceil\\sqrt{N}\\rceil$ columns and $n_y = \\lceil N / n_x \\rceil$ rows. The center of cell $(i, j)$ is:\n\n$$x_{i,j} = i \\cdot d + d/2, \\quad y_{i,j} = j \\cdot d + d/2$$\n\nwhere $d$ is the grid spacing in nanometers. Coordinates in PDB outputs are in Angstroms ($\\times 10$).\n\n### APL-weighted grid spacing\n\nWhen `--spacing` is omitted, BILBO computes $d$ from the composition-weighted mean area per lipid (APL):\n\n$$\\bar{A} = \\frac{\\sum_i n_i \\cdot \\text{APL}_i}{\\sum_i n_i}, \\quad d = \\frac{\\sqrt{\\bar{A}}}{10} \\text{ nm}$$\n\nsumming over all lipid counts across both leaflets. This places each lipid center at the mean projected footprint for that composition in the liquid-crystalline $L_\\alpha$ phase. When any species is absent from the reference table, BILBO prints a warning and uses $d = 0.7$ nm.\n\nAPL reference values (303 K, $L_\\alpha$ phase, from MD simulations validated against X-ray and neutron diffraction):\n\n| Lipid | Full name | APL (Å²) | Source |\n|-------|-----------|----------|--------|\n| DPPC  | 1,2-dipalmitoyl-sn-glycero-3-phosphocholine | 64.3 | Kucerka et al. Biophys J. 2011;101:1828 |\n| DMPC  | 1,2-dimyristoyl-sn-glycero-3-phosphocholine | 60.6 | Klauda et al. J Phys Chem B. 2010;114:7830 |\n| DOPC  | 1,2-dioleoyl-sn-glycero-3-phosphocholine | 72.5 | Kucerka et al. Biophys J. 2011;101:1828 |\n| DOPE  | 1,2-dioleoyl-sn-glycero-3-phosphoethanolamine | 65.7 | Venable et al. J Chem Theory Comput. 2014;10:1397 |\n| POPE  | 1-palmitoyl-2-oleoyl-sn-glycero-3-phosphoethanolamine | 56.6 | Kucerka et al. Biophys J. 2011;101:1828 |\n| POPC  | 1-palmitoyl-2-oleoyl-sn-glycero-3-phosphocholine | 68.3 | Kucerka et al. Biophys J. 2011;101:1828 |\n| POPG  | 1-palmitoyl-2-oleoyl-sn-glycero-3-phospho-(1'-rac-glycerol) | 65.0 | Venable et al. J Chem Theory Comput. 2014;10:1397 |\n| POPS  | 1-palmitoyl-2-oleoyl-sn-glycero-3-phosphoserine | 55.5 | Mukhopadhyay et al. Biophys J. 2004;86:1601 |\n| CL    | cardiolipin (1,3-bis(sn-3'-phosphatidyl)-sn-glycerol) | 130.0 | Dahlberg. J Phys Chem B. 2007;111:7194 |\n| TOCL  | 1,1',2,2'-tetraoleoyl cardiolipin | 130.0 | Dahlberg. J Phys Chem B. 2007;111:7194 |\n\nCardiolipin (CL) has two phosphate groups and four acyl chains and is counted as one molecule; its APL of 130 Å² reflects the full molecular footprint.\n\n### Per-lipid azimuthal rotation\n\nEach lipid in the grid receives a random azimuthal rotation $\\theta \\sim U(0, 2\\pi)$ around Z before placement. The template is first centered on its XY centroid $(\\bar{x}, \\bar{y})$, then rotated and translated to the grid cell center $(c_x, c_y)$:\n\n$$x' = \\cos\\theta \\cdot (x_0 - \\bar{x}) - \\sin\\theta \\cdot (y_0 - \\bar{y}) + c_x$$\n$$y' = \\sin\\theta \\cdot (x_0 - \\bar{x}) + \\cos\\theta \\cdot (y_0 - \\bar{y}) + c_y$$\n\nThe pseudorandom generator is `random.Random(seed)`, isolated from Python's global state. Identical `(seed, composition, N)` triples always produce identical structures. The Z coordinate is normalized so the terminal tail atom sits at $z_\\text{gap}$ from the bilayer center, with sign flipped for the lower leaflet:\n\n$$z = z_\\text{flip} \\cdot (z_0 - z_\\text{tail} + z_\\text{gap})$$\n\n### Inter-species clash detection\n\nAfter tiling, BILBO scans for steric clashes between atoms of different lipid species in the same leaflet. Clashes between atoms of the same species are not reported because they arise from tiling and resolve during energy minimization regardless of composition. The algorithm uses a 3D bounding-box prefilter to reduce the candidate set before computing full pairwise distances with NumPy. Inter-leaflet pairs are excluded automatically because their Z ranges do not overlap. The output counts clashing residue pairs (not atom pairs) and reports the first five with their minimum interatomic distances.\n\nA high clash count with a small minimum distance (e.g. \u003c 0.5 Å) between specific species suggests the grid spacing is too small for that composition. Increase `--spacing` or let BILBO compute it automatically from APL.\n\n### Leaflet area balance\n\nFor asymmetric bilayers, BILBO checks whether the two leaflets have compatible projected areas:\n\n$$\\text{mismatch} = \\frac{|N \\cdot \\bar{A}_\\text{upper} - N \\cdot \\bar{A}_\\text{lower}|}{\\max(\\ldots)} \\times 100\\%$$\n\nA mismatch above 10% generates a warning with the recommended lipid count for the smaller leaflet to equalize areas. In simulation, a persistent area difference causes lateral membrane stress and can produce artificial curvature.\n\n### Composition expansion: largest-remainder method\n\n`membrane compose` and `membrane build-preset` convert percentage compositions to integer counts. Each species $i$ receives $\\lfloor p_i \\cdot N / 100 \\rfloor$ lipids; the deficit to reach $N$ total is distributed one unit at a time to the species with the largest fractional remainder. Ties break alphabetically. This minimizes the maximum absolute rounding error across all species.\n\n### Peptide placement algorithm\n\n1. **Principal axis**: the molecular principal axis is computed from SVD of the mean-centered coordinate matrix. The first right singular vector gives the direction of maximum spatial variance.\n\n2. **Rodrigues rotation**: the principal axis is rotated onto the target direction using the Rodrigues formula:\n\n$$R = I + K + K^2 \\frac{1 - \\cos\\alpha}{\\sin^2\\alpha}$$\n\nwhere $K$ is the skew-symmetric matrix of $\\hat{u} \\times \\hat{v}$ and $\\alpha$ is the angle between source and target vectors. The antiparallel case ($\\cos\\alpha \\approx -1$) uses the reflection $R = 2\\hat{w}\\hat{w}^T - I$.\n\n3. **Surface anchoring**: the headgroup surface Z is extracted from `preview_allatom.pdb` as the maximum Z of upper-leaflet atoms. The Z offset applied to the molecule is:\n\n$$\\Delta z = z_\\text{surface} - z_\\text{min} - d_\\text{ins}$$\n\nwhere $z_\\text{min}$ is the minimum Z of the rotated molecule and $d_\\text{ins}$ is the insertion depth in Angstroms.\n\n4. **Collision count**: all peptide-membrane atom pairs below 2.0 Å are counted. The count and minimum distance are recorded in `build_report.json`.\n\n## Data directory structure\n\n```\ndata/\n  examples/\n    lipids/          YAML descriptors for each lipid species\n    presets/         YAML compositions for named membrane models\n    forcefields/     CSV files mapping lipids to force field residue names\n    charmm_gui/      PDB templates (one per lipid, e.g. POPE.pdb)\n    peptides/        PDB structures for test peptides\n```\n\n## Limitations\n\n- The all-atom PDB is assembled by tiling single-lipid templates. Each template is rotated azimuthally but not otherwise modified. The structure contains steric clashes and is not energy-minimized. It is suitable only for visual inspection and as a starting point for minimization.\n\n- The inter-species clash detector flags clashes between different lipid species. It is a diagnostic for inadequate grid spacing, not a geometry optimizer. Intra-species clashes are not reported by design.\n\n- `bilbo membrane place` applies rigid-body positioning. It does not resolve clashes between the placed molecule and membrane lipids. Use `--allow-overlap` to suppress the warning when testing geometries.\n\n- BILBO does not generate or modify force field parameters. Topology parameters must come from an external validated source (CHARMM-GUI, Lipid21, Slipids, etc.).\n\n- The `topol.top` from `build-preset` is a skeleton. It needs solvation, ion addition, and correct `#include` paths before `gmx grompp` can process it.\n\n- The `--bilayer-gap` parameter is a clash-avoidance buffer, not a physical bilayer thickness. Do not interpret inter-leaflet distances in the unminimized structure.\n\n- LPS, gangliosides, ionizable lipids at non-standard pH, and ceramides with complex headgroups have no bundled descriptors.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmadsondeluna%2Fbilbo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmadsondeluna%2Fbilbo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmadsondeluna%2Fbilbo/lists"}