Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ ratatui = "0.29"
crossterm = "0.28"
ratatui-image = { version = "9.0.0", default-features = false, features = ["crossterm"] }
image = "0.25"
libc = "0.2"
pdbtbx = { version = "0.12", features = ["rstar"] }
clap = { version = "4", features = ["derive"] }
anyhow = "1"
Expand All @@ -26,6 +27,7 @@ flate2 = "1"
rayon = "1"
reqwest = { version = "0.12", features = ["blocking"], optional = true }
serde = { version = "1", features = ["derive"] }
toml = "0.8"
serde_json = "1"
tempfile = { version = "3.27.0", optional = true }
tokio = { version = "1", features = ["rt", "macros"], optional = true }
Expand Down
68 changes: 68 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Terminal molecular structure viewer — load, rotate, and explore proteins, nucl
- **RNA/DNA support** — backbone, wireframe, and cartoon modes with base-type coloring
- **Small molecule rendering** — ligands as ball-and-stick, ions as spheres
- **Interface analysis** — inter-chain contacts, binding pockets, and interaction visualization (H-bonds, salt bridges, hydrophobic contacts)
- **Sequence panel** — scroll every chain's sequence, select residues, and show them as ball-and-stick in the 3D view
- **7 color schemes** — structure, chain, element (CPK), B-factor, rainbow, pLDDT (AlphaFold)
- **Interactive controls** — vim-style rotation, zoom, pan with auto-rotation
- **PDB & mmCIF** — both formats supported, with RCSB PDB fetch (`--fetch`)
Expand Down Expand Up @@ -248,10 +249,50 @@ leave the prior frame, state, and revision unchanged.
| `I` | Interface interactions |
| `g` | Toggle ligands |
| `[`/`]` | Prev/next chain |
| `S` | Sequence panel |
| `b` | Ball-and-stick for the selection |
| `z` | Centre the view on the selection |
| `Space` | Auto-rotate |
| `?` | Help |
| `q` | Quit |

While the sequence panel is open it takes the arrow keys; `h`/`j`/`k`/`l` still
rotate the view, so you can turn the structure while picking residues.

| Key | Action in the sequence panel |
|-----|------------------------------|
| `←`/`→` | Move the cursor one residue (across chain ends) |
| `↑`/`↓` | Move one row |
| `Shift`+arrow | Extend the selection from the cursor |
| `PgUp`/`PgDn` | Move a screenful |
| `Home`/`End` | Start / end of the chain |
| `Enter` | Select or deselect the residue |
| `A` | Select or deselect the whole chain |
| `x` | Clear the selection |
| `[`/`]` | Jump to the previous / next chain |
| `<`/`>` | Shrink / grow the panel |
| `S` / `Esc` | Close the panel |

## Sequence Panel & Residue Selection

Press `S` to open a scrollable panel listing the sequence of every chain in
one-letter codes — amino acids and nucleotides alike, numbered in the gutter and
grouped in tens. Each chain gets a header with its type, length, and residue
range, so a 52-chain ribosome reads as one continuous list.

The cursor moves with the arrow keys; `Enter` picks a residue, `Shift`+arrow
extends a range, and `A` takes a whole chain. Picked residues are drawn in the
3D view as ball-and-stick over whatever mode is active, with the selection color
on carbons and CPK colors elsewhere, z-buffered so a side chain that really is
behind the structure stays behind it. `b` turns the ball-and-stick off, leaving a
marker sphere per residue; `z` centres the view on the selection, which is how
you find a handful of residues inside something the size of a ribosome. The
selection survives closing the panel, and the status bar keeps its count.

Letters are colored by the active color scheme, so the panel and the structure
read as one picture; the selection and cursor colors come from `[selection]` in
the palette file.

## Color Schemes

| Scheme | Description |
Expand All @@ -263,6 +304,33 @@ leave the prior frame, state, and revision unchanged.
| **Rainbow** | N-terminus (blue) to C-terminus (red). |
| **pLDDT** | AlphaFold confidence (blue=high, orange=low). |

### Customizing the palette

Every fixed color above can be changed from a TOML file. ProteinView reads
`~/.config/proteinview/palette.toml` (or `$XDG_CONFIG_HOME/proteinview/palette.toml`)
when it exists, and `--palette <FILE>` overrides that:

