relaxed ID matching parameter JAL-753
authorjprocter <Jim Procter>
Fri, 21 Jan 2011 17:05:43 +0000 (17:05 +0000)
committerjprocter <Jim Procter>
Fri, 21 Jan 2011 17:05:43 +0000 (17:05 +0000)
src/jalview/io/FeaturesFile.java
src/jalview/io/packed/JalviewDataset.java
src/jalview/io/packed/ParsePackedSet.java

index 64bb539..34253cb 100755 (executable)
@@ -20,6 +20,7 @@ package jalview.io;
 import java.io.*;\r
 import java.util.*;\r
 \r
+import jalview.analysis.SequenceIdMatcher;\r
 import jalview.datamodel.*;\r
 import jalview.schemes.*;\r
 import jalview.util.Format;\r
@@ -70,28 +71,60 @@ public class FeaturesFile extends AlignFile
   }\r
 \r
   /**\r
-   * The Application can render HTML, but the applet will remove HTML tags and\r
-   * replace links with %LINK% Both need to read links in HTML however\r
-   * \r
-   * @throws IOException\r
-   *           DOCUMENT ME!\r
+   * Parse GFF or sequence features file using case-independent matching, discarding URLs\r
+   * @param align - alignment/dataset containing sequences that are to be annotated\r
+   * @param colours - hashtable to store feature colour definitions\r
+   * @param removeHTML - process html strings into plain text\r
+   * @return true if features were added\r
    */\r
   public boolean parse(AlignmentI align, Hashtable colours,\r
           boolean removeHTML)\r
   {\r
-    return parse(align, colours, null, removeHTML);\r
+    return parse(align, colours, null, removeHTML, false);\r
   }\r
 \r
   /**\r
-   * The Application can render HTML, but the applet will remove HTML tags and\r
-   * replace links with %LINK% Both need to read links in HTML however\r
-   * \r
-   * @throws IOException\r
-   *           DOCUMENT ME!\r
+   * Parse GFF or sequence features file optionally using case-independent matching, discarding URLs\r
+   * @param align - alignment/dataset containing sequences that are to be annotated\r
+   * @param colours - hashtable to store feature colour definitions\r
+   * @param removeHTML - process html strings into plain text\r
+   * @param relaxedIdmatching - when true, ID matches to compound sequence IDs are allowed\r
+   * @return true if features were added\r
+   */\r
+  public boolean parse(AlignmentI align, \r
+          Hashtable colours, boolean removeHTML, boolean relaxedIdMatching)\r
+  {\r
+    return parse(align, colours, null, removeHTML, relaxedIdMatching);\r
+  }\r
+\r
+  /**\r
+   * Parse GFF or sequence features file optionally using case-independent matching\r
+   * @param align - alignment/dataset containing sequences that are to be annotated\r
+   * @param colours - hashtable to store feature colour definitions\r
+   * @param featureLink - hashtable to store associated URLs \r
+   * @param removeHTML - process html strings into plain text\r
+   * @return true if features were added\r
    */\r
   public boolean parse(AlignmentI align, Hashtable colours,\r
           Hashtable featureLink, boolean removeHTML)\r
   {\r
+    return parse(align, colours, featureLink, removeHTML, false);\r
+  }\r
+\r
+  /**\r
+  /**\r
+   * Parse GFF or sequence features file \r
+   * @param align - alignment/dataset containing sequences that are to be annotated\r
+   * @param colours - hashtable to store feature colour definitions\r
+   * @param featureLink - hashtable to store associated URLs \r
+   * @param removeHTML - process html strings into plain text\r
+   * @param relaxedIdmatching - when true, ID matches to compound sequence IDs are allowed\r
+   * @return true if features were added\r
+   */\r
+  public boolean parse(AlignmentI align,\r
+          Hashtable colours, Hashtable featureLink, boolean removeHTML, boolean relaxedIdmatching)\r
+  {\r
+\r
     String line = null;\r
     try\r
     {\r
@@ -369,7 +402,7 @@ public class FeaturesFile extends AlignFile
             // Still possible this is an old Jalview file,\r
             // which does not have type colours at the beginning\r
             seqId = token = st.nextToken();\r
-            seq = align.findName(seqId, true);\r
+            seq = findName(align, seqId, relaxedIdmatching);\r
             if (seq != null)\r
             {\r
               desc = st.nextToken();\r
@@ -478,7 +511,7 @@ public class FeaturesFile extends AlignFile
 \r
           if (!token.equals("ID_NOT_SPECIFIED"))\r
           {\r
-            seq = align.findName(seqId = token, true);\r
+            seq = findName(align, seqId = token, relaxedIdmatching);\r
             st.nextToken();\r
           }\r
           else\r
@@ -548,17 +581,52 @@ public class FeaturesFile extends AlignFile
           GFFFile = false;\r
         }\r
       }\r
+      resetMatcher();\r
     } catch (Exception ex)\r
     {\r
       System.out.println(line);\r
       System.out.println("Error parsing feature file: " + ex + "\n" + line);\r
       ex.printStackTrace(System.err);\r
+      resetMatcher();\r
       return false;\r
     }\r
 \r
     return true;\r
   }\r
 \r
