<p>Assuming you can use <code>R</code>, have you tried with <code>biomaRt</code>? For example, using <code>2bhl</code> (my PhD lover :D)</p>
<pre><code>library(biomaRt)
ensembl &lt;- useMart(&quot;ensembl&quot;,dataset=&quot;hsapiens_gene_ensembl&quot;)

# get list of all available info
filters &lt;- listFilters(ensembl)
attributes &lt;- listAttributes(ensembl)

getBM(attributes=c('hgnc_symbol','ensembl_gene_id','entrezgene_id',
                'protein_id','description',&quot;superfamily&quot;), 
      filters = 'pdb', 
      values = &quot;2bhl&quot;, 
      mart = ensembl)
</code></pre>
<p>Returns</p>
<pre><code>hgnc_symbol ensembl_gene_id entrezgene_id protein_id description
1         G6PD ENSG00000160211          2539   ADO22353 glucose-6-phosphate dehydrogenase [Source:HGNC Symbol;Acc:HGNC:4057]
2         G6PD ENSG00000160211          2539   CAA27309 glucose-6-phosphate dehydrogenase [Source:HGNC Symbol;Acc:HGNC:4057]
3         G6PD ENSG00000160211          2539   AAA63175 glucose-6-phosphate dehydrogenase [Source:HGNC Symbol;Acc:HGNC:4057]
4         G6PD ENSG00000160211          2539   AAA52500 glucose-6-phosphate dehydrogenase [Source:HGNC Symbol;Acc:HGNC:4057]
5         G6PD ENSG00000160211          2539   AAA52501 glucose-6-phosphate dehydrogenase [Source:HGNC Symbol;Acc:HGNC:4057]
6         G6PD ENSG00000160211          2539   CAA39089 glucose-6-phosphate dehydrogenase [Source:HGNC Symbol;Acc:HGNC:4057]
7 ...
</code></pre>
<p>I am sure if you look at all the available filters and attributes, you can pinpoint the ID you are looking for.</p>

CC BY-SA 4.0
2020-10-31T18:34:30.587Z
Thanks. I can reproduce that, but only paint by numbers with R. How would I modify that to loop through a list of 4000 proteins and ensure the pdb ID was included in the output?
David
CC BY-SA 4.0
2020-10-31T22:51:31.463Z
You can add `'pdb'` to the list of attributes. That will add a column with the pdb id. `c('pdb','hgnc_symbol',....),`
fra
CC BY-SA 4.0
2020-11-01T00:39:38.127Z
Ok. Get it. Thanks.
David
CC BY-SA 4.0
2020-11-01T11:05:57.250Z
I am not sure how your input file is (csv, vector, data.frame), but to run on multiple pdbs, you need to change your`values` (`values= c("2bhl","pdbID2","pdbID3",...)`)
fra
CC BY-SA 4.0
2020-11-01T11:43:39.970Z
My input is just a text file of filenames, one per line, generated from a unix ls command. I can convert it into a string of the type you suggest, although I wonder if there is any limit on the length of such strings. Referencing a text file would be preferable if it is possible.
David
CC BY-SA 4.0
2020-11-02T10:38:26.953Z
I think the limit is 500 values x query, bu the newest versions of biomaRt should automatically split for you. I am not 100% sure, so you may want to double check. You can `ls *.pdb >> all_pdbs.txt` , use `all_pdb_list <- read.delim("./all_pdbs.txt")` to read `all_pdbs.txt` , and `gsub` to remove the extension from your entries (`gsub(".pdb","", all_pdb_list)`) .
fra
CC BY-SA 4.0
2020-10-31T16:11:32.100Z
2020-10-31T16:11:32.100Z
fra
<p>You can use one of the <a href="https://www.ebi.ac.uk/proteins/api/doc/#!/proteins/getByCrossReference" rel="nofollow noreferrer">UniProt Protein APIs</a>.</p>
<p>As you said you have your pdb entries in a text file line by line you can, like this <code>example.txt</code> containing:</p>
<pre><code>1brr
4lzm
2dyi
</code></pre>
<p>Using the commandline, you can use a little script like this to download the name, if it is available for the given pdb entry.</p>
<pre><code>while read line;
do 
 curl -X GET --header 'Accept:application/json' &quot;https://www.ebi.ac.uk/proteins/api/proteins/pdb:$line&quot; | 
 jq -r '.[].protein.recommendedName.fullName.value'  |
 sed &quot;s/^/$line\t/&quot; &gt;&gt; pdb_names.txt;
