JAL-3081 test and fix for preserve annotation order on New View
[jalview.git] / test / jalview / project / Jalview2xmlTests.java
index 72cbc50..3e7279c 100644 (file)
@@ -27,12 +27,15 @@ import static org.testng.Assert.assertNull;
 import static org.testng.Assert.assertSame;
 import static org.testng.Assert.assertTrue;
 
+import jalview.analysis.scoremodels.SimilarityParams;
 import jalview.api.AlignViewportI;
 import jalview.api.AlignmentViewPanel;
 import jalview.api.FeatureColourI;
 import jalview.api.ViewStyleI;
+import jalview.bin.Cache;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
 import jalview.datamodel.HiddenSequences;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.PDBEntry.Type;
@@ -49,6 +52,7 @@ import jalview.gui.AlignmentPanel;
 import jalview.gui.Desktop;
 import jalview.gui.FeatureRenderer;
 import jalview.gui.JvOptionPane;
+import jalview.gui.PCAPanel;
 import jalview.gui.PopupMenu;
 import jalview.gui.SliderPanel;
 import jalview.io.DataSourceType;
@@ -77,6 +81,8 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import javax.swing.JInternalFrame;
+
 import org.testng.Assert;
 import org.testng.AssertJUnit;
 import org.testng.annotations.BeforeClass;
@@ -95,7 +101,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
   }
 
   @Test(groups = { "Functional" })
