Как извлечь начальные и конечные сайты на основе заглавной буквы в последовательности?

Я хотел бы извлечь начальную и конечную информацию о сайте, которая указана заглавной буквой. При подсчете длины последовательности с помощью приведенного ниже кода невозможно точно вернуть информацию о последовательности. Результат P-match, который мне нужно обработать с учетом начального сайта, основан на первом алфавите, но начальный сайт, который мне действительно нужен, — это первая заглавная буква, встречающаяся на каждом сайте. Как я могу получить точный начальный и конечный сайт? Кто-нибудь может мне помочь?

Текстовый файл A.txt

Scanning sequence ID:   BEST1_HUMAN

          150 (-)  1.000  0.997  GGAAAggccc                                   R05891
          354 (+)  0.988  0.981  gtgtAGACAtt                                  R06227
V$CREL_01c-RelV$EVI1_05Evi-1

Scanning sequence ID:   4F2_HUMAN

          365 (+)  1.000  1.000  gggacCTACA                                   R05884
           789 (-)  1.000  1.000  gcgCGAAA                                       R05828; R05834; R05835; R05838; R05839
V$CREL_01c-RelV$E2F_02E2F

Ожидаемый результат:

Идентификатор последовательности начало конец

BEST1_HUMAN 150 155
BEST1_HUMAN 358 363
4F2_HUMAN   370 370
4F2_HUMAN   792 797

Файл B.txt

Scanning sequence ID: hg17_ct_ER_ER_142

              512 (-)  0.988  0.981  taTAGCTaagc                        Evi-1          R06227
V$EVI1_05

Scanning sequence ID: hg17_ct_ER_ER_1

              213 (-)  1.000  0.989  aggggcaggGGTCA                     COUP-TF, HNF-4 R07445
V$COUP_01

Ожидаемый результат:

hg17_ct_ER_ER_142 514 519
hg17_ct_ER_ER_1 222 227

Пример кода:

output_file = open('output.bed','w')
with open('A.txt') as f:
    text = f.read()
    chunks = text.split('Scanning sequence ID:')
    for chunk in chunks:
        if chunk:
            lines = chunk.split('\n')
            sequence_id = lines[0].strip()
            for line in lines:
                if line.startswith('              '):
                    start = int(line.split()[0].strip())
                    sequence = line.split()[-2].strip()
                    stop = start + len(sequence)
                    #print sequence_id, start, stop
                    seq='%s\t%i\t%i\n' % \
                         (sequence_id,start,stop)
                    output_file.write(seq)
output_file.close()

person Xiong89    schedule 19.06.2015    source источник
comment
Итак, вам нужно зафиксировать шаблон BEST1_HUMAN и следующие два числа (150, 155). Где 155 в тексте?   -  person Freek Wiekmeijer    schedule 19.06.2015
comment
значение 155 не предоставляется в результате P-match. Мне нужно обработать результат в файл кровати, который содержит идентификатор последовательности, начальный сайт и конечный сайт. Результат возвращает начальный сайт, основанный на первом алфавите, но мне нужен начальный и конечный сайты на основе алфавита заглавных букв, например GGAAA.   -  person Xiong89    schedule 19.06.2015
comment
Я думаю, что метку и первое значение лучше всего найти с помощью регулярного выражения. Затем будет рассчитано второе значение.   -  person Freek Wiekmeijer    schedule 19.06.2015
comment
Это, вероятно, лучше всего сделать с помощью регулярного выражения. Однако я не понимаю, что вы хотите получить в качестве вывода, иначе я бы дал вам точное регулярное выражение.   -  person EvertW    schedule 19.06.2015


Ответы (1)


Этот код получит метку и начальные значения:

import re

p = "Scanning sequence ID\:\s*(?P<label>[A-Z0-9]+\_[A-Z0-9]+).*?(?P<start_value>\d+)"

with open("A.txt", "r") as f:
    s = f.read()

re.findall(p,s, re.DOTALL)

Пример вывода:

