001// $Id: PsiToBiopax3Converter.java,v 1.2 2009/11/23 13:59:42 rodche Exp $ 002//------------------------------------------------------------------------------ 003/** Copyright (c) 2009 Memorial Sloan-Kettering Cancer Center. 004 ** 005 ** This library is free software; you can redistribute it and/or modify it 006 ** under the terms of the GNU Lesser General Public License as published 007 ** by the Free Software Foundation; either version 2.1 of the License, or 008 ** any later version. 009 ** 010 ** This library is distributed in the hope that it will be useful, but 011 ** WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF 012 ** MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. The software and 013 ** documentation provided hereunder is on an "as is" basis, and 014 ** Memorial Sloan-Kettering Cancer Center 015 ** has no obligations to provide maintenance, support, 016 ** updates, enhancements or modifications. In no event shall 017 ** Memorial Sloan-Kettering Cancer Center 018 ** be liable to any party for direct, indirect, special, 019 ** incidental or consequential damages, including lost profits, arising 020 ** out of the use of this software and its documentation, even if 021 ** Memorial Sloan-Kettering Cancer Center 022 ** has been advised of the possibility of such damage. See 023 ** the GNU Lesser General Public License for more details. 024 ** 025 ** You should have received a copy of the GNU Lesser General Public License 026 ** along with this library; if not, write to the Free Software Foundation, 027 ** Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 028 **/ 029package org.biopax.paxtools.converter.psi; 030 031 032import psidev.psi.mi.tab.PsimiTabException; 033import psidev.psi.mi.tab.PsimiTabReader; 034import psidev.psi.mi.tab.converter.tab2xml.Tab2Xml; 035import psidev.psi.mi.tab.converter.tab2xml.XmlConversionException; 036import psidev.psi.mi.tab.model.BinaryInteraction; 037import psidev.psi.mi.xml.model.Entry; 038import psidev.psi.mi.xml.model.EntrySet; 039import psidev.psi.mi.xml.PsimiXmlReader; 040import psidev.psi.mi.xml.PsimiXmlReaderException; 041 042import java.io.IOException; 043import java.io.InputStream; 044import java.io.OutputStream; 045import java.util.Collection; 046 047import org.biopax.paxtools.io.SimpleIOHandler; 048import org.biopax.paxtools.model.BioPAXLevel; 049import org.biopax.paxtools.model.Model; 050 051/** 052 * The PSIMI 2.5 to BioPAX Level3 converter. 053 * 054 * @author Igor Rodchenkov (rodche) 055 */ 056public class PsiToBiopax3Converter { 057 058 private final String xmlBase; //common URI prefix 059 060 /** 061 * Constructor. 062 * Will use the default empty string xml:base. 063 * 064 */ 065 public PsiToBiopax3Converter() { 066 this.xmlBase = null; 067 } 068 069 /** 070 * Constructor. 071 * 072 * @param xmlBase xml:base to be used when generating non-canonical BioPAX objects' URIs 073 */ 074 public PsiToBiopax3Converter(String xmlBase) { 075 this.xmlBase = xmlBase; 076 } 077 078 079 /** 080 * Converts the PSI-MI inputStream into BioPAX outputStream. 081 * Streams will be closed by the converter. 082 * 083 * Warning: for very large models (about 1-2Gb if serialized), and when ByteArrayOutputStream 084 * is used, OutOfMemoryError might be thrown (increasing the "heap" RAM won't help; but using FileOutputStream will). 085 * 086 * @param inputStream PSI-MI 087 * @param outputStream BioPAX 088 * @param forceInteractionToComplex - always generate Complex instead of MolecularInteraction 089 * 090 * @throws IOException when an I/O error occur 091 * @throws PsimiXmlReaderException when an error in the PSI-MI parser happens 092 */ 093 public void convert(InputStream inputStream, OutputStream outputStream, 094 boolean forceInteractionToComplex) throws IOException, PsimiXmlReaderException { 095 096 // check args 097 if (inputStream == null || outputStream == null) { 098 throw new IllegalArgumentException("convert(): " + 099 "one or more null arguments."); 100 } 101 102 // unmarshall the data, close the stream 103 PsimiXmlReader reader = new PsimiXmlReader(); 104 EntrySet entrySet = reader.read(inputStream); 105 inputStream.close(); 106 107 // convert 108 convert(entrySet, outputStream, forceInteractionToComplex); 109 } 110 111 112 /** 113 * Converts the PSI-MITAB inputStream into BioPAX outputStream. 114 * Streams will be closed by the converter. 115 * 116 * @param inputStream psi-mitab 117 * @param outputStream biopax 118 * @param forceInteractionToComplex - always generate Complex instead of MolecularInteraction 119 * 120 * @throws IOException when an I/O error occur 121 * @throws PsimiTabException when there's a problem within the PSI-MITAB parser 122 */ 123 public void convertTab(InputStream inputStream, OutputStream outputStream, 124 boolean forceInteractionToComplex) throws IOException, PsimiTabException { 125 126 // check args 127 if (inputStream == null || outputStream == null) { 128 throw new IllegalArgumentException("convertTab(): " + 129 "one or more null arguments."); 130 } 131 132 // unmarshall the data, close the stream 133 PsimiTabReader reader = new PsimiTabReader(); 134 Collection<BinaryInteraction> interactions = reader.read(inputStream); 135 Tab2Xml tab2Xml = new Tab2Xml(); 136 EntrySet entrySet; 137 try { 138 entrySet = tab2Xml.convert(interactions); 139 } catch (IllegalAccessException e) { 140 throw new RuntimeException(e); 141 } catch (XmlConversionException e) { 142 throw new RuntimeException(e); 143 } 144 inputStream.close(); 145 146 // convert 147 convert(entrySet, outputStream, forceInteractionToComplex); 148 } 149 150 /** 151 * Converts the PSI interactions from the EntrySet and places into BioPAX output stream. 152 * Stream will be closed by the converter. 153 * 154 * @param entrySet PSI-MI entry set 155 * @param outputStream output stream for writing the BioPAX RDF/XML result 156 * @param forceInteractionToComplex true/false - whether to always generate Complex instead of MolecularInteraction 157 */ 158 public void convert(EntrySet entrySet, OutputStream outputStream, 159 boolean forceInteractionToComplex) { 160 161 // check args 162 if (entrySet == null || outputStream == null) { 163 throw new IllegalArgumentException("convert: one or more null arguments."); 164 } 165 if (entrySet.getLevel() != 2) { 166 throw new IllegalArgumentException("convert: only PSI-MI Level 2.5 is supported."); 167 } 168 169 //create a new empty BioPAX Model 170 final Model model = BioPAXLevel.L3.getDefaultFactory().createModel(); 171 model.setXmlBase(xmlBase); 172 173 // convert all psimi entries 174 EntryMapper entryMapper = new EntryMapper(model, forceInteractionToComplex); 175 for (Entry entry : entrySet.getEntries()) { 176 entryMapper.run(entry); 177 } 178 179 //try to release some RAM earlier 180 entrySet.getEntries().clear(); 181 entrySet = null; 182 183 // write BioPAX RDF/XML 184 (new SimpleIOHandler()).convertToOWL(model, outputStream); 185 } 186 187 /** 188 * @return the xml:base, a namespace for the converter-generated BioPAX objects' URIs. 189 */ 190 public String getXmlBase() { 191 return xmlBase; 192 } 193 194}