/* * The MIT License (MIT) * * Copyright (c) 2007-2015 Broad Institute * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package org.broad.igv.ui; //~--- non-JDK imports -------------------------------------------------------- import org.broad.igv.ui.color.ColorUtilities; import org.w3c.dom.DOMException; import org.w3c.dom.Document; import org.w3c.dom.Element; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.awt.*; import java.io.*; import java.util.*; import java.util.List; /** * Generate an XML resource file, suitable for loading from IGV * in the "load from server" dialog, * based on a directory. Certain properties are set based on * file naming conventions (see {@link #doEpigenetics(java.io.File[], String)}) * * @author eflakes */ public class ResourceFileBuilder { private static Document masterDocument = null; // private static Element rootCategoryNode = null; private static String DEFAULT_SERVER_URL = "http://www.broadinstitute.org/dataserver/data"; private static String DEFAULT_OUTPUT_FILE = "tempResourceFile.xml"; boolean epigenetics; Element rootNode = null; /** * Method description * * @param inputDir */ public void process(File inputDir) { try { process(inputDir, DEFAULT_OUTPUT_FILE, DEFAULT_SERVER_URL); } catch (Exception ex) { ex.printStackTrace(); } } /** * Method description * * @param inputDir * @param outputFile * @param serverUrl * @throws Exception */ public void process(File inputDir, String outputFile, String serverUrl) throws Exception { masterDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); rootNode = masterDocument.createElement("Global"); rootNode.setAttribute("name", "Data"); rootNode.setAttribute("version", "1"); masterDocument.appendChild(rootNode); if (epigenetics) { File[] files = inputDir.listFiles(); Arrays.sort(files); doEpigenetics(files, serverUrl); } else { lookForChildren(inputDir, serverUrl); } // Transform document into XML TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); StreamResult streamResult = new StreamResult(new StringWriter()); DOMSource source = new DOMSource(masterDocument); transformer.transform(source, streamResult); // Create output dir String xmlString = streamResult.getWriter().toString(); File tempXMLFile = new File(outputFile); FileWriter fileWriter = null; fileWriter = new FileWriter(tempXMLFile); fileWriter.write(xmlString); fileWriter.close(); } private void createSampleInfoFiles(File[] files, String sampleInfoFile, String trackPropertiesFile) { Arrays.sort(files); try { PrintWriter sampleInfoWriter = new PrintWriter(new BufferedWriter(new FileWriter(sampleInfoFile))); PrintWriter trackWriter = new PrintWriter(new BufferedWriter(new FileWriter(trackPropertiesFile))); sampleInfoWriter.println("Name\tCell Type\tMark\t#height\t#renderer\t#color\t#min\t#max"); for (File file : files) { String[] tokens = file.getName().split("\\."); if (tokens.length > 2) { String trackName = file.getName().replace(".h5", ""); String cellType = tokens[0].replace("r1", "").replace("r2", "").replace("r3", ""); String mark = tokens[1]; sampleInfoWriter.print(trackName + "\t" + cellType + "\t" + mark); int min = 0; int max = 10; String colorString = ColorUtilities.colorToString(Color.gray); if (mark.toUpperCase().contains("K4")) { max = 25; colorString = "(0,150,0)"; } else if (mark.toUpperCase().contains("K9")) { colorString = "(100,0,0)"; } else if (mark.toUpperCase().contains("K27")) { colorString = "(255,0,0)"; } sampleInfoWriter.println("\t40\tBAR_CHART\t" + colorString + "\t" + min + "\t" + max); } } sampleInfoWriter.close(); } catch (IOException iOException) { } } private void doEpigenetics(File[] files, String serverUrl) throws IOException { LinkedHashSet<String> cellTypes = new LinkedHashSet(); LinkedHashSet<String> markers = new LinkedHashSet(); Map<String, LinkedHashSet<File>> cellMarkerFileMap = new LinkedHashMap(); for (File file : files) { String[] tokens = file.getName().split("\\."); if (tokens.length > 2) { String cellType = tokens[0]; String marker = tokens[1]; cellTypes.add(cellType); markers.add(marker); String cellMarker = cellType + "." + marker; LinkedHashSet<File> cellMarkerFiles = cellMarkerFileMap.get(cellMarker); if (cellMarkerFiles == null) { cellMarkerFiles = new LinkedHashSet(); cellMarkerFileMap.put(cellMarker, cellMarkerFiles); } cellMarkerFiles.add(file); } } Element cellTypeRootNode = masterDocument.createElement("Category"); cellTypeRootNode.setAttribute("name", "Cell Type"); rootNode.appendChild(cellTypeRootNode); List<String> sortedCellTypes = new ArrayList(cellTypes); Collections.sort(sortedCellTypes); List<String> sortedMarks = new ArrayList(markers); Collections.sort(sortedMarks); for (String cellType : sortedCellTypes) { Element cellTypeNode = masterDocument.createElement("Category"); cellTypeNode.setAttribute("name", cellType); cellTypeRootNode.appendChild(cellTypeNode); for (String marker : sortedMarks) { String cmKey = cellType + "." + marker; outputResources(cellMarkerFileMap, serverUrl, cellTypeNode, cmKey); } } Element markerRootNode = masterDocument.createElement("Category"); markerRootNode.setAttribute("name", "Chromatin Mark"); rootNode.appendChild(markerRootNode); for (String marker : sortedMarks) { Element markerNode = masterDocument.createElement("Category"); markerNode.setAttribute("name", marker); markerRootNode.appendChild(markerNode); for (String cellType : sortedCellTypes) { String cmKey = cellType + "." + marker; outputResources(cellMarkerFileMap, serverUrl, markerNode, cmKey); } } } private void outputResources(Map<String, LinkedHashSet<File>> cellMarkerFileMap, String serverUrl, Element cellTypeRootNode, String cmKey) throws IOException, DOMException { LinkedHashSet<File> files = cellMarkerFileMap.get(cmKey); if (files != null) { System.out.println(cmKey + " -> " + files.size()); if (files.size() > 0) { for (File file : files) { String canonicalPath = file.getCanonicalPath(); Element resourceNode = masterDocument.createElement("Resource"); resourceNode.setAttribute("name", cmKey); resourceNode.setAttribute("path", canonicalPath); resourceNode.setAttribute("serverURL", serverUrl); cellTypeRootNode.appendChild(resourceNode); } } } } private void lookForChildren(File dir, String serverUrl) throws IOException { if (dir.isDirectory()) { if (rootNode != null) { for (File file : dir.listFiles()) { String canonicalPath = file.getCanonicalPath(); Element resourceNode = masterDocument.createElement("Resource"); resourceNode.setAttribute("name", file.getName()); resourceNode.setAttribute("path", canonicalPath); resourceNode.setAttribute("serverURL", serverUrl); rootNode.appendChild(resourceNode); } } } else { System.err.println("Input must be a directory: " + dir.getAbsolutePath()); } } }