Adding AAConWS
[jabaws.git] / datamodel / compbio / data / sequence / SequenceUtil.java
index 99a8147..149e0e0 100644 (file)
@@ -1,22 +1,15 @@
-/* \r
- * @(#)SequenceUtil.java 1.0 September 2009\r
- * \r
- * Copyright (c) 2009 Peter Troshin\r
- *  \r
- * Jalview Web Services version: 2.0     \r
- * \r
- *  This library is free software; you can redistribute it and/or modify it under the terms of the\r
- *  Apache License version 2 as published by the Apache Software Foundation\r
- * \r
- *  This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\r
- *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Apache \r
- *  License for more details.\r
- * \r
- *  A copy of the license is in apache_license.txt. It is also available here:\r
- * see: http://www.apache.org/licenses/LICENSE-2.0.txt\r
- * \r
- * Any republication or derived work distributed in source code form\r
- * must include this copyright and license notice.\r
+/*\r
+ * @(#)SequenceUtil.java 1.0 September 2009 Copyright (c) 2009 Peter Troshin\r
+ * Jalview Web Services version: 2.0 This library is free software; you can\r
+ * redistribute it and/or modify it under the terms of the Apache License\r
+ * version 2 as published by the Apache Software Foundation This library is\r
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\r
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A\r
+ * PARTICULAR PURPOSE. See the Apache License for more details. A copy of the\r
+ * license is in apache_license.txt. It is also available here: see:\r
+ * http://www.apache.org/licenses/LICENSE-2.0.txt Any republication or derived\r
+ * work distributed in source code form must include this copyright and license\r
+ * notice.\r
  */\r
 \r
 package compbio.data.sequence;\r
@@ -33,6 +26,7 @@ import java.io.OutputStream;
 import java.io.OutputStreamWriter;\r
 import java.util.ArrayList;\r
 import java.util.List;\r
+import java.util.Scanner;\r
 import java.util.logging.Level;\r
 import java.util.regex.Matcher;\r
 import java.util.regex.Pattern;\r
