Характеристики трёх пар белков в локальном парном выравнивании
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.
Сама программа запрашивает путь к файлу и выдаёт следующие данные:
First entry ID: #indels in first sequence
Second entry ID: #indels in second sequence
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))