patch re JAL-554
[jalview.git] / src / jalview / gui / Jalview2XML.java
index b3cf1af..260f603 100755 (executable)
@@ -1,20 +1,19 @@
 /*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4)
- * Copyright (C) 2008 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5)
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
  * 
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
+ * This file is part of Jalview.
  * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
  * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
  */
 package jalview.gui;
 
@@ -401,13 +400,13 @@ public class Jalview2XML
    * JarOutputStream
    * 
    * @param ap
-   *                panel to create jalview model for
+   *          panel to create jalview model for
    * @param fileName
-   *                name of alignment panel written to output stream
+   *          name of alignment panel written to output stream
    * @param jout
-   *                jar output stream
+   *          jar output stream
    * @param out
-   *                jar entry name
+   *          jar entry name
    */
   public JalviewModel SaveState(AlignmentPanel ap, String fileName,
           JarOutputStream jout)
@@ -574,16 +573,21 @@ public class Jalview2XML
           AppJmol jmol;
           // This must have been loaded, is it still visible?
           JInternalFrame[] frames = Desktop.desktop.getAllFrames();
+          String matchedFile = null;
           for (int f = frames.length - 1; f > -1; f--)
           {
             if (frames[f] instanceof AppJmol)
             {
               jmol = (AppJmol) frames[f];
-              if (!jmol.pdbentry.getId().equals(entry.getId()) 
-                      && !(entry.getId().length()>4 
-                              && entry.getId().startsWith(jmol.pdbentry.getId())))
+              if (!jmol.pdbentry.getId().equals(entry.getId())
+                      && !(entry.getId().length() > 4 && entry.getId()
+                              .toLowerCase().startsWith(
+                                      jmol.pdbentry.getId().toLowerCase())))
                 continue;
-
+              matchedFile = jmol.pdbentry.getFile(); // record the file so we
+              // can get at it if the ID
+              // match is ambiguous (e.g.
+              // 1QIP==1qipA)
               StructureState state = new StructureState();
               state.setVisible(true);
               state.setXpos(jmol.getX());
@@ -606,9 +610,14 @@ public class Jalview2XML
             }
           }
 