-  public void testRNAStructureRecovery() throws Exception
+  public void testRestoreRNAStructure() throws Exception
   {
     String inFile = "examples/RF00031_folded.stk";
     String tfile = File.createTempFile("JalviewTest", ".jvp")
@@ -105,65 +111,73 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     assertNotNull(af, "Didn't read input file " + inFile);
     int olddsann = countDsAnn(af.getViewport());
     assertTrue(olddsann > 0, "Didn't find any dataset annotations");
-    af.changeColour_actionPerformed(JalviewColourScheme.RNAHelices
-            .toString());
+    af.changeColour_actionPerformed(
+            JalviewColourScheme.RNAHelices.toString());
     assertTrue(
-            af.getViewport().getGlobalColourScheme() instanceof RNAHelicesColour,
+            af.getViewport()
+                    .getGlobalColourScheme() instanceof RNAHelicesColour,
             "Couldn't apply RNA helices colourscheme");
     assertTrue(af.saveAlignment(tfile, FileFormat.Jalview),
             "Failed to store as a project.");
     af.closeMenuItem_actionPerformed(true);
     af = null;
-    af = new FileLoader()
-            .LoadFileWaitTillLoaded(tfile, DataSourceType.FILE);
+    af = new FileLoader().LoadFileWaitTillLoaded(tfile,
+            DataSourceType.FILE);
     assertNotNull(af, "Failed to import new project");
     int newdsann = countDsAnn(af.getViewport());
     assertEquals(olddsann, newdsann,
             "Differing numbers of dataset sequence annotation\nOriginally "
                     + olddsann + " and now " + newdsann);
-    System.out
-            .println("Read in same number of annotations as originally present ("
+    System.out.println(
+            "Read in same number of annotations as originally present ("
                     + olddsann + ")");
     assertTrue(
 
-    af.getViewport().getGlobalColourScheme() instanceof RNAHelicesColour,
+            af.getViewport()
+                    .getGlobalColourScheme() instanceof RNAHelicesColour,
             "RNA helices colourscheme was not applied on import.");
   }
 
   @Test(groups = { "Functional" })
-  public void testTCoffeeScores() throws Exception
+  public void testRestoreTCoffeeColouring() throws Exception
   {
-    String inFile = "examples/uniref50.fa", inAnnot = "examples/uniref50.score_ascii";
+    String inFile = "examples/uniref50.fa",
+            inAnnot = "examples/uniref50.score_ascii";
     String tfile = File.createTempFile("JalviewTest", ".jvp")
             .getAbsolutePath();
     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
             DataSourceType.FILE);
     assertNotNull(af, "Didn't read input file " + inFile);
     af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
-    assertSame(af.getViewport().getGlobalColourScheme().getClass(),
+    AlignViewport viewport = af.getViewport();
+    assertSame(viewport.getGlobalColourScheme().getClass(),
             TCoffeeColourScheme.class, "Didn't set T-coffee colourscheme");
-    assertNotNull(ColourSchemeProperty.getColourScheme(af.getViewport()
-            .getAlignment(), af.getViewport().getGlobalColourScheme()
-            .getSchemeName()), "Recognise T-Coffee score from string");
+    assertNotNull(
+            ColourSchemeProperty.getColourScheme(viewport,
+                    viewport.getAlignment(),
+                    viewport.getGlobalColourScheme()
+                            .getSchemeName()),
+            "Recognise T-Coffee score from string");
 
     assertTrue(af.saveAlignment(tfile, FileFormat.Jalview),
             "Failed to store as a project.");
     af.closeMenuItem_actionPerformed(true);
     af = null;
-    af = new FileLoader()
-            .LoadFileWaitTillLoaded(tfile, DataSourceType.FILE);
+    af = new FileLoader().LoadFileWaitTillLoaded(tfile,
+            DataSourceType.FILE);
     assertNotNull(af, "Failed to import new project");
     assertSame(af.getViewport().getGlobalColourScheme().getClass(),
             TCoffeeColourScheme.class,
             "Didn't set T-coffee colourscheme for imported project.");
-    System.out
-            .println("T-Coffee score shading successfully recovered from project.");
+    System.out.println(
+            "T-Coffee score shading successfully recovered from project.");
   }
 
   @Test(groups = { "Functional" })
-  public void testColourByAnnotScores() throws Exception
+  public void testRestoreColourByAnnotion() throws Exception
   {
-    String inFile = "examples/uniref50.fa", inAnnot = "examples/testdata/uniref50_iupred.jva";
+    String inFile = "examples/uniref50.fa",
+            inAnnot = "examples/testdata/uniref50_iupred.jva";
     String tfile = File.createTempFile("JalviewTest", ".jvp")
             .getAbsolutePath();
     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
@@ -174,12 +188,12 @@ public class Jalview2xmlTests extends Jalview2xmlBase
             .getSequenceAt(0).getAnnotation("IUPredWS (Short)");
     assertTrue(
 
-    aa != null && aa.length > 0,
+            aa != null && aa.length > 0,
             "Didn't find any IUPred annotation to use to shade alignment.");
     AnnotationColourGradient cs = new AnnotationColourGradient(aa[0], null,
             AnnotationColourGradient.ABOVE_THRESHOLD);
-    AnnotationColourGradient gcs = new AnnotationColourGradient(aa[0],
-            null, AnnotationColourGradient.BELOW_THRESHOLD);
+    AnnotationColourGradient gcs = new AnnotationColourGradient(aa[0], null,
+            AnnotationColourGradient.BELOW_THRESHOLD);
     cs.setSeqAssociated(true);
     gcs.setSeqAssociated(true);
     af.changeColour(cs);
@@ -195,15 +209,15 @@ public class Jalview2xmlTests extends Jalview2xmlBase
             "Failed to store as a project.");
     af.closeMenuItem_actionPerformed(true);
     af = null;
-    af = new FileLoader()
-            .LoadFileWaitTillLoaded(tfile, DataSourceType.FILE);
+    af = new FileLoader().LoadFileWaitTillLoaded(tfile,
+            DataSourceType.FILE);
     assertNotNull(af, "Failed to import new project");
 
     // check for group and alignment colourschemes
 
     ColourSchemeI _rcs = af.getViewport().getGlobalColourScheme();
-    ColourSchemeI _rgcs = af.getViewport().getAlignment().getGroups()
-            .get(0).getColourScheme();
+    ColourSchemeI _rgcs = af.getViewport().getAlignment().getGroups().get(0)
+            .getColourScheme();
     assertNotNull(_rcs, "Didn't recover global colourscheme");
     assertTrue(_rcs instanceof AnnotationColourGradient,
             "Didn't recover annotation colour global scheme");
@@ -213,8 +227,8 @@ public class Jalview2xmlTests extends Jalview2xmlBase
 
     boolean diffseqcols = false, diffgseqcols = false;
     SequenceI[] sqs = af.getViewport().getAlignment().getSequencesArray();
-    for (int p = 0, pSize = af.getViewport().getAlignment().getWidth(); p < pSize
-            && (!diffseqcols || !diffgseqcols); p++)
+    for (int p = 0, pSize = af.getViewport().getAlignment()
+            .getWidth(); p < pSize && (!diffseqcols || !diffgseqcols); p++)
     {
       if (_rcs.findColour(sqs[0].getCharAt(p), p, sqs[0], null, 0f) != _rcs
               .findColour(sqs[5].getCharAt(p), p, sqs[5], null, 0f))
@@ -223,8 +237,8 @@ public class Jalview2xmlTests extends Jalview2xmlBase
       }
     }
     assertTrue(diffseqcols, "Got Different sequence colours");
