Mercurial > repos > yhoogstrate > edger_with_design_matrix
view bin/edger_dge_table_to_bedgraph @ 5:bde663b872d9 draft
planemo upload for repository https://bitbucket.org/EMCbioinf/galaxy-tool-shed-tools/raw/master/edger_with_design_matrix commit 275a72ec0424e4e5d658d1bc8227077ea46f0fdc
author | yhoogstrate |
---|---|
date | Mon, 14 Dec 2015 11:01:38 -0500 |
parents | a4a4c88783ea |
children |
line wrap: on
line source
#!/usr/bin/env python import re,sys,os,os.path,argparse,textwrap,datetime class GTF: def __init__(self,filename,features=["exon"],symbol="gene_id"): self.features = features if(re.match("^[a-zA-Z0-9_\-]+$",symbol)): self.symbol = symbol else: raise ValueError('False symbol matching symbol: '+str(symbol)) self.index = {} self.parse(filename) def parse(self,filename): with open(filename) as infile: for line in infile: self.parse_line(line) def parse_line(self,line): line = line.strip().split("\t") if(len(line) == 9): if(line[2] in self.features): gene_id = self.parse_column_9(line[8]) if(gene_id): if(not self.index.has_key(gene_id)): self.index[gene_id] = [] self.index[gene_id].append([line[0],line[3],line[4]]) def parse_column_9(self,line): query = self.symbol+'[ =]+([^ ;]+)' m = re.search(query, line) if(m): return m.group(1).strip("'").strip('"') else: return None def get(self,key): try: return self.index[key] except: return False class EdgeR_table: def __init__(self,table,gtf,columns=[3,7]): self.index = {} self.gtf = gtf self.columns = columns self.parse(table) def parse(self,filename): i = 0 with open(filename) as infile: for line in infile: if(i == 0): self.parse_header(line) else: self.parse_line(line) i += 1 def parse_header(self,line): params = line.strip().split("\t") if(params[1].lower().find("genes") == -1): raise ValueError('False header in file - no "genes" in 2nd colum: '+line) if(params[2].lower().find("logfc") == -1): raise ValueError('False header in file - no "logfc" in 3rd colum: '+line) if(params[3].lower().find("logcpm") == -1): raise ValueError('False header in file - no "logcpm" in 4th colum: '+line) if(params[4].lower().find("lr") == -1): raise ValueError('False header in file - no "lr" in 5th colum: '+line) if(params[5].lower().find("pvalue") == -1): raise ValueError('False header in file - no "pvalue" in 6th colum: '+line) if(params[6].lower().find("fdr") == -1): raise ValueError('False header in file - no "fdr" in 7th colum: '+line) def parse_line(self,line): line = line.strip().split("\t") if(len(line) == 7): gene_id = line[1].strip('"').strip("'") column_data = {} for column in self.columns: if(column in [6,7]): column_data[column] = str(1.0 - float(line[column-1])) else: column_data[column] = line[column-1] locations = self.gtf.get(gene_id) if(not locations): print "Warning: no location found for gene "+gene_id else: for location in locations: self.insert(location,column_data) def insert(self,location,data): chrom = location[0] start = location[1] end = location[2] if(not self.index.has_key(chrom)): self.index[chrom] = {} if(not self.index[chrom].has_key(start)): self.index[chrom][start] = {} if(not self.index[chrom][start].has_key(end)): self.index[chrom][start][end] = [] self.index[chrom][start][end].append(data) def export(self,filenames={3:"log_cpm.txt",7:"fdr.txt"}): for column in self.columns: fh = open(filenames[column],"w") buf = False for chrom in sorted(self.index.keys()): for start in sorted(self.index[chrom].keys()): for end in sorted(self.index[chrom][start].keys()): fh.write(chrom+"\t"+start+"\t"+end+"\t"+self.index[chrom][start][end][0][column]+"\n") fh.close() os.system("sort -k1,1V -k2,2g -k3,3g '"+filenames[column]+"' > '"+filenames[column]+".sorted'") def remove_overlap_in_bedgraph(bedgraph_file_dirty,bedgraph_file_clean): fh = open(bedgraph_file_clean,"w") buf = False with open(bedgraph_file_dirty,"r") as f: for line in f: cur = line.strip().split("\t") cur[1] = int(cur[1]) cur[2] = int(cur[2]) if(not buf): buf = cur else: if(cur[0] == buf[0] and cur[1] <= buf[2] ): if(buf[1] == cur[1]): #is subset newscore = (float(buf[3])+float(cur[3]))/2 buf[2] = cur[2] buf[3] = newscore else: c1 = buf[1] c2 = cur[1] c3 = min(buf[2],cur[2]) c4 = max(buf[2],cur[2]) fh.write(buf[0]+"\t"+str(c1)+"\t"+str(c2-1)+"\t"+str(buf[3])+"\n") newscore = (float(buf[3])+float(cur[3]))/2 #fh.write(buf[0]+"\t"+str(c2+1)+"\t"+str(c3)+"\t"+str(newscore)+"\tp2\n") #buf = [buf[0], c3+1 , c4 , cur[3]] buf = [buf[0], c2 , c4 , cur[3]] # find if buf is a subset -> if so, merge and send to buffer # or find the overlapping region # if current is overlapping with buffer; merge: ## [ ] < buf ## [ ] < cur ## ## [ ] < buf ## [ ] < cur ## 111112222333333 << write 1 and 2 and keep 3 in buf else: fh.write(buf[0]+"\t"+str(buf[1])+"\t"+str(buf[2])+"\t"+str(buf[3])+"\n") buf=cur fh.write(buf[0]+"\t"+str(buf[1])+"\t"+str(buf[2])+"\t"+str(buf[3])+"\n") fh.close() if __name__ == "__main__": parser = argparse.ArgumentParser() parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,epilog="For more info please visit:\n<https://github.com/yhoogstrate/fuma>") parser.add_argument("-t",help="CPM table to extract columns from",nargs=1,required=True) parser.add_argument("-g",help="GTF file used to extract genomic location",nargs=1,required=True) parser.add_argument("-c3",help="Output (bedgraph) for column 3 (logFC)",nargs="?",required=False) parser.add_argument("-c4",help="Output (bedgraph) for column 4 (logCPM)",nargs="?",required=False) parser.add_argument("-c5",help="Output (bedgraph) for column 5 (LR)",nargs="?",required=False) parser.add_argument("-c6",help="Output (bedgraph) for column 6 (PValue)",nargs="?",required=False) parser.add_argument("-c7",help="Output (bedgraph) for column 7 (FDR)",nargs="?",required=False) args = parser.parse_args() #files = {3:"VCAP_logFC.hg19.bedgraph",7:"VCAP_fdr.hg19.bedgraph"} files = {} if(args.c3): files[3] = args.c3 if(args.c4): files[4] = args.c4 if(args.c5): files[5] = args.c5 if(args.c6): files[6] = args.c6 if(args.c7): files[7] = args.c7 print "Parsing GTF file" g = GTF(args.g[0]) print "Parsing EdgeR table" e = EdgeR_table(args.t[0],g,files.keys()) print "Exporting raw bedgraph(s)" e.export(files) print "Removing overlapping entries in bedgraph(s)" for key in files.keys(): remove_overlap_in_bedgraph(files[key]+".sorted",files[key]) os.system("rm '"+files[key]+".sorted'")