<p>I don't know how to do this with biopython, but it's simple enough in Perl using <a href="http://swissknife.sourceforge.net/" rel="nofollow noreferrer">Swisskinfe</a>:</p>

<pre class="lang-perl prettyprint-override"><code>#!/usr/bin/env perl
use strict;
use warnings;
use SWISS::Entry;

my $flat=$ARGV[0]||die("Need a flat file\n");

## Change the line termination string so we read an 
## entire entry at a time
local $/ = "\n//\n";

my $fh;
## Deal with compressed or uncompressed files
if($flat=~/\.gz$/){
    open($fh,"zcat $flat |")|| die("cannot open flat file $flat : $! \n");
}
else{
    open($fh,"$flat")|| die("cannot open flat file $flat : $!: $@\n");
}
## Parse the file. 
entry: while (my $current_entry = &lt;$fh&gt;) {
    ## Read the current entry as an "entry" object
    my $entry = SWISS::Entry-&gt;fromText($current_entry);
    ## Iterate over the entry's features
    foreach my $feature ($entry-&gt;FTs-&gt;elements()) {
        ## If any of the features are 'TRANSMEM', print the entry
        if ($feature-&gt;[0] eq 'TRANSMEM') {
            print "$current_entry\n";
            ## Skip to the next entry
            next entry;
        }
    }
}
</code></pre>

<p>You need to install the Swissknife module first:</p>

<ol>
<li><p>Download Swissknife_1.73.tar.gz from <a href="https://sourceforge.net/projects/swissknife/files/latest/download" rel="nofollow noreferrer">here</a> (SourceForge link).</p></li>
<li><p>Install</p>

<pre><code>tar xvzf Swissknife.tar.gz
cd Swissknife_1.73/
perl Makefile.PL
sudo make install
</code></pre></li>
</ol>

<p>Now, make the script above executable and run with:</p>

<pre><code>foo.pl file.flat
</code></pre>

CC BY-SA 3.0
2017-06-29T11:26:35.603Z
2017-06-29T11:33:38.093Z
2017-06-29T11:33:38.093Z
terdon
<p>Using <code>SeqIO.index</code> rather than <code>SeqIO.parse</code> lets you read all the records into a <code>dict</code>, from which you can then extract the raw entry:</p>

<pre class="lang-python prettyprint-override"><code>from Bio import SeqIO

record_dict = SeqIO.index('Input.txt', 'swiss')
for key in record_dict:
    print(record_dict.get_raw(key).decode())
</code></pre>

<p>Now you should be able to apply your test for a transmembrane protein to each entry, and write out only the ones you want to keep.</p>

<pre class="lang-python prettyprint-override"><code>from Bio import SeqIO

record_dict = SeqIO.index('Input.txt', 'swiss')
out = open('Output.txt', 'wb')
for key in record_dict:
    record = record_dict[key]
    for i, feature in enumerate(record.features):
    if feature.type == "TRANSMEM":
        out.write(record_dict.get_raw(key).decode())
</code></pre>

CC BY-SA 3.0
2017-06-30T04:12:04.307Z
Perfect solution, worked like a charm.
James
CC BY-SA 3.0
2017-06-29T11:14:06.497Z
2017-06-29T11:14:06.497Z
sjcockell
<p>I have the following mwe for filtering a Swissprot file based on a certain feature, in this case, transmembrane regions. </p>

<pre><code>from Bio import SeqIO
records=[]
for record in SeqIO.parse("Input.txt", "swiss"):
    transmembrane_protein=False
    print record.id
    for i, feature in enumerate(record.features):
        if feature.type == "TRANSMEM":
            transmembrane_protein=True
    if transmembrane_protein==True:
        records.append(record)
SeqIO.write(records, "Output.txt", "swiss")
</code></pre>

<p>The script works when <code>SeqIO.write(records, "Output.txt", "swiss")</code> becomes <code>SeqIO.write(records, "Output.txt", "fasta")</code></p>

<p>However, such a method is not yet supported.  </p>

<pre><code>ValueError: Reading format 'swiss' is supported, but not writing
</code></pre>

<p>From the docs, I see that <a href="http://biopython.org/DIST/docs/api/Bio.SeqIO-module.html" rel="nofollow noreferrer">writing is not supported for swiss</a>:</p>

<blockquote>
  <p>Note that while Bio.SeqIO can read all the above file formats, it cannot write to all of them.</p>
</blockquote>

<p>Is there any unofficial way of using biopython/python to write swissprot files from parsed swissprot files? </p>