done &lt; example.txt;
</code></pre>
<p>You need to have <code>curl</code>, <code>sed</code> and <code>jq</code> installed on your system.</p>
<p>This gives you following output in <code>pdb_names.txt</code></p>
<pre><code>1brr    Bacteriorhodopsin
4lzm    Endolysin
2dyi    Ribosome maturation factor RimM
</code></pre>
<hr />
<p>Update</p>
<p>if you want to speed it up, you can run it with <code>parallel</code>.</p>
<pre><code>parallel -j 4 'curl -X GET --header &quot;Accept:application/json&quot; &quot;https://www.ebi.ac.uk/proteins/api/proteins/pdb:{}&quot; |   jq -r &quot;.[]. .protein.recommendedName.fullName.value&quot;  |  sed &quot;s/^/{}\t/&quot; &gt;&gt; pdb_names_parallel.txt' :::: example.txt
</code></pre>
<p>With the <code>-j</code> option you call how many jobs should run in parallel. The limit of the UniProt API is 200 request per second per user.</p>
<hr />
<p>Update 7. Nov 2020</p>
<p>To get another info beside the protein name, you need to know how the <code>JSON</code> response from UniProt looks like.</p>
<p>To get also the scientific name, you can run following command:</p>
<pre><code>parallel -j 4 'curl -X GET --header &quot;Accept:application/json&quot; &quot;https://www.ebi.ac.uk/proteins/api/proteins/pdb:{}&quot; | jq -r &quot;.[] | .protein.recommendedName.fullName.value + \&quot; - \&quot; + .organism.names[0].value&quot;  |  sed &quot;s/^/{}\t/&quot; &gt;&gt; pdb_names_parallel.txt' :::: example.txt
</code></pre>
<p>As result you get this:</p>
<pre><code>1brr    Bacteriorhodopsin - Halobacterium salinarum (strain ATCC 700922 / JCM 11081 / NRC-1)
4lzm    Endolysin - Enterobacteria phage T4
2dyi    Ribosome maturation factor RimM - Thermus thermophilus (strain HB8 / ATCC 27634 / DSM 579)
</code></pre>

