JAL-2137 STRUCTMODEL statement added, logic not yet implemented
[jalview.git] / src / jalview / io / AnnotationFile.java
index 8dc84b8..54e96f3 100755 (executable)
@@ -1,6 +1,6 @@
 /*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
- * Copyright (C) 2014 The Jalview Authors
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
  * 
  * This file is part of Jalview.
  * 
@@ -241,7 +241,7 @@ public class AnnotationFile
                     && row.annotations[j].displayCharacter.length() > 0 && !row.annotations[j].displayCharacter
                     .equals(" "));
             hasGlyphs |= (row.annotations[j].secondaryStructure != 0 && row.annotations[j].secondaryStructure != ' ');
-            hasValues |= (row.annotations[j].value != Float.NaN); // NaNs can't
+            hasValues |= (!Float.isNaN(row.annotations[j].value)); // NaNs can't
             // be
             // rendered..
             hasText |= (row.annotations[j].description != null && row.annotations[j].description
@@ -294,8 +294,7 @@ public class AnnotationFile
             }
             else
             {
-              graphGroup_refs.put(key, new Object[]
-              { refSeq, refGroup });
+              graphGroup_refs.put(key, new Object[] { refSeq, refGroup });
               graphGroup.put(key, row.label);
             }
           }
@@ -331,13 +330,13 @@ public class AnnotationFile
             }
             if (hasValues)
             {
-              if (row.annotations[j].value != Float.NaN)
+              if (!Float.isNaN(row.annotations[j].value))
               {
                 text.append(comma + row.annotations[j].value);
               }
               else
               {
-                System.err.println("Skipping NaN - not valid value.");
+                // System.err.println("Skipping NaN - not valid value.");
                 text.append(comma + 0f);// row.annotations[j].value);
               }
               comma = ",";
@@ -472,8 +471,9 @@ public class AnnotationFile
         text.append(properties.get(key));
       }
       // TODO: output alignment visualization settings here if required
-      // iterate through one or more views, defining, marking columns and rows as visible/hidden, and emmitting view properties.
-      // View specific annotation is 
+      // iterate through one or more views, defining, marking columns and rows
+      // as visible/hidden, and emmitting view properties.
+      // View specific annotation is
     }
 
     return text.toString();
@@ -670,14 +670,14 @@ public class AnnotationFile
     }
     boolean rslt = readAnnotationFile(viewport.getAlignment(), colSel,
             file, protocol);
-    if (rslt
-            && (colSel.hasSelectedColumns() || colSel.hasHiddenColumns()))
+    if (rslt && (colSel.hasSelectedColumns() || colSel.hasHiddenColumns()))
     {
       viewport.setColumnSelection(colSel);
     }
 
     return rslt;
   }
+
   public boolean readAnnotationFile(AlignmentI al, String file,
           String protocol)
   {
@@ -734,11 +734,11 @@ public class AnnotationFile
 
   String lastread = "";
 
-  private static String GRAPHLINE = "GRAPHLINE", COMBINE = "COMBINE";
+  private static String GRAPHLINE = "GRAPHLINE", COMBINE = "COMBINE",
+          STRUCTMODEL = "STRUCTMODEL";
 
   public boolean parseAnnotationFrom(AlignmentI al, ColumnSelection colSel,
-          BufferedReader in)
-          throws Exception
+          BufferedReader in) throws Exception
   {
     nlinesread = 0;
     ArrayList<Object[]> combineAnnotation_calls = new ArrayList<Object[]>();
@@ -831,8 +831,8 @@ public class AnnotationFile
         else if (token.equalsIgnoreCase(COMBINE))
         {
           // keep a record of current state and resolve groupRef at end
-          combineAnnotation_calls.add(new Object[]
-          { st, refSeq, groupRef });
+          combineAnnotation_calls
+                  .add(new Object[] { st, refSeq, groupRef });
           modified = true;
           continue;
         }
@@ -845,8 +845,8 @@ public class AnnotationFile
         else if (token.equalsIgnoreCase(GRAPHLINE))
         {
           // resolve at end
-          deferredAnnotation_calls.add(new Object[]
-          { GRAPHLINE, st, refSeq, groupRef });
+          deferredAnnotation_calls.add(new Object[] { GRAPHLINE, st,
+              refSeq, groupRef });
           modified = true;
           continue;
         }
@@ -981,7 +981,42 @@ public class AnnotationFile
           modified = true;
           continue;
         }
-
+        else if (token.equalsIgnoreCase(STRUCTMODEL))
+        {
+          boolean failedtoadd = true;
+          // expect
+          // STRUCTMODEL <QUERYID> <TemplateID> <URL to model> <URL to
+          // alignment>
+          if (st.hasMoreTokens()) {
+            refSeq = al.findName(refSeqId = st.nextToken());
+            if (refSeq == null)
+            {
+              System.err.println("Couldn't locate " + refSeqId
+                      + " in the alignment for STRUCTMODEL");
+              refSeqId = null;
+            }
+            else
+            {
+              String tempId = st.nextToken();
+              String urlToModel = st.nextToken();
+              String urlToPairwise = st.hasMoreTokens() ? st.nextToken()
+                      : "";
+              if (add_structmodel(refSeq, tempId, urlToModel, urlToPairwise))
+              {
+                failedtoadd = false;
+              }
+            }
+          }
+          if (failedtoadd)
+          {
+            System.err
+                    .println("Need <QueryId> <TemplateId> <URL to Model> [<URL to pairwise alignment>] as tab separated fields after "
+                            + STRUCTMODEL);
+          } else {
+            modified = true;
+          }
+          continue;
+        }
         // Parse out the annotation row
         graphStyle = AlignmentAnnotation.getGraphValueFromString(token);
         label = st.nextToken();
@@ -1154,7 +1189,7 @@ public class AnnotationFile
                   (SequenceI) _deferred_args[2], // refSeq
                   (_deferred_args[3] == null) ? null : groupRefLookup
                           .get(_deferred_args[3]) // the reference
-                                                           // group, or null
+                                                  // group, or null
           );
         }
       }
@@ -1174,16 +1209,40 @@ public class AnnotationFile
                 (SequenceI) _combine_args[1], // refSeq
                 (_combine_args[2] == null) ? null : groupRefLookup
                         .get(_combine_args[2]) // the reference group,
-                                                        // or null
+                                               // or null
         );
       }
     }
     return modified;
   }
 
+  /**
+   * resolve a structural model and generate and add an alignment sequence for
+   * it
+   * 
+   * @param refSeq2
+   * @param tempId
+   * @param urlToModel
+   * @param urlToPairwise
+   * @return true if model and sequence was added
+   */
+  private boolean add_structmodel(SequenceI refSeq2, String tempId,
+          String urlToModel, String urlToPairwise)
+  {
+
+    return false;
+  }
+
+  private void add_structmodel(StringTokenizer st)
+  {
+
+    // TODO Auto-generated method stub
+
+  }
+
   private void parseHideCols(ColumnSelection colSel, String nextToken)
   {
-    StringTokenizer inval = new StringTokenizer(nextToken,",");
+    StringTokenizer inval = new StringTokenizer(nextToken, ",");
     while (inval.hasMoreTokens())
     {
       String range = inval.nextToken().trim();
@@ -1301,8 +1360,8 @@ public class AnnotationFile
         }
       }
       if (hasSymbols
-              && (token.equals("H") || token.equals("E")
-                      || token.equals("S") || token.equals(" ")))
+              && (token.length() == 1 && "()<>[]{}AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"
+                      .contains(token)))
       {
         // Either this character represents a helix or sheet
         // or an integer which can be displayed
@@ -1761,6 +1820,10 @@ public class AnnotationFile
    */
   public String printCSVAnnotations(AlignmentAnnotation[] annotations)
   {
+    if (annotations == null)
+    {
+      return "";
+    }
     StringBuffer sp = new StringBuffer();
     for (int i = 0; i < annotations.length; i++)
     {