-    System.out
-            .println("Per sequence colourscheme (Background) successfully applied and recovered.");
+    System.out.println(
+            "Per sequence colourscheme (Background) successfully applied and recovered.");
 
     assertNotNull(_rgcs, "Didn't recover group colourscheme");
     assertTrue(_rgcs instanceof AnnotationColourGradient,
@@ -233,25 +247,26 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     assertTrue(__rcs.isSeqAssociated(),
             "Group Annotation colourscheme wasn't sequence associated");
 
-    for (int p = 0, pSize = af.getViewport().getAlignment().getWidth(); p < pSize
-            && (!diffseqcols || !diffgseqcols); p++)
+    for (int p = 0, pSize = af.getViewport().getAlignment()
+            .getWidth(); p < pSize && (!diffseqcols || !diffgseqcols); p++)
     {
-      if (_rgcs.findColour(sqs[1].getCharAt(p), p, sqs[1], null, 0f) != _rgcs
-              .findColour(sqs[2].getCharAt(p), p, sqs[2], null, 0f))
+      if (_rgcs.findColour(sqs[1].getCharAt(p), p, sqs[1], null,
+              0f) != _rgcs.findColour(sqs[2].getCharAt(p), p, sqs[2], null,
+                      0f))
       {
         diffgseqcols = true;
       }
     }
     assertTrue(diffgseqcols, "Got Different group sequence colours");
-    System.out
-            .println("Per sequence (Group) colourscheme successfully applied and recovered.");
+    System.out.println(
+            "Per sequence (Group) colourscheme successfully applied and recovered.");
   }
 
   @Test(groups = { "Functional" })
   public void gatherViewsHere() throws Exception
   {
-    int origCount = Desktop.getAlignFrames() == null ? 0 : Desktop
-            .getAlignFrames().length;
+    int origCount = Desktop.getAlignFrames() == null ? 0
+            : Desktop.getAlignFrames().length;
     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
             "examples/exampleFile_2_7.jar", DataSourceType.FILE);
     assertNotNull(af, "Didn't read in the example file correctly.");
@@ -332,14 +347,14 @@ public class Jalview2xmlTests extends Jalview2xmlBase
           sq.findPosition(p);
           try
           {
-            assertTrue(
-                    (alaa.annotations[p] == null && refan.annotations[p] == null)
-                            || alaa.annotations[p].value == refan.annotations[p].value,
+            assertTrue((alaa.annotations[p] == null
+                    && refan.annotations[p] == null)
+                    || alaa.annotations[p].value == refan.annotations[p].value,
                     "Mismatch at alignment position " + p);
           } catch (NullPointerException q)
           {
-            Assert.fail("Mismatch of alignment annotations at position "
-                    + p + " Ref seq ann: " + refan.annotations[p]
+            Assert.fail("Mismatch of alignment annotations at position " + p
+                    + " Ref seq ann: " + refan.annotations[p]
                     + " alignment " + alaa.annotations[p]);
           }
         }
@@ -374,10 +389,10 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     AssertJUnit.assertFalse(structureStyle.sameStyle(groupStyle));
 
     groups.getAlignViewport().setViewStyle(structureStyle);
-    AssertJUnit.assertFalse(groupStyle.sameStyle(groups.getAlignViewport()
-            .getViewStyle()));
-    Assert.assertTrue(structureStyle.sameStyle(groups.getAlignViewport()
-            .getViewStyle()));
+    AssertJUnit.assertFalse(
+            groupStyle.sameStyle(groups.getAlignViewport().getViewStyle()));
+    Assert.assertTrue(structureStyle
+            .sameStyle(groups.getAlignViewport().getViewStyle()));
 
   }
 
