Change header template for a new version
[jabaws.git] / datamodel / compbio / data / sequence / Score.java
index 3416e78..c8cbfb4 100644 (file)
+/* Copyright (c) 2011 Peter Troshin\r
+ *  \r
+ *  JAva Bioinformatics Analysis Web Services (JABAWS) @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
 package compbio.data.sequence;\r
 \r
-import java.util.Arrays;\r
-import java.util.List;\r
+import java.io.IOException;\r
+import java.io.Writer;\r
+import java.text.NumberFormat;\r
+import java.util.ArrayList;\r
+import java.util.Locale;\r
+import java.util.TreeSet;\r
 \r
 import javax.xml.bind.annotation.XmlAccessType;\r
 import javax.xml.bind.annotation.XmlAccessorType;\r
 \r
 import compbio.util.annotation.Immutable;\r
 \r
+/**\r
+ * A value class for AACon annotation results storage. The objects of this type\r
+ * are immutable\r
+ * \r
+ * @author pvtroshin\r
+ * \r
+ */\r
 @XmlAccessorType(XmlAccessType.FIELD)\r
 @Immutable\r
-public class Score {\r
+public class Score implements Comparable<Score> {\r
 \r
-       private Method method;\r
+       static final NumberFormat NUMBER_FORMAT = NumberFormat\r
+                       .getNumberInstance(Locale.UK);\r
+       static {\r
+               NUMBER_FORMAT.setGroupingUsed(false);\r
+               NUMBER_FORMAT.setMaximumFractionDigits(3);\r
+       }\r
+       // This should be Enum<?> but JAXB cannot serialize it.\r
+       private final String method;\r
+\r
+       private TreeSet<Range> ranges = new TreeSet<Range>();\r
 \r
-       private List<Float> scores;\r
+       private ArrayList<Float> scores = new ArrayList<Float>(0);\r
 \r
        private Score() {\r
                // JaXB default constructor\r
+               method = "";\r
+       }\r
+\r
+       /**\r
+        * Instantiate the Score\r
+        * \r
+        * @param method\r
+        *            the ConservationMethod with which {@code scores} were\r
+        *            calculated\r
+        * @param scores\r
+        *            the actual conservation values for each column of the\r
+        *            alignment\r
+        */\r
+       public Score(Enum<?> method, ArrayList<Float> scores) {\r
+               this.method = method.toString();\r
+               this.scores = new ArrayList<Float>(scores);\r
        }\r
 \r
-       public Score(Method method, List<Float> scores) {\r
-               this.method = method;\r
+       /**\r
+        * @param method\r
+        *            the ConservationMethod with which {@code scores} were\r
+        *            calculated\r
+        * @param scores\r
+        *            the actual conservation values for each column of the\r
+        *            alignment\r
+        * @param ranges\r
+        *            The set of ranges i.e. parts of the sequence with specific\r
+        *            function, usually can be calculated based on scores\r
+        */\r
+       public Score(Enum<?> method, ArrayList<Float> scores, TreeSet<Range> ranges) {\r
+               this.method = method.toString();\r
+               this.ranges = ranges;\r
                this.scores = scores;\r
        }\r
 \r
-       public Method getMethod() {\r
+       public Score(Enum<?> method, TreeSet<Range> ranges) {\r
+               this.method = method.toString();\r
+               this.ranges = ranges;\r
+       }\r
+\r
+       public Score(Enum<?> method, float[] scores) {\r
+               this.method = method.toString();\r
+               this.scores = toList(scores);\r
+       }\r
+\r
+       private ArrayList<Float> toList(float[] values) {\r
+               ArrayList<Float> vlist = new ArrayList<Float>();\r
+               for (float v : values) {\r
+                       vlist.add(new Float(v));\r
+               }\r
+               return vlist;\r
+       }\r
+       /**\r
+        * Returns the ConservationMethod\r
+        * \r
+        * @return the ConservationMethod\r
+        */\r
+       public String getMethod() {\r
                return method;\r
        }\r
 \r
-       public List<Float> getScores() {\r
+       /**\r
+        * The column scores for the alignment\r
+        * \r
+        * @return the column scores for the alignment\r
+        */\r
+       public ArrayList<Float> getScores() {\r
                return scores;\r
        }\r
 \r
+       /**\r
+        * Return Ranges if any Collections.EMPTY_SET otherwise\r
+        * \r
+        * @return\r
+        */\r
+       public TreeSet<Range> getRanges() {\r
+               return ranges;\r
+       }\r
+\r
+       public void setRanges(TreeSet<Range> ranges) {\r
+               this.ranges = ranges;\r
+       }\r
+\r
        @Override\r
        public String toString() {\r
-               return "Score [method=" + method + ", scores=" + scores + "]";\r
+               return "Score [method=" + method + ", ranges=" + ranges + ", scores="\r
+                               + scores + "]";\r
        }\r
 \r
        @Override\r
        public int hashCode() {\r
-               final int prime = 31;\r
+               final int prime = 7;\r
                int result = 1;\r
                result = prime * result + ((method == null) ? 0 : method.hashCode());\r
+               result = prime * result + ((ranges == null) ? 0 : ranges.hashCode());\r
                result = prime * result + ((scores == null) ? 0 : scores.hashCode());\r
                return result;\r
        }\r
 \r
-       /*\r
-        * TODO test ! (non-Javadoc)\r
-        * \r
-        * @see java.lang.Object#equals(java.lang.Object)\r
-        */\r
        @Override\r
        public boolean equals(Object obj) {\r
                if (this == obj)\r
@@ -61,16 +163,76 @@ public class Score {
                if (getClass() != obj.getClass())\r
                        return false;\r
                Score other = (Score) obj;\r
-               if (method != other.method)\r
+               if (method == null) {\r
+                       if (other.method != null)\r
+                               return false;\r
+               } else if (!method.equals(other.method))\r
                        return false;\r
-               if (scores == other.scores) {\r
-                       return true;\r
-               }\r
-               if (scores == null) {\r
+               if (ranges == null) {\r
+                       if (other.ranges != null)\r
+                               return false;\r
+               } else if (!ranges.equals(other.ranges))\r
                        return false;\r
-               }\r
-               if (!Arrays.deepEquals(scores.toArray(), other.scores.toArray()))\r
+               if (scores == null) {\r
+                       if (other.scores != null)\r
+                               return false;\r
+               } else if (!scores.equals(other.scores))\r
                        return false;\r
                return true;\r
        }\r
+\r
+       /**\r
+        * Outputs the List of Score objects into the Output stream. The output\r
+        * format is as follows:\r
+        * \r
+        * <pre>\r
+        * {@code\r
+        * #MethodName <space separated list of values>\r
+        *        \r
+        * For example:\r
+        *       \r
+        * #KABAT 0.2 0.3 0.2 0 0.645 0.333 1 1 0 0\r
+        * #SMERFS 0.645 0.333 1 1 0 0 0.2 0.3 0.2 0\r
+        * }\r
+        * </pre>\r
+        * \r
+        * The maximum precision for values is 3 digits, but can be less.\r
+        * \r
+        * @param scores\r
+        *            the list of scores to output\r
+        * @param output\r
+        *            the stream to output the data to\r
+        * @throws IOException\r
+        *             if the OutputStream cannot be written into\r
+        * @throws NullPointerException\r
+        *             if the output stream is null\r
+        */\r
+       public static void write(TreeSet<Score> scores, Writer writer)\r
+                       throws IOException {\r
+               if (writer == null) {\r
+                       throw new NullPointerException("Writer must be provided!");\r
+               }\r
+               for (Score score : scores) {\r
+                       writer.write("#" + score.method + " ");\r
+                       int count = score.ranges.size();\r
+                       for (Range range : score.ranges) {\r
+                               count--;\r
+                               writer.write(range.toString());\r
+                               if (count != 0) {\r
+                                       writer.write(", ");\r
+                               }\r
+                       }\r
+                       for (Float scoreVal : score.scores) {\r
+                               writer.write(NUMBER_FORMAT.format(scoreVal) + " ");\r
+                       }\r
+                       writer.write("\n");\r
+                       writer.flush();\r
+               }\r
+               writer.flush();\r
+       }\r
+\r
+       @Override\r
+       public int compareTo(Score o) {\r
+               return this.method.compareTo(o.method);\r
+       }\r
 }\r