У меня есть коллекция файлов fasta, содержащих много фрагментов последовательности ДНК. Я пытаюсь подсчитать суммарные вхождения k-mers, которые можно найти в каждом файле. Хорошей частью подсчета k-mers является то, что можно создать один массив размером 4 ** k, где k - размер используемого k-mer. Файлы последовательности, которые я обрабатываю, представляют собой короткие последовательности считывания из машин для секвенирования нового поколения, и поэтому предполагать, что все чтения из 5 '-> 3' не могут быть выполнены. Лучший способ решить эту проблему - сопоставить все k-mers, наблюдаемые с одним индексом для последовательных и обратных последовательностей.Алгоритм срыва вперед и назад дополнения последовательности ДНК в python?
Желаемая отображение:
с к = 2 & исходного индекса для массива равен 0
строка = «аа»; карты для указания -> 0
string = 'tt'; map to index -> 0
string = 'at'; карты индексировать -> 1
По руке я был в состоянии понять, что массив для всех меров с распадом прямых и обратным комплементы будет иметь длину 10, а конкретные показатели будут представлять следующие меры: А.А. , AT, AC, AG, TA, TC, TG, CC, CG, GC
У меня возникли проблемы с рассмотрением обобщенного алгоритма, чтобы узнать количество возможных мер для больших размеров k. Сколько ячеек должно быть выделено в массиве count?
В моем существующем коде я придумал эти три функции для обработки фрагментов, создания обратного дополнения и сопоставления mer (или обратного дополнения) с индексом.
Эта первая функция примет строку mer и возвращает индекс, который относится к mer в массиве размером 4 ** k.
def mer_index_finder(my_string, mer_size):
# my_string = my_string.lower()
char_value = {}
char_value["a"] = 0
char_value["t"] = 1
char_value["c"] = 2
char_value["g"] = 3
i = 0
j = 0
base_four_string = ""
while(i < mer_size):
base_four_string += str(char_value[my_string[i]])
i += 1
index = int(base_four_string, 4)
return index
Эта функция обрабатывает все фрагменты ДНК и отображает счетчики с индексом в массиве размера 4 ** к
def get_mer_count(mer_size, file_fragments, slidingSize):
mer_counts = {}
for fragment in file_fragments:
j = 0
max_j = len(fragment) - mer_size
while(j < max_j):
mer_frag = fragment[j:j+mer_size]
mer_frag = mer_frag.lower()
if("n" not in mer_frag):
try:
mer_counts[mer_frag] += 1
except:
mer_counts[mer_frag] = 1
j += slidingSize
myNSV = [0] * (4**mer_size)
for mer in mer_counts.keys():
mer_index = mer_index_finder(mer, mer_size)
# examples showing how to collapse,
# without shrinking the array
# rev_mer = make_complment_mer(mer)
# print rev_mer
# rev_index = mer_index_finder(rev_mer, mer_size)
# min_index = min(mer_index, rev_index)
# print mer_index,"\t",rev_index,"\t",min_index
# myNSV[min_index] += mer_counts[mer]
myNSV[mer_index] = mer_counts[mer]
return myNSV[:]
Наконец эта функция будет принимать Меры и произвести обратный комплемент :
def make_complment_mer(mer_string):
nu_mer = ""
compliment_map = {"a" : "t", "c" : "g", "t" : "a", "g" : "c"}
for base in mer_string:
nu_mer += compliment_map[base]
nu_mer = nu_mer[::-1]
return nu_mer[:]
Похоже, что должно быть очевидным способом, чтобы всегда знать, сколько ячеек массива должны иметь при сворачивании в прямом и обратном дополняет вместе, и есть экзамен в литературе, и некоторые пакеты, показывающие это, были выполнены; однако я не нахожу, где в исходном коде они могут генерировать эти вычисления.
Вторая часть этого вопроса: как вы узнаете, является ли mer прямым или обратным дополнением, не проверяя оба?
Пример:
(вперед)
AAGATCACGG
(дополнение)
TTCTAGTGCC
(обратный комплемент)
CCGTGATCTT
В моем приведенном выше коде я беру нижний из двух индексов, но кажется, что должен быть способ понять это, не найдя индекс для каждого мера дважды: один раз вперед и один раз в качестве обратного дополнения.
TL; DR Каков размер массива, если форматированные и обратные дополнения сопоставлены с одним и тем же индексом?
Edit: Чтобы определить размер массива, используя ответ, который я модифицировал get_mer_count(), чтобы включить в него следующие строки, чтобы создать размер индекса:
array_size = (4 ** mer_size)/2
if mer_size % 2 == 0:
array_size += 2**(mer_size - 1)
myNSV = [0] * array_size
Удивительный! Спасибо! Я изменил ваше решение в сокращенном выражении if. См. Править. –