Практикум 9

1. Глобальное парное выравнивание гомологичных белков

Характеристики трёх пар белков в глобальном парном выравнивании

Protein Name ID 1 ID 2 Score Identity, % Similarity, % Gaps Indels
DNA-topoisomerase II complex CCDB_ECOLI CCDB_BACSU 13.5 9.5 17.8 117 7
DNA-binding transcription repressor RBSR_ECOLI RBSR_BACSU 384.5 30.2 48.5 20 8
Thiamin biosynthesis protein G THIG_ECOLI THIG_BACSU 567.0 47.1 66.0 6 3

2. Локальное парное выравнивание гомологичных белков

Характеристики трёх пар белков в локальном парном выравнивании

Protein Name ID 1 ID 2 Score Identity, % Similarity, % Gaps Indels Coverage 1, % Coverage 2, %
DNA-topoisomerase II complex CCDB_ECOLI CCDB_BACSU 27.0 71.4 85.7 0 0 6.9 5.8
DNA-binding transcription repressor RBSR_ECOLI RBSR_BACSU 386.5 31.2 49.7 16 7 96.9 95.7
Thiamin biosynthesis protein G THIG_ECOLI THIG_BACSU 572.0 48.6 68.1 1 1 97.7 98.0

3. Результат применения программ выравнивания к неродственным белкам

Для данной задачи были выбраны два неродственных белка со следующими названиями функций: RSBR_ECOLI (DNA-binding transcription repressor) и THIG_ECOLI (Thiamin biosynthesis protein G).

Особенности сравнения двух негомологичных белков с помощью глобального выравнивания

Program Name ID 1 ID 2 Score Identity, % Similarity, % Gaps Indels Coverage 1, % Coverage 2, %
Needle RBSR_ECOLI THIG_ECOLI 21.5 8.9 15.1 312 12 - -
Water RBSR_ECOLI THIG_ECOLI 31.0 20.7 31.0 55 7 48.2 52.3

Из полученных данных видно, что к процент идентичности (8.9) и процент схожести (15.1) в глобальном выравнивании, так процент идентичности (20.7) и процент схожести (31.01) в локальном выравнивании крайне низкие, что доказывает, что эти белки на самом деле негомологичны.

4. Множественное выравнивание белков

Для поиска белком со схожей мнемоникой функций я ввёл в UniProt запрос (id=RBSR_*) и получит 10 результатов
Я выбрал 5 из них (Q9K6K2;P0ACQ1;Q9CF41;Q9CPA2;P0ACQ2), а так же 2 белка из ECOLI и BACSU (P0ACQ0;P36944) и сделал множественное выравнивание в JalView при помощи программы Muscle

Множественное выравнивание белков Q9K6K2;P0ACQ1;Q9CF41;Q9CPA2;P0ACQ2 и P0ACQ0;P36944

Исходя из результатов множественного выравнивания, я могу сделать вывод, что белки скорее всего являются гомологичными. Хотя и встречаются большие негомологичные участки:
119-140, 147-163, 205-219, 251-263, 309-326, 328-339.
Есть и полностью (или почти полностью) консервативные участки:
17-19, 51-54, 62-65, 271-274.

Всё же различия в последовательностях этих белков не слишком велики, чтобы говорить о том, что они гомологичны. Вероятно, неконсервативные участки - это следствие мутаций, накопленных за долгое время.

6. Подсчёт инделей

Я неожиданно для себя обнаружил, что написанный мной для выполнения практикума парсер можно легко переоборудовать в требуемую в задании 6 программу. Для этого я написал небольшой адаптер и перенаправил stdout из output.txt обратно в консоль.
Сам код доступе здесь, а так же в папке ~/term2/indels/indels.py.
Сама программа запрашивает путь к файлу и выдаёт следующие данные:

  1. First entry ID: #indels in first sequence

  2. Second entry ID: #indels in second sequence

  3. Total: total #indels in both sequences

В случае ошибки парсинга или неверного формата исходного файла программа выдаст сообщение об ошибке:
"Parsing error: file must be unmodified neddle/water output"

You can try it yourself right now:

