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