<p>The discontinuity is normal: it is a missing stretch due to lack of density. In PyMOL you see them as dotted lines.</p>
<p>I am sorry to say, the easiest/safest way to get the sequences is not using the PDB files...</p>
<pre><code>import requests
data = requests.get(f'https://www.ebi.ac.uk/pdbe/api/pdb/entry/molecules/{code}').json()[code.lower()]
print(data[0]['sequence'])
</code></pre>
<p>One gets back a lot of information: <a href="https://www.ebi.ac.uk/pdbe/api/pdb/entry/molecules/1UBQ" rel="noreferrer">example</a>. This will tell you when you have multiple copies of the same peptide. The only information you do not get is what the PDB numbering is relative to the canonical Uniprot for that chain, which has to be taken from SIFTS.</p>
<p>A side note... Biopython.PDB is one of the best BioPython packages, but I personally I much prefer PyMOL as a python module (<code>pymol2</code> module) to Biopython.PDB as it is functionally more complete and straightforward even if everything operates in a stage. You might want to check it out.</p>
<pre><code>with pymol2.PyMOL() as pymol:
    pymol.cmd.fetch('1UBQ', 'prot')
    print(pymol.cmd.get_fastastr('prot'))
</code></pre>

CC BY-SA 4.0
2020-10-11T01:34:37.507Z
Thank you! I've accepted the other answer because of the point with how to iterate over the residues, but the info about the density/unitpro were very helpful, and I really appreciate the pointer to pymol!
mzzx
CC BY-SA 4.0
2020-08-08T10:16:57.923Z
2020-08-08T10:16:57.923Z
Matteo Ferla
<p>You can also use the SeqIO module from Biopython <a href="https://biopython.org/docs/1.75/api/Bio.SeqIO.PdbIO.html" rel="nofollow noreferrer">https://biopython.org/docs/1.75/api/Bio.SeqIO.PdbIO.html</a></p>
<p>and do something like this:</p>
<pre><code>from Bio import SeqIO

for record in SeqIO.parse(target, &quot;pdb-atom&quot;):
    print(record.seq)
</code></pre>
<p>where target is the path to your pdb file
the parser has multiple input/output functions, and pdb-atom is the one that will read out of the coordinates itself.</p>

CC BY-SA 4.0
2021-04-08T13:57:06.427Z
2021-04-08T13:57:06.427Z
cminima
<p>you can try PDBx Python Parser too:</p>
<p><a href="http://mmcif.wwpdb.org/docs/sw-examples/python/html/index.html" rel="nofollow noreferrer">http://mmcif.wwpdb.org/docs/sw-examples/python/html/index.html</a></p>
<p>it has an example showing exactly what you need</p>
<p><a href="http://mmcif.wwpdb.org/docs/sw-examples/python/html/fasta.html" rel="nofollow noreferrer">http://mmcif.wwpdb.org/docs/sw-examples/python/html/fasta.html</a></p>

CC BY-SA 4.0
2020-12-16T10:01:56.187Z
2020-12-16T10:01:56.187Z
pippo1980
<ol>
<li><p>There are other ways to do it (many and some might be easier), but if you want to do it with BioPython PDB module you can iterate the residues like this:</p>
<pre><code> # You can use a dict to convert three letter code to one letter code
 d3to1 = {'CYS': 'C', 'ASP': 'D', 'SER': 'S', 'GLN': 'Q', 'LYS': 'K',
 'ILE': 'I', 'PRO': 'P', 'THR': 'T', 'PHE': 'F', 'ASN': 'N', 
 'GLY': 'G', 'HIS': 'H', 'LEU': 'L', 'ARG': 'R', 'TRP': 'W', 
 'ALA': 'A', 'VAL':'V', 'GLU': 'E', 'TYR': 'Y', 'MET': 'M'}


 # Just an example input pdb
 record = '1pa2.pdb'

 # run parser
 parser = PDBParser(QUIET=True)
 structure = parser.get_structure('struct', record)    

 # iterate each model, chain, and residue
 # printing out the sequence for each chain

 for model in structure:
     for chain in model:
         seq = []
         for residue in chain:
             seq.append(d3to1[residue.resname])
         print('&gt;some_header\n',''.join(seq))