-          if (entry.getFile() != null)
+          if (matchedFile != null || entry.getFile() != null)
           {
-            pdb.setFile(entry.getFile());
+            if (entry.getFile() != null)
+            {
+              // use entry's file
+              matchedFile = entry.getFile();
+            }
+            pdb.setFile(matchedFile); // entry.getFile());
             if (pdbfiles == null)
             {
               pdbfiles = new Vector();
@@ -619,7 +628,7 @@ public class Jalview2XML
               pdbfiles.addElement(entry.getId());
               try
               {
-                File file = new File(entry.getFile());
+                File file = new File(matchedFile);
                 if (file.exists() && jout != null)
                 {
                   byte[] data = new byte[(int) file.length()];
@@ -679,9 +688,10 @@ public class Jalview2XML
         for (int p = 0; p < jac[i].aaWidth; p++)
         {
           Alcodon cmap = new Alcodon();
-          if (jac[i].codons[p]!=null)
+          if (jac[i].codons[p] != null)
           {
-            // Null codons indicate a gapped column in the translated peptide alignment. 
+            // Null codons indicate a gapped column in the translated peptide
+            // alignment.
             cmap.setPos1(jac[i].codons[p][0]);
             cmap.setPos2(jac[i].codons[p][1]);
             cmap.setPos3(jac[i].codons[p][2]);
@@ -696,7 +706,7 @@ public class Jalview2XML
           for (int m = 0; m < pmaps.length; m++)
           {
             AlcodMap alcmap = new AlcodMap();
-            alcmap.setDnasq(seqHash(dnas[m])); 
+            alcmap.setDnasq(seqHash(dnas[m]));
             alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
                     false));
             alc.addAlcodMap(alcmap);
@@ -751,6 +761,10 @@ public class Jalview2XML
     }
 
     // SAVE ANNOTATIONS
+    /**
+     * store forward refs from an annotationRow to any groups
+     */
+    IdentityHashMap groupRefs = new IdentityHashMap();
     if (jal.getAlignmentAnnotation() != null)
     {
       jalview.datamodel.AlignmentAnnotation[] aa = jal
@@ -767,15 +781,6 @@ public class Jalview2XML
 
         an.setId(aa[i].annotationId);
 
-        if (aa[i] == av.quality || aa[i] == av.conservation
-                || aa[i] == av.consensus)
-        {
-          an.setLabel(aa[i].label);
-          an.setGraph(true);
-          vamsasSet.addAnnotation(an);
-          continue;
-        }
-
         an.setVisible(aa[i].visible);
 
         an.setDescription(aa[i].description);
@@ -786,6 +791,30 @@ public class Jalview2XML
           // sequence rather than its display name
           an.setSequenceRef(aa[i].sequenceRef.getName());
         }
+        if (aa[i].groupRef != null)
+        {
+          Object groupIdr = groupRefs.get(aa[i].groupRef);
+          if (groupIdr == null)
+          {
+            // make a locally unique String
+            groupRefs.put(aa[i].groupRef,
+                    groupIdr = ("" + System.currentTimeMillis()
+                            + aa[i].groupRef.getName() + groupRefs.size()));
+          }
+          an.setGroupRef(groupIdr.toString());
+        }
+        if (aa[i] == av.quality || aa[i] == av.conservation
+                || aa[i] == av.consensus || aa[i].autoCalculated)
+        {
+          // new way of indicating autocalculated annotation -
+          an.setAutoCalculated(aa[i].autoCalculated);
+          // write a stub for this annotation - indicate presence of autocalc
+          // rows
+          an.setLabel(aa[i].label);
+          an.setGraph(true);
+          vamsasSet.addAnnotation(an);
+          continue;
+        }
 
         if (aa[i].graph > 0)
         {
@@ -854,7 +883,6 @@ public class Jalview2XML
         vamsasSet.addAnnotation(an);
       }
     }
-
     // SAVE GROUPS
     if (jal.getGroups() != null)
     {
@@ -868,9 +896,12 @@ public class Jalview2XML
                 .getGroups().elementAt(i);
         groups[i].setStart(sg.getStartRes());
         groups[i].setEnd(sg.getEndRes());
-        groups[i].setName(sg.getName()); // TODO later sequence group should
-        // specify IDs of sequences, not just
-        // names
+        groups[i].setName(sg.getName());
+        if (groupRefs.containsKey(sg))
+        {
+          // group has references so set it's ID field
+          groups[i].setId(groupRefs.get(sg).toString());
+        }
         if (sg.cs != null)
         {
           if (sg.cs.conservationApplied())
@@ -916,6 +947,9 @@ public class Jalview2XML
         groups[i].setTextCol2(sg.textColour2.getRGB());
         groups[i].setTextColThreshold(sg.thresholdTextColour);
         groups[i].setShowUnconserved(sg.getShowunconserved());
+        groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
+        groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
+        groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
         for (int s = 0; s < sg.getSize(); s++)
         {
           jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
@@ -1027,7 +1061,15 @@ public class Jalview2XML
     view.setTextCol1(av.textColour.getRGB());
     view.setTextCol2(av.textColour2.getRGB());
     view.setTextColThreshold(av.thresholdTextColour);
-
+    view.setShowConsensusHistogram(av.isShowConsensusHistogram());
+    view.setShowSequenceLogo(av.isShowSequenceLogo());
+    view.setShowGroupConsensus(av.isShowGroupConsensus());
+    view.setShowGroupConservation(av.isShowGroupConservation());
+    view.setShowNPfeatureTooltip(av.isShowNpFeats());
+    view.setShowDbRefTooltip(av.isShowDbRefs());
+    view.setFollowHighlight(av.followHighlight);
+    view.setFollowSelection(av.followSelection);
+    view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
     if (av.featuresDisplayed != null)
     {
       jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
@@ -1035,12 +1077,31 @@ public class Jalview2XML
       String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;
 
       Vector settingsAdded = new Vector();
+      Object gstyle = null;
+      GraduatedColor gcol = null;
       for (int ro = 0; ro < renderOrder.length; ro++)
       {
+        gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer()
+                .getFeatureStyle(renderOrder[ro]);
         Setting setting = new Setting();
         setting.setType(renderOrder[ro]);
-        setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
-                .getColour(renderOrder[ro]).getRGB());
+        if (gstyle instanceof GraduatedColor)
+        {
+          gcol = (GraduatedColor) gstyle;
+          setting.setColour(gcol.getMaxColor().getRGB());
+          setting.setMincolour(gcol.getMinColor().getRGB());
+          setting.setMin(gcol.getMin());
+          setting.setMax(gcol.getMax());
+          setting.setColourByLabel(gcol.isColourByLabel());
+          setting.setAutoScale(gcol.isAutoScale());
+          setting.setThreshold(gcol.getThresh());
+          setting.setThreshstate(gcol.getThreshType());
+        }
+        else
+        {
+          setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
+                  .getColour(renderOrder[ro]).getRGB());
+        }
 
         setting.setDisplay(av.featuresDisplayed
                 .containsKey(renderOrder[ro]));
@@ -1104,14 +1165,23 @@ public class Jalview2XML
 
     if (av.hasHiddenColumns)
     {
-      for (int c = 0; c < av.getColumnSelection().getHiddenColumns().size(); c++)
+      if (av.getColumnSelection() == null
+              || av.getColumnSelection().getHiddenColumns() == null)
       {
-        int[] region = (int[]) av.getColumnSelection().getHiddenColumns()
-                .elementAt(c);
-        HiddenColumns hc = new HiddenColumns();
-        hc.setStart(region[0]);
-        hc.setEnd(region[1]);
-        view.addHiddenColumns(hc);
+        warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
+      }
+      else
+      {
+        for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
+                .size(); c++)
+        {
+          int[] region = (int[]) av.getColumnSelection().getHiddenColumns()
+                  .elementAt(c);
+          HiddenColumns hc = new HiddenColumns();
+          hc.setStart(region[0]);
+          hc.setEnd(region[1]);
+          view.addHiddenColumns(hc);
+        }
       }
     }
 
@@ -1158,7 +1228,7 @@ public class Jalview2XML
    * exist, the result of the hashcode call for the object.
    * 
    * @param jvobj
-   *                jalview data object
+   *          jalview data object
    * @return unique ID for referring to jvobj
    */
   private String makeHashCode(Object jvobj, String altCode)
@@ -1189,7 +1259,7 @@ public class Jalview2XML
    * return local jalview object mapped to ID, if it exists
    * 
    * @param idcode
-   *                (may be null)
+   *          (may be null)
    * @return null or object bound to idcode
    */
   private Object retrieveExistingObj(String idcode)
@@ -1328,11 +1398,16 @@ public class Jalview2XML
   {
     String id = null;
     jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
-
+    boolean newucs = false;
     if (!userColours.contains(ucs))
     {
       userColours.add(ucs);
-
+      newucs = true;
+    }
+    id = "ucs" + userColours.indexOf(ucs);
+    if (newucs)
+    {
+      // actually create the scheme's entry in the XML model
       java.awt.Color[] colours = ucs.getColours();
       jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
       jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
@@ -1356,7 +1431,6 @@ public class Jalview2XML
         }
       }
 
-      id = "ucs" + userColours.indexOf(ucs);
       uc.setId(id);
       uc.setUserColourScheme(jbucs);
       jms.addUserColours(uc);
@@ -1420,8 +1494,8 @@ public class Jalview2XML
   /**
    * Load a jalview project archive from a jar file
    * 
-   * @param file -
-   *                HTTP URL or filename
+   * @param file
+   *          - HTTP URL or filename
    */
   public AlignFrame LoadJalviewAlign(final String file)
   {
@@ -1597,8 +1671,10 @@ public class Jalview2XML
               + ex + "\n");
     } catch (OutOfMemoryError e)
     {
-      new jalview.gui.OOMWarning("loading jalview XML file", e,
-              Desktop.instance);
+      // Don't use the OOM Window here
+      errorMessage = "Out of memory loading jalview XML file";
+      System.err.println("Out of memory whilst loading jalview XML file");
+      e.printStackTrace();
     }
 
     if (Desktop.instance != null)
@@ -1725,13 +1801,13 @@ public class Jalview2XML
    * Load alignment frame from jalview XML DOM object
    * 
    * @param object
-   *                DOM
+   *          DOM
    * @param file
-   *                filename source string
+   *          filename source string
    * @param loadTreesAndStructures
-   *                when false only create Viewport
+   *          when false only create Viewport
    * @param jprovider
-   *                data source provider
+   *          data source provider
    * @return alignment frame created from view stored in DOM
    */
   AlignFrame LoadFromObject(JalviewModel object, String file,
@@ -1905,14 +1981,17 @@ public class Jalview2XML
           Alcodon[] alcods = alc[i].getAlcodon();
           for (int p = 0; p < cf.codons.length; p++)
           {
-            if (alcods[p].hasPos1() && alcods[p].hasPos2() && alcods[p].hasPos3())
+            if (alcods[p].hasPos1() && alcods[p].hasPos2()
+                    && alcods[p].hasPos3())
             {
               // translated codons require three valid positions
               cf.codons[p] = new int[3];
               cf.codons[p][0] = (int) alcods[p].getPos1();
               cf.codons[p][1] = (int) alcods[p].getPos2();
               cf.codons[p][2] = (int) alcods[p].getPos3();
-            } else {
+            }
+            else
+            {
               cf.codons[p] = null;
             }
           }
@@ -1951,6 +2030,10 @@ public class Jalview2XML
     // ////////////////////////////////
     // LOAD ANNOTATIONS
     boolean hideQuality = true, hideConservation = true, hideConsensus = true;
+    /**
+     * store any annotations which forward reference a group's ID
+     */
+    Hashtable groupAnnotRefs = new Hashtable();
 
     if (vamsasSet.getAnnotationCount() > 0)
     {
@@ -2061,14 +2144,33 @@ public class Jalview2XML
             al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
           }
         }
+        // and make a note of any group association
+        if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
+        {
+          groupAnnotRefs.put(an[i].getGroupRef(), jaa);
+        }
+
         if (an[i].hasScore())
         {
           jaa.setScore(an[i].getScore());
         }
-
         if (an[i].hasVisible())
           jaa.visible = an[i].getVisible();
 
+        if (an[i].hasCentreColLabels())
+          jaa.centreColLabels = an[i].getCentreColLabels();
+
+        if (an[i].hasScaleColLabels())
+        {
+          jaa.scaleColLabel = an[i].getScaleColLabels();
+        }
+        if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
+        {
+          // newer files have an 'autoCalculated' flag and store calculation
+          // state in viewport properties
+          jaa.autoCalculated = true; // means annotation will be marked for
+          // update at end of load.
+        }
         al.addAnnotation(jaa);
       }
     }
@@ -2131,9 +2233,24 @@ public class Jalview2XML
 
         sg.textColour = new java.awt.Color(groups[i].getTextCol1());
         sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
-        sg.setShowunconserved(groups[i].hasShowUnconserved() ? groups[i].isShowUnconserved() : false);
+        sg.setShowunconserved(groups[i].hasShowUnconserved() ? groups[i]
+                .isShowUnconserved() : false);
         sg.thresholdTextColour = groups[i].getTextColThreshold();
-
+        if (groups[i].hasShowConsensusHistogram())
+        {
+          sg
+                  .setShowConsensusHistogram(groups[i]
+                          .isShowConsensusHistogram());
+        }
+        ;
+        if (groups[i].hasShowSequenceLogo())
+        {
+          sg.setIncludeAllConsSymbols(groups[i].isShowSequenceLogo());
+        }
+        if (groups[i].hasIgnoreGapsinConsensus())
+        {
+          sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
+        }
         if (groups[i].getConsThreshold() != 0)
         {
           jalview.analysis.Conservation c = new jalview.analysis.Conservation(
@@ -2144,7 +2261,18 @@ public class Jalview2XML
           sg.cs.setConservation(c);
         }
 
+        if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
+        {
+          // re-instate unique group/annotation row reference
+          jalview.datamodel.AlignmentAnnotation jaa = (jalview.datamodel.AlignmentAnnotation) groupAnnotRefs
+                  .get(groups[i].getId());
+          if (jaa != null)
+          {
+            jaa.groupRef = sg;
+          }
+        }
         al.addGroup(sg);
+
       }
     }
 
@@ -2243,12 +2371,14 @@ public class Jalview2XML
                     .getHeight(), tree.getXpos(), tree.getYpos());
             if (tree.getId() != null)
             {
-
+              // perhaps bind the tree id to something ?
             }
           }
           else
           {
             // update local tree attributes ?
+            // TODO: should check if tp has been manipulated by user - if so its
+            // settings shouldn't be modified
             tp.setTitle(tree.getTitle());
             tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
                     .getWidth(), tree.getHeight()));