[('BEST1_HUMAN', '150'), ('4F2_HUMAN', '365')]

Затем идет расчет второго числа ("конечный сайт"). В коде во вступительном посте вижу: sequence = line.split()[-2].strip(); stop = start + len(sequence). Следовательно, я бы сделал вывод, что вы хотите увеличить значение start на длину строки предпоследнего столбца (GGAAAggccc и т. д.).

Я также могу захватить этот столбец, используя следующее модифицированное регулярное выражение:

p = "Scanning sequence ID\:\s*(?P<label>[A-Z0-9]+\_[A-Z0-9]+).*?(?P<start_value>\d+)\s+\S+\s+\S+\s+\S+\s+(?P<sequence>\S+)"
re.findall(p,s, re.DOTALL)

Пример вывода:

[('BEST1_HUMAN', '150', 'GGAAAggccc'), ('4F2_HUMAN', '365', 'gggacCTACA')]

Теперь мы хотим обработать ситуацию, когда одна метка имеет более одной строки данных. Для этого нам нужно сбросить re.findall и перейти к итерации:

import re
with open("A.txt", "r") as f:
    lines = f.readlines()

label_ptrn = re.compile("^Scanning sequence ID\\:\\s*(?P<label>[A-Z0-9]+\\_[A-Z0-9]+)$")
line_ptrn = re.compile("^\s+(?P<start_value>\\d+)\\s+\\S+\\s+\\S+\\s+\\S+\\s+(?P<sequence>\\S+).*$")
inner_ptrn = re.compile("[A-Z]+")

all_matches = []
for line in lines:
    m = label_ptrn.match(line)
    if m:
        label = m.groupdict().get("label")
        continue
    m = line_ptrn.match(line)
    if m:
        start = m.groupdict().get("start_value")
        sequence = m.groupdict().get("sequence")
        mi = inner_ptrn.search(sequence)
        if not mi:
            continue
        span = mi.span()
        all_matches.append((label, int(start)+span[0], int(start)+span[1]))

Затем вы можете распечатать совпадения следующим образом:

with open("output.bed", "w+b") as f:
    for m in all_matches:
        f.write('%s\t%i\t%i\n' % m)

Пример вывода:

BEST1_HUMAN 150 155
BEST1_HUMAN 358 363
4F2_HUMAN   370 375
4F2_HUMAN   792 797

Думаю проблема решена ;)

person Freek Wiekmeijer    schedule 19.06.2015
comment
Потому что строчная буква не считается. Мне нужно местоположение с заглавной буквы, например. aaggTCAaagg, который является TCA. Если первый алфавит начинается с «а», что является значением 1. Тогда начальное местоположение для заглавной буквы равно 5 и заканчивается 8, потому что для файла кровати, если, скажем, последовательность 100, местоположение начинается с 0 и заканчивается 99. Другой способ чтобы сделать это проще, нужно получить местоположение T и добавить значение 3 для каждого начального сайта. - person Xiong89; 19.06.2015
comment
@ Xiong89 Взгляните на мою последнюю правку. Я думаю, что он отлично воспроизводит ваш пример вывода. - person Freek Wiekmeijer; 19.06.2015
comment
Спасибо за вашу помощь. Очень ценю =) - person Xiong89; 19.06.2015
comment
Однако, когда я ввожу другой файл с другим номером последовательности, он не может решить его соответствующим образом. Код, который я предоставил выше, может решить с другим числом последовательностей, но не может получить местоположение заглавной буквы. - person Xiong89; 19.06.2015
comment
Файл А в порядке. Когда я попытался с файлом B, возникла ошибка. - person Xiong89; 19.06.2015
comment
Проблема в том, что метка в B.txt не соответствует шаблону метки. Подставка и крайние указатели кажутся в порядке. Я предлагаю следующее изменение: label_ptrn = re.compile("^Scanning sequence ID\\:\\s*(?P<label>[a-zA-Z0-9\_]+)$") - person Freek Wiekmeijer; 19.06.2015