@@ -387,7 +402,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
    * @throws Exception
    */
   @Test(groups = { "Functional" }, enabled = true)
-  public void testStoreAndRecoverExpandedviews() throws Exception
+  public void testRestoreExpandedviews() throws Exception
   {
     Desktop.instance.closeAll_actionPerformed(null);
 
@@ -398,9 +413,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
 
     // check FileLoader returned a reference to the one alignFrame that is
     // actually on the Desktop
-    assertSame(
-            af,
-            Desktop.getAlignFrameFor(af.getViewport()),
+    assertSame(af, Desktop.getAlignFrameFor(af.getViewport()),
             "Jalview2XML.loadAlignFrame() didn't return correct AlignFrame reference for multiple view window");
 
     Desktop.explodeViews(af);
@@ -408,7 +421,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     int oldviews = Desktop.getAlignFrames().length;
     Assert.assertEquals(Desktop.getAlignFrames().length,
             Desktop.getAlignmentPanels(afid).length);
-    File tfile = File.createTempFile("testStoreAndRecoverExpanded", ".jvp");
+    File tfile = File.createTempFile("testRestoreExpandedviews", ".jvp");
     try
     {
       new Jalview2XML(false).saveState(tfile);
@@ -427,11 +440,12 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
             DataSourceType.FILE);
     Assert.assertNotNull(af);
+    Assert.assertEquals(Desktop.getAlignFrames().length,
+            Desktop.getAlignmentPanels(
+                    af.getViewport().getSequenceSetId()).length);
     Assert.assertEquals(
-            Desktop.getAlignFrames().length,
-            Desktop.getAlignmentPanels(af.getViewport().getSequenceSetId()).length);
-    Assert.assertEquals(
-            Desktop.getAlignmentPanels(af.getViewport().getSequenceSetId()).length,
+            Desktop.getAlignmentPanels(
+                    af.getViewport().getSequenceSetId()).length,
             oldviews);
   }
 
@@ -442,7 +456,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
    * @throws Exception
    */
   @Test(groups = { "Functional" })
-  public void testStoreAndRecoverReferenceSeqSettings() throws Exception
+  public void testRestoreReferenceSeqSettings() throws Exception
   {
     Desktop.instance.closeAll_actionPerformed(null);
     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
@@ -474,7 +488,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
 
       n++;
     }
-    File tfile = File.createTempFile("testStoreAndRecoverReferenceSeq",
+    File tfile = File.createTempFile("testRestoreReferenceSeqSettings",
             ".jvp");
     try
     {
@@ -533,8 +547,8 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     assertTrue(Jalview2XML.isVersionStringLaterThan(null, "Test"));
     assertTrue(Jalview2XML.isVersionStringLaterThan(null, "TEST"));
     assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "Test"));
-    assertTrue(Jalview2XML
-            .isVersionStringLaterThan(null, "Automated Build"));
+    assertTrue(
+            Jalview2XML.isVersionStringLaterThan(null, "Automated Build"));
     assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
             "Automated Build"));
     assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
@@ -575,7 +589,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
    * @throws Exception
    */
   @Test(groups = { "Functional" })
-  public void testStoreAndRecoverGroupRepSeqs() throws Exception
+  public void testRestoreGroupRepSeqs() throws Exception
   {
     Desktop.instance.closeAll_actionPerformed(null);
     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
@@ -643,8 +657,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
 
       n++;
     }
