Удаление остатка из PDB с помощью библиотеки Biopython

Используя библиотеку biopython, я хочу удалить остатки, перечисленные в списке, следующим образом. Эта ветка (http://pelican.rsvs.ulaval.ca/mediawiki/index.php/Manipulating_PDB_files_using_BioPython) предоставляет пример удаления остатков. У меня есть следующий код для удаления остатков

 residue_ids_to_remove = [105, 5, 8, 10, 25, 48]
 structure = pdbparser.get_structure("3chy", "./3chy.pdb")
 first_model = structure[0]
 for chain in first_model:
     for residue in chain:
         id = residue.id
         if id[1] in residue_ids_to_remove:
             chain.detach_child(id[1])
 modified_first_model = first_model 

Но этот код не работал и выдавал ошибку

def detach_child(self, id):
    "Remove a child."
    child=self.child_dict[id]
    KeyError: '105'

Что не так с этим кодом?

В качестве альтернативы я могу использовать accept_residue() и записать его в PDB. Я не хочу следовать этому, потому что хочу сделать это в памяти для дальнейшей обработки.


person Exchhattu    schedule 17.09.2014    source источник


Ответы (1)


Biopython не может найти ключ во внутреннем словаре к цепочке, потому что вы предоставляете случайный ключ. Дикт выглядит так:

child_dict = {(' ', 5, ' '): <Residue HOH het=W resseq=5 icode= >,
              (' ', 6, ' '): <Residue HOH het=W resseq=6 icode= >,
              (' ', 7, ' '): <Residue HOH het=W resseq=7 icode= >}

То есть: использование кортежей в качестве ключей dict. Вы можете видеть, как дикт делает print chain.child_dict.

Как только вы это узнаете, ошибка/решение станет ясным. Передайте действительный ключ detach_child, а именно удалите [1]:

   if id[1] in residue_ids_to_remove:
       chain.detach_child(id)

Правильный путь

Отсоедините дочерние элементы от цепного уровня и не циклируйте остатки напрямую:

for chain in first model:
    for id in residue_ids_to_remove:
        chain.detach_child((' ', id, ' '))

Или с пониманием списка:

for chain in first_model:
    [chain.detach_child((' ', id, ' ')) for id in residue_ids_to_remove]
person xbello    schedule 17.09.2014
comment
спасибо!!! Тем не менее, он не работает идеально. Когда выполняется chain.detach_child(id). Он удаляет один остаток, принадлежащий идентификатору, и пропускает следующий остаток, который является последующим остатком. Мне интересно, почему это так? - person Exchhattu; 18.09.2014
comment
Я не понимаю ситуацию. Если вы detach_child((' ', 5, ' '), что пропускается? Что вы считаете следующим в словаре? (' ', 6, ' ') может быть? - person xbello; 18.09.2014
comment
Да... подробнее - когда chain.detach_child((' ', 5, ' ')) был выполнен, он пропустил (' ', 6, ' ') . Я не знаю причину. Чтобы увидеть эффект, я просто прокомментировал # chain.detach_child((' ', 5, ' ')) и он показал весь остаток.id как (' ', 5, ' '), (' ', 6, ' ') . Из этого я обнаружил, что ошибка находится в chain.detach_child((' ', 5, ' ')) но я не знаю, как ее решить. - person Exchhattu; 18.09.2014
comment
Я нашел это. при зацикливании списка И его изменении соседние остатки перескакивают в списке. Вы должны циклически копировать список: for residue in list(chain): вместо for residue in chain: - person xbello; 18.09.2014
comment
Это работает, но я думаю, что это неправильно! Вставка правильного пути в исходный ответ. - person xbello; 18.09.2014