Merge branch 'Jalview-JS/develop' into merge_js_develop
[jalview.git] / src / jalview / project / Jalview2XML.java
index 84fda34..e88a4a1 100644 (file)
@@ -42,6 +42,7 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.GeneLocus;
 import jalview.datamodel.GraphLine;
+import jalview.datamodel.HiddenMarkovModel;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.Point;
 import jalview.datamodel.RnaViewerModel;
@@ -74,6 +75,7 @@ import jalview.gui.TreePanel;
 import jalview.io.BackupFiles;
 import jalview.io.DataSourceType;
 import jalview.io.FileFormat;
+import jalview.io.HMMFile;
 import jalview.io.NewickFile;
 import jalview.math.Matrix;
 import jalview.math.MatrixI;
@@ -97,9 +99,9 @@ import jalview.viewmodel.ViewportRanges;
 import jalview.viewmodel.seqfeatures.FeatureRendererModel;
 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
 import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
-import jalview.ws.jws2.Jws2Discoverer;
+import jalview.ws.api.ServiceWithParameters;
+import jalview.ws.jws2.PreferredServiceRegistry;
 import jalview.ws.jws2.dm.AAConSettings;
-import jalview.ws.jws2.jabaws2.Jws2Instance;
 import jalview.ws.params.ArgumentI;
 import jalview.ws.params.AutoCalcSetting;
 import jalview.ws.params.WsParamSetI;
@@ -226,6 +228,8 @@ public class Jalview2XML
 
   private static final String RNA_PREFIX = "rna_";
 
+  private static final String HMMER_PREFIX = "hmmer_";
+
   private static final String UTF_8 = "UTF-8";
 
   /**
@@ -1105,6 +1109,9 @@ public class Jalview2XML
         jseq.getFeatures().add(features);
       }
 
+      /*
+       * save PDB entries for sequence
+       */
       if (jdatasq.getAllPDBEntries() != null)
       {
         Enumeration<PDBEntry> en = jdatasq.getAllPDBEntries().elements();
@@ -1197,6 +1204,11 @@ public class Jalview2XML
 
       saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
 
+      if (jds.hasHMMProfile())
+      {
+        saveHmmerProfile(jout, jseq, jds);
+      }
+
       // jms.addJSeq(jseq);
       object.getJSeq().add(jseq);
     }
@@ -1745,7 +1757,39 @@ public class Jalview2XML
     }
     return object;
   }
+  /**
+   * Saves the HMMER profile associated with the sequence as a file in the jar,
+   * in HMMER format, and saves the name of the file as a child element of the
+   * XML sequence element
+   * 
+   * @param jout
+   * @param xmlSeq
+   * @param seq
+   */
+  protected void saveHmmerProfile(JarOutputStream jout, JSeq xmlSeq,
+          SequenceI seq)
+  {
+    HiddenMarkovModel profile = seq.getHMM();
+    if (profile == null)
+    {
+      warn("Want to save HMM profile for " + seq.getName()
+              + " but none found");
+      return;
+    }
+    HMMFile hmmFile = new HMMFile(profile);
+    String hmmAsString = hmmFile.print();
+    String jarEntryName = HMMER_PREFIX + nextCounter();
+    try
+    {
+      writeJarEntry(jout, jarEntryName, hmmAsString.getBytes());
+      xmlSeq.setHmmerProfile(jarEntryName);
+    } catch (IOException e)
+    {
+      warn("Error saving HMM profile: " + e.getMessage());
+    }
+  }
 
