annotate pyPRADA_1.2/prada-fusion @ 1:03815b87eb65 draft

Uploaded
author siyuan
date Fri, 21 Feb 2014 18:08:37 -0500
parents acc2ca1a3ba4
children f17965495ec9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
1 #!/usr/bin/env python
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
2
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
3 #PRADA: Pipeline for RnAseq Data Analysis
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
4 #Fusion detection module, algorithm published by Michael Berger et al (Genome Res, 2010) at Broad Institute.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
5 #Implemented by Siyuan Zheng, Wandaliz Torres-Garcia and Rahul Vegesna.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
6 #Copy Right: The Univ of Texas MD Anderson Cancer Center, Department of Bioinformatics and Computational Biology
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
7 #Contact: Roel Verhaak (rverhaak@mdanderson.org)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
8 #Citation: to be added
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
9 #Tested with Python v2.6 and v2.7
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
10 #The program requires NM tag and high quality mapping reads with mapping score more than -minmapq.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
11 #Last modified: 04/11/2013
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
12
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
13 ######################################################################################
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
14 import sys
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
15 import time
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
16 import os
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
17 import os.path
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
18 import subprocess
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
19 import operator
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
20 import pysam
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
21 import bioclass
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
22 import gfclass
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
23 import ioprada
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
24 import privutils
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
25 from Bio import SeqIO,Seq
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
26
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
27 ######################################################################################
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
28 args=sys.argv
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
29
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
30 help_menu='''\nPipeline for RNAseq Data Analaysis - fusion detection (PRADA).
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
31 **Command**:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
32 prada-fusion -bam XX.bam -conf xx.txt -tag XX -mm 1 -junL XX -minmapq 30 -outdir ./
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
33 **Parameters**:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
34 -h print help message
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
35 -bam input BAM file, must has a .bam suffix. BAM is the output from PRADA preprocess module.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
36 -conf config file for references and parameters. Use conf.txt in py-PRADA installation folder if none specified.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
37 -tag a tag to describe the sample, used to name output files. Default is ''.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
38 -mm number of mismatches allowed in discordant pairs and fusion spanning reads.Default is 1.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
39 -junL length of sequences taken from EACH side of exons when making hypothetical junctions. No default.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
40 -minmapq minimum read mapping quality to be considered as fusion evidences. Default is 30.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
41 -outdir output directory.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
42 -v print version
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
43 '''
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
44
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
45 if '-h' in args or '-help' in args or len(args)==1:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
46 print help_menu
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
47 sys.exit(0)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
48
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
49 if '-v' in args:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
50 import version
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
51 print version.version
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
52 sys.exit(0)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
53
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
54 if '-bam' not in args:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
55 sys.exit('ERROR: BAM file needed')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
56 i=args.index('-bam')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
57 bampath=args[i+1]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
58 bampath=os.path.abspath(bampath)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
59 bam=os.path.basename(bampath)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
60 if bam[-4:] != '.bam':
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
61 sys.exit('ERROR: BAM file must have suffix .bam')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
62
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
63 #Mismatch allowed. This filter is applied at the very end of the pipeline.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
64 #I strongly suggest 1. We also record how many junction spanning reads (JSRs) are perfect matched.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
65 if '-mm' not in args:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
66 mm=1
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
67 else:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
68 i=args.index('-mm')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
69 mm=int(args[i+1])
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
70
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
71 #junL should be less than the read length in the dataset. I suggest it to be read_length*0.8
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
72 if '-junL' not in args:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
73 sys.exit('ERROR: junL must be specified')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
74 i=args.index('-junL')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
75 overlap=int(args[i+1])
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
76
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
77 #minimum mapping quality for reads as fusion evidences
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
78 if '-minmapq' not in args:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
79 minmapq=30
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
80 else:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
81 i=args.index('-minmapq')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
82 minmapq=int(args[i+1])
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
83
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
84 if '-outdir' not in args:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
85 outpath=os.path.abspath('./')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
86 else:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
87 i=args.index('-outdir')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
88 outpath=os.path.abspath(args[i+1])
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
89 if os.path.exists(outpath):
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
90 print 'WARNING: outdir %s exists'%outpath
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
91 else:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
92 os.mkdir(outpath)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
93
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
94 if '-tag' not in args:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
95 docstring='prada'
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
96 else:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
97 i=args.index('-tag')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
98 docstring=args[i+1]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
99
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
100 #by default, search conf.txt in the prada folder
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
101 prada_path=os.path.dirname(os.path.abspath(__file__)) #path to find libraries and executives.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
102 ref_search_path=[prada_path,os.getcwd()] #search path for conf file if not specified in command line
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
103
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
104 if '-conf' in args:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
105 i=args.index('-ref')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
106 reffile=args[i+1]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
107 if os.path.exists(reffile):
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
108 pass
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
109 else:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
110 for pth in ref_search_path:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
111 new_reffile='%s/%s'%(pth, os.path.basename(reffile))
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
112 if os.path.exists(new_reffile):
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
113 reffile=new_reffile
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
114 break
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
115 else:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
116 sys.exit('ERROR: conf file %s not found'%reffile)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
117 else:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
118 reffile='%s/conf.txt'%prada_path
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
119 if not os.path.exists(reffile):
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
120 sys.exit('ERROR: No default conf.txt found and none specified')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
121
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
122 #Now print all input parameters
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
123 print 'CMD: %s'%('\t'.join(args))
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
124
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
125 #reference files pointing to the annotation files.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
126 refdict=ioprada.read_conf(reffile)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
127 featurefile=refdict['--REF--']['feature_file']
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
128 txseqfile=refdict['--REF--']['tx_seq_file']
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
129 txcatfile=refdict['--REF--']['txcat_file']
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
130 cdsfile=refdict['--REF--']['cds_file']
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
131
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
132 #underlying utilities, automatically detected
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
133 #these are customized tools. update is needed.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
134 samtools='%s/tools/samtools-0.1.16/samtools'%prada_path
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
135 bwa='%s/tools/bwa-0.5.7-mh/bwa'%prada_path
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
136 blastn='%s/tools/blastn'%prada_path
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
137
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
138 ######################################################################################
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
139 print 'step 0: loading gene annotations @ %s'%time.ctime()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
140 #call functions in ioprada module //
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
141 txdb,genedb=ioprada.read_feature(featurefile,verbose=True)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
142 tx_primary=ioprada.read_tx_cat(txcatfile)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
143 tx_cds=ioprada.read_cds(cdsfile)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
144
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
145 ######################################################################################
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
146 print 'step 1: finding discordant pairs @ %s'%time.ctime()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
147
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
148 #We sift through all exons of protein coding genes and get the mapping reads.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
149 #Within, we exclude low mapping quality reads and PCR duplicates. For pairs that the two ends
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
150 #map to different genes, we all it a discordant pair.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
151 #This is a step for finding all possible candidate fusions.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
152
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
153 samfile=pysam.Samfile(bampath,'rb')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
154
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
155 read1_ab={}
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
156 read2_ab={}
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
157 db1={}
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
158 db2={}
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
159
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
160 i,N=0,len(genedb)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
161 for gene in genedb:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
162 i+=1
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
163 if i%200==0:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
164 print '%d/%d genes processed for discordant pairs'%(i,N)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
165 g=genedb[gene]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
166 exons=g.get_exons()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
167 for e in exons.values():
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
168 for rd in samfile.fetch(e.chr,e.start-1,e.end):
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
169 if rd.mapq < minmapq:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
170 continue
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
171 if rd.is_duplicate:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
172 continue
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
173 if rd.mate_is_unmapped: #at this point, only consider pairs
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
174 continue
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
175 if rd.rnext == rd.tid and rd.mpos <= g.end and rd.mpos >= g.start-1: #remove reads that fall into the same gene range
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
176 continue
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
177 if rd.is_read1:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
178 if read1_ab.has_key(rd.qname):
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
179 read1_ab[rd.qname].add(gene)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
180 else:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
181 read1_ab[rd.qname]=set([gene])
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
182 db1[rd.qname]=rd
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
183 if rd.is_read2:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
184 if read2_ab.has_key(rd.qname):
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
185 read2_ab[rd.qname].add(gene)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
186 else:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
187 read2_ab[rd.qname]=set([gene])
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
188 db2[rd.qname]=rd
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
189
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
190 ##output the discordant pairs and determine the orientation of candidate fusions
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
191 discordant={} #catalogue all discordant pairs, using gene pairs as keys
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
192 outfile=open('%s/%s.discordant.txt'%(outpath,docstring),'w')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
193 title=['read','gene1','gene1_chr','read1_pos','read1_mm','read1_strand','read1_orient','gene2',\
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
194 'gene2_chr','read2_pos','read2_mm','read2_strand','read2_orient']
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
195 outfile.write('%s\n'%('\t'.join(title)))
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
196 i=0
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
197 for rdid in read1_ab:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
198 i+=1
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
199 if i%10000==0:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
200 print '%d discordant pairs processed'%i
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
201 if not read2_ab.has_key(rdid): #skip if not all ends are catalogued
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
202 continue
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
203 g1set=read1_ab[rdid] #consider all combinations if a read maps to multiple genes
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
204 g2set=read2_ab[rdid] #consider all combinations if a read maps to multiple genes
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
205 r1,r2=db1[rdid],db2[rdid]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
206 read1strd='-1' if r1.is_reverse else '1'
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
207 read2strd='-1' if r2.is_reverse else '1'
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
208 for g1 in g1set:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
209 for g2 in g2set:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
210 if g1==g2: #for some uncasual cases
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
211 continue
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
212 g1obj,g2obj=genedb[g1],genedb[g2]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
213 read1orient='F' if read1strd == g1obj.strand else 'R' #read1 --> gene1
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
214 read2orient='F' if read2strd == g2obj.strand else 'R' #read2 --> gene2
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
215 fkey=''
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
216 if read1orient=='F' and read2orient=='R': ##scenario I, gene1-gene2
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
217 fkey=g1+'_'+g2
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
218 if read1orient=='R' and read2orient=='F': ##scenario II, gene2-gene1
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
219 fkey=g2+'_'+g1
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
220 if fkey:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
221 if discordant.has_key(fkey):
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
222 discordant[fkey].update({rdid:'%s:%s'%(read1orient,read2orient)})
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
223 else:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
224 discordant[fkey]={rdid:'%s:%s'%(read1orient,read2orient)}
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
225 ##output
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
226 nm1=str([x[1] for x in r1.tags if x[0]=='NM'][0]) #output mismatch, but does not consider it at this point
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
227 nm2=str([x[1] for x in r2.tags if x[0]=='NM'][0])
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
228 uvec=[rdid,g1,g1obj.chr,str(r1.pos+1),nm1,read1strd,read1orient,g2,g2obj.chr,str(r2.pos+1),nm2,read2strd,read2orient]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
229 outfile.write('%s\n'%('\t'.join(uvec)))
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
230 outfile.close()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
231
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
232 ##########################################################################
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
233 print 'step 2: finding recurrent pairs (candidates) @ %s'%time.ctime()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
234
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
235 #step 2 finds all candidates that have at least 2 discordant pairs. Meanwhile, filter out potential
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
236 #read through events. read through is defined as reads with mapping position less than 1M, while meeting
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
237 #the strand expectation.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
238
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
239 guess=[]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
240 outfile=open('%s/%s.recurrent.txt'%(outpath,docstring),'w')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
241 title=['geneA','geneA_chr','geneB','geneB_chr','num_pairs','IDs']
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
242 outfile.write('%s\n'%('\t'.join(title)))
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
243 for pp in discordant:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
244 if len(discordant[pp]) < 2: #consider only "recurrent" (more than 1 pair support) cases
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
245 continue
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
246 gene1,gene2=pp.split('_')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
247 g1obj,g2obj=genedb[gene1],genedb[gene2]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
248 rdset=discordant[pp].keys()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
249 #filter read-through
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
250 #readthrough is defined at read level, regardless of mapping genes
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
251 for rd in rdset:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
252 r1,r2=db1[rd],db2[rd]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
253 read1strd='-1' if r1.is_reverse else '1'
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
254 read2strd='-1' if r2.is_reverse else '1'
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
255 readthrough=False
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
256 if db1[rd].tid == db2[rd].tid and abs(db1[rd].pos - db2[rd].pos) <= 1000000:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
257 if discordant[pp][rd]=='F:R':
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
258 if read1strd=='1' and read2strd=='-1' and db1[rd].pos < db2[rd].pos:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
259 readthrough=True
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
260 if read1strd=='-1' and read2strd=='1' and db1[rd].pos > db2[rd].pos:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
261 readthrough=True
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
262 if discordant[pp][rd]=='R:F':
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
263 if read2strd=='1' and read1strd=='-1' and db2[rd].pos < db1[rd].pos:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
264 readthrough=True
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
265 if read2strd=='-1' and read1strd=='1' and db2[rd].pos > db1[rd].pos:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
266 readthrough=True
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
267 if readthrough:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
268 del discordant[pp][rd] #in-place deletion!!!! Change the discordant variable in place!
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
269 if len(discordant[pp]) < 2: #skip all that have less than 2 supporting discordant read pairs after readthrough filter
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
270 continue
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
271 guess.append(pp)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
272 #output
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
273 uvec2=[gene1,g1obj.chr,gene2,g2obj.chr,str(len(discordant[pp])),'|'.join(discordant[pp])]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
274 outfile.write('%s\n'%('\t'.join(uvec2)))
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
275 outfile.close()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
276
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
277 ##########################################################################
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
278 print 'step 3: finding potential junction spanning reads @ %s'%time.ctime()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
279
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
280 #For all candidates, find potential junction spanning reads (JSRs). A JSR is defined as a unmapped read but with the mate mapping
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
281 #to either F or R partner, with high mapping quality. Since the JSR is unmapped, it is not practical to consider PCR duplicate
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
282 #because they are not properly marked.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
283
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
284 Fpartners=set()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
285 Rpartners=set()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
286 for pp in guess:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
287 gs=pp.split('_')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
288 Fpartners.add(gs[0])
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
289 Rpartners.add(gs[1])
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
290 AllPartners=Fpartners|Rpartners
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
291
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
292 samfile.reset()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
293 posjun={} ##catalogue all JSRs, with track of the mate mapping genes and orientation.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
294 i,N=0,len(AllPartners)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
295 for gene in AllPartners:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
296 i+=1
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
297 if i%200==0:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
298 print '%d/%d genes processed for potential junc reads'%(i,N)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
299 g=genedb[gene]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
300 exons=g.get_exons().values()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
301 for e in exons:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
302 for rd in samfile.fetch(e.chr,e.start-1,e.end):
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
303 if rd.mapq < minmapq:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
304 continue
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
305 if not rd.mate_is_unmapped:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
306 continue
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
307 readstrd='-1' if rd.is_reverse else '1'
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
308 orient='F' if readstrd == g.strand else 'R' #mapping info of mate read. JSR per se is unmapped in BAM
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
309 posjun[rd.qname]={'gene':gene,'orient':orient}
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
310
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
311 samfile.reset()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
312 outfile=open('%s/%s.pos_junc_unmapped.fastq'%(outpath,docstring),'w')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
313 i,N=0,len(posjun)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
314 for rd in samfile:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
315 if rd.mate_is_unmapped: #since the read is potential jun spanning read, all mate map to A or B
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
316 continue
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
317 if rd.is_unmapped:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
318 if posjun.has_key(rd.qname):
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
319 i+=1
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
320 if i%10000==0:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
321 print 'extracted %d/%d potential junc reads'%(i,N)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
322 rdname='%s_prada_%s_prada_%s'%(rd.qname,posjun[rd.qname]['gene'],posjun[rd.qname]['orient']) #_prada_ as split
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
323 outfile.write('@%s\n'%rdname)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
324 outfile.write('%s\n'%rd.seq)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
325 outfile.write('+\n')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
326 outfile.write('%s\n'%rd.qual)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
327 outfile.close()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
328
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
329 ######################################################################################
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
330 print 'step 4: building junction database @ %s'%time.ctime()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
331
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
332 #Make hypothetical junctions between candidate fusion partners. To improve speed, we make a big junction database comprising
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
333 #exons of all candidates, instead of by candidate individually. This also gives the possibility to assess the JSR mapping ambiguity
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
334 #across many junctions. It turned out very useful in filtering out false positives.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
335 #Note that in PRADA transcript sequence file, all sequences are + strand sequences. For - strand transcript, one need to
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
336 #reverse complement the sequence to get the real transcript sequences.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
337
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
338 seqdb={}
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
339 for record in SeqIO.parse(txseqfile,'fasta'):
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
340 seqdb[record.name]=record
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
341
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
342 outfile=open('%s/%s.junction.fasta'%(outpath,docstring),'w')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
343 i,N=0,len(guess)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
344 for pp in guess:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
345 i+=1
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
346 if i%100==0:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
347 print 'building junction for %d/%d pairs'%(i,N)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
348 gene1,gene2=pp.split('_')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
349 g1obj,g2obj=genedb[gene1],genedb[gene2]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
350 eset1=g1obj.get_exons() #unique exons in gene 1
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
351 eset2=g2obj.get_exons() #unique exons in gene 2
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
352 #collect unique junctions
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
353 juncseqdict={} #save junction sequences
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
354 for e1 in eset1.values():
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
355 for e2 in eset2.values():
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
356 e1_jun_name='%s:%s:%s'%(gene1,e1.chr,e1.end) if e1.strand=='1' else '%s:%s:%s'%(gene1,e1.chr,e1.start)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
357 e2_jun_name='%s:%s:%s'%(gene2,e2.chr,e2.start) if e2.strand=='1' else '%s:%s:%s'%(gene2,e2.chr,e2.end)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
358 jun_name=e1_jun_name+'_'+e2_jun_name
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
359 tx1,tx2=txdb[e1.transcript],txdb[e2.transcript]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
360 max_a=tx1.exon_relative_pos()[e1.name][1]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
361 min_a=0 if max_a - overlap < 0 else max_a - overlap
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
362 min_b=tx2.exon_relative_pos()[e2.name][0]-1
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
363 max_b=tx2.length if min_b + overlap > tx2.length else min_b + overlap
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
364 #reverse complementary when necessary
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
365 try:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
366 tx1seq=seqdb[tx1.name].seq.tostring() if tx1.strand=='1' else seqdb[tx1.name].reverse_complement().seq.tostring()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
367 tx2seq=seqdb[tx2.name].seq.tostring() if tx2.strand=='1' else seqdb[tx2.name].reverse_complement().seq.tostring()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
368 except KeyError: #in case transcript not found in sequence file
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
369 continue
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
370 jun_seq=tx1seq[min_a:max_a]+tx2seq[min_b:max_b]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
371 juncseqdict[jun_name]=jun_seq
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
372 for junc in juncseqdict:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
373 outfile.write('>%s\n'%junc)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
374 outfile.write('%s\n'%juncseqdict[junc])
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
375 outfile.close()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
376 samfile.close()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
377
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
378 #for memory efficiecy, del seqdb
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
379 del seqdb
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
380
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
381 ########################################################################################
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
382 print 'step 5: aligning potential junction reads to junction database @ %s'%time.ctime()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
383
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
384 #Mapping potential JSRs to hypothetical junction database.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
385 #Allow 4 mismatches at the beginning.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
386
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
387 idx_cmd='%s index %s/%s.junction.fasta'%(bwa,outpath,docstring)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
388 os.system(idx_cmd)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
389 aln_cmd='%s aln -n 4 -R 100 %s/%s.junction.fasta %s/%s.pos_junc_unmapped.fastq > %s/%s.juncmap.sai'%(bwa,outpath,docstring,outpath,docstring,outpath,docstring)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
390 os.system(aln_cmd)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
391 samse_cmd='%s samse -n 1000 -s %s/%s.junction.fasta %s/%s.juncmap.sai %s/%s.pos_junc_unmapped.fastq > %s/%s.juncmap.sam'%(bwa,outpath,docstring,outpath,docstring,outpath,docstring,outpath,docstring)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
392 os.system(samse_cmd)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
393 sam2bam_cmd='%s view -bS %s/%s.juncmap.sam -o %s/%s.juncmap.bam'%(samtools,outpath,docstring,outpath,docstring)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
394 os.system(sam2bam_cmd)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
395
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
396 jsam=pysam.Samfile('%s/%s.juncmap.bam'%(outpath,docstring),'rb')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
397 #get the junction name directory
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
398 junctions=jsam.references
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
399 junname=dict(zip(range(0,len(junctions)),junctions)) #this is essential for quick speed.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
400 junc_align={}
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
401
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
402 #go through the BAM file for meaningful (meeting fusion orientation etc) reads
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
403 strd_right_reads={}
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
404 rdb={} #collect all junction spanning reads
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
405 i=0
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
406 for rd in jsam:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
407 i+=1
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
408 if i%100000==0:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
409 print '%d junction alignments parsed'%i
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
410 if rd.is_unmapped:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
411 continue
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
412 read,mate_gene,mate_orient=rd.qname.split('_prada_')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
413 junc=junname[rd.tid]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
414 tmp=junc.split('_')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
415 gene1,gene2=[x.split(':')[0] for x in tmp]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
416 if gene1==mate_gene:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
417 if mate_orient=='F':
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
418 if rd.is_reverse:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
419 if strd_right_reads.has_key(rd.qname):
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
420 strd_right_reads[rd.qname]+=1 #count how many times the read maps
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
421 else:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
422 strd_right_reads[rd.qname]=1
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
423 rdb[rd.qname]={'read':rd,'gene1':gene1,'gene2':gene2,'junc':junc} #will overwrite, but it is OK since we only look at unique ones
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
424 elif gene2==mate_gene:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
425 if mate_orient == 'R':
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
426 if not rd.is_reverse:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
427 if strd_right_reads.has_key(rd.qname):
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
428 strd_right_reads[rd.qname]+=1
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
429 else:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
430 strd_right_reads[rd.qname]=1
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
431 rdb[rd.qname]={'read':rd,'gene1':gene1,'gene2':gene2,'junc':junc} #will overwrite, but it is OK since we only look at unique ones
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
432
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
433 #find uniquely mapped reads and their gene pairs
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
434 junc_map={} #a dictionary from junction to mapping reads
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
435 for rdname in strd_right_reads:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
436 if strd_right_reads[rdname] > 1: #remove non-unique junction spanning reads
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
437 continue
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
438 infodict=rdb[rdname]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
439 pp=infodict['gene1']+'_'+infodict['gene2']
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
440 if junc_map.has_key(pp):
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
441 junc_map[pp].add(rdname)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
442 else:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
443 junc_map[pp]=set([rdname])
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
444
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
445 ########################################################################################
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
446 print 'step 6: summarizing fusion evidences @ %s'%time.ctime()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
447
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
448 #Now, time to apply mismatch filter and summarize the results
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
449 #Candidate fusions --> guess
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
450 #Discordant pairs --> discordant, db1, db2
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
451 #Junction reads --> junc_map, rdb
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
452 #Gene info --> genedb
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
453
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
454 outfile_s=open('%s/%s.fus.candidates.txt'%(outpath,docstring),'w')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
455 outfile_d=open('%s/%s.fus.evidences.txt'%(outpath,docstring),'w')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
456
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
457 title=['Gene_A','Gene_B','A_chr','B_chr','A_strand','B_strand','Discordant_n','JSR_n','perfectJSR_n','Junc_n','Position_Consist','Junction']
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
458 outfile_s.write('%s\n'%('\t'.join(title)))
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
459
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
460 for pp in junc_map: #all pairs with junc reads
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
461 gene1,gene2=pp.split('_')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
462 g1obj,g2obj=genedb[gene1],genedb[gene2]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
463 fus_disc=[] #collecting discordant pairs
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
464 for rdname in discordant[pp]:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
465 #arrange read1/read2 into F/R so it will be easier for GeneFusion obj to handle
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
466 r1,r2=db1[rdname],db2[rdname]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
467 orient=discordant[pp][rdname]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
468 if orient=='F:R':
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
469 fus_disc.append((r1,r2))
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
470 elif orient=='R:F':
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
471 fus_disc.append((r2,r1))
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
472 fus_jsr=[]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
473 if junc_map.has_key(pp):
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
474 for rdname in junc_map[pp]:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
475 r=rdb[rdname]['read']
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
476 junc=rdb[rdname]['junc']
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
477 jsr=gfclass.JSR(r,junc)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
478 fus_jsr.append(jsr)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
479 gf=gfclass.GeneFusion(gene1,gene2,fus_disc,fus_jsr)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
480 gf_new=gf.update(mm=mm) ##apply the mismatch parameter, default is 1
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
481 #output the results
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
482 disc_n=str(len(gf_new.discordantpairs))
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
483 junctions=sorted(gf_new.get_junction_freq(),key=operator.itemgetter(1),reverse=True) #sort junc by # of JSRs
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
484 junc_n=str(len(junctions))
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
485 junc_str='|'.join([','.join([x[0],str(x[1])]) for x in junctions])
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
486 jsr_n=str(len(gf_new.fusionreads))
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
487 pjsr_n=str(len(gf_new.get_perfect_JSR()))
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
488 pos_consist=gf_new.positioncheck()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
489 svec=[gene1,gene2,g1obj.chr,g2obj.chr,g1obj.strand,g2obj.strand,disc_n,jsr_n,pjsr_n,junc_n,pos_consist,junc_str]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
490 outfile_s.write('%s\n'%('\t'.join(svec)))
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
491 outfile_d.write('@@\t%s,%s,%s\t%s,%s,%s\n'%(gene1,g1obj.chr,g1obj.strand,gene2,g2obj.chr,g2obj.strand))
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
492 outfile_d.write('\n')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
493 outfile_d.write('>discordant\n')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
494 for rp in gf_new.discordantpairs:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
495 rf,rr=rp
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
496 nm1=[x[1] for x in rf.tags if x[0]=='NM'][0]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
497 nm2=[x[1] for x in rr.tags if x[0]=='NM'][0]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
498 outfile_d.write('%s\tF\t%s.%s.mm%d\n'%(rf.qname,gene1,rf.pos+1,nm1)) ##0-based coordinates
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
499 outfile_d.write('%s\tR\t%s.%s.mm%d\n'%(rr.qname,gene2,rr.pos+1,nm2)) ##0-based coordinates
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
500 outfile_d.write('\n')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
501 outfile_d.write('>spanning\n')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
502 for jsr in gf_new.fusionreads:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
503 r=jsr.read
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
504 nm=[x[1] for x in r.tags if x[0]=='NM'][0]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
505 outfile_d.write('%s\t%s.mm%d\n'%(r.qname,jsr.junction,nm))
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
506 outfile_d.write('\n')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
507 outfile_d.write('>junction\n')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
508 for junc_info in junctions:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
509 outfile_d.write('%s\t%d\n'%(junc_info[0],junc_info[1]))
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
510 outfile_d.write('\n')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
511 outfile_d.write('>summary\n')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
512 outfile_d.write('Number of Discordant Pairs = %s\n'%disc_n)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
513 outfile_d.write('Number of Fusion Reads = %s\n'%jsr_n)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
514 outfile_d.write('Number of Perfect Fusion Reads = %s\n'%pjsr_n)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
515 outfile_d.write('Number of Distinct Junctions = %s\n'%junc_n)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
516 outfile_d.write('Position Consistency = %s\n'%pos_consist)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
517 outfile_d.write('\n')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
518
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
519 outfile_s.close()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
520 outfile_d.close()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
521
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
522 ########################################################################################
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
523 print 'step 7: generating fusion lists @ %s'%time.ctime()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
524
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
525 #For convenience, filter the lists to candidates with
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
526 # 1) at least 2 discordant pairs
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
527 # 2) at least 1 perfect JSR
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
528 #meanwhile, calculate sequence similarity for each pair
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
529 #user may need to manually filter the lists per this measure.
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
530
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
531 #The following code is a copy of prada-homology
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
532 outfile_o=open('%s/%s.fus.summary.txt'%(outpath,docstring),'w')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
533 ifname='%s/%s.fus.candidates.txt'%(outpath,docstring)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
534 if not os.path.exists(ifname):
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
535 sys.exit('ERROR: %s was not found'%ifname)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
536
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
537 blastseq_tmp_dir='%s/blast_tmp/'%outpath
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
538 if not os.path.exists(blastseq_tmp_dir):
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
539 os.mkdir(blastseq_tmp_dir)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
540
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
541 flists=[]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
542 infile=open(ifname)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
543 iN=0
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
544 for line in open(ifname):
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
545 info=line.strip().split('\t')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
546 if iN==0:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
547 iN+=1 #skip title
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
548 flists.append(info)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
549 continue
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
550 else:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
551 if int(info[6])>=2 and int(info[8])>=1 and info[10] in ['PARTIALLY','YES']:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
552 flists.append(info)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
553 infile.close()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
554
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
555 if len(flists)==1: #if no candidate passes the filters
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
556 outfile_o.write('%s\n'%'\t'.join(flists[0]))
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
557 outfile_o.close()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
558 print 'step done @ %s'%time.ctime()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
559 sys.exit(0)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
560
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
561 candidates={}
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
562 for line in flists[1:]:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
563 geneA,geneB=line[0],line[1]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
564 key='%s_%s'%(geneA,geneB)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
565 candidates[key]=''
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
566
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
567 selecttranscript={}
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
568 for gene in genedb:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
569 txs=genedb[gene].transcript
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
570 stx=txs[0]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
571 initlen=stx.length
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
572 for tx in txs:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
573 if tx.length >= initlen:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
574 stx=tx
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
575 initlen=stx.length
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
576 selecttranscript[gene]=stx.name
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
577
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
578 allpartners=set()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
579 for item in candidates:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
580 sset=set(item.split('_'))
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
581 allpartners=allpartners.union(sset)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
582
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
583 presenttxs=[] #tx that is present in our annotation
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
584 absent=[] #tx that is not in our annotation
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
585 for gene in allpartners:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
586 if selecttranscript.has_key(gene):
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
587 presenttxs.append(selecttranscript[gene])
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
588 else:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
589 absent.append(gene)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
590
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
591 for seq_record in SeqIO.parse(txseqfile,'fasta'):
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
592 sid=seq_record.id
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
593 seq=seq_record.seq
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
594 if sid in presenttxs:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
595 g=txdb[sid].gene
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
596 fastafile=open('%s/%s.fasta'%(blastseq_tmp_dir,g),'w')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
597 SeqIO.write(seq_record,fastafile,'fasta')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
598 fastafile.close()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
599
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
600 for gp in candidates:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
601 geneA,geneB=gp.split('_')
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
602 if geneA in absent or geneB in absent:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
603 candidates[gp]=['NA']*4
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
604 else:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
605 gaseq='%s/%s.fasta'%(blastseq_tmp_dir,geneA)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
606 gaobj=SeqIO.parse(gaseq,'fasta').next()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
607 gbseq='%s/%s.fasta'%(blastseq_tmp_dir,geneB)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
608 gbobj=SeqIO.parse(gbseq,'fasta').next()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
609 ga_len,gb_len=str(len(gaobj.seq)),str(len(gbobj.seq))
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
610 a=privutils.seqblast(gaseq,gbseq,blastn)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
611 if a==None:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
612 candidates[gp]=['NA','NA','100','0']
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
613 else:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
614 candidates[gp]=a
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
615
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
616 header=flists[0][:]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
617 header.extend(['Identity','Align_Len','Evalue','BitScore'])
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
618 outfile_o.write('%s\n'%('\t'.join(header)))
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
619
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
620 for info in flists[1:]:
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
621 geneA,geneB=info[0],info[1]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
622 key='%s_%s'%(geneA,geneB)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
623 vv=candidates[key]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
624 row=info[:]
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
625 row.extend(vv)
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
626 outfile_o.write('%s\n'%('\t'.join(row)))
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
627 outfile_o.close()
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
628
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
629 ########################################################################################
acc2ca1a3ba4 Uploaded
siyuan
parents:
diff changeset
630 print 'step done @ %s'%time.ctime()