</code></pre>
</li>
<li><p>Not really, is very common, you can turn it off like this (taken from <a href="https://lists.open-bio.org/pipermail/biopython/2014-July/015371.html" rel="nofollow noreferrer">https://lists.open-bio.org/pipermail/biopython/2014-July/015371.html</a>):</p>
<pre><code> import warnings
 from Bio import PDBConstructionWarning
 #your code
 with warnings.catch_warnings():
 warnings.simplefilter('ignore', PDBConstructionWarning)
 #your code which might trigger the warning
 #rest of your code here

 However, because this is so common, you can just use the
 QUIET=True option on the PDBParser object:

 from Bio.PDB.PDBParser import PDBParser
 struct = PDBParser(QUIET=True).get_structure('tmp', pdbf)
</code></pre>
</li>
</ol>
<p>Try help(PDBParser) for more, or see:
<a href="http://biopython.org/DIST/docs/api/Bio.PDB.PDBParser%27.PDBParser-class.html#__init_" rel="nofollow noreferrer">http://biopython.org/DIST/docs/api/Bio.PDB.PDBParser%27.PDBParser-class.html#__init_</a>_</p>

CC BY-SA 4.0
2020-09-30T22:24:07.020Z
2020-09-30T22:24:07.020Z
Arap
<p>I'm new to Biopython and I'd like to extract the sequence of residues from a pdb file.</p>
<p>My two questions are:</p>
<ol>
<li>What is the simplest way to do this? (Esp. when there is more than one sequence)
and</li>
<li>Should I be worried about &quot;PDBConstructionWarning: WARNING: Chain B is discontinuous&quot;?</li>
</ol>
<p>So far, I've obtained the residue sequence via:</p>
<pre><code>p = PDBParser()
structure = p.get_structure(&quot;1ppi&quot;, &quot;1ppi.pdb&quot;)
ppb=PPBuilder()
for pp in ppb.build_peptides(structure):
     print(pp.get_sequence())

seq = pp.get_sequence().__str__()
</code></pre>
<p>This seems to work well for this molecule. However, is there an easier way, especially when there is more than one sequence?</p>
<p>For example, I've read that one can also do</p>
<pre><code>res_list = Bio.PDB.Selection.unfold_entities(structure, 'R')
</code></pre>
<p>but res_list is not a sequence of residues in str, and I don't know how to convert the output from res_list to a str sequence.</p>
<p>In addition (or perhaps because I'm going through the PPBuilder), I've recently gotten a lot of warnings of the type:
/usr/local/lib/python3.8/site-packages/Bio/PDB/StructureBuilder.py:89: PDBConstructionWarning: WARNING: Chain A is discontinuous at line..
(For example, with <code>structure = p.get_structure(&quot;5owu&quot;, &quot;5owu.pdb&quot;)</code>)</p>
<p>I've seen a discussion about how to silence such warnings, but should I be worried about this? I've also noticed that when I get these warnings, pp builder seems to give me more sequences then are there.</p>

CC BY-SA 4.0
2020-10-01T10:07:28.047Z
One thing to consider is whether you want the full sequence of the protein (equivalent to the SEQRES record) or the sequence of the residues with coordinate data in the file (from parsing the ATOM records). They often differ, especially for proteins with disordered regions, and the answers below cover both methods.
jgreener
<python><pdb>
Extract residue sequence from pdb file (in biopython, but open to recommendations)
# Extract residue sequence from pdb file (in biopython, but open to recommendations)

(Asked by: username_0 on 2020-08-07)

I'm new to Biopython and I'd like to extract the sequence of residues from a pdb file.
My two questions are:

What is the simplest way to do this? (Esp. when there is more than one sequence)
and
Should I be worried about "PDBConstructionWarning: WARNING: Chain B is discontinuous"?

So far, I've obtained the residue sequence via:
p = PDBParser()
structure = p.get_structure("1ppi", "1ppi.pdb")
ppb=PPBuilder()
for pp in ppb.build_peptides(structure):
     print(pp.get_sequence())

seq = pp.get_sequence().__str__()

This seems to work well for this molecule. However, is there an easier way, especially when there is more than one sequence?
For example, I've read that one can also do
res_list = Bio.PDB.Selection.unfold_entities(structure, 'R')

but res_list is not a sequence of residues in str, and I don't know how to convert the output from res_list to a str sequence.
In addition (or perhaps because I'm going through the PPBuilder), I've recently gotten a lot of warnings of the type:
/usr/local/lib/python3.8/site-packages/Bio/PDB/StructureBuilder.py:89: PDBConstructionWarning: WARNING: Chain A is discontinuous at line..
(For example, with structure = p.get_structure("5owu", "5owu.pdb"))
I've seen a discussion about how to silence such warnings, but should I be worried about this? I've also noticed that when I get these warnings, pp builder seems to give me more sequences then are there.

**Tags:** python, pdb
> **Comments:**
> **username_1**: One thing to consider is whether you want the full sequence of the protein (equivalent to the SEQRES record) or the sequence of the residues with coordinate data in the file (from parsing the ATOM records). They often differ, especially for proteins with disordered regions, and the answers below cover both methods.  

---

## 4 answers

### Answer by username_5 on 2020-09-30. Score: 4 | Accepted answer

There are other ways to do it (many and some might be easier), but if you want to do it with BioPython PDB module you can iterate the residues like this:
 # You can use a dict to convert three letter code to one letter code
 d3to1 = {'CYS': 'C', 'ASP': 'D', 'SER': 'S', 'GLN': 'Q', 'LYS': 'K',
 'ILE': 'I', 'PRO': 'P', 'THR': 'T', 'PHE': 'F', 'ASN': 'N', 
 'GLY': 'G', 'HIS': 'H', 'LEU': 'L', 'ARG': 'R', 'TRP': 'W', 
 'ALA': 'A', 'VAL':'V', 'GLU': 'E', 'TYR': 'Y', 'MET': 'M'}


 # Just an example input pdb
 record = '1pa2.pdb'

 # run parser
 parser = PDBParser(QUIET=True)
 structure = parser.get_structure('struct', record)    

 # iterate each model, chain, and residue
 # printing out the sequence for each chain

 for model in structure:
     for chain in model:
         seq = []
         for residue in chain:
             seq.append(d3to1[residue.resname])
         print('>some_header\n',''.join(seq))


Not really, is very common, you can turn it off like this (taken from https://lists.open-bio.org/pipermail/biopython/2014-July/015371.html):
 import warnings
 from Bio import PDBConstructionWarning
 #your code
 with warnings.catch_warnings():
 warnings.simplefilter('ignore', PDBConstructionWarning)
 #your code which might trigger the warning
 #rest of your code here

 However, because this is so common, you can just use the
 QUIET=True option on the PDBParser object:

 from Bio.PDB.PDBParser import PDBParser
 struct = PDBParser(QUIET=True).get_structure('tmp', pdbf)



Try help(PDBParser) for more, or see:
http://biopython.org/DIST/docs/api/Bio.PDB.PDBParser%27.PDBParser-class.html#__init__


---

### Answer by username_2 on 2020-08-08. Score: 8

The discontinuity is normal: it is a missing stretch due to lack of density. In PyMOL you see them as dotted lines.
I am sorry to say, the easiest/safest way to get the sequences is not using the PDB files...
import requests
data = requests.get(f'https://www.ebi.ac.uk/pdbe/api/pdb/entry/molecules/{code}').json()[code.lower()]
print(data[0]['sequence'])

One gets back a lot of information: example. This will tell you when you have multiple copies of the same peptide. The only information you do not get is what the PDB numbering is relative to the canonical Uniprot for that chain, which has to be taken from SIFTS.
A side note... Biopython.PDB is one of the best BioPython packages, but I personally I much prefer PyMOL as a python module (pymol2 module) to Biopython.PDB as it is functionally more complete and straightforward even if everything operates in a stage. You might want to check it out.
with pymol2.PyMOL() as pymol:
    pymol.cmd.fetch('1UBQ', 'prot')
    print(pymol.cmd.get_fastastr('prot'))

> **Comments:**
> **username_0**: Thank you! I've accepted the other answer because of the point with how to iterate over the residues, but the info about the density/unitpro were very helpful, and I really appreciate the pointer to pymol!  

---

### Answer by username_3 on 2021-04-08. Score: 4

You can also use the SeqIO module from Biopython https://biopython.org/docs/1.75/api/Bio.SeqIO.PdbIO.html
and do something like this:
from Bio import SeqIO

for record in SeqIO.parse(target, "pdb-atom"):
    print(record.seq)

where target is the path to your pdb file
the parser has multiple input/output functions, and pdb-atom is the one that will read out of the coordinates itself.


---

### Answer by username_4 on 2020-12-16. Score: 0

you can try PDBx Python Parser too:

<http://mmcif.wwpdb.org/docs/sw-examples/python/html/index.html>

it has an example showing exactly what you need

<http://mmcif.wwpdb.org/docs/sw-examples/python/html/fasta.html>


---