@@ -45,362 +39,415 @@ import java.util.regex.Pattern;
  */\r
 public final class SequenceUtil {\r
 \r
-    /**\r
-     * A whitespace character: [\t\n\x0B\f\r]\r
-     */\r
-    public static final Pattern WHITE_SPACE = Pattern.compile("\\s");\r
-\r
-    /**\r
-     * A digit\r
-     */\r
-    public static final Pattern DIGIT = Pattern.compile("\\d");\r
-\r
-    /**\r
-     * Non word\r
-     */\r
-    public static final Pattern NONWORD = Pattern.compile("\\W");\r
-\r
-    /**\r
-     * Valid Amino acids\r
-     */\r
-    public static final Pattern AA = Pattern.compile("[ARNDCQEGHILKMFPSTWYV]+",\r
-           Pattern.CASE_INSENSITIVE);\r
-\r
-    /**\r
-     * inversion of AA pattern\r
-     */\r
-    public static final Pattern NON_AA = Pattern.compile(\r
-           "[^ARNDCQEGHILKMFPSTWYV]+", Pattern.CASE_INSENSITIVE);\r
-\r
-    /**\r
-     * Same as AA pattern but with two additional letters - XU\r
-     */\r
-    public static final Pattern AMBIGUOUS_AA = Pattern.compile(\r
-           "[ARNDCQEGHILKMFPSTWYVXU]+", Pattern.CASE_INSENSITIVE);\r
-\r
-    /**\r
-     * Nucleotides a, t, g, c, u\r
-     */\r
-    public static final Pattern NUCLEOTIDE = Pattern.compile("[AGTCU]+",\r
-           Pattern.CASE_INSENSITIVE);\r
-\r
-    /**\r
-     * Ambiguous nucleotide\r
-     */\r
-    public static final Pattern AMBIGUOUS_NUCLEOTIDE = Pattern.compile(\r
-           "[AGTCRYMKSWHBVDNU]+", Pattern.CASE_INSENSITIVE); // see IUPAC\r
-    /**\r
-     * Non nucleotide\r
-     */\r
-    public static final Pattern NON_NUCLEOTIDE = Pattern.compile("[^AGTCU]+",\r
-           Pattern.CASE_INSENSITIVE);\r
-\r
-    private SequenceUtil() {\r
-    } // utility class, no instantiation\r
-\r
-    /*\r
-     * public static void write_PirSeq(OutputStream os, FastaSequence seq)\r
-     * throws IOException { BufferedWriter pir_out = new BufferedWriter(new\r
-     * OutputStreamWriter(os)); pir_out.write(">P1;" + seq.getId() +\r
-     * SysPrefs.newlinechar); pir_out.write(seq.getSequence() +\r
-     * SysPrefs.newlinechar); pir_out.close(); }\r
-     * \r
-     * public static void write_FastaSeq(OutputStream os, FastaSequence seq)\r
-     * throws IOException { BufferedWriter fasta_out = new BufferedWriter( new\r
-     * OutputStreamWriter(os)); fasta_out.write(">" + seq.getId() +\r
-     * SysPrefs.newlinechar); fasta_out.write(seq.getSequence() +\r
-     * SysPrefs.newlinechar); fasta_out.close(); }\r
-     */\r
-\r
-    /**\r
-     * @return true is the sequence contains only letters a,c, t, g, u\r
-     */\r
-    public static boolean isNucleotideSequence(final FastaSequence s) {\r
-       return SequenceUtil.isNonAmbNucleotideSequence(s.getSequence());\r
-    }\r
-\r
-    /**\r
-     * Ambiguous DNA chars : AGTCRYMKSWHBVDN // differs from protein in only one\r
-     * (!) - B char\r
-     */\r
-    public static boolean isNonAmbNucleotideSequence(String sequence) {\r
-       sequence = SequenceUtil.cleanSequence(sequence);\r
-       if (SequenceUtil.DIGIT.matcher(sequence).find()) {\r
-           return false;\r
+       /**\r
+        * A whitespace character: [\t\n\x0B\f\r]\r
+        */\r
+       public static final Pattern WHITE_SPACE = Pattern.compile("\\s");\r
+\r
+       /**\r
+        * A digit\r
+        */\r
+       public static final Pattern DIGIT = Pattern.compile("\\d");\r
+\r
+       /**\r
+        * Non word\r
+        */\r
+       public static final Pattern NONWORD = Pattern.compile("\\W");\r
+\r
+       /**\r
+        * Valid Amino acids\r
+        */\r
+       public static final Pattern AA = Pattern.compile("[ARNDCQEGHILKMFPSTWYV]+",\r
+                       Pattern.CASE_INSENSITIVE);\r
+\r
+       /**\r
+        * inversion of AA pattern\r
+        */\r
+       public static final Pattern NON_AA = Pattern.compile(\r
+                       "[^ARNDCQEGHILKMFPSTWYV]+", Pattern.CASE_INSENSITIVE);\r
+\r
+       /**\r
+        * Same as AA pattern but with two additional letters - XU\r
+        */\r
+       public static final Pattern AMBIGUOUS_AA = Pattern.compile(\r
+                       "[ARNDCQEGHILKMFPSTWYVXU]+", Pattern.CASE_INSENSITIVE);\r
+\r
+       /**\r
+        * Nucleotides a, t, g, c, u\r
+        */\r
+       public static final Pattern NUCLEOTIDE = Pattern.compile("[AGTCU]+",\r
+                       Pattern.CASE_INSENSITIVE);\r
+\r
+       /**\r
+        * Ambiguous nucleotide\r
+        */\r
+       public static final Pattern AMBIGUOUS_NUCLEOTIDE = Pattern.compile(\r
+                       "[AGTCRYMKSWHBVDNU]+", Pattern.CASE_INSENSITIVE); // see IUPAC\r
+       /**\r
+        * Non nucleotide\r
+        */\r
+       public static final Pattern NON_NUCLEOTIDE = Pattern.compile("[^AGTCU]+",\r
+                       Pattern.CASE_INSENSITIVE);\r
+\r
+       private SequenceUtil() {\r
+       } // utility class, no instantiation\r
+\r
+       /*\r
+        * public static void write_PirSeq(OutputStream os, FastaSequence seq)\r
+        * throws IOException { BufferedWriter pir_out = new BufferedWriter(new\r
+        * OutputStreamWriter(os)); pir_out.write(">P1;" + seq.getId() +\r
+        * SysPrefs.newlinechar); pir_out.write(seq.getSequence() +\r
+        * SysPrefs.newlinechar); pir_out.close(); } public static void\r
+        * write_FastaSeq(OutputStream os, FastaSequence seq) throws IOException {\r
+        * BufferedWriter fasta_out = new BufferedWriter( new\r
+        * OutputStreamWriter(os)); fasta_out.write(">" + seq.getId() +\r
+        * SysPrefs.newlinechar); fasta_out.write(seq.getSequence() +\r
+        * SysPrefs.newlinechar); fasta_out.close(); }\r
+        */\r
+\r
+       /**\r
+        * @return true is the sequence contains only letters a,c, t, g, u\r
+        */\r
+       public static boolean isNucleotideSequence(final FastaSequence s) {\r
+               return SequenceUtil.isNonAmbNucleotideSequence(s.getSequence());\r
        }\r
-       if (SequenceUtil.NON_NUCLEOTIDE.matcher(sequence).find()) {\r
-           return false;\r
-           /*\r
-            * System.out.format("I found the text starting at " +\r
-            * "index %d and ending at index %d.%n", nonDNAmatcher .start(),\r
-            * nonDNAmatcher.end());\r
-            */\r
+\r
+       /**\r
+        * Ambiguous DNA chars : AGTCRYMKSWHBVDN // differs from protein in only one\r
+        * (!) - B char\r
+        */\r
+       public static boolean isNonAmbNucleotideSequence(String sequence) {\r
+               sequence = SequenceUtil.cleanSequence(sequence);\r
+               if (SequenceUtil.DIGIT.matcher(sequence).find()) {\r
+                       return false;\r
+               }\r
+               if (SequenceUtil.NON_NUCLEOTIDE.matcher(sequence).find()) {\r
+                       return false;\r
+                       /*\r
+                        * System.out.format("I found the text starting at " +\r
+                        * "index %d and ending at index %d.%n", nonDNAmatcher .start(),\r
+                        * nonDNAmatcher.end());\r
+                        */\r
+               }\r
+               final Matcher DNAmatcher = SequenceUtil.NUCLEOTIDE.matcher(sequence);\r
+               return DNAmatcher.find();\r
        }\r
-       final Matcher DNAmatcher = SequenceUtil.NUCLEOTIDE.matcher(sequence);\r
-       return DNAmatcher.find();\r
-    }\r
-\r
-    /**\r
-     * Removes all whitespace chars in the sequence string\r
-     * \r
-     * @param sequence\r
-     * @return cleaned up sequence\r
-     */\r
-    public static String cleanSequence(String sequence) {\r
-       assert sequence != null;\r
-       final Matcher m = SequenceUtil.WHITE_SPACE.matcher(sequence);\r
-       sequence = m.replaceAll("").toUpperCase();\r
-       return sequence;\r
-    }\r
-\r
-    /**\r
-     * Removes all special characters and digits as well as whitespace chars\r
-     * from the sequence\r
-     * \r
-     * @param sequence\r
-     * @return cleaned up sequence\r
-     */\r
-    public static String deepCleanSequence(String sequence) {\r
-       sequence = SequenceUtil.cleanSequence(sequence);\r
-       sequence = SequenceUtil.DIGIT.matcher(sequence).replaceAll("");\r
-       sequence = SequenceUtil.NONWORD.matcher(sequence).replaceAll("");\r
-       final Pattern othernonSeqChars = Pattern.compile("[_-]+");\r
-       sequence = othernonSeqChars.matcher(sequence).replaceAll("");\r
-       return sequence;\r
-    }\r
-\r
-    /**\r
-     * \r
-     * @param sequence\r
-     * @return true is the sequence is a protein sequence, false overwise\r
-     */\r
-    public static boolean isProteinSequence(String sequence) {\r
-       sequence = SequenceUtil.cleanSequence(sequence);\r
-       if (SequenceUtil.isNonAmbNucleotideSequence(sequence)) {\r
-           return false;\r
+\r
+       /**\r
+        * Removes all whitespace chars in the sequence string\r
+        * \r
+        * @param sequence\r
+        * @return cleaned up sequence\r
+        */\r
+       public static String cleanSequence(String sequence) {\r
+               assert sequence != null;\r
+               final Matcher m = SequenceUtil.WHITE_SPACE.matcher(sequence);\r
+               sequence = m.replaceAll("").toUpperCase();\r
+               return sequence;\r
        }\r
-       if (SequenceUtil.DIGIT.matcher(sequence).find()) {\r
-           return false;\r
+\r
+       /**\r
+        * Removes all special characters and digits as well as whitespace chars\r
+        * from the sequence\r
+        * \r
+        * @param sequence\r
+        * @return cleaned up sequence\r
+        */\r
+       public static String deepCleanSequence(String sequence) {\r
+               sequence = SequenceUtil.cleanSequence(sequence);\r
+               sequence = SequenceUtil.DIGIT.matcher(sequence).replaceAll("");\r
+               sequence = SequenceUtil.NONWORD.matcher(sequence).replaceAll("");\r
+               final Pattern othernonSeqChars = Pattern.compile("[_-]+");\r
+               sequence = othernonSeqChars.matcher(sequence).replaceAll("");\r
+               return sequence;\r
        }\r
-       if (SequenceUtil.NON_AA.matcher(sequence).find()) {\r
-           return false;\r
+\r
+       /**\r
+        * @param sequence\r
+        * @return true is the sequence is a protein sequence, false overwise\r
+        */\r
+       public static boolean isProteinSequence(String sequence) {\r
+               sequence = SequenceUtil.cleanSequence(sequence);\r
+               if (SequenceUtil.isNonAmbNucleotideSequence(sequence)) {\r
+                       return false;\r
+               }\r
+               if (SequenceUtil.DIGIT.matcher(sequence).find()) {\r
+                       return false;\r
+               }\r
+               if (SequenceUtil.NON_AA.matcher(sequence).find()) {\r
+                       return false;\r
+               }\r
+               final Matcher protmatcher = SequenceUtil.AA.matcher(sequence);\r
+               return protmatcher.find();\r
        }\r
-       final Matcher protmatcher = SequenceUtil.AA.matcher(sequence);\r
-       return protmatcher.find();\r
-    }\r
-\r
-    /**\r
-     * Check whether the sequence confirms to amboguous protein sequence\r
-     * \r
-     * @param sequence\r
-     * @return return true only if the sequence if ambiguous protein sequence\r
-     *         Return false otherwise. e.g. if the sequence is non-ambiguous\r
-     *         protein or DNA\r
-     */\r
-    public static boolean isAmbiguosProtein(String sequence) {\r
-       sequence = SequenceUtil.cleanSequence(sequence);\r
-       if (SequenceUtil.isNonAmbNucleotideSequence(sequence)) {\r
-           return false;\r
+\r
+       /**\r
+        * Check whether the sequence confirms to amboguous protein sequence\r
+        * \r
+        * @param sequence\r
+        * @return return true only if the sequence if ambiguous protein sequence\r
+        *         Return false otherwise. e.g. if the sequence is non-ambiguous\r
+        *         protein or DNA\r
+        */\r
+       public static boolean isAmbiguosProtein(String sequence) {\r
+               sequence = SequenceUtil.cleanSequence(sequence);\r
+               if (SequenceUtil.isNonAmbNucleotideSequence(sequence)) {\r
+                       return false;\r
+               }\r
+               if (SequenceUtil.DIGIT.matcher(sequence).find()) {\r
+                       return false;\r
+               }\r
+               if (SequenceUtil.NON_AA.matcher(sequence).find()) {\r
+                       return false;\r
+               }\r
+               if (SequenceUtil.AA.matcher(sequence).find()) {\r
+                       return false;\r
+               }\r
+               final Matcher amb_prot = SequenceUtil.AMBIGUOUS_AA.matcher(sequence);\r
+               return amb_prot.find();\r
        }\r
-       if (SequenceUtil.DIGIT.matcher(sequence).find()) {\r
-           return false;\r
+\r
+       /**\r
+        * Writes list of FastaSequeces into the outstream formatting the sequence\r
+        * so that it contains width chars on each line\r
+        * \r
+        * @param outstream\r
+        * @param sequences\r
+        * @param width\r
+        *            - the maximum number of characters to write in one line\r
+        * @throws IOException\r
+        */\r
+       public static void writeFasta(final OutputStream outstream,\r
+                       final List<FastaSequence> sequences, final int width)\r
+                       throws IOException {\r
+               writeFastaKeepTheStream(outstream, sequences, width);\r
+               outstream.close();\r
        }\r
-       if (SequenceUtil.NON_AA.matcher(sequence).find()) {\r
-           return false;\r
+\r
+       public static void writeFastaKeepTheStream(final OutputStream outstream,\r
+                       final List<FastaSequence> sequences, final int width)\r
+                       throws IOException {\r
+               final OutputStreamWriter writer = new OutputStreamWriter(outstream);\r
+               final BufferedWriter fastawriter = new BufferedWriter(writer);\r
+               for (final FastaSequence fs : sequences) {\r
+                       fastawriter.write(">" + fs.getId() + "\n");\r
+                       fastawriter.write(fs.getFormatedSequence(width));\r
+                       fastawriter.write("\n");\r
+               }\r
+               fastawriter.flush();\r
+               writer.flush();\r
+       }\r
+\r
+       /**\r
+        * Reads fasta sequences from inStream into the list of FastaSequence\r
+        * objects\r
+        * \r
+        * @param inStream\r
+        *            from\r
+        * @return list of FastaSequence objects\r
+        * @throws IOException\r
+        */\r
+       public static List<FastaSequence> readFasta(final InputStream inStream)\r
+                       throws IOException {\r
+               final List<FastaSequence> seqs = new ArrayList<FastaSequence>();\r
+\r
+               final BufferedReader infasta = new BufferedReader(\r
+                               new InputStreamReader(inStream, "UTF8"), 16000);\r
+               final Pattern pattern = Pattern.compile("//s+");\r
+\r
+               String line;\r
+               String sname = "", seqstr = null;\r
+               do {\r
+                       line = infasta.readLine();\r
+                       if ((line == null) || line.startsWith(">")) {\r
+                               if (seqstr != null) {\r
+                                       seqs.add(new FastaSequence(sname.substring(1), seqstr));\r
+                               }\r
+                               sname = line; // remove >\r
+                               seqstr = "";\r
+                       } else {\r
+                               final String subseq = pattern.matcher(line).replaceAll("");\r
+                               seqstr += subseq;\r
+                       }\r
+               } while (line != null);\r
+\r
+               infasta.close();\r
+               return seqs;\r
        }\r
-       if (SequenceUtil.AA.matcher(sequence).find()) {\r
-           return false;\r
+\r
+       /**\r
+        * Writes FastaSequence in the file, each sequence will take one line only\r
+        * \r
+        * @param os\r
+        * @param sequences\r
+        * @throws IOException\r
+        */\r
+       public static void writeFasta(final OutputStream os,\r
+                       final List<FastaSequence> sequences) throws IOException {\r
+               final OutputStreamWriter outWriter = new OutputStreamWriter(os);\r
+               final BufferedWriter fasta_out = new BufferedWriter(outWriter);\r
+               for (final FastaSequence fs : sequences) {\r
+                       fasta_out.write(fs.getOnelineFasta());\r
+               }\r
+               fasta_out.close();\r
+               outWriter.close();\r
+       }\r
+\r
+       public static List<AnnotatedSequence> readJRonn(final File result)\r
+                       throws IOException, UnknownFileFormatException {\r
+               InputStream input = new FileInputStream(result);\r
+               List<AnnotatedSequence> sequences = readJRonn(input);\r
+               input.close();\r
+               return sequences;\r
        }\r
-       final Matcher amb_prot = SequenceUtil.AMBIGUOUS_AA.matcher(sequence);\r
-       return amb_prot.find();\r
-    }\r
-\r
-    /**\r
-     * Writes list of FastaSequeces into the outstream formatting the sequence\r
-     * so that it contains width chars on each line\r
-     * \r
-     * @param outstream\r
-     * @param sequences\r
-     * @param width\r
-     *            - the maximum number of characters to write in one line\r
-     * @throws IOException\r
-     */\r
-    public static void writeFasta(final OutputStream outstream,\r
-           final List<FastaSequence> sequences, final int width)\r
-           throws IOException {\r
-       final OutputStreamWriter writer = new OutputStreamWriter(outstream);\r
-       final BufferedWriter fastawriter = new BufferedWriter(writer);\r
-       for (final FastaSequence fs : sequences) {\r
-           fastawriter.write(fs.getFormatedSequence(width));\r
+\r
+       /**\r
+        * Reader for JRonn horizontal file format >Foobar M G D T T A G 0.48 0.42\r
+        * 0.42 0.48 0.52 0.53 0.54 All values are tab delimited\r
+        * \r
+        * @param inStream\r
+        * @return\r
+        * @throws IOException\r
+        * @throws UnknownFileFormatException\r
+        */\r
+       public static List<AnnotatedSequence> readJRonn(final InputStream inStream)\r
+                       throws IOException, UnknownFileFormatException {\r
+               final List<AnnotatedSequence> seqs = new ArrayList<AnnotatedSequence>();\r
+\r
+               final BufferedReader infasta = new BufferedReader(\r
+                               new InputStreamReader(inStream, "UTF8"), 16000);\r
+\r
+               String line;\r
+               String sname = "";\r
+               do {\r
+                       line = infasta.readLine();\r
+                       if (line == null || line.isEmpty()) {\r
+                               // skip empty lines\r
+                               continue;\r
+                       }\r
+                       if (line.startsWith(">")) {\r
+                               // read name\r
+                               sname = line.trim().substring(1);\r
+                               // read sequence line\r
+                               line = infasta.readLine();\r
+                               final String sequence = line.replace("\t", "");\r
+                               // read annotation line\r
+                               line = infasta.readLine();\r
+                               String[] annotValues = line.split("\t");\r
+                               float[] annotation = convertToNumber(annotValues);\r
+                               if (annotation.length != sequence.length()) {\r
+                                       throw new UnknownFileFormatException(\r
+                                                       "File does not look like Jronn horizontally formatted output file!\n"\r
+                                                                       + JRONN_WRONG_FORMAT_MESSAGE);\r
+                               }\r
+                               seqs.add(new AnnotatedSequence(sname, sequence, annotation));\r
+                       }\r
+               } while (line != null);\r
+\r
+               infasta.close();\r
+               return seqs;\r
        }\r
-       outstream.flush();\r
-       fastawriter.close();\r
-       writer.close();\r
-    }\r
-\r
-    /**\r
-     * Reads fasta sequences from inStream into the list of FastaSequence\r
-     * objects\r
-     * \r
-     * @param inStream\r
-     *            from\r
-     * @return list of FastaSequence objects\r
-     * @throws IOException\r
-     */\r
-    public static List<FastaSequence> readFasta(final InputStream inStream)\r
-           throws IOException {\r
-       final List<FastaSequence> seqs = new ArrayList<FastaSequence>();\r
-\r
-       final BufferedReader infasta = new BufferedReader(\r
-               new InputStreamReader(inStream, "UTF8"), 16000);\r
-       final Pattern pattern = Pattern.compile("//s+");\r
-\r
-       String line;\r
-       String sname = "", seqstr = null;\r
-       do {\r
-           line = infasta.readLine();\r
-           if ((line == null) || line.startsWith(">")) {\r
-               if (seqstr != null) {\r
-                   seqs.add(new FastaSequence(sname.substring(1), seqstr));\r
+\r
+       private static float[] convertToNumber(String[] annotValues)\r
+                       throws UnknownFileFormatException {\r
+               float[] annotation = new float[annotValues.length];\r
+               try {\r
+                       for (int i = 0; i < annotation.length; i++) {\r
+                               annotation[i] = Float.parseFloat(annotValues[i]);\r
+                       }\r
+               } catch (NumberFormatException e) {\r
+                       throw new UnknownFileFormatException(JRONN_WRONG_FORMAT_MESSAGE,\r
+                                       e.getCause());\r
                }\r
-               sname = line; // remove >\r
-               seqstr = "";\r
-           } else {\r
-               final String subseq = pattern.matcher(line).replaceAll("");\r
-               seqstr += subseq;\r
-           }\r
-       } while (line != null);\r
-\r
-       infasta.close();\r
-       return seqs;\r
-    }\r
-\r
-    /**\r
-     * Writes FastaSequence in the file, each sequence will take one line only\r
-     * \r
-     * @param os\r
-     * @param sequences\r
-     * @throws IOException\r
-     */\r
-    public static void writeFasta(final OutputStream os,\r
-           final List<FastaSequence> sequences) throws IOException {\r
-       final OutputStreamWriter outWriter = new OutputStreamWriter(os);\r
-       final BufferedWriter fasta_out = new BufferedWriter(outWriter);\r
-       for (final FastaSequence fs : sequences) {\r
-           fasta_out.write(fs.getOnelineFasta());\r
+               return annotation;\r
        }\r
-       fasta_out.close();\r
-       outWriter.close();\r
-    }\r
-\r
-    public static List<AnnotatedSequence> readJRonn(final File result)\r
-           throws IOException, UnknownFileFormatException {\r
-       InputStream input = new FileInputStream(result);\r
-       List<AnnotatedSequence> sequences = readJRonn(input);\r
-       input.close();\r
-       return sequences;\r
-    }\r
-\r
-    /**\r
-     * Reader for JRonn horizontal file format\r
-     * \r
-     * >Foobar\r
-     * \r
-     * M G D T T A G\r
-     * \r
-     * 0.48 0.42 0.42 0.48 0.52 0.53 0.54\r
-     * \r
-     * All values are tab delimited\r
-     * \r
-     * @param inStream\r
-     * @return\r
-     * @throws IOException\r
-     * @throws UnknownFileFormatException\r
-     */\r
-    public static List<AnnotatedSequence> readJRonn(final InputStream inStream)\r
-           throws IOException, UnknownFileFormatException {\r
-       final List<AnnotatedSequence> seqs = new ArrayList<AnnotatedSequence>();\r
-\r
-       final BufferedReader infasta = new BufferedReader(\r
-               new InputStreamReader(inStream, "UTF8"), 16000);\r
-\r
-       String line;\r
-       String sname = "";\r
-       do {\r
-           line = infasta.readLine();\r
-           if (line == null || line.isEmpty()) {\r
-               // skip empty lines\r
-               continue;\r
-           }\r
-           if (line.startsWith(">")) {\r
-               // read name\r
-               sname = line.trim().substring(1);\r
-               // read sequence line\r
-               line = infasta.readLine();\r
-               final String sequence = line.replace("\t", "");\r
-               // read annotation line\r
-               line = infasta.readLine();\r
-               String[] annotValues = line.split("\t");\r
-               float[] annotation = convertToNumber(annotValues);\r
-               if (annotation.length != sequence.length()) {\r
-                   throw new UnknownFileFormatException(\r
-                           "File does not look like Jronn horizontally formatted output file!\n"\r
-                                   + JRONN_WRONG_FORMAT_MESSAGE);\r
+\r
+       private static final String JRONN_WRONG_FORMAT_MESSAGE = "Jronn file must be in the following format:\n"\r
+                       + ">sequence_name\n "\r
+                       + "M    V       S\n"\r
+                       + "0.43 0.22    0.65\n"\r
+                       + "Where first line is the sequence name,\n"\r
+                       + "second line is the tab delimited sequence,\n"\r
+                       + "third line contains tab delimited disorder prediction values.\n"\r
+                       + "No lines are allowed between these three. Additionally, the number of  "\r
+                       + "sequence residues must be equal to the number of the disorder values.";\r
+\r
+       /**\r
+        * Closes the Closable and logs the exception if any\r
+        * \r
+        * @param log\r
+        * @param stream\r
+        */\r
+       public final static void closeSilently(java.util.logging.Logger log,\r
+                       Closeable stream) {\r
+               if (stream != null) {\r
+                       try {\r
+                               stream.close();\r
+                       } catch (IOException e) {\r
+                               log.log(Level.WARNING, e.getLocalizedMessage(), e.getCause());\r
+                       }\r
                }\r
-               seqs.add(new AnnotatedSequence(sname, sequence, annotation));\r
-           }\r
-       } while (line != null);\r
-\r
-       infasta.close();\r
-       return seqs;\r
-    }\r
-\r
-    private static float[] convertToNumber(String[] annotValues)\r
-           throws UnknownFileFormatException {\r
-       float[] annotation = new float[annotValues.length];\r
-       try {\r
-           for (int i = 0; i < annotation.length; i++) {\r
-               annotation[i] = Float.parseFloat(annotValues[i]);\r
-           }\r
-       } catch (NumberFormatException e) {\r
-           throw new UnknownFileFormatException(JRONN_WRONG_FORMAT_MESSAGE, e\r
-                   .getCause());\r
        }\r
-       return annotation;\r
-    }\r
-\r
-    private static final String JRONN_WRONG_FORMAT_MESSAGE = "Jronn file must be in the following format:\n"\r
-           + ">sequence_name\n "\r
-           + "M        V       S\n"\r
-           + "0.43     0.22    0.65\n"\r
-           + "Where first line is the sequence name,\n"\r
-           + "second line is the tab delimited sequence,\n"\r
-           + "third line contains tab delimited disorder prediction values.\n"\r
-           + "No lines are allowed between these three. Additionally, the number of  "\r
-           + "sequence residues must be equal to the number of the disorder values.";\r
-\r
-    /**\r
-     * Closes the Closable and logs the exception if any\r
-     * \r
-     * @param log\r
-     * @param stream\r
-     */\r
-    public final static void closeSilently(java.util.logging.Logger log,\r
-           Closeable stream) {\r
-       if (stream != null) {\r
-           try {\r
-               stream.close();\r
-           } catch (IOException e) {\r
-               log.log(Level.WARNING, e.getLocalizedMessage(), e.getCause());\r
-           }\r
+\r
+       /**\r
+        * \r
+        * TODO complete!\r
+        * \r
+        * # RESIDUE COILS REM465 HOTLOOPS M 0.86010 0.88512 0.37094 T 0.79983\r
+        * 0.85864 0.44331 .... # RESIDUE COILS REM465 HOTLOOPS M 0.86010 0.88512\r
+        * 0.37094\r
+        * \r
+        * @param input\r
+        * @return\r
+        * @throws IOException\r
+        * @throws UnknownFileFormatException\r
+        */\r
+       public static List<MultiAnnotatedSequence<DisemblResultAnnot>> readDisembl(\r
+                       final InputStream input) throws IOException,\r
+                       UnknownFileFormatException {\r
+               Scanner scan = new Scanner(input);\r
+               scan.useDelimiter("# RESIDUE COILS REM465 HOTLOOPS\n");\r
+               if (!scan.hasNext()) {\r
+                       throw new UnknownFileFormatException(\r
+                                       "In Disembl score format each seqeunce score is expected to start from the line: "\r
+                                                       + "'# RESIDUE COILS REM465 HOTLOOPS\\n'."\r
+                                                       + " No such line was found!");\r
+               }\r
+\r
+               List<MultiAnnotatedSequence<DisemblResultAnnot>> results = new ArrayList<MultiAnnotatedSequence<DisemblResultAnnot>>();\r
+               int seqCounter = 0;\r
+               while (scan.hasNext()) {\r
+                       seqCounter++;\r
+                       String singleSeq = scan.next();\r
+                       Scanner scansingle = new Scanner(singleSeq);\r
+                       StringBuffer seqbuffer = new StringBuffer();\r
+                       List<Float> coils = new ArrayList<Float>();\r
+                       List<Float> rem = new ArrayList<Float>();\r
+                       List<Float> hotloops = new ArrayList<Float>();\r
+\r
+                       MultiAnnotatedSequence<DisemblResultAnnot> disemblRes = new MultiAnnotatedSequence<DisemblResultAnnot>(\r
+                                       DisemblResultAnnot.class);\r
+\r
+                       while (scansingle.hasNextLine()) {\r
+                               String valueLine = scansingle.nextLine();\r
+                               Scanner values = new Scanner(valueLine);\r
+                               seqbuffer.append(values.next());\r
+                               coils.add(values.nextFloat());\r
+                               rem.add(values.nextFloat());\r
+                               hotloops.add(values.nextFloat());\r
+                               values.close();\r
+                       }\r
+                       disemblRes.addAnnotation(DisemblResultAnnot.COILS, coils);\r
+                       disemblRes.addAnnotation(DisemblResultAnnot.REM465, rem);\r
+                       disemblRes.addAnnotation(DisemblResultAnnot.HOTLOOPS, hotloops);\r
+                       // TODO\r
+                       // disemblRes.sequence = seqbuffer.toString();\r
+                       scansingle.close();\r
+                       results.add(disemblRes);\r
+               }\r
+\r
+               input.close();\r
+               return results;\r
        }\r
-    }\r
-\r
-    public static List<AnnotatedSequence> readDisembl(final File result)\r
-           throws IOException, UnknownFileFormatException {\r
-       InputStream input = new FileInputStream(result);\r
-       List<AnnotatedSequence> sequences = readJRonn(input);\r
-       input.close();\r
-       return sequences;\r
-    }\r
+\r
 }\r