CC BY-SA 4.0
2020-11-04T19:56:48.523Z
`sed` should also be available for you. You can install `jq` and `parallel` with `brew`
Mr_Z
CC BY-SA 4.0
2020-11-05T12:52:17.957Z
Many thanks. Got this running. Only problem is that on OS X the \t tab escape does not work (it is apparently non-standard) and none of the [answers here](https://unix.stackexchange.com/questions/145299/simple-sed-replacement-of-tabs-mysteriously-failing) worked for me. However it is easy enough to insert a tab after the four-character PDB ID programmatically.
David
CC BY-SA 4.0
2020-11-05T12:59:27.667Z
Check this answer https://stackoverflow.com/a/6392271 for your tab problem.
Mr_Z
CC BY-SA 4.0
2020-11-07T16:58:28.707Z
Thanks again. I know it is bad form to ask supplementary questions, but could you possibly provide a link in your answer to the particular page in the API which describes the need to specify all of the four "dotted" terms. I went to https://www.ebi.ac.uk/proteins/api to try to find out how to construct a query to get the species (so I didn't have to ask) but must be looking in the wrong place. I can find an example XML for a protein under proteins/proteins that includes some of these terms, and various unpromising json thingies. NCBI provides intelligible APIs (or used to) — whereas EBI…
David
CC BY-SA 4.0
2020-11-07T19:49:07.750Z
I've updated my answer. The dotted format is not a problem of the API. It is just how `jq` is getting the keys from the `JSON` formatted result. https://stedolan.github.io/jq/manual/#Basicfilters gives you a basic overview of how to use `jq`.
Mr_Z
CC BY-SA 4.0
2020-11-04T16:41:34.437Z
2020-11-07T19:46:22.703Z
2020-11-07T19:46:22.703Z
Mr_Z
<p>I have a list of about 4000 PDB IDs and would like to get the actual names of the proteins (e.g. lactate dehydrogenase, cytochrome c). I tried the batch header section at the <a href="https://www.rcsb.org/downloads" rel="nofollow noreferrer">Protein Databank Download page</a> but it refused to accept my PDB IDs in formats (xxxx or xxxx.pdb, individually or space-separated) that worked in an interactive search for the protein structure.</p>
<p>Any suggestions?</p>

CC BY-SA 4.0
2020-10-31T13:08:47.987Z
Have you tried writing a PyMol script?
M__
CC BY-SA 4.0
2020-10-31T13:20:33.053Z
Perhaps you could use ftp://ftp.wwpdb.org/pub/pdb/derived_data/index/entries.idx which contains HEADER and COMPOUND fields extracted from all PDB entries.
marcin
CC BY-SA 4.0
2020-10-31T15:34:11.760Z
@Michael — Could you clarify please. A script tTo do what on what? And why in PyMol?
David
CC BY-SA 4.0
2020-10-31T15:40:24.700Z
@marcin — Thanks, but the problem with the HEADER and COMPOUND fields is that they are such utter unparsable anarchy. I could write a script to get these fields from all my pdb files, but take for example 102L — I would get as HEADER "HYDROLASE(O-GLYCOSYL)" (useless) and as COMPOUND "HOW AMINO-ACID INSERTIONS ARE ALLOWED IN AN ALPHA-HELIX OF T4 LYSOZYME ENTEROBACTERIA PHAGE T4" where the name of the protein — Lysozyme — is buried. The prehistoric format of pdb files is the problem, but surely someone, somewhere has done something with them.
David
CC BY-SA 4.0
2020-10-31T17:48:35.800Z
In which case, going from PDB to Uniprot using SIFTS [https://www.ebi.ac.uk/pdbe/docs/sifts/quick.html](https://www.ebi.ac.uk/pdbe/docs/sifts/quick.html) is the best bet as the Uniprot entries will have all the synonyms you could have for.
Matteo Ferla
CC BY-SA 4.0
2020-10-31T18:35:24.667Z
@MatteoFerla Thanks. Will check that out.
David
<protein-structure>
Get protein names corresponding to PDB ID
# Get protein names corresponding to PDB ID

(Asked by: username_0 on 2020-10-31)

I have a list of about 4000 PDB IDs and would like to get the actual names of the proteins (e.g. lactate dehydrogenase, cytochrome c). I tried the batch header section at the [Protein Databank Download page](https://www.rcsb.org/downloads) but it refused to accept my PDB IDs in formats (xxxx or xxxx.pdb, individually or space-separated) that worked in an interactive search for the protein structure.

Any suggestions?

**Tags:** protein-structure
> **Comments:**
> **username_1**: Have you tried writing a PyMol script?  
> **username_2**: Perhaps you could use ftp://ftp.wwpdb.org/pub/pdb/derived_data/index/entries.idx which contains HEADER and COMPOUND fields extracted from all PDB entries.  
> **username_0**: @Michael — Could you clarify please. A script tTo do what on what? And why in PyMol?  
> **username_0**: @marcin — Thanks, but the problem with the HEADER and COMPOUND fields is that they are such utter unparsable anarchy. I could write a script to get these fields from all my pdb files, but take for example 102L — I would get as HEADER "HYDROLASE(O-GLYCOSYL)" (useless) and as COMPOUND "HOW AMINO-ACID INSERTIONS ARE ALLOWED IN AN ALPHA-HELIX OF T4 LYSOZYME ENTEROBACTERIA PHAGE T4" where the name of the protein — Lysozyme — is buried. The prehistoric format of pdb files is the problem, but surely someone, somewhere has done something with them.  
> **username_3**: In which case, going from PDB to Uniprot using SIFTS [https://www.ebi.ac.uk/pdbe/docs/sifts/quick.html](https://www.ebi.ac.uk/pdbe/docs/sifts/quick.html) is the best bet as the Uniprot entries will have all the synonyms you could have for.  
> **username_0**: @MatteoFerla Thanks. Will check that out.  

---

## 2 answers

### Answer by username_5 on 2020-11-04. Score: 5 | Accepted answer

You can use one of the UniProt Protein APIs.
As you said you have your pdb entries in a text file line by line you can, like this example.txt containing:
1brr
4lzm
2dyi

Using the commandline, you can use a little script like this to download the name, if it is available for the given pdb entry.
while read line;
do 
 curl -X GET --header 'Accept:application/json' "https://www.ebi.ac.uk/proteins/api/proteins/pdb:$line" | 
 jq -r '.[].protein.recommendedName.fullName.value'  |
 sed "s/^/$line\t/" >> pdb_names.txt;
done < example.txt;

You need to have curl, sed and jq installed on your system.
This gives you following output in pdb_names.txt
1brr    Bacteriorhodopsin
4lzm    Endolysin
2dyi    Ribosome maturation factor RimM


Update
if you want to speed it up, you can run it with parallel.
parallel -j 4 'curl -X GET --header "Accept:application/json" "https://www.ebi.ac.uk/proteins/api/proteins/pdb:{}" |   jq -r ".[]. .protein.recommendedName.fullName.value"  |  sed "s/^/{}\t/" >> pdb_names_parallel.txt' :::: example.txt

With the -j option you call how many jobs should run in parallel. The limit of the UniProt API is 200 request per second per user.

Update 7. Nov 2020
To get another info beside the protein name, you need to know how the JSON response from UniProt looks like.
To get also the scientific name, you can run following command:
parallel -j 4 'curl -X GET --header "Accept:application/json" "https://www.ebi.ac.uk/proteins/api/proteins/pdb:{}" | jq -r ".[] | .protein.recommendedName.fullName.value + \" - \" + .organism.names[0].value"  |  sed "s/^/{}\t/" >> pdb_names_parallel.txt' :::: example.txt

As result you get this:
1brr    Bacteriorhodopsin - Halobacterium salinarum (strain ATCC 700922 / JCM 11081 / NRC-1)
4lzm    Endolysin - Enterobacteria phage T4
2dyi    Ribosome maturation factor RimM - Thermus thermophilus (strain HB8 / ATCC 27634 / DSM 579)

> **Comments:**
> **username_5**: `sed` should also be available for you. You can install `jq` and `parallel` with `brew`  
> **username_0**: Many thanks. Got this running. Only problem is that on OS X the \t tab escape does not work (it is apparently non-standard) and none of the [answers here](https://unix.stackexchange.com/questions/145299/simple-sed-replacement-of-tabs-mysteriously-failing) worked for me. However it is easy enough to insert a tab after the four-character PDB ID programmatically.  
> **username_5**: Check this answer https://stackoverflow.com/a/6392271 for your tab problem.  
> **username_0**: Thanks again. I know it is bad form to ask supplementary questions, but could you possibly provide a link in your answer to the particular page in the API which describes the need to specify all of the four "dotted" terms. I went to https://www.ebi.ac.uk/proteins/api to try to find out how to construct a query to get the species (so I didn't have to ask) but must be looking in the wrong place. I can find an example XML for a protein under proteins/proteins that includes some of these terms, and various unpromising json thingies. NCBI provides intelligible APIs (or used to) — whereas EBI…  
> **username_5**: I've updated my answer. The dotted format is not a problem of the API. It is just how `jq` is getting the keys from the `JSON` formatted result. https://stedolan.github.io/jq/manual/#Basicfilters gives you a basic overview of how to use `jq`.  

---

### Answer by username_4 on 2020-10-31. Score: 2

Assuming you can use R, have you tried with biomaRt? For example, using 2bhl (my PhD lover :D)
library(biomaRt)
ensembl <- useMart("ensembl",dataset="hsapiens_gene_ensembl")

# get list of all available info
filters <- listFilters(ensembl)
attributes <- listAttributes(ensembl)

getBM(attributes=c('hgnc_symbol','ensembl_gene_id','entrezgene_id',
                'protein_id','description',"superfamily"), 
      filters = 'pdb', 
      values = "2bhl", 
      mart = ensembl)

Returns
hgnc_symbol ensembl_gene_id entrezgene_id protein_id description
1         G6PD ENSG00000160211          2539   ADO22353 glucose-6-phosphate dehydrogenase [Source:HGNC Symbol;Acc:HGNC:4057]
2         G6PD ENSG00000160211          2539   CAA27309 glucose-6-phosphate dehydrogenase [Source:HGNC Symbol;Acc:HGNC:4057]
3         G6PD ENSG00000160211          2539   AAA63175 glucose-6-phosphate dehydrogenase [Source:HGNC Symbol;Acc:HGNC:4057]
4         G6PD ENSG00000160211          2539   AAA52500 glucose-6-phosphate dehydrogenase [Source:HGNC Symbol;Acc:HGNC:4057]
5         G6PD ENSG00000160211          2539   AAA52501 glucose-6-phosphate dehydrogenase [Source:HGNC Symbol;Acc:HGNC:4057]
6         G6PD ENSG00000160211          2539   CAA39089 glucose-6-phosphate dehydrogenase [Source:HGNC Symbol;Acc:HGNC:4057]
7 ...

I am sure if you look at all the available filters and attributes, you can pinpoint the ID you are looking for.

> **Comments:**
> **username_0**: Thanks. I can reproduce that, but only paint by numbers with R. How would I modify that to loop through a list of 4000 proteins and ensure the pdb ID was included in the output?  
> **username_4**: You can add `'pdb'` to the list of attributes. That will add a column with the pdb id. `c('pdb','hgnc_symbol',....),`  
> **username_0**: Ok. Get it. Thanks.  
> **username_4**: I am not sure how your input file is (csv, vector, data.frame), but to run on multiple pdbs, you need to change your`values` (`values= c("2bhl","pdbID2","pdbID3",...)`)  
> **username_0**: My input is just a text file of filenames, one per line, generated from a unix ls command. I can convert it into a string of the type you suggest, although I wonder if there is any limit on the length of such strings. Referencing a text file would be preferable if it is possible.  
> **username_4**: I think the limit is 500 values x query, bu the newest versions of biomaRt should automatically split for you. I am not 100% sure, so you may want to double check. You can `ls *.pdb >> all_pdbs.txt` , use `all_pdb_list <- read.delim("./all_pdbs.txt")` to read `all_pdbs.txt` , and `gsub` to remove the extension from your entries (`gsub(".pdb","", all_pdb_list)`) .  

---

