/*-------------------------------------------------------------------------- * Copyright 2009 utgenome.org * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *--------------------------------------------------------------------------*/ //-------------------------------------- // utgb-core Project // // BED2Silk.java // Since: 2009/05/07 // // $URL$ // $Author$ //-------------------------------------- package org.utgenome.shell.db.bed; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.PrintWriter; import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; import java.util.ArrayList; import org.antlr.runtime.ANTLRReaderStream; import org.antlr.runtime.CommonTokenStream; import org.antlr.runtime.RecognitionException; import org.antlr.runtime.tree.Tree; import org.utgenome.shell.UTGBShellException; import org.xerial.core.XerialException; import org.xerial.util.bean.impl.BeanUtilImpl; import org.xerial.util.log.Logger; /** * @author yoshimura * */ public class BED2Silk { // private File bedFile; // private BEDHeaderDescription browser; // private BEDHeaderDescription track; // private ArrayList genes; private static Logger _logger = Logger.getLogger(BED2Silk.class); private final BufferedReader reader; public static class BEDHeaderDescription { String name; ArrayList attributes = new ArrayList(); public void setName(String name) { this.name = name; } public void addAttribute(BEDHeaderAttribute attribute) { attributes.add(attribute); } @Override public String toString() { return String.format("name=%s, attributes=%s", name, attributes.toString()); } } public static class BEDHeaderAttribute { String name; String value; public void setName(String name) { this.name = name; } public void setValue(String value) { this.value = value; } @Override public String toString() { return String.format("{name=%s, value=%s}", name, value); } } public BED2Silk(File bedFile) throws IOException { this(new FileReader(bedFile)); } /** * * @param bedFile * @throws IOException */ public BED2Silk(Reader bedFile) throws IOException { // track = new BEDHeaderDescription(); // genes = new ArrayList(); this.reader = new BufferedReader(bedFile); } /** * * @param out * @throws IOException * @throws UTGBShellException */ public void toSilk(PrintWriter out) throws IOException, UTGBShellException { // print header line out.print("%silk(version:1.0)"); out.flush(); int geneCount = 0; int lineNum = 1; for (String line; (line = reader.readLine()) != null; lineNum++) { try { if (line.startsWith("#") || line.length() == 0) { } else if (line.startsWith("browser")) { // this.browser = readTrackLine(line,i); } else if (line.startsWith("track")) { // print track line BEDHeaderDescription track = readTrackLine(line); StringBuffer sb = new StringBuffer("\n-track("); for (BEDHeaderAttribute a : track.attributes) { sb.append(a.name + ":"); if ((a.value.contains(",") || a.value.contains(" ")) && !a.value.startsWith("\"") && !a.value.endsWith("\"")) { sb.append("\"" + a.value + "\", "); } else { sb.append(a.value + ", "); } } sb.delete(sb.lastIndexOf(","), sb.length()).append(")"); out.println(sb.toString()); out.flush(); } else { String[] gene = readBEDLine(line, lineNum); if (geneCount == 0) { // print gene header line out.println(" -gene(coordinate, start, end, name, strand, cds(start, end), exon(start, end)*, color, _[json])|"); out.flush(); } geneCount++; StringBuilder sb = new StringBuilder(); if (gene.length >= 3) { // print "coordinate.name, start, end" sb.append(gene[0] + "\t" + shiftOneBase(gene[1]) + "\t" + gene[2]); // print "name" if (gene.length >= 4) { sb.append("\t" + gene[3]); } // print "strand" sb.append("\t"); if (gene.length >= 6) { sb.append(gene[5]); } // print "cds" sb.append("\t"); if (gene.length >= 8) { sb.append("[" + shiftOneBase(gene[6]) + ", " + gene[7] + "]"); } // print "exon" sb.append("\t"); if (gene.length >= 12) { String[] blockSizes = gene[10].split(","); String[] blockStarts = gene[11].split(","); sb.append("["); for (int i = 0; i < Integer.valueOf(gene[9]); i++) { long startExon = Long.valueOf(gene[1]) + Long.valueOf(shiftOneBase(blockStarts[i])); long endExon = startExon + Long.valueOf(blockSizes[i]).longValue() - 1; sb.append("[" + startExon + ", " + endExon + "]"); if (i < Integer.valueOf(gene[9]) - 1) { sb.append(", "); } } sb.append("]"); } // print "color" sb.append("\t"); if (gene.length >= 9) { sb.append(changeRGB2Hex(gene[8])); } // print "score" sb.append("\t"); if (gene.length >= 5) { sb.append("{\"score\":" + gene[4] + "}"); } out.println(sb.toString()); out.flush(); } } } catch (RecognitionException e) { throw new UTGBShellException(String.format("line %d: %s", lineNum, e)); } catch (XerialException e) { throw new UTGBShellException(String.format("line %d: %s", lineNum, e)); } } } public String toSilk() throws IOException, UTGBShellException { StringWriter out = new StringWriter(); toSilk(new PrintWriter(out)); return out.toString(); } private static String[] readBEDLine(String line, int lineNo) { String[] temp = line.replace(" ", "\t").trim().split("\t+"); // split by tab or space if (temp.length < 3) { _logger.error("Error data -> line:" + lineNo); } return temp; } private static BEDHeaderDescription readTrackLine(String line) throws IOException, XerialException, RecognitionException { BEDLexer lexer = new BEDLexer(new ANTLRReaderStream(new StringReader(line))); CommonTokenStream tokens = new CommonTokenStream(lexer); BEDParser parser = new BEDParser(tokens); BEDParser.description_return ret = parser.description(); return BeanUtilImpl.createBeanFromParseTree(BEDHeaderDescription.class, (Tree) ret.getTree(), BEDParser.tokenNames); } private static String changeRGB2Hex(String rgb) { String[] temp = rgb.split(","); StringBuffer ret = new StringBuffer("\"#"); if (temp.length >= 3) { for (int i = 0; i < 3; i++) { if (Integer.valueOf(temp[i]) > 255 || Integer.valueOf(temp[i]) < 0) { System.err.println("Warn : out of color range 0-255"); return ""; } if (Integer.toHexString(Integer.valueOf(temp[i])).length() == 1) { ret.append("0"); } ret.append(Integer.toHexString(Integer.valueOf(temp[i]))); } return ret.append("\"").toString(); } else { return ""; } } private static String shiftOneBase(String baseNumber) { return String.valueOf(Long.valueOf(baseNumber) + 1); } }