+    
   /**
    * Writes PCA viewer attributes and computed values to an XML model object and
    * adds it to the JalviewModel. Any exceptions are reported by logging.
@@ -2140,9 +2184,9 @@ public class Jalview2XML
       }
       else if (!matchedFile.equals(pdbentry.getFile()))
       {
-        Cache.log.warn(
-                "Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
-                        + pdbentry.getFile());
+         Cache.log.warn(
+                  "Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
+                          + pdbentry.getFile());
       }
       // record the
       // file so we
@@ -2424,7 +2468,7 @@ public class Jalview2XML
     if (calcIdParam.getVersion().equals("1.0"))
     {
       final String[] calcIds = calcIdParam.getServiceURL().toArray(new String[0]);
-      Jws2Instance service = Jws2Discoverer.getInstance()
+      ServiceWithParameters service = PreferredServiceRegistry.getRegistry()
               .getPreferredServiceFor(calcIds);
       if (service != null)
       {
@@ -2457,7 +2501,7 @@ public class Jalview2XML
           argList = parmSet.getArguments();
           parmSet = null;
         }
-        AAConSettings settings = new AAConSettings(
+        AutoCalcSetting settings = new AAConSettings(
                 calcIdParam.isAutoUpdate(), service, parmSet, argList);
         av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
                 calcIdParam.isNeedsUpdate());
@@ -2465,7 +2509,7 @@ public class Jalview2XML
       }
       else
       {
-        warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
+        warn("Cannot resolve a service for the parameters used in this project. Try configuring a server in the Web Services preferences tab.");
         return false;
       }
     }
@@ -2850,6 +2894,12 @@ public class Jalview2XML
         }
 
         @Override
+        public File getFile()
+        {
+          return jarFile;
+        }
+
+        @Override
         public String getFilename()
         {
           return file;
@@ -2885,8 +2935,8 @@ public class Jalview2XML
     AlignFrame af = null, _af = null;
     IdentityHashMap<AlignmentI, AlignmentI> importedDatasets = new IdentityHashMap<>();
     Map<String, AlignFrame> gatherToThisFrame = new HashMap<>();
-    final String file = jprovider.getFilename();
-
+    String fileName = jprovider.getFilename();
+    File file = jprovider.getFile();
     List<AlignFrame> alignFrames = new ArrayList<>();
 
     try
@@ -2941,7 +2991,7 @@ public class Jalview2XML
             // Q: Do we have to load from the model, even if it
             // does not have a viewport, could we discover that early on?
             // Q: Do we need to load this object?
-            _af = loadFromObject(model, file, true, jprovider);
+            _af = loadFromObject(model, fileName, file, true, jprovider);
 //            Platform.timeCheck("Jalview2XML.loadFromObject",
             // Platform.TIME_MARK);
 
@@ -2984,7 +3034,7 @@ public class Jalview2XML
     } catch (IOException ex)
     {
       ex.printStackTrace();
-      errorMessage = "Couldn't locate Jalview XML file : " + file;
+      errorMessage = "Couldn't locate Jalview XML file : " + fileName;
       System.err.println(
               "Exception whilst loading jalview XML file : " + ex + "\n");
     } catch (Exception ex)
@@ -3356,16 +3406,17 @@ public class Jalview2XML
    * 
    * @param jalviewModel
    *          DOM
-   * @param file
+   * @param fileName
    *          filename source string
+   * @param file 
    * @param loadTreesAndStructures
    *          when false only create Viewport
    * @param jprovider
    *          data source provider
    * @return alignment frame created from view stored in DOM
    */
-  AlignFrame loadFromObject(JalviewModel jalviewModel, String file,
-          boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
+  AlignFrame loadFromObject(JalviewModel jalviewModel, String fileName,
+          File file, boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
   {
     SequenceSet vamsasSet = jalviewModel.getVamsasModel().getSequenceSet().get(0);
     List<Sequence> vamsasSeqs = vamsasSet.getSequence();
@@ -3680,6 +3731,16 @@ public class Jalview2XML
           }
         }
 
+        /*
+         * load any HMMER profile
+         */
+        // TODO fix this
+
+        String hmmJarFile = jseqs.get(i).getHmmerProfile();
+        if (hmmJarFile != null && jprovider != null)
+        {
+          loadHmmerProfile(jprovider, hmmJarFile, al.getSequenceAt(i));
+        }
       }
     } // end !multipleview
 
