+/*\r
+ * Jalview - A Sequence Alignment Editor and Viewer\r
+ * Copyright (C) 2006 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA\r
+ */\r
+\r
+package jalview.io;\r
+\r
+import java.io.*;\r
+import jalview.datamodel.*;\r
+import java.util.*;\r
+import jalview.schemes.UserColourScheme;\r
+import java.net.URL;\r
+\r
+\r
+public class AnnotationFile\r
+{\r
+\r
+ public String printAnnotations(AlignmentAnnotation [] annotations)\r
+ {\r
+ StringBuffer text = new StringBuffer(\r
+ "JALVIEW_ANNOTATION\n"\r
+ +"# Created: "\r
+ +new java.util.Date()+"\n\n");\r
+\r
+ AlignmentAnnotation row;\r
+ String comma;\r
+ String seqref = null;\r
+\r
+ StringBuffer colours = new StringBuffer();\r
+ StringBuffer graphLine = new StringBuffer();\r
+\r
+ Hashtable graphGroup = new Hashtable();\r
+\r
+ java.awt.Color color;\r
+\r
+ for(int i=0; i<annotations.length; i++)\r
+ {\r
+ row = annotations[i];\r
+ color = null;\r
+\r
+ if( row.sequenceRef == null)\r
+ seqref = null;\r
+\r
+ else if (seqref == null\r
+ || !seqref.equals(row.sequenceRef.getName()))\r
+ {\r
+ seqref = row.sequenceRef.getName();\r
+ text.append("\nSEQUENCE_REF\t" + seqref + "\n");\r
+ }\r
+\r
+\r
+ switch( row.graph )\r
+ {\r
+ case AlignmentAnnotation.NO_GRAPH:\r
+ text.append("NO_GRAPH\t");\r
+ break;\r
+ case AlignmentAnnotation.BAR_GRAPH:\r
+ text.append("BAR_GRAPH\t");\r
+ case AlignmentAnnotation.LINE_GRAPH:\r
+ text.append("LINE_GRAPH\t");\r
+\r
+ if(row.getThreshold()!=null)\r
+ graphLine.append("GRAPHLINE\t"\r
+ + row.label + "\t"\r
+ + row.getThreshold().value + "\t"\r
+ + row.getThreshold().label + "\t"\r
+ + jalview.util.Format.getHexString(\r
+ row.getThreshold().colour)+"\n"\r
+ );\r
+\r
+ if(row.graphGroup>-1)\r
+ {\r
+ String key = String.valueOf(row.graphGroup);\r
+ if(graphGroup.containsKey(key))\r
+ graphGroup.put(key, graphGroup.get(key)\r
+ +"\t"+row.label);\r
+ else\r
+ graphGroup.put(key, row.label);\r
+ }\r
+ }\r
+\r
+ text.append(row.label+"\t");\r
+\r
+ for(int j=0; j<row.annotations.length; j++)\r
+ {\r
+ if(row.annotations[j]!=null)\r
+ {\r
+ comma = "";\r
+ if (row.annotations[j].displayCharacter.length() > 0\r
+ && !row.annotations[j].displayCharacter.equals(" "))\r
+ {\r
+ text.append(row.annotations[j].displayCharacter);\r
+ comma = ",";\r
+ }\r
+ if (row.annotations[j].secondaryStructure!=' ')\r
+ {\r
+ text.append(comma + row.annotations[j].secondaryStructure);\r
+ comma = ",";\r
+ }\r
+ if (row.annotations[j].value!=0f)\r
+ {\r
+ color = row.annotations[j].colour;\r
+ text.append(comma + row.annotations[j].value);\r
+ }\r
+ }\r
+ text.append("|");\r
+ }\r
+\r
+ text.append("\n");\r
+\r
+ if(color!=null && color!=java.awt.Color.black)\r
+ {\r
+ colours.append("COLOUR\t"\r
+ +row.label+"\t"\r
+ +jalview.util.Format.getHexString(color)+"\n");\r
+ }\r
+\r
+ }\r
+\r
+ text.append("\n");\r
+\r
+ text.append(colours.toString());\r
+ text.append(graphLine.toString());\r
+ if(graphGroup.size()>0)\r
+ {\r
+ text.append("COMBINE\t");\r
+ Enumeration en = graphGroup.elements();\r
+ while(en.hasMoreElements())\r
+ {\r
+ text.append(en.nextElement()+"\n");\r
+ }\r
+ }\r
+\r
+ return text.toString();\r
+ }\r
+\r
+ public boolean readAnnotationFile(AlignmentI al, String file)\r
+ {\r
+ try\r
+ {\r
+ BufferedReader in = null;\r
+ java.io.InputStream is = getClass().getResourceAsStream("/" + file);\r
+ if (is != null)\r
+ {\r
+ in = new BufferedReader(new java.io.InputStreamReader(is));\r
+ }\r
+ else\r
+ {\r
+ try\r
+ {\r
+ URL url = new URL(file);\r
+ in = new BufferedReader(new InputStreamReader(url.openStream()));\r
+ }\r
+ catch (java.net.MalformedURLException ex)\r
+ {\r
+ in = new BufferedReader(new FileReader(file));\r
+ }\r
+ }\r
+\r
+ String line, label, description, token;\r
+ int graphStyle, index;\r
+ SequenceI refSeq = null;\r
+ int refSeqIndex = 1;\r
+ int existingAnnotations = 0;\r
+ if(al.getAlignmentAnnotation()!=null)\r
+ existingAnnotations = al.getAlignmentAnnotation().length;\r
+\r
+ int alWidth = al.getWidth();\r
+\r
+ StringTokenizer st;\r
+ Annotation[] annotations;\r
+ AlignmentAnnotation annotation = null;\r
+\r
+ // First confirm this is an Annotation file\r
+ boolean jvAnnotationFile = false;\r
+ while ( (line = in.readLine()) != null)\r
+ {\r
+ if (line.indexOf("#") == 0 )\r
+ continue;\r
+\r
+ if (line.indexOf("JALVIEW_ANNOTATION") > -1)\r
+ {\r
+ jvAnnotationFile = true;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if(!jvAnnotationFile)\r
+ {\r
+ in.close();\r
+ return false;\r
+ }\r
+\r
+ while ( (line = in.readLine()) != null)\r
+ {\r
+ if(line.indexOf("#")==0\r
+ || line.indexOf("JALVIEW_ANNOTATION")>-1\r
+ || line.length()==0)\r
+ continue;\r
+\r
+ st = new StringTokenizer(line, "\t");\r
+ token = st.nextToken();\r
+ if(token.equalsIgnoreCase("COLOUR"))\r
+ {\r
+ colourAnnotations(al, st.nextToken(), st.nextToken());\r
+ continue;\r
+ }\r
+\r
+ if(token.equalsIgnoreCase("COMBINE") )\r
+ {\r
+ combineAnnotations(al, st);\r
+ continue;\r
+ }\r
+\r
+ if (token.equalsIgnoreCase("GRAPHLINE"))\r
+ {\r
+ addLine(al, st);\r
+ continue;\r
+ }\r
+\r
+\r
+ if(token.equalsIgnoreCase("SEQUENCE_REF") )\r
+ {\r
+ refSeq = al.findName(st.nextToken());\r
+ try{\r
+ refSeqIndex = Integer.parseInt(st.nextToken());\r
+ }\r
+ catch(Exception ex)\r
+ {\r
+ refSeqIndex = 1;\r
+ }\r
+\r
+ continue;\r
+ }\r
+\r
+\r
+ graphStyle = AlignmentAnnotation.getGraphValueFromString(token);\r
+ label = description = st.nextToken();\r
+\r
+ line = st.nextToken();\r
+\r
+ st = new StringTokenizer(line, "|", true);\r
+ annotations = new Annotation[alWidth];\r
+\r
+ index = 0;\r
+ boolean emptyColumn = true;\r
+\r
+\r
+ while (st.hasMoreElements() && index<alWidth)\r
+ {\r
+ token = st.nextToken().trim();\r
+ if(token.equals("|"))\r
+ {\r
+ if(emptyColumn)\r
+ index++;\r
+\r
+ emptyColumn = true;\r
+ }\r
+ else\r
+ {\r
+ annotations[index++] = parseAnnotation(token);\r
+ emptyColumn = false;\r
+ }\r
+ }\r
+\r
+ annotation = new AlignmentAnnotation(label,\r
+ description,\r
+ annotations,\r
+ 0,\r
+ 0,\r
+ graphStyle);\r
+\r
+ if(refSeq!=null)\r
+ {\r
+ annotation.createSequenceMapping(refSeq, refSeqIndex);\r
+ refSeq.addAlignmentAnnotation(annotation);\r
+ }\r
+\r
+ al.addAnnotation(annotation);\r
+\r
+ al.setAnnotationIndex(annotation, al.getAlignmentAnnotation().length - existingAnnotations-1);\r
+ }\r
+\r
+ }catch(Exception ex)\r
+ {\r
+ ex.printStackTrace();\r
+ System.out.println("Problem reading annotation file: "+ex);\r
+ return false;\r
+ }\r
+ return true;\r
+ }\r
+\r
+ Annotation parseAnnotation(String string)\r
+ {\r
+ String desc = "", displayChar="";\r
+ char ss = ' '; // secondaryStructure\r
+ float value = 0;\r
+ boolean parsedValue = false;\r
+ StringTokenizer st = new StringTokenizer(string, ",");\r
+ String token;\r
+ while(st.hasMoreTokens())\r
+ {\r
+ token = st.nextToken().trim();\r
+ if(token.length()==0)\r
+ continue;\r
+\r
+ if(!parsedValue)\r
+ {\r
+ try{\r
+ value = new Float(token).floatValue();\r
+ displayChar = token;\r
+ parsedValue = true;\r
+ }catch(NumberFormatException ex){}\r
+ }\r
+\r
+ if(token.equals("H") || token.equals("E"))\r
+ {\r
+ // Either this character represents a helix or sheet\r
+ // or an integer which can be displayed\r
+ ss = token.charAt(0);\r
+ }\r
+ else if(desc.length()<1)\r
+ desc = token;\r
+\r
+ }\r
+\r
+ return new Annotation(displayChar, desc, ss, value);\r
+ }\r
+\r
+ void colourAnnotations(AlignmentI al, String label, String colour)\r
+ {\r
+ UserColourScheme ucs = new UserColourScheme(colour);\r
+ Annotation[] annotations;\r
+ for(int i=0; i<al.getAlignmentAnnotation().length; i++)\r
+ {\r
+ if(al.getAlignmentAnnotation()[i].label.equalsIgnoreCase(label))\r
+ {\r
+ annotations = al.getAlignmentAnnotation()[i].annotations;\r
+ for(int j=0; j<annotations.length; j++)\r
+ {\r
+ if(annotations[j]!=null)\r
+ annotations[j].colour = ucs.findColour("A");\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ void combineAnnotations(AlignmentI al, StringTokenizer st)\r
+ {\r
+ int graphGroup = -1;\r
+ String group = st.nextToken();\r
+ //First make sure we are not overwriting the graphIndex\r
+ for(int i=0; i<al.getAlignmentAnnotation().length; i++)\r
+ {\r
+ if(al.getAlignmentAnnotation()[i].label.equalsIgnoreCase(group))\r
+ {\r
+ graphGroup = al.getAlignmentAnnotation()[i].graphGroup +1;\r
+ al.getAlignmentAnnotation()[i].graphGroup = graphGroup;\r
+ break;\r
+ }\r
+ }\r
+\r
+ //Now update groups\r
+ while(st.hasMoreTokens())\r
+ {\r
+ group = st.nextToken();\r
+ for(int i=0; i<al.getAlignmentAnnotation().length; i++)\r
+ {\r
+ if (al.getAlignmentAnnotation()[i].label.equalsIgnoreCase(group))\r
+ {\r
+ al.getAlignmentAnnotation()[i].graphGroup = graphGroup;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ void addLine(AlignmentI al, StringTokenizer st)\r
+ {\r
+ String group = st.nextToken();\r
+ AlignmentAnnotation annotation = null;\r
+\r
+ for (int i = 0; i < al.getAlignmentAnnotation().length; i++)\r
+ {\r
+ if (al.getAlignmentAnnotation()[i].label.equalsIgnoreCase(group))\r
+ {\r
+ annotation = al.getAlignmentAnnotation()[i];\r
+ break;\r
+ }\r
+ }\r
+\r
+ if(annotation==null)\r
+ return;\r
+ float value = new Float(st.nextToken()).floatValue();\r
+ String label = st.hasMoreTokens() ? st.nextToken() : null;\r
+ java.awt.Color colour = null;\r
+ if(st.hasMoreTokens())\r
+ {\r
+ UserColourScheme ucs = new UserColourScheme(st.nextToken());\r
+ colour = ucs.findColour("A");\r
+ }\r
+\r
+ annotation.setThreshold(new GraphLine(value, label, colour));\r
+\r
+ }\r
+}\r