```bash
proteinview examples/1UBQ.pdb --palette my-palette.toml
```

Every key is optional — anything you leave out keeps its built-in default, so a
file this short is valid:

```toml
[structure]
helix = "#00FFFF"
```

Colors are six hex digits, with or without a leading `#`, in either case.
Element symbols merge onto the built-in CPK table, so overriding carbon leaves
the rest alone, while `[chain] colors` replaces the chain cycle outright. Unknown
keys are rejected rather than ignored, so a typo tells you rather than silently
doing nothing.

See [`docs/palette.example.toml`](docs/palette.example.toml) for a fully
commented file listing every setting at its default value.

## Terminal Support

| Terminal | Braille | HD | FullHD |
Expand Down
106 changes: 106 additions & 0 deletions docs/palette.example.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# ProteinView color palette
#
# Copy to ~/.config/proteinview/palette.toml to have it picked up automatically,
# or point at it explicitly:
#
# proteinview structure.pdb --palette docs/palette.example.toml
#
# Every key is optional. Anything you leave out keeps its built-in default, so a
# file containing nothing but a single color is perfectly valid. Colors are six
# hexadecimal digits, with or without a leading '#', in either case.
#
# Unknown keys are an error rather than being ignored, so a typo tells you
# instead of silently doing nothing.

# --- Structure scheme (the default, keyed by secondary structure) ------------
[structure]
helix = "FF0080"
sheet = "FFC800"
turn = "6080FF"
coil = "00CC00"

# --- Nucleic acid bases ------------------------------------------------------
# Used for DNA/RNA residues under the Structure scheme.
[nucleotide]
adenine = "DC3C3C"
uracil = "3C3CDC"
thymine = "3C3CDC"
guanine = "3CB43C"
cytosine = "DCC828"
inosine = "9664B4"

# --- Chain scheme ------------------------------------------------------------
# Cycled by chain id. Order matters, and the list replaces the default outright
# rather than merging, so give it as many colors as you want in the rotation.
[chain]
colors = [
"00B4FF",
"FF6400",
"00DC64",
"FF3296",
"B464FF",
"FFDC00",
"00C8C8",
"FF9696",
]

# --- Element scheme (CPK) ----------------------------------------------------
[element]
# Color for any element not listed below.
fallback = "C8C8C8"

# These *merge* onto the built-in table, so overriding carbon leaves every other
# element alone. Keys are element symbols and are matched case-insensitively.
[element.symbols]
C = "909090"
N = "3050F8"
O = "FF0D0D"
S = "FFFF30"
H = "FFFFFF"
P = "FF8000"
FE = "E06633"
MG = "00B400"
ZN = "7D80B0"
CA = "3DFF00"
MN = "9C7AC7"
CO = "F090A0"
CU = "C88033"
NI = "50D050"
CL = "1FF01F"
BR = "A62929"

# --- pLDDT scheme (AlphaFold confidence bands) -------------------------------
[plddt]
very_high = "0053D6" # >= 90
high = "65CBF3" # >= 70
low = "FFDB13" # >= 50
very_low = "FF7D45" # < 50

# --- B-factor scheme ---------------------------------------------------------
# Endpoints of a linear gradient across roughly the 5..80 B-factor range.
[bfactor]
low = "0000FF"
high = "FF0000"

# --- Interface highlighting ('f') --------------------------------------------
[interface]
focus_contact = "00FF64" # focus chain, touching a partner
focus_other = "28643C" # focus chain, away from the interface
partner_contact = "FFA500" # partner chain, touching the focus chain
partner_other = "64503C" # partner chain, away from the interface
ligand = "FFFFFF" # ligands, kept bright so they stay visible

# --- Small molecules ---------------------------------------------------------
[ligand]
ligand = "FF00FF"
ion = "00FFFF"
rainbow = "FF00FF" # ligands under the Rainbow scheme

# --- Sequence panel selection ('S') ------------------------------------------
# Residues picked in the sequence panel. Carbons of the ball-and-stick overlay
# take `carbon`; every other element keeps its CPK color, so a picked residue
# still reads as itself.
[selection]
carbon = "00E68C" # ball-and-stick carbons of picked residues
marker = "00E68C" # marker sphere shown when ball-and-stick is off ('b')
cursor = "FFC800" # the sequence panel's cursor cell
Loading