JAL-2136 broken build fix attempt
[jalview.git] / src / jalview / io / AnnotationFile.java
index eca27a7..206d971 100755 (executable)
@@ -34,13 +34,13 @@ import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ColourSchemeProperty;
-import jalview.schemes.UserColourScheme;
 import jalview.structure.StructureSelectionManager;
+import jalview.util.ColorUtils;
 
+import java.awt.Color;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
-import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.StringReader;
 import java.net.URL;
@@ -55,6 +55,28 @@ import java.util.Vector;
 
 public class AnnotationFile
 {
+  StringBuffer text;
+
+  SequenceI refSeq = null;
+
+  String refSeqId = null;
+
+  String[] StructModelHeader = null;
+
+  long nlinesread = 0;
+
+  String lastread = "";
+
+  /**
+   * used for resolving absolute references to resources relative to
+   * annotationFile location
+   */
+  String baseUri = "";
+
+  private static String GRAPHLINE = "GRAPHLINE", COMBINE = "COMBINE",
+          STRUCTMODEL = "STRUCTMODEL",
+          HEADER_STRUCT_MODEL = "HEADER_STRUCT_MODEL";
+
   public AnnotationFile()
   {
     init();
@@ -81,7 +103,6 @@ public class AnnotationFile
     return newline;
   }
 
-  StringBuffer text;
 
   private void init()
   {
@@ -586,7 +607,7 @@ public class AnnotationFile
       if (sg.cs != null)
       {
         text.append("colour=");
-        text.append(ColourSchemeProperty.getColourName(sg.cs));
+        text.append(sg.cs.toString());
         text.append("\t");
         if (sg.cs.getThreshold() != 0)
         {
@@ -660,12 +681,9 @@ public class AnnotationFile
     }
   }
 
-  SequenceI refSeq = null;
-
-  String refSeqId = null;
 
   public boolean annotateAlignmentView(AlignViewportI viewport,
-          String file, String protocol)
+          String file, DataSourceType protocol)
   {
     ColumnSelection colSel = viewport.getColumnSelection();
     if (colSel == null)
@@ -683,19 +701,19 @@ public class AnnotationFile
   }
 
   public boolean readAnnotationFile(AlignmentI al, String file,
-          String protocol)
+          DataSourceType sourceType)
   {
-    return readAnnotationFile(al, null, file, protocol);
+    return readAnnotationFile(al, null, file, sourceType);
   }
 
   public boolean readAnnotationFile(AlignmentI al, ColumnSelection colSel,
-          String file, String protocol)
+          String file, DataSourceType sourceType)
   {
     baseUri = "";
     BufferedReader in = null;
     try
     {
-      if (protocol.equals(AppletFormatAdapter.FILE))
+      if (sourceType == DataSourceType.FILE)
       {
         in = new BufferedReader(new FileReader(file));
         baseUri = new File(file).getParent();
@@ -708,7 +726,7 @@ public class AnnotationFile
           baseUri += "/";
         }
       }
-      else if (protocol.equals(AppletFormatAdapter.URL))
+      else if (sourceType == DataSourceType.URL)
       {
         URL url = new URL(file);
         in = new BufferedReader(new InputStreamReader(url.openStream()));
@@ -721,13 +739,13 @@ public class AnnotationFile
           baseUri = baseUri.substring(0, baseUri.lastIndexOf("/")) + "/";
         }
       }
-      else if (protocol.equals(AppletFormatAdapter.PASTE))
+      else if (sourceType == DataSourceType.PASTE)
       {
         in = new BufferedReader(new StringReader(file));
         // TODO - support mimencoded PDBs for a paste.. ?
         baseUri = "";
       }
-      else if (protocol.equals(AppletFormatAdapter.CLASSLOADER))
+      else if (sourceType == DataSourceType.CLASSLOADER)
       {
         java.io.InputStream is = getClass().getResourceAsStream("/" + file);
         if (is != null)
@@ -756,18 +774,6 @@ public class AnnotationFile
     return false;
   }
 