@@ -4132,7 +4193,7 @@ public class Jalview2XML
 
     if (af == null)
     {
-      af = loadViewport(file, jseqs, hiddenSeqs, al, jalviewModel, view,
+      af = loadViewport(fileName, file, jseqs, hiddenSeqs, al, jalviewModel, view,
               uniqueSeqSetId, viewId, autoAlan);
       av = af.getViewport();
       // note that this only retrieves the most recently accessed
@@ -4204,6 +4265,31 @@ public class Jalview2XML
   }
 
   /**
+   * Loads a HMMER profile from a file stored in the project, and associates it
+   * with the specified sequence
+   * 
+   * @param jprovider
+   * @param hmmJarFile
+   * @param seq
+   */
+  protected void loadHmmerProfile(jarInputStreamProvider jprovider,
+          String hmmJarFile, SequenceI seq)
+  {
+    try
+    {
+      String hmmFile = copyJarEntry(jprovider, hmmJarFile, "hmm", null);
+      HMMFile parser = new HMMFile(hmmFile, DataSourceType.FILE);
+      HiddenMarkovModel hmmModel = parser.getHMM();
+      hmmModel = new HiddenMarkovModel(hmmModel, seq);
+      seq.setHMM(hmmModel);
+    } catch (IOException e)
+    {
+      warn("Error loading HMM profile for " + seq.getName() + ": "
+              + e.getMessage());
+    }
+  }
+
+  /**
    * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
    * panel is restored from separate jar entries, two (gapped and trimmed) per
    * sequence and secondary structure.
@@ -4326,6 +4412,12 @@ public class Jalview2XML
                   tree.getTitle(), safeInt(tree.getWidth()),
                   safeInt(tree.getHeight()), safeInt(tree.getXpos()),
                   safeInt(tree.getYpos()));
+          if (tp == null)
+          {
+            warn("There was a problem recovering stored Newick tree: \n"
+                    + tree.getNewick());
+            continue;
+          }
           if (tree.getId() != null)
           {
             // perhaps bind the tree id to something ?
@@ -4346,13 +4438,6 @@ public class Jalview2XML
           tp.getTreeCanvas().setAssociatedPanel(ap); // af.alignPanel;
         }
         tp.getTreeCanvas().setApplyToAllViews(tree.isLinkToAllViews());
-        if (tp == null)
-        {
-          warn("There was a problem recovering stored Newick tree: \n"
-                  + tree.getNewick());
-          continue;
-        }
-
         tp.fitToWindow.setState(safeBoolean(tree.isFitToWindow()));
         tp.fitToWindow_actionPerformed(null);
 
@@ -4992,7 +5077,7 @@ public class Jalview2XML
     }
   }
 
-  AlignFrame loadViewport(String fileName, List<JSeq> JSEQ,
+  AlignFrame loadViewport(String fileName, File file, List<JSeq> JSEQ,
           List<SequenceI> hiddenSeqs, AlignmentI al, JalviewModel jm,
           Viewport view, String uniqueSeqSetId, String viewId,
           List<JvAnnotRow> autoAlan)
@@ -5012,7 +5097,7 @@ public class Jalview2XML
     // }
     ;
     af.alignPanel.setHoldRepaint(true);
-    af.setFileName(fileName, FileFormat.Jalview);
+    af.setFile(fileName, file, null, FileFormat.Jalview);
     af.setFileObject(jarFile); // BH 2019 JAL-3436
 
     final AlignViewport viewport = af.getViewport();
@@ -5613,10 +5698,10 @@ public class Jalview2XML
     String id = object.getViewport().get(0).getSequenceSetId();
     if (skipList.containsKey(id))
     {
-      if (Cache.log != null && Cache.log.isDebugEnabled())
-      {
-        Cache.log.debug("Skipping seuqence set id " + id);
-      }
+       if (Cache.log != null && Cache.log.isDebugEnabled())
+        {
+          Cache.log.debug("Skipping seuqence set id " + id);
+        }
       return true;
     }
     return false;
@@ -6090,7 +6175,6 @@ public class Jalview2XML
         jmap.setTo(djs);
         incompleteSeqs.put(sqid, djs);
         seqRefIds.put(sqid, djs);
-
       }
       jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
       addDBRefs(djs, ms);
@@ -6128,7 +6212,7 @@ public class Jalview2XML
 
     viewportsAdded.clear();
 
-    AlignFrame af = loadFromObject(jm, null, false, null);
+    AlignFrame af = loadFromObject(jm, null, null, false, null);
     af.getAlignPanels().clear();
     af.closeMenuItem_actionPerformed(true);
     af.alignPanel.setHoldRepaint(false);
@@ -6276,7 +6360,7 @@ public class Jalview2XML
       }
       else
       {
-        Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
+          Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
       }
     }
   }
@@ -6752,7 +6836,7 @@ public class Jalview2XML
         maxcol = new Color(Integer.parseInt(colourModel.getRGB(), 16));
       } catch (Exception e)
       {
-        Cache.log.warn("Couldn't parse out graduated feature color.", e);
+          Cache.log.warn("Couldn't parse out graduated feature color.", e);
       }
   
       NoValueColour noCol = colourModel.getNoValueColour();