-    File tfile = File
-            .createTempFile("testStoreAndRecoverGroupReps", ".jvp");
+    File tfile = File.createTempFile("testRestoreGroupRepSeqs", ".jvp");
     try
     {
       new Jalview2XML(false).saveState(tfile);
@@ -683,9 +696,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
        */
       List<String> hidden = hiddenSeqNames.get(ap.getViewName());
       HiddenSequences hs = alignment.getHiddenSequences();
-      assertEquals(
-              hidden.size(),
-              hs.getSize(),
+      assertEquals(hidden.size(), hs.getSize(),
               "wrong number of restored hidden sequences in "
                       + ap.getViewName());
     }
@@ -697,7 +708,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
    * @throws Exception
    */
   @Test(groups = { "Functional" })
-  public void testStoreAndRecoverPDBEntry() throws Exception
+  public void testRestorePDBEntry() throws Exception
   {
     Desktop.instance.closeAll_actionPerformed(null);
     String exampleFile = "examples/3W5V.pdb";
@@ -727,16 +738,20 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     pdbEntries[1] = new PDBEntry("3W5V", "B", Type.PDB, testFile);
     pdbEntries[2] = new PDBEntry("3W5V", "C", Type.PDB, testFile);
     pdbEntries[3] = new PDBEntry("3W5V", "D", Type.PDB, testFile);
-    Assert.assertEquals(seqs[0].getDatasetSequence().getAllPDBEntries()
-            .get(0), pdbEntries[0]);
-    Assert.assertEquals(seqs[1].getDatasetSequence().getAllPDBEntries()
-            .get(0), pdbEntries[1]);
-    Assert.assertEquals(seqs[2].getDatasetSequence().getAllPDBEntries()
-            .get(0), pdbEntries[2]);
-    Assert.assertEquals(seqs[3].getDatasetSequence().getAllPDBEntries()
-            .get(0), pdbEntries[3]);
-
-    File tfile = File.createTempFile("testStoreAndRecoverPDBEntry", ".jvp");
+    Assert.assertEquals(
+            seqs[0].getDatasetSequence().getAllPDBEntries().get(0),
+            pdbEntries[0]);
+    Assert.assertEquals(
+            seqs[1].getDatasetSequence().getAllPDBEntries().get(0),
+            pdbEntries[1]);
+    Assert.assertEquals(
+            seqs[2].getDatasetSequence().getAllPDBEntries().get(0),
+            pdbEntries[2]);
+    Assert.assertEquals(
+            seqs[3].getDatasetSequence().getAllPDBEntries().get(0),
+            pdbEntries[3]);
+
+    File tfile = File.createTempFile("testRestorePDBEntry", ".jvp");
     try
     {
       new Jalview2XML(false).saveState(tfile);
@@ -793,7 +808,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
    * @throws IOException
    */
   @Test(groups = { "Functional" })
-  public void testStoreAndRecoverColourThresholds() throws IOException
+  public void testRestoreColourThresholds() throws IOException
   {
     Desktop.instance.closeAll_actionPerformed(null);
     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
@@ -805,6 +820,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     /*
      * Colour alignment by Buried Index, Above 10% PID, By Conservation 20%
      */
+    av.setColourAppliesToAllGroups(false);
     af.changeColour_actionPerformed(JalviewColourScheme.Buried.toString());
     assertTrue(av.getGlobalColourScheme() instanceof BuriedColourScheme);
     af.abovePIDThreshold_actionPerformed(true);
@@ -830,8 +846,8 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     sg.setEndRes(25);
     av.setSelectionGroup(sg);
     PopupMenu popupMenu = new PopupMenu(af.alignPanel, null, null);
-    popupMenu.changeColour_actionPerformed(JalviewColourScheme.Strand
-            .toString());
+    popupMenu.changeColour_actionPerformed(
+            JalviewColourScheme.Strand.toString());
     assertTrue(sg.getColourScheme() instanceof StrandColourScheme);
     assertEquals(al.getGroups().size(), 1);
     assertSame(al.getGroups().get(0), sg);
@@ -850,7 +866,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     /*
      * save project, close windows, reload project, verify
      */
-    File tfile = File.createTempFile("testStoreAndRecoverColourThresholds",
+    File tfile = File.createTempFile("testRestoreColourThresholds",
             ".jvp");
     tfile.deleteOnExit();
     new Jalview2XML(false).saveState(tfile);
@@ -886,7 +902,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
    * @throws IOException
    */
   @Test(groups = { "Functional" })
-  public void testSaveLoadFeatureColoursAndFilters() throws IOException
+  public void testRestoreFeatureColoursAndFilters() throws IOException
   {
     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
             ">Seq1\nACDEFGHIKLM", DataSourceType.PASTE);
@@ -917,8 +933,8 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     fr.setColour("type2", byLabel);
 
     // type3: by score above threshold
-    FeatureColourI byScore = new FeatureColour(Color.BLACK, Color.BLUE, 1,
-            10);
+    FeatureColourI byScore = new FeatureColour(null, Color.BLACK,
+            Color.BLUE, null, 1, 10);
     byScore.setAboveThreshold(true);
     byScore.setThreshold(2f);
     fr.setColour("type3", byScore);
@@ -930,8 +946,8 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     fr.setColour("type4", byAF);
 
     // type5: by attribute CSQ:PolyPhen below threshold
-    FeatureColourI byPolyPhen = new FeatureColour(Color.BLACK, Color.BLUE,
-            1, 10);
+    FeatureColourI byPolyPhen = new FeatureColour(null, Color.BLACK,
+            Color.BLUE, null, 1, 10);
     byPolyPhen.setBelowThreshold(true);
     byPolyPhen.setThreshold(3f);
     byPolyPhen.setAttributeName("CSQ", "PolyPhen");
@@ -974,8 +990,8 @@ public class Jalview2xmlTests extends Jalview2xmlBase
      */
     af.closeMenuItem_actionPerformed(true);
     af = null;
-    af = new FileLoader()
-            .LoadFileWaitTillLoaded(filePath, DataSourceType.FILE);
+    af = new FileLoader().LoadFileWaitTillLoaded(filePath,
+            DataSourceType.FILE);
     assertNotNull(af, "Failed to import new project");
 
     /*
@@ -1043,12 +1059,50 @@ public class Jalview2xmlTests extends Jalview2xmlBase
    * pre 2.11 - jalview 2.10 erroneously created new dataset entries for each
    * view (JAL-3171) this test ensures we can import and merge those views
    */
+  @Test(groups = { "Functional" })
   public void testMergeDatasetsforViews() throws IOException
   {
+    // simple project - two views on one alignment
     AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
             "examples/testdata/projects/twoViews.jvp", DataSourceType.FILE);
     assertNotNull(af);
     assertTrue(af.getAlignPanels().size() > 1);
+    verifyDs(af);
+  }
+
+  /**
+   * pre 2.11 - jalview 2.10 erroneously created new dataset entries for each
+   * view (JAL-3171) this test ensures we can import and merge those views This
+   * is a more complex project
+   */
+  @Test(groups = { "Functional" })
+  public void testMergeDatasetsforManyViews() throws IOException
+  {
+    Desktop.instance.closeAll_actionPerformed(null);
+
+    // complex project - one dataset, several views on several alignments
+    AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
+            "examples/testdata/projects/manyViews.jvp",
+            DataSourceType.FILE);
+    assertNotNull(af);
+
+    AlignmentI ds = null;
+    for (AlignFrame alignFrame : Desktop.getAlignFrames())
+    {
+      if (ds == null)
+      {
+        ds = verifyDs(alignFrame);
+      }
+      else
+      {
+        // check that this frame's dataset matches the last
+        assertTrue(ds == verifyDs(alignFrame));
+      }
+    }
+  }
+
+  private AlignmentI verifyDs(AlignFrame af)
+  {
     AlignmentI ds = null;
     for (AlignmentViewPanel ap : af.getAlignPanels())
     {
@@ -1062,5 +1116,207 @@ public class Jalview2xmlTests extends Jalview2xmlBase
                 "Dataset was not the same for imported 2.10.5 project with several alignment views");
       }
     }
+    return ds;
+  }
+
+  @Test(groups = "Functional")
+  public void testRestorePCAViewAssociation() throws IOException
+  {
+    Desktop.instance.closeAll_actionPerformed(null);
+    final String PCAVIEWNAME = "With PCA";
+    // create a new tempfile
+    File tempfile = File.createTempFile("testRestorePCAViewAssociation",
+            "jvp");
+
+    {
+      String exampleFile = "examples/uniref50.fa";
+      AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
+              DataSourceType.FILE);
+      assertNotNull(af, "Didn't read in the example file correctly.");
+      AlignmentPanel origView = (AlignmentPanel) af.getAlignPanels().get(0);
+      AlignmentPanel newview = af.newView(PCAVIEWNAME, true);
+      // create another for good measure
+      af.newView("Not the PCA View", true);
+      PCAPanel pcaPanel = new PCAPanel(origView, "BLOSUM62",
+              new SimilarityParams(true, true, true, false));
+      // we're in the test exec thread, so we can just run synchronously here
+      pcaPanel.run();
+
+      // now switch the linked view
+      pcaPanel.selectAssociatedView(newview);
+
+      assertTrue(pcaPanel.getAlignViewport() == newview.getAlignViewport(),
+              "PCA should be associated with 'With PCA' view: test is broken");
+
+      // now save and reload project
+      Jalview2XML jv2xml = new jalview.project.Jalview2XML(false);
+      tempfile.delete();
+      jv2xml.saveState(tempfile);
+      assertTrue(jv2xml.errorMessage == null,
+              "Failed to save dummy project with PCA: test broken");
+    }
+
+    // load again.
+    Desktop.instance.closeAll_actionPerformed(null);
+    AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+            tempfile.getCanonicalPath(), DataSourceType.FILE);
+    JInternalFrame[] frames = Desktop.instance.getAllFrames();
+    // PCA and the tabbed alignment view should be the only two windows on the
+    // desktop
+    assertEquals(frames.length, 2,
+            "PCA and the tabbed alignment view should be the only two windows on the desktop");
+    PCAPanel pcaPanel = (PCAPanel) frames[frames[0] == af ? 1 : 0];
+
+    AlignmentViewPanel restoredNewView = null;
+    for (AlignmentViewPanel alignpanel : Desktop.getAlignmentPanels(null))
+    {
+      if (alignpanel.getAlignViewport() == pcaPanel.getAlignViewport())
+      {
+        restoredNewView = alignpanel;
+      }
+    }
+    assertEquals(restoredNewView.getViewName(), PCAVIEWNAME);
+    assertTrue(
+            restoredNewView.getAlignViewport() == pcaPanel
+                    .getAlignViewport(),
+            "Didn't restore correct view association for the PCA view");
+  }
+
+  /**
+   * Test that annotation ordering is faithfully restored
+   * 
+   * @throws Exception
+   */
+  @Test(groups = { "Functional" })
+  public void testRestoreAnnotationOrdering() throws Exception
+  {
+    Desktop.instance.closeAll_actionPerformed(null);
+    Cache.setProperty("SHOW_ANNOTATION", "true");
+    Cache.setProperty("SHOW_CONSERVATION", "true");
+    Cache.setProperty("SHOW_QUALITY", "false");
+    Cache.setProperty("SHOW_IDENTITY", "false");
+    Cache.setProperty("SHOW_OCCUPANCY", "true");
+    AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+            "examples/uniref50.fa", DataSourceType.FILE);
+    assertNotNull(af, "Didn't read in the example file correctly.");
+
+    AlignFrame[] afs = Desktop.getAlignFrames();
+    assertEquals(afs.length, 1);
+    AlignmentI alignment = afs[0].getViewport().getAlignment();
+    AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation();
+    assertEquals(anns.length, 2);
+
+    /*
+     * this order is hard wired in AlignmentViewport.initAutoAnnotation()
+     */
+    assertEquals(anns[0].label, "Conservation");
+    assertEquals(anns[1].label, "Occupancy");
+
+    /*
+     * add two user annotations, adjust order, height and visibility
+     */
+    AlignmentAnnotation tmp = anns[0];
+    anns[0] = anns[1];
+    anns[1] = tmp;
+    Annotation[] an1 = new Annotation[] { new Annotation(2f) };
+    Annotation[] an2 = new Annotation[] { new Annotation(3f) };
+    alignment.addAnnotation(new AlignmentAnnotation("hello", "desc1", an1),
+            1);
+    alignment.addAnnotation(new AlignmentAnnotation("world", "desc2", an2),
+            3);
+    anns = alignment.getAlignmentAnnotation();
+    assertEquals(anns[0].label, "Occupancy");
+    assertEquals(anns[1].label, "hello");
+    assertEquals(anns[2].label, "Conservation");
+    assertEquals(anns[3].label, "world");
+    anns[0].graphHeight = 60;
+    anns[0].visible = false;
+    anns[1].graphHeight = 70;
+    anns[2].graphHeight = 80;
+    anns[3].graphHeight = 90;
+    anns[3].visible = false;
+
+    /*
+     * save project to temporary file and reload on to an empty desktop,
+     * verify annotation order, height and visibility is restored
+     */
+    File projectFile = File.createTempFile("jvTest", ".jvp");
+    new Jalview2XML(false).saveState(projectFile);
+    Desktop.instance.closeAll_actionPerformed(null);
+    if (Desktop.getAlignFrames() != null)
+    {
+      Assert.assertEquals(Desktop.getAlignFrames().length, 0);
+    }
+  
+    af = new FileLoader().LoadFileWaitTillLoaded(
+            projectFile.getAbsolutePath(),
+            DataSourceType.FILE);
+    anns = af.getViewport().getAlignment().getAlignmentAnnotation();
+    assertEquals(anns.length, 4);
+    assertEquals(anns[0].label, "Occupancy");
+    assertEquals(anns[1].label, "hello");
+    assertEquals(anns[2].label, "Conservation");
+    assertEquals(anns[3].label, "world");
+    assertEquals(anns[0].graphHeight, 60);
+    assertEquals(anns[1].graphHeight, 70);
+    assertEquals(anns[2].graphHeight, 80);
+    assertEquals(anns[3].graphHeight, 90);
+    assertFalse(anns[0].visible);
+    assertTrue(anns[1].visible);
+    assertTrue(anns[2].visible);
+    assertFalse(anns[3].visible);
+
+    /*
+     * make a new view of the alignment (uses project save/load code)
+     * and verify annotations are ordered the same
+     */
+    AlignmentPanel newPanel = af.newView("new", true);
+    AlignmentAnnotation[] newAnns = newPanel.getAlignment()
+            .getAlignmentAnnotation();
+    assertEquals(newAnns.length, 4);
+    assertEquals(newAnns[0].label, "Occupancy");
+    assertEquals(newAnns[1].label, "hello");
+    assertEquals(newAnns[2].label, "Conservation");
+    assertEquals(newAnns[3].label, "world");
+    assertEquals(newAnns[0].graphHeight, 60);
+    assertEquals(newAnns[1].graphHeight, 70);
+    assertEquals(newAnns[2].graphHeight, 80);
+    assertEquals(newAnns[3].graphHeight, 90);
+    assertFalse(newAnns[0].visible);
+    assertTrue(newAnns[1].visible);
+    assertTrue(newAnns[2].visible);
+    assertFalse(newAnns[3].visible);
+    newPanel.closePanel();
+
+    /*
+     * reload the project with Preferences set to not create Occupancy;
+     * this should still appear, as it is in the saved project
+     */
+    Desktop.instance.closeAll_actionPerformed(null);
+    Cache.setProperty("SHOW_OCCUPANCY", "false");
+    af = new FileLoader().LoadFileWaitTillLoaded(
+            projectFile.getAbsolutePath(), DataSourceType.FILE);
+    anns = af.getViewport().getAlignment().getAlignmentAnnotation();
+    assertEquals(anns.length, 4);
+    assertEquals(anns[0].label, "Occupancy");
+    assertEquals(anns[1].label, "hello");
+    assertEquals(anns[2].label, "Conservation");
+    assertEquals(anns[3].label, "world");
+
+    /*
+     * reload the project with Preferences set to create Quality annotation;
+     * this should not appear, as it is not in the saved project
+     */
+    Desktop.instance.closeAll_actionPerformed(null);
+    Cache.setProperty("SHOW_OCCUPANCY", "false");
+    Cache.setProperty("SHOW_QUALITY", "true");
+    af = new FileLoader().LoadFileWaitTillLoaded(
+            projectFile.getAbsolutePath(), DataSourceType.FILE);
+    anns = af.getViewport().getAlignment().getAlignmentAnnotation();
+    assertEquals(anns.length, 4);
+    assertEquals(anns[0].label, "Occupancy");
+    assertEquals(anns[1].label, "hello");
+    assertEquals(anns[2].label, "Conservation");
+    assertEquals(anns[3].label, "world");
   }
 }