from js import document, Element from pyodide.ffi import create_proxy def on_click(event): file = document.getElementById("align_seq").value; def extract_sequence(line: str) -> str: counter: int = 0 for x in line.split(" "): if len(x) > 0: counter += 1 if counter == 3: return x def count_indels(sequence: str) -> int: indels: int = 0 openedIndel: bool = False for symbol in sequence: if symbol == "-": if not openedIndel: indels += 1 openedIndel = True else: openedIndel = False return indels class NeedleAlignment: __slots__ = ("firstEntry", "secondEntry", "firstSequence", "secondSequence", "length", "identity", "exactIdentity", "similarity", "exactSimilarity", "gaps", "exactGaps", "firstSequenceIndels", "secondSequenceIndels", "score") def __init__(self, NeedleAlignmentFile: str) -> None: # Default values: self.firstEntry: str = "" self.secondEntry: str = "" self.firstSequence: str = "" self.secondSequence: str = "" self.length: int = 0 self.identity: str = "" self.exactIdentity: int = 0 self.similarity: str = "" self.exactSimilarity: int = 0 self.gaps: str = "" self.exactGaps: int = 0 self.firstSequenceIndels: int = 0 self.secondSequenceIndels: int = 0 self.score: str = "" # Parsing: if NeedleAlignmentFile != "": needleAlignmentContent: list[str] = [line.strip() for line in NeedleAlignmentFile.split("\n")] for line in needleAlignmentContent: # Entries: if line.startswith("# 1: "): self.firstEntry = line[5:].strip() if line.startswith("# 2: "): self.secondEntry = line[5:].strip() # Length: if line.startswith("# Length:"): self.length = int(line.split(":")[-1].strip()) # Identity: if line.startswith("# Identity:"): self.identity = line.split("(")[1][:5].strip() self.exactIdentity = int(line.split("/")[0].split(" ")[-1]) # Similarity: if line.startswith("# Similarity:"): self.similarity = line.split("(")[1][:5].strip() self.exactSimilarity = int(line.split("/")[0].split(" ")[-1]) # Gaps: if line.startswith("# Gaps:"): self.gaps = line.split("(")[1][:5].strip() self.exactGaps = int(line.split("/")[0].split(" ")[-1]) # Score: if line.startswith("# Score:"): self.score = line.split(" ")[-1].strip() # Sequence: for line in needleAlignmentContent: if line.startswith(self.firstEntry) and self.firstEntry != "": self.firstSequence += extract_sequence(line) if line.startswith(self.secondEntry) and self.secondEntry != "": self.secondSequence += extract_sequence(line) # Indels: self.firstSequenceIndels = count_indels(self.firstSequence) self.secondSequenceIndels = count_indels(self.secondSequence) def __repr__(self): # result: str = f"First entry name: {self.firstEntry}" # result += f"\nSecond entry name: {self.secondEntry}\n" result: str = f"Length: {self.length}\n" result += f"Identity: {self.identity} ({self.exactIdentity})\n" result += f"Similarity: {self.similarity}, ({self.exactSimilarity})\n" result += f"Gaps: {self.gaps}, ({self.exactGaps})\n" result += f"Indels: ({self.firstSequenceIndels}, {self.secondSequenceIndels})\n" result += f"Score: {self.score}\n" result += "\n" result += f"First Sequence ({self.firstEntry}) = {self.firstSequence}\n" result += f"Second Sequence ({self.secondEntry}) = {self.secondSequence}\n" return result class NeedleAlignmentAdaper: __slots__ = ("firstEntry", "firstSequenceIndels", "secondEntry", "secondSequenceIndels", "totalIndels") def __init__(self, align: NeedleAlignment) -> None: self.firstEntry = align.firstEntry self.firstSequenceIndels = align.firstSequenceIndels self.secondEntry = align.secondEntry self.secondSequenceIndels = align.secondSequenceIndels self.totalIndels = self.firstSequenceIndels + self.secondSequenceIndels def __repr__(self) -> str: result: str = f"{self.firstEntry}: {self.firstSequenceIndels}\n" result += f"{self.secondEntry}: {self.secondSequenceIndels}\n" result += f"Total: {self.totalIndels}" return result needleAlign: NeedleAlignment = NeedleAlignment(file) align: NeedleAlignmentAdaper = NeedleAlignmentAdaper(needleAlign) print(align) button = document.getElementById("calculate_indels") button.addEventListener("click", create_proxy(on_click))