Check for all gapped seqs
[jalview.git] / src / jalview / io / AnnotationFile.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4  *\r
5  * This program is free software; you can redistribute it and/or\r
6  * modify it under the terms of the GNU General Public License\r
7  * as published by the Free Software Foundation; either version 2\r
8  * of the License, or (at your option) any later version.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  * You should have received a copy of the GNU General Public License\r
16  * along with this program; if not, write to the Free Software\r
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18  */\r
19 \r
20 package jalview.io;\r
21 \r
22 import java.io.*;\r
23 import jalview.datamodel.*;\r
24 import java.util.*;\r
25 import jalview.schemes.UserColourScheme;\r
26 import java.net.URL;\r
27 \r
28 \r
29 public class AnnotationFile\r
30 {\r
31 \r
32   public String printAnnotations(AlignmentAnnotation [] annotations)\r
33   {\r
34     StringBuffer text = new StringBuffer(\r
35       "JALVIEW_ANNOTATION\n"\r
36       +"# Created: "\r
37       +new java.util.Date()+"\n\n");\r
38 \r
39     AlignmentAnnotation row;\r
40     String comma;\r
41     String seqref = null;\r
42 \r
43     StringBuffer colours = new StringBuffer();\r
44     StringBuffer graphLine = new StringBuffer();\r
45 \r
46     Hashtable graphGroup = new Hashtable();\r
47 \r
48     java.awt.Color color;\r
49 \r
50     for(int i=0; i<annotations.length; i++)\r
51     {\r
52       row = annotations[i];\r
53       color = null;\r
54 \r
55       if( row.sequenceRef == null)\r
56         seqref = null;\r
57 \r
58       else if (seqref == null\r
59            || !seqref.equals(row.sequenceRef.getName()))\r
60       {\r
61         seqref = row.sequenceRef.getName();\r
62         text.append("\nSEQUENCE_REF\t" + seqref + "\n");\r
63       }\r
64 \r
65 \r
66       if( row.graph == AlignmentAnnotation.NO_GRAPH)\r
67       {\r
68           text.append("NO_GRAPH\t");\r
69       }\r
70       else\r
71       {\r
72         if( row.graph == AlignmentAnnotation.BAR_GRAPH)\r
73           text.append("BAR_GRAPH\t");\r
74         else if(row.graph == AlignmentAnnotation.LINE_GRAPH)\r
75           text.append("LINE_GRAPH\t");\r
76 \r
77         if(row.getThreshold()!=null)\r
78             graphLine.append("GRAPHLINE\t"\r
79                              + row.label + "\t"\r
80                              + row.getThreshold().value + "\t"\r
81                              + row.getThreshold().label + "\t"\r
82                              + jalview.util.Format.getHexString(\r
83                                  row.getThreshold().colour)+"\n"\r
84                 );\r
85 \r
86           if(row.graphGroup>-1)\r
87           {\r
88             String key = String.valueOf(row.graphGroup);\r
89             if(graphGroup.containsKey(key))\r
90               graphGroup.put(key, graphGroup.get(key)\r
91                              +"\t"+row.label);\r
92             else\r
93               graphGroup.put(key, row.label);\r
94           }\r
95       }\r
96 \r
97       text.append(row.label+"\t");\r
98 \r
99       for(int j=0; j<row.annotations.length; j++)\r
100       {\r
101         if(row.annotations[j]!=null)\r
102         {\r
103           comma = "";\r
104           if (row.annotations[j].displayCharacter.length() > 0\r
105               && !row.annotations[j].displayCharacter.equals(" "))\r
106           {\r
107             text.append(row.annotations[j].displayCharacter);\r
108             comma = ",";\r
109           }\r
110           if (row.annotations[j].secondaryStructure!=' ')\r
111           {\r
112             text.append(comma + row.annotations[j].secondaryStructure);\r
113             comma = ",";\r
114           }\r
115           if (row.annotations[j].value!=0f)\r
116           {\r
117             color = row.annotations[j].colour;\r
118             text.append(comma + row.annotations[j].value);\r
119           }\r
120         }\r
121         text.append("|");\r
122       }\r
123 \r
124       text.append("\n");\r
125 \r
126       if(color!=null && color!=java.awt.Color.black)\r
127       {\r
128         colours.append("COLOUR\t"\r
129                        +row.label+"\t"\r
130                        +jalview.util.Format.getHexString(color)+"\n");\r
131       }\r
132 \r
133     }\r
134 \r
135     text.append("\n");\r
136 \r
137     text.append(colours.toString());\r
138     text.append(graphLine.toString());\r
139     if(graphGroup.size()>0)\r
140     {\r
141       text.append("COMBINE\t");\r
142       Enumeration en = graphGroup.elements();\r
143       while(en.hasMoreElements())\r
144       {\r
145         text.append(en.nextElement()+"\n");\r
146       }\r
147     }\r
148 \r
149     return text.toString();\r
150   }\r
151 \r
152   public boolean readAnnotationFile(AlignmentI al, String file)\r
153   {\r
154     try\r
155     {\r
156       BufferedReader in = null;\r
157       java.io.InputStream is = getClass().getResourceAsStream("/" + file);\r
158       if (is != null)\r
159       {\r
160         in = new BufferedReader(new java.io.InputStreamReader(is));\r
161       }\r
162       else\r
163       {\r
164         try\r
165         {\r
166           URL url = new URL(file);\r
167           in = new BufferedReader(new InputStreamReader(url.openStream()));\r
168         }\r
169         catch (java.net.MalformedURLException ex)\r
170         {\r
171           in = new BufferedReader(new FileReader(file));\r
172         }\r
173       }\r
174 \r
175       String line, label, description, token;\r
176       int graphStyle, index;\r
177       SequenceI refSeq = null;\r
178       int refSeqIndex = 1;\r
179       int existingAnnotations = 0;\r
180       if(al.getAlignmentAnnotation()!=null)\r
181        existingAnnotations = al.getAlignmentAnnotation().length;\r
182 \r
183       int alWidth = al.getWidth();\r
184 \r
185       StringTokenizer st;\r
186       Annotation[] annotations;\r
187       AlignmentAnnotation annotation = null;\r
188 \r
189       // First confirm this is an Annotation file\r
190       boolean jvAnnotationFile = false;\r
191       while ( (line = in.readLine()) != null)\r
192       {\r
193         if (line.indexOf("#") == 0 )\r
194           continue;\r
195 \r
196         if (line.indexOf("JALVIEW_ANNOTATION") > -1)\r
197         {\r
198           jvAnnotationFile = true;\r
199           break;\r
200         }\r
201       }\r
202 \r
203       if(!jvAnnotationFile)\r
204       {\r
205         in.close();\r
206         return false;\r
207       }\r
208 \r
209       while ( (line = in.readLine()) != null)\r
210       {\r
211         if(line.indexOf("#")==0\r
212            || line.indexOf("JALVIEW_ANNOTATION")>-1\r
213            || line.length()==0)\r
214           continue;\r
215 \r
216         st = new StringTokenizer(line, "\t");\r
217         token = st.nextToken();\r
218         if(token.equalsIgnoreCase("COLOUR"))\r
219         {\r
220           colourAnnotations(al, st.nextToken(), st.nextToken());\r
221           continue;\r
222         }\r
223 \r
224         if(token.equalsIgnoreCase("COMBINE") )\r
225         {\r
226           combineAnnotations(al, st);\r
227           continue;\r
228         }\r
229 \r
230         if (token.equalsIgnoreCase("GRAPHLINE"))\r
231         {\r
232           addLine(al, st);\r
233           continue;\r
234         }\r
235 \r
236 \r
237         if(token.equalsIgnoreCase("SEQUENCE_REF") )\r
238         {\r
239           refSeq = al.findName(st.nextToken());\r
240           try{\r
241             refSeqIndex = Integer.parseInt(st.nextToken());\r
242           }\r
243           catch(Exception ex)\r
244           {\r
245             refSeqIndex = 1;\r
246           }\r
247 \r
248           continue;\r
249         }\r
250 \r
251 \r
252         graphStyle = AlignmentAnnotation.getGraphValueFromString(token);\r
253         label = description = st.nextToken();\r
254 \r
255         line = st.nextToken();\r
256 \r
257         st = new StringTokenizer(line, "|", true);\r
258         annotations = new Annotation[alWidth];\r
259 \r
260         index = 0;\r
261         boolean emptyColumn = true;\r
262 \r
263 \r
264         while (st.hasMoreElements() && index<alWidth)\r
265         {\r
266           token = st.nextToken().trim();\r
267           if(token.equals("|"))\r
268           {\r
269             if(emptyColumn)\r
270               index++;\r
271 \r
272             emptyColumn = true;\r
273           }\r
274           else\r
275           {\r
276             annotations[index++] = parseAnnotation(token);\r
277             emptyColumn = false;\r
278           }\r
279         }\r
280 \r
281        annotation = new AlignmentAnnotation(label,\r
282                                           description,\r
283                                           annotations,\r
284                                           0,\r
285                                           0,\r
286                                           graphStyle);\r
287 \r
288        if(refSeq!=null)\r
289        {\r
290          annotation.createSequenceMapping(refSeq, refSeqIndex);\r
291          refSeq.addAlignmentAnnotation(annotation);\r
292        }\r
293 \r
294        al.addAnnotation(annotation);\r
295 \r
296        al.setAnnotationIndex(annotation,  al.getAlignmentAnnotation().length - existingAnnotations-1);\r
297       }\r
298 \r
299     }catch(Exception ex)\r
300     {\r
301       ex.printStackTrace();\r
302       System.out.println("Problem reading annotation file: "+ex);\r
303       return false;\r
304     }\r
305     return true;\r
306   }\r
307 \r
308   Annotation parseAnnotation(String string)\r
309   {\r
310     String desc = "", displayChar="";\r
311     char ss = ' '; // secondaryStructure\r
312     float value = 0;\r
313     boolean parsedValue = false;\r
314     StringTokenizer st = new StringTokenizer(string, ",");\r
315     String token;\r
316     while(st.hasMoreTokens())\r
317     {\r
318       token = st.nextToken().trim();\r
319       if(token.length()==0)\r
320         continue;\r
321 \r
322       if(!parsedValue)\r
323       {\r
324         try{\r
325           displayChar = token;\r
326           value = new Float(token).floatValue();\r
327           parsedValue = true;\r
328         }catch(NumberFormatException ex){}\r
329       }\r
330 \r
331       if(token.equals("H") || token.equals("E"))\r
332       {\r
333         // Either this character represents a helix or sheet\r
334         // or an integer which can be displayed\r
335         ss = token.charAt(0);\r
336         if(displayChar.equals(token.substring(0,1)))\r
337           displayChar = "";\r
338       }\r
339       else if(desc.length()<1)\r
340         desc = token;\r
341 \r
342     }\r
343 \r
344     return new Annotation(displayChar, desc, ss, value);\r
345   }\r
346 \r
347   void colourAnnotations(AlignmentI al, String label, String colour)\r
348   {\r
349     UserColourScheme ucs = new UserColourScheme(colour);\r
350     Annotation[] annotations;\r
351     for(int i=0; i<al.getAlignmentAnnotation().length; i++)\r
352     {\r
353       if(al.getAlignmentAnnotation()[i].label.equalsIgnoreCase(label))\r
354       {\r
355         annotations = al.getAlignmentAnnotation()[i].annotations;\r
356         for(int j=0; j<annotations.length; j++)\r
357         {\r
358           if(annotations[j]!=null)\r
359             annotations[j].colour = ucs.findColour("A");\r
360         }\r
361       }\r
362     }\r
363   }\r
364 \r
365   void combineAnnotations(AlignmentI al, StringTokenizer st)\r
366   {\r
367     int graphGroup = -1;\r
368     String group = st.nextToken();\r
369     //First make sure we are not overwriting the graphIndex\r
370     for(int i=0; i<al.getAlignmentAnnotation().length; i++)\r
371     {\r
372       if(al.getAlignmentAnnotation()[i].label.equalsIgnoreCase(group))\r
373       {\r
374         graphGroup = al.getAlignmentAnnotation()[i].graphGroup +1;\r
375         al.getAlignmentAnnotation()[i].graphGroup = graphGroup;\r
376         break;\r
377       }\r
378     }\r
379 \r
380     //Now update groups\r
381     while(st.hasMoreTokens())\r
382     {\r
383       group = st.nextToken();\r
384       for(int i=0; i<al.getAlignmentAnnotation().length; i++)\r
385       {\r
386         if (al.getAlignmentAnnotation()[i].label.equalsIgnoreCase(group))\r
387         {\r
388           al.getAlignmentAnnotation()[i].graphGroup = graphGroup;\r
389           break;\r
390         }\r
391       }\r
392     }\r
393   }\r
394 \r
395   void addLine(AlignmentI al, StringTokenizer st)\r
396   {\r
397     String group = st.nextToken();\r
398     AlignmentAnnotation annotation = null;\r
399 \r
400     for (int i = 0; i < al.getAlignmentAnnotation().length; i++)\r
401     {\r
402       if (al.getAlignmentAnnotation()[i].label.equalsIgnoreCase(group))\r
403       {\r
404         annotation = al.getAlignmentAnnotation()[i];\r
405         break;\r
406       }\r
407     }\r
408 \r
409     if(annotation==null)\r
410       return;\r
411     float value = new Float(st.nextToken()).floatValue();\r
412     String label = st.hasMoreTokens() ?  st.nextToken() : null;\r
413     java.awt.Color colour = null;\r
414     if(st.hasMoreTokens())\r
415     {\r
416       UserColourScheme ucs = new UserColourScheme(st.nextToken());\r
417       colour = ucs.findColour("A");\r
418     }\r
419 \r
420     annotation.setThreshold(new GraphLine(value, label, colour));\r
421 \r
422   }\r
423 }\r