@@ -2259,9 +2389,10 @@ public class Jalview2XML
             tp.treeCanvas.ap = ap; // af.alignPanel;
 
           }
-         if (tp==null)
+          if (tp == null)
           {
-            warn("There was a problem recovering stored Newick tree: \n"+tree.getNewick());
+            warn("There was a problem recovering stored Newick tree: \n"
+                    + tree.getNewick());
             continue;
           }
 
@@ -2365,8 +2496,9 @@ public class Jalview2XML
                   }
                 }
               }
-              Desktop.desktop.getComponentAt(x, y);
-
+              // Probably don't need to do this anymore...
+              // Desktop.desktop.getComponentAt(x, y);
+              // TODO: NOW: check that this recovers the PDB file correctly.
               String pdbFile = loadPDBFile(jprovider, ids[p].getId());
 
               jalview.datamodel.SequenceI[] seq = new jalview.datamodel.SequenceI[]
@@ -2377,17 +2509,34 @@ public class Jalview2XML
               {
                 // create a new Jmol window
                 String state = ids[p].getStructureState(s).getContent();
+                StringBuffer newFileLoc = null;
+                if (state.indexOf("load") > -1)
+                {
+                  newFileLoc = new StringBuffer(state.substring(0, state
+                          .indexOf("\"", state.indexOf("load")) + 1));
 
-                StringBuffer newFileLoc = new StringBuffer(state.substring(
-                        0, state.indexOf("\"", state.indexOf("load")) + 1));
+                  newFileLoc.append(jpdb.getFile());
+                  newFileLoc.append(state.substring(state.indexOf("\"",
+                          state.indexOf("load \"") + 6)));
+                }
+                else
+                {
+                  System.err
+                          .println("Ignoring incomplete Jmol state for PDB "
+                                  + ids[p].getId());
 
-                newFileLoc.append(jpdb.getFile());
-                newFileLoc.append(state.substring(state.indexOf("\"", state
-                        .indexOf("load \"") + 6)));
+                  newFileLoc = new StringBuffer(state);
+                  newFileLoc.append("; load \"");
+                  newFileLoc.append(jpdb.getFile());
+                  newFileLoc.append("\";");
+                }
 
-                new AppJmol(pdbFile, ids[p].getId(), seq, af.alignPanel,
-                        newFileLoc.toString(), new java.awt.Rectangle(x, y,
-                                width, height), sviewid);
+                if (newFileLoc != null)
+                {
+                  new AppJmol(pdbFile, ids[p].getId(), seq, af.alignPanel,
+                          newFileLoc.toString(), new java.awt.Rectangle(x,
+                                  y, width, height), sviewid);
+                }
 
               }
               else