+  private AlignmentI lastmatchedAl = null;\r
+\r
+  private SequenceIdMatcher matcher = null;\r
+\r
+  /**\r
+   * clear any temporary handles used to speed up ID matching\r
+   */\r
+  private void resetMatcher()\r
+  {\r
+    lastmatchedAl = null;\r
+    matcher = null;\r
+  }\r
+\r
+  private SequenceI findName(AlignmentI align, String seqId,\r
+          boolean relaxedIdMatching)\r
+  {\r
+    SequenceI match = null;\r
+    if (relaxedIdMatching)\r
+    {\r
+      if (lastmatchedAl != align)\r
+      {\r
+        matcher = new SequenceIdMatcher(\r
+                (lastmatchedAl = align).getSequencesArray());\r
+      }\r
+      match = matcher.findIdMatch(seqId);\r
+    }\r
+    else\r
+    {\r
+      match = align.findName(seqId, true);\r
+    }\r
+    return match;\r
+  }\r
+\r
   public void parseDescriptionHTML(SequenceFeature sf, boolean removeHTML)\r
   {\r
     if (sf.getDescription() == null)\r
@@ -929,19 +997,18 @@ public class FeaturesFile extends AlignFile
           out.append(source);\r
           out.append("\t");\r
           out.append(next[j].type);\r
-          out.append( "\t");\r
-          out.append(  next[j].begin );\r
           out.append("\t");\r
-          out.append(\r
-                  next[j].end);\r
-          out.append( "\t");\r
-          out.append( next[j].score);\r
-          out.append( "\t");\r
+          out.append(next[j].begin);\r
+          out.append("\t");\r
+          out.append(next[j].end);\r
+          out.append("\t");\r
+          out.append(next[j].score);\r
+          out.append("\t");\r
 \r
           if (next[j].getValue("STRAND") != null)\r
           {\r
             out.append(next[j].getValue("STRAND"));\r
-            out.append( "\t");\r
+            out.append("\t");\r
           }\r
           else\r
           {\r
@@ -956,7 +1023,8 @@ public class FeaturesFile extends AlignFile
           {\r
             out.append(".");\r
           }\r
-          // TODO: verify/check GFF - should there be a /t here before attribute output ?\r
+          // TODO: verify/check GFF - should there be a /t here before attribute\r
+          // output ?\r
 \r
           if (next[j].getValue("ATTRIBUTES") != null)\r
           {\r
@@ -989,4 +1057,5 @@ public class FeaturesFile extends AlignFile
   {\r
     return "USE printGFFFormat() or printJalviewFormat()";\r
   }\r
+\r
 }\r
index 5e5c446..f4fe55b 100644 (file)
@@ -148,6 +148,8 @@ public class JalviewDataset
    */
   Hashtable seqDetails;
 
+  public boolean relaxedIdMatching=false;
+
   public JalviewDataset()
   {
     seqDetails = new Hashtable();
index 787a88f..97802f3 100644 (file)
@@ -133,8 +133,8 @@ public class ParsePackedSet
         try
         {
           jalview.io.FeaturesFile ff = new jalview.io.FeaturesFile(src);
-          context.updateSetModified(ff.parse(context.getLastAlignment(),
-                  context.featureColours, false));
+          context.updateSetModified(ff.parse(context.getLastAlignment(), 
+                  context.featureColours, false, context.relaxedIdMatching));
         } catch (Exception e)
         {
           errmsg = ("Failed to parse the Features file associated with the alignment.");