У меня есть файл SAM с полем RX:, содержащим 12 баз, разделенных посередине -, т.е. RX:Z:CTGTGC-TCGTAA

Я хочу удалить дефис из этого поля, но я не могу просто удалить все дефисы из всего файла, так как имена для чтения содержат их, например, 1713704_EP0004-T

В основном пытались tr,, но это просто удаление всех дефисов из файла .:

tr -d '"-' < sample.fq.unaln.umi.sam > sample.fq.unaln.umi.re.sam

Input - это большой SAM-файл, содержащий более 10 000 000 строк, например:

1902336-103-016_C1D1_1E-T:34    99  chr1    131341  36  146M    =   131376  182 GGACAGGGAGTGTTGACCCTGGGCGGCCCCCTGGAGCCACCTGCCCTGAAAGCCCAGGGCCCGCAACCCCACACACTTTGGGGCTGGTGGAACCTGGTAAAAGCTCACCTCCCACCATGGAGGAGGAGCCCTGGGCCCCTCAGGGG  NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN  MC:Z:147M   MD:Z:83T62cD:i:4    cE:f:0  PG:Z:bwa    RG:Z:A  MI:Z:34 NM:i:1  cM:i:3  MQ:i:36 UQ:i:45 AS:i:141    XS:i:136    RX:Z:CTGTGC-TCGTAA

Желаемый результат (то есть последнее поле)

1902336-103-016_C1D1_1E-T:34    99  chr1    131341  36  146M    =   131376  182 GGACAGGGAGTGTTGACCCTGGGCGGCCCCCTGGAGCCACCTGCCCTGAAAGCCCAGGGCCCGCAACCCCACACACTTTGGGGCTGGTGGAACCTGGTAAAAGCTCACCTCCCACCATGGAGGAGGAGCCCTGGGCCCCTCAGGGG  NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN  MC:Z:147M   MD:Z:83T62cD:i:4    cE:f:0  PG:Z:bwa    RG:Z:A  MI:Z:34 NM:i:1  cM:i:3  MQ:i:36 UQ:i:45 AS:i:141    XS:i:136    RX:Z:CTGTGCTCGTAA

Как мне решить эту проблему?

1
lgallagher 1 Май 2019 в 17:42

3 ответа

Лучший ответ

Я решил эту проблему с помощью pysam, который работает быстрее, безопаснее и требует меньше места на диске, поскольку файл sam не требуется. Это не идеально, я все еще изучаю Python и использую pysam в течение половины дня.

import pysam
import sys
from re import sub

# Provide a bam file
if len(sys.argv) == 2:
    assert sys.argv[1].endswith('.bam')

# Makes output filehandle
inbamfn = sys.argv[1]
outbamfn = sub('.bam$', '.fixRX.bam', inbamfn)

inbam = pysam.Samfile(inbamfn, 'rb')
outbam = pysam.Samfile(outbamfn, 'wb', template=inbam)

# Counters for reads processed and written
n = 0
w = 0

# .get_tag() retrieves RX tag from each read
for read in inbam.fetch(until_eof=True):
    n += 1
    umi = read.get_tag('RX')
    assert umi is not None
    umifix = umi[:6] + umi[7:]
    read.set_tag('RX', umifix, value_type='Z')
    if '-' in umifix:
        print('Hyphen found in UMI:', umifix, read)
        break
    else:
        w += 1
        outbam.write(read)

inbam.close()
outbam.close()

print ('Processed', n, 'reads:\n',
       w, 'UMIs written.\n',
       str(int((w / n) * 100)) + '% of UMIs fixed')

2
lgallagher 10 Май 2019 в 14:51

Этот шаблон находится на многих записях, которые вы хотите редактировать, и всегда находится в конце строки? Если так -

sed -E 's/^(.*)(\s..:.:......)-(......\s*)$/\1\2\3/' < sample.fq.unaln.umi.sam > sample.fq.unaln.umi.re.sam
0
Paul Hodges 1 Май 2019 в 15:07

Лучшее решение - работать с файлами BAM, а не с файлами SAM, и использовать подходящую библиотеку BAM-анализатора / записи, такую как htslib.

Не имея этого, вы можете что-то объединить, выполнив поиск регулярного выражения ^RX:Z: в необязательных тегах (столбцы 12 и выше).

Работать с колонками, хотя это возможно, сложно с sed. Вместо этого вот как это сделать в awk:

awk -F '[[:space:]]*' '{
    for (i = 12; i <= NF; i++) {
        if ($i ~ /^RX:Z:/) gsub("-", "", $i)
    }
}
1' file.sam

И вот примерно такое же решение, как Perl "one-liner":

perl -ape '
    for (@F[11..(scalar @F)]) {
        s/-//g if /^RX:Z:/;
    }
    $_ = join("\t", @F);
' file.sam

Чтобы выполнить замену в исходном файле, вы можете передать параметр -i.bak в perl (это создаст резервную копию file.sam.bak; если вы не хотите создавать резервную копию, опустите расширение) ,

1
Konrad Rudolph 9 Май 2019 в 13:09