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