How to Extract a Single Chain from a PDB File

To extract one chain from a PDB file, open the structure and save only that chain’s selection. In PyMOL: select chA, chain A then save chainA.pdb, chA. In ChimeraX: select /A then save chainA.pdb selectedOnly true. From a terminal, pdb_selchain -A input.pdb > chainA.pdb does it in one line. Check the ligand and cofactors afterwards.
This is the step-1 task nobody writes a tutorial about, and it is where a surprising number of docking and MD projects quietly go wrong. You download a structure, it turns out to hold a dimer plus a nanobody plus three sulfate ions, you dock into the whole thing, and the binding site you reported sits at a crystal contact that does not exist in solution. This guide from the StemSkills Lab team (10+ years in structural bioinformatics, drug design and molecular modeling) covers four ways to pull out the chain you need, and the four things that break afterwards, with every command and column number checked against primary documentation on 20 September 2026. It sits inside our computational biology skills roadmap and follows on from downloading a protein structure from the RCSB PDB.
Why does picking the right chain matter?
Because most structures have more than one. A search of the RCSB PDB on 20 September 2026 returns 260,089 released entries, and 163,955 of them contain more than one polymer chain instance. That is 63 percent. Multi-chain is the normal case, not the exception.
Those extra chains are there for different reasons, and the reason decides what you do:
- Crystallographic copies. Several identical molecules in the asymmetric unit. Keep one. Which one is mostly arbitrary, so pick the most complete chain and say which you picked.
- A real biological partner. The second chain is part of the functional unit. Deleting it removes part of the binding site or destabilises the fold.
- A crystallisation aid. A nanobody, a fusion partner, a fiducial. Remove it, and check it was not propping up a loop you care about.
- A different molecule type. DNA, RNA or a peptide ligand recorded as its own chain.
The check that tells you which situation you are in is the biological assembly. On any RCSB entry page, compare the deposited asymmetric unit with the listed assembly. If the assembly is a dimer and you keep one chain, you are simulating something that does not exist on its own, and your reviewer will say so.
How do you find out what chains the file contains?
Three quick checks, in increasing order of trust.
From the terminal, list the chain identifiers actually present in the coordinates:
grep "^ATOM" 1brs.pdb | cut -c22 | sort -uColumn 22 is not a guess. The wwPDB coordinate section format specification fixes the ATOM record layout: the record name occupies columns 1 to 6, the alternate location indicator is column 17, the chain identifier is column 22, the residue sequence number is columns 23 to 26, and the insertion code is column 27. Every command below relies on that layout.
Second, read the SEQRES and COMPND records, or the entry page, to learn what each chain is. Chain identity is metadata, not something you can infer from coordinates.
Third, open it. A structure viewer colours by chain in one click and shows you immediately whether the second chain is wrapped around your binding site or sitting on the far side of the box.
The worked example below uses PDB entry 1BRS, the barnase-barstar complex solved by X-ray diffraction at 2.0 Angstrom. It has two distinct polymer entities and six chains, three copies of each protein, which makes it a good stand-in for the structure you will actually download.
How do you extract a chain in PyMOL?
Three lines. Fetch, select, save.
fetch 1brs, async=0
select chA, chain A
save chainA.pdb, chAThe save syntax is save file [,(selection) [,state [,format]]], and if you leave the selection out it writes everything in the session, which is the most common way to think you extracted a chain and not have. The format follows the file extension, so .pdb gives PDB and .cif gives mmCIF.
Two refinements matter in practice. To take the protein only and leave waters, ions and the ligand behind:
select chA_prot, chain A and polymer.protein
save chainA_protein.pdb, chA_protAnd to keep a cofactor that belongs to your chain, name it explicitly rather than hoping:
select chA_plus, chain A and (polymer.protein or resn NAD+HEM+ZN)
save chainA_plus.pdb, chA_plusIf you would rather work with a real object than a selection, create objA, chain A makes a separate object you can inspect, colour and save on its own. Our guide to installing PyMOL for free covers the open-source build if you do not have a licence.
How do you extract a chain in ChimeraX?
ChimeraX uses a different specifier syntax, where a chain is written /A.
open 1brs
select /A
save chainA.pdb selectedOnly trueThe documented save syntax is save filename [format pdb] [models model-spec] [relModel model-spec] [selectedOnly true|false] [displayedOnly true|false] [allCoordsets true|false]. The option that does the work here is selectedOnly, which restricts the output to the current selection.
The alternative is to delete what you do not want, which gives a cleaner file because nothing stray can survive the selection:
open 1brs
delete ~/A
save chainA.pdb~ is negation, so ~/A means everything that is not chain A. One caution on relModel: it writes coordinates relative to another model’s original frame, which matters when you have superimposed structures and want the saved file in the reference frame rather than the moved one. If you have aligned anything, decide deliberately which frame you are saving. Our ChimeraX tutorial for beginners covers the specifier syntax in full.
Want the guided, hands-on version?
Our live Molecular Modeling & MD Simulations cohort bootcamp takes you from zero to running real docking and MD workflows, with a portfolio project for your grad-school applications.
How do you extract a chain with Biopython?
Use Biopython when you have fifty structures rather than one, or when the extraction is a step inside a longer script. The pattern is a Select subclass handed to PDBIO.save(). The Bio.PDB.PDBIO documentation defines four hooks you can override: accept_model, accept_chain, accept_residue and accept_atom. Each returns True to keep an entity and False to drop it.
from Bio.PDB import PDBParser, PDBIO, Select
class ChainSelect(Select):
def __init__(self, chain_id):
self.chain_id = chain_id
def accept_chain(self, chain):
return chain.get_id() == self.chain_id
parser = PDBParser(QUIET=True)
structure = parser.get_structure("1brs", "1brs.pdb")
io = PDBIO()
io.set_structure(structure)
io.save("chainA.pdb", ChainSelect("A"))Two additions cover the cases that bite. To drop waters at the same time, override accept_residue as well and reject residues whose hetero flag is W. To keep only the first model, which matters for NMR ensembles, override accept_model and compare the model id to 0.
Biopython 1.88 is the current release on PyPI. PDBParser(QUIET=True) suppresses the discontinuity warnings that otherwise fill your terminal on any crystal structure with missing loops. Do not leave QUIET on while you are still deciding whether the structure is usable, because those warnings are the ones telling you about missing residues and loops.
How do you extract a chain from the command line?
The cleanest option is pdb-tools, a set of single-purpose scripts from the Bonvin lab. Rodrigues, Teixeira, Trellet and Bonvin describe them in pdb-tools: a swiss army knife for molecular structures (F1000Research 7:1961, 2018) as “a collection of Python scripts for working with molecular structure data in the Protein Data Bank (PDB) format”, implemented “without any external dependencies”. Install with pip install pdb-tools, then:
pdb_fetch 1brs > 1brs.pdb
pdb_selchain -A 1brs.pdb > 1brs_A.pdbSeveral chains at once, and a full clean-up pipeline, read as one line each:
pdb_selchain -A,D 1brs.pdb > 1brs_AD.pdb
pdb_selchain -A,D 1brs.pdb | pdb_delhetatm | pdb_tidy > 1brs_AD_noHET.pdbpdb_tidy is the part people skip and should not. It repairs the record structure, including the TER and END records that selection alone leaves inconsistent. pdb_fetch -biounit 1brs downloads the biological assembly instead of the asymmetric unit, which for this entry gives 2 chains rather than 6, and is often the correct starting point.
If you cannot install anything, awk on the raw columns works, and knowing why it works is worth the two minutes:
awk '/^(ATOM|HETATM)/ && substr($0,22,1)=="A"' 1brs.pdb > chainA_raw.pdb
echo "END" >> chainA_raw.pdbDo not write grep "^ATOM.* A ". Atom names, residue names and element symbols all produce stray matches, and a single-letter chain id is not something whitespace-delimited matching can find reliably. Cut on the column, as the format specification defines it, or use a tool that parses the format.
Which method should you use?
| Method | Best for | Keeps ligands | Fixes TER/END | Scriptable |
|---|---|---|---|---|
| PyMOL | One structure you are already looking at | If you name them in the selection | Yes | Yes, with .pml scripts |
| ChimeraX | One structure, plus assembly inspection | If selected or not deleted | Yes | Yes, with .cxc scripts |
| Biopython | Batches, and extraction inside a pipeline | Only if accept_residue allows them | Yes | Fully |
| pdb-tools | Fast one-liners and shell pipelines | Yes, unless pdb_delhetatm is used | With pdb_tidy | Fully |
| awk on columns | No-install environments, clusters | Only HETATM lines on that chain | No, you add them | Fully |
For a single thesis structure, use the viewer you already have open, because you can see what you produced. For anything repeated more than three times, use Biopython or pdb-tools so the step is recorded in a script rather than in your memory of what you clicked.
What breaks after you extract a chain?
The ligand or cofactor disappears. This is the most common failure, and it is silent. Ligands, metals and cofactors sit on HETATM records. In a well-formed file they carry the chain id of the chain they belong to, and a chain selection keeps them. But some depositions assign ligands their own chain, and a protein-only selection such as polymer.protein drops them by design. After every extraction, run grep "^HETATM" chainA.pdb | cut -c18-20 | sort -u and confirm that what you see is what you expected.
Alternate conformations survive and cause duplicate atoms. Residues modelled in two positions produce two sets of atoms distinguished only by the altLoc character in column 17. Selecting a chain keeps both. GROMACS notices: gmx pdb2gmx prints “Checking for duplicate atoms….” and then “deleting duplicate atom” lines, reporting the altloc it dropped. Letting it choose for you is a decision made by default. Keep conformer A explicitly instead, with awk 'substr($0,17,1)==" " || substr($0,17,1)=="A"', and say so in your methods.
The chain gets split in two. If the extracted chain’s records are not contiguous, for example because a ligand block sits between two stretches of the same chain id, pdb2gmx warns: “Chain identifier ‘A’ is used in two non-sequential blocks. They will be treated as separate chains unless you reorder your file.” Treating one protein as two chains adds a pair of charged termini in the middle of your molecule. Reorder the file, or run pdb_tidy, before you build a topology.
TER and END records go missing or land in the wrong place. Column-based extraction copies coordinate lines and nothing else, so the file has no chain terminator and no END. Most parsers tolerate it until one does not. Append them, or pass the file through pdb_tidy.
Residue numbering is not what the paper says. Extraction preserves the original numbering, which is usually what you want, so resist renumbering from 1 unless a downstream tool forces it. If you must, pdb_reres -1 chainA.pdb renumbers, and you then owe your methods section a sentence mapping new numbering to the crystallographic numbering. This is the single most common reason a reported hotspot residue cannot be found by the person reading your thesis.
How do you check the extracted chain is actually usable?
Three checks take two minutes and save a week.
- Count what you kept.
grep -c "^ATOM" chainA.pdbfor atoms, andgrep "^ATOM" chainA.pdb | cut -c18-27 | sort -u | wc -lfor residues. Compare against the chain length in SEQRES. A gap means missing residues, which you deal with before docking, not after. - Run it through the topology builder you will actually use. For MD,
gmx pdb2gmx -f chainA.pdb -o processed.gro -water spceand read every warning. Our gmx pdb2gmx tutorial explains what each one means. For docking, load the file in AutoDock Tools or your prep script and confirm the atom count and charges are sane. Our guide to preparing a protein and ligand for docking covers the rest of that path. - Look at it. Open the extracted file on its own, not on top of the original. A chain that looked fine inside the complex can have an exposed hydrophobic face, a dangling loop, or a gap where the partner used to be.
Then handle the rest of the preparation in order: remove waters and unwanted heteroatoms, set protonation states and add hydrogens, and only then build the box. Our full protein preparation checklist for MD puts these in sequence.
Frequently asked questions
Should I extract a chain from the asymmetric unit or the biological assembly?
Start from the biological assembly whenever your question is about function. The asymmetric unit is a crystallographic construct and may contain more or fewer copies than the functional molecule. pdb_fetch -biounit downloads the assembly, and both viewers can generate it from the entry.
How do I extract a chain from an mmCIF file instead?
The same viewer and Biopython methods work, using MMCIFParser in place of PDBParser. Be aware that mmCIF carries two chain identifiers, the author-assigned one and the internal label, and they do not always agree. Select on the author chain id, which is the one that matches the literature and the PDB-format file.
My chain identifier is blank. How do I select it?
Older and computationally generated files sometimes leave column 22 empty. In PyMOL, chain "" selects the blank chain. With awk, test for substr($0,22,1)==" ". The better fix is to assign an identifier before anything downstream sees the file, since several tools treat a blank chain as an error.
Does extracting a chain change the coordinates?
No. Every method here copies coordinates unchanged. The one exception to watch is ChimeraX’s relModel option, which writes coordinates in another model’s frame, and any case where you saved after aligning or moving the structure.
Can I keep two chains and drop the rest?
Yes, and the syntax is the natural extension in each tool: chain A+B in PyMOL, /A,B in ChimeraX, a membership test in the Biopython accept_chain method, and pdb_selchain -A,B on the command line.
Which chain should I pick when several identical copies exist?
Pick the most complete one. Compare residue counts and missing-loop warnings across the copies, prefer the chain with the fewest gaps in the region you care about, and state in your methods which chain you used and why. Defaulting to chain A is common and acceptable, provided you checked it is not the worst copy in the file.
Want the guided, hands-on version?
Our live Molecular Modeling & MD Simulations cohort bootcamp takes you from zero to running real docking and MD workflows, with a portfolio project for your grad-school applications.
