package com.github.lindenb.jvarkit.tools.biostar; import htsjdk.samtools.util.CloserUtil; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.util.List; import java.util.regex.Pattern; import org.broad.igv.bbfile.BBFileReader; import org.broad.igv.bbfile.BigWigIterator; import org.broad.igv.bbfile.WigItem; import com.beust.jcommander.Parameter; import com.github.lindenb.jvarkit.io.IOUtils; import com.github.lindenb.jvarkit.util.jcommander.Launcher; import com.github.lindenb.jvarkit.util.jcommander.Program; import com.github.lindenb.jvarkit.util.log.Logger; /** BEGIN_DOC ## Example ``` $ echo -e "1\t1000\t20000\n3\t100\t200\nUn\t10\t11" |\ java -jar dist/biostar105754.jar -B path/to//All_hg19_RS_noprefix.b #no data found for Un 10 11 1 1000 1001 0.0 1 1000 20000 3 100 101 0.0 3 100 200 ``` END_DOC */ @Program(name="biostar105754",description="bigwig : peak distance from specific genomic region",biostars=105754) public class Biostar105754 extends Launcher { private static final Logger LOG = Logger.build(Biostar105754.class).make(); @Parameter(names={"-o","--output"},description="Output file. Optional . Default: stdout") private File outputFile = null; @Parameter(names={"-B","--bigwig"},description="Big Wig file") private String bigWigFile = null; private static int distance(int start1,int end1, int start2,int end2) { if(end1< start2) { return start2-end1; } else if(end2< start1) { return start1-end2; } int d=Math.abs(start1-start2); d=Math.min(d,Math.abs(start1-end2)); d=Math.min(d,Math.abs(end1-start2)); d=Math.min(d,Math.abs(end1-end2)); return d; } private PrintWriter out=null; private org.broad.igv.bbfile.BBFileReader bbFileReader=null; private final long EXTEND_SHIFT=1000000;// private final long MAX_CHROM_END=Integer.MAX_VALUE-EXTEND_SHIFT; private void run(BufferedReader r) throws IOException { String line; final Pattern tab=Pattern.compile("[\t]"); while((line=r.readLine())!=null && !this.out.checkError()) { if(line.startsWith("#")) { continue; } String tokens[]=tab.split(line,4); if(tokens.length<3) { System.err.println("Bad BED line: "+line); continue; } String chrom=tokens[0]; int chromStart0=Integer.parseInt(tokens[1]); int chromEnd0=Integer.parseInt(tokens[2]); if(chrom.isEmpty() || chromStart0<0L || chromEnd0<chromStart0) { System.err.println("Bad BED line: "+line); continue; } //extends bed area until something was found int chromStart=chromStart0; int chromEnd=chromEnd0; for(;;) { BigWigIterator iter=this.bbFileReader.getBigWigIterator( chrom, chromStart, chrom, chromEnd, false); if(iter!=null) { WigItem best=null; while(iter.hasNext()) { WigItem wigItem=iter.next(); if(best==null || distance(chromStart,chromEnd,best.getStartBase(),best.getEndBase()) > distance(chromStart,chromEnd,wigItem.getStartBase(),wigItem.getEndBase()) ) { best=wigItem; } } if(best!=null) { this.out.print(best.getChromosome()); this.out.print("\t"); this.out.print(best.getStartBase()); this.out.print("\t"); this.out.print(best.getEndBase()); this.out.print("\t"); this.out.print(best.getWigValue()); this.out.print("\t"); this.out.print(line); this.out.println(); break; } } //extend bed area long start2=chromStart-EXTEND_SHIFT; long end2=chromEnd+EXTEND_SHIFT; if(start2<0) start2=0; if(end2>MAX_CHROM_END) end2=MAX_CHROM_END; //too wide, break loop if(start2==0 && end2==MAX_CHROM_END) { LOG.warn("no data found for\t"+line); break; } chromStart=(int)start2; chromEnd=(int)end2; } } } @Override public int doWork(List<String> args) { if(this.bigWigFile==null) { LOG.error("Big wig file undefined option"); return -1; } try { LOG.info("Opening "+this.bigWigFile); this.bbFileReader=new BBFileReader(this.bigWigFile); if(!this.bbFileReader.isBigWigFile()) { LOG.error("File "+this.bigWigFile+" is not a bigwig file"); return -1; } this.out = super.openFileOrStdoutAsPrintWriter(outputFile); if(args.isEmpty()) { BufferedReader r= new BufferedReader(new InputStreamReader(stdin())); run(r); CloserUtil.close(r); } else { for(final String filename : args) { LOG.info("Reading BED from "+filename); final BufferedReader r= IOUtils.openURIForBufferedReading(filename); run(r); CloserUtil.close(r); } } this.out.flush(); this.out.close(); return RETURN_OK; } catch(Exception err) { LOG.error(err); return -1; } finally { CloserUtil.close(bbFileReader); CloserUtil.close(this.out); bbFileReader=null; this.out=null; } } public static void main(String[] args) { new Biostar105754().instanceMainWithExit(args); } }