CC BY-SA 3.0
2017-06-29T09:12:53.440Z
I read that "SeqIO cannot output the file format (e.g. the plain text SwissProt format, "swiss") ". But you could paste the proteins without using Biopython once you know the id of the features you want
llrs
CC BY-SA 3.0
2017-06-29T09:20:23.733Z
It must be in some of the docs somewhere I'm sure, I just haven't seen it explicitly stated, but it is pointed out in the error handling so that's good enough for me to know there is no easy way. I'm dealing with several proteomes. Manual pasting wouldn't be fun ;) I could really do with a programmatic solution.
James
CC BY-SA 3.0
2017-06-29T09:22:05.313Z
You could use grep, or awk to select the records and output them in another file using a pipe.
llrs
CC BY-SA 3.0
2017-06-29T09:59:25.013Z
@Llopis That would certainly be one way forward. However I'd like to keep the script in a single python file because it's cross platform and transportable.
James
<database><python>
Is there any way of using biopython to write Swissprot files?
# Is there any way of using biopython to write Swissprot files?

(Asked by: username_0 on 2017-06-29)

I have the following mwe for filtering a Swissprot file based on a certain feature, in this case, transmembrane regions. 
from Bio import SeqIO
records=[]
for record in SeqIO.parse("Input.txt", "swiss"):
    transmembrane_protein=False
    print record.id
    for i, feature in enumerate(record.features):
        if feature.type == "TRANSMEM":
            transmembrane_protein=True
    if transmembrane_protein==True:
        records.append(record)
SeqIO.write(records, "Output.txt", "swiss")

The script works when SeqIO.write(records, "Output.txt", "swiss") becomes SeqIO.write(records, "Output.txt", "fasta")
However, such a method is not yet supported.  
ValueError: Reading format 'swiss' is supported, but not writing

From the docs, I see that writing is not supported for swiss:

Note that while Bio.SeqIO can read all the above file formats, it cannot write to all of them.

Is there any unofficial way of using biopython/python to write swissprot files from parsed swissprot files?

**Tags:** database, python
> **Comments:**
> **username_1**: I read that "SeqIO cannot output the file format (e.g. the plain text SwissProt format, "swiss") ". But you could paste the proteins without using Biopython once you know the id of the features you want  
> **username_0**: It must be in some of the docs somewhere I'm sure, I just haven't seen it explicitly stated, but it is pointed out in the error handling so that's good enough for me to know there is no easy way. I'm dealing with several proteomes. Manual pasting wouldn't be fun ;) I could really do with a programmatic solution.  
> **username_1**: You could use grep, or awk to select the records and output them in another file using a pipe.  
> **username_0**: @Llopis That would certainly be one way forward. However I'd like to keep the script in a single python file because it's cross platform and transportable.  

---

## 2 answers

### Answer by username_3 on 2017-06-29. Score: 6 | Accepted answer

Using SeqIO.index rather than SeqIO.parse lets you read all the records into a dict, from which you can then extract the raw entry:
from Bio import SeqIO

record_dict = SeqIO.index('Input.txt', 'swiss')
for key in record_dict:
    print(record_dict.get_raw(key).decode())

Now you should be able to apply your test for a transmembrane protein to each entry, and write out only the ones you want to keep.
from Bio import SeqIO

record_dict = SeqIO.index('Input.txt', 'swiss')
out = open('Output.txt', 'wb')
for key in record_dict:
    record = record_dict[key]
    for i, feature in enumerate(record.features):
    if feature.type == "TRANSMEM":
        out.write(record_dict.get_raw(key).decode())

> **Comments:**
> **username_0**: Perfect solution, worked like a charm.  

---

### Answer by username_2 on 2017-06-29. Score: 2

I don't know how to do this with biopython, but it's simple enough in Perl using Swisskinfe:
#!/usr/bin/env perl
use strict;
use warnings;
use SWISS::Entry;

my $flat=$ARGV[0]||die("Need a flat file\n");

## Change the line termination string so we read an 
## entire entry at a time
local $/ = "\n//\n";

my $fh;
## Deal with compressed or uncompressed files
if($flat=~/\.gz$/){
    open($fh,"zcat $flat |")|| die("cannot open flat file $flat : $! \n");
}
else{
    open($fh,"$flat")|| die("cannot open flat file $flat : $!: $@\n");
}
## Parse the file. 
entry: while (my $current_entry = <$fh>) {
    ## Read the current entry as an "entry" object
    my $entry = SWISS::Entry->fromText($current_entry);
    ## Iterate over the entry's features
    foreach my $feature ($entry->FTs->elements()) {
        ## If any of the features are 'TRANSMEM', print the entry
        if ($feature->[0] eq 'TRANSMEM') {
            print "$current_entry\n";
            ## Skip to the next entry
            next entry;
        }
    }
}

You need to install the Swissknife module first:

Download Swissknife_1.73.tar.gz from here (SourceForge link).
Install
tar xvzf Swissknife.tar.gz
cd Swissknife_1.73/
perl Makefile.PL
sudo make install


Now, make the script above executable and run with:
foo.pl file.flat


---

