set sequence_ref alignment
[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     SequenceI 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       {\r
57         if(seqref!=null)\r
58           text.append("\nSEQUENCE_REF\tALIGNMENT\n");\r
59 \r
60         seqref = null;\r
61       }\r
62 \r
63       else if (seqref == null || seqref != row.sequenceRef)\r
64       {\r
65         seqref = row.sequenceRef;\r
66         text.append("\nSEQUENCE_REF\t" + seqref.getName() + "\n");\r
67       }\r
68 \r
69 \r
70       if( row.graph == AlignmentAnnotation.NO_GRAPH)\r
71       {\r
72           text.append("NO_GRAPH\t");\r
73       }\r
74       else\r
75       {\r
76         if( row.graph == AlignmentAnnotation.BAR_GRAPH)\r
77           text.append("BAR_GRAPH\t");\r
78         else if(row.graph == AlignmentAnnotation.LINE_GRAPH)\r
79           text.append("LINE_GRAPH\t");\r
80 \r
81         if(row.getThreshold()!=null)\r
82             graphLine.append("GRAPHLINE\t"\r
83                              + row.label + "\t"\r
84                              + row.getThreshold().value + "\t"\r
85                              + row.getThreshold().label + "\t"\r
86                              + jalview.util.Format.getHexString(\r
87                                  row.getThreshold().colour)+"\n"\r
88                 );\r
89 \r
90           if(row.graphGroup>-1)\r
91           {\r
92             String key = String.valueOf(row.graphGroup);\r
93             if(graphGroup.containsKey(key))\r
94               graphGroup.put(key, graphGroup.get(key)\r
95                              +"\t"+row.label);\r
96             else\r
97               graphGroup.put(key, row.label);\r
98           }\r
99       }\r
100 \r
101       text.append(row.label+"\t");\r
102 \r
103       for(int j=0; j<row.annotations.length; j++)\r
104       {\r
105         if (seqref != null && jalview.util.Comparison.isGap(seqref.getCharAt(j)))\r
106           continue;\r
107 \r
108         if(row.annotations[j]!=null)\r
109         {\r
110           comma = "";\r
111           if (row.annotations[j].secondaryStructure!=' ')\r
112           {\r
113             text.append(comma + row.annotations[j].secondaryStructure);\r
114             comma = ",";\r
115           }\r
116           if (row.annotations[j].displayCharacter.length() > 0\r
117                   && !row.annotations[j].displayCharacter.equals(" "))\r
118               {\r
119                 text.append(comma + row.annotations[j].displayCharacter);\r
120                 comma = ",";\r
121               }\r
122 \r
123           if (row.annotations[j]!=null)\r
124           {\r
125             color = row.annotations[j].colour;\r
126             if (row.annotations[j].value!=0f)\r
127               text.append(comma + row.annotations[j].value);\r
128           }\r
129         }\r
130         text.append("|");\r
131       }\r
132 \r
133       text.append("\n");\r
134 \r
135       if(color!=null && color!=java.awt.Color.black)\r
136       {\r
137         colours.append("COLOUR\t"\r
138                        +row.label+"\t"\r
139                        +jalview.util.Format.getHexString(color)+"\n");\r
140       }\r
141 \r
142     }\r
143 \r
144     text.append("\n");\r
145 \r
146     text.append(colours.toString());\r
147     text.append(graphLine.toString());\r
148     if(graphGroup.size()>0)\r
149     {\r
150       text.append("COMBINE\t");\r
151       Enumeration en = graphGroup.elements();\r
152       while(en.hasMoreElements())\r
153       {\r
154         text.append(en.nextElement()+"\n");\r
155       }\r
156     }\r
157 \r
158     return text.toString();\r
159   }\r
160 \r
161   public boolean readAnnotationFile(AlignmentI al, String file)\r
162   {\r
163     try\r
164     {\r
165       BufferedReader in = null;\r
166       java.io.InputStream is = getClass().getResourceAsStream("/" + file);\r
167       if (is != null)\r
168       {\r
169         in = new BufferedReader(new java.io.InputStreamReader(is));\r
170       }\r
171       else\r
172       {\r
173         try\r
174         {\r
175           URL url = new URL(file);\r
176           in = new BufferedReader(new InputStreamReader(url.openStream()));\r
177         }\r
178         catch (java.net.MalformedURLException ex)\r
179         {\r
180           in = new BufferedReader(new FileReader(file));\r
181         }\r
182       }\r
183 \r
184       String line, label, description, token;\r
185       int graphStyle, index;\r
186       SequenceI refSeq = null;\r
187       int refSeqIndex = 1;\r
188       int existingAnnotations = 0;\r
189       if(al.getAlignmentAnnotation()!=null)\r
190        existingAnnotations = al.getAlignmentAnnotation().length;\r
191 \r
192       int alWidth = al.getWidth();\r
193 \r
194       StringTokenizer st;\r
195       Annotation[] annotations;\r
196       AlignmentAnnotation annotation = null;\r
197 \r
198       // First confirm this is an Annotation file\r
199       boolean jvAnnotationFile = false;\r
200       while ( (line = in.readLine()) != null)\r
201       {\r
202         if (line.indexOf("#") == 0 )\r
203           continue;\r
204 \r
205         if (line.indexOf("JALVIEW_ANNOTATION") > -1)\r
206         {\r
207           jvAnnotationFile = true;\r
208           break;\r
209         }\r
210       }\r
211 \r
212       if(!jvAnnotationFile)\r
213       {\r
214         in.close();\r
215         return false;\r
216       }\r
217 \r
218       while ( (line = in.readLine()) != null)\r
219       {\r
220         if(line.indexOf("#")==0\r
221            || line.indexOf("JALVIEW_ANNOTATION")>-1\r
222            || line.length()==0)\r
223           continue;\r
224 \r
225         st = new StringTokenizer(line, "\t");\r
226         token = st.nextToken();\r
227         if(token.equalsIgnoreCase("COLOUR"))\r
228         {\r
229           colourAnnotations(al, st.nextToken(), st.nextToken());\r
230           continue;\r
231         }\r
232 \r
233         if(token.equalsIgnoreCase("COMBINE") )\r
234         {\r
235           combineAnnotations(al, st);\r
236           continue;\r
237         }\r
238 \r
239         if (token.equalsIgnoreCase("GRAPHLINE"))\r
240         {\r
241           addLine(al, st);\r
242           continue;\r
243         }\r
244 \r
245 \r
246         if(token.equalsIgnoreCase("SEQUENCE_REF") )\r
247         {\r
248           refSeq = al.findName(st.nextToken());\r
249           try{\r
250             refSeqIndex = Integer.parseInt(st.nextToken());\r
251             if(refSeqIndex<1)\r
252             {\r
253               refSeqIndex = 1;\r
254               System.out.println("WARNING: SEQUENCE_REF index must be > 0 in AnnotationFile");\r
255             }\r
256           }\r
257           catch(Exception ex)\r
258           {\r
259             refSeqIndex = 1;\r
260           }\r
261 \r
262           continue;\r
263         }\r
264 \r
265 \r
266         graphStyle = AlignmentAnnotation.getGraphValueFromString(token);\r
267         label = description = st.nextToken();\r
268 \r
269         line = st.nextToken();\r
270 \r
271         st = new StringTokenizer(line, "|", true);\r
272         annotations = new Annotation[alWidth];\r
273 \r
274         index = 0;\r
275         boolean emptyColumn = true;\r
276 \r
277 \r
278         while (st.hasMoreElements() && index<alWidth)\r
279         {\r
280           token = st.nextToken().trim();\r
281           if(token.equals("|"))\r
282           {\r
283             if(emptyColumn)\r
284               index++;\r
285 \r
286             emptyColumn = true;\r
287           }\r
288           else\r
289           {\r
290             annotations[index++] = parseAnnotation(token);\r
291             emptyColumn = false;\r
292           }\r
293         }\r
294 \r
295        annotation = new AlignmentAnnotation(label,\r
296                                           description,\r
297                                           annotations,\r
298                                           0,\r
299                                           0,\r
300                                           graphStyle);\r
301 \r
302        if(refSeq!=null)\r
303        {\r
304          annotation.createSequenceMapping(refSeq, refSeqIndex, false);\r
305          refSeq.addAlignmentAnnotation(annotation);\r
306        }\r
307 \r
308        al.addAnnotation(annotation);\r
309 \r
310        al.setAnnotationIndex(annotation,  al.getAlignmentAnnotation().length - existingAnnotations-1);\r
311       }\r
312 \r
313     }catch(Exception ex)\r
314     {\r
315       ex.printStackTrace();\r
316       System.out.println("Problem reading annotation file: "+ex);\r
317       return false;\r
318     }\r
319     return true;\r
320   }\r
321 \r
322   Annotation parseAnnotation(String string)\r
323   {\r
324     String desc = null, displayChar="";\r
325     char ss = ' '; // secondaryStructure\r
326     float value = 0;\r
327     boolean parsedValue = false;\r
328     StringTokenizer st = new StringTokenizer(string, ",");\r
329     String token;\r
330     while(st.hasMoreTokens())\r
331     {\r
332       token = st.nextToken().trim();\r
333       if(token.length()==0)\r
334         continue;\r
335 \r
336       if(!parsedValue)\r
337       {\r
338         try{\r
339           displayChar = token;\r
340           value = new Float(token).floatValue();\r
341           parsedValue = true;\r
342           continue;\r
343         }catch(NumberFormatException ex){}\r
344       }\r
345 \r
346       if(token.equals("H") || token.equals("E"))\r
347       {\r
348         // Either this character represents a helix or sheet\r
349         // or an integer which can be displayed\r
350         ss = token.charAt(0);\r
351         if(displayChar.equals(token.substring(0,1)))\r
352           displayChar = "";\r
353       }\r
354       else if(desc==null)\r
355         desc = token;\r
356 \r
357     }\r
358 \r
359     if(desc == null)\r
360       desc = value+"";\r
361 \r
362     if(displayChar.length()>1 && desc.length()==1)\r
363     {\r
364       String tmp = displayChar;\r
365       displayChar = desc;\r
366       desc = tmp;\r
367     }\r
368 \r
369     return new Annotation(displayChar, desc, ss, value);\r
370   }\r
371 \r
372   void colourAnnotations(AlignmentI al, String label, String colour)\r
373   {\r
374     UserColourScheme ucs = new UserColourScheme(colour);\r
375     Annotation[] annotations;\r
376     for(int i=0; i<al.getAlignmentAnnotation().length; i++)\r
377     {\r
378       if(al.getAlignmentAnnotation()[i].label.equalsIgnoreCase(label))\r
379       {\r
380         annotations = al.getAlignmentAnnotation()[i].annotations;\r
381         for(int j=0; j<annotations.length; j++)\r
382         {\r
383           if(annotations[j]!=null)\r
384             annotations[j].colour = ucs.findColour('A');\r
385         }\r
386       }\r
387     }\r
388   }\r
389 \r
390   void combineAnnotations(AlignmentI al, StringTokenizer st)\r
391   {\r
392     int graphGroup = -1;\r
393     String group = st.nextToken();\r
394     //First make sure we are not overwriting the graphIndex\r
395     for(int i=0; i<al.getAlignmentAnnotation().length; i++)\r
396     {\r
397       if(al.getAlignmentAnnotation()[i].label.equalsIgnoreCase(group))\r
398       {\r
399         graphGroup = al.getAlignmentAnnotation()[i].graphGroup +1;\r
400         al.getAlignmentAnnotation()[i].graphGroup = graphGroup;\r
401         break;\r
402       }\r
403     }\r
404 \r
405     //Now update groups\r
406     while(st.hasMoreTokens())\r
407     {\r
408       group = st.nextToken();\r
409       for(int i=0; i<al.getAlignmentAnnotation().length; i++)\r
410       {\r
411         if (al.getAlignmentAnnotation()[i].label.equalsIgnoreCase(group))\r
412         {\r
413           al.getAlignmentAnnotation()[i].graphGroup = graphGroup;\r
414           break;\r
415         }\r
416       }\r
417     }\r
418   }\r
419 \r
420   void addLine(AlignmentI al, StringTokenizer st)\r
421   {\r
422     String group = st.nextToken();\r
423     AlignmentAnnotation annotation = null;\r
424 \r
425     for (int i = 0; i < al.getAlignmentAnnotation().length; i++)\r
426     {\r
427       if (al.getAlignmentAnnotation()[i].label.equalsIgnoreCase(group))\r
428       {\r
429         annotation = al.getAlignmentAnnotation()[i];\r
430         break;\r
431       }\r
432     }\r
433 \r
434     if(annotation==null)\r
435       return;\r
436     float value = new Float(st.nextToken()).floatValue();\r
437     String label = st.hasMoreTokens() ?  st.nextToken() : null;\r
438     java.awt.Color colour = null;\r
439     if(st.hasMoreTokens())\r
440     {\r
441       UserColourScheme ucs = new UserColourScheme(st.nextToken());\r
442       colour = ucs.findColour('A');\r
443     }\r
444 \r
445     annotation.setThreshold(new GraphLine(value, label, colour));\r
446 \r
447   }\r
448 }\r