ec4cadc4a5e2a8650e1376bd4f681aad1b5f64d8
[jabaws.git] / datamodel / compbio / data / sequence / Score.java
1 /* Copyright (c) 2011 Peter Troshin\r
2  *  \r
3  *  JAva Bioinformatics Analysis Web Services (JABAWS) @version: 2.0     \r
4  * \r
5  *  This library is free software; you can redistribute it and/or modify it under the terms of the\r
6  *  Apache License version 2 as published by the Apache Software Foundation\r
7  * \r
8  *  This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\r
9  *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Apache \r
10  *  License for more details.\r
11  * \r
12  *  A copy of the license is in apache_license.txt. It is also available here:\r
13  * @see: http://www.apache.org/licenses/LICENSE-2.0.txt\r
14  * \r
15  * Any republication or derived work distributed in source code form\r
16  * must include this copyright and license notice.\r
17  */\r
18 package compbio.data.sequence;\r
19 \r
20 import java.io.IOException;\r
21 import java.io.Writer;\r
22 import java.text.NumberFormat;\r
23 import java.util.ArrayList;\r
24 import java.util.Locale;\r
25 import java.util.TreeSet;\r
26 \r
27 import javax.xml.bind.annotation.XmlAccessType;\r
28 import javax.xml.bind.annotation.XmlAccessorType;\r
29 \r
30 import compbio.util.annotation.Immutable;\r
31 \r
32 /**\r
33  * A value class for AACon annotation results storage. The objects of this type\r
34  * are immutable\r
35  * \r
36  * @author pvtroshin\r
37  * \r
38  */\r
39 @XmlAccessorType(XmlAccessType.FIELD)\r
40 @Immutable\r
41 public class Score implements Comparable<Score> {\r
42 \r
43         static final NumberFormat NUMBER_FORMAT = NumberFormat\r
44                         .getNumberInstance(Locale.UK);\r
45         static {\r
46                 NUMBER_FORMAT.setGroupingUsed(false);\r
47                 NUMBER_FORMAT.setMaximumFractionDigits(3);\r
48         }\r
49         // This should be Enum<?> but JAXB cannot serialize it.\r
50         private final String method;\r
51 \r
52         private TreeSet<Range> ranges = new TreeSet<Range>();\r
53 \r
54         private ArrayList<Float> scores = new ArrayList<Float>(0);\r
55 \r
56         private Score() {\r
57                 // JaXB default constructor\r
58                 method = "";\r
59         }\r
60 \r
61         /**\r
62          * Instantiate the Score\r
63          * \r
64          * @param method\r
65          *            the ConservationMethod with which {@code scores} were\r
66          *            calculated\r
67          * @param scores\r
68          *            the actual conservation values for each column of the\r
69          *            alignment\r
70          */\r
71         public Score(Enum<?> method, ArrayList<Float> scores) {\r
72                 this.method = method.toString();\r
73                 this.scores = new ArrayList<Float>(scores);\r
74         }\r
75 \r
76         /**\r
77          * @param method\r
78          *            the ConservationMethod with which {@code scores} were\r
79          *            calculated\r
80          * @param scores\r
81          *            the actual conservation values for each column of the\r
82          *            alignment\r
83          * @param ranges\r
84          *            The set of ranges i.e. parts of the sequence with specific\r
85          *            function, usually can be calculated based on scores\r
86          */\r
87         public Score(Enum<?> method, ArrayList<Float> scores, TreeSet<Range> ranges) {\r
88                 this.method = method.toString();\r
89                 this.ranges = ranges;\r
90                 this.scores = scores;\r
91         }\r
92 \r
93         public Score(Enum<?> method, TreeSet<Range> ranges) {\r
94                 this.method = method.toString();\r
95                 this.ranges = ranges;\r
96         }\r
97 \r
98         public Score(Enum<?> method, float[] scores) {\r
99                 this.method = method.toString();\r
100                 this.scores = toList(scores);\r
101         }\r
102 \r
103         private ArrayList<Float> toList(float[] values) {\r
104                 ArrayList<Float> vlist = new ArrayList<Float>();\r
105                 for (float v : values) {\r
106                         vlist.add(new Float(v));\r
107                 }\r
108                 return vlist;\r
109         }\r
110         /**\r
111          * Returns the ConservationMethod\r
112          * \r
113          * @return the ConservationMethod\r
114          */\r
115         public String getMethod() {\r
116                 return method;\r
117         }\r
118 \r
119         /**\r
120          * The column scores for the alignment\r
121          * \r
122          * @return the column scores for the alignment\r
123          */\r
124         public ArrayList<Float> getScores() {\r
125                 return scores;\r
126         }\r
127 \r
128         /**\r
129          * Return Ranges if any Collections.EMPTY_SET otherwise\r
130          * \r
131          * @return ordered set of Range\r
132          */\r
133         public TreeSet<Range> getRanges() {\r
134                 return ranges;\r
135         }\r
136 \r
137         public void setRanges(TreeSet<Range> ranges) {\r
138                 this.ranges = ranges;\r
139         }\r
140 \r
141         @Override\r
142         public String toString() {\r
143                 return "Score [method=" + method + ", ranges=" + ranges + ", scores="\r
144                                 + scores + "]";\r
145         }\r
146 \r
147         @Override\r
148         public int hashCode() {\r
149                 final int prime = 7;\r
150                 int result = 1;\r
151                 result = prime * result + ((method == null) ? 0 : method.hashCode());\r
152                 result = prime * result + ((ranges == null) ? 0 : ranges.hashCode());\r
153                 result = prime * result + ((scores == null) ? 0 : scores.hashCode());\r
154                 return result;\r
155         }\r
156 \r
157         @Override\r
158         public boolean equals(Object obj) {\r
159                 if (this == obj)\r
160                         return true;\r
161                 if (obj == null)\r
162                         return false;\r
163                 if (getClass() != obj.getClass())\r
164                         return false;\r
165                 Score other = (Score) obj;\r
166                 if (method == null) {\r
167                         if (other.method != null)\r
168                                 return false;\r
169                 } else if (!method.equals(other.method))\r
170                         return false;\r
171                 if (ranges == null) {\r
172                         if (other.ranges != null)\r
173                                 return false;\r
174                 } else if (!ranges.equals(other.ranges))\r
175                         return false;\r
176                 if (scores == null) {\r
177                         if (other.scores != null)\r
178                                 return false;\r
179                 } else if (!scores.equals(other.scores))\r
180                         return false;\r
181                 return true;\r
182         }\r
183 \r
184         /**\r
185          * Outputs the List of Score objects into the Output stream. The output\r
186          * format is as follows:\r
187          * \r
188          * <pre>\r
189          * {@code\r
190          * #MethodName <space separated list of values>\r
191          *        \r
192          * For example:\r
193          *       \r
194          * #KABAT 0.2 0.3 0.2 0 0.645 0.333 1 1 0 0\r
195          * #SMERFS 0.645 0.333 1 1 0 0 0.2 0.3 0.2 0\r
196          * }\r
197          * </pre>\r
198          * \r
199          * The maximum precision for values is 3 digits, but can be less.\r
200          * \r
201          * @param scores\r
202          *            the list of scores to output\r
203          * @param writer\r
204          * @throws IOException\r
205          *             if the OutputStream cannot be written into\r
206          * @throws NullPointerException\r
207          *             if the output stream is null\r
208          */\r
209         public static void write(TreeSet<Score> scores, Writer writer)\r
210                         throws IOException {\r
211                 if (writer == null) {\r
212                         throw new NullPointerException("Writer must be provided!");\r
213                 }\r
214                 for (Score score : scores) {\r
215                         writer.write("#" + score.method + " ");\r
216                         int count = score.ranges.size();\r
217                         for (Range range : score.ranges) {\r
218                                 count--;\r
219                                 writer.write(range.toString());\r
220                                 if (count != 0) {\r
221                                         writer.write(", ");\r
222                                 }\r
223                         }\r
224                         for (Float scoreVal : score.scores) {\r
225                                 writer.write(NUMBER_FORMAT.format(scoreVal) + " ");\r
226                         }\r
227                         writer.write("\n");\r
228                         writer.flush();\r
229                 }\r
230                 writer.flush();\r
231         }\r
232 \r
233         @Override\r
234         public int compareTo(Score o) {\r
235                 return this.method.compareTo(o.method);\r
236         }\r
237 }\r