我的目标是有效地将包含短DNA测序读数的bowtie2映射的bam文件转换为包含映射开始和百分比同一性的简单表。我即将完成此任务,但我的解决方案非常缓慢,无法处理重要的异常。我将逐步解释这种情况:
我们从像这样的字符串开始
FCC5G2YACXX:5:1101:1224:2059#NNNNNNNN 97 genome 96003934 24 118M4D11M = 96004135 0 GCA....ACG P\..GW^EO AS:i:-28 XN:i:0 XM:i:2 XO:i:1 XG:i:4 NM:i:6 MD:Z:54G53T9^TACA11 YT:Z:UP
我们只采用第四列和MD:Z:54G53T9^TACA11
部分,后者表示匹配(数字)和不匹配(字母)。除非字母前面有' ^'然后字母是参考序列中的删除。
然后我把它计算成一个像96003934 98.00
第一列与原始输入的第四列相同,第二列是匹配,除以总和匹配和不匹配。
由于我更喜欢bash / zsh脚本,所以我做了以下
if_sam2tab() {
tab=$(echo $1 | rev | cut -d '.' -f 2- | rev)
if [ ! -e ./bowtie_results/$tab.tab ]
then echo -e "rstart\tmatch\tmismatch" > ./bowtie_results/$tab.tab
while read -r l
do rstart=$(echo $l | cut -f 4 -d " " )
t=$(echo $l | grep -o 'MD:Z:[0-9A-Z]*' )
match=$(echo ${t: 5} | tr '[a-zA-Z]' '+' | bc )
mismatch=$(echo ${t: 5} | tr -d '[0-9]\n' | wc -c )
sum=$(echo "$match + $mismatch" | bc )
id=$(echo "scale=2; $match / $sum *100" | bc )
echo -e "$rstart\t$id" >> ./bowtie_results/$tab.tab
done < <(grep 'MD:Z' ./bowtie_results/$1 )
fi
}
然而,此解决方案有问题,因为它将^TCTAAG
等删除视为不匹配。
其次它对我来说似乎非常慢,即使我在六个CPU上并行运行它们中的五个。
重述一下,我的目标是有效地将带有映射信息的字符串转换为身份百分比。
感谢您的考虑
答案 0 :(得分:2)
Jose对前一个答案的补充:MD字符串不一定是第18列。因此,我在Jose的awk脚本中添加了一行来查找MD字符串,而不管该行中的位置如何。毫无疑问,在整个过程中添加一个正则表达式步骤会使整个过程变慢。
/repoName
我选择直接在这个awk脚本中管道bowtie输出而不将其保存在磁盘上。在我的有限测试中,我没有发现磁盘i / o是限制的,也没有发现直接输入awk的管道bowtie2输出大大降低了同时运行时的整体性能。
答案 1 :(得分:1)
使用二进制数据(bam文件)输入和输出要快得多,但你有一个sam文件(平面版)
正如@cel之前评论过的那样,用编译语言(C,C ++等)编写的程序总是比脚本(ej,bash,awk等)更快
我在awk
中显示了一个脚本,供您尝试
awk '{
split($18,v,/[\^:]/);
nmatch = split(v[3],vmatch, /[^0-9]/);
cmatch=0;
for(i=1; i<=nmatch; i++) cmatch+=vmatch[i];
printf("%s"OFS"%.2f\n", $4, cmatch*100/(cmatch+nmatch-1));
}' file.sam
你得到了
96003934 98.31
<强>解释强>
第18栏:MD:Z:54G53T9^TACA11
匹配= 54 + 53 + 9 = 116
mismatch = count_letter(54G53T9)= 2
id = 116 /(116 + 2)= 0.9830508474576272