beginnings of view definition capability for annotations file
[jalview.git] / src / jalview / io / AnnotationFile.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2007 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 java.net.*;\r
24 import java.util.*;\r
25 \r
26 import jalview.analysis.*;\r
27 import jalview.datamodel.*;\r
28 import jalview.schemes.*;\r
29 \r
30 public class AnnotationFile\r
31 {\r
32   StringBuffer text = new StringBuffer(\r
33       "JALVIEW_ANNOTATION\n"\r
34       + "# Created: "\r
35       + new java.util.Date() + "\n\n");\r
36   /**\r
37    * convenience method for pre-2.4 feature files which have no view, hidden columns or hidden row keywords.\r
38    * @param annotations\r
39    * @param groups\r
40    * @param properties\r
41    * @return feature file as a string.\r
42    */\r
43   public String printAnnotations(AlignmentAnnotation[] annotations,\r
44                                  Vector groups,\r
45                                  Hashtable properties)\r
46   {\r
47     return printAnnotations(annotations, groups,\r
48             properties, null);\r
49 \r
50   }\r
51   /**\r
52    * hold all the information about a particular view definition\r
53    * read from or written out in an annotations file.\r
54    */\r
55   public class ViewDef {\r
56     public String viewname;\r
57     public HiddenSequences hidseqs;\r
58     public ColumnSelection hiddencols;\r
59     public Vector visibleGroups;\r
60     public ViewDef(String viewname, HiddenSequences hidseqs,\r
61             ColumnSelection hiddencols)\r
62     {\r
63       this.viewname = viewname;\r
64       this.hidseqs = hidseqs;\r
65       this.hiddencols = hiddencols;\r
66     }\r
67   }\r
68   public String printAnnotations(AlignmentAnnotation[] annotations,\r
69           Vector groups,\r
70           Hashtable properties, ViewDef[] views)\r
71   {\r
72     if (annotations != null)\r
73     {\r
74       boolean oneColour = true;\r
75       AlignmentAnnotation row;\r
76       String comma;\r
77       SequenceI refSeq = null;\r
78 \r
79       StringBuffer colours = new StringBuffer();\r
80       StringBuffer graphLine = new StringBuffer();\r
81 \r
82       Hashtable graphGroup = new Hashtable();\r
83 \r
84       java.awt.Color color;\r
85 \r
86       for (int i = 0; i < annotations.length; i++)\r
87       {\r
88         row = annotations[i];\r
89 \r
90         if (!row.visible && !row.hasScore())\r
91         {\r
92           continue;\r
93         }\r
94 \r
95         color = null;\r
96         oneColour = true;\r
97 \r
98         if (row.sequenceRef == null)\r
99         {\r
100           if (refSeq != null)\r
101           {\r
102             text.append("\nSEQUENCE_REF\tALIGNMENT\n");\r
103           }\r
104 \r
105           refSeq = null;\r
106         }\r
107 \r
108         else if (refSeq == null || refSeq != row.sequenceRef)\r
109         {\r
110           refSeq = row.sequenceRef;\r
111           text.append("\nSEQUENCE_REF\t" + refSeq.getName() + "\n");\r
112         }\r
113 \r
114         if (row.graph == AlignmentAnnotation.NO_GRAPH)\r
115         {\r
116           text.append("NO_GRAPH\t");\r
117         }\r
118         else\r
119         {\r
120           if (row.graph == AlignmentAnnotation.BAR_GRAPH)\r
121           {\r
122             text.append("BAR_GRAPH\t");\r
123           }\r
124           else if (row.graph == AlignmentAnnotation.LINE_GRAPH)\r
125           {\r
126             text.append("LINE_GRAPH\t");\r
127           }\r
128 \r
129           if (row.getThreshold() != null)\r
130           {\r
131             graphLine.append("GRAPHLINE\t"\r
132                              + row.label + "\t"\r
133                              + row.getThreshold().value + "\t"\r
134                              + row.getThreshold().label + "\t"\r
135                              + jalview.util.Format.getHexString(\r
136                                  row.getThreshold().colour) + "\n"\r
137                 );\r
138           }\r
139 \r
140           if (row.graphGroup > -1)\r
141           {\r
142             String key = String.valueOf(row.graphGroup);\r
143             if (graphGroup.containsKey(key))\r
144             {\r
145               graphGroup.put(key, graphGroup.get(key)\r
146                              + "\t" + row.label);\r
147             }\r
148             else\r
149             {\r
150               graphGroup.put(key, row.label);\r
151             }\r
152           }\r
153         }\r
154 \r
155         text.append(row.label + "\t");\r
156         if (row.description != null)\r
157         {\r
158           text.append(row.description + "\t");\r
159         }\r
160 \r
161         for (int j = 0; row.annotations!=null && j < row.annotations.length; j++)\r
162         {\r
163           if (refSeq != null &&\r
164               jalview.util.Comparison.isGap(refSeq.getCharAt(j)))\r
165           {\r
166             continue;\r
167           }\r
168 \r
169           if (row.annotations[j] != null)\r
170           {\r
171             comma = "";\r
172             if (row.annotations[j].secondaryStructure != ' ')\r
173             {\r
174               text.append(comma + row.annotations[j].secondaryStructure);\r
175               comma = ",";\r
176             }\r
177             if (row.annotations[j].displayCharacter!=null\r
178                 && row.annotations[j].displayCharacter.length() > 0\r
179                 && !row.annotations[j].displayCharacter.equals(" "))\r
180             {\r
181               text.append(comma + row.annotations[j].displayCharacter);\r
182               comma = ",";\r
183             }\r
184 \r
185             if (row.annotations[j] != null)\r
186             {\r
187               if(color!=null && !color.equals(row.annotations[j].colour))\r
188               {\r
189                 oneColour = false;\r
190               }\r
191 \r
192               color = row.annotations[j].colour;\r
193               if (row.annotations[j].value != 0f)\r
194               {\r
195                 text.append(comma + row.annotations[j].value);\r
196               }\r
197             }\r
198 \r
199             if(row.annotations[j].colour!=null\r
200                && row.annotations[j].colour!=java.awt.Color.black)\r
201             {\r
202               text.append(comma+"["+\r
203                           jalview.util.Format.getHexString(\r
204                           row.annotations[j].colour)+"]");\r
205             }\r
206           }\r
207           text.append("|");\r
208         }\r
209 \r
210         if(row.hasScore())\r
211           text.append("\t"+row.score);\r
212 \r
213         text.append("\n");\r
214 \r
215         if (color != null && color != java.awt.Color.black && oneColour)\r
216         {\r
217           colours.append("COLOUR\t"\r
218                          + row.label + "\t"\r
219                          + jalview.util.Format.getHexString(color) + "\n");\r
220         }\r
221 \r
222       }\r
223 \r
224       text.append("\n");\r
225 \r
226       text.append(colours.toString());\r
227       text.append(graphLine.toString());\r
228       if (graphGroup.size() > 0)\r
229       {\r
230         text.append("COMBINE\t");\r
231         Enumeration en = graphGroup.elements();\r
232         while (en.hasMoreElements())\r
233         {\r
234           text.append(en.nextElement() + "\n");\r
235         }\r
236       }\r
237     }\r
238 \r
239     if (groups != null)\r
240     {\r
241       printGroups(groups);\r
242     }\r
243 \r
244     if(properties!=null)\r
245     {\r
246       text.append("\n\nALIGNMENT");\r
247       Enumeration en = properties.keys();\r
248       while(en.hasMoreElements())\r
249       {\r
250         String key = en.nextElement().toString();\r
251         text.append("\t"+key+"="+properties.get(key));\r
252       }\r
253 \r
254     }\r
255     \r
256     return text.toString();\r
257   }\r
258 \r
259   public void printGroups(Vector sequenceGroups)\r
260   {\r
261     SequenceGroup sg;\r
262     for (int i = 0; i < sequenceGroups.size(); i++)\r
263     {\r
264       sg = (SequenceGroup) sequenceGroups.elementAt(i);\r
265       text.append("SEQUENCE_GROUP\t"\r
266                   + sg.getName() + "\t"\r
267                   + (sg.getStartRes() + 1) + "\t"\r
268                   + (sg.getEndRes() + 1) + "\t" + "-1\t");\r
269       for (int s = 0; s < sg.getSize(); s++)\r
270       {\r
271         text.append(sg.getSequenceAt(s).getName() + "\t");\r
272       }\r
273 \r
274       text.append("\nPROPERTIES\t" + sg.getName() + "\t");\r
275 \r
276       if (sg.getDescription() != null)\r
277       {\r
278         text.append("description=" + sg.getDescription() + "\t");\r
279       }\r
280       if (sg.cs != null)\r
281       {\r
282         text.append("colour=" + ColourSchemeProperty.getColourName(sg.cs) +\r
283                     "\t");\r
284         if (sg.cs.getThreshold() != 0)\r
285         {\r
286           text.append("pidThreshold=" + sg.cs.getThreshold());\r
287         }\r
288         if (sg.cs.conservationApplied())\r
289         {\r
290           text.append("consThreshold=" + sg.cs.getConservationInc() + "\t");\r
291         }\r
292       }\r
293       text.append("outlineColour=" +\r
294                   jalview.util.Format.getHexString(sg.getOutlineColour()) +\r
295                   "\t");\r
296 \r
297       text.append("displayBoxes=" + sg.getDisplayBoxes() + "\t");\r
298       text.append("displayText=" + sg.getDisplayText() + "\t");\r
299       text.append("colourText=" + sg.getColourText() + "\t");\r
300 \r
301       if (sg.textColour != java.awt.Color.black)\r
302       {\r
303         text.append("textCol1=" +\r
304                     jalview.util.Format.getHexString(sg.textColour) + "\t");\r
305       }\r
306       if (sg.textColour2 != java.awt.Color.white)\r
307       {\r
308         text.append("textCol2=" +\r
309                     jalview.util.Format.getHexString(sg.textColour2) + "\t");\r
310       }\r
311       if (sg.thresholdTextColour != 0)\r
312       {\r
313         text.append("textColThreshold=" + sg.thresholdTextColour);\r
314       }\r
315 \r
316       text.append("\n\n");\r
317 \r
318     }\r
319   }\r
320 \r
321   SequenceI refSeq = null;\r
322   public boolean readAnnotationFile(AlignmentI al,\r
323                                     String file,\r
324                                     String protocol)\r
325   {\r
326     try\r
327     {\r
328       BufferedReader in = null;\r
329       if (protocol.equals(AppletFormatAdapter.FILE))\r
330       {\r
331         in = new BufferedReader(new FileReader(file));\r
332       }\r
333       else if (protocol.equals(AppletFormatAdapter.URL))\r
334       {\r
335         URL url = new URL(file);\r
336         in = new BufferedReader(new InputStreamReader(url.openStream()));\r
337       }\r
338       else if (protocol.equals(AppletFormatAdapter.PASTE))\r
339       {\r
340         in = new BufferedReader(new StringReader(file));\r
341       }\r
342       else if (protocol.equals(AppletFormatAdapter.CLASSLOADER))\r
343       {\r
344         java.io.InputStream is = getClass().getResourceAsStream("/" + file);\r
345         if (is != null)\r
346         {\r
347           in = new BufferedReader(new java.io.InputStreamReader(is));\r
348         }\r
349       }\r
350 \r
351       String line, label, description, token;\r
352       int graphStyle, index;\r
353       int refSeqIndex = 1;\r
354       int existingAnnotations = 0;\r
355       if (al.getAlignmentAnnotation() != null)\r
356       {\r
357         existingAnnotations = al.getAlignmentAnnotation().length;\r
358       }\r
359 \r
360       int alWidth = al.getWidth();\r
361 \r
362       StringTokenizer st;\r
363       Annotation[] annotations;\r
364       AlignmentAnnotation annotation = null;\r
365 \r
366       // First confirm this is an Annotation file\r
367       boolean jvAnnotationFile = false;\r
368       while ( (line = in.readLine()) != null)\r
369       {\r
370         if (line.indexOf("#") == 0)\r
371         {\r
372           continue;\r
373         }\r
374 \r
375         if (line.indexOf("JALVIEW_ANNOTATION") > -1)\r
376         {\r
377           jvAnnotationFile = true;\r
378           break;\r
379         }\r
380       }\r
381 \r
382       if (!jvAnnotationFile)\r
383       {\r
384         in.close();\r
385         return false;\r
386       }\r
387 \r
388       while ( (line = in.readLine()) != null)\r
389       {\r
390         if (line.indexOf("#") == 0\r
391             || line.indexOf("JALVIEW_ANNOTATION") > -1\r
392             || line.length() == 0)\r
393         {\r
394           continue;\r
395         }\r
396 \r
397         st = new StringTokenizer(line, "\t");\r
398         token = st.nextToken();\r
399         if (token.equalsIgnoreCase("COLOUR"))\r
400         {\r
401           colourAnnotations(al, st.nextToken(), st.nextToken());\r
402           continue;\r
403         }\r
404 \r
405         else if (token.equalsIgnoreCase("COMBINE"))\r
406         {\r
407           combineAnnotations(al, st);\r
408           continue;\r
409         }\r
410 \r
411         else if (token.equalsIgnoreCase("GRAPHLINE"))\r
412         {\r
413           addLine(al, st);\r
414           continue;\r
415         }\r
416 \r
417         else if (token.equalsIgnoreCase("SEQUENCE_REF"))\r
418         {\r
419           refSeq = al.findName(st.nextToken());\r
420           try\r
421           {\r
422             refSeqIndex = Integer.parseInt(st.nextToken());\r
423             if (refSeqIndex < 1)\r
424             {\r
425               refSeqIndex = 1;\r
426               System.out.println(\r
427                   "WARNING: SEQUENCE_REF index must be > 0 in AnnotationFile");\r
428             }\r
429           }\r
430           catch (Exception ex)\r
431           {\r
432             refSeqIndex = 1;\r
433           }\r
434 \r
435           continue ;\r
436         }\r
437 \r
438         else if (token.equalsIgnoreCase("SEQUENCE_GROUP"))\r
439         {\r
440           addGroup(al, st);\r
441           continue;\r
442         }\r
443 \r
444         else if (token.equalsIgnoreCase("PROPERTIES"))\r
445         {\r
446           addProperties(al, st);\r
447           continue;\r
448         }\r
449 \r
450         else if( token.equalsIgnoreCase("BELOW_ALIGNMENT"))\r
451         {\r
452           setBelowAlignment(al, st);\r
453           continue;\r
454         }\r
455         else if( token.equalsIgnoreCase("ALIGNMENT"))\r
456         {\r
457           addAlignmentDetails(al, st);\r
458           continue;\r
459         }\r
460 \r
461         graphStyle = AlignmentAnnotation.getGraphValueFromString(token);\r
462         label = st.nextToken();\r
463 \r
464 \r
465         index = 0;\r
466         annotations = new Annotation[alWidth];\r
467         description = null;\r
468         float score = Float.NaN;\r
469 \r
470         if(st.hasMoreTokens())\r
471         {\r
472           line = st.nextToken();\r
473 \r
474           if (line.indexOf("|") ==-1)\r
475           {\r
476             description = line;\r
477             if (st.hasMoreTokens())\r
478               line = st.nextToken();\r
479           }\r
480 \r
481           if(st.hasMoreTokens())\r
482           {\r
483             //This must be the score\r
484             score = Float.valueOf(st.nextToken()).floatValue();\r
485           }\r
486 \r
487           st = new StringTokenizer(line, "|", true);\r
488 \r
489 \r
490           boolean emptyColumn = true;\r
491           boolean onlyOneElement = (st.countTokens()==1);\r
492 \r
493           while (st.hasMoreElements() && index < alWidth)\r
494           {\r
495             token = st.nextToken().trim();\r
496 \r
497             if(onlyOneElement)\r
498             {\r
499               try\r
500               {\r
501                 score = Float.valueOf(token).floatValue();\r
502                 break;\r
503               }\r
504               catch(NumberFormatException ex){}\r
505             }\r
506 \r
507             if (token.equals("|"))\r
508             {\r
509               if (emptyColumn)\r
510               {\r
511                 index++;\r
512               }\r
513 \r
514               emptyColumn = true;\r
515             }\r
516             else\r
517             {\r
518               annotations[index++] = parseAnnotation(token);\r
519               emptyColumn = false;\r
520             }\r
521           }\r
522 \r
523         }\r
524 \r
525         annotation = new AlignmentAnnotation(label,\r
526                                              description,\r
527                                              (index==0) ? null : annotations,\r
528                                              0,\r
529                                              0,\r
530                                              graphStyle);\r
531 \r
532         annotation.score = score;\r
533 \r
534         if (refSeq != null)\r
535         {\r
536           annotation.belowAlignment=false;\r
537           annotation.createSequenceMapping(refSeq, refSeqIndex, false);\r
538           annotation.adjustForAlignment();\r
539           refSeq.addAlignmentAnnotation(annotation);\r
540         }\r
541 \r
542         al.addAnnotation(annotation);\r
543 \r
544         al.setAnnotationIndex(annotation,\r
545                               al.getAlignmentAnnotation().length - existingAnnotations -\r
546                               1);\r
547       }\r
548 \r
549     }\r
550     catch (Exception ex)\r
551     {\r
552       ex.printStackTrace();\r
553       System.out.println("Problem reading annotation file: " + ex);\r
554       return false;\r
555     }\r
556     return true;\r
557   }\r
558 \r
559   Annotation parseAnnotation(String string)\r
560   {\r
561     String desc = null, displayChar = null;\r
562     char ss = ' '; // secondaryStructure\r
563     float value = 0;\r
564     boolean parsedValue = false;\r
565 \r
566     //find colour here\r
567     java.awt.Color colour = null;\r
568     int i=string.indexOf("[");\r
569     int j=string.indexOf("]");\r
570     if(i>-1 && j>-1)\r
571     {\r
572       UserColourScheme ucs = new UserColourScheme();\r
573 \r
574       colour = ucs.getColourFromString(string.substring(i+1,j));\r
575 \r
576       string = string.substring(0,i)+string.substring(j+1);\r
577     }\r
578 \r
579     StringTokenizer st = new StringTokenizer(string, ",");\r
580     String token;\r
581     while (st.hasMoreTokens())\r
582     {\r
583       token = st.nextToken().trim();\r
584       if (token.length() == 0)\r
585       {\r
586         continue;\r
587       }\r
588 \r
589       if (!parsedValue)\r
590       {\r
591         try\r
592         {\r
593           displayChar = token;\r
594           value = new Float(token).floatValue();\r
595           parsedValue = true;\r
596           continue;\r
597         }\r
598         catch (NumberFormatException ex)\r
599         {}\r
600       }\r
601 \r
602       if (token.equals("H") || token.equals("E"))\r
603       {\r
604         // Either this character represents a helix or sheet\r
605         // or an integer which can be displayed\r
606         ss = token.charAt(0);\r
607         if (displayChar.equals(token.substring(0, 1)))\r
608         {\r
609           displayChar = "";\r
610         }\r
611       }\r
612       else if (desc == null)\r
613       {\r
614         desc = token;\r
615       }\r
616 \r
617     }\r
618 \r
619     if (displayChar!=null\r
620         && displayChar.length() > 1\r
621         &&  desc!=null\r
622         && desc.length() == 1)\r
623     {\r
624       String tmp = displayChar;\r
625       displayChar = desc;\r
626       desc = tmp;\r
627     }\r
628     /*\r
629      * In principle, this code will ensure that the Annotation element generated is renderable by any of the applet or application rendering code\r
630      * but instead we check for null strings when the display character is rendered. \r
631     if (displayChar==null)\r
632     {\r
633       displayChar="";\r
634     }\r
635     */\r
636     Annotation anot = new Annotation(displayChar, desc, ss, value);\r
637 \r
638     anot.colour = colour;\r
639 \r
640     return anot;\r
641   }\r
642 \r
643   void colourAnnotations(AlignmentI al, String label, String colour)\r
644   {\r
645     UserColourScheme ucs = new UserColourScheme(colour);\r
646     Annotation[] annotations;\r
647     for (int i = 0; i < al.getAlignmentAnnotation().length; i++)\r
648     {\r
649       if (al.getAlignmentAnnotation()[i].label.equalsIgnoreCase(label))\r
650       {\r
651         annotations = al.getAlignmentAnnotation()[i].annotations;\r
652         for (int j = 0; j < annotations.length; j++)\r
653         {\r
654           if (annotations[j] != null)\r
655           {\r
656             annotations[j].colour = ucs.findColour('A');\r
657           }\r
658         }\r
659       }\r
660     }\r
661   }\r
662 \r
663   void combineAnnotations(AlignmentI al, StringTokenizer st)\r
664   {\r
665     int graphGroup = -1;\r
666     String group = st.nextToken();\r
667     //First make sure we are not overwriting the graphIndex\r
668     for (int i = 0; i < al.getAlignmentAnnotation().length; i++)\r
669     {\r
670       if (al.getAlignmentAnnotation()[i].label.equalsIgnoreCase(group))\r
671       {\r
672         graphGroup = al.getAlignmentAnnotation()[i].graphGroup + 1;\r
673         al.getAlignmentAnnotation()[i].graphGroup = graphGroup;\r
674         break;\r
675       }\r
676     }\r
677 \r
678     //Now update groups\r
679     while (st.hasMoreTokens())\r
680     {\r
681       group = st.nextToken();\r
682       for (int i = 0; i < al.getAlignmentAnnotation().length; i++)\r
683       {\r
684         if (al.getAlignmentAnnotation()[i].label.equalsIgnoreCase(group))\r
685         {\r
686           al.getAlignmentAnnotation()[i].graphGroup = graphGroup;\r
687           break;\r
688         }\r
689       }\r
690     }\r
691   }\r
692 \r
693   void addLine(AlignmentI al, StringTokenizer st)\r
694   {\r
695     String group = st.nextToken();\r
696     AlignmentAnnotation annotation = null;\r
697 \r
698     for (int i = 0; i < al.getAlignmentAnnotation().length; i++)\r
699     {\r
700       if (al.getAlignmentAnnotation()[i].label.equalsIgnoreCase(group))\r
701       {\r
702         annotation = al.getAlignmentAnnotation()[i];\r
703         break;\r
704       }\r
705     }\r
706 \r
707     if (annotation == null)\r
708     {\r
709       return;\r
710     }\r
711     float value = new Float(st.nextToken()).floatValue();\r
712     String label = st.hasMoreTokens() ? st.nextToken() : null;\r
713     java.awt.Color colour = null;\r
714     if (st.hasMoreTokens())\r
715     {\r
716       UserColourScheme ucs = new UserColourScheme(st.nextToken());\r
717       colour = ucs.findColour('A');\r
718     }\r
719 \r
720     annotation.setThreshold(new GraphLine(value, label, colour));\r
721   }\r
722 \r
723   void addGroup(AlignmentI al, StringTokenizer st)\r
724   {\r
725     SequenceGroup sg = new SequenceGroup();\r
726     sg.setName(st.nextToken());\r
727     sg.setStartRes(Integer.parseInt(st.nextToken()) - 1);\r
728     sg.setEndRes(Integer.parseInt(st.nextToken()) - 1);\r
729 \r
730     String index = st.nextToken();\r
731     if (index.equals("-1"))\r
732     {\r
733       while (st.hasMoreElements())\r
734       {\r
735         sg.addSequence(al.findName(st.nextToken()), false);\r
736       }\r
737     }\r
738     else\r
739     {\r
740       StringTokenizer st2 = new StringTokenizer(index, ",");\r
741 \r
742       while (st2.hasMoreTokens())\r
743       {\r
744         String tmp = st2.nextToken();\r
745         if (tmp.equals("*"))\r
746         {\r
747           for (int i = 0; i < al.getHeight(); i++)\r
748           {\r
749             sg.addSequence(al.getSequenceAt(i), false);\r
750           }\r
751         }\r
752         else if (tmp.indexOf("-") >= 0)\r
753         {\r
754           StringTokenizer st3 = new StringTokenizer(tmp, "-");\r
755 \r
756           int start = (Integer.parseInt(st3.nextToken()));\r
757           int end = (Integer.parseInt(st3.nextToken()));\r
758 \r
759           if (end > start)\r
760           {\r
761             for (int i = start; i <= end; i++)\r
762             {\r
763               sg.addSequence(al.getSequenceAt(i - 1), false);\r
764             }\r
765           }\r
766         }\r
767         else\r
768         {\r
769           sg.addSequence(al.getSequenceAt(Integer.parseInt(tmp) - 1), false);\r
770         }\r
771       }\r
772     }\r
773 \r
774 \r
775 \r
776     if (refSeq != null)\r
777     {\r
778       sg.setStartRes(refSeq.findIndex(sg.getStartRes() + 1) - 1);\r
779       sg.setEndRes(refSeq.findIndex(sg.getEndRes() + 1) - 1);\r
780     }\r
781 \r
782     if (sg.getSize() > 0)\r
783     {\r
784       al.addGroup(sg);\r
785     }\r
786   }\r
787 \r
788   void addProperties(AlignmentI al, StringTokenizer st)\r
789   {\r
790 \r
791     //So far we have only added groups to the annotationHash,\r
792     //the idea is in the future properties can be added to\r
793     //alignments, other annotations etc\r
794     if (al.getGroups() == null)\r
795     {\r
796       return;\r
797     }\r
798     SequenceGroup sg = null;\r
799 \r
800     String name = st.nextToken();\r
801 \r
802     Vector groups = al.getGroups();\r
803     for (int i = 0; i < groups.size(); i++)\r
804     {\r
805       sg = (SequenceGroup) groups.elementAt(i);\r
806       if (sg.getName().equals(name))\r
807       {\r
808         break;\r
809       }\r
810       else\r
811       {\r
812         sg = null;\r
813       }\r
814     }\r
815 \r
816     if (sg != null)\r
817     {\r
818       String keyValue, key, value;\r
819       while (st.hasMoreTokens())\r
820       {\r
821         keyValue = st.nextToken();\r
822         key = keyValue.substring(0, keyValue.indexOf("="));\r
823         value = keyValue.substring(keyValue.indexOf("=") + 1);\r
824 \r
825         if (key.equalsIgnoreCase("description"))\r
826         {\r
827           sg.setDescription(value);\r
828         }\r
829         else if (key.equalsIgnoreCase("colour"))\r
830         {\r
831           sg.cs = ColourSchemeProperty.getColour(al, value);\r
832         }\r
833         else if (key.equalsIgnoreCase("pidThreshold"))\r
834         {\r
835           sg.cs.setThreshold(Integer.parseInt(value), true);\r
836 \r
837         }\r
838         else if (key.equalsIgnoreCase("consThreshold"))\r
839         {\r
840           sg.cs.setConservationInc(Integer.parseInt(value));\r
841           Conservation c = new Conservation("Group",\r
842                                             ResidueProperties.propHash, 3,\r
843                                             sg.getSequences(null),\r
844                                             sg.getStartRes(),\r
845                                             sg.getEndRes() + 1);\r
846 \r
847           c.calculate();\r
848           c.verdict(false, 25);\r
849 \r
850           sg.cs.setConservation(c);\r
851 \r
852         }\r
853         else if (key.equalsIgnoreCase("outlineColour"))\r
854         {\r
855           sg.setOutlineColour(new UserColourScheme(value).findColour('A'));\r
856         }\r
857         else if (key.equalsIgnoreCase("displayBoxes"))\r
858         {\r
859           sg.setDisplayBoxes(Boolean.valueOf(value).booleanValue());\r
860         }\r
861         else if (key.equalsIgnoreCase("displayText"))\r
862         {\r
863           sg.setDisplayText(Boolean.valueOf(value).booleanValue());\r
864         }\r
865         else if (key.equalsIgnoreCase("colourText"))\r
866         {\r
867           sg.setColourText(Boolean.valueOf(value).booleanValue());\r
868         }\r
869         else if (key.equalsIgnoreCase("textCol1"))\r
870         {\r
871           sg.textColour = new UserColourScheme(value).findColour('A');\r
872         }\r
873         else if (key.equalsIgnoreCase("textCol2"))\r
874         {\r
875           sg.textColour2 = new UserColourScheme(value).findColour('A');\r
876         }\r
877         else if (key.equalsIgnoreCase("textColThreshold"))\r
878         {\r
879           sg.thresholdTextColour = Integer.parseInt(value);\r
880         }\r
881 \r
882         sg.recalcConservation();\r
883       }\r
884     }\r
885   }\r
886 \r
887   void setBelowAlignment(AlignmentI al, StringTokenizer st)\r
888   {\r
889     String token;\r
890     AlignmentAnnotation aa;\r
891     while(st.hasMoreTokens())\r
892     {\r
893       token = st.nextToken();\r
894       for(int i=0; i<al.getAlignmentAnnotation().length; i++)\r
895       {\r
896         aa = al.getAlignmentAnnotation()[i];\r
897         if(aa.sequenceRef==refSeq && aa.label.equals(token))\r
898         {\r
899           aa.belowAlignment = true;\r
900         }\r
901       }\r
902     }\r
903   }\r
904 \r
905   void addAlignmentDetails(AlignmentI al, StringTokenizer st)\r
906   {\r
907     String keyValue, key, value;\r
908     while (st.hasMoreTokens())\r
909     {\r
910       keyValue = st.nextToken();\r
911       key = keyValue.substring(0, keyValue.indexOf("="));\r
912       value = keyValue.substring(keyValue.indexOf("=") + 1);\r
913       al.setProperty(key,value);\r
914     }\r
915   }\r
916 \r
917   /**\r
918    * Write annotations as a CSV file of the form 'label, value, value, ...' for each row.\r
919    * @param annotations\r
920    * @return CSV file as a string.\r
921    */\r
922   public String printCSVAnnotations(AlignmentAnnotation[] annotations)\r
923   {\r
924     StringBuffer sp = new StringBuffer();\r
925     for (int i=0; i<annotations.length; i++)\r
926     {\r
927       String atos = annotations[i].toString();\r
928       int p = 0;\r
929       do {\r
930         int cp = atos.indexOf("\n", p);\r
931         sp.append(annotations[i].label);\r
932         sp.append(",");\r
933         if (cp>p)\r
934         {\r
935           sp.append(atos.substring(p, cp+1));\r
936         } else {\r
937           sp.append(atos.substring(p));\r
938           sp.append("\n");\r
939         }\r
940         p = cp+1;\r
941       } while (p>0);\r
942     }\r
943     return sp.toString();\r
944   }\r
945 }\r