@@ -2533,7 +2682,8 @@ public class Jalview2XML
     af.viewport.textColour = new java.awt.Color(view.getTextCol1());
     af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
     af.viewport.thresholdTextColour = view.getTextColThreshold();
-    af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view.isShowUnconserved() : false);
+    af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
+            .isShowUnconserved() : false);
     af.viewport.setStartRes(view.getStartRes());
     af.viewport.setStartSeq(view.getStartSeq());
 
@@ -2548,85 +2698,91 @@ public class Jalview2XML
       else if (view.getBgColour().startsWith("Annotation"))
       {
         // int find annotation
-        for (int i = 0; i < af.viewport.alignment.getAlignmentAnnotation().length; i++)
+        if (af.viewport.alignment.getAlignmentAnnotation() != null)
         {
-          if (af.viewport.alignment.getAlignmentAnnotation()[i].label
-                  .equals(view.getAnnotationColours().getAnnotation()))
+          for (int i = 0; i < af.viewport.alignment
+                  .getAlignmentAnnotation().length; i++)
           {
-            if (af.viewport.alignment.getAlignmentAnnotation()[i]
-                    .getThreshold() == null)
+            if (af.viewport.alignment.getAlignmentAnnotation()[i].label
+                    .equals(view.getAnnotationColours().getAnnotation()))
             {
-              af.viewport.alignment.getAlignmentAnnotation()[i]
-                      .setThreshold(new jalview.datamodel.GraphLine(view
-                              .getAnnotationColours().getThreshold(),
-                              "Threshold", java.awt.Color.black)
-
-                      );
-            }
+              if (af.viewport.alignment.getAlignmentAnnotation()[i]
+                      .getThreshold() == null)
+              {
+                af.viewport.alignment.getAlignmentAnnotation()[i]
+                        .setThreshold(new jalview.datamodel.GraphLine(view
+                                .getAnnotationColours().getThreshold(),
+                                "Threshold", java.awt.Color.black)
 
-            if (view.getAnnotationColours().getColourScheme()
-                    .equals("None"))
-            {
-              cs = new AnnotationColourGradient(af.viewport.alignment
-                      .getAlignmentAnnotation()[i], new java.awt.Color(view
-                      .getAnnotationColours().getMinColour()),
-                      new java.awt.Color(view.getAnnotationColours()
-                              .getMaxColour()), view.getAnnotationColours()
-                              .getAboveThreshold());
-            }
-            else if (view.getAnnotationColours().getColourScheme()
-                    .startsWith("ucs"))
-            {
-              cs = new AnnotationColourGradient(af.viewport.alignment
-                      .getAlignmentAnnotation()[i], GetUserColourScheme(
-                      jms, view.getAnnotationColours().getColourScheme()),
-                      view.getAnnotationColours().getAboveThreshold());
-            }
-            else
-            {
-              cs = new AnnotationColourGradient(af.viewport.alignment
-                      .getAlignmentAnnotation()[i], ColourSchemeProperty
-                      .getColour(al, view.getAnnotationColours()
-                              .getColourScheme()), view
-                      .getAnnotationColours().getAboveThreshold());
-            }
+                        );
+              }
 
-            // Also use these settings for all the groups
-            if (al.getGroups() != null)
-            {
-              for (int g = 0; g < al.getGroups().size(); g++)
+              if (view.getAnnotationColours().getColourScheme().equals(
+                      "None"))
               {
-                jalview.datamodel.SequenceGroup sg = (jalview.datamodel.SequenceGroup) al
-                        .getGroups().elementAt(g);
+                cs = new AnnotationColourGradient(af.viewport.alignment
+                        .getAlignmentAnnotation()[i], new java.awt.Color(
+                        view.getAnnotationColours().getMinColour()),
+                        new java.awt.Color(view.getAnnotationColours()
+                                .getMaxColour()), view
+                                .getAnnotationColours().getAboveThreshold());
+              }
+              else if (view.getAnnotationColours().getColourScheme()
+                      .startsWith("ucs"))
+              {
+                cs = new AnnotationColourGradient(af.viewport.alignment
+                        .getAlignmentAnnotation()[i],
+                        GetUserColourScheme(jms, view
+                                .getAnnotationColours().getColourScheme()),
+                        view.getAnnotationColours().getAboveThreshold());
+              }
+              else
+              {
+                cs = new AnnotationColourGradient(af.viewport.alignment
+                        .getAlignmentAnnotation()[i], ColourSchemeProperty
+                        .getColour(al, view.getAnnotationColours()
+                                .getColourScheme()), view
+                        .getAnnotationColours().getAboveThreshold());
+              }
 
-                if (sg.cs == null)
+              // Also use these settings for all the groups
+              if (al.getGroups() != null)
+              {
+                for (int g = 0; g < al.getGroups().size(); g++)
                 {
-                  continue;
-                }
+                  jalview.datamodel.SequenceGroup sg = (jalview.datamodel.SequenceGroup) al
+                          .getGroups().elementAt(g);
 
-                /*
-                 * if
-                 * (view.getAnnotationColours().getColourScheme().equals("None")) {
-                 * sg.cs = new AnnotationColourGradient(
-                 * af.viewport.alignment.getAlignmentAnnotation()[i], new
-                 * java.awt.Color(view.getAnnotationColours(). getMinColour()),
-                 * new java.awt.Color(view.getAnnotationColours().
-                 * getMaxColour()),
-                 * view.getAnnotationColours().getAboveThreshold()); } else
-                 */
-                {
-                  sg.cs = new AnnotationColourGradient(
-                          af.viewport.alignment.getAlignmentAnnotation()[i],
-                          sg.cs, view.getAnnotationColours()
-                                  .getAboveThreshold());
-                }
+                  if (sg.cs == null)
+                  {
+                    continue;
+                  }
 
+                  /*
+                   * if
+                   * (view.getAnnotationColours().getColourScheme().equals("None"
+                   * )) { sg.cs = new AnnotationColourGradient(
+                   * af.viewport.alignment.getAlignmentAnnotation()[i], new
+                   * java.awt.Color(view.getAnnotationColours().
+                   * getMinColour()), new
+                   * java.awt.Color(view.getAnnotationColours().
+                   * getMaxColour()),
+                   * view.getAnnotationColours().getAboveThreshold()); } else
+                   */
+                  {
+                    sg.cs = new AnnotationColourGradient(
+                            af.viewport.alignment.getAlignmentAnnotation()[i],
+                            sg.cs, view.getAnnotationColours()
+                                    .getAboveThreshold());
+                  }
+
+                }
               }
+
+              break;
             }
 
-            break;
           }
-
         }
       }
       else