-  long nlinesread = 0;
-
-  String lastread = "";
-
-  /**
-   * used for resolving absolute references to resources relative to
-   * annotationFile location
-   */
-  String baseUri = "";
-
-  private static String GRAPHLINE = "GRAPHLINE", COMBINE = "COMBINE",
-          STRUCTMODEL = "STRUCTMODEL";
 
   public boolean parseAnnotationFrom(AlignmentI al, ColumnSelection colSel,
           BufferedReader in) throws Exception
@@ -961,12 +967,6 @@ public class AnnotationFile
           modified = true;
           continue;
         }
-        // else if (token.equalsIgnoreCase("VIEW_DEF"))
-        // {
-        // addOrSetView(al,st);
-        // modified = true;
-        // continue;
-        // }
         else if (token.equalsIgnoreCase("VIEW_SETREF"))
         {
           if (refSeq != null)
@@ -1013,12 +1013,23 @@ public class AnnotationFile
           modified = true;
           continue;
         }
+        else if (token.equalsIgnoreCase(HEADER_STRUCT_MODEL))
+        {
+          int hSize = st.countTokens();
+          StructModelHeader = new String[hSize];
+          for (int x = 0; x < hSize; x++)
+          {
+            StructModelHeader[x] = st.nextToken();
+          }
+          continue;
+        }
         else if (token.equalsIgnoreCase(STRUCTMODEL))
         {
           boolean failedtoadd = true;
-          // expect
-          // STRUCTMODEL <QUERYID> <TemplateID> <URL to model> <URL to
-          // alignment>
+          // expects STRUCTMODEL <Query> <TemplateSeqId> <ModelFile>
+          // <FastaMappingFile>
+          String querySeqId = !st.hasMoreTokens() ? "" : st.nextToken();
+          SequenceI querySeq = al.findName(querySeqId);
           if (st.hasMoreTokens()) {
             refSeq = al.findName(refSeqId = st.nextToken());
             if (refSeq == null)
@@ -1029,12 +1040,16 @@ public class AnnotationFile
             }
             else
             {
-              String tempId = st.nextToken();
-              String urlToModel = st.nextToken();
-              String urlToPairwise = st.hasMoreTokens() ? st.nextToken()
-                      : "";
-              if (add_structmodel(al, refSeq, tempId, urlToModel,
-                      urlToPairwise))
+              int tSize = st.countTokens() + 2;
+              String[] rowData = new String[tSize];
+              rowData[0] = querySeqId;
+              rowData[1] = refSeqId;
+              for (int x = 2; x < tSize; x++)
+              {
+                rowData[x] = st.nextToken();
+              }
+              if (processStructModel(al, querySeq, refSeq,
+                      StructModelHeader, rowData, baseUri))
               {
                 failedtoadd = false;
               }
@@ -1043,7 +1058,7 @@ public class AnnotationFile
           if (failedtoadd)
           {
             System.err
-                    .println("Need <QueryId> <TemplateId> <URL to Model> [<URL to pairwise alignment>] as tab separated fields after "
+                    .println("Need minimum of <Query> <TemplateSeqId> <ModelFile> <FastaMappingFile> as tab separated fields after"
                             + STRUCTMODEL);
           } else {
             modified = true;
@@ -1250,85 +1265,48 @@ public class AnnotationFile
   }
 
   /**
-   * resolve a structural model and generate and add an alignment sequence for
-   * it
+   * Resolve structural model to a reference sequence and register it to
+   * StructureSelectionManager
    * 
-   * @param refSeq2
-   * @param tempId
-   * @param urlToModel
-   * @param urlToPairwise
+   * @param al
+   * @param querySequence
+   * @param templateSeq
+   * @param structModelHeader
+   * @param structModelData
    * @return true if model and sequence was added
    */
-  private boolean add_structmodel(AlignmentI al, SequenceI refSeq2, String tempId,
-          String urlToModel, String urlToPairwise)
+  static boolean processStructModel(AlignmentI al, SequenceI querySequence,
+          SequenceI templateSeq,
+ String[] structModelHeader,
+          String[] structModelData, String baseUri)
   {
-    String warningMessage = null, modelPath = null, modelProt = null, aliPath = null, aliProt = null;
+    String warningMessage = null;
     boolean added = false;
     try {
-      // locate tempId. if it exists, will need to merge, otherwise:
-      SequenceI templateSeq = al.findName(tempId);
-      // 1. load urlToModel
-      modelPath = resolveAbsolute(urlToModel);
-      modelProt = AppletFormatAdapter.checkProtocol(modelPath);
-      // need to transfer to local temp file ?
-      PDBEntry modelpe = new PDBEntry(tempId, null, Type.FILE, modelPath);
-      PDBEntry templpe = new PDBEntry(tempId, null, Type.FILE, modelPath);
-      refSeq2.addPDBId(modelpe);
-      aliPath = resolveAbsolute(urlToPairwise);
-      aliProt = AppletFormatAdapter.checkProtocol(aliPath);
-      // 2. load urlToPairwise
-      AlignmentI pwa = new AppletFormatAdapter().readFile(aliPath, aliProt,
-              "FASTA");
-      SequenceI qPw = null, tPw = null;
-      if (pwa != null)
-      {
-        // resolve query/template sequences in provided alignment
-        qPw = pwa.findName(refSeqId);
-        tPw = pwa.findName(tempId);
-      }
-      if (false)
-      // (qPw != null && tPw != null)
-      {
-        // not yet complete
-        // refalQ vvva--addrvvvtttddd
-        // refalT ---aaaa---sss---ddd
-        // profalQ ---v-v-v-a.-.-a---dd--r--vvvtt--td--dd
-        // profalT ---.-.-.-aa-a-a---..--.--sss..--.d--dd
-        // Pragmatic solution here:
-        // Map templpe onto refalT only where refalT and refalQ are both
-        // non-gaps
-
-        // columns for start..end in refSeq2
-        int[] gapMap = refSeq2.gapMap();
-        // insert gaps in tPw
-        int curi = 0, width = refSeq2.getLength();
-        // TBC
-      }
-      else
-      {
-        // assume 1:1 - so synthesise sequences to use to construct mapping
-        StructureFile pdbf = StructureSelectionManager
-                .getStructureSelectionManager().setMapping(false,
-                        new SequenceI[] { refSeq2.getDatasetSequence() },
-                        null, modelPath, modelProt);
-        refSeq2.getDatasetSequence().addPDBId(modelpe);
-        if (templateSeq == null && tPw != null)
-        {
-          tPw.createDatasetSequence();
-          tPw.getDatasetSequence().addPDBId(templpe); // needs to set mapping based on model yet...
-          al.addSequence(tPw);
-          added = true;
-        }
-      }
-    // 3. pad/insert gaps in urlToPairwise according to gaps already present in
-    // refSeq2
-    // 4. add padded tempId sequence to alignment
-    // 4. associate urlToModel with refSeq2 based on position map provided by
-    // urlToPairwise
-    // 5. associate urlToModel with tempId based on position map provided by
-    // urlToPairwise
-    // start a thread to load urlToModel and process/annotate sequences.
-    } catch (IOException x)
+      String structureModelFile = resolveAbsolutePath(structModelData[2],
+              baseUri);
+      String fastaMappingFile = resolveAbsolutePath(structModelData[3],
+              baseUri);
+      // System.out.println("Model File >> " + structureModelFile);
+      // System.out.println("Fasta File >> " + fastaMappingFile);
+      String modelName = StructureFile.safeName(structureModelFile);
+      PDBEntry phyre2PDBEntry = new PDBEntry(modelName, " ",
+              Type.PDB,
+              structureModelFile);
+      String phyre2ModelDesc = generatePhyre2InfoHTMLTable(
+              structModelHeader, structModelData);
+      phyre2PDBEntry.setProperty("PHYRE2_MODEL_INFO", phyre2ModelDesc);
+      templateSeq.getDatasetSequence().addPDBId(phyre2PDBEntry);
+      if (querySequence != null)
+      {
+        querySequence.getDatasetSequence().addPDBId(phyre2PDBEntry);
+      }
+      StructureSelectionManager ssm = StructureSelectionManager
+              .getStructureSelectionManager();
+      ssm.registerPhyre2Template(structureModelFile, fastaMappingFile);
+      added = true;
+
+    } catch (Exception x)
     {
       warningMessage = x.toString();
     } finally {
@@ -1336,18 +1314,51 @@ public class AnnotationFile
       {
         System.err.println("Warnings whilst processing STRUCTMODEL: "+warningMessage);
       }
-      return added;
     }
+    return added;
+  }
+
+  static String generatePhyre2InfoHTMLTable(String[] structModelHeader,
+          String[] structModelData)
+  {
+    StringBuilder phyre2InfoBuilder = new StringBuilder();
+    if (isGenerateStructInfoHtml(structModelHeader, structModelData))
+    {
+      phyre2InfoBuilder.append("<html><table border=\"1\" width=100%>")
+              .append("<tr><td colspan=\"2\"><strong>Phyre2 Template Info</strong></td></tr>");
+      for (int x = 4; x < structModelData.length; x++)
+      {
+        phyre2InfoBuilder.append("<tr><td>").append(structModelHeader[x])
+                .append("</td><td>").append(structModelData[x])
+                .append("</td></tr>");
+      }
+      phyre2InfoBuilder.append("</table></html>");
+    }
+    return phyre2InfoBuilder.toString();
   }
 
-  private String resolveAbsolute(String relURI)
+  static boolean isGenerateStructInfoHtml(String[] header, String[] data)
+  {
+    boolean generate = true;
+    if (header == null || data == null)
+    {
+      return false;
+    }
+    if (header.length < 3 || data.length < 3)
+    {
+      generate = false;
+    }
+    return generate;
+  }
+
+  static String resolveAbsolutePath(String relURI, String _baseUri)
   {
     if (relURI.indexOf(":/") > -1 || relURI.startsWith("/")
-            || "".equals(baseUri) || relURI.startsWith(baseUri))
+            || "".equals(_baseUri) || relURI.startsWith(_baseUri))
     {
       return relURI;
     }
-    return baseUri + relURI;
+    return _baseUri + relURI;
   }
 
   private void parseHideCols(ColumnSelection colSel, String nextToken)
@@ -1394,29 +1405,21 @@ public class AnnotationFile
 
   Annotation parseAnnotation(String string, int graphStyle)
   {
-    boolean hasSymbols = (graphStyle == AlignmentAnnotation.NO_GRAPH); // don't
-    // do the
-    // glyph
-    // test
-    // if we
-    // don't
-    // want
-    // secondary
-    // structure
+    // don't do the glyph test if we don't want secondary structure
+    boolean hasSymbols = (graphStyle == AlignmentAnnotation.NO_GRAPH);
     String desc = null, displayChar = null;
     char ss = ' '; // secondaryStructure
     float value = 0;
     boolean parsedValue = false, dcset = false;
 
     // find colour here
-    java.awt.Color colour = null;
+    Color colour = null;
     int i = string.indexOf("[");
     int j = string.indexOf("]");
     if (i > -1 && j > -1)
     {
-      UserColourScheme ucs = new UserColourScheme();
-
-      colour = ucs.getColourFromString(string.substring(i + 1, j));
+      colour = ColorUtils.parseColourString(string.substring(i + 1,
+              j));
       if (i > 0 && string.charAt(i - 1) == ',')
       {
         // clip the preceding comma as well
@@ -1518,7 +1521,7 @@ public class AnnotationFile
 
   void colourAnnotations(AlignmentI al, String label, String colour)
   {
-    UserColourScheme ucs = new UserColourScheme(colour);
+    Color awtColour = ColorUtils.parseColourString(colour);
     Annotation[] annotations;
     for (int i = 0; i < al.getAlignmentAnnotation().length; i++)
     {
@@ -1529,7 +1532,7 @@ public class AnnotationFile
         {
           if (annotations[j] != null)
           {
-            annotations[j].colour = ucs.findColour('A');
+            annotations[j].colour = awtColour;
           }
         }
       }
@@ -1599,15 +1602,22 @@ public class AnnotationFile
           SequenceGroup groupRef)
   {
     String group = st.nextToken();
-    AlignmentAnnotation annotation = null, alannot[] = al
-            .getAlignmentAnnotation();
-    float value = new Float(st.nextToken()).floatValue();
+    AlignmentAnnotation[] alannot = al.getAlignmentAnnotation();
+    String nextToken = st.nextToken();
+    float value = 0f;
+    try
+    {
+      value = Float.valueOf(nextToken);
+    } catch (NumberFormatException e)
+    {
+      System.err.println("line " + nlinesread + ": Threshold '" + nextToken
+              + "' invalid, setting to zero");
+    }
     String label = st.hasMoreTokens() ? st.nextToken() : null;
-    java.awt.Color colour = null;
+    Color colour = null;
     if (st.hasMoreTokens())
     {
-      UserColourScheme ucs = new UserColourScheme(st.nextToken());
-      colour = ucs.findColour('A');
+      colour = ColorUtils.parseColourString(st.nextToken());
     }
     if (alannot != null)
     {
@@ -1621,10 +1631,6 @@ public class AnnotationFile
         }
       }
     }
-    if (annotation == null)
-    {
-      return;
-    }
   }
 
   void addGroup(AlignmentI al, StringTokenizer st)
@@ -1784,8 +1790,7 @@ public class AnnotationFile
     if (sg != null)
     {
       String keyValue, key, value;
-      ColourSchemeI def = sg.cs;
-      sg.cs = null;
+      ColourSchemeI def = sg.getColourScheme();
       while (st.hasMoreTokens())
       {
         keyValue = st.nextToken();
@@ -1798,7 +1803,8 @@ public class AnnotationFile
         }
         else if (key.equalsIgnoreCase("colour"))
         {
-          sg.cs = ColourSchemeProperty.getColour(al, value);
+          sg.cs.setColourScheme(ColourSchemeProperty
+                  .getColourScheme(al, value));
         }
         else if (key.equalsIgnoreCase("pidThreshold"))
         {
@@ -1808,9 +1814,8 @@ public class AnnotationFile
         else if (key.equalsIgnoreCase("consThreshold"))
         {
           sg.cs.setConservationInc(Integer.parseInt(value));
-          Conservation c = new Conservation("Group", 3,
-                  sg.getSequences(null), sg.getStartRes(),
-                  sg.getEndRes() + 1);
+          Conservation c = new Conservation("Group", sg.getSequences(null),
+                  sg.getStartRes(), sg.getEndRes() + 1);
 
           c.calculate();
           c.verdict(false, 25); // TODO: refer to conservation percent threshold
@@ -1820,7 +1825,7 @@ public class AnnotationFile
         }
         else if (key.equalsIgnoreCase("outlineColour"))
         {
-          sg.setOutlineColour(new UserColourScheme(value).findColour('A'));
+          sg.setOutlineColour(ColorUtils.parseColourString(value));
         }
         else if (key.equalsIgnoreCase("displayBoxes"))
         {
@@ -1840,11 +1845,11 @@ public class AnnotationFile
         }
         else if (key.equalsIgnoreCase("textCol1"))
         {
-          sg.textColour = new UserColourScheme(value).findColour('A');
+          sg.textColour = ColorUtils.parseColourString(value);
         }
         else if (key.equalsIgnoreCase("textCol2"))
         {
-          sg.textColour2 = new UserColourScheme(value).findColour('A');
+          sg.textColour2 = ColorUtils.parseColourString(value);
         }
         else if (key.equalsIgnoreCase("textColThreshold"))
         {
@@ -1852,9 +1857,8 @@ public class AnnotationFile
         }
         else if (key.equalsIgnoreCase("idColour"))
         {
-          // consider warning if colour doesn't resolve to a real colour
-          sg.setIdColour((def = new UserColourScheme(value))
-                  .findColour('A'));
+          Color idColour = ColorUtils.parseColourString(value);
+          sg.setIdColour(idColour == null ? Color.black : idColour);
         }
         else if (key.equalsIgnoreCase("hide"))
         {
@@ -1868,9 +1872,9 @@ public class AnnotationFile
         }
         sg.recalcConservation();
       }
-      if (sg.cs == null)
+      if (sg.getColourScheme() == null)
       {
-        sg.cs = def;
+        sg.setColourScheme(def);
       }
     }
   }