Report invalid chars
[jalview.git] / src / jalview / io / AnnotationReader.java
1 package jalview.io;\r
2 \r
3 import java.io.*;\r
4 import jalview.datamodel.*;\r
5 import java.util.StringTokenizer;\r
6 import jalview.schemes.UserColourScheme;\r
7 import java.net.URL;\r
8 \r
9 public class AnnotationReader\r
10 {\r
11   public boolean readAnnotationFile(AlignmentI al, String file)\r
12   {\r
13 \r
14     try\r
15     {\r
16 \r
17       BufferedReader in = null;\r
18       try{\r
19         URL url = new URL(file);\r
20         in = new BufferedReader(new InputStreamReader(url.openStream()));\r
21       }\r
22       catch(java.net.MalformedURLException ex)\r
23       {\r
24         in = new BufferedReader(new FileReader(file));\r
25       }\r
26 \r
27 \r
28       String line, label, description, token;\r
29       int graphStyle, index;\r
30       SequenceI refSeq = null;\r
31       int refSeqIndex = 0;\r
32       int existingAnnotations = 0;\r
33       if(al.getAlignmentAnnotation()!=null)\r
34        existingAnnotations = al.getAlignmentAnnotation().length;\r
35 \r
36       StringTokenizer st;\r
37       Annotation[] annotations;\r
38       AlignmentAnnotation annotation = null;\r
39 \r
40       // First confirm this is an Annotation file\r
41       boolean jvAnnotationFile = false;\r
42       while ( (line = in.readLine()) != null)\r
43       {\r
44         if (line.indexOf("#") == 0 )\r
45           continue;\r
46 \r
47         if (line.indexOf("JALVIEW_ANNOTATION") > -1)\r
48         {\r
49           jvAnnotationFile = true;\r
50           break;\r
51         }\r
52       }\r
53 \r
54       if(!jvAnnotationFile)\r
55       {\r
56         in.close();\r
57         return false;\r
58       }\r
59 \r
60       while ( (line = in.readLine()) != null)\r
61       {\r
62         if(line.indexOf("#")==0\r
63            || line.indexOf("JALVIEW_ANNOTATION")>-1\r
64            || line.length()==0)\r
65           continue;\r
66 \r
67         st = new StringTokenizer(line, "\t");\r
68         token = st.nextToken();\r
69         if(token.equalsIgnoreCase("COLOUR"))\r
70         {\r
71           colourAnnotations(al, st.nextToken(), st.nextToken());\r
72           continue;\r
73         }\r
74 \r
75         if(token.equalsIgnoreCase("COMBINE") )\r
76         {\r
77           combineAnnotations(al, st);\r
78           continue;\r
79         }\r
80 \r
81         if (token.equalsIgnoreCase("GRAPHLINE"))\r
82         {\r
83           addLine(al, st);\r
84           continue;\r
85         }\r
86 \r
87 \r
88         if(token.equalsIgnoreCase("SEQUENCE_REF") )\r
89         {\r
90           refSeq = al.findName(st.nextToken());\r
91           try{\r
92             refSeqIndex = Integer.parseInt(st.nextToken());\r
93           }\r
94           catch(Exception ex)\r
95           {\r
96             refSeqIndex = 0;\r
97           }\r
98 \r
99           continue;\r
100         }\r
101 \r
102         graphStyle = AlignmentAnnotation.getGraphValueFromString(token);\r
103         label = description = st.nextToken();\r
104 \r
105         line = st.nextToken();\r
106         st = new StringTokenizer(line, "|", true);\r
107         annotations = new Annotation[st.countTokens()+refSeqIndex];\r
108         index = refSeqIndex;\r
109         boolean emptyColumn = true;\r
110         while (st.hasMoreElements())\r
111         {\r
112           token = st.nextToken().trim();\r
113 \r
114           if(token.equals("|"))\r
115           {\r
116             if(emptyColumn)\r
117               annotations[index++] = parseAnnotation("");\r
118 \r
119             emptyColumn = true;\r
120           }\r
121           else\r
122           {\r
123             annotations[index++] = parseAnnotation(token);\r
124             emptyColumn = false;\r
125           }\r
126         }\r
127 \r
128        annotation = new AlignmentAnnotation(label,\r
129                                           description,\r
130                                           annotations,\r
131                                           0,\r
132                                           0,\r
133                                           graphStyle);\r
134 \r
135        annotation = al.addAnnotation(annotation, refSeq);\r
136        al.setAnnotationIndex(annotation,  al.getAlignmentAnnotation().length - existingAnnotations-1);\r
137       }\r
138 \r
139        al.adjustSequenceAnnotations();\r
140 \r
141 \r
142     }catch(Exception ex)\r
143     {\r
144       ex.printStackTrace();\r
145       System.out.println("Problem reading annotation file: "+ex);\r
146       return false;\r
147     }\r
148     return true;\r
149   }\r
150 \r
151   Annotation parseAnnotation(String string)\r
152   {\r
153     String desc = "", displayChar="";\r
154     char ss = ' '; // secondaryStructure\r
155     float value = 0;\r
156     StringTokenizer st = new StringTokenizer(string, ",");\r
157     String token;\r
158     while(st.hasMoreTokens())\r
159     {\r
160       token = st.nextToken().trim();\r
161       if(token.length()==0)\r
162         continue;\r
163 \r
164       if(value==0)\r
165       {  try{\r
166           value =  new Float(token).floatValue();\r
167         }catch(NumberFormatException ex){}\r
168       }\r
169 \r
170       if(token.length()==1)\r
171       {\r
172         // Either this character represents a helix or sheet\r
173         // or an integer which can be displayed\r
174         if(token.equals("H") || token.equals("E"))\r
175         {\r
176           ss = token.charAt(0);\r
177         }\r
178         else //if(value!=0)\r
179         {\r
180           displayChar = token;\r
181         }\r
182       }\r
183       else if(desc.length()<1)\r
184         desc = token;\r
185       else\r
186         displayChar = token;\r
187     }\r
188 \r
189     return new Annotation(displayChar, desc, ss, value);\r
190   }\r
191 \r
192   void colourAnnotations(AlignmentI al, String label, String colour)\r
193   {\r
194     UserColourScheme ucs = new UserColourScheme(colour);\r
195     Annotation[] annotations;\r
196     for(int i=0; i<al.getAlignmentAnnotation().length; i++)\r
197     {\r
198       if(al.getAlignmentAnnotation()[i].label.equalsIgnoreCase(label))\r
199       {\r
200         annotations = al.getAlignmentAnnotation()[i].annotations;\r
201         for(int j=0; j<annotations.length; j++)\r
202         {\r
203           if(annotations[j]!=null)\r
204             annotations[j].colour = ucs.findColour("A");\r
205         }\r
206       }\r
207     }\r
208   }\r
209 \r
210   void combineAnnotations(AlignmentI al, StringTokenizer st)\r
211   {\r
212     int graphGroup = -1;\r
213     String group = st.nextToken();\r
214     //First make sure we are not overwriting the graphIndex\r
215     for(int i=0; i<al.getAlignmentAnnotation().length; i++)\r
216     {\r
217       if(al.getAlignmentAnnotation()[i].label.equalsIgnoreCase(group))\r
218       {\r
219         graphGroup = al.getAlignmentAnnotation()[i].graphGroup +1;\r
220         al.getAlignmentAnnotation()[i].graphGroup = graphGroup;\r
221         break;\r
222       }\r
223     }\r
224 \r
225     //Now update groups\r
226     while(st.hasMoreTokens())\r
227     {\r
228       group = st.nextToken();\r
229       for(int i=0; i<al.getAlignmentAnnotation().length; i++)\r
230       {\r
231         if (al.getAlignmentAnnotation()[i].label.equalsIgnoreCase(group))\r
232         {\r
233           al.getAlignmentAnnotation()[i].graphGroup = graphGroup;\r
234           break;\r
235         }\r
236       }\r
237     }\r
238   }\r
239 \r
240   void addLine(AlignmentI al, StringTokenizer st)\r
241   {\r
242     String group = st.nextToken();\r
243     AlignmentAnnotation annotation = null;\r
244 \r
245     for (int i = 0; i < al.getAlignmentAnnotation().length; i++)\r
246     {\r
247       if (al.getAlignmentAnnotation()[i].label.equalsIgnoreCase(group))\r
248       {\r
249         annotation = al.getAlignmentAnnotation()[i];\r
250         break;\r
251       }\r
252     }\r
253 \r
254     if(annotation==null)\r
255       return;\r
256     float value = new Float(st.nextToken()).floatValue();\r
257     String label = st.hasMoreTokens() ?  st.nextToken() : null;\r
258     java.awt.Color colour = null;\r
259     if(st.hasMoreTokens())\r
260     {\r
261       UserColourScheme ucs = new UserColourScheme(st.nextToken());\r
262       colour = ucs.findColour("A");\r
263     }\r
264 \r
265     annotation.addGraphLine(new GraphLine(value, label, colour));\r
266 \r
267   }\r
268 }\r