Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-10-31T18:34:30.587Z
Answers.Text: 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?
Answers.UserDisplayName: David
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-10-31T22:51:31.463Z
Answers.Text: You can add `'pdb'` to the list of attributes. That will add a column with the pdb id. `c('pdb','hgnc_symbol',....),`
Answers.UserDisplayName: fra
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-11-01T00:39:38.127Z
Answers.Text: Ok. Get it. Thanks.
Answers.UserDisplayName: David
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-11-01T11:05:57.250Z
Answers.Text: 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",...)`)
Answers.UserDisplayName: fra
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-11-01T11:43:39.970Z
Answers.Text: 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.
Answers.UserDisplayName: David
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-11-02T10:38:26.953Z
Answers.Text: 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)`) .
Answers.UserDisplayName: fra
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-10-31T16:11:32.100Z
Answers.LastActivityDate: 2020-10-31T16:11:32.100Z
Answers.UserDisplayName: fra
Answers.Body: <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>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-11-04T19:56:48.523Z
Answers.Text: `sed` should also be available for you. You can install `jq` and `parallel` with `brew`
Answers.UserDisplayName: Mr_Z
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-11-05T12:52:17.957Z
Answers.Text: 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.
Answers.UserDisplayName: David
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-11-05T12:59:27.667Z
Answers.Text: Check this answer https://stackoverflow.com/a/6392271 for your tab problem.
Answers.UserDisplayName: Mr_Z
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-11-07T16:58:28.707Z
Answers.Text: 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…
Answers.UserDisplayName: David
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-11-07T19:49:07.750Z
Answers.Text: 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`.
Answers.UserDisplayName: Mr_Z
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-11-04T16:41:34.437Z
Answers.LastActivityDate: 2020-11-07T19:46:22.703Z
Answers.LastEditDate: 2020-11-07T19:46:22.703Z
Answers.UserDisplayName: Mr_Z
Body: <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>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-10-31T13:08:47.987Z
Comments.Text: Have you tried writing a PyMol script?
Comments.UserDisplayName: M__
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-10-31T13:20:33.053Z
Comments.Text: 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.
Comments.UserDisplayName: marcin
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-10-31T15:34:11.760Z
Comments.Text: @Michael — Could you clarify please. A script tTo do what on what? And why in PyMol?
Comments.UserDisplayName: David
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-10-31T15:40:24.700Z
Comments.Text: @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.
Comments.UserDisplayName: David
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-10-31T17:48:35.800Z
Comments.Text: 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.
Comments.UserDisplayName: Matteo Ferla
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-10-31T18:35:24.667Z
Comments.Text: @MatteoFerla Thanks. Will check that out.
Comments.UserDisplayName: David
Tags: <protein-structure>
Title: Get protein names corresponding to PDB ID
ThreadText: # 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**: @username_2 — 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**: @username_3 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](https://www.ebi.ac.uk/proteins/api/doc/#!/proteins/getByCrossReference).
  
  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)`) .  
  
  ---
  
  