MSA Files¶
This part shows how to parse, refine, filter, slice, and write MSA files.
In [1]: from prody import *
In [2]: from matplotlib.pylab import *
In [3]: ion() # turn interactive mode on
Let’s get the Pfam MSA file for the protein family that contains PIWI_ARCFU:
Parsing MSA files¶
This shows how to use MSAFile
or parseMSA()
to read the
MSA file.
Reading using MSAFile
yields an MSAFile object. Iterating over the
object will yield an object of Sequence
from which labels, sequence
can be obtained. Like any file object, you can over iterate over a
MSAFile
object once.
In [4]: msafile = 'PF02171_seed.sth'
In [5]: msafobj = MSAFile(msafile)
In [6]: msafobj
Out[6]: <MSAFile: PF02171_seed (Stockholm; mode 'rt')>
In [7]: msa_seq_list = list(msafobj)
In [8]: msa_seq_list[0]
Out[8]: <Sequence: TAG76_CAEEL (length 395; 307 residues and 88 gaps)>
parseMSA()
returns an MSA
object. We can parse
compressed files, but reading uncompressed files is much faster.
In [9]: fetchPfamMSA('PF02171', compressed=True)
Out[9]: 'PF02171_full.sth.gz'
In [10]: parseMSA('PF02171_full.sth.gz')
Out[10]: <MSA: PF02171_full (2067 sequences, 1392 residues)>
In [11]: fetchPfamMSA('PF02171', format='fasta')
Out[11]: 'PF02171_full.fasta.gz'
In [12]: parseMSA('PF02171_full.fasta.gz')
Out[12]: <MSA: PF02171_full (2067 sequences, 1392 residues)>
Iterating over a file will yield sequence id, sequence, residue start and end indices:
In [13]: msa = MSAFile('PF02171_seed.sth')
In [14]: seq_list = [seq for seq in msa]
In [15]: seq_list
Out[15]:
[<Sequence: TAG76_CAEEL (length 395; 307 residues and 88 gaps)>,
<Sequence: O16720_CAEEL (length 395; 302 residues and 93 gaps)>,
<Sequence: AGO10_ARATH (length 395; 322 residues and 73 gaps)>,
<Sequence: AGO1_SCHPO (length 395; 300 residues and 95 gaps)>,
<Sequence: AGO6_ARATH (length 395; 311 residues and 84 gaps)>,
<Sequence: AGO4_ARATH (length 395; 309 residues and 86 gaps)>,
<Sequence: YQ53_CAEEL (length 395; 328 residues and 67 gaps)>,
<Sequence: Q21691_CAEEL (length 395; 329 residues and 66 gaps)>,
<Sequence: O62275_CAEEL (length 395; 331 residues and 64 gaps)>,
<Sequence: O16386_CAEEL (length 395; 300 residues and 95 gaps)>,
<Sequence: Q21495_CAEEL (length 395; 285 residues and 110 gaps)>,
<Sequence: O76922_DROME (length 395; 298 residues and 97 gaps)>,
<Sequence: PIWI_DROME (length 395; 292 residues and 103 gaps)>,
<Sequence: Q17567_CAEEL (length 395; 312 residues and 83 gaps)>,
<Sequence: PIWL1_HUMAN (length 395; 293 residues and 102 gaps)>,
<Sequence: PIWI_ARCFU (length 395; 297 residues and 98 gaps)>,
<Sequence: Y1321_METJA (length 395; 274 residues and 121 gaps)>,
<Sequence: O67434_AQUAE (length 395; 276 residues and 119 gaps)>]
Filtering and Slicing¶
This shows how to use the MSAFile
object or MSA
object to
refine MSA using filters and slices.
Filtering¶
Any function that takes label and sequence arguments and returns a boolean value can be used for filtering the sequences. A sequence will be yielded if the function returns True. In the following example, sequences from organism ARATH are filtered:
In [16]: msafobj = MSAFile(msafile, filter=lambda lbl, seq: 'ARATH' in lbl)
In [17]: seq_list2 = [seq for seq in msafobj]
In [18]: seq_list2
Out[18]:
[<Sequence: AGO10_ARATH (length 395; 322 residues and 73 gaps)>,
<Sequence: AGO6_ARATH (length 395; 311 residues and 84 gaps)>,
<Sequence: AGO4_ARATH (length 395; 309 residues and 86 gaps)>]
Slicing¶
A list of integers can be used to slice sequences as follows. This enables selective parsing of the MSA file.
In [19]: msafobj = MSAFile(msafile, slice=list(range(10)) + list(range(374,384)))
In [20]: list(msafobj)[0]
Out[20]: <Sequence: TAG76_CAEEL (length 20; 19 residues and 1 gaps)>
Slicing can also be done using MSA
. The MSA
object offers
other functionalities like querying, indexing, slicing row and columns and
refinement.
MSA objects¶
Indexing¶
Retrieving a sequence at a given index or by label will give an object of
Sequence
. Here’s an example using an index.
In [21]: msa = parseMSA(msafile)
In [22]: seq = msa[0]
In [23]: seq
Out[23]: <Sequence: TAG76_CAEEL (PF02171_seed[0]; length 395; 307 residues and 88 gaps)>
In [24]: str(seq)
Out[24]: 'CIIVVLQS.KNSDI.YMTVKEQSDIVHGIMSQCVLMKNVSRP.........TPATCANIVLKLNMKMGGIN..SRIVADKITNKYLVDQPTM.........VVGIDVTHPTQAEM.......RMNMPSVAAIVANVD.LLPQSYGANVKVQKKCRESVVY.LLD............AIRERIITFYRHTKQ.KPARIIVYRDGVSEGQFSEVLREEIQSIRTACL.......AIAEDFR..PPITYIVVQKRHHARIFCKYQNDM.....................VGKAKNVPPGTTV...DTGIVSPEGFDFYLCSHYGVQGTSRPARYHVLLDECKFTADEI.QSI......TYGMCHTYGRCT....RSVSIPTPVYYADLVATRARCHVK'
Here we retrieve a sequence by UniProt ID:
In [25]: msa['YQ53_CAEEL']
Out[25]: <Sequence: YQ53_CAEEL (PF02171_seed[6]; length 395; 328 residues and 67 gaps)>
Querying¶
You can query whether a sequence in contained in the instance using the UniProt identifier of the sequence as follows:
In [26]: 'YQ53_CAEEL' in msa
Out[26]: True
Slicing¶
Slice an MSA instance to give a new MSA
. object :
In [27]: new_msa = msa[:2]
In [28]: new_msa
Out[28]: <MSA: PF02171_seed (2 sequences, 395 residues)>
Slice using a list of UniProt IDs:
In [29]: msa[['TAG76_CAEEL', 'O16720_CAEEL']]
Out[29]: <MSA: PF02171_seed (2 sequences, 395 residues)>
Retrieve a character or a slice of a sequence:
In [30]: msa[0,0]
Out[30]: <Sequence: TAG76_CAEEL (length 1; 1 residues and 0 gaps)>
In [31]: msa[0,0:10]
Out[31]: <Sequence: TAG76_CAEEL (length 10; 9 residues and 1 gaps)>
Slice MSA rows and columns:
In [32]: msa[:10,20:40]
Out[32]: <MSA: PF02171_seed (10 sequences, 20 residues)>
Merging MSAs¶
mergeMSA()
can be used to merge two or more MSAs. Based on their labels
only those sequences that appear in both MSAs are retained, and concatenated
horizontally to give a joint or merged MSA. This can be useful while evaluating
covariance patterns for proteins with multiple domains or protein-protein
interactions. The example shows merging for the multi-domain receptor
3KG2 containing pfam domains PF01094 and PF00497.
In [33]: fetchPfamMSA('PF01094', alignment='seed')
Out[33]: 'PF01094_seed.sth'
In [34]: fetchPfamMSA('PF00497', alignment='seed')
Out[34]: 'PF00497_seed.sth'
Let’s parse and merge the two files:
In [35]: msa1 = parseMSA('PF01094_seed.sth')
In [36]: msa1
Out[36]: <MSA: PF01094_seed (69 sequences, 686 residues)>
In [37]: msa2 = parseMSA('PF00497_seed.sth')
In [38]: msa2
Out[38]: <MSA: PF00497_seed (231 sequences, 503 residues)>
In [39]: merged = mergeMSA(msa1, msa2)
In [40]: merged
The merged MSA contains 4889 sequences with common labels.
Writing MSAs¶
writeMSA()
can be used to write MSA. It takes filename as input
which should contain appropriate extension that can be ".slx"
or
".sth"
or ".fasta"
or format should be specified as "SELEX"
,
"Stockholm"
or "FASTA"
. Input MSA should be MSAFile
or
MSA
object. Filename can contain ".gz"
extension, in which case
a compressed file will be written.
In [41]: writeMSA('sliced_MSA.gz', msa, format='SELEX')
Out[41]: 'sliced_MSA.gz'
In [42]: writeMSA('sliced_MSA.fasta', msafobj)
Out[42]: 'sliced_MSA.fasta'
writeMSA()
returns the name of the MSA file that is written.