8b975bd19adf5d93807071d8d60c1d111bb29dcb
[jalview.git] / test / jalview / gui / AlignFrameTest.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.gui;
22
23 import static org.junit.Assert.assertNotEquals;
24 import static org.testng.Assert.assertEquals;
25 import static org.testng.Assert.assertFalse;
26 import static org.testng.Assert.assertNotSame;
27 import static org.testng.Assert.assertSame;
28 import static org.testng.Assert.assertTrue;
29
30 import jalview.api.FeatureColourI;
31 import jalview.bin.Cache;
32 import jalview.bin.Jalview;
33 import jalview.datamodel.Alignment;
34 import jalview.datamodel.AlignmentI;
35 import jalview.datamodel.HiddenColumns;
36 import jalview.datamodel.Sequence;
37 import jalview.datamodel.SequenceFeature;
38 import jalview.datamodel.SequenceGroup;
39 import jalview.datamodel.SequenceI;
40 import jalview.io.DataSourceType;
41 import jalview.io.FileLoader;
42 import jalview.project.Jalview2xmlTests;
43 import jalview.renderer.ResidueShaderI;
44 import jalview.schemes.BuriedColourScheme;
45 import jalview.schemes.FeatureColour;
46 import jalview.schemes.HelixColourScheme;
47 import jalview.schemes.JalviewColourScheme;
48 import jalview.schemes.StrandColourScheme;
49 import jalview.schemes.TurnColourScheme;
50 import jalview.util.MessageManager;
51
52 import java.awt.Color;
53 import java.util.Iterator;
54
55 import org.testng.annotations.AfterMethod;
56 import org.testng.annotations.BeforeClass;
57 import org.testng.annotations.BeforeMethod;
58 import org.testng.annotations.Test;
59
60 public class AlignFrameTest
61 {
62   AlignFrame af;
63
64   @BeforeClass(alwaysRun = true)
65   public void setUpJvOptionPane()
66   {
67     JvOptionPane.setInteractiveMode(false);
68     JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
69     Jalview.setSynchronous(true);
70   }
71
72   @Test(groups = "Functional")
73   public void testHideFeatureColumns()
74   {
75     SequenceI seq1 = new Sequence("Seq1", "ABCDEFGHIJ");
76     SequenceI seq2 = new Sequence("Seq2", "ABCDEFGHIJ");
77     seq1.addSequenceFeature(new SequenceFeature("Metal", "", 1, 5, 0f, null));
78     seq2.addSequenceFeature(new SequenceFeature("Metal", "", 6, 10, 10f,
79             null));
80     seq1.addSequenceFeature(new SequenceFeature("Turn", "", 2, 4,
81             Float.NaN, null));
82     seq2.addSequenceFeature(new SequenceFeature("Turn", "", 7, 9,
83             Float.NaN, null));
84     AlignmentI al = new Alignment(new SequenceI[] { seq1, seq2 });
85     AlignFrame alignFrame = new AlignFrame(al, al.getWidth(),
86             al.getHeight());
87
88     /*
89      * make all features visible (select feature columns checks visibility)
90      */
91     alignFrame.getFeatureRenderer().findAllFeatures(true);
92
93     /*
94      * hiding a feature not present does nothing
95      */
96     assertFalse(alignFrame.hideFeatureColumns("exon", true));
97     assertTrue(alignFrame.getViewport().getColumnSelection().isEmpty());
98
99     assertEquals(alignFrame.getViewport().getAlignment().getHiddenColumns()
100             .getNumberOfRegions(), 0);
101
102     assertFalse(alignFrame.hideFeatureColumns("exon", false));
103     assertTrue(alignFrame.getViewport().getColumnSelection().isEmpty());
104
105     assertEquals(alignFrame.getViewport().getAlignment().getHiddenColumns()
106             .getNumberOfRegions(), 0);
107
108     /*
109      * hiding a feature in all columns does nothing
110      */
111     assertFalse(alignFrame.hideFeatureColumns("Metal", true));
112     assertTrue(alignFrame.getViewport().getColumnSelection().isEmpty());
113
114     assertEquals(alignFrame.getViewport().getAlignment().getHiddenColumns()
115             .getNumberOfRegions(), 0);
116
117
118     /*
119      * threshold Metal to hide features where score < 5
120      * seq1 feature in columns 1-5 is hidden
121      * seq2 feature in columns 6-10 is shown
122      */
123     FeatureColourI fc = new FeatureColour(null, Color.red, Color.blue, null,
124             0f, 10f);
125     fc.setAboveThreshold(true);
126     fc.setThreshold(5f);
127     alignFrame.getFeatureRenderer().setColour("Metal", fc);
128     assertTrue(alignFrame.hideFeatureColumns("Metal", true));
129     HiddenColumns hidden = alignFrame.getViewport().getAlignment().getHiddenColumns();
130     assertEquals(hidden.getNumberOfRegions(), 1);
131     Iterator<int[]> regions = hidden.iterator();
132     int[] next = regions.next();
133     assertEquals(next[0], 5);
134     assertEquals(next[1], 9);
135
136     /*
137      * hide a feature present in some columns
138      * sequence positions [2-4], [7-9] are column positions
139      * [1-3], [6-8] base zero
140      */
141     alignFrame.getViewport().showAllHiddenColumns();
142     assertTrue(alignFrame.hideFeatureColumns("Turn", true));
143     regions = alignFrame.getViewport().getAlignment()
144             .getHiddenColumns().iterator();
145     assertEquals(alignFrame.getViewport().getAlignment().getHiddenColumns()
146             .getNumberOfRegions(), 2);
147     next = regions.next();
148     assertEquals(next[0], 1);
149     assertEquals(next[1], 3);
150     next = regions.next();
151     assertEquals(next[0], 6);
152     assertEquals(next[1], 8);
153   }
154
155   @BeforeClass(alwaysRun = true)
156   public static void setUpBeforeClass() throws Exception
157   {
158     /*
159      * use read-only test properties file
160      */
161     Cache.loadProperties("test/jalview/io/testProps.jvprops");
162     Jalview.main(new String[] { "-nonews" });
163   }
164
165   @AfterMethod(alwaysRun = true)
166   public void tearDown()
167   {
168     Desktop.getInstance().closeAll_actionPerformed(null);
169   }
170
171   /**
172    * configure (read-only) properties for test to ensure Consensus is computed
173    * for colour Above PID testing
174    */
175   @BeforeMethod(alwaysRun = true)
176   public void setUp()
177   {
178     Cache.loadProperties("test/jalview/io/testProps.jvprops");
179     Cache.getInstance().applicationProperties.setProperty("SHOW_IDENTITY",
180             Boolean.TRUE.toString());
181     af = new FileLoader().LoadFileWaitTillLoaded("examples/uniref50.fa",
182             DataSourceType.FILE);
183
184     /*
185      * wait for Consensus thread to complete
186      */
187     synchronized (this)
188     {
189       while (af.getViewport().getConsensusSeq() == null)
190       {
191         try
192         {
193           wait(50);
194         } catch (InterruptedException e)
195         {
196         }
197       }
198     }
199   }
200
201   /**
202    * Test that changing background (alignment) colour scheme
203    * <ul>
204    * <li>with Apply Colour to All Groups not selected, does not change group
205    * colours</li>
206    * <li>with Apply Colour to All Groups selected, does change group colours</li>
207    * <li>in neither case, changes alignment or group colour thresholds (PID or
208    * Conservation)</li>
209    * </ul>
210    */
211   @Test(groups = "Functional")
212   public void testChangeColour_background_groupsAndThresholds()
213   {
214     AlignViewport av = af.getViewport();
215     AlignmentI al = av.getAlignment();
216
217     /*
218      * Colour alignment by Buried Index
219      */
220     af.applyToAllGroups_actionPerformed(false);
221     af.changeColour_actionPerformed(JalviewColourScheme.Buried.toString());
222     assertTrue(av.getGlobalColourScheme() instanceof BuriedColourScheme);
223     assertFalse(av.getResidueShading().conservationApplied());
224     assertEquals(av.getResidueShading().getThreshold(), 0);
225
226     /*
227      * Apply Conservation 20%
228      */
229     af.conservationMenuItem_actionPerformed(true);
230     SliderPanel sp = SliderPanel.getSliderPanel();
231     assertEquals(sp.getTitle(), MessageManager.formatMessage(
232             "label.conservation_colour_increment",
233             new String[] { "Background" }));
234     assertTrue(sp.isForConservation());
235     sp.valueChanged(20);
236     assertTrue(av.getResidueShading().conservationApplied());
237     assertEquals(av.getResidueShading().getConservationInc(), 20);
238
239     /*
240      * Apply PID threshold 10% (conservation still applies as well)
241      */
242     af.abovePIDThreshold_actionPerformed(true);
243     sp = SliderPanel.getSliderPanel();
244     assertFalse(sp.isForConservation());
245     assertEquals(sp.getTitle(), MessageManager.formatMessage(
246             "label.percentage_identity_threshold",
247             new String[] { "Background" }));
248     sp.valueChanged(10);
249     assertEquals(av.getResidueShading().getThreshold(), 10);
250     assertTrue(av.getResidueShading().conservationApplied());
251     assertEquals(av.getResidueShading().getConservationInc(), 20);
252
253     /*
254      * create a group with Strand colouring, 30% Conservation
255      * and 40% PID threshold
256      */
257     SequenceGroup sg = new SequenceGroup();
258     sg.addSequence(al.getSequenceAt(0), false);
259     sg.setStartRes(15);
260     sg.setEndRes(25);
261     av.setSelectionGroup(sg);
262
263     /*
264      * apply 30% Conservation to group
265      */
266     PopupMenu popupMenu = new PopupMenu(af.alignPanel, null, null);
267     popupMenu.changeColour_actionPerformed(JalviewColourScheme.Strand
268             .toString());
269     assertTrue(sg.getColourScheme() instanceof StrandColourScheme);
270     assertEquals(al.getGroups().size(), 1);
271     assertSame(al.getGroups().get(0), sg);
272     popupMenu.conservationMenuItem_actionPerformed(true);
273     sp = SliderPanel.getSliderPanel();
274     assertTrue(sp.isForConservation());
275     assertEquals(sp.getTitle(), MessageManager.formatMessage(
276             "label.conservation_colour_increment",
277             new String[] { sg.getName() }));
278     sp.valueChanged(30);
279     assertTrue(sg.getGroupColourScheme().conservationApplied());
280     assertEquals(sg.getGroupColourScheme().getConservationInc(), 30);
281
282     /*
283      * apply 40% PID threshold to group
284      */
285     popupMenu.abovePIDColour_actionPerformed(true);
286     sp = SliderPanel.getSliderPanel();
287     assertFalse(sp.isForConservation());
288     assertEquals(sp.getTitle(), MessageManager.formatMessage(
289             "label.percentage_identity_threshold",
290             new String[] { sg.getName() }));
291     sp.valueChanged(40);
292     assertEquals(sg.getGroupColourScheme().getThreshold(), 40);
293     // conservation threshold is unchanged:
294     assertTrue(sg.getGroupColourScheme().conservationApplied());
295     assertEquals(sg.getGroupColourScheme().getConservationInc(), 30);
296
297     /*
298      * change alignment colour - group colour, and all thresholds,
299      * should be unaffected
300      */
301     af.changeColour_actionPerformed(JalviewColourScheme.Turn.toString());
302     assertTrue(av.getGlobalColourScheme() instanceof TurnColourScheme);
303     assertTrue(av.getResidueShading().conservationApplied());
304     assertEquals(av.getResidueShading().getConservationInc(), 20);
305     assertEquals(av.getResidueShading().getThreshold(), 10);
306     assertTrue(sg.getColourScheme() instanceof StrandColourScheme);
307     assertTrue(sg.getGroupColourScheme().conservationApplied());
308     assertEquals(sg.getGroupColourScheme().getConservationInc(), 30);
309     assertEquals(sg.getGroupColourScheme().getThreshold(), 40);
310
311     /*
312      * Now change alignment colour with Apply Colour To All Groups
313      * - group colour should change, but not colour thresholds
314      */
315     af.applyToAllGroups_actionPerformed(true);
316     af.changeColour_actionPerformed(JalviewColourScheme.Helix.toString());
317     assertTrue(av.getGlobalColourScheme() instanceof HelixColourScheme);
318     assertTrue(av.getResidueShading().conservationApplied());
319     assertEquals(av.getResidueShading().getConservationInc(), 20);
320     assertEquals(av.getResidueShading().getThreshold(), 10);
321     assertTrue(sg.getColourScheme() instanceof HelixColourScheme);
322     assertTrue(sg.getGroupColourScheme().conservationApplied());
323     assertEquals(sg.getGroupColourScheme().getConservationInc(), 30);
324     assertEquals(sg.getGroupColourScheme().getThreshold(), 40);
325   }
326
327   /**
328    * Test residue colouring with various options
329    * <ol>
330    * <li>no PID or Conservation threshold</li>
331    * <li>colour by Conservation applied</li>
332    * <li>colour by Conservation removed</li>
333    * <li>colour above PID - various values</li>
334    * <li>colour above PID removed</li>
335    * <li>Above PID plus By Conservation combined</li>
336    * <li>remove Above PID to leave just By Conservation</li>
337    * <li>re-add Above PID</li>
338    * <li>remove By Conservation to leave just Above PID</li>
339    * <li>remove Above PID to leave original colours</li>
340    * </ol>
341    */
342   @Test(groups = "Functional")
343   public void testColourThresholdActions()
344   {
345     AlignViewport av = af.getViewport();
346     AlignmentI al = av.getAlignment();
347
348     /*
349      * Colour alignment by Helix Propensity, no thresholds
350      */
351     af.applyToAllGroups_actionPerformed(false);
352     af.changeColour_actionPerformed(JalviewColourScheme.Helix.toString());
353     assertTrue(av.getGlobalColourScheme() instanceof HelixColourScheme);
354     assertFalse(av.getResidueShading().conservationApplied());
355     assertEquals(av.getResidueShading().getThreshold(), 0);
356
357     /*
358      * inspect the colour of 
359      * FER_CAPAN.9(I), column 14 (14 base 0)
360      * FER_CAPAN.10(SER), column 16 (15 base 0)
361      */
362     SequenceI ferCapan = al.findName("FER_CAPAN");
363     ResidueShaderI rs = av.getResidueShading();
364     Color c = rs.findColour('I', 14, ferCapan);
365     Color i_original = new Color(138, 117, 138);
366     assertEquals(c, i_original);
367     c = rs.findColour('S', 15, ferCapan);
368     Color s_original = new Color(54, 201, 54);
369     assertEquals(c, s_original);
370
371     /*
372      * colour by conservation with increment 10
373      */
374     af.conservationMenuItem_actionPerformed(true);
375     SliderPanel sp = SliderPanel.getSliderPanel();
376     assertTrue(sp.isForConservation());
377     assertEquals(sp.getValue(), 30); // initial slider setting
378     sp.valueChanged(10);
379     assertSame(rs, av.getResidueShading());
380     c = rs.findColour('I', 14, ferCapan);
381     Color i_faded = new Color(196, 186, 196);
382     assertEquals(c, i_faded);
383     c = rs.findColour('S', 15, ferCapan);
384     Color s_faded = new Color(144, 225, 144);
385     assertEquals(c, s_faded);
386
387     /*
388      * deselect By Conservation - colour should revert
389      */
390     af.conservationMenuItem_actionPerformed(false);
391     c = rs.findColour('S', 15, ferCapan);
392     assertEquals(c, s_original);
393
394     /*
395      * now Above PID, threshold = 0%
396      * should be no change
397      */
398     af.abovePIDThreshold_actionPerformed(true);
399     sp = SliderPanel.getSliderPanel();
400     assertFalse(sp.isForConservation());
401     assertEquals(sp.getValue(), 0); // initial slider setting
402     c = rs.findColour('I', 14, ferCapan);
403     assertEquals(c, i_original);
404     c = rs.findColour('S', 15, ferCapan);
405     assertEquals(c, s_original);
406
407     /*
408      * Above PID, threshold = 1%
409      * 15.I becomes White because no match to consensus (V)
410      * 16.S remains coloured as matches 66.66% consensus
411      */
412     sp.valueChanged(1);
413     c = rs.findColour('I', 14, ferCapan);
414     assertEquals(c, Color.white);
415     c = rs.findColour('S', 15, ferCapan);
416     assertEquals(c, s_original);
417
418     /*
419      * threshold 66% - no further change yet...
420      */
421     sp.valueChanged(66);
422     c = rs.findColour('I', 14, ferCapan);
423     assertEquals(c, Color.white);
424     c = rs.findColour('S', 15, ferCapan);
425     assertEquals(c, s_original);
426
427     /*
428      * threshold 67% - now both residues are white
429      */
430     sp.valueChanged(67);
431     c = rs.findColour('I', 14, ferCapan);
432     assertEquals(c, Color.white);
433     c = rs.findColour('S', 15, ferCapan);
434     assertEquals(c, Color.white);
435
436     /*
437      * deselect Above PID - colours should revert
438      */
439     af.abovePIDThreshold_actionPerformed(false);
440     c = rs.findColour('I', 14, ferCapan);
441     assertEquals(c, i_original);
442     c = rs.findColour('S', 15, ferCapan);
443     assertEquals(c, s_original);
444
445     /*
446      * Now combine Above 50% PID and By Conservation 10%
447      * 15.I is White because no match to consensus (V)
448      * 16.S is coloured but faded
449      */
450     af.abovePIDThreshold_actionPerformed(true);
451     sp = SliderPanel.getSliderPanel();
452     assertFalse(sp.isForConservation());
453     sp.valueChanged(50);
454     af.conservationMenuItem_actionPerformed(true);
455     sp = SliderPanel.getSliderPanel();
456     assertTrue(sp.isForConservation());
457     sp.valueChanged(10);
458     c = rs.findColour('I', 14, ferCapan);
459     assertEquals(c, Color.white);
460     c = rs.findColour('S', 15, ferCapan);
461     assertEquals(c, s_faded);
462
463     /*
464      * turn off Above PID - should just leave Conservation fading as before 
465      */
466     af.abovePIDThreshold_actionPerformed(false);
467     c = rs.findColour('I', 14, ferCapan);
468     assertEquals(c, i_faded);
469     c = rs.findColour('S', 15, ferCapan);
470     assertEquals(c, s_faded);
471
472     /*
473      * Now add Above 50% PID to conservation colouring
474      * - should give the same as PID followed by conservation (above)
475      */
476     af.abovePIDThreshold_actionPerformed(true);
477     SliderPanel.getSliderPanel().valueChanged(50);
478     c = rs.findColour('I', 14, ferCapan);
479     assertEquals(c, Color.white);
480     c = rs.findColour('S', 15, ferCapan);
481     assertEquals(c, s_faded);
482
483     /*
484      * turn off By Conservation
485      * should leave I white, S original (unfaded) colour
486      */
487     af.conservationMenuItem_actionPerformed(false);
488     c = rs.findColour('I', 14, ferCapan);
489     assertEquals(c, Color.white);
490     c = rs.findColour('S', 15, ferCapan);
491     assertEquals(c, s_original);
492
493     /*
494      * finally turn off Above PID to leave original colours
495      */
496     af.abovePIDThreshold_actionPerformed(false);
497     c = rs.findColour('I', 14, ferCapan);
498     assertEquals(c, i_original);
499     c = rs.findColour('S', 15, ferCapan);
500     assertEquals(c, s_original);
501   }
502
503   /**
504    * Verify that making a New View transfers alignment and group colour schemes,
505    * including any thresholds, to the new view. Because New View is performed by
506    * saving and reloading a 'project' file, this is similar to verifying a
507    * project save and reload.
508    * 
509    * @see Jalview2xmlTests#testStoreAndRecoverColourThresholds()
510    */
511   @Test(groups = "Functional")
512   public void testNewView_colourThresholds()
513   {
514     AlignViewport av = af.getViewport();
515     AlignmentI al = av.getAlignment();
516
517     /*
518      * Colour alignment by Buried Index, Above 10% PID, By Conservation 20%
519      */
520     af.changeColour_actionPerformed(JalviewColourScheme.Buried.toString());
521     assertTrue(av.getGlobalColourScheme() instanceof BuriedColourScheme);
522     af.abovePIDThreshold_actionPerformed(true);
523     SliderPanel sp = SliderPanel.getSliderPanel();
524     assertFalse(sp.isForConservation());
525     sp.valueChanged(10);
526     af.conservationMenuItem_actionPerformed(true);
527     sp = SliderPanel.getSliderPanel();
528     assertTrue(sp.isForConservation());
529     sp.valueChanged(20);
530     ResidueShaderI rs = av.getResidueShading();
531     assertEquals(rs.getThreshold(), 10);
532     assertTrue(rs.conservationApplied());
533     assertEquals(rs.getConservationInc(), 20);
534
535     /*
536      * create a group with Strand colouring, 30% Conservation
537      * and 40% PID threshold
538      */
539     SequenceGroup sg = new SequenceGroup();
540     sg.addSequence(al.getSequenceAt(0), false);
541     sg.setStartRes(15);
542     sg.setEndRes(25);
543     av.setSelectionGroup(sg);
544     PopupMenu popupMenu = new PopupMenu(af.alignPanel, null, null);
545     popupMenu.changeColour_actionPerformed(JalviewColourScheme.Strand
546             .toString());
547     assertTrue(sg.getColourScheme() instanceof StrandColourScheme);
548     assertEquals(al.getGroups().size(), 1);
549     assertSame(al.getGroups().get(0), sg);
550     popupMenu.conservationMenuItem_actionPerformed(true);
551     sp = SliderPanel.getSliderPanel();
552     assertTrue(sp.isForConservation());
553     sp.valueChanged(30);
554     popupMenu.abovePIDColour_actionPerformed(true);
555     sp = SliderPanel.getSliderPanel();
556     assertFalse(sp.isForConservation());
557     sp.valueChanged(40);
558     rs = sg.getGroupColourScheme();
559     assertTrue(rs.conservationApplied());
560     assertEquals(rs.getConservationInc(), 30);
561     assertEquals(rs.getThreshold(), 40);
562
563     /*
564      * set slider panel focus to the background alignment
565      */
566     af.conservationMenuItem_actionPerformed(true);
567     sp = SliderPanel.getSliderPanel();
568     assertTrue(sp.isForConservation());
569     assertEquals(sp.getTitle(), MessageManager.formatMessage(
570             "label.conservation_colour_increment",
571             new String[] { "Background" }));
572
573     /*
574      * make a new View, verify alignment and group colour schemes
575      */
576     af.newView_actionPerformed(null);
577     assertEquals(af.alignPanel.getViewName(), "View 1");
578     AlignViewport av2 = af.getViewport();
579     assertNotSame(av, av2);
580     assertSame(av2, af.alignPanel.av);
581     rs = av2.getResidueShading();
582     assertNotSame(av.getResidueShading(), rs);
583     assertEquals(rs.getThreshold(), 10);
584     assertTrue(rs.conservationApplied(), rs.toString());
585     assertEquals(rs.getConservationInc(), 20);
586     assertEquals(av2.getAlignment().getGroups().size(), 1);
587     sg = av2.getAlignment().getGroups().get(0);
588     rs = sg.getGroupColourScheme();
589     assertTrue(rs.conservationApplied());
590     assertEquals(rs.getConservationInc(), 30);
591     assertEquals(rs.getThreshold(), 40);
592
593     /*
594      * check the Conservation SliderPanel (still open) is linked to 
595      * and updates the new view (JAL-2385)
596      */
597     sp = SliderPanel.getSliderPanel();
598     assertTrue(sp.isForConservation());
599     assertEquals(sp.getTitle(), MessageManager.formatMessage(
600             "label.conservation_colour_increment",
601             new String[] { "View 1" }));
602     sp.valueChanged(22);
603     assertEquals(av2.getResidueShading().getConservationInc(), 22);
604   }
605
606   /**
607    * Verify that making a New View preserves the dataset reference for the
608    * alignment. Otherwise, see a 'duplicate jar entry' reference when trying to
609    * save alignments with multiple views, and codon mappings will not be shared
610    * across all panels in a split frame.
611    * 
612    * @see Jalview2xmlTests#testStoreAndRecoverColourThresholds()
613    */
614   @Test(groups = "Functional")
615   public void testNewView_dsRefPreserved()
616   {
617     AlignViewport av = af.getViewport();
618     AlignmentI al = av.getAlignment();
619     AlignmentI original_ds = al.getDataset();
620     af.newView_actionPerformed(null);
621     assertNotEquals("New view didn't select the a new panel", av,
622             af.getViewport());
623     org.testng.Assert.assertEquals(original_ds,
624             af.getViewport().getAlignment().getDataset(),
625             "Dataset was not preserved in new view");
626   }
627 }