Parsing 从单个字符串高效地计算统计信息(bowtie2提供的bam文件)

Parsing 从单个字符串高效地计算统计信息(bowtie2提供的bam文件),parsing,optimization,bioinformatics,Parsing,Optimization,Bioinformatics,我的目标是有效地将包含短DNA测序读取的bowtie2映射的bam文件转换为一个简单的表,该表包含映射开始和百分比标识。我即将完成这项工作,但是我的解决方案非常缓慢,无法处理重要的异常。我会逐步解释情况: 我们从这样的字符串开始 FCC5G2YACXX:5:1101:1224:2059#NNNNNNNN 97 genome 96003934 24 118M4D11M = 96004135 0 GCA....ACG P\..GW^EO AS:i:-2

我的目标是有效地将包含短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
部分,后者表示匹配(数字)和不匹配(字母)。除非字母前面有一个“^”,否则字母是引用序列中的删除项

然后我将其计算成如下字符串
9600393498.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
    }
if_sam2tab(){
表=$(回显$1 |版次|切割-d'.-f 2 |版次)
如果[!-e./bowtie_结果/$tab.tab]
然后echo-e“rstart\tmatch\tmismatch”>。/bowtie_results/$tab.tab
而read-rl
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)
不匹配=$(echo${t:5}|tr-d'[0-9]\n'|wc-c)
总和=$(回显“$匹配+$不匹配”| bc)
id=$(echo“scale=2;$match/$sum*100”| bc)
echo-e“$rstart\t$id”>>。/bowtie_results/$tab.tab
完成<
  • 使用二进制数据(bam文件)输入和输出要快得多,但您有一个sam文件(平面版本)

  • 以前已经注释过的,总是用编译语言(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
awk'{
拆分($18,v,/\^://);
n匹配=分割(v[3],v匹配,/[^0-9]/);
cmatch=0;

对于(i=1;iJose对前面答案的补充:MD字符串不一定是第18列。因此,我在Jose的awk脚本中添加了一行,以查找MD字符串,而不考虑该行中的位置。毫无疑问,在该过程中添加regex步骤将使其整体速度减慢

awk '{
 match($0, /MD:Z:[0-9A-Z\^]*/,m );
 split(m[0],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));
}' 
awk'{
匹配($0,/MD:Z:[0-9A-Z\^]*/,m);
分裂(m[0],v,/[\^:]/);
n匹配=分割(v[3],v匹配,/[^0-9]/);
cmatch=0;

对于(i=1;术语< >代码>有效< /COD>和<代码> shell脚本不一致。Shell脚本总是非常慢。通常使用shell时不关心速度。如果是,那么考虑移动到脚本语言。BAM文件?像山姆文件如何…谢谢您看一下!确实我知道shell脚本不是。如果速度很重要,那该怎么办。我更喜欢shell脚本,因为它是我所熟悉的唯一一种,而且通常足够快,可以学习一些有趣的生物学。我选择不在问题中详细说明这一点,以保持它的简洁性和相关性。一旦这篇论文发表,我希望能找到一些时间来学习脚本语言。你的解决方案这似乎很有效!谢谢你的时间。我会花一些时间来剖析这段代码到底做了什么,乍一看,这在生物学上似乎很好。
awk '{
 match($0, /MD:Z:[0-9A-Z\^]*/,m );
 split(m[0],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));
}'