apply version 2.7 copyright
[jalview.git] / src / jalview / io / StockholmFile.java
index d0d84f5..1625241 100644 (file)
@@ -1,20 +1,19 @@
 /*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2007 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
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)\r
+ * Copyright (C) 2011 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle\r
+ * \r
+ * This file is part of Jalview.\r
+ * \r
+ * Jalview 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 3 of the License, or (at your option) any later version.\r
+ * \r
+ * Jalview is distributed in the hope that it will be useful, but \r
+ * WITHOUT ANY WARRANTY; without even the implied warranty \r
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR \r
+ * PURPOSE.  See the GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.\r
  */\r
 /*\r
  * This extension was written by Benjamin Schuster-Boeckler at sanger.ac.uk\r
@@ -30,10 +29,16 @@ import jalview.datamodel.*;
 // import org.apache.log4j.*;\r
 \r
 /**\r
- * This class is supposed to parse a Stockholm format file into Jalview\r
+ * This class is supposed to parse a Stockholm format file into Jalview There\r
+ * are TODOs in this class: we do not know what the database source and version\r
+ * is for the file when parsing the #GS= AC tag which associates accessions with\r
+ * sequences. Database references are also not parsed correctly: a separate\r
+ * reference string parser must be added to parse the database reference form\r
+ * into Jalview's local representation.\r
  * \r
  * @author bsb at sanger.ac.uk\r
- * @version 0.3\r
+ * @version 0.3 + jalview mods\r
+ * \r
  */\r
 public class StockholmFile extends AlignFile\r
 {\r
@@ -48,6 +53,11 @@ public class StockholmFile extends AlignFile
     super(inFile, type);\r
   }\r
 \r
+  public StockholmFile(FileParse source) throws IOException\r
+  {\r
+    super(source);\r
+  }\r
+\r
   public void initData()\r
   {\r
     super.initData();\r
@@ -88,10 +98,10 @@ public class StockholmFile extends AlignFile
     }\r
 \r
     // We define some Regexes here that will be used regularily later\r
-    rend = new Regex("\\/\\/"); // Find the end of an alignment\r
+    rend = new Regex("^\\s*\\/\\/"); // Find the end of an alignment\r
     p = new Regex("(\\S+)\\/(\\d+)\\-(\\d+)"); // split sequence id in\r
-                                                // id/from/to\r
-    s = new Regex("(\\S+)\\s+(\\w{2})\\s+(.*)"); // Parses annotation subtype\r
+    // id/from/to\r
+    s = new Regex("(\\S+)\\s+(\\S*)\\s+(.*)"); // Parses annotation subtype\r
     r = new Regex("#=(G[FSRC]?)\\s+(.*)"); // Finds any annotation line\r
     x = new Regex("(\\S+)\\s+(\\S+)"); // split id from sequence\r
 \r
