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