@@ -2657,6 +2813,65 @@ public class Jalview2XML
     {
       af.viewport.showSequenceFeatures = true;
     }
+    if (view.hasCentreColumnLabels())
+    {
+      af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
+    }
+    if (view.hasIgnoreGapsinConsensus())
+    {
+      af.viewport.ignoreGapsInConsensusCalculation = view
+              .getIgnoreGapsinConsensus();
+    }
+    if (view.hasFollowHighlight())
+    {
+      af.viewport.followHighlight = view.getFollowHighlight();
+    }
+    if (view.hasFollowSelection())
+    {
+      af.viewport.followSelection = view.getFollowSelection();
+    }
+    if (view.hasShowConsensusHistogram())
+    {
+      af.viewport.setShowConsensusHistogram(view
+              .getShowConsensusHistogram());
+    }
+    else
+    {
+      af.viewport.setShowConsensusHistogram(true);
+    }
+    if (view.hasShowSequenceLogo())
+    {
+      af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
+    }
+    else
+    {
+      af.viewport.setShowSequenceLogo(false);
+    }
+    if (view.hasShowDbRefTooltip())
+    {
+      af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
+    }
+    if (view.hasShowNPfeatureTooltip())
+    {
+      af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
+    }
+    if (view.hasShowGroupConsensus())
+    {
+      af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
+    }
+    else
+    {
+      af.viewport.setShowGroupConsensus(false);
+    }
+    if (view.hasShowGroupConservation())
+    {
+      af.viewport.setShowGroupConservation(view.getShowGroupConservation());
+    }
+    else
+    {
+      af.viewport.setShowGroupConservation(false);
+    }
+
     // recover featre settings
     if (jms.getFeatureSettings() != null)
     {
@@ -2668,16 +2883,35 @@ public class Jalview2XML
         Setting setting = jms.getFeatureSettings().getSetting(fs);
         if (setting.hasMincolour())
         {
-          // TODO: determine how to set data independent bounds for a graduated colour scheme's range.
-          GraduatedColor gc = new GraduatedColor(new java.awt.Color(setting.getMincolour()), new java.awt.Color(setting.getColour()),
-                  0,1);
-          if (setting.hasThreshold()) {
+          GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
+                  new java.awt.Color(setting.getMincolour()),
+                  new java.awt.Color(setting.getColour()),
+                  setting.getMin(), setting.getMax()) : new GraduatedColor(
+                  new java.awt.Color(setting.getMincolour()),
+                  new java.awt.Color(setting.getColour()), 0, 1);
+          if (setting.hasThreshold())
+          {
             gc.setThresh(setting.getThreshold());
             gc.setThreshType(setting.getThreshstate());
           }
-        } else {
+          gc.setAutoScaled(true); // default
+          if (setting.hasAutoScale())
+          {
+            gc.setAutoScaled(setting.getAutoScale());
+          }
+          if (setting.hasColourByLabel())
+          {
+            gc.setColourByLabel(setting.getColourByLabel());
+          }
+          // and put in the feature colour table.
           af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
-                  setting.getType(), new java.awt.Color(setting.getColour()));
+                  setting.getType(), gc);
+        }
+        else
+        {
+          af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
+                  setting.getType(),
+                  new java.awt.Color(setting.getColour()));
         }
         renderOrder[fs] = setting.getType();
         if (setting.hasOrder())
@@ -2714,9 +2948,11 @@ public class Jalview2XML
     }
 
     af.setMenusFromViewport(af.viewport);
+    af.alignPanel.updateAnnotation(false); // recompute any autoannotation
     // TODO: we don't need to do this if the viewport is aready visible.
     Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(), view
             .getHeight());
+    af.alignPanel.updateAnnotation(false); // recompute any autoannotation
     return af;
   }
 
@@ -2796,6 +3032,8 @@ public class Jalview2XML
       SequenceI[] dsseqs = new SequenceI[dseqs.size()];
       dseqs.copyInto(dsseqs);
       ds = new jalview.datamodel.Alignment(dsseqs);
+      debug("Created new dataset " + vamsasSet.getDatasetId()
+              + " for alignment " + System.identityHashCode(al));
       addDatasetRef(vamsasSet.getDatasetId(), ds);
     }
     // set the dataset for the newly imported alignment.
@@ -2808,11 +3046,11 @@ public class Jalview2XML
   /**
    * 
    * @param vamsasSeq
-   *                sequence definition to create/merge dataset sequence for
+   *          sequence definition to create/merge dataset sequence for
    * @param ds
-   *                dataset alignment
+   *          dataset alignment
    * @param dseqs
-   *                vector to add new dataset sequence to
+   *          vector to add new dataset sequence to
    */
   private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
           AlignmentI ds, Vector dseqs)