@@ -118,7 +128,7 @@ public class StockholmFile extends AlignFile
         {\r
           String acc = (String) accs.nextElement();\r
           // logger.debug("Processing sequence " + acc);\r
-          String seq = (String) seqs.get(acc);\r
+          String seq = (String) seqs.remove(acc);\r
           if (maxLength < seq.length())\r
           {\r
             maxLength = seq.length();\r
@@ -131,7 +141,7 @@ public class StockholmFile extends AlignFile
 \r
           if (seqAnn != null && seqAnn.containsKey(acc))\r
           {\r
-            accAnnotations = (Hashtable) seqAnn.get(acc);\r
+            accAnnotations = (Hashtable) seqAnn.remove(acc);\r
           }\r
 \r
           // Split accession in id and from/to\r
@@ -158,16 +168,15 @@ public class StockholmFile extends AlignFile
             {\r
               String src = dbr.substring(0, dbr.indexOf(";"));\r
               String acn = dbr.substring(dbr.indexOf(";") + 1);\r
-              DBRefEntry dbref = new DBRefEntry(jalview.util.DBRefUtils\r
-                      .getCanonicalName(src), acn, "");\r
-              seqO.addDBRef(dbref);\r
+              jalview.util.DBRefUtils.parseToDbRef(seqO, src, "0", acn);\r
+              // seqO.addDBRef(dbref);\r
             }\r
           }\r
           Hashtable features = null;\r
           // We need to adjust the positions of all features to account for gaps\r
           try\r
           {\r
-            features = (Hashtable) accAnnotations.get("features");\r
+            features = (Hashtable) accAnnotations.remove("features");\r
           } catch (java.lang.NullPointerException e)\r
           {\r
             // loggerwarn("Getting Features for " + acc + ": " +\r
@@ -177,6 +186,7 @@ public class StockholmFile extends AlignFile
           // if we have features\r
           if (features != null)\r
           {\r
+            int posmap[] = seqO.findPositionMap();\r
             Enumeration i = features.keys();\r
             while (i.hasMoreElements())\r
             {\r
@@ -185,8 +195,7 @@ public class StockholmFile extends AlignFile
               // TODO: parse out scores as annotation row\r
               // TODO: map coding region to core jalview feature types\r
               String type = i.nextElement().toString();\r
-              Hashtable content = (Hashtable) features.get(type);\r
-\r
+              Hashtable content = (Hashtable) features.remove(type);\r
               Enumeration j = content.keys();\r
               while (j.hasMoreElements())\r
               {\r
@@ -196,9 +205,15 @@ public class StockholmFile extends AlignFile
                 for (int k = 0; k < byChar.length; k++)\r
                 {\r
                   char c = byChar[k];\r
-                  if (!(c == ' ' || c == '_' || c == '-'))\r
+                  if (!(c == ' ' || c == '_' || c == '-' || c == '.')) // PFAM\r
+                  // uses\r
+                  // '.'\r
+                  // for\r
+                  // feature\r
+                  // background\r
                   {\r
-                    int new_pos = seqO.findPosition(k);\r
+                    int new_pos = posmap[k]; // look up nearest seqeunce\r
+                    // position to this column\r
                     SequenceFeature feat = new SequenceFeature(type, desc,\r
                             new_pos, new_pos, 0f, null);\r
 \r
@@ -210,10 +225,13 @@ public class StockholmFile extends AlignFile
             }\r
 \r
           }\r
+          // garbage collect\r
+\r
           // logger.debug("Adding seq " + acc + " from " + start + " to " + end\r
           // + ": " + seq);\r
           this.seqs.addElement(seqO);\r
         }\r
+        return; // finished parsing this segment of source\r
       }\r
       else if (!r.search(line))\r
       {\r
@@ -345,8 +363,8 @@ public class StockholmFile extends AlignFile
           if (x.search(annContent))\r
           {\r
             // parse out and create alignment annotation directly.\r
-            parseAnnotationRow(annotations, x.stringMatched(1), x\r
-                    .stringMatched(2));\r
+            parseAnnotationRow(annotations, x.stringMatched(1),\r
+                    x.stringMatched(2));\r
           }\r
         }\r
         else if (annType.equals("GR"))\r
@@ -365,14 +383,20 @@ public class StockholmFile extends AlignFile
           {\r
             String acc = s.stringMatched(1);\r
             String type = s.stringMatched(2);\r
-            String seq = s.stringMatched(3);\r
-            String description = new String();\r
-\r
+            String seq = new String(s.stringMatched(3));\r
+            String description = null;\r
             // Check for additional information about the current annotation\r
-            if (x.search(seq))\r
+            // We use a simple string tokenizer here for speed\r
+            StringTokenizer sep = new StringTokenizer(seq, " \t");\r
+            description = sep.nextToken();\r
+            if (sep.hasMoreTokens())\r
             {\r
-              description = x.stringMatched(1);\r
-              seq = x.stringMatched(2);\r
+              seq = sep.nextToken();\r
+            }\r
+            else\r
+            {\r
+              seq = description;\r
+              description = new String();\r
             }\r
             // sequence id with from-to fields\r
 \r
@@ -423,11 +447,14 @@ public class StockholmFile extends AlignFile
               ns = "";\r
             }\r
             ns += seq;\r
-            content.put(description, seq);\r
+            content.put(description, ns);\r
           }\r
           else\r
           {\r
-            throw new IOException("Error parsing " + line);\r
+            System.err\r
+                    .println("Warning - couldn't parse sequence annotation row line:\n"\r
+                            + line);\r
+            // throw new IOException("Error parsing " + line);\r
           }\r
         }\r
         else\r
@@ -464,18 +491,19 @@ public class StockholmFile extends AlignFile
     {\r
       String pos = annots.substring(i, i + 1);\r
       Annotation ann;\r
-      ann = new Annotation(pos, "", ' ', Float.NaN);\r
+      ann = new Annotation(pos, "", ' ', 0f); // 0f is 'valid' null - will not\r
+      // be written out\r
       if (ss)\r
       {\r
         ann.secondaryStructure = jalview.schemes.ResidueProperties\r
                 .getDssp3state(pos).charAt(0);\r
         if (ann.secondaryStructure == pos.charAt(0) || pos.charAt(0) == 'C')\r
         {\r
-          ann.displayCharacter = "";\r
+          ann.displayCharacter = ""; // null; // " ";\r
         }\r
         else\r
         {\r
-          ann.displayCharacter += " ";\r
+          ann.displayCharacter = " " + ann.displayCharacter;\r
         }\r
       }\r
 \r