Commit 1f44238f authored by Bertrand  NÉRON's avatar Bertrand NÉRON
Browse files

add exercises with data and solutions

parent 43e22266
...@@ -37,23 +37,35 @@ The sequence of the binding site must be cleaned up. ...@@ -37,23 +37,35 @@ The sequence of the binding site must be cleaned up.
Exercise Exercise
-------- --------
write a function which take the path of a fasta file write a function which take the path of a fasta file (containing only one sequence)
and return a data structure of your choice that allow to stock and return a data structure of your choice that allow to stock
the id of the sequence and the sequence itself. the id of the sequence and the sequence itself.
:download:`seq.fasta <_static/data/seq.fasta>` . use the file :download:`seq.fasta <_static/data/seq.fasta>` to test your code.
solution 1
""""""""""
.. literalinclude:: _static/code/fasta_reader.py .. literalinclude:: _static/code/fasta_reader.py
:linenos: :linenos:
:language: python :language: python
:download:`fasta_reader.py <_static/code/fasta_reader.py>` . :download:`fasta_reader.py <_static/code/fasta_reader.py>` .
solution 2 Exercise
"""""""""" --------
Modify the code at the previous exercise to read multiple sequences fasta file.
use the file :download:`abcd.fasta <_static/data/abcd.fasta>` to test your code.
solution 1
^^^^^^^^^^
.. literalinclude:: _static/code/multiple_fasta_reader.py
:linenos:
:language: python
:download:`fasta_iterator.py <_static/code/multiple_fasta_reader.py>`
solution 2
^^^^^^^^^^
.. literalinclude:: _static/code/fasta_iterator.py .. literalinclude:: _static/code/fasta_iterator.py
:linenos: :linenos:
:language: python :language: python
...@@ -63,12 +75,33 @@ solution 2 ...@@ -63,12 +75,33 @@ solution 2
The second version is an iterator. Thus it retrun sequence by sequence the advantage of this version. The second version is an iterator. Thus it retrun sequence by sequence the advantage of this version.
If the file contains lot of sequences you have not to load all the file in memory. If the file contains lot of sequences you have not to load all the file in memory.
You can call this function and put in in a loop or call next. work with the sequence and pass to the next sequence on so on. You can call this function and put in in a loop or call next.
Work with the sequence and pass to the next sequence on so on.
for instance : :: for instance : ::
for seq in fasta_iter('my_fast_file.fasta'): for seq in fasta_iter('my_fast_file.fasta'):
print seq print seq
Exercise
--------
Read a multiple sequence file in fasta format and write to a new file, one sequence by file,
only sequences starting with methionine and containing at least six tryptophanes (W).
(*you should create files for sequences: ABCD1_HUMAN, ABCD1_MOUSE, ABCD2_HUMAN, ABCD2_MOUSE, ABCD2_RAT, ABCD4_HUMAN, ABCD4_MOUSE*)
bonus
^^^^^
Write sequences with 80 aa/line
.. literalinclude:: _static/code/fasta_filter.py
:linenos:
:language: python
:download:`fasta_iterator.py <_static/code/fasta_filter.py>` .
Exercise Exercise
-------- --------
...@@ -87,8 +120,8 @@ query start, query end, subject start, subject end, Expect value, HSP bit score. ...@@ -87,8 +120,8 @@ query start, query end, subject start, subject end, Expect value, HSP bit score.
(adapted from *managing your biological data with python* p138) :: (adapted from *managing your biological data with python* p138) ::
.. literalinclude:: _static/code/parse_blast_output.py .. literalinclude:: _static/code/parse_blast.py
:linenos: :linenos:
:language: python :language: python
:download:`parse_blast_output.py <_static/code/parse_blast_output.py>` . :download:`parse_blast.py <_static/code/parse_blast.py>` .
\ No newline at end of file \ No newline at end of file
import sys
import os
from collections import namedtuple
from itertools import groupby
Sequence = namedtuple("Sequence", "id comment sequence")
def fasta_iter(fasta_path):
"""
:param fasta_file: the file containing all input sequences in fasta format.
:type fasta_file: file object
:author: http://biostar.stackexchange.com/users/36/brentp
:return: for a given fasta file, it returns an iterator which yields tuples
(string id, string comment, int sequence length)
:rtype: iterator
"""
with open(fasta_path) as fasta_file:
# ditch the boolean (x[0]) and just keep the header or sequence since
# we know they alternate.
group = (x[1] for x in groupby(fasta_file , lambda line: line[0] == ">"))
for header in group:
# drop the ">"
header = header.next()[1:].strip()
header = header.split()
_id = header[0]
comment = ' '.join(header[1:])
seq = ''.join(s.strip() for s in group.next())
yield Sequence(_id, comment, seq)
def fasta_writer(sequence, fasta_path):
"""
write a sequence in a file in fasta format
:param sequence: the sequence to print
:type sequence: Sequence instance
:param fasta_path: the path to the file to print the sequence in
:type fasta_path: string
"""
print "appel de fasta_writer ",sequence.id, " ",fasta_path
with open(fasta_path, 'w') as output:
output.write('>{0.id} {0.comment}\n'.format(seq))
start = 0
while start < len(seq.sequence):
end = start + 80
print start, " : ", end
output.write(seq.sequence[start: end + 1] + '\n')
start = end
if __name__ == '__main__':
if len(sys.argv) != 2:
sys.exit("usage: fasta_filter path/to/fasta/file/to/read")
input_path = sys.argv[1]
for seq in fasta_iter(input_path):
if seq.sequence.startswith('M') and seq.sequence.count('W') > 6:
if os.path.exists(seq.id):
print >> sys.stderr , "file {0} already exist: sequence {0} skipped".format(seq.id)
continue
else:
output_fasta = seq.id + ".fa"
fasta_writer(seq, output_fasta)
\ No newline at end of file
...@@ -3,19 +3,22 @@ from collections import namedtuple ...@@ -3,19 +3,22 @@ from collections import namedtuple
Sequence = namedtuple("Sequence", "id comment sequence") Sequence = namedtuple("Sequence", "id comment sequence")
def fasta_reader(fasta_path): def fasta_reader(fasta_path):
"""
:param fasta_path: the path to the file to parse
:type fasta_path: string
:return: a sequence
:rtype: Sequence instance
"""
with open(fasta_path, 'r') as fasta_infile: with open(fasta_path, 'r') as fasta_infile:
id = '' id_ = ''
comment = '' comment = ''
sequence = '' sequence = ''
in_sequence = False
for line in fasta_infile: for line in fasta_infile:
if line.startswith('>'): if line.startswith('>'):
header = line.split() header = line.split()
id = header[0] id_ = header[0]
comment = ' '.join(header[1:]) comment = ' '.join(header[1:])
in_sequence = True in_sequence = True
elif in_sequence:
sequence += line.strip()
else: else:
continue sequence += line.strip()
return Sequence(id , comment, sequence) return Sequence(id_ , comment, sequence)
\ No newline at end of file \ No newline at end of file
from collections import namedtuple
Sequence = namedtuple("Sequence", "id comment sequence")
def fasta_reader(fasta_path):
"""
:param fasta_path: the path to the file to parse
:type fasta_path: string
:return: the list of sequences read from the file
:rtype: list of Sequence
"""
sequences = []
with open(fasta_path, 'r') as fasta_infile:
id_ = ''
comment = ''
sequence = ''
for line in fasta_infile:
if line.startswith('>'):
# a new sequence begin
if id_ != '':
# a sequence was already parsed so add it to the list
sequences.append(Sequence(id_ , comment, sequence))
sequence = ''
header = line.split()
id_ = header[0]
comment = ' '.join(header[1:])
else:
sequence += line.strip()
#append the last sequence of the file to the list
sequences.append(Sequence(id_ , comment, sequence))
return sequences
\ No newline at end of file
>ABCD3_HUMAN ATP-binding cassette sub-family D member 3 (70 kDa peroxisomal membrane protein) (PMP70)
MAAFSKYLTARNSSLAGAAFLLLCLLHKRRRALGLHGKKSGKPPLQNNEKEGKKERAVVDKVFFSRLIQILKIMVPRTFC
KETGYLVLIAVMLVSRTYCDVWMIQNGTLIESGIIGRSRKDFKRYLLNFIAAMPLISLVNNFLKYGLNELKLCFRVRLTK
YLYEEYLQAFTYYKMGNLDNRIANPDQLLTQDVEKFCNSVVDLYSNLSKPFLDIVLYIFKLTSAIGAQGPASMMAYLVVS
GLFLTRLRRPIGKMTITEQKYEGEYRYVNSRLITNSEEIAFYNGNKREKQTVHSVFRKLVEHLHNFILFRFSMGFIDSII
AKYLATVVGYLVVSRPFLDLSHPRHLKSTHSELLEDYYQSGRMLLRMSQALGRIVLAGREMTRLAGFTARITELMQVLKD
LNHGKYERTMVSQQEKGIEGVQVIPLIPGAGEIIIADNIIKFDHVPLATPNGDVLIRDLNFEVRSGANVLICGPNGCGKS
SLFRVLGELWPLFGGRLTKPERGKLFYVPQRPYMTLGTLRDQVIYPDGREDQKRKGISDLVLKEYLDNVQLGHILEREGG
WDSVQDWMDVLSGGEKQRMAMARLFYHKPQFAILDECTSAVSVDVEGYIYSHCRKVGITLFTVSHRKSLWKHHEYYLHMD
GRGNYEFKQITEDTVEFGS
>ABCD3_RAT ATP-binding cassette sub-family D member 3 (70 kDa peroxisomal membrane protein) (PMP70)
MAAFSKYLTARNSSLAGAAFLLFCLLHKRRRALGLHGKKSGKPPLQNNEKEGKKERAVVDKVFLSRLSQILKIMVPRTFC
KETGYLILIAVMLVSRTYCDVWMIQNGTLIESGIIGRSSKDFKRYLFNFIAAMPLISLVNNFLKYGLNELKLCFRVRLTR
YLYEEYLQAFTYYKMGNLDNRIANPDQLLTQDVEKFCNSVVDLYSNLSKPFLDIVLYIFKLTSAIGAQGPASMMAYLLVS
GLFLTRLRRPIGKMTIMEQKYEGEYRFVNSRLITNSEEIAFYNGNKREKQTIHSVFRKLVEHLHNFIFFRFSMGFIDSII
AKYIATVVGYLVVSRPFLDLAHPRHLHSTHSELLEDYYQSGRMLLRMSQALGRIVLAGREMTRLAGFTARITELMQVLKD
LNHGKYERTMVSQQDKGIEGAQASPLIPGAGEIINADNIIKFDHVPLATPNGDILIQDLSFEVRSGANVLICGPNGCGKS
SLFRVLGELWPLFGGHLTKPERGKLFYVPQRPYMTLGTLRDQVIYPDGKEDQKKKGISDQVLKGYLDNVQLGHILEREGG
WDSVQDWMDVLSGGEKQRMAMARLFYHKPQFAILDECTSAVSVDVEDYIYSHCRKVGITLFTVSHRKSLWKHHEYYLHMD
GRGNYEFKKITEDTVEFGS
>ABCD3_MOUSE ATP-binding cassette sub-family D member 3 (70 kDa peroxisomal membrane protein) (PMP70) (PMP68)
MAAFSKYLTARNTSLAGAAFLLLCLLHKRRRALGLHGKKSGKPPLQNNEKEGKKERAVVDKVFLSRLSQILKIMVPRTFC
KETGYLLLIAVMLVSRTYCDVWMIQNGTLIESGIIGRSSKDFKRYLFNFIAAMPLISLVNNFLKYGLNELKLCFRVRLTR
YLYEEYLQAFTYYKMGNLDNRIANPDQLLTQDVEKFCNSVVDLYSNLSKPFLDIVLYIFKLTSAIGAQGPASMMAYLLVS
GLFLTRLRRPIGKMTIMEQKYEGEYRYVNSRLITNSEEIAFYNGNKREKQTIHSVFRKLVEHLHNFIFFRFSMGFIDSII
AKYVATVVGYLVVSRPFLDLAHPRHLHSTHSELLEDYYQSGRMLLRMSQALGRIVLAGREMTRLAGFTARITELMQVLKD
LNHGRYERTMVSQQGKGIEGAQASPLVPGAGEIINTDNIIKFDHVPLATPNGDILIQDLSFEVRSGNHVLICGPNGRGKS
SLFRVLGELWPLFGGRLTKPERGKLFYVPQRPYMTLGTLRDQVIYPDGKEDQKKRGISDQVLKEYLDNVQLGHILEREGG
WDSVQDWMDVLSGGEKQRMAMARLFYHKPQFAILDECTSAVSVDVEDYIYSHCRKVGITLFTVSHTKCLWKHHEYYLHMD
GRGNYEFKKITEDTVEFGS
>ABCD1_HUMAN ATP-binding cassette sub-family D member 1 (Adrenoleukodystrophy protein) (ALDP)
MPVLSRPRPWRGNTLKRTAVLLALAAYGAHKVYPLVRQCLAPARGLQAPAGEPTQEASGVAAAKAGMNRVFLQRLLWLLR
LLFPRVLCRETGLLALHSAALVSRTFLSVYVARLDGRLARCIVRKDPRAFGWQLLQWLLIALPATFVNSAIRYLEGQLAL
SFRSRLVAHAYRLYFSQQTYYRVSNMDGRLRNPDQSLTEDVVAFAASVAHLYSNLTKPLLDVAVTSYTLLRAARSRGAGT
AWPSAIAGLVVFLTANVLRAFSPKFGELVAEEARRKGELRYMHSRVVANSEEIAFYGGHEVELALLQRSYQDLASQINLI
LLERLWYVMLEQFLMKYVWSASGLLMVAVPIITATGYSESDAEAVKKAALEKKEEELVSERTEAFTIARNLLTAAADAIE
RIMSSYKEVTELAGYTARVHEMFQVFEDVQRCHFKRPRELEDAQAGSGTIGRSGVRVEGPLKIRGQVVDVEQGIICENIP
IVTPSGEVVVASLNIRVEEGMHLLITGPNGCGKSSLFRILGGLWPTYGGVLYKPPPQRMFYIPQRPYMSVGSLRDQVIYP
DSVEDMQRKGYSEQDLEAILDVVHLHHILQREGGWEAMCDWKDVLSGGEKQRIGMARMFYHRPKYALLDECTSAVSIDVE
GKIFQAAKDAGIALLSITHRPSLWKYHTHLLQFDGEGGWKFEKLDSAARLSLTEEKQRLEQQLAGIPKMQRRLQELCQIL
GEAVAPAHVPAPSPQGPGGLQGAST
>ABCD1_MOUSE ATP-binding cassette sub-family D member 1 (Adrenoleukodystrophy protein) (ALDP)
MPVLSTPRPSRVTTLKRTAVVLALTAYGVHKIYPLVRQCLTPARGPQVPAGEPTQEASGATATKAGMNRVFLQRLLALLR
LLFPRVLCRETGLLALHSAALVSRTFLSVYVARLDGRLARCIVRKDPRAFSWQLLQWLLIALPATFINSAIRYLEGQLAL
SFRSRLVAHAYGLYFSQQTYYRVSNMDGRLRNPDQSLTEDVVAFAASVAHLYSNLTKPLLDVAVTSYTLLRAARSRGAGT
AWPSAIAGLVVFLTANVLRAFSPKFGELVAEEARRKGELRYMHSRVVANSEEIAFYGGHEVELALLQHSYQDLASQINLI
LLERLWYVMLEQFLMKYVWSASGLLMVAVPIITATGYAESDSEAMKKAALEMKEEELVSERTEAFTIARNLLTAAADATE
RIMSSYKEVTELAGYTARVYEMFQVFEDVKHCRFKRTGDLEEAQAGPGVMVQSGVHVEGPLKIQGQVVDVEQGIICENIP
IITPTGEVVVASLNIRVEEGMHLLITGPNGCGKSSLFRILGGLWPTYSGVLYKPPPQRMFYIPQRPYMSVGSLRDQVIYP
DSAEDMRRKGCSEQQLEAILGIVHLRHILQREGGWEAVCDWKDVLSGGEKQRIGMARMFYHRPKYALLDECTSAVSIDVE
GKIFQAAKDAGIALLSITHRPSLWKYHTHLLQFDGEGGWKFEKLDSAARLSLTEEKQRLEQQLAGIPKMQGRLQELRQIL
GEAAAPVQPLVPGVPT
>ABCD2_HUMAN ATP-binding cassette sub-family D member 2 (Adrenoleukodystrophy-related protein) (hALDR) (Adrenoleukodystrophy-like 1)
MTHMLNAAADRVKWTRSSAAKRAACLVAAAYALKTLYPIIGKRLKQSGHGKKKAAAYPAAENTEILHCTETICEKPSPGV
NADFFKQLLELRKILFPKLVTTETGWLCLHSVALISRTFLSIYVAGLDGKIVKSIVEKKPRTFIIKLIKWLMIAIPATFV
NSAIRYLECKLALAFRTRLVDHAYETYFTNQTYYKVINMDGRLANPDQSLTEDIMMFSQSVAHLYSNLTKPILDVMLTSY
TLIQTATSRGASPIGPTLLAGLVVYATAKVLKACSPKFGKLVAEEAHRKGYLRYVHSRIIANVEEIAFYRGHKVEMKQLQ
KSYKALADQMNLILSKRLWYIMIEQFLMKYVWSSSGLIMVAIPIITATGFADGEDGQKQVMVSERTEAFTTARNLLASGA
DAIERIMSSYKEVTELAGYTARVYNMFWVFDEVKRGIYKRTAVIQESESHSKNGAKVELPLSDTLAIKGKVIDVDHGIIC
ENVPIITPAGEVVASRLNFKVEEGMHLLITGPNGCGKSSLFRILSGLWPVYEGVLYKPPPQHMFYIPQRPYMSLGSLRDQ
VIYPDSVDDMHDKGYTDQDLERILHNVHLYHIVQREGGWDAVMDWKDVLSGGEKQRMGMARMFYHKPKYALLDECTSAVS
IDVEGKIFQAAKGAGISLLSITHRPSLWKYHTHLLQFDGEGGWRFEQLDTAIRLTLSEEKQKLESQLAGIPKMQQRLNEL
CKILGEDSVLKTIKNEDETS
>ABCD2_MOUSE ATP-binding cassette sub-family D member 2 (Adrenoleukodystrophy-related protein)
MIHMLNAAAYRVKWTRSGAAKRAACLVAAAYALKTLYPIIGKRLKQPGHRKAKAEAYSPAENREILHCTEIICKKPAPGL
NAAFFKQLLELRKILFPKLVTTETGWLCLHSVALISRTFLSIYVAGLDGKIVKSIVEKKPRTFIIKLIKWLMIAIPATFV
NSAIRYLECKLALAFRTRLVDHAYETYFANQTYYKVINMDGRLANPDQSLTEDIMMFSQSVAHLYSNLTKPILDVILTSY
TLIRTATSRGASPIGPTLLAGLVVYATAKVLKACSPKFGSLVAEEAHRKGYLRYVHSRIIANVEEIAFYRGHKVEMKQLQ
KCYKALAYQMNLILSKRLWYIMIEQFLMKYVWSSCGLIMVAIPIITATGFADGDLEDGPKQAMVSDRTEAFTTARNLLAS
GADAIERIMSSYKEITELAGYTARVYNMFWVFDEVKRGIYKRTVTQEPENHSKRGGNLELPLSDTLAIKGTVIDVDHGII
CENVPIITPAGEVVASRLNFKVEEGMHLLITGPNGCGKSSLFRILSGLWPVYEGVLYKPPPQHMFYIPQRPYMSLGSLRD
QVIYPDSADDMREKGYTDQDLERILHSVHLYHIVQREGGWDAVMDWKDVLSGGEKQRMGMARMFYHKPKYALLDECTSAV
SIDVEGKIFQAAIGAGISLLSITHRPSLWKYHTHLLQFDGEGGWRFEQLDTAIRLTLSEEKQKLESQLAGIPKMQQRLNE
LCKILGEDSVLKTIQTPEKTS
>ABCD2_RAT ATP-binding cassette sub-family D member 2 (Adrenoleukodystrophy-related protein)
MIHMLNAAAYRVKWTRSGAAKRAACLVAAAYALKTLYPILGRRLKQPGHRKAKAEDYPPAENRERLHCTEIICKKPAPGL
NADFFKQLLELRKILFPKLVTTETGWLCLHSVALISRTFLSIYVAGLDGKIVKSIVEKKPRTFIIKLVKWLMIAVPATFV
NSAIRYLECKLALAFRTRLVDHAYETYFANQTYYKVINMDGRLANPDQSLTEDIMMFSQSVAHLYSNLTKPILDVILTSY
TLIRTATSRGASPIGPTLLAGLVVYATAKVLKACSPKFGTLVAEEAHRKGYLRYVHSRIIANVEEIAFYRGHKVEMKQLQ
KCYKALAYQMNLILSKRLWYIMIEQFLMKYVWSGCGLIMVAIPIITATGFADGDLEDGPKQAMVSDRTEAFTTARNLLAS
GADAIERIMSSYKEITELAGYTARVYNMFWVFDEVKRGIYKRTVTQEPENNSKSGGGLELPLSDTLAIKGTVIDVDHGIL
CENVPIITPAGEVVASSLNFKVEEGMHLLITGPNGCGKSSLFRILSGLWPVYEGVLYKPPPQHMFYIPQRPYMSLGSLRD
QVIYPDSVDDMHEKGYTDRDLEHILHSVHLYHIVQREGGWDAVMDWKDVLSGGEKQRMGMARMFYHKPKYALLDECTSAV
SIDVEGKIFQAAIGAGISLLSITHRPSLWKYHTHLLQFDGEGGWRFEQLDTAIRLTLSEEKQKLESQLAGIPKMQQRLNE
LCKILGEDSVLKTIQTAEDTS
>ABCD4_HUMAN ATP-binding cassette sub-family D member 4 (Peroxisomal membrane protein 69) (PMP69) (Peroxisomal membrane protein 1-like) (PXMP1-L) (P70R)
MAVAGPAPGAGARPRLDLQFLQRFLQILKVLFPSWSSQNALMFLTLLCLTLLEQFVIYQVGLIPSQYYGVLGNKDLEGFK
TLTFLAVMLIVLNSTLKSFDQFTCNLLYVSWRKDLTEHLHRLYFRGRAYYTLNVLRDDIDNPDQRISQDVERFCRQLSSM
ASKLIISPFTLVYYTYQCFQSTGWLGPVSIFGYFILGTVVNKTLMGPIVMKLVHQEKLEGDFRFKHMQIRVNAEPAAFYR
AGHVEHMRTDRRLQRLLQTQRELMSKELWLYIGINTFDYLGSILSYVVIAIPIFSGVYGDLSPAELSTLVSKNAFVCIYL
ISCFTQLIDLSTTLSDVAGYTHRIGQLRETLLDMSLKSQDCEILGESEWGLDTPPGWPAAEPADTAFLLERVSISAPSSD
KPLIKDLSLKISEGQSLLITGNTGTGKTSLLRVLGGLWTSTRGSVQMLTDFGPHGVLFLPQKPFFTDGTLREQVIYPLKE
VYPDSGSADDERILRFLELAGLSNLVARTEGLDQQVDWNWYDVLSPGEMQRLSFARLFYLQPKYAVLDEATSALTEEVES
ELYRIGQQLGMTFISVGHRQSLEKFHSLVLKLCGGGRWELMRIKVE
>ABCD4_MOUSE ATP-binding cassette sub-family D member 4 (Peroxisomal membrane protein 69) (PMP69) (Peroxisomal membrane protein 1-like) (PXMP1-L) (P70R)
MAVPGPTARAGARPRLDLQLVQRFVRIQKVFFPSWSSQNVLMLMTLLCVTLLEQLVIYQVGLIPSQYYGVLGNKDLDGFK
ALTLLAVTLIVLNSTLKSFDQFTCNLLYVSWRKDLTEHLHHLYFRARVYYTLNVLRDDIDNPDQRISQDVERFCRQLSSV
TSKLIISPFTLTYYTYQCFQSTGWLGPVSIFGYFIVGTMVNKTLMGPIVTKLVQQEKLEGDFRFKHMQIRVNAEPAAFYR
AGLVEHMRTDRRLQRLLQTQRELMSRELWLYIGINTFDYLGSILSYVVIAIPIFSGVYGDLSPTELSTLVSKNAFVCIYL
ISCFTQLIDLSTTLSDVAGYTHRIGELQEALLDMSRKSQDCEALGESEWDLDKTPGCPTTEPSDTAFLLDRVSILAPSSD
KPLIKDLSLKICEGQSLLITGNTGTGKTSLLRVLGGLWEGMKGSVQMLADFGPHGVLFLPQKPFFTDGTLREQVIYPLKE
IYPDSGSADDERIVRFLELAGLSSLVARTGGLDQQVDWNWYDVLSPGEMQRLSFARLFYLQPKYAVLDEATSALTEEAES
ELYRIGQQLGMTFISVGHRPSLEKFHSWVLRLHGGGSWELTRIKLE
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment