From a7e215c6f83cd33f9100673cd97d1a95b89922e1 Mon Sep 17 00:00:00 2001 From: langella <langella@b8ef2a07-7df7-436f-90b9-41648038564b> Date: Tue, 30 Apr 2013 14:23:34 +0000 Subject: [PATCH] 2 new jars added new output package to produce xtp output new peptide redundant output BEWARE : work in progress git-svn-id: https://subversion.renater.fr/xtandempipeline/trunk@366 b8ef2a07-7df7-436f-90b9-41648038564b --- xtandempipeline/.classpath | 2 + xtandempipeline/CMakeLists.txt | 2 + xtandempipeline/build_ubuntu.xml.cmake | 28 ++- xtandempipeline/lib/javacsv.jar | Bin 0 -> 13582 bytes xtandempipeline/lib/ods2csv.jar | Bin 0 -> 25063 bytes .../xtandempipeline.jnlp.cmake | 2 + .../print_peptide_list_to_phosphopeptide.java | 1 - .../print_protein_to_phosphopeptide.java | 1 - .../output/CsvRedundantPeptideOutput.java | 75 +++++++ .../output/IndentingXMLStreamWriter.java | 177 +++++++++++++++++ .../MassChroQmlOutput.java | 2 +- .../MassChroQmlWriter.java | 16 +- .../output/OdsRedundantPeptideOutput.java | 188 ++++++++++++++++++ .../ProticDbMlOutput.java | 2 +- .../ProticDbMlWriter.java | 74 +++---- .../sax_parse/IndentingXMLStreamWriter.java | 173 ---------------- .../xtandempipeline/thread/individual.java | 8 +- .../xtandempipeline/thread/printing_base.java | 45 +++-- .../thread/printing_combine.java | 27 +-- .../thread/printing_indiv.java | 23 ++- .../thread/printing_phosphopeptide.java | 26 +-- 21 files changed, 589 insertions(+), 283 deletions(-) create mode 100644 xtandempipeline/lib/javacsv.jar create mode 100644 xtandempipeline/lib/ods2csv.jar create mode 100644 xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/CsvRedundantPeptideOutput.java create mode 100644 xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/IndentingXMLStreamWriter.java rename xtandempipeline/src/fr/inra/pappso/xtandempipeline/{sax_parse => output}/MassChroQmlOutput.java (98%) rename xtandempipeline/src/fr/inra/pappso/xtandempipeline/{sax_parse => output}/MassChroQmlWriter.java (97%) create mode 100644 xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/OdsRedundantPeptideOutput.java rename xtandempipeline/src/fr/inra/pappso/xtandempipeline/{sax_parse => output}/ProticDbMlOutput.java (98%) rename xtandempipeline/src/fr/inra/pappso/xtandempipeline/{sax_parse => output}/ProticDbMlWriter.java (94%) delete mode 100644 xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/IndentingXMLStreamWriter.java diff --git a/xtandempipeline/.classpath b/xtandempipeline/.classpath index d012119fe..76d3be6e8 100644 --- a/xtandempipeline/.classpath +++ b/xtandempipeline/.classpath @@ -32,5 +32,7 @@ <classpathentry kind="lib" path="lib/swt/swt-gtk-linux-x86_64.jar"/> <classpathentry kind="lib" path="lib/cxf-common-utilities-2.2.4.jar"/> <classpathentry kind="lib" path="lib/mascotdatfile-3.3.jar"/> + <classpathentry kind="lib" path="lib/ods2csv.jar"/> + <classpathentry kind="lib" path="lib/javacsv.jar"/> <classpathentry kind="output" path="bin"/> </classpath> diff --git a/xtandempipeline/CMakeLists.txt b/xtandempipeline/CMakeLists.txt index fe77b9811..a8d7bbe4d 100644 --- a/xtandempipeline/CMakeLists.txt +++ b/xtandempipeline/CMakeLists.txt @@ -175,6 +175,8 @@ INSTALL(FILES ${CMAKE_BINARY_DIR}/share/xtandempipeline/XtandemPipeline.jar DEST INSTALL(FILES ${CMAKE_BINARY_DIR}/share/xtandempipeline/libproteomicsvg.jar DESTINATION share/xtandempipeline) INSTALL(FILES ${CMAKE_BINARY_DIR}/share/xtandempipeline/libodsstream.jar DESTINATION share/xtandempipeline) INSTALL(FILES ${CMAKE_BINARY_DIR}/share/xtandempipeline/${MASCOT_DAT_FILE_JAR} DESTINATION share/xtandempipeline) +INSTALL(FILES ${CMAKE_BINARY_DIR}/share/xtandempipeline/ods2csv.jar DESTINATION share/xtandempipeline) +INSTALL(FILES ${CMAKE_BINARY_DIR}/share/xtandempipeline/javacsv.jar DESTINATION share/xtandempipeline) INSTALL(FILES ${CMAKE_BINARY_DIR}/share/xtandempipeline/cxf-common-utilities-2.2.4.jar DESTINATION share/xtandempipeline) INSTALL(FILES ${CMAKE_BINARY_DIR}/share/xtandempipeline/PPClient.jar DESTINATION share/xtandempipeline) diff --git a/xtandempipeline/build_ubuntu.xml.cmake b/xtandempipeline/build_ubuntu.xml.cmake index e01bae61a..857e4dd79 100644 --- a/xtandempipeline/build_ubuntu.xml.cmake +++ b/xtandempipeline/build_ubuntu.xml.cmake @@ -19,6 +19,19 @@ <property name="confDir" location="src/conf/release" /> <property name="docDir" location="doc" /> + <target name="updateSharedLibraries"> + + <copy file="@CMAKE_SOURCE_DIR@/lib/javacsv.jar" tofile="${share}/xtandempipeline/javacsv.jar" overwrite="true" /> + <copy file="@CMAKE_SOURCE_DIR@/lib/ods2csv.jar" tofile="${share}/xtandempipeline/ods2csv.jar" overwrite="true" /> + <copy file="@CMAKE_SOURCE_DIR@/lib/libproteomicsvg.jar" tofile="${share}/xtandempipeline/libproteomicsvg.jar" overwrite="true" /> + <copy file="@CMAKE_SOURCE_DIR@/lib/libodsstream.jar" tofile="${share}/xtandempipeline/libodsstream.jar" overwrite="true" /> + <copy file="@CMAKE_SOURCE_DIR@/lib/PPClient.jar" tofile="${share}/xtandempipeline/PPClient.jar" overwrite="true" /> + <copy file="@CMAKE_SOURCE_DIR@/lib/mascotdatfile-3.3.jar" tofile="${share}/xtandempipeline/mascotdatfile-3.3.jar" overwrite="true" /> + <copy file="@CMAKE_SOURCE_DIR@/lib/cxf-common-utilities-2.2.4.jar" tofile="${share}/xtandempipeline/cxf-common-utilities-2.2.4.jar" overwrite="true" /> + + </target> + + <target name="reset"> <!-- reset the build and dist directory --> <delete dir="${build}" /> @@ -26,13 +39,6 @@ <mkdir dir="${build}" /> <mkdir dir="${dist}" /> <mkdir dir="${confDest}" /> - - - <copy file="@CMAKE_SOURCE_DIR@/lib/libproteomicsvg.jar" tofile="${share}/xtandempipeline/libproteomicsvg.jar" overwrite="true" /> - <copy file="@CMAKE_SOURCE_DIR@/lib/libodsstream.jar" tofile="${share}/xtandempipeline/libodsstream.jar" overwrite="true" /> - <copy file="@CMAKE_SOURCE_DIR@/lib/PPClient.jar" tofile="${share}/xtandempipeline/PPClient.jar" overwrite="true" /> - <copy file="@CMAKE_SOURCE_DIR@/lib/mascotdatfile-3.3.jar" tofile="${share}/xtandempipeline/mascotdatfile-3.3.jar" overwrite="true" /> - <copy file="@CMAKE_SOURCE_DIR@/lib/cxf-common-utilities-2.2.4.jar" tofile="${share}/xtandempipeline/cxf-common-utilities-2.2.4.jar" overwrite="true" /> </target> @@ -45,6 +51,8 @@ <path id="classpath"> <!--xml-apis-ext.jar xml-apis.jar xercesImpl.jar xalan2.jar swt.jar batik.jar liblog4j1.2-java --> <fileset dir="${sys.dir}" includes="commons-httpclient.jar commons-codec.jar commons-logging.jar log4j-1.2.jar xml-apis-ext.jar xml-apis.jar xercesImpl.jar xalan2.jar swt.jar batik.jar" /> + <fileset dir="${share.dest}/xtandempipeline" includes="javacsv.jar" /> + <fileset dir="${share.dest}/xtandempipeline" includes="ods2csv.jar" /> <fileset dir="${share.dest}/xtandempipeline" includes="libproteomicsvg.jar" /> <fileset dir="${share.dest}/xtandempipeline" includes="libodsstream.jar" /> <fileset dir="${share.dest}/xtandempipeline" includes="PPClient.jar" /> @@ -55,6 +63,8 @@ <target name="compile" depends="init" description="compile the source and put in build directory"> <!-- Compile the java code from ${src} into ${build} --> + <copy file="${share}/xtandempipeline/javacsv.jar" todir="${share.dest}/xtandempipeline" overwrite="true" /> + <copy file="${share}/xtandempipeline/ods2csv.jar" todir="${share.dest}/xtandempipeline" overwrite="true" /> <copy file="${share}/xtandempipeline/libproteomicsvg.jar" todir="${share.dest}/xtandempipeline" overwrite="true" /> <copy file="${share}/xtandempipeline/libodsstream.jar" todir="${share.dest}/xtandempipeline" overwrite="true" /> <copy file="${share}/xtandempipeline/PPClient.jar" todir="${share.dest}/xtandempipeline" overwrite="true" /> @@ -89,7 +99,7 @@ <!--<fileset file=".classpath" />--> <manifest> <attribute name="Main-Class" value="fr.inra.pappso.xtandempipeline.XtandemPipelineMain" /> - <attribute name="Class-Path" value="${sys.dir}/commons-httpclient.jar ${sys.dir}/commons-codec.jar ${sys.dir}/commons-logging.jar ${sys.dir}/log4j-1.2.jar ${sys.dir}/xml-apis-ext.jar ${sys.dir}/xml-apis.jar ${sys.dir}/xercesImpl.jar ${sys.dir}/xalan2.jar ${sys.dir}/swt.jar ${sys.dir}/batik.jar ${usr.dir}/share/xtandempipeline/libproteomicsvg.jar ${usr.dir}/share/xtandempipeline/libodsstream.jar ${usr.dir}/share/xtandempipeline/PPClient.jar ${usr.dir}/share/xtandempipeline/@MASCOT_DAT_FILE_JAR@ ${usr.dir}/share/xtandempipeline/cxf-common-utilities-2.2.4.jar" /> + <attribute name="Class-Path" value="${usr.dir}/share/xtandempipeline/ods2csv.jar ${usr.dir}/share/xtandempipeline/javacsv.jar ${sys.dir}/commons-httpclient.jar ${sys.dir}/commons-codec.jar ${sys.dir}/commons-logging.jar ${sys.dir}/log4j-1.2.jar ${sys.dir}/xml-apis-ext.jar ${sys.dir}/xml-apis.jar ${sys.dir}/xercesImpl.jar ${sys.dir}/xalan2.jar ${sys.dir}/swt.jar ${sys.dir}/batik.jar ${usr.dir}/share/xtandempipeline/libproteomicsvg.jar ${usr.dir}/share/xtandempipeline/libodsstream.jar ${usr.dir}/share/xtandempipeline/PPClient.jar ${usr.dir}/share/xtandempipeline/@MASCOT_DAT_FILE_JAR@ ${usr.dir}/share/xtandempipeline/cxf-common-utilities-2.2.4.jar" /> </manifest> </jar> @@ -104,6 +114,8 @@ </target> <target name="copyInShare" description="copies jar needed by the ubuntu package into the share directory"> + <copy file="@xtandempipeline_SOURCE_DIR@/lib/javacsv.jar" todir="${share}/xtandempipeline" overwrite="true" /> + <copy file="@xtandempipeline_SOURCE_DIR@/lib/ods2csv.jar" todir="${share}/xtandempipeline" overwrite="true" /> <copy file="@xtandempipeline_SOURCE_DIR@/lib/libproteomicsvg.jar" todir="${share}/xtandempipeline" overwrite="true" /> <copy file="@xtandempipeline_SOURCE_DIR@/lib/libodsstream.jar" todir="${share}/xtandempipeline" overwrite="true" /> <copy file="@xtandempipeline_SOURCE_DIR@/lib/PPClient.jar" todir="${share}/xtandempipeline" overwrite="true" /> diff --git a/xtandempipeline/lib/javacsv.jar b/xtandempipeline/lib/javacsv.jar new file mode 100644 index 0000000000000000000000000000000000000000..ceb59eb464c3b059ae28007e79994b4fbbb960b5 GIT binary patch literal 13582 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 literal 0 HcmV?d00001 diff --git a/xtandempipeline/lib/ods2csv.jar b/xtandempipeline/lib/ods2csv.jar new file mode 100644 index 0000000000000000000000000000000000000000..9fb0da05b12e721e72d0cf5ce9485fd14a06597a GIT binary patch literal 25063 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 literal 0 HcmV?d00001 diff --git a/xtandempipeline/share/xtandempipeline/xtandempipeline.jnlp.cmake b/xtandempipeline/share/xtandempipeline/xtandempipeline.jnlp.cmake index a8171ccac..fac932e25 100644 --- a/xtandempipeline/share/xtandempipeline/xtandempipeline.jnlp.cmake +++ b/xtandempipeline/share/xtandempipeline/xtandempipeline.jnlp.cmake @@ -61,6 +61,8 @@ <jar href="lib/libproteomicsvg.jar" main="false" download="eager" /> <jar href="lib/libodsstream.jar" main="false" download="eager" /> + <jar href="lib/javacsv.jar" main="false" download="eager" /> + <jar href="lib/ods2csv.jar" main="false" download="eager" /> </resources> <resources os="Windows" arch="x86"> diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/filter_print/print_peptide_list_to_phosphopeptide.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/filter_print/print_peptide_list_to_phosphopeptide.java index c23fe188e..da2433280 100644 --- a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/filter_print/print_peptide_list_to_phosphopeptide.java +++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/filter_print/print_peptide_list_to_phosphopeptide.java @@ -5,7 +5,6 @@ import java.util.Collection; import java.util.TreeSet; import fr.inra.pappso.xtandempipeline.class_msms.Match; -import fr.inra.pappso.xtandempipeline.class_msms.Modifs; import fr.inra.pappso.xtandempipeline.class_msms.MapDb.Peptide; import fr.inra.pappso.xtandempipeline.grouping.Group; import fr.inra.pappso.xtandempipeline.grouping.HashSampleScan; diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/filter_print/print_protein_to_phosphopeptide.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/filter_print/print_protein_to_phosphopeptide.java index eb8ed4be1..bb626d7ef 100644 --- a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/filter_print/print_protein_to_phosphopeptide.java +++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/filter_print/print_protein_to_phosphopeptide.java @@ -5,7 +5,6 @@ import fr.inra.pappso.xtandempipeline.grouping.Group; import fr.inra.pappso.xtandempipeline.grouping.HashSampleScanSetPhospho; import fr.inra.pappso.xtandempipeline.grouping.HashSampleScanSetProt; import fr.inra.pappso.xtandempipeline.grouping.SubGroup; -import fr.inra.pappso.xtandempipeline.grouping.interfaces.GrpProtMatch; import fr.inra.pappso.xtandempipeline.sax_parse.msms_output; public class print_protein_to_phosphopeptide extends print_base { diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/CsvRedundantPeptideOutput.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/CsvRedundantPeptideOutput.java new file mode 100644 index 000000000..4114ea64d --- /dev/null +++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/CsvRedundantPeptideOutput.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2012 Olivier Langella <Olivier.Langella@moulon.inra.fr>. + * + * This file is part of XTandemPipeline. + * + * XTandemPipeline is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * XTandemPipeline is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XTandemPipeline. If not, see <http://www.gnu.org/licenses/>. + * + * Contributors: + * Benoit Valot <Benoit.Valot@moulon.inra.fr> + * Olivier Langella <Olivier.Langella@moulon.inra.fr> + ******************************************************************************/ + +package fr.inra.pappso.xtandempipeline.output; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.stream.XMLStreamException; + +import org.apache.log4j.Logger; + +import fr.inra.pappso.csv2ods.Ods2Csv; +import fr.inra.pappso.libodsstream.OdsDocWriter; +import fr.inra.pappso.xtandempipeline.MsException.MSMSException; + +public class CsvRedundantPeptideOutput extends OdsRedundantPeptideOutput { + private static final Logger logger = Logger + .getLogger(CsvRedundantPeptideOutput.class); + private Ods2Csv ods2csv; + + public CsvRedundantPeptideOutput(OutputStream outputStream) + throws MSMSException { + try { + + PipedOutputStream pos = new PipedOutputStream(); + PipedInputStream pis = new PipedInputStream(pos); + + odsTable = new OdsDocWriter(pos); + + ods2csv = new Ods2Csv(); + ods2csv.setSourceInputStream(pis); + ods2csv.setSinkOutputStream(outputStream); + //ods2csv.setSeparator('\t'); + (new Thread(ods2csv)).start(); + //ods2csv.run(); + } catch (IOException e) { + String message = "IOException " + e.getMessage(); + logger.error(message); + throw new MSMSException(message); + } catch (XMLStreamException e) { + String message = "XMLStreamException " + e.getMessage(); + logger.error(message); + throw new MSMSException(message); + } catch (DatatypeConfigurationException e) { + String message = "DatatypeConfigurationException " + e.getMessage(); + logger.error(message); + throw new MSMSException(message); + } + } + +} diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/IndentingXMLStreamWriter.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/IndentingXMLStreamWriter.java new file mode 100644 index 000000000..2daea8d78 --- /dev/null +++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/IndentingXMLStreamWriter.java @@ -0,0 +1,177 @@ +package fr.inra.pappso.xtandempipeline.output; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.cxf.staxutils.DelegatingXMLStreamWriter; + +import java.util.Stack; + +/** + * @author Kohsuke Kawaguchi + */ +public class IndentingXMLStreamWriter extends DelegatingXMLStreamWriter { + private final static Object SEEN_NOTHING = new Object(); + private final static Object SEEN_ELEMENT = new Object(); + private final static Object SEEN_DATA = new Object(); + + private Object state = SEEN_NOTHING; + private Stack<Object> stateStack = new Stack<Object>(); + + private String indentStep = " "; + private int depth = 0; + + public IndentingXMLStreamWriter(XMLStreamWriter writer) { + super(writer); + } + + /** + * Return the current indent step. + * + * <p> + * Return the current indent step: each start tag will be indented by this + * number of spaces times the number of ancestors that the element has. + * </p> + * + * @return The number of spaces in each indentation step, or 0 or less for + * no indentation. + * @see #setIndentStep(int) + * + * @deprecated Only return the length of the indent string. + */ + public int getIndentStep() { + return indentStep.length(); + } + + /** + * Set the current indent step. + * + * @param indentStep + * The new indent step (0 or less for no indentation). + * @see #getIndentStep() + * + * @deprecated Should use the version that takes string. + */ + public void setIndentStep(int indentStep) { + StringBuilder s = new StringBuilder(); + for (; indentStep > 0; indentStep--) + s.append(' '); + setIndentStep(s.toString()); + } + + public void setIndentStep(String s) { + this.indentStep = s; + } + + private void onStartElement() throws XMLStreamException { + stateStack.push(SEEN_ELEMENT); + state = SEEN_NOTHING; + if (depth > 0) { + super.writeCharacters("\n"); + } + doIndent(); + depth++; + } + + private void onEndElement() throws XMLStreamException { + depth--; + if (state == SEEN_ELEMENT) { + super.writeCharacters("\n"); + doIndent(); + } + state = stateStack.pop(); + } + + private void onEmptyElement() throws XMLStreamException { + state = SEEN_ELEMENT; + if (depth > 0) { + super.writeCharacters("\n"); + } + doIndent(); + } + + /** + * Print indentation for the current level. + * + * @exception org.xml.sax.SAXException + * If there is an error writing the indentation characters, + * or if a filter further down the chain raises an exception. + */ + private void doIndent() throws XMLStreamException { + if (depth > 0) { + for (int i = 0; i < depth; i++) + super.writeCharacters(indentStep); + } + } + + public void writeStartDocument() throws XMLStreamException { + super.writeStartDocument(); + super.writeCharacters("\n"); + } + + public void writeStartDocument(String version) throws XMLStreamException { + super.writeStartDocument(version); + super.writeCharacters("\n"); + } + + public void writeStartDocument(String encoding, String version) + throws XMLStreamException { + super.writeStartDocument(encoding, version); + super.writeCharacters("\n"); + } + + public void writeStartElement(String localName) throws XMLStreamException { + onStartElement(); + super.writeStartElement(localName); + } + + public void writeStartElement(String namespaceURI, String localName) + throws XMLStreamException { + onStartElement(); + super.writeStartElement(namespaceURI, localName); + } + + public void writeStartElement(String prefix, String localName, + String namespaceURI) throws XMLStreamException { + onStartElement(); + super.writeStartElement(prefix, localName, namespaceURI); + } + + public void writeEmptyElement(String namespaceURI, String localName) + throws XMLStreamException { + onEmptyElement(); + super.writeEmptyElement(namespaceURI, localName); + } + + public void writeEmptyElement(String prefix, String localName, + String namespaceURI) throws XMLStreamException { + onEmptyElement(); + super.writeEmptyElement(prefix, localName, namespaceURI); + } + + public void writeEmptyElement(String localName) throws XMLStreamException { + onEmptyElement(); + super.writeEmptyElement(localName); + } + + public void writeEndElement() throws XMLStreamException { + onEndElement(); + super.writeEndElement(); + } + + public void writeCharacters(String text) throws XMLStreamException { + state = SEEN_DATA; + super.writeCharacters(text); + } + + public void writeCharacters(char[] text, int start, int len) + throws XMLStreamException { + state = SEEN_DATA; + super.writeCharacters(text, start, len); + } + + public void writeCData(String data) throws XMLStreamException { + state = SEEN_DATA; + super.writeCData(data); + } +} diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/MassChroQmlOutput.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/MassChroQmlOutput.java similarity index 98% rename from xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/MassChroQmlOutput.java rename to xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/MassChroQmlOutput.java index ccaae2d2f..7c3b038e1 100644 --- a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/MassChroQmlOutput.java +++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/MassChroQmlOutput.java @@ -21,7 +21,7 @@ * Olivier Langella <Olivier.Langella@moulon.inra.fr> ******************************************************************************/ -package fr.inra.pappso.xtandempipeline.sax_parse; +package fr.inra.pappso.xtandempipeline.output; import java.io.IOException; import java.io.OutputStream; diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/MassChroQmlWriter.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/MassChroQmlWriter.java similarity index 97% rename from xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/MassChroQmlWriter.java rename to xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/MassChroQmlWriter.java index aaa2a3f21..f20cfb84d 100644 --- a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/MassChroQmlWriter.java +++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/MassChroQmlWriter.java @@ -21,7 +21,7 @@ * Olivier Langella <Olivier.Langella@moulon.inra.fr> ******************************************************************************/ -package fr.inra.pappso.xtandempipeline.sax_parse; +package fr.inra.pappso.xtandempipeline.output; import java.util.ArrayList; import java.util.HashSet; @@ -294,7 +294,7 @@ public class MassChroQmlWriter { logger.debug("write begin"); try { writer.writeStartElement("rawdata"); - for (MsRun sample : ident.get_samples().getMsRunList()) { + for (MsRun sample : ident.getMsRunSet().getMsRunList()) { String id_samp = "samp" + this.sample2xmlId.size(); // ajout dans les hashtable sample2xmlId.put(sample, id_samp); @@ -328,7 +328,7 @@ public class MassChroQmlWriter { writer.writeEmptyElement("group"); writer.writeAttribute("id", this.groupe_id); String raw_list = ""; - for (MsRun sample : ident.get_samples().getMsRunList()) { + for (MsRun sample : ident.getMsRunSet().getMsRunList()) { raw_list = raw_list + " " + sample2xmlId.get(sample); } writer.writeAttribute("data_ids", raw_list.trim()); @@ -401,10 +401,10 @@ public class MassChroQmlWriter { Match top = (Match) sgList.get(0) .getHashSampleScanSetProtList().get(0) .getGrpProtMatch(); - Peptide pep = (Peptide) top.getBestPeptideToHashSampleScan(hash); + Peptide pep = (Peptide) top + .getBestPeptideToHashSampleScan(hash); - String seqMod = pep - .get_LI_sequenceModifsWithoutMs3(); + String seqMod = pep.get_LI_sequenceModifsWithoutMs3(); if (seqMod2protIds.containsKey(seqMod)) { } else { // Add new peptide id @@ -419,8 +419,8 @@ public class MassChroQmlWriter { HashSet<String> temp = new HashSet<String>(); seqMod2protIds.put(seqMod, temp); - seqMod2PeptideList.put(seqMod, - new ArrayList<Peptide>()); + seqMod2PeptideList + .put(seqMod, new ArrayList<Peptide>()); } seqMod2PeptideList.get(seqMod).add(pep); diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/OdsRedundantPeptideOutput.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/OdsRedundantPeptideOutput.java new file mode 100644 index 000000000..e9d41ba65 --- /dev/null +++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/OdsRedundantPeptideOutput.java @@ -0,0 +1,188 @@ +/******************************************************************************* + * Copyright (c) 2012 Olivier Langella <Olivier.Langella@moulon.inra.fr>. + * + * This file is part of XTandemPipeline. + * + * XTandemPipeline is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * XTandemPipeline is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XTandemPipeline. If not, see <http://www.gnu.org/licenses/>. + * + * Contributors: + * Benoit Valot <Benoit.Valot@moulon.inra.fr> + * Olivier Langella <Olivier.Langella@moulon.inra.fr> + ******************************************************************************/ + +package fr.inra.pappso.xtandempipeline.output; + +import java.io.IOException; +import java.io.OutputStream; + +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.stream.XMLStreamException; + +import org.apache.log4j.Logger; + +import fr.inra.pappso.libodsstream.OdsDocWriter; +import fr.inra.pappso.xtandempipeline.MsException.MSMSException; +import fr.inra.pappso.xtandempipeline.class_msms.Identification; +import fr.inra.pappso.xtandempipeline.class_msms.Match; +import fr.inra.pappso.xtandempipeline.class_msms.Protein; +import fr.inra.pappso.xtandempipeline.class_msms.MapDb.Peptide; +import fr.inra.pappso.xtandempipeline.grouping.Group; +import fr.inra.pappso.xtandempipeline.grouping.HashSampleScanSetProt; +import fr.inra.pappso.xtandempipeline.grouping.SubGroup; + +public class OdsRedundantPeptideOutput { + private static final Logger logger = Logger + .getLogger(OdsRedundantPeptideOutput.class); + + protected OdsDocWriter odsTable; + + protected OdsRedundantPeptideOutput() { + + } + + public OdsRedundantPeptideOutput(OutputStream outputStream) + throws MSMSException { + try { + odsTable = new OdsDocWriter(outputStream); + } catch (IOException e) { + String message = "IOException " + e.getMessage(); + logger.error(message); + throw new MSMSException(message); + } catch (XMLStreamException e) { + String message = "XMLStreamException " + e.getMessage(); + logger.error(message); + throw new MSMSException(message); + } catch (DatatypeConfigurationException e) { + String message = "DatatypeConfigurationException " + e.getMessage(); + logger.error(message); + throw new MSMSException(message); + } + } + + public void close() throws MSMSException { + try { + odsTable.close(); + } catch (Exception e) { + String message = "Exception closing OdsRedundantPeptideOutput " + + e.getMessage(); + logger.error(message); + throw new MSMSException(message); + } + } + + public void write(Identification ident) throws MSMSException { + try { + odsTable.writeSheet("peptides"); + + this.writeHeaders(); + for (Group group : ident.getGrouping().getGroupList()) { + for (SubGroup sg : group.getSubGroupSet().getSubGroupList()) { + + for (HashSampleScanSetProt hashProt : sg + .getHashSampleScanSetProtList()) { + Protein prot = (Protein) hashProt.getGrpProtMatch() + .getGrpProtein(); + // peptidesHitRef + for (Peptide peptide : ((Match) hashProt + .getGrpProtMatch()) + .get_peptide_order_inclus_redon()) { + + this.writeOnePeptide(group, sg, prot, peptide); + } + } + } + } + odsTable.writeLine(); + odsTable.writeLine(); + + } catch (XMLStreamException e) { + String message = "XMLStreamException in write(Identification ident) " + + e.getMessage(); + logger.error(message); + throw new MSMSException(message); + } + } + + private void writeHeaders() throws MSMSException { + try { + odsTable.writeLine(); + odsTable.writeCell("Group"); + odsTable.writeCell("Subgroup"); + odsTable.writeCell("Protein accession"); + odsTable.writeCell("Protein description"); + odsTable.writeCell("MS Sample"); + odsTable.writeCell("Scan"); + odsTable.writeCell("Rt (s)"); + odsTable.writeCell("Sequence"); + odsTable.writeCell("Modifs"); + odsTable.writeCell("Start"); + odsTable.writeCell("Stop"); + + odsTable.writeCell("E-value"); + odsTable.writeCell("Charge"); + odsTable.writeCell("MH+ Obs"); + odsTable.writeCell("MH+ theo"); + odsTable.writeCell("DeltaMH+"); + odsTable.writeCell("Delta-ppm"); + } catch (XMLStreamException e) { + String message = "XMLStreamException in writeHeaders() " + + e.getMessage(); + logger.error(message); + throw new MSMSException(message); + } + + } + + private void writeOnePeptide(Group group, SubGroup sg, Protein prot, + Peptide peptide) throws MSMSException { + try { + odsTable.writeLine(); + odsTable.writeCell(group.getNumber()); + odsTable.writeCell(sg.getNumber()); + odsTable.writeCell(prot.getAccession()); + odsTable.writeCell(prot.get_description()); + odsTable.writeCell(peptide.get_sample()); + odsTable.writeCell(peptide.getSampleScan().getScan()); + odsTable.writeCell(peptide.get_RT_in_sec()); + odsTable.writeCell(peptide.getSequence()); + odsTable.writeCell(peptide.get_Modifs_formater()); + odsTable.writeCell(peptide.get_start()); + odsTable.writeCell(peptide.get_stop()); + + odsTable.writeCell(peptide.get_evalue()); + // S.append("\t" + pep.get_evalue()); + odsTable.writeCell(peptide.get_charge()); + // S.append("\t" + pep.get_charge()); + odsTable.writeCell(peptide.get_mhplus_obser()); + // S.append("\t" + pep.get_mhplus_obser()); + odsTable.writeCell(peptide.get_mhplus_theo()); + // S.append("\t" + pep.get_mhplus_theo()); + odsTable.writeCell(peptide.get_deltamass()); + // S.append("\t" + pep.get_deltamass()); + odsTable.writeCell(((peptide.get_deltamass() / peptide + .get_mhplus_theo()) * 1000000)); + + } catch (XMLStreamException e) { + String message = "XMLStreamException in writeOnePeptide(Group group, SubGroup sg, Protein prot, Peptide peptide) " + + e.getMessage(); + logger.error(message); + throw new MSMSException(message); + } catch (Exception e) { + String message = "Exception in writeOnePeptide(Protein prot, Peptide peptide) " + + e.getMessage(); + logger.error(message); + throw new MSMSException(message); + } + } +} diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/ProticDbMlOutput.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/ProticDbMlOutput.java similarity index 98% rename from xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/ProticDbMlOutput.java rename to xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/ProticDbMlOutput.java index ae9c3d998..e63e3e22d 100644 --- a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/ProticDbMlOutput.java +++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/ProticDbMlOutput.java @@ -21,7 +21,7 @@ * Olivier Langella <Olivier.Langella@moulon.inra.fr> ******************************************************************************/ -package fr.inra.pappso.xtandempipeline.sax_parse; +package fr.inra.pappso.xtandempipeline.output; import java.io.IOException; import java.io.OutputStream; diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/ProticDbMlWriter.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/ProticDbMlWriter.java similarity index 94% rename from xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/ProticDbMlWriter.java rename to xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/ProticDbMlWriter.java index 72db150ca..51a1109b5 100644 --- a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/ProticDbMlWriter.java +++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/output/ProticDbMlWriter.java @@ -21,7 +21,7 @@ * Olivier Langella <Olivier.Langella@moulon.inra.fr> ******************************************************************************/ -package fr.inra.pappso.xtandempipeline.sax_parse; +package fr.inra.pappso.xtandempipeline.output; import java.util.ArrayList; import java.util.Hashtable; @@ -285,7 +285,8 @@ public class ProticDbMlWriter { writer.writeAttribute("display_id", prot .get_description().substring(0, 59)); } else { - writer.writeAttribute("display_id", + writer.writeAttribute( + "display_id", prot.get_description() .substring( 0, @@ -296,10 +297,10 @@ public class ProticDbMlWriter { // dbname="AGI_LocusCode"></dbxref> if (prot.get_dbxref_type().equals("no") == false) { writer.writeStartElement("dbxref"); - writer.writeAttribute("key", prot - .get_dbxref_accession()); - writer.writeAttribute("dbname", prot - .get_dbxref_type()); + writer.writeAttribute("key", + prot.get_dbxref_accession()); + writer.writeAttribute("dbname", + prot.get_dbxref_type()); writer.writeEndElement();// dbxref } writer.writeStartElement("description"); @@ -403,9 +404,8 @@ public class ProticDbMlWriter { writer.writeAttribute("value", "" + XtandemPipelineSession.getInstance().getConfig() .get_peptide_number()); - writer - .writeAttribute("name", - "X!TandemPipeline filter on minimal number of peptide per protein"); + writer.writeAttribute("name", + "X!TandemPipeline filter on minimal number of peptide per protein"); writer.writeAttribute("cvLabel", "PROTICdbO"); writer.writeAttribute("accession", "PROTICdbO:0000325"); writer.writeEndElement();// cvParam @@ -435,19 +435,15 @@ public class ProticDbMlWriter { String pep_hit_id = "pep" + pep_to_id.size(); // param par default writer.writeStartElement("peptideHit"); - writer - .writeAttribute("calc_mr", "" - + (pep.get_mhplus_theo() - 1.00794)); + writer.writeAttribute("calc_mr", "" + (pep.get_mhplus_theo() - 1.00794)); double exp_mz = (pep.get_mhplus_obser() + (1.00794 * (pep.get_charge() - 1))) / pep.get_charge(); writer.writeAttribute("exp_mz", "" + exp_mz); writer.writeAttribute("delta", "" + pep.get_deltamass()); - writer - .writeAttribute("exp_mr", "" - + (pep.get_mhplus_obser() - 1.00794)); + writer.writeAttribute("exp_mr", "" + (pep.get_mhplus_obser() - 1.00794)); writer.writeAttribute("acq_number", "" + pep.get_scan()); - writer.writeAttribute("ms_run_id", "" - + msrun_to_id.get(pep.get_sample())); + writer.writeAttribute("ms_run_id", + "" + msrun_to_id.get(pep.get_sample())); writer.writeAttribute("id", pep_hit_id); writer.writeAttribute("exp_z", "" + pep.get_charge()); @@ -612,9 +608,11 @@ public class ProticDbMlWriter { for (MsRun sample : match.get_sample_matchs()) { if (!view.containsKey(sample.getSampleName())) { writer.writeStartElement("matchSample"); - writer.writeAttribute("sample_id", "" - + sample_to_id.get(sample - .getSampleName())); + writer.writeAttribute( + "sample_id", + "" + + sample_to_id.get(sample + .getSampleName())); String name = sample.getSampleName(); name = name.replaceAll(".xml", ""); writer.writeAttribute("name", "" + name); @@ -631,8 +629,8 @@ public class ProticDbMlWriter { writer.writeStartElement("proteinHit"); Protein prot = (Protein) hashProt.getGrpProtMatch() .getGrpProtein(); - writer.writeAttribute("sequence_id", "" - + prot_to_id.get(prot.get_description())); + writer.writeAttribute("sequence_id", + "" + prot_to_id.get(prot.get_description())); // proteinHit.setAttribute("score", ""); writer.writeAttribute("rank", "" + k); @@ -660,9 +658,12 @@ public class ProticDbMlWriter { if (samples.size() == 1) { writer.writeStartElement("cvParam"); - writer.writeAttribute("value", "" - + ((Match) hashProt.getGrpProtMatch()) - .get_coverage()); + writer.writeAttribute( + "value", + "" + + ((Match) hashProt + .getGrpProtMatch()) + .get_coverage()); writer.writeAttribute("name", "Coverage determination by Benuch"); writer.writeAttribute("cvLabel", "PROTICdbO"); @@ -681,20 +682,19 @@ public class ProticDbMlWriter { for (Peptide pep : ((Match) hashProt.getGrpProtMatch()) .get_peptide_order_inclus_redon()) { writer.writeStartElement("peptideHitRef"); - writer - .writeAttribute( - "peptide_hit_id", - "" - + pep_to_id - .get(pep - .get_sample_scan_sequencepeptide_cle())); + writer.writeAttribute( + "peptide_hit_id", + "" + + pep_to_id.get(pep + .get_sample_scan_sequencepeptide_cle())); writer.writeStartElement("fromSeq"); - writer.writeAttribute("seq_id", "" - + prot_to_id.get(prot2.get_description())); - writer - .writeAttribute("start", "" - + pep.get_start()); + writer.writeAttribute( + "seq_id", + "" + + prot_to_id.get(prot2 + .get_description())); + writer.writeAttribute("start", "" + pep.get_start()); writer.writeAttribute("stop", "" + pep.get_stop()); String res1 = pep.get_pre(); res1 = res1.replaceAll("]", "-"); diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/IndentingXMLStreamWriter.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/IndentingXMLStreamWriter.java deleted file mode 100644 index e0e30ec9e..000000000 --- a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/sax_parse/IndentingXMLStreamWriter.java +++ /dev/null @@ -1,173 +0,0 @@ -package fr.inra.pappso.xtandempipeline.sax_parse; - -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamWriter; - -import org.apache.cxf.staxutils.DelegatingXMLStreamWriter; - -import java.util.Stack; - -/** - * @author Kohsuke Kawaguchi - */ -public class IndentingXMLStreamWriter extends DelegatingXMLStreamWriter { - private final static Object SEEN_NOTHING = new Object(); - private final static Object SEEN_ELEMENT = new Object(); - private final static Object SEEN_DATA = new Object(); - - private Object state = SEEN_NOTHING; - private Stack<Object> stateStack = new Stack<Object>(); - - private String indentStep = " "; - private int depth = 0; - - public IndentingXMLStreamWriter(XMLStreamWriter writer) { - super(writer); - } - - /** - * Return the current indent step. - * - * <p>Return the current indent step: each start tag will be - * indented by this number of spaces times the number of - * ancestors that the element has.</p> - * - * @return The number of spaces in each indentation step, - * or 0 or less for no indentation. - * @see #setIndentStep(int) - * - * @deprecated - * Only return the length of the indent string. - */ - public int getIndentStep() { - return indentStep.length(); - } - - - /** - * Set the current indent step. - * - * @param indentStep The new indent step (0 or less for no - * indentation). - * @see #getIndentStep() - * - * @deprecated - * Should use the version that takes string. - */ - public void setIndentStep(int indentStep) { - StringBuilder s = new StringBuilder(); - for (; indentStep > 0; indentStep--) s.append(' '); - setIndentStep(s.toString()); - } - - public void setIndentStep(String s) { - this.indentStep = s; - } - - private void onStartElement() throws XMLStreamException { - stateStack.push(SEEN_ELEMENT); - state = SEEN_NOTHING; - if (depth > 0) { - super.writeCharacters("\n"); - } - doIndent(); - depth++; - } - - private void onEndElement() throws XMLStreamException { - depth--; - if (state == SEEN_ELEMENT) { - super.writeCharacters("\n"); - doIndent(); - } - state = stateStack.pop(); - } - - private void onEmptyElement() throws XMLStreamException { - state = SEEN_ELEMENT; - if (depth > 0) { - super.writeCharacters("\n"); - } - doIndent(); - } - - /** - * Print indentation for the current level. - * - * @exception org.xml.sax.SAXException If there is an error - * writing the indentation characters, or if a filter - * further down the chain raises an exception. - */ - private void doIndent() throws XMLStreamException { - if (depth > 0) { - for (int i = 0; i < depth; i++) - super.writeCharacters(indentStep); - } - } - - - public void writeStartDocument() throws XMLStreamException { - super.writeStartDocument(); - super.writeCharacters("\n"); - } - - public void writeStartDocument(String version) throws XMLStreamException { - super.writeStartDocument(version); - super.writeCharacters("\n"); - } - - public void writeStartDocument(String encoding, String version) throws XMLStreamException { - super.writeStartDocument(encoding, version); - super.writeCharacters("\n"); - } - - public void writeStartElement(String localName) throws XMLStreamException { - onStartElement(); - super.writeStartElement(localName); - } - - public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException { - onStartElement(); - super.writeStartElement(namespaceURI, localName); - } - - public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException { - onStartElement(); - super.writeStartElement(prefix, localName, namespaceURI); - } - - public void writeEmptyElement(String namespaceURI, String localName) throws XMLStreamException { - onEmptyElement(); - super.writeEmptyElement(namespaceURI, localName); - } - - public void writeEmptyElement(String prefix, String localName, String namespaceURI) throws XMLStreamException { - onEmptyElement(); - super.writeEmptyElement(prefix, localName, namespaceURI); - } - - public void writeEmptyElement(String localName) throws XMLStreamException { - onEmptyElement(); - super.writeEmptyElement(localName); - } - - public void writeEndElement() throws XMLStreamException { - onEndElement(); - super.writeEndElement(); - } - - public void writeCharacters(String text) throws XMLStreamException { - state = SEEN_DATA; - super.writeCharacters(text); - } - - public void writeCharacters(char[] text, int start, int len) throws XMLStreamException { - state = SEEN_DATA; - super.writeCharacters(text, start, len); - } - - public void writeCData(String data) throws XMLStreamException { - state = SEEN_DATA; - super.writeCData(data); - } -} diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/individual.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/individual.java index e87f0c4d8..53df785da 100644 --- a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/individual.java +++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/individual.java @@ -4,7 +4,6 @@ import java.util.ArrayList; import java.util.Vector; import fr.inra.pappso.xtandempipeline.XtandemPipelineSession; -import fr.inra.pappso.xtandempipeline.MsException.MSMSException; import fr.inra.pappso.xtandempipeline.MsException.StopException; import fr.inra.pappso.xtandempipeline.class_msms.MsRun; import fr.inra.pappso.xtandempipeline.class_msms.MsRunSet; @@ -46,7 +45,7 @@ public class individual extends process { // Is sample exist? Get previous identification Identification identtemp = null; for (int m = 0; m < identifications.size(); m++) { - logger.debug("identifications.size() "+identifications.size()); + logger.debug("identifications.size() " + identifications.size()); MsRunSet samples = identifications.get(m).getMsRunSet(); for (MsRun sample : samples) { logger.debug("msRun name : " + sample.getSampleName()); @@ -67,7 +66,8 @@ public class individual extends process { // identifications.add(handler.get_identifications()); // Load identification from datasource - identifications.add(dataSourceToParse.loadIdentification(identtemp)); + identifications + .add(dataSourceToParse.loadIdentification(identtemp)); // verification pas arreté if (this.isStop()) @@ -81,7 +81,7 @@ public class individual extends process { // filtering this.set_view("Analysing file : " + (j + 1) + "/" + identifications.size() + "\n" + "Filtering file : " - + ident.get_samples().getMsRunList().get(0).getSampleName()); + + ident.getMsRunSet().getMsRunList().get(0).getSampleName()); // on mets à jour les liens ident.filtered_match(new filter_index_and_order_match_scan()); diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_base.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_base.java index 05ab57d13..907552a86 100644 --- a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_base.java +++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_base.java @@ -17,8 +17,10 @@ import fr.inra.pappso.xtandempipeline.filter_print.calculation_protein_fdr_distr import fr.inra.pappso.xtandempipeline.filter_print.filter_isotopic_modifs; import fr.inra.pappso.xtandempipeline.filter_print.print_fasta; import fr.inra.pappso.xtandempipeline.filter_print.print_pepnovo; -import fr.inra.pappso.xtandempipeline.sax_parse.MassChroQmlOutput; -import fr.inra.pappso.xtandempipeline.sax_parse.ProticDbMlOutput; +import fr.inra.pappso.xtandempipeline.output.CsvRedundantPeptideOutput; +import fr.inra.pappso.xtandempipeline.output.MassChroQmlOutput; +import fr.inra.pappso.xtandempipeline.output.OdsRedundantPeptideOutput; +import fr.inra.pappso.xtandempipeline.output.ProticDbMlOutput; import fr.inra.pappso.xtandempipeline.sax_parse.msms_output; public class printing_base extends process { @@ -54,8 +56,7 @@ public class printing_base extends process { this.set_view("Printing Open Document Spreadsheet file results"); OdsDocWriter doc = this.ods_specific_printing(this.getfileout() - .getAbsolutePath() - + ".ods"); + .getAbsolutePath() + ".ods"); doc.close(); } @@ -64,8 +65,7 @@ public class printing_base extends process { this.set_view("Printing PROTICdbML file results"); FileOutputStream outputStream = new FileOutputStream(new File(this - .getfileout().getAbsolutePath() - + "_protic.xml")); + .getfileout().getAbsolutePath() + "_protic.xml")); ProticDbMlOutput protidDbMlOutput = new ProticDbMlOutput(); protidDbMlOutput.open(outputStream); @@ -109,7 +109,7 @@ public class printing_base extends process { + "<tandem_to_pepnovo>" + "\n"); for (Identification ident : this.identifications) { ident.print_result(new print_pepnovo(output, ident - .get_samples())); + .getMsRunSet())); } output.write("</tandem_to_pepnovo>" + "\n"); output.close(); @@ -146,19 +146,38 @@ public class printing_base extends process { this.set_view("Printing MassChroQ xml file results"); Identification ident = this.identifications.get(0); // modification isotopic - ident - .filtered_match(new filter_isotopic_modifs( - this.isotopic_mods)); + ident.filtered_match(new filter_isotopic_modifs(this.isotopic_mods)); MassChroQmlOutput massChroQmlOutput = new MassChroQmlOutput( this.isotopic_mods, ident); FileOutputStream outputStream = new FileOutputStream(new File(this - .getfileout().getAbsolutePath() - + ".masschroqML")); - ; + .getfileout().getAbsolutePath() + ".masschroqML")); + massChroQmlOutput.write(outputStream); } + // redundant peptide output (containing start and stop positions on + // proteins) + if (true) { + FileOutputStream outputStream = new FileOutputStream(new File(this + .getfileout().getAbsolutePath() + "_pep_redundant.ods")); + OdsRedundantPeptideOutput odsRedOutput = new OdsRedundantPeptideOutput( + outputStream); + for (Identification ident : this.identifications) { + odsRedOutput.write(ident); + } + odsRedOutput.close(); + + FileOutputStream csvStream = new FileOutputStream(new File(this + .getfileout().getAbsolutePath() + "_pep_redundant.csv")); + CsvRedundantPeptideOutput csvRedOutput = new CsvRedundantPeptideOutput( + csvStream); + for (Identification ident : this.identifications) { + csvRedOutput.write(ident); + } + csvRedOutput.close(); + } + if (this.isStop()) throw new StopException(""); this.add_current_progress(); diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_combine.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_combine.java index b1f4f14e7..9ae88a6e0 100644 --- a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_combine.java +++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_combine.java @@ -18,21 +18,22 @@ public class printing_combine extends printing_base { super(conf); } - protected OdsDocWriter ods_specific_printing(String filename) throws Exception { + protected OdsDocWriter ods_specific_printing(String filename) + throws Exception { logger.info("Print combine results in ODS"); OdsDocWriter odsDoc = new OdsDocWriter(filename); this.set_view("Printing protein file results"); - + odsDoc.writeSheet("proteins"); - //msms_output output = new msms_output(); - //output.open(this.getfileout().getAbsolutePath() + "_protein.txt"); + // msms_output output = new msms_output(); + // output.open(this.getfileout().getAbsolutePath() + "_protein.txt"); // protein view for (Identification ident : this.identifications) { ident.print_result(new print_ods_protein_to_combined(odsDoc)); } - //output.close(); + // output.close(); // Verification pas arrete if (this.isStop()) @@ -41,13 +42,13 @@ public class printing_combine extends printing_base { this.set_view("Printing peptide file results"); odsDoc.writeSheet("peptides"); - //output.open(this.getfileout().getAbsolutePath() + "_peptide.txt"); + // output.open(this.getfileout().getAbsolutePath() + "_peptide.txt"); // peptide list for (Identification ident : this.identifications) { ident.print_result(new print_ods_peptide_list(odsDoc)); } - //output.close(); + // output.close(); // Verification pas arrete if (this.isStop()) @@ -55,17 +56,17 @@ public class printing_combine extends printing_base { this.add_current_progress(); this.set_view("Printing compar file results"); - //odsDoc.writeSheet("compar"); - //output.open(this.getfileout().getAbsolutePath() + "_compar.txt"); + // odsDoc.writeSheet("compar"); + // output.open(this.getfileout().getAbsolutePath() + "_compar.txt"); for (Identification ident : this.identifications) { - ident.print_result(new print_ods_compar(odsDoc, ident.get_samples())); + ident.print_result(new print_ods_compar(odsDoc, ident.getMsRunSet())); } - //output.close(); + // output.close(); this.add_current_progress(); return odsDoc; } - + protected void specific_printing() throws Exception { logger.info("Print combine results"); @@ -101,7 +102,7 @@ public class printing_combine extends printing_base { this.set_view("Printing compar file results"); output.open(this.getfileout().getAbsolutePath() + "_compar.txt"); for (Identification ident : this.identifications) { - ident.print_result(new print_compar(output, ident.get_samples())); + ident.print_result(new print_compar(output, ident.getMsRunSet())); } output.close(); diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_indiv.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_indiv.java index 448e899c6..259aabc2b 100644 --- a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_indiv.java +++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_indiv.java @@ -1,6 +1,5 @@ package fr.inra.pappso.xtandempipeline.thread; - import fr.inra.pappso.libodsstream.OdsDocWriter; import fr.inra.pappso.xtandempipeline.MsException.StopException; import fr.inra.pappso.xtandempipeline.class_msms.config; @@ -11,23 +10,24 @@ import fr.inra.pappso.xtandempipeline.filter_print.print_peptide_list; import fr.inra.pappso.xtandempipeline.filter_print.print_protein_to_indiv; import fr.inra.pappso.xtandempipeline.sax_parse.msms_output; - public class printing_indiv extends printing_base { public printing_indiv(config conf) { super(conf); } - - protected OdsDocWriter ods_specific_printing(String filename) throws Exception { + + protected OdsDocWriter ods_specific_printing(String filename) + throws Exception { logger.info("Print individual results in ODS"); OdsDocWriter odsDoc = new OdsDocWriter(filename); - + this.set_view("Printing protein file results"); - + odsDoc.writeSheet("proteins"); // protein view for (Identification ident : this.identifications) { - ident.print_result(new print_ods_protein_to_indiv(odsDoc, ident.get_samples())); + ident.print_result(new print_ods_protein_to_indiv(odsDoc, ident + .getMsRunSet())); } // Verification pas arrete @@ -46,19 +46,20 @@ public class printing_indiv extends printing_base { if (this.isStop()) throw new StopException(""); this.add_current_progress(); - + return odsDoc; } - protected void specific_printing () throws Exception { + protected void specific_printing() throws Exception { logger.info("Print individual results"); - + this.set_view("Printing protein file results"); msms_output output = new msms_output(); output.open(this.getfileout().getAbsolutePath() + "_protein.txt"); // protein view for (Identification ident : this.identifications) { - ident.print_result(new print_protein_to_indiv(output, ident.get_samples())); + ident.print_result(new print_protein_to_indiv(output, ident + .getMsRunSet())); } output.close(); diff --git a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_phosphopeptide.java b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_phosphopeptide.java index ef274d832..cbae3ca8f 100644 --- a/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_phosphopeptide.java +++ b/xtandempipeline/src/fr/inra/pappso/xtandempipeline/thread/printing_phosphopeptide.java @@ -18,20 +18,21 @@ public class printing_phosphopeptide extends printing_base { super(conf); } - protected OdsDocWriter ods_specific_printing(String filename) throws Exception { + protected OdsDocWriter ods_specific_printing(String filename) + throws Exception { OdsDocWriter odsDoc = new OdsDocWriter(filename); logger.info("Print phophopeptide results ODS"); this.set_view("Printing protein file results"); odsDoc.writeSheet("proteins"); - //msms_output output = new msms_output(); - //output.open(this.getfileout().getAbsolutePath() + "_protein.txt"); + // msms_output output = new msms_output(); + // output.open(this.getfileout().getAbsolutePath() + "_protein.txt"); // protein view for (Identification ident : this.identifications) { ident.print_result(new print_ods_protein_to_phosphopeptide(odsDoc)); } - //output.close(); + // output.close(); // Verification pas arrete if (this.isStop()) @@ -39,14 +40,15 @@ public class printing_phosphopeptide extends printing_base { this.add_current_progress(); this.set_view("Printing peptide file results"); - //output.open(this.getfileout().getAbsolutePath() + "_peptide.txt"); + // output.open(this.getfileout().getAbsolutePath() + "_peptide.txt"); odsDoc.writeSheet("peptides"); // peptide list for (Identification ident : this.identifications) { - ident.print_result(new print_ods_peptide_list_to_phosphopeptide(odsDoc)); + ident.print_result(new print_ods_peptide_list_to_phosphopeptide( + odsDoc)); } - //output.close(); + // output.close(); // Verification pas arrete if (this.isStop()) @@ -54,13 +56,13 @@ public class printing_phosphopeptide extends printing_base { this.add_current_progress(); this.set_view("Printing compar file results"); - //odsDoc.writeSheet("compar"); - //output.open(this.getfileout().getAbsolutePath() + "_compar.txt"); + // odsDoc.writeSheet("compar"); + // output.open(this.getfileout().getAbsolutePath() + "_compar.txt"); for (Identification ident : this.identifications) { ident.print_result(new print_ods_compar_phospho(odsDoc, ident - .get_samples())); + .getMsRunSet())); } - //output.close(); + // output.close(); this.add_current_progress(); return odsDoc; @@ -101,7 +103,7 @@ public class printing_phosphopeptide extends printing_base { output.open(this.getfileout().getAbsolutePath() + "_compar.txt"); for (Identification ident : this.identifications) { ident.print_result(new print_compar_phospho(output, ident - .get_samples())); + .getMsRunSet())); } output.close(); -- GitLab