打印bam文件比对后的碱基矩阵python脚本
2022-02-16 本文已影响0人
九月_1012
脚本的初衷是想看多序列比对后的序列整齐度;
但多序列比对往往是无监督学习,需要耗费大量的内存和时间,所以以下代码实现了:有参比对,然后使用pysam将比对后的bam文件打印成每个位置的对应的碱基文件,类似于多序列比对后的既视感,或者是samtools 软件的pileup文件。
如果喜欢用samtools获得整齐的比对碱基矩阵,也可参考以下tview命令(缺点是不能指定ref的具体区域)
samtools example:
#COLUMNS数值代表想打印多少列
COLUMNS=5000 samtools tview IonXpress_004_rawlib.bam -d T -p {chr:start} --reference {ref.fasta} >ouput.tview.txt
pysam读写bam文件脚本:
import sys
sys.path.append("/XXXpath/python_module/")
import argparse
import re
import pysam
import pysamstats
def Get_opt():
parser = argparse.ArgumentParser()
parser.add_argument('-i','--input',dest='Ref',help='the path of ref fasta')
parser.add_argument('-bam','--Bam',dest='Bam',help='the path of bam')
parser.add_argument('-r','--region',dest='region',help='the region chr:start-end')
parser.add_argument('-o','--output',dest='output',help='the name of outfile')
options = parser.parse_args()
return options
def pysamresults(Bamfile,Fafile,region):
fafile=pysam.FastaFile(Fafile)
bf = pysam.AlignmentFile(Bamfile, 'rb')
target=re.split(r'\:|\-',region)
chrom=target[0]
start=int(target[1])
end=int(target[2])
#allref = bf.get_reference_name
dout = {}
dout.setdefault('ref',{})
dout.setdefault('reads',{})
for col in bf.pileup(chrom, start, end, truncate=True):
reads = col.pileups
ref = fafile.fetch(chrom, col.pos, col.pos+1).upper()
dout['ref'][col.pos] = ref
for read in reads:
dout['reads'].setdefault(read.alignment.query_name,{})
if read.is_del:
base = '-'
elif read.indel >0 :
base = read.alignment.seq[read.query_position:(read.query_position+read.indel+1)]
else :
base = read.alignment.seq[read.query_position]
dout['reads'][read.alignment.query_name][col.pos]=base
bf.close()
fafile.close()
return dout
opt=Get_opt()
dout = pysamresults(opt.Bam,opt.Ref,opt.region)
chrom=re.split(r'\:|\-',opt.region)[0]
print('Term\t'+'\t'.join([str(pos) for pos in sorted(dout['ref'])]))
print(chrom+'\t'+'\t'.join([dout['ref'][pos] for pos in sorted(dout['ref'])]))
for ccs in dout['reads']:
ccsbase = []
for pos in sorted(dout['ref']):
if pos in dout['reads'][ccs]:
ccsbase.append(dout['reads'][ccs][pos])
else:
ccsbase.append("*")
print(ccs+'\t'+'\t'.join(ccsbase))