= COUNTRESIDUES =
Требуется написать программу, которая подсчитывает количество вхождений каждой из 20 аминокислот в исследуемый белок (точнее, в его pdb-файл). Выходные данные программы представляют собой словарь, ключ которого - pdb-код белка и аминокислота, а значение - количество вхождений.
Рассмотрев файл, можно увидеть, что в нем существуют строки "ATOM", описывающие состояние каждого атома в белке - в таких строках отделить аминокислотные остатки можно с помощью поиска C-альфа атомов. Просмотр каждой строки 'АТОМ' сперва кажется не таким эффективным. Рассматривая файл и документацию к формату можно заметить, что в файле существуют строки 'SEQRES', т.е. результаты секвенирования (?). Понятно, что не в каждом эксперименте возможно полностью определить аминокислотную последовательность в силу разнообразных факторов. Для того, чтобы это учесть, в строках 'REMARK' нужно найти раздел 'MISSING RESIDUES'. В его описании сказано, что в нем можно найти те остатки, которых нет в SEQRES - исследователи, выкладывавшие белок, не нашли их во время своего эксперимента. Гипотетически, сложив значения для каждой из аминокислот от строк 'SEQRES' и 'REMARK MISSING RESIDUES', можно получить схожие значения. Однако, не все так просто.
Строки АТОМ
Предлагаемый код делает так, как указано в задании и 'по инструкции' - проходит по файлам, ищет строки 'ATOM' и С-альфа атом в них (для различения аминокислот друг от друга):
def countresidues(pdbs): amac_count_dict = dict() amac_list = ['GLY', 'ALA', 'VAL', 'CYS', 'PRO', 'LEU', 'ILE', 'MET', 'TRP', 'TYR', 'THR', 'ARG', 'LYS', 'HIS', 'GLU', 'GLN', 'ASP', 'ASN', 'PHE', 'SER', 'PHE'] for filecounter in pdbs: current_file = open(filecounter, 'r') for amac in amac_list: amac_count_dict[filecounter[0:4], amac] = 0 for gline in current_file: if gline[0:4] == 'ATOM' and gline[12:16] == ' CA ': amac_count_dict[filecounter[0:4], gline[17:20]] +=1 current_file.close() return amac_count_dict
Рассмотрим, что выдаст данная программа на файл '5fdq.pdb' - pdb-файл COX-2:
mrbelyash@kodomo:~/term1/block2/homeworks$ python3 atom_strings.py 5fdq.pdb ('5fdq', 'GLY') ~~~ 74 ('5fdq', 'ALA') ~~~ 42 ('5fdq', 'VAL') ~~~ 62 ('5fdq', 'CYS') ~~~ 24 ('5fdq', 'PRO') ~~~ 72 ('5fdq', 'LEU') ~~~ 104 ('5fdq', 'ILE') ~~~ 62 ('5fdq', 'MET') ~~~ 26 ('5fdq', 'TRP') ~~~ 12 ('5fdq', 'TYR') ~~~ 54 ('5fdq', 'THR') ~~~ 66 ('5fdq', 'ARG') ~~~ 46 ('5fdq', 'LYS') ~~~ 66 ('5fdq', 'HIS') ~~~ 40 ('5fdq', 'GLU') ~~~ 74 ('5fdq', 'GLN') ~~~ 54 ('5fdq', 'ASP') ~~~ 44 ('5fdq', 'ASN') ~~~ 54 ('5fdq', 'PHE') ~~~ 72 ('5fdq', 'SER') ~~~ 56
SEQRES и REMARK
Предлагаемый код делает то, о чем было сказано выше: проходит по строкам файла, и в одном случае ищет строки 'SEQRES' - тогда он просто обновляет словарь для соответствующих аминокислот и файлов; в другом случае - ищет строку 'REMARK', содержащую 'MISSING RESIDUES' и вновь читает файл по строкам, которые начинаются с 'REMARK NUM', где NUM - номер ремарки, в которой нашлись 'потерянные остатки':
def countresidues(pdbs): amac_count_dict = dict() amac = ('GLY', 'ALA', 'VAL', 'CYS', 'PRO', 'LEU', 'ILE', 'MET', 'TRP', 'TYR', 'THR', 'ARG', 'LYS', 'HIS', 'GLU', 'GLN', 'ASP', 'ASN', 'SER', 'PHE') rem_num = 0 for filecounter in pdbs: filename = filecounter[0:4] for am in amac: amac_count_dict[filename, am] = 0 for filecounter in pdbs: current_file = open(filecounter, 'r') filename = filecounter[0:4] linelist = current_file.read().splitlines() for cline in linelist: if cline[0:6] == 'REMARK' and cline[11:27] == 'MISSING RESIDUES': rem_num = cline[7:10] for elem in linelist: if elem[0:6] == 'REMARK' and elem[7:10] == rem_num and elem[15:18] in amac: amac_count_dict[filename, elem[15:18]] +=1 if cline[0:6] == 'SEQRES': cline = cline.split()[4:] for element in cline: if element in amac: amac_count_dict[filename, element] += 1 current_file.close() return amac_count_dict
Рассмотрим, что выдаст данная программа на файл '5fdq.pdb' - pdb-файл COX-2:
mrbelyash@kodomo:~/term1/block2/homeworks$ python3 seqres_remark_strings.py 5fdq. ('5fdq', 'GLY') ~~~ 74 ('5fdq', 'ALA') ~~~ 58 ('5fdq', 'VAL') ~~~ 66 ('5fdq', 'CYS') ~~~ 24 ('5fdq', 'PRO') ~~~ 84 ('5fdq', 'LEU') ~~~ 116 ('5fdq', 'ILE') ~~~ 74 ('5fdq', 'MET') ~~~ 26 ('5fdq', 'TRP') ~~~ 12 ('5fdq', 'TYR') ~~~ 54 ('5fdq', 'THR') ~~~ 86 ('5fdq', 'ARG') ~~~ 58 ('5fdq', 'LYS') ~~~ 74 ('5fdq', 'HIS') ~~~ 58 ('5fdq', 'GLU') ~~~ 78 ('5fdq', 'GLN') ~~~ 62 ('5fdq', 'ASP') ~~~ 56 ('5fdq', 'ASN') ~~~ 58 ('5fdq', 'SER') ~~~ 72 ('5fdq', 'PHE') ~~~ 72
Сравнение методов
Для сравнения результатов работы двух функций напишем программу для их сравнения - она будет выводить, на сколько единиц различается результат работы каждого из методов друг от друга.
from countresidues import countresidues as countmain from countresidues_another import countresidues as countsec from sys import argv test = argv[1:] res1 = countmain(test) res2 = countsec(test) for i in res1: if res2[i] > res1[i]: print('Method using SEQRES-strings has found {} more aminoacids than the one using ATOM-strings in\t'.format(res2[i] - res1[i]), i) if res1[i] > res2[i]: print('Method using ATOM-strings has found {} more aminoacids than the one using SEQRES-strings in\t'.format(res1[i] - res2[i]), i) if res2[i] == res1[i]: print('Both methods found the same amount of aminoacids ({}) in \t\t\t\t\t'.format(res1[i]), i)
\t в выводе нужен только лишь для его чистоты. Проверим скрипт на 5fdq.pdb:
mrbelyash@kodomo:~/term1/block2/homeworks$ python3 comparement.py 5fdq.pdb Both methods found the same amount of aminoacids (74) in ('5fdq', 'GLY') Method using SEQRES-strings has found 16 more aminoacids than the one using ATOM-strings in ('5fdq', 'ALA') Method using SEQRES-strings has found 4 more aminoacids than the one using ATOM-strings in ('5fdq', 'VAL') Both methods found the same amount of aminoacids (24) in ('5fdq', 'CYS') Method using SEQRES-strings has found 12 more aminoacids than the one using ATOM-strings in ('5fdq', 'PRO') Method using SEQRES-strings has found 12 more aminoacids than the one using ATOM-strings in ('5fdq', 'LEU') Method using SEQRES-strings has found 12 more aminoacids than the one using ATOM-strings in ('5fdq', 'ILE') Both methods found the same amount of aminoacids (26) in ('5fdq', 'MET') Both methods found the same amount of aminoacids (12) in ('5fdq', 'TRP') Both methods found the same amount of aminoacids (54) in ('5fdq', 'TYR') Method using SEQRES-strings has found 20 more aminoacids than the one using ATOM-strings in ('5fdq', 'THR') Method using SEQRES-strings has found 12 more aminoacids than the one using ATOM-strings in ('5fdq', 'ARG') Method using SEQRES-strings has found 8 more aminoacids than the one using ATOM-strings in ('5fdq', 'LYS') Method using SEQRES-strings has found 18 more aminoacids than the one using ATOM-strings in ('5fdq', 'HIS') Method using SEQRES-strings has found 4 more aminoacids than the one using ATOM-strings in ('5fdq', 'GLU') Method using SEQRES-strings has found 8 more aminoacids than the one using ATOM-strings in ('5fdq', 'GLN') Method using SEQRES-strings has found 12 more aminoacids than the one using ATOM-strings in ('5fdq', 'ASP') Method using SEQRES-strings has found 4 more aminoacids than the one using ATOM-strings in ('5fdq', 'ASN') Both methods found the same amount of aminoacids (72) in ('5fdq', 'PHE') Method using SEQRES-strings has found 16 more aminoacids than the one using ATOM-strings in ('5fdq', 'SER')
Как видно из вывода, нет ни одной строки, где количество аминокислот, найденных с помощью строк 'АТОМ' было бы больше, чем найденных с помощью 'SEQRES'.
Попробуем подвести статистику хотя бы на 10 белках: 1AO6 (альбумин сыворотки крови человека), 1UP5 (куриный кальмодулин), 4HP1 (Sec12 - один из белков для отшнуровки пузырьков ЭПС), 3KJQ (каспаза 8), 1J19 (RecA - белок SOS-репарации), 1SUV (трансферрин), 3GTT (супероксиддисмутаза мышей), 2H40 (фосфодиэстераза), 1ZNI (инсулин), 3CIG (Толл-подобный рецептор 3).
Proteins |
1AO6 |
1UP5 |
4HP1 |
3KJQ |
1J19 |
1SUV |
3GTT |
2H40 |
1ZNI |
3CIG |
||||||||||||||||||||
Methods |
ATOM |
SEQRES |
DIFF |
ATOM |
SEQRES |
DIFF |
ATOM |
SEQRES |
DIFF |
ATOM |
SEQRES |
DIFF |
ATOM |
SEQRES |
DIFF |
ATOM |
SEQRES |
DIFF |
ATOM |
SEQRES |
DIFF |
ATOM |
SEQRES |
DIFF |
ATOM |
SEQRES |
DIFF |
ATOM |
SEQRES |
DIFF |
GLY |
22 |
26 |
4 |
22 |
22 |
0 |
2 |
2 |
0 |
15 |
15 |
0 |
16 |
16 |
0 |
180 |
180 |
0 |
156 |
156 |
0 |
8 |
8 |
0 |
8 |
8 |
0 |
24 |
30 |
6 |
ALA |
122 |
126 |
4 |
21 |
23 |
2 |
1 |
1 |
0 |
10 |
10 |
0 |
20 |
20 |
0 |
216 |
216 |
0 |
60 |
60 |
0 |
27 |
27 |
0 |
4 |
4 |
0 |
17 |
21 |
4 |
VAL |
82 |
82 |
0 |
14 |
14 |
0 |
5 |
5 |
0 |
10 |
10 |
0 |
21 |
21 |
0 |
184 |
184 |
0 |
84 |
84 |
0 |
10 |
10 |
0 |
8 |
8 |
0 |
19 |
19 |
0 |
CYS |
70 |
70 |
0 |
0 |
0 |
0 |
8 |
8 |
0 |
10 |
10 |
0 |
2 |
2 |
0 |
84 |
84 |
0 |
18 |
18 |
0 |
9 |
9 |
0 |
12 |
12 |
0 |
10 |
10 |
0 |
PRO |
48 |
48 |
0 |
4 |
4 |
0 |
3 |
3 |
0 |
13 |
17 |
4 |
15 |
15 |
0 |
110 |
110 |
0 |
30 |
30 |
0 |
8 |
10 |
2 |
2 |
2 |
0 |
26 |
34 |
8 |
LEU |
118 |
126 |
8 |
18 |
18 |
0 |
2 |
2 |
0 |
19 |
23 |
4 |
32 |
32 |
0 |
248 |
248 |
0 |
42 |
42 |
0 |
41 |
45 |
4 |
12 |
12 |
0 |
127 |
129 |
2 |
ILE |
16 |
16 |
0 |
16 |
16 |
0 |
1 |
1 |
0 |
18 |
18 |
0 |
19 |
19 |
0 |
86 |
86 |
0 |
48 |
48 |
0 |
22 |
24 |
2 |
4 |
4 |
0 |
34 |
34 |
0 |
MET |
12 |
12 |
0 |
18 |
18 |
0 |
2 |
2 |
0 |
6 |
6 |
0 |
8 |
10 |
2 |
38 |
38 |
0 |
12 |
12 |
0 |
8 |
10 |
2 |
0 |
0 |
0 |
4 |
4 |
0 |
TRP |
2 |
2 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
7 |
7 |
0 |
38 |
38 |
0 |
0 |
0 |
0 |
4 |
4 |
0 |
0 |
0 |
0 |
8 |
10 |
2 |
TYR |
36 |
36 |
0 |
4 |
4 |
0 |
1 |
1 |
0 |
11 |
11 |
0 |
14 |
14 |
0 |
98 |
98 |
0 |
6 |
6 |
0 |
7 |
7 |
0 |
8 |
8 |
0 |
17 |
19 |
2 |
THR |
56 |
56 |
0 |
24 |
24 |
0 |
1 |
1 |
0 |
17 |
18 |
1 |
15 |
15 |
0 |
130 |
130 |
0 |
54 |
54 |
0 |
15 |
17 |
2 |
4 |
4 |
0 |
40 |
40 |
0 |
ARG |
48 |
48 |
0 |
12 |
12 |
0 |
6 |
6 |
0 |
10 |
12 |
2 |
22 |
22 |
0 |
100 |
100 |
0 |
24 |
24 |
0 |
14 |
18 |
4 |
2 |
2 |
0 |
22 |
24 |
2 |
LYS |
116 |
120 |
4 |
14 |
14 |
0 |
9 |
9 |
0 |
19 |
19 |
0 |
31 |
31 |
0 |
202 |
202 |
0 |
54 |
54 |
0 |
20 |
22 |
2 |
2 |
2 |
0 |
35 |
39 |
4 |
HIS |
30 |
34 |
4 |
2 |
2 |
0 |
1 |
1 |
0 |
7 |
7 |
0 |
6 |
6 |
0 |
62 |
62 |
0 |
60 |
60 |
0 |
12 |
12 |
0 |
4 |
4 |
0 |
18 |
32 |
14 |
GLU |
124 |
124 |
0 |
42 |
42 |
0 |
2 |
2 |
0 |
14 |
18 |
4 |
27 |
27 |
0 |
154 |
154 |
0 |
60 |
60 |
0 |
21 |
27 |
6 |
8 |
8 |
0 |
31 |
35 |
4 |
GLN |
40 |
40 |
0 |
11 |
13 |
2 |
2 |
2 |
0 |
13 |
18 |
5 |
19 |
19 |
0 |
80 |
80 |
0 |
48 |
48 |
0 |
22 |
22 |
0 |
6 |
6 |
0 |
29 |
33 |
4 |
ASP |
70 |
74 |
4 |
33 |
35 |
2 |
0 |
0 |
0 |
18 |
20 |
2 |
18 |
18 |
0 |
166 |
166 |
0 |
48 |
48 |
0 |
16 |
18 |
2 |
0 |
0 |
0 |
26 |
28 |
2 |
ASN |
34 |
34 |
0 |
12 |
12 |
0 |
3 |
3 |
0 |
12 |
12 |
0 |
15 |
15 |
0 |
134 |
134 |
0 |
36 |
36 |
0 |
15 |
19 |
4 |
6 |
6 |
0 |
71 |
75 |
4 |
PHE |
68 |
68 |
0 |
16 |
16 |
0 |
0 |
0 |
0 |
10 |
10 |
0 |
16 |
16 |
0 |
132 |
132 |
0 |
18 |
18 |
0 |
16 |
16 |
0 |
6 |
6 |
0 |
35 |
41 |
6 |
SER |
42 |
42 |
0 |
8 |
8 |
0 |
2 |
2 |
0 |
13 |
21 |
8 |
9 |
9 |
0 |
184 |
184 |
0 |
60 |
60 |
0 |
16 |
16 |
0 |
6 |
6 |
0 |
70 |
74 |
4 |
Интерпретация результатов
Обсуждать то, почему некоторые аминокислоты "правильно" считаются в обоих программах, будет бессмысленно, поскольку такой результат можно интерпретировать как обыкновенное совпадение. Также бессмысленно будет обсуждать, почему выходные данные двух методов совпадают в файлах некоторых белков полностью, - это попросту показывает, что обе программы получили те условия, при которых совпадет их выход. Гораздо интереснее то, что метод SEQRES+REMARK всегда дает больший результат, чем метод ATOM. Минимальное различие между результатами - 1 аминокислота, максимальное - 14. Средняя разница между методами определения ~ 3.8 ~~ 4 аминокислоты. Также кажется важным отметить, что у белков, количество каждой из аминокислот в которых не больше 10, выходные данные совпадают - т.е. программы работают одинаково на малом приближении, ошибки начинаются на больших белках.
К сожалению, не совсем понятно по-прежнему, что вообще служит причиной появления данной разницы. Я считаю, что это недостаток программы SEQRES+REMARK - возможно, что-то я все же не учел при ее написании.