@@ -2902,7 +3140,9 @@ public class Jalview2XML
   }
 
   java.util.Hashtable datasetIds = null;
+
   java.util.IdentityHashMap dataset2Ids = null;
+
   private Alignment getDatasetFor(String datasetId)
   {
     if (datasetIds == null)
@@ -2925,35 +3165,40 @@ public class Jalview2XML
     }
     datasetIds.put(datasetId, dataset);
   }
+
   /**
    * make a new dataset ID for this jalview dataset alignment
+   * 
    * @param dataset
    * @return
    */
   private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
   {
-    if (dataset.getDataset()!=null)
+    if (dataset.getDataset() != null)
     {
       warn("Serious issue!  Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
     }
-    String datasetId=makeHashCode(dataset, null);
-    if (datasetId==null)
+    String datasetId = makeHashCode(dataset, null);
+    if (datasetId == null)
     {
       // make a new datasetId and record it
       if (dataset2Ids == null)
       {
         dataset2Ids = new IdentityHashMap();
-      } else {
+      }
+      else
+      {
         datasetId = (String) dataset2Ids.get(dataset);
       }
-      if (datasetId==null)
+      if (datasetId == null)
       {
-        datasetId = "ds"+dataset2Ids.size()+1;
-        dataset2Ids.put(dataset,datasetId);
+        datasetId = "ds" + dataset2Ids.size() + 1;
+        dataset2Ids.put(dataset, datasetId);
       }
     }
     return datasetId;
   }
+
   private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
   {
     for (int d = 0; d < sequence.getDBRefCount(); d++)
@@ -2997,7 +3242,7 @@ public class Jalview2XML
       MappingChoice mc = m.getMappingChoice();
       if (mc.getDseqFor() != null)
       {
-        String dsfor = ""+mc.getDseqFor();
+        String dsfor = "" + mc.getDseqFor();
         if (seqRefIds.containsKey(dsfor))
         {
           /**
@@ -3073,9 +3318,12 @@ public class Jalview2XML
     else
     {
       uniqueSetSuffix = "";
-      jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't overwrite the view we just copied
+      jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
+      // overwrite the
+      // view we just
+      // copied
     }
-    if (this.frefedSequence==null)
+    if (this.frefedSequence == null)
     {
       frefedSequence = new Vector();
     }
@@ -3087,8 +3335,9 @@ public class Jalview2XML
     af.closeMenuItem_actionPerformed(true);
 
     /*
-     * if(ap.av.alignment.getAlignmentAnnotation()!=null) { for(int i=0; i<ap.av.alignment.getAlignmentAnnotation().length;
-     * i++) { if(!ap.av.alignment.getAlignmentAnnotation()[i].autoCalculated) {
+     * if(ap.av.alignment.getAlignmentAnnotation()!=null) { for(int i=0;
+     * i<ap.av.alignment.getAlignmentAnnotation().length; i++) {
+     * if(!ap.av.alignment.getAlignmentAnnotation()[i].autoCalculated) {
      * af.alignPanel.av.alignment.getAlignmentAnnotation()[i] =
      * ap.av.alignment.getAlignmentAnnotation()[i]; } } }
      */
@@ -3149,6 +3398,34 @@ public class Jalview2XML
     }
   }
 
+  private void debug(String string)
+  {
+    debug(string, null);
+  }
+
+  private void debug(String msg, Exception e)
+  {
+    if (Cache.log != null)
+    {
+      if (e != null)
+      {
+        Cache.log.debug(msg, e);
+      }
+      else
+      {
+        Cache.log.debug(msg);
+      }
+    }
+    else
+    {
+      System.err.println("Warning: " + msg);
+      if (e != null)
+      {
+        e.printStackTrace();
+      }
+    }
+  }
+
   /**
    * set the object to ID mapping tables used to write/recover objects and XML
    * ID strings for the jalview project. If external tables are provided then
@@ -3157,9 +3434,9 @@ public class Jalview2XML
    * alignment objects containing dataset sequences
    * 
    * @param vobj2jv
-   *                Map from ID strings to jalview datamodel
+   *          Map from ID strings to jalview datamodel
    * @param jv2vobj
-   *                Map from jalview datamodel to ID strings
+   *          Map from jalview datamodel to ID strings
    * 
    * 
    */