JAL-2136 New Phyre2 branch + attempt to resynced with develop
[jalview.git] / src / jalview / io / AnnotationFile.java
index b72184b..49e99a1 100755 (executable)
@@ -26,13 +26,15 @@ import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.DynamicData;
+import jalview.datamodel.DynamicData.DataType;
 import jalview.datamodel.GraphLine;
+import jalview.datamodel.HiddenColumns;
 import jalview.datamodel.HiddenSequences;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.PDBEntry.Type;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
-import jalview.gui.Desktop;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ColourSchemeProperty;
 import jalview.structure.StructureSelectionManager;
@@ -56,6 +58,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();
@@ -82,7 +106,6 @@ public class AnnotationFile
     return newline;
   }
 
-  StringBuffer text;
 
   private void init()
   {
@@ -114,23 +137,22 @@ public class AnnotationFile
    */
   public class ViewDef
   {
-    public String viewname;
+    // TODO this class is not used - remove?
+    public final String viewname;
 
-    public HiddenSequences hidseqs;
+    public final HiddenSequences hidseqs;
 
-    public ColumnSelection hiddencols;
+    public final HiddenColumns hiddencols;
 
-    public Vector visibleGroups;
+    public final Hashtable hiddenRepSeqs;
 
-    public Hashtable hiddenRepSeqs;
-
-    public ViewDef(String viewname, HiddenSequences hidseqs,
-            ColumnSelection hiddencols, Hashtable hiddenRepSeqs)
+    public ViewDef(String vname, HiddenSequences hseqs,
+            HiddenColumns hcols, Hashtable hRepSeqs)
     {
-      this.viewname = viewname;
-      this.hidseqs = hidseqs;
-      this.hiddencols = hiddencols;
-      this.hiddenRepSeqs = hiddenRepSeqs;
+      this.viewname = vname;
+      this.hidseqs = hseqs;
+      this.hiddencols = hcols;
+      this.hiddenRepSeqs = hRepSeqs;
     }
   }
 
@@ -146,7 +168,8 @@ public class AnnotationFile
    */
   public String printAnnotations(AlignmentAnnotation[] annotations,
           List<SequenceGroup> list, Hashtable properties,
-          ColumnSelection cs, AlignmentI al, ViewDef view)
+ HiddenColumns cs,
+          AlignmentI al, ViewDef view)
   {
     if (view != null)
     {
@@ -156,7 +179,7 @@ public class AnnotationFile
       }
       if (list == null)
       {
-        list = view.visibleGroups;
+        // list = view.visibleGroups;
       }
       if (cs == null)
       {
@@ -175,7 +198,7 @@ public class AnnotationFile
     if (cs != null && cs.hasHiddenColumns())
     {
       text.append("VIEW_HIDECOLS\t");
-      List<int[]> hc = cs.getHiddenColumns();
+      List<int[]> hc = cs.getHiddenRegions();
       boolean comma = false;
       for (int[] r : hc)
       {
@@ -541,7 +564,7 @@ public class AnnotationFile
     return false;
   }
 
-  public void printGroups(List<SequenceGroup> list)
+  protected void printGroups(List<SequenceGroup> list)
   {
     SequenceI seqrep = null;
     for (SequenceGroup sg : list)
@@ -587,7 +610,8 @@ public class AnnotationFile
       if (sg.cs != null)
       {
         text.append("colour=");
-        text.append(sg.cs.toString());
+        text.append(ColourSchemeProperty.getColourName(sg.cs
+                .getColourScheme()));
         text.append("\t");
         if (sg.cs.getThreshold() != 0)
         {
@@ -661,23 +685,26 @@ public class AnnotationFile
     }
   }
 
-  SequenceI refSeq = null;
-
-  String refSeqId = null;
 
   public boolean annotateAlignmentView(AlignViewportI viewport,
           String file, DataSourceType protocol)
   {
     ColumnSelection colSel = viewport.getColumnSelection();
+    HiddenColumns hidden = viewport.getAlignment().getHiddenColumns();
     if (colSel == null)
     {
       colSel = new ColumnSelection();
     }
-    boolean rslt = readAnnotationFile(viewport.getAlignment(), colSel,
+    if (hidden == null)
+    {
+      hidden = new HiddenColumns();
+    }
+    boolean rslt = readAnnotationFile(viewport.getAlignment(), hidden,
             file, protocol);
-    if (rslt && (colSel.hasSelectedColumns() || colSel.hasHiddenColumns()))
+    if (rslt && (colSel.hasSelectedColumns() || hidden.hasHiddenColumns()))
     {
       viewport.setColumnSelection(colSel);
+      viewport.getAlignment().setHiddenColumns(hidden);
     }
 
     return rslt;
@@ -689,7 +716,7 @@ public class AnnotationFile
     return readAnnotationFile(al, null, file, sourceType);
   }
 
-  public boolean readAnnotationFile(AlignmentI al, ColumnSelection colSel,
+  public boolean readAnnotationFile(AlignmentI al, HiddenColumns hidden,
           String file, DataSourceType sourceType)
   {
     baseUri = "";
@@ -740,7 +767,7 @@ public class AnnotationFile
       }
       if (in != null)
       {
-        return parseAnnotationFrom(al, colSel, in);
+        return parseAnnotationFrom(al, hidden, in);
       }
 
     } catch (Exception ex)
@@ -757,20 +784,8 @@ 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,
+  public boolean parseAnnotationFrom(AlignmentI al, HiddenColumns hidden,
           BufferedReader in) throws Exception
   {
     nlinesread = 0;
@@ -962,12 +977,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)
@@ -981,11 +990,11 @@ public class AnnotationFile
         {
           if (st.hasMoreTokens())
           {
-            if (colSel == null)
+            if (hidden == null)
             {
-              colSel = new ColumnSelection();
+              hidden = new HiddenColumns();
             }
-            parseHideCols(colSel, st.nextToken());
+            parseHideCols(hidden, st.nextToken());
           }
           modified = true;
           continue;
@@ -999,7 +1008,7 @@ public class AnnotationFile
           }
           if (sr != null)
           {
-            if (colSel == null)
+            if (hidden == null)
             {
               System.err
                       .println("Cannot process HIDE_INSERTIONS without an alignment view: Ignoring line: "
@@ -1008,19 +1017,27 @@ public class AnnotationFile
             else
             {
               // consider deferring this till after the file has been parsed ?
-              colSel.hideInsertionsFor(sr);
+              hidden.hideInsertionsFor(sr);
             }
           }
           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 <Query> <TemplateSeqId> <ModelFile> <FastaMappingFile>
-          // <Confidence> <%.I.D>
-          // <MatchStart> <MatchEnd> <Coverage> [<Other Information>]
+          // expects STRUCTMODEL <Query> <TemplateSeqId> <ModelFile>
+          // <FastaMappingFile>
           String querySeqId = !st.hasMoreTokens() ? "" : st.nextToken();
           SequenceI querySeq = al.findName(querySeqId);
           if (st.hasMoreTokens()) {
@@ -1033,19 +1050,16 @@ public class AnnotationFile
             }
             else
             {
-              String tempId = st.nextToken();
-              String fastaMapping = st.nextToken();
-              String confidence = !st.hasMoreTokens() ? "" : 100
-                      * Double.valueOf(st.nextToken()) + "";
-              String pid = !st.hasMoreTokens() ? "" : st.nextToken();
-              String alignRange = !st.hasMoreTokens() ? "" : st.nextToken()
-                      + "-" + st.nextToken();
-              String otherInfo = !st.hasMoreTokens() ? "" : st.nextToken();
-              String coverage = "";
-              if (add_structmodel(al, querySeq, refSeq, tempId,
-                      fastaMapping,
-                      alignRange, coverage,
-                      confidence, pid, otherInfo))
+              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;
               }
@@ -1054,9 +1068,8 @@ public class AnnotationFile
           if (failedtoadd)
           {
             System.err
-                    .println("Need <Query> <TemplateSeqId> <ModelFile> <FastaMappingFile> <Confidence> <%.I.D> <MatchStart> <MatchEnd> <Coverage> [<Other Information>] as tab separated fields after"
-                            + STRUCTMODEL
-                            + ".\nNote: other information could be provided in html format ");
+                    .println("Need minimum of <Query> <TemplateSeqId> <ModelFile> <FastaMappingFile> as tab separated fields after"
+                            + STRUCTMODEL);
           } else {
             modified = true;
           }
@@ -1261,42 +1274,46 @@ public class AnnotationFile
     return modified;
   }
 
+
   /**
-   * 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 querySequence,
+  static boolean processStructModel(AlignmentI al, SequenceI querySequence,
           SequenceI templateSeq,
-          String modelFile, String fastaFile, String aRange,
-          String coverage, String confidence,
-          String pid, String otherInfo)
+ String[] structModelHeader,
+          String[] structModelData, String baseUri)
   {
     String warningMessage = null;
     boolean added = false;
     try {
-      String structureModelFile = resolveAbsolute(modelFile);
-      String fastaMappingFile = resolveAbsolute(fastaFile.replaceAll(
-              ".fasta.jal", ".fasta"));
+      String structureModelFile = resolveAbsolutePath(structModelData[2],
+              baseUri);
+      String fastaMappingFile = resolveAbsolutePath(structModelData[3],
+              baseUri);
       // System.out.println("Model File >> " + structureModelFile);
       // System.out.println("Fasta File >> " + fastaMappingFile);
-      PDBEntry phyre2PDBEntry = new PDBEntry(modelFile, null, Type.FILE,
+      String modelName = StructureFile.safeName(structureModelFile);
+      PDBEntry phyre2PDBEntry = new PDBEntry(modelName, " ",
+              Type.PDB,
               structureModelFile);
-      String phyre2ModelDesc = generatePhyre2InfoHTMLTable(aRange,
-              coverage, confidence, pid, otherInfo);
-      phyre2PDBEntry.setProperty("PHYRE2_MODEL_INFO", phyre2ModelDesc);
+      List<DynamicData> phyreDD = generatePhyreDynamicDataList(
+              structModelHeader, structModelData);
+      phyre2PDBEntry.setProperty("DYNAMIC_DATA_PHYRE2", phyreDD);
       templateSeq.getDatasetSequence().addPDBId(phyre2PDBEntry);
       if (querySequence != null)
       {
         querySequence.getDatasetSequence().addPDBId(phyre2PDBEntry);
       }
       StructureSelectionManager ssm = StructureSelectionManager
-              .getStructureSelectionManager(Desktop.instance);
+              .getStructureSelectionManager();
       ssm.registerPhyre2Template(structureModelFile, fastaMappingFile);
       added = true;
 
@@ -1312,53 +1329,46 @@ public class AnnotationFile
     return added;
   }
 
-  private String generatePhyre2InfoHTMLTable(String aRange,
-          String coverage, String confidence, String pid, String otherInfo)
+  static List<DynamicData> generatePhyreDynamicDataList(
+          String[] headerArray,
+          String[] dataArray)
   {
-    StringBuilder phyre2InfoBuilder = new StringBuilder();
-    phyre2InfoBuilder.append("<html><table border=\"1\" width=100%>");
-    phyre2InfoBuilder
-            .append("<tr><td colspan=\"2\"><strong>Phyre2 Template Info</strong></td></tr>");
-    if (aRange != null && !aRange.isEmpty())
-    {
-      phyre2InfoBuilder.append("<tr><td>").append("Aligned range")
-              .append("</td><td>").append(aRange).append("</td></tr>");
-    }
-    if (coverage != null && !coverage.isEmpty())
-    {
-      phyre2InfoBuilder.append("<tr><td>").append("Coverage")
-              .append("</td><td>").append(coverage).append("</td></tr>");
-    }
-    if (confidence != null && !confidence.isEmpty())
+
+    if (headerArray == null || dataArray == null)
     {
-      phyre2InfoBuilder.append("<tr><td>").append("Confidence")
-              .append("</td><td>").append(confidence).append("</td></tr>");
+      throw new IllegalArgumentException(
+              "Header or data arrays must not be null");
     }
-    if (pid != null && !pid.isEmpty())
+
+    if (headerArray.length != dataArray.length)
     {
-      phyre2InfoBuilder.append("<tr><td>").append("%.i.d")
-              .append("</td><td>").append(pid).append("</td></tr>");
+      throw new IllegalArgumentException(
+              "Header and data arrays must be of same lenght");
     }
-    if (otherInfo != null && !otherInfo.isEmpty())
+    List<DynamicData> dynamicDataList = new ArrayList<DynamicData>();
+    int x = 0;
+    for (String data : dataArray)
     {
-      phyre2InfoBuilder.append("<tr><td>").append("Other information")
-              .append("</td><td>").append(otherInfo).append("</td></tr>");
+      // first four column should be hidden;
+      boolean show = (x > 4);
+      dynamicDataList.add(new DynamicData(headerArray[x], data, DataType.S,
+              "PHYRE2", show));
+      x++;
     }
-    phyre2InfoBuilder.append("</table></html>");
-    return phyre2InfoBuilder.toString();
+    return dynamicDataList;
   }
 
-  private String resolveAbsolute(String relURI)
+  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)
+  private void parseHideCols(HiddenColumns hidden, String nextToken)
   {
     StringTokenizer inval = new StringTokenizer(nextToken, ",");
     while (inval.hasMoreTokens())
@@ -1370,7 +1380,7 @@ public class AnnotationFile
         from = to = Integer.parseInt(range);
         if (from >= 0)
         {
-          colSel.hideColumns(from, to);
+          hidden.hideColumns(from, to);
         }
       }
       else
@@ -1386,7 +1396,7 @@ public class AnnotationFile
         }
         if (from > 0 && to >= from)
         {
-          colSel.hideColumns(from, to);
+          hidden.hideColumns(from, to);
         }
       }
     }
@@ -1965,7 +1975,7 @@ public class AnnotationFile
     return printAnnotations(viewport.isShowAnnotation() ? viewport
             .getAlignment().getAlignmentAnnotation() : null, viewport
             .getAlignment().getGroups(), viewport.getAlignment()
-            .getProperties(), viewport.getColumnSelection(),
+            .getProperties(), viewport.getAlignment().getHiddenColumns(),
             viewport.getAlignment(), null);
   }