2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
21 package jalview.project;
23 import static org.testng.Assert.assertEquals;
24 import static org.testng.Assert.assertFalse;
25 import static org.testng.Assert.assertNotNull;
26 import static org.testng.Assert.assertNotSame;
27 import static org.testng.Assert.assertNull;
28 import static org.testng.Assert.assertSame;
29 import static org.testng.Assert.assertTrue;
31 import java.awt.Color;
32 import java.awt.Rectangle;
34 import java.io.IOException;
35 import java.math.BigInteger;
36 import java.util.ArrayList;
37 import java.util.BitSet;
38 import java.util.HashMap;
39 import java.util.List;
40 import java.util.Locale;
43 import javax.swing.JInternalFrame;
45 import org.testng.Assert;
46 import org.testng.AssertJUnit;
47 import org.testng.annotations.BeforeClass;
48 import org.testng.annotations.Test;
50 import jalview.analysis.AlignmentUtils;
51 import jalview.analysis.scoremodels.SimilarityParams;
52 import jalview.api.AlignViewportI;
53 import jalview.api.AlignmentViewPanel;
54 import jalview.api.FeatureColourI;
55 import jalview.api.ViewStyleI;
56 import jalview.bin.Cache;
57 import jalview.datamodel.AlignmentAnnotation;
58 import jalview.datamodel.AlignmentI;
59 import jalview.datamodel.Annotation;
60 import jalview.datamodel.ContactListI;
61 import jalview.datamodel.ContactMatrix;
62 import jalview.datamodel.ContactMatrixI;
63 import jalview.datamodel.DBRefEntry;
64 import jalview.datamodel.GeneLocus;
65 import jalview.datamodel.GroupSet;
66 import jalview.datamodel.HiddenSequences;
67 import jalview.datamodel.Mapping;
68 import jalview.datamodel.PDBEntry;
69 import jalview.datamodel.PDBEntry.Type;
70 import jalview.datamodel.Sequence.DBModList;
71 import jalview.datamodel.SequenceCollectionI;
72 import jalview.datamodel.SequenceFeature;
73 import jalview.datamodel.SequenceGroup;
74 import jalview.datamodel.SequenceI;
75 import jalview.datamodel.features.FeatureMatcher;
76 import jalview.datamodel.features.FeatureMatcherSet;
77 import jalview.datamodel.features.FeatureMatcherSetI;
78 import jalview.gui.AlignFrame;
79 import jalview.gui.AlignViewport;
80 import jalview.gui.AlignmentPanel;
81 import jalview.gui.Desktop;
82 import jalview.gui.JvOptionPane;
83 import jalview.gui.OverviewPanel;
84 import jalview.gui.PCAPanel;
85 import jalview.gui.PopupMenu;
86 import jalview.gui.Preferences;
87 import jalview.gui.SliderPanel;
88 import jalview.io.DataSourceType;
89 import jalview.io.FileFormat;
90 import jalview.io.FileLoader;
91 import jalview.io.Jalview2xmlBase;
92 import jalview.renderer.ResidueShaderI;
93 import jalview.schemes.AnnotationColourGradient;
94 import jalview.schemes.BuriedColourScheme;
95 import jalview.schemes.ColourSchemeI;
96 import jalview.schemes.ColourSchemeProperty;
97 import jalview.schemes.FeatureColour;
98 import jalview.schemes.JalviewColourScheme;
99 import jalview.schemes.RNAHelicesColour;
100 import jalview.schemes.StrandColourScheme;
101 import jalview.schemes.TCoffeeColourScheme;
102 import jalview.structure.StructureImportSettings;
103 import jalview.util.MapList;
104 import jalview.util.matcher.Condition;
105 import jalview.viewmodel.AlignmentViewport;
106 import jalview.viewmodel.seqfeatures.FeatureRendererModel;
107 import jalview.ws.datamodel.MappableContactMatrixI;
108 import jalview.ws.datamodel.alphafold.PAEContactMatrix;
110 @Test(singleThreaded = true)
111 public class Jalview2xmlTests extends Jalview2xmlBase
115 @BeforeClass(alwaysRun = true)
116 public void setUpJvOptionPane()
118 if (Desktop.instance != null)
119 Desktop.instance.closeAll_actionPerformed(null);
120 JvOptionPane.setInteractiveMode(false);
121 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
124 @Test(groups = { "Functional" })
125 public void testRNAStructureRecovery() throws Exception
127 String inFile = "examples/RF00031_folded.stk";
128 String tfile = File.createTempFile("JalviewTest", ".jvp")
130 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
131 DataSourceType.FILE);
132 assertNotNull(af, "Didn't read input file " + inFile);
133 int olddsann = countDsAnn(af.getViewport());
134 assertTrue(olddsann > 0, "Didn't find any dataset annotations");
135 af.changeColour_actionPerformed(
136 JalviewColourScheme.RNAHelices.toString());
139 .getGlobalColourScheme() instanceof RNAHelicesColour,
140 "Couldn't apply RNA helices colourscheme");
141 af.saveAlignment(tfile, FileFormat.Jalview);
142 assertTrue(af.isSaveAlignmentSuccessful(),
143 "Failed to store as a project.");
144 af.closeMenuItem_actionPerformed(true);
146 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
147 DataSourceType.FILE);
148 assertNotNull(af, "Failed to import new project");
149 int newdsann = countDsAnn(af.getViewport());
150 assertEquals(olddsann, newdsann,
151 "Differing numbers of dataset sequence annotation\nOriginally "
152 + olddsann + " and now " + newdsann);
154 "Read in same number of annotations as originally present ("
159 .getGlobalColourScheme() instanceof RNAHelicesColour,
160 "RNA helices colourscheme was not applied on import.");
163 @Test(groups = { "Functional" })
164 public void testTCoffeeScores() throws Exception
166 String inFile = "examples/uniref50.fa",
167 inAnnot = "examples/uniref50.score_ascii";
168 String tfile = File.createTempFile("JalviewTest", ".jvp")
170 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
171 DataSourceType.FILE);
172 assertNotNull(af, "Didn't read input file " + inFile);
173 af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
174 AlignViewport viewport = af.getViewport();
175 assertSame(viewport.getGlobalColourScheme().getClass(),
176 TCoffeeColourScheme.class, "Didn't set T-coffee colourscheme");
178 ColourSchemeProperty.getColourScheme(viewport,
179 viewport.getAlignment(),
180 viewport.getGlobalColourScheme().getSchemeName()),
181 "Recognise T-Coffee score from string");
183 af.saveAlignment(tfile, FileFormat.Jalview);
184 assertTrue(af.isSaveAlignmentSuccessful(),
185 "Failed to store as a project.");
186 af.closeMenuItem_actionPerformed(true);
188 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
189 DataSourceType.FILE);
190 assertNotNull(af, "Failed to import new project");
191 assertSame(af.getViewport().getGlobalColourScheme().getClass(),
192 TCoffeeColourScheme.class,
193 "Didn't set T-coffee colourscheme for imported project.");
195 "T-Coffee score shading successfully recovered from project.");
198 @Test(groups = { "Functional" })
199 public void testColourByAnnotScores() throws Exception
201 String inFile = "examples/uniref50.fa",
202 inAnnot = "examples/testdata/uniref50_iupred.jva";
203 String tfile = File.createTempFile("JalviewTest", ".jvp")
205 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
206 DataSourceType.FILE);
207 assertNotNull(af, "Didn't read input file " + inFile);
208 af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
209 AlignmentAnnotation[] aa = af.getViewport().getAlignment()
210 .getSequenceAt(0).getAnnotation("IUPredWS (Short)");
213 aa != null && aa.length > 0,
214 "Didn't find any IUPred annotation to use to shade alignment.");
215 AnnotationColourGradient cs = new AnnotationColourGradient(aa[0], null,
216 AnnotationColourGradient.ABOVE_THRESHOLD);
217 AnnotationColourGradient gcs = new AnnotationColourGradient(aa[0], null,
218 AnnotationColourGradient.BELOW_THRESHOLD);
219 cs.setSeqAssociated(true);
220 gcs.setSeqAssociated(true);
222 SequenceGroup sg = new SequenceGroup();
225 sg.cs.setColourScheme(gcs);
226 af.getViewport().getAlignment().addGroup(sg);
227 sg.addSequence(af.getViewport().getAlignment().getSequenceAt(1), false);
228 sg.addSequence(af.getViewport().getAlignment().getSequenceAt(2), true);
229 af.alignPanel.alignmentChanged();
230 af.saveAlignment(tfile, FileFormat.Jalview);
231 assertTrue(af.isSaveAlignmentSuccessful(),
232 "Failed to store as a project.");
233 af.closeMenuItem_actionPerformed(true);
235 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
236 DataSourceType.FILE);
237 assertNotNull(af, "Failed to import new project");
239 // check for group and alignment colourschemes
241 ColourSchemeI _rcs = af.getViewport().getGlobalColourScheme();
242 ColourSchemeI _rgcs = af.getViewport().getAlignment().getGroups().get(0)
244 assertNotNull(_rcs, "Didn't recover global colourscheme");
245 assertTrue(_rcs instanceof AnnotationColourGradient,
246 "Didn't recover annotation colour global scheme");
247 AnnotationColourGradient __rcs = (AnnotationColourGradient) _rcs;
248 assertTrue(__rcs.isSeqAssociated(),
249 "Annotation colourscheme wasn't sequence associated");
251 boolean diffseqcols = false, diffgseqcols = false;
252 SequenceI[] sqs = af.getViewport().getAlignment().getSequencesArray();
253 for (int p = 0, pSize = af.getViewport().getAlignment()
254 .getWidth(); p < pSize && (!diffseqcols || !diffgseqcols); p++)
256 if (_rcs.findColour(sqs[0].getCharAt(p), p, sqs[0], null, 0f) != _rcs
257 .findColour(sqs[5].getCharAt(p), p, sqs[5], null, 0f))
262 assertTrue(diffseqcols, "Got Different sequence colours");
264 "Per sequence colourscheme (Background) successfully applied and recovered.");
266 assertNotNull(_rgcs, "Didn't recover group colourscheme");
267 assertTrue(_rgcs instanceof AnnotationColourGradient,
268 "Didn't recover annotation colour group colourscheme");
269 __rcs = (AnnotationColourGradient) _rgcs;
270 assertTrue(__rcs.isSeqAssociated(),
271 "Group Annotation colourscheme wasn't sequence associated");
273 for (int p = 0, pSize = af.getViewport().getAlignment()
274 .getWidth(); p < pSize && (!diffseqcols || !diffgseqcols); p++)
276 if (_rgcs.findColour(sqs[1].getCharAt(p), p, sqs[1], null,
277 0f) != _rgcs.findColour(sqs[2].getCharAt(p), p, sqs[2], null,
283 assertTrue(diffgseqcols, "Got Different group sequence colours");
285 "Per sequence (Group) colourscheme successfully applied and recovered.");
288 @Test(groups = { "Functional" })
289 public void gatherViewsHere() throws Exception
291 int origCount = Desktop.getAlignFrames() == null ? 0
292 : Desktop.getAlignFrames().length;
293 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
294 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
295 assertNotNull(af, "Didn't read in the example file correctly.");
296 assertTrue(Desktop.getAlignFrames().length == 1 + origCount,
297 "Didn't gather the views in the example file.");
302 * Test for JAL-2223 - multiple mappings in View Mapping report
306 @Test(groups = { "Functional" })
307 public void noDuplicatePdbMappingsMade() throws Exception
309 StructureImportSettings.setProcessSecondaryStructure(true);
310 StructureImportSettings.setVisibleChainAnnotation(true);
311 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
312 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
313 assertNotNull(af, "Didn't read in the example file correctly.");
315 // locate Jmol viewer
316 // count number of PDB mappings the structure selection manager holds -
317 String pdbFile = af.getCurrentView().getStructureSelectionManager()
318 .findFileForPDBId("1A70");
320 af.getCurrentView().getStructureSelectionManager()
321 .getMapping(pdbFile).length,
322 2, "Expected only two mappings for 1A70");
326 @Test(groups = { "Functional" })
327 public void viewRefPdbAnnotation() throws Exception
329 StructureImportSettings.setProcessSecondaryStructure(true);
330 StructureImportSettings.setVisibleChainAnnotation(true);
331 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
332 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
333 assertNotNull(af, "Didn't read in the example file correctly.");
334 AlignmentViewPanel sps = null;
335 for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
337 if ("Spinach Feredoxin Structure".equals(ap.getViewName()))
343 assertNotNull(sps, "Couldn't find the structure view");
344 AlignmentAnnotation refan = null;
345 for (AlignmentAnnotation ra : sps.getAlignment()
346 .getAlignmentAnnotation())
354 assertNotNull(refan, "Annotation secondary structure not found.");
355 SequenceI sq = sps.getAlignment().findName("1A70|");
356 assertNotNull(sq, "Couldn't find 1a70 null chain");
357 // compare the manually added temperature factor annotation
358 // to the track automatically transferred from the pdb structure on load
359 assertNotNull(sq.getDatasetSequence().getAnnotation(),
360 "1a70 has no annotation");
361 for (AlignmentAnnotation ala : sq.getDatasetSequence().getAnnotation())
363 AlignmentAnnotation alaa;
364 sq.addAlignmentAnnotation(alaa = new AlignmentAnnotation(ala));
365 alaa.adjustForAlignment();
366 if (ala.graph == refan.graph)
368 for (int p = 0; p < ala.annotations.length; p++)
373 assertTrue((alaa.annotations[p] == null
374 && refan.annotations[p] == null)
375 || alaa.annotations[p].value == refan.annotations[p].value,
376 "Mismatch at alignment position " + p);
377 } catch (NullPointerException q)
379 Assert.fail("Mismatch of alignment annotations at position " + p
380 + " Ref seq ann: " + refan.annotations[p]
381 + " alignment " + alaa.annotations[p]);
389 @Test(groups = { "Functional" })
390 public void testCopyViewSettings() throws Exception
392 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
393 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
394 assertNotNull(af, "Didn't read in the example file correctly.");
395 AlignmentViewPanel sps = null, groups = null;
396 for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
398 if ("Spinach Feredoxin Structure".equals(ap.getViewName()))
402 if (ap.getViewName().contains("MAFFT"))
407 assertNotNull(sps, "Couldn't find the structure view");
408 assertNotNull(groups, "Couldn't find the MAFFT view");
410 ViewStyleI structureStyle = sps.getAlignViewport().getViewStyle();
411 ViewStyleI groupStyle = groups.getAlignViewport().getViewStyle();
412 AssertJUnit.assertFalse(structureStyle.sameStyle(groupStyle));
414 groups.getAlignViewport().setViewStyle(structureStyle);
415 AssertJUnit.assertFalse(
416 groupStyle.sameStyle(groups.getAlignViewport().getViewStyle()));
417 Assert.assertTrue(structureStyle
418 .sameStyle(groups.getAlignViewport().getViewStyle()));
423 * test store and recovery of expanded views
427 @Test(groups = { "Functional" }, enabled = true)
428 public void testStoreAndRecoverExpandedviews() throws Exception
430 Desktop.instance.closeAll_actionPerformed(null);
432 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
433 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
434 Assert.assertEquals(Desktop.getAlignFrames().length, 1);
435 String afid = af.getViewport().getSequenceSetId();
437 // check FileLoader returned a reference to the one alignFrame that is
438 // actually on the Desktop
439 assertSame(af, Desktop.getAlignFrameFor(af.getViewport()),
440 "Jalview2XML.loadAlignFrame() didn't return correct AlignFrame reference for multiple view window");
442 Desktop.explodeViews(af);
444 int oldviews = Desktop.getAlignFrames().length;
445 Assert.assertEquals(Desktop.getAlignFrames().length,
446 Desktop.getAlignmentPanels(afid).length);
447 File tfile = File.createTempFile("testStoreAndRecoverExpanded", ".jvp");
450 new Jalview2XML(false).saveState(tfile);
453 Assert.fail("Didn't save the expanded view state", e);
454 } catch (Exception e)
456 Assert.fail("Didn't save the expanded view state", e);
458 Desktop.instance.closeAll_actionPerformed(null);
459 if (Desktop.getAlignFrames() != null)
461 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
463 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
464 DataSourceType.FILE);
465 Assert.assertNotNull(af);
466 Assert.assertEquals(Desktop.getAlignFrames().length,
467 Desktop.getAlignmentPanels(
468 af.getViewport().getSequenceSetId()).length);
469 Assert.assertEquals(Desktop
470 .getAlignmentPanels(af.getViewport().getSequenceSetId()).length,
475 * Test save and reload of a project with a different representative sequence
480 @Test(groups = { "Functional" })
481 public void testStoreAndRecoverReferenceSeqSettings() throws Exception
483 Desktop.instance.closeAll_actionPerformed(null);
484 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
485 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
486 assertNotNull(af, "Didn't read in the example file correctly.");
487 String afid = af.getViewport().getSequenceSetId();
489 // remember reference sequence for each panel
490 Map<String, SequenceI> refseqs = new HashMap<>();
493 * mark sequence 2, 3, 4.. in panels 1, 2, 3...
494 * as reference sequence for itself and the preceding sequence
497 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
499 AlignViewportI av = ap.getAlignViewport();
500 AlignmentI alignment = ap.getAlignment();
501 int repIndex = n % alignment.getHeight();
502 SequenceI rep = alignment.getSequenceAt(repIndex);
503 refseqs.put(ap.getViewName(), rep);
505 // code from mark/unmark sequence as reference in jalview.gui.PopupMenu
506 // todo refactor this to an alignment view controller
507 av.setDisplayReferenceSeq(true);
508 av.setColourByReferenceSeq(true);
509 av.getAlignment().setSeqrep(rep);
513 File tfile = File.createTempFile("testStoreAndRecoverReferenceSeq",
517 new Jalview2XML(false).saveState(tfile);
518 } catch (Throwable e)
520 Assert.fail("Didn't save the expanded view state", e);
522 Desktop.instance.closeAll_actionPerformed(null);
523 if (Desktop.getAlignFrames() != null)
525 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
528 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
529 DataSourceType.FILE);
530 afid = af.getViewport().getSequenceSetId();
532 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
534 // check representative
535 AlignmentI alignment = ap.getAlignment();
536 SequenceI rep = alignment.getSeqrep();
537 Assert.assertNotNull(rep,
538 "Couldn't restore sequence representative from project");
539 // can't use a strong equals here, because by definition, the sequence IDs
540 // will be different.
541 // could set vamsas session save/restore flag to preserve IDs across
543 Assert.assertEquals(refseqs.get(ap.getViewName()).toString(),
545 "Representative wasn't the same when recovered.");
546 Assert.assertTrue(ap.getAlignViewport().isDisplayReferenceSeq(),
547 "Display reference sequence view setting not set.");
548 Assert.assertTrue(ap.getAlignViewport().isColourByReferenceSeq(),
549 "Colour By Reference Seq view setting not set.");
553 @Test(groups = { "Functional" })
554 public void testIsVersionStringLaterThan()
557 * No version / development / test / autobuild is leniently assumed to be
560 assertTrue(Jalview2XML.isVersionStringLaterThan(null, null));
561 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", null));
562 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "2.8.3"));
563 assertTrue(Jalview2XML.isVersionStringLaterThan(null,
564 "Development Build"));
565 assertTrue(Jalview2XML.isVersionStringLaterThan(null,
566 "DEVELOPMENT BUILD"));
567 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
568 "Development Build"));
569 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "Test"));
570 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "TEST"));
571 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "Test"));
573 Jalview2XML.isVersionStringLaterThan(null, "Automated Build"));
574 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
576 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
580 * same version returns true i.e. compatible
582 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8", "2.8"));
583 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.3"));
584 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3b1"));
585 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3B1", "2.8.3b1"));
586 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3B1"));
589 * later version returns true
591 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.4"));
592 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.9"));
593 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.9.2"));
594 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8", "2.8.3"));
595 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.3b1"));
598 * earlier version returns false
600 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8"));
601 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.4", "2.8.3"));
602 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3"));
603 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.2b1"));
604 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.0b2", "2.8.0b1"));
606 * test for patch release versions
608 assertFalse(Jalview2XML.isVersionStringLaterThan("2.11.3.0", "2.11.2"));
609 assertTrue(Jalview2XML.isVersionStringLaterThan("2.11.3.0", "2.11.4"));
611 Jalview2XML.isVersionStringLaterThan("2.12.2.0b1", "2.12.2.0"));
613 Jalview2XML.isVersionStringLaterThan("2.12.2.3", "2.12.2.2"));
618 * Test save and reload of a project with a different sequence group (and
619 * representative sequence) in each view.
623 @Test(groups = { "Functional" })
624 public void testStoreAndRecoverGroupRepSeqs() throws Exception
626 Desktop.instance.closeAll_actionPerformed(null);
627 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
628 "examples/uniref50.fa", DataSourceType.FILE);
629 assertNotNull(af, "Didn't read in the example file correctly.");
630 String afid = af.getViewport().getSequenceSetId();
631 // make a second view of the alignment
632 af.newView_actionPerformed(null);
635 * remember representative and hidden sequences marked
638 Map<String, SequenceI> repSeqs = new HashMap<>();
639 Map<String, List<String>> hiddenSeqNames = new HashMap<>();
642 * mark sequence 2, 3, 4.. in panels 1, 2, 3...
643 * as reference sequence for itself and the preceding sequence
646 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
648 AlignViewportI av = ap.getAlignViewport();
649 AlignmentI alignment = ap.getAlignment();
650 int repIndex = n % alignment.getHeight();
651 // ensure at least one preceding sequence i.e. index >= 1
652 repIndex = Math.max(repIndex, 1);
653 SequenceI repSeq = alignment.getSequenceAt(repIndex);
654 repSeqs.put(ap.getViewName(), repSeq);
655 List<String> hiddenNames = new ArrayList<>();
656 hiddenSeqNames.put(ap.getViewName(), hiddenNames);
659 * have rep sequence represent itself and the one before it
660 * this hides the group (except for the rep seq)
662 SequenceGroup sg = new SequenceGroup();
663 sg.addSequence(repSeq, false);
664 SequenceI precedingSeq = alignment.getSequenceAt(repIndex - 1);
665 sg.addSequence(precedingSeq, false);
666 sg.setSeqrep(repSeq);
667 assertTrue(sg.getSequences().contains(repSeq));
668 assertTrue(sg.getSequences().contains(precedingSeq));
669 av.setSelectionGroup(sg);
670 assertSame(repSeq, sg.getSeqrep());
673 * represent group with sequence adds to a map of hidden rep sequences
674 * (it does not create a group on the alignment)
676 ((AlignmentViewport) av).hideSequences(repSeq, true);
677 assertSame(repSeq, sg.getSeqrep());
678 assertTrue(sg.getSequences().contains(repSeq));
679 assertTrue(sg.getSequences().contains(precedingSeq));
680 assertTrue(alignment.getGroups().isEmpty(), "alignment has groups");
681 Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av
682 .getHiddenRepSequences();
683 assertNotNull(hiddenRepSeqsMap);
684 assertEquals(1, hiddenRepSeqsMap.size());
685 assertSame(sg, hiddenRepSeqsMap.get(repSeq));
686 assertTrue(alignment.getHiddenSequences().isHidden(precedingSeq));
687 assertFalse(alignment.getHiddenSequences().isHidden(repSeq));
688 hiddenNames.add(precedingSeq.getName());
692 File tfile = File.createTempFile("testStoreAndRecoverGroupReps",
696 new Jalview2XML(false).saveState(tfile);
697 } catch (Throwable e)
699 Assert.fail("Didn't save the expanded view state", e);
701 Desktop.instance.closeAll_actionPerformed(null);
702 if (Desktop.getAlignFrames() != null)
704 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
707 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
708 DataSourceType.FILE);
709 afid = af.getViewport().getSequenceSetId();
711 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
713 String viewName = ap.getViewName();
714 AlignViewportI av = ap.getAlignViewport();
715 AlignmentI alignment = ap.getAlignment();
716 List<SequenceGroup> groups = alignment.getGroups();
717 assertNotNull(groups);
718 assertTrue(groups.isEmpty(), "Alignment has groups");
719 Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av
720 .getHiddenRepSequences();
721 assertNotNull(hiddenRepSeqsMap, "No hidden represented sequences");
722 assertEquals(1, hiddenRepSeqsMap.size());
723 assertEquals(repSeqs.get(viewName).getDisplayId(true),
724 hiddenRepSeqsMap.keySet().iterator().next()
725 .getDisplayId(true));
728 * verify hidden sequences in restored panel
730 List<String> hidden = hiddenSeqNames.get(ap.getViewName());
731 HiddenSequences hs = alignment.getHiddenSequences();
732 assertEquals(hidden.size(), hs.getSize(),
733 "wrong number of restored hidden sequences in "
739 * Test save and reload of PDBEntry in Jalview project
743 @Test(groups = { "Functional" })
744 public void testStoreAndRecoverPDBEntry() throws Exception
746 Desktop.instance.closeAll_actionPerformed(null);
747 String exampleFile = "examples/3W5V.pdb";
748 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
749 DataSourceType.FILE);
750 assertNotNull(af, "Didn't read in the example file correctly.");
751 String afid = af.getViewport().getSequenceSetId();
753 AlignmentPanel[] alignPanels = Desktop.getAlignmentPanels(afid);
754 System.out.println();
755 AlignmentViewPanel ap = alignPanels[0];
756 String tfileBase = new File(".").getAbsolutePath().replace(".", "");
757 String testFile = tfileBase + exampleFile;
758 AlignmentI alignment = ap.getAlignment();
759 System.out.println("blah");
760 SequenceI[] seqs = alignment.getSequencesArray();
761 Assert.assertNotNull(seqs[0]);
762 Assert.assertNotNull(seqs[1]);
763 Assert.assertNotNull(seqs[2]);
764 Assert.assertNotNull(seqs[3]);
765 Assert.assertNotNull(seqs[0].getDatasetSequence());
766 Assert.assertNotNull(seqs[1].getDatasetSequence());
767 Assert.assertNotNull(seqs[2].getDatasetSequence());
768 Assert.assertNotNull(seqs[3].getDatasetSequence());
769 PDBEntry[] pdbEntries = new PDBEntry[4];
770 pdbEntries[0] = new PDBEntry("3W5V", "A", Type.PDB, testFile);
771 pdbEntries[1] = new PDBEntry("3W5V", "B", Type.PDB, testFile);
772 pdbEntries[2] = new PDBEntry("3W5V", "C", Type.PDB, testFile);
773 pdbEntries[3] = new PDBEntry("3W5V", "D", Type.PDB, testFile);
775 seqs[0].getDatasetSequence().getAllPDBEntries().get(0),
778 seqs[1].getDatasetSequence().getAllPDBEntries().get(0),
781 seqs[2].getDatasetSequence().getAllPDBEntries().get(0),
784 seqs[3].getDatasetSequence().getAllPDBEntries().get(0),
787 File tfile = File.createTempFile("testStoreAndRecoverPDBEntry", ".jvp");
790 new Jalview2XML(false).saveState(tfile);
791 } catch (Throwable e)
793 Assert.fail("Didn't save the state", e);
795 Desktop.instance.closeAll_actionPerformed(null);
796 if (Desktop.getAlignFrames() != null)
798 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
801 AlignFrame restoredFrame = new FileLoader().LoadFileWaitTillLoaded(
802 tfile.getAbsolutePath(), DataSourceType.FILE);
803 String rfid = restoredFrame.getViewport().getSequenceSetId();
804 AlignmentPanel[] rAlignPanels = Desktop.getAlignmentPanels(rfid);
805 AlignmentViewPanel rap = rAlignPanels[0];
806 AlignmentI rAlignment = rap.getAlignment();
807 System.out.println("blah");
808 SequenceI[] rseqs = rAlignment.getSequencesArray();
809 Assert.assertNotNull(rseqs[0]);
810 Assert.assertNotNull(rseqs[1]);
811 Assert.assertNotNull(rseqs[2]);
812 Assert.assertNotNull(rseqs[3]);
813 Assert.assertNotNull(rseqs[0].getDatasetSequence());
814 Assert.assertNotNull(rseqs[1].getDatasetSequence());
815 Assert.assertNotNull(rseqs[2].getDatasetSequence());
816 Assert.assertNotNull(rseqs[3].getDatasetSequence());
818 // The Asserts below are expected to fail until the PDB chainCode is
819 // recoverable from a Jalview projects
820 for (int chain = 0; chain < 4; chain++)
822 PDBEntry recov = rseqs[chain].getDatasetSequence().getAllPDBEntries()
824 PDBEntry expected = pdbEntries[chain];
825 Assert.assertEquals(recov.getId(), expected.getId(),
827 Assert.assertEquals(recov.getChainCode(), expected.getChainCode(),
829 Assert.assertEquals(recov.getType(), expected.getType(),
830 "Mismatch PDBEntry 'Type'");
831 Assert.assertNotNull(recov.getFile(),
832 "Recovered PDBEntry should have a non-null file entry");
834 recov.getFile().toLowerCase(Locale.ENGLISH)
836 recov.getFile().length() - 3,
837 "Recovered PDBEntry file should have PDB suffix");
842 * Configure an alignment and a sub-group each with distinct colour schemes,
843 * Conservation and PID thresholds, and confirm these are restored from the
846 * @throws IOException
848 @Test(groups = { "Functional" })
849 public void testStoreAndRecoverAnnotationRowElementColours()
852 Desktop.instance.closeAll_actionPerformed(null);
853 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded("SEQ\tMNQ",
854 DataSourceType.PASTE);
856 AlignViewport av = af.getViewport();
857 AlignmentI al = av.getAlignment();
859 fsq = al.getSequenceAt(0);
860 Annotation annots[] = new Annotation[fsq.getLength()];
861 AlignmentAnnotation ala = new AlignmentAnnotation("Colour", "Annots",
863 annots[0] = new Annotation(1.0f);
864 annots[1] = new Annotation(2.0f);
865 annots[2] = new Annotation(3.0f);
866 annots[0].colour = Color.RED;
867 annots[1].colour = Color.GREEN;
868 annots[2].colour = Color.BLUE;
869 ala.validateRangeAndDisplay();
870 al.getSequenceAt(0).addAlignmentAnnotation(ala);
871 al.addAnnotation(ala);
873 * and colour by annotation
875 AnnotationColourGradient acg = new AnnotationColourGradient(ala,
876 af.alignPanel.av.getGlobalColourScheme(), 0);
877 acg.setSeqAssociated(true);
878 acg.setPredefinedColours(true);
879 af.changeColour(acg);
880 Color seqcol[] = new Color[3];
881 for (int iStart = fsq.findIndex(fsq.getStart()), i = 0; i < 3; i++)
883 seqcol[i] = af.alignPanel.getSeqPanel().seqCanvas
884 .getSequenceRenderer()
885 .getResidueColour(fsq, iStart + i, null);
888 * save project, close windows, reload project, verify
890 File tfile = File.createTempFile(
891 "testStoreAndRecoverAnnotRowElemColors", ".jvp");
892 tfile.deleteOnExit();
893 new Jalview2XML(false).saveState(tfile);
894 // Desktop.instance.closeAll_actionPerformed(null);
895 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
896 DataSourceType.FILE);
897 Assert.assertNotNull(af, "Failed to reload project");
899 * verify alignment annotation has colors
901 av = af.getViewport();
903 ColourSchemeI loadedCscheme = av.getGlobalColourScheme();
904 Assert.assertTrue(loadedCscheme instanceof AnnotationColourGradient,
905 "Didn't apply Annotation colour gradient");
906 acg = (AnnotationColourGradient) loadedCscheme;
907 assertTrue(acg.isSeqAssociated());
908 assertTrue(acg.isPredefinedColours());
910 al = av.getAlignment();
911 fsq = al.getSequenceAt(0);
912 ala = fsq.getAnnotation()[0];
913 Assert.assertNotNull(ala, "No annotation row recovered");
914 Assert.assertNotNull(ala.annotations);
915 for (int iStart = al.getSequenceAt(0)
916 .findIndex(al.getSequenceAt(0).getStart()), i = 0; i < 3; i++)
918 Assert.assertTrue(ala.annotations[i].colour != null);
919 Assert.assertTrue(ala.annotations[i].colour.equals(annots[i].colour));
920 Color newseqcol = af.alignPanel.getSeqPanel().seqCanvas
921 .getSequenceRenderer()
922 .getResidueColour(fsq, iStart + i, null);
923 Assert.assertTrue(seqcol[i].equals(newseqcol),
924 "Sequence shading is different");
931 * Configure an alignment and a sub-group each with distinct colour schemes,
932 * Conservation and PID thresholds, and confirm these are restored from the
935 * @throws IOException
937 @Test(groups = { "Functional" })
938 public void testStoreAndRecoverColourThresholds() throws IOException
940 Desktop.instance.closeAll_actionPerformed(null);
941 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
942 "examples/uniref50.fa", DataSourceType.FILE);
944 AlignViewport av = af.getViewport();
945 AlignmentI al = av.getAlignment();
948 * Colour alignment by Buried Index, Above 10% PID, By Conservation 20%
950 av.setColourAppliesToAllGroups(false);
951 af.changeColour_actionPerformed(JalviewColourScheme.Buried.toString());
952 assertTrue(av.getGlobalColourScheme() instanceof BuriedColourScheme);
953 af.abovePIDThreshold_actionPerformed(true);
954 SliderPanel sp = SliderPanel.getSliderPanel();
955 assertFalse(sp.isForConservation());
957 af.conservationMenuItem_actionPerformed(true);
958 sp = SliderPanel.getSliderPanel();
959 assertTrue(sp.isForConservation());
961 ResidueShaderI rs = av.getResidueShading();
962 assertEquals(rs.getThreshold(), 10);
963 assertTrue(rs.conservationApplied());
964 assertEquals(rs.getConservationInc(), 20);
967 * create a group with Strand colouring, 30% Conservation
968 * and 40% PID threshold
969 * (notice menu action applies to selection group even if mouse click
970 * is at a sequence not in the group)
972 SequenceGroup sg = new SequenceGroup();
973 sg.addSequence(al.getSequenceAt(0), false);
976 av.setSelectionGroup(sg);
977 PopupMenu popupMenu = new PopupMenu(af.alignPanel, al.getSequenceAt(2),
979 popupMenu.changeColour_actionPerformed(
980 JalviewColourScheme.Strand.toString());
981 assertTrue(sg.getColourScheme() instanceof StrandColourScheme);
982 assertEquals(al.getGroups().size(), 1);
983 assertSame(al.getGroups().get(0), sg);
984 popupMenu.conservationMenuItem_actionPerformed(true);
985 sp = SliderPanel.getSliderPanel();
986 assertTrue(sp.isForConservation());
988 popupMenu.abovePIDColour_actionPerformed(true);
989 sp = SliderPanel.getSliderPanel();
990 assertFalse(sp.isForConservation());
992 assertTrue(sg.getGroupColourScheme().conservationApplied());
993 assertEquals(sg.getGroupColourScheme().getConservationInc(), 30);
994 assertEquals(sg.getGroupColourScheme().getThreshold(), 40);
997 * save project, close windows, reload project, verify
999 File tfile = File.createTempFile("testStoreAndRecoverColourThresholds",
1001 tfile.deleteOnExit();
1002 new Jalview2XML(false).saveState(tfile);
1003 Desktop.instance.closeAll_actionPerformed(null);
1004 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
1005 DataSourceType.FILE);
1006 Assert.assertNotNull(af, "Failed to reload project");
1009 * verify alignment (background) colouring
1011 rs = af.getViewport().getResidueShading();
1012 assertTrue(rs.getColourScheme() instanceof BuriedColourScheme);
1013 assertEquals(rs.getThreshold(), 10);
1014 assertTrue(rs.conservationApplied());
1015 assertEquals(rs.getConservationInc(), 20);
1018 * verify group colouring
1020 assertEquals(1, af.getViewport().getAlignment().getGroups().size(), 1);
1021 rs = af.getViewport().getAlignment().getGroups().get(0)
1022 .getGroupColourScheme();
1023 assertTrue(rs.getColourScheme() instanceof StrandColourScheme);
1024 assertEquals(rs.getThreshold(), 40);
1025 assertTrue(rs.conservationApplied());
1026 assertEquals(rs.getConservationInc(), 30);
1030 * Test save and reload of feature colour schemes and filter settings
1032 * @throws IOException
1034 @Test(groups = { "Functional" })
1035 public void testSaveLoadFeatureColoursAndFilters() throws IOException
1037 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1038 ">Seq1\nACDEFGHIKLM", DataSourceType.PASTE);
1039 SequenceI seq1 = af.getViewport().getAlignment().getSequenceAt(0);
1042 * add some features to the sequence
1045 addFeatures(seq1, "type1", score++);
1046 addFeatures(seq1, "type2", score++);
1047 addFeatures(seq1, "type3", score++);
1048 addFeatures(seq1, "type4", score++);
1049 addFeatures(seq1, "type5", score++);
1052 * set colour schemes for features
1054 FeatureRendererModel fr = af.getFeatureRenderer();
1055 fr.findAllFeatures(true);
1058 fr.setColour("type1", new FeatureColour(Color.red));
1061 FeatureColourI byLabel = new FeatureColour();
1062 byLabel.setColourByLabel(true);
1063 fr.setColour("type2", byLabel);
1065 // type3: by score above threshold
1066 FeatureColourI byScore = new FeatureColour(null, Color.BLACK,
1067 Color.BLUE, null, 1, 10);
1068 byScore.setAboveThreshold(true);
1069 byScore.setThreshold(2f);
1070 fr.setColour("type3", byScore);
1072 // type4: by attribute AF
1073 FeatureColourI byAF = new FeatureColour();
1074 byAF.setColourByLabel(true);
1075 byAF.setAttributeName("AF");
1076 fr.setColour("type4", byAF);
1078 // type5: by attribute CSQ:PolyPhen below threshold
1079 FeatureColourI byPolyPhen = new FeatureColour(null, Color.BLACK,
1080 Color.BLUE, null, 1, 10);
1081 byPolyPhen.setBelowThreshold(true);
1082 byPolyPhen.setThreshold(3f);
1083 byPolyPhen.setAttributeName("CSQ", "PolyPhen");
1084 fr.setColour("type5", byPolyPhen);
1087 * set filters for feature types
1090 // filter type1 features by (label contains "x")
1091 FeatureMatcherSetI filterByX = new FeatureMatcherSet();
1092 filterByX.and(FeatureMatcher.byLabel(Condition.Contains, "x"));
1093 fr.setFeatureFilter("type1", filterByX);
1095 // filter type2 features by (score <= 2.4 and score > 1.1)
1096 FeatureMatcherSetI filterByScore = new FeatureMatcherSet();
1097 filterByScore.and(FeatureMatcher.byScore(Condition.LE, "2.4"));
1098 filterByScore.and(FeatureMatcher.byScore(Condition.GT, "1.1"));
1099 fr.setFeatureFilter("type2", filterByScore);
1101 // filter type3 features by (AF contains X OR CSQ:PolyPhen != 0)
1102 FeatureMatcherSetI filterByXY = new FeatureMatcherSet();
1104 .and(FeatureMatcher.byAttribute(Condition.Contains, "X", "AF"));
1105 filterByXY.or(FeatureMatcher.byAttribute(Condition.NE, "0", "CSQ",
1107 fr.setFeatureFilter("type3", filterByXY);
1110 * save as Jalview project
1112 File tfile = File.createTempFile("JalviewTest", ".jvp");
1113 tfile.deleteOnExit();
1114 String filePath = tfile.getAbsolutePath();
1115 af.saveAlignment(filePath, FileFormat.Jalview);
1116 assertTrue(af.isSaveAlignmentSuccessful(),
1117 "Failed to store as a project.");
1120 * close current alignment and load the saved project
1122 af.closeMenuItem_actionPerformed(true);
1124 af = new FileLoader().LoadFileWaitTillLoaded(filePath,
1125 DataSourceType.FILE);
1126 assertNotNull(af, "Failed to import new project");
1129 * verify restored feature colour schemes and filters
1131 fr = af.getFeatureRenderer();
1132 FeatureColourI fc = fr.getFeatureStyle("type1");
1133 assertTrue(fc.isSimpleColour());
1134 assertEquals(fc.getColour(), Color.red);
1135 fc = fr.getFeatureStyle("type2");
1136 assertTrue(fc.isColourByLabel());
1137 fc = fr.getFeatureStyle("type3");
1138 assertTrue(fc.isGraduatedColour());
1139 assertNull(fc.getAttributeName());
1140 assertTrue(fc.isAboveThreshold());
1141 assertEquals(fc.getThreshold(), 2f);
1142 fc = fr.getFeatureStyle("type4");
1143 assertTrue(fc.isColourByLabel());
1144 assertTrue(fc.isColourByAttribute());
1145 assertEquals(fc.getAttributeName(), new String[] { "AF" });
1146 fc = fr.getFeatureStyle("type5");
1147 assertTrue(fc.isGraduatedColour());
1148 assertTrue(fc.isColourByAttribute());
1149 assertEquals(fc.getAttributeName(), new String[] { "CSQ", "PolyPhen" });
1150 assertTrue(fc.isBelowThreshold());
1151 assertEquals(fc.getThreshold(), 3f);
1153 assertEquals(fr.getFeatureFilter("type1").toStableString(),
1154 "Label Contains x");
1155 assertEquals(fr.getFeatureFilter("type2").toStableString(),
1156 "(Score LE 2.4) AND (Score GT 1.1)");
1157 assertEquals(fr.getFeatureFilter("type3").toStableString(),
1158 "(AF Contains X) OR (CSQ:PolyPhen NE 0)");
1161 private void addFeature(SequenceI seq, String featureType, int score)
1163 SequenceFeature sf = new SequenceFeature(featureType, "desc", 1, 2,
1165 sf.setValue("AF", score);
1166 sf.setValue("CSQ", new HashMap<String, String>()
1169 put("PolyPhen", Integer.toString(score));
1172 seq.addSequenceFeature(sf);
1176 * Adds two features of the given type to the given sequence, also setting the
1177 * score as the value of attribute "AF" and sub-attribute "CSQ:PolyPhen"
1180 * @param featureType
1183 private void addFeatures(SequenceI seq, String featureType, int score)
1185 addFeature(seq, featureType, score++);
1186 addFeature(seq, featureType, score);
1190 * pre 2.11 - jalview 2.10 erroneously created new dataset entries for each
1191 * view (JAL-3171) this test ensures we can import and merge those views
1193 @Test(groups = { "Functional" })
1194 public void testMergeDatasetsforViews() throws IOException
1196 // simple project - two views on one alignment
1197 AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
1198 "examples/testdata/projects/twoViews.jvp", DataSourceType.FILE);
1200 assertTrue(af.getAlignPanels().size() > 1);
1205 * pre 2.11 - jalview 2.10 erroneously created new dataset entries for each
1206 * view (JAL-3171) this test ensures we can import and merge those views This
1207 * is a more complex project
1209 @Test(groups = { "Functional" })
1210 public void testMergeDatasetsforManyViews() throws IOException
1212 Desktop.instance.closeAll_actionPerformed(null);
1214 // complex project - one dataset, several views on several alignments
1215 AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
1216 "examples/testdata/projects/manyViews.jvp",
1217 DataSourceType.FILE);
1220 AlignmentI ds = null;
1221 for (AlignFrame alignFrame : Desktop.getAlignFrames())
1225 ds = verifyDs(alignFrame);
1229 // check that this frame's dataset matches the last
1230 assertTrue(ds == verifyDs(alignFrame));
1235 private AlignmentI verifyDs(AlignFrame af)
1237 AlignmentI ds = null;
1238 for (AlignmentViewPanel ap : af.getAlignPanels())
1242 ds = ap.getAlignment().getDataset();
1246 assertTrue(ap.getAlignment().getDataset() == ds,
1247 "Dataset was not the same for imported 2.10.5 project with several alignment views");
1253 @Test(groups = "Functional")
1254 public void testPcaViewAssociation() throws IOException
1256 Desktop.instance.closeAll_actionPerformed(null);
1257 final String PCAVIEWNAME = "With PCA";
1258 // create a new tempfile
1259 File tempfile = File.createTempFile("jvPCAviewAssoc", "jvp");
1262 String exampleFile = "examples/uniref50.fa";
1263 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
1264 DataSourceType.FILE);
1265 assertNotNull(af, "Didn't read in the example file correctly.");
1266 AlignmentPanel origView = (AlignmentPanel) af.getAlignPanels().get(0);
1267 AlignmentPanel newview = af.newView(PCAVIEWNAME, true);
1268 // create another for good measure
1269 af.newView("Not the PCA View", true);
1270 PCAPanel pcaPanel = new PCAPanel(origView, "BLOSUM62",
1271 new SimilarityParams(true, true, true, false));
1272 // we're in the test exec thread, so we can just run synchronously here
1275 // now switch the linked view
1276 pcaPanel.selectAssociatedView(newview);
1278 assertTrue(pcaPanel.getAlignViewport() == newview.getAlignViewport(),
1279 "PCA should be associated with 'With PCA' view: test is broken");
1281 // now save and reload project
1282 Jalview2XML jv2xml = new jalview.project.Jalview2XML(false);
1284 jv2xml.saveState(tempfile);
1285 assertTrue(jv2xml.errorMessage == null,
1286 "Failed to save dummy project with PCA: test broken");
1290 Desktop.instance.closeAll_actionPerformed(null);
1291 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1292 tempfile.getCanonicalPath(), DataSourceType.FILE);
1293 JInternalFrame[] frames = Desktop.instance.getAllFrames();
1294 // PCA and the tabbed alignment view should be the only two windows on the
1296 assertEquals(frames.length, 2,
1297 "PCA and the tabbed alignment view should be the only two windows on the desktop");
1298 PCAPanel pcaPanel = (PCAPanel) frames[frames[0] == af ? 1 : 0];
1300 AlignmentViewPanel restoredNewView = null;
1301 for (AlignmentViewPanel alignpanel : Desktop.getAlignmentPanels(null))
1303 if (alignpanel.getAlignViewport() == pcaPanel.getAlignViewport())
1305 restoredNewView = alignpanel;
1308 assertEquals(restoredNewView.getViewName(), PCAVIEWNAME);
1310 restoredNewView.getAlignViewport() == pcaPanel
1311 .getAlignViewport(),
1312 "Didn't restore correct view association for the PCA view");
1316 * Test save and reload of DBRefEntry including GeneLocus in project
1320 @Test(groups = { "Functional" })
1321 public void testStoreAndRecoverGeneLocus() throws Exception
1323 Desktop.instance.closeAll_actionPerformed(null);
1324 String seqData = ">P30419\nACDE\n>X1235\nGCCTGTGACGAA";
1325 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(seqData,
1326 DataSourceType.PASTE);
1327 assertNotNull(af, "Didn't read in the example file correctly.");
1329 AlignmentViewPanel ap = Desktop.getAlignmentPanels(null)[0];
1330 SequenceI pep = ap.getAlignment().getSequenceAt(0);
1331 SequenceI cds = ap.getAlignment().getSequenceAt(1);
1334 * give 'protein' a dbref to self, a dbref with map to CDS,
1335 * and a dbref with map to gene 'locus'
1337 DBRefEntry dbref1 = new DBRefEntry("Uniprot", "1", "P30419", null);
1338 pep.addDBRef(dbref1);
1339 Mapping cdsmap = new Mapping(cds,
1340 new MapList(new int[]
1341 { 1, 4 }, new int[] { 1, 12 }, 1, 3));
1342 DBRefEntry dbref2 = new DBRefEntry("EMBLCDS", "2", "X1235", cdsmap);
1343 pep.addDBRef(dbref2);
1344 Mapping locusmap = new Mapping(null,
1345 new MapList(new int[]
1346 { 1, 4 }, new int[] { 2674123, 2674135 }, 1, 3));
1347 DBRefEntry dbref3 = new GeneLocus("human", "GRCh38", "5", locusmap);
1348 pep.addDBRef(dbref3);
1350 File tfile = File.createTempFile("testStoreAndRecoverGeneLocus",
1354 new Jalview2XML(false).saveState(tfile);
1355 } catch (Throwable e)
1357 Assert.fail("Didn't save the state", e);
1359 Desktop.instance.closeAll_actionPerformed(null);
1361 new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
1362 DataSourceType.FILE);
1363 AlignmentViewPanel rap = Desktop.getAlignmentPanels(null)[0];
1364 SequenceI rpep = rap.getAlignment().getSequenceAt(0);
1365 DBModList<DBRefEntry> dbrefs = rpep.getDBRefs();
1366 assertEquals(rpep.getName(), "P30419");
1367 assertEquals(dbrefs.size(), 3);
1368 DBRefEntry dbRef = dbrefs.get(0);
1369 assertFalse(dbRef instanceof GeneLocus);
1370 assertNull(dbRef.getMap());
1371 assertEquals(dbRef, dbref1);
1374 * restored dbrefs with mapping have a different 'map to'
1375 * sequence but otherwise match the original dbrefs
1377 dbRef = dbrefs.get(1);
1378 assertFalse(dbRef instanceof GeneLocus);
1379 assertTrue(dbRef.equalRef(dbref2));
1380 assertNotNull(dbRef.getMap());
1381 SequenceI rcds = rap.getAlignment().getSequenceAt(1);
1382 assertSame(dbRef.getMap().getTo(), rcds);
1383 // compare MapList but not map.to
1384 assertEquals(dbRef.getMap().getMap(), dbref2.getMap().getMap());
1387 * GeneLocus map.to is null so can compare Mapping objects
1389 dbRef = dbrefs.get(2);
1390 assertTrue(dbRef instanceof GeneLocus);
1391 assertEquals(dbRef, dbref3);
1395 * test store and recovery of Overview windows
1399 @Test(groups = { "Functional" }, enabled = true)
1400 public void testStoreAndRecoverOverview() throws Exception
1402 Desktop.instance.closeAll_actionPerformed(null);
1404 Cache.setProperty("SHOW_OVERVIEW", "false");
1405 Cache.setProperty(Preferences.USE_LEGACY_GAP, "false");
1406 Cache.setColourProperty(Preferences.GAP_COLOUR, Color.green);
1407 Cache.setColourProperty(Preferences.HIDDEN_COLOUR, Color.yellow);
1408 Cache.setProperty(Preferences.SHOW_OV_HIDDEN_AT_START, "true");
1410 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1411 "examples/uniref50.fa", DataSourceType.FILE);
1414 * open and resize / reposition overview
1416 af.overviewMenuItem_actionPerformed(null);
1417 OverviewPanel ov1 = af.alignPanel.getOverviewPanel();
1419 ov1.setFrameBounds(20, 30, 200, 400);
1420 assertEquals(ov1.getTitle(), "Overview examples/uniref50.fa");
1421 assertTrue(ov1.isShowHiddenRegions());
1424 * open a New View and its Overview and reposition it
1426 af.newView_actionPerformed(null);
1427 af.overviewMenuItem_actionPerformed(null);
1428 OverviewPanel ov2 = af.alignPanel.getOverviewPanel();
1430 assertNotSame(ov1, ov2);
1431 ov2.setFrameBounds(25, 35, 205, 405);
1432 assertEquals(ov1.getTitle(), "Overview examples/uniref50.fa Original");
1433 assertEquals(ov2.getTitle(), "Overview examples/uniref50.fa View 1");
1435 File tfile = File.createTempFile("testStoreAndRecoverOverview", ".jvp");
1436 new Jalview2XML(false).saveState(tfile);
1437 Desktop.instance.closeAll_actionPerformed(null);
1440 * change preferences (should _not_ affect reloaded Overviews)
1442 Cache.setProperty("SHOW_OVERVIEW", "true");
1443 Cache.setProperty(Preferences.USE_LEGACY_GAP, "true");
1444 Cache.setColourProperty(Preferences.GAP_COLOUR, Color.blue);
1445 Cache.setColourProperty(Preferences.HIDDEN_COLOUR, Color.orange);
1446 Cache.setProperty(Preferences.SHOW_OV_HIDDEN_AT_START, "false");
1448 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
1449 DataSourceType.FILE);
1452 * workaround: explicitly select View 1 (not in focus after restore)
1454 af.tabSelectionChanged(1);
1457 * verify restored overview for View 1
1459 ov2 = af.alignPanel.getOverviewPanel();
1460 assertEquals(ov2.getCanvas().getGapColour(), Color.green);
1461 // 'non-legacy' colouring uses white for non-gapped residues
1462 assertEquals(ov2.getCanvas().getResidueColour(), Color.white);
1463 assertEquals(ov2.getCanvas().getHiddenColour(), Color.yellow);
1464 assertEquals(ov2.getTitle(), "Overview examples/uniref50.fa View 1");
1465 assertEquals(ov2.getFrameBounds(), new Rectangle(25, 35, 205, 405));
1466 assertTrue(ov2.isShowHiddenRegions());
1469 * verify restored overview for Original view
1471 af.tabSelectionChanged(0);
1472 ov1 = af.alignPanel.getOverviewPanel();
1473 assertEquals(ov1.getCanvas().getGapColour(), Color.green);
1474 // 'non-legacy' colouring uses white for non-gapped residues
1475 assertEquals(ov1.getCanvas().getResidueColour(), Color.white);
1476 assertEquals(ov1.getCanvas().getHiddenColour(), Color.yellow);
1477 assertEquals(ov1.getTitle(), "Overview examples/uniref50.fa Original");
1478 assertEquals(ov1.getFrameBounds(), new Rectangle(20, 30, 200, 400));
1479 assertTrue(ov1.isShowHiddenRegions());
1483 * Test that a view with no Overview is restored with no Overview, even if
1484 * 'Open Overview' is selected in Preferences
1488 @Test(groups = { "Functional" }, enabled = true)
1489 public void testStoreAndRecoverNoOverview() throws Exception
1491 Cache.setProperty("SHOW_OVERVIEW", "false");
1492 Desktop.instance.closeAll_actionPerformed(null);
1493 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1494 ">seq1\nMATRSQFLVNF\n", DataSourceType.PASTE);
1496 File tfile = File.createTempFile("testStoreAndRecoverOverview", ".jvp");
1497 new Jalview2XML(false).saveState(tfile);
1498 Desktop.instance.closeAll_actionPerformed(null);
1500 Cache.setProperty("SHOW_OVERVIEW", "true");
1501 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
1502 DataSourceType.FILE);
1504 assertNull(af.alignPanel.getOverviewPanel());
1508 * Test that a view from an older version of Jalview is restored with Overview
1509 * automatically shown when the preference is set
1513 @Test(groups = { "Functional" }, enabled = true)
1514 public void testAutoShowOverviewForLegacyProjects() throws Exception
1516 Desktop.instance.closeAll_actionPerformed(null);
1517 Cache.setProperty("SHOW_OVERVIEW", "true");
1518 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1519 "examples/exampleFile.jvp", DataSourceType.FILE);
1521 Cache.setProperty("SHOW_OVERVIEW", "false");
1522 assertNotNull(af.alignPanel.getOverviewPanel());
1526 * Test that loading example.jvp, doing some stuff, then hitting reload
1527 * doesn't leave the modified window still open
1529 * See JAL-4127 - interactively performing the same actions and reloading
1530 * works fine, but programmatically they do not
1534 @Test(groups = { "Functional" }, enabled = false)
1535 public void testReloadActuallyReloads() throws Exception
1537 Desktop.instance.closeAll_actionPerformed(null);
1538 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1539 "examples/exampleFile.jvp", DataSourceType.FILE);
1540 af.getViewport().getColumnSelection().addElement(3);
1541 af.hideSelColumns_actionPerformed(null);
1542 af.newView("new", true);
1543 af.reload_actionPerformed(null);
1545 // af exists still but isn't shown
1546 assertTrue(af.isClosed());
1549 @Test(groups = { "Functional" })
1550 public void testPAEsaveRestore() throws Exception
1552 Desktop.instance.closeAll_actionPerformed(null);
1553 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1554 ">seq1\nMATRSQFLVNF\n", DataSourceType.PASTE);
1555 AlignmentI al = af.getViewport().getAlignment();
1556 // PAE matrices are added as reference annotation to the dataset sequence
1557 // at least for now.
1558 SequenceI sq = al.getSequenceAt(0).getDatasetSequence();
1559 int i = sq.getLength();
1560 float[][] paevals = new float[i][i];
1561 for (i = i - 1; i >= 0; i--)
1563 for (int j = 0; j <= i; j++)
1565 paevals[i][j] = ((i - j < 2)
1566 || ((i > 1 && i < 5) && (j > 1 && i < 5))) ? 1 : 0f;
1567 paevals[j][i] = -paevals[i][j];
1570 PAEContactMatrix dummyMat = new PAEContactMatrix(sq, paevals);
1571 String content = ContactMatrix.contactToFloatString(dummyMat);
1572 Assert.assertTrue(content.contains("\t1.")); // at least one element must be
1574 float[][] vals = ContactMatrix.fromFloatStringToContacts(content,
1575 sq.getLength(), sq.getLength());
1576 assertEquals(vals[3][4], paevals[3][4]);
1577 assertEquals(vals[4][3], paevals[4][3]);
1578 dummyMat.setGroupSet(GroupSet.makeGroups(dummyMat, false,0.5f, false));
1579 Assert.assertNotSame(dummyMat.getNewick(), "");
1580 AlignmentAnnotation paeCm = sq.addContactList(dummyMat);
1581 al.addAnnotation(paeCm);
1582 // verify store/restore of group bitsets
1583 for (BitSet gp : dummyMat.getGroups())
1585 StringBuilder sb = new StringBuilder();
1586 for (long val : gp.toLongArray())
1588 if (sb.length() > 0)
1594 String[] longvals = sb.toString().split(",");
1595 long[] newlongvals = new long[longvals.length];
1596 for (int lv = 0; lv < longvals.length; lv++)
1600 newlongvals[lv] = Long.valueOf(longvals[lv]);
1601 } catch (Exception x)
1603 Assert.fail("failed to deserialise bitset element ");
1606 BitSet newGp = BitSet.valueOf(newlongvals);
1607 assertTrue(gp.equals(newGp));
1609 File tfile = File.createTempFile("testStoreAndRecoverPAEmatrix",
1611 new Jalview2XML(false).saveState(tfile);
1612 Desktop.instance.closeAll_actionPerformed(null);
1614 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
1615 DataSourceType.FILE);
1616 AlignmentI newAl = af.getViewport().getAlignment();
1617 SequenceI newSeq = newAl.getSequenceAt(0).getDatasetSequence();
1618 // check annotation of the expected type exists
1619 Assert.assertEquals(newSeq.getAnnotation().length, 1);
1620 Assert.assertEquals(newSeq.getAnnotation()[0].graph, paeCm.graph);
1622 // check a contact matrix was recovered
1623 Assert.assertEquals(newSeq.getContactMaps().size(), 1);
1624 // and can be found for the annotation on the sequence
1625 ContactMatrixI restoredMat = newSeq
1626 .getContactMatrixFor(newSeq.getAnnotation()[0]);
1627 Assert.assertNotNull(restoredMat);
1628 MapList oldMap = ((MappableContactMatrixI) dummyMat).getMapFor(sq);
1629 MapList newMap = ((MappableContactMatrixI) restoredMat)
1631 Assert.assertEquals(oldMap.getFromRanges(), newMap.getFromRanges());
1632 Assert.assertEquals(oldMap.getToRanges(), newMap.getToRanges());
1633 Assert.assertEquals(oldMap.getFromRatio(), newMap.getFromRatio());
1634 Assert.assertEquals(oldMap.getToRatio(), newMap.getToRatio());
1635 for (i = sq.getLength() - 1; i >= 0; i--)
1637 ContactListI oldCM = dummyMat.getContactList(i),
1638 newCM = restoredMat.getContactList(i);
1639 for (int j = oldCM.getContactHeight(); j >= 0; j--)
1641 double old_j = oldCM.getContactAt(j);
1642 double new_j = newCM.getContactAt(j);
1643 Assert.assertEquals(old_j, new_j);
1646 Assert.assertEquals(restoredMat.hasGroups(), dummyMat.hasGroups());
1647 Assert.assertEquals(restoredMat.getGroups(), dummyMat.getGroups());
1648 Assert.assertEquals(restoredMat.hasTree(), dummyMat.hasTree());
1649 Assert.assertEquals(restoredMat.getNewick(), dummyMat.getNewick());
1651 // verify no duplicate PAE matrix data when new view created and saved
1653 // add reference annotations to view first, then copy
1654 AlignmentUtils.addReferenceAnnotationTo(newAl, newAl.getSequenceAt(0), newSeq.getAnnotation()[0],null);
1656 AlignmentViewPanel newview = af.newView("copy of PAE", true);
1658 // redundant asserts here check all is good with the new view firest...
1659 AlignmentI newviewAl = newview.getAlignment();
1660 SequenceI newviewSeq = newviewAl.getSequenceAt(0);
1661 // check annotation of the expected type exists
1662 Assert.assertEquals(newviewSeq.getAnnotation().length, 1);
1663 Assert.assertEquals(newviewSeq.getAnnotation()[0].graph, paeCm.graph);
1664 // check we have just one contact matrix mapping
1665 Assert.assertEquals(newviewSeq.getContactMaps().size(), 1);
1667 // and can be found for the annotation on the sequence
1668 ContactMatrixI newviewMat = newviewSeq
1669 .getContactMatrixFor(newviewSeq.getAnnotation()[0]);
1670 Assert.assertNotNull(newviewMat);
1672 Assert.assertTrue(newviewMat == restoredMat);
1674 // save the two views and restore. Now look at visible annotation to check all views have shared refs.
1676 tfile = File.createTempFile("testStoreAndRecoverPAEmatrixTwoViews",
1678 new Jalview2XML(false).saveState(tfile);
1679 Desktop.instance.closeAll_actionPerformed(null);
1681 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
1682 DataSourceType.FILE);
1683 newAl = af.getAlignPanels().get(0).getAlignment();
1684 AlignmentAnnotation view1aa = newAl.getSequenceAt(0).getAnnotation()[0];
1686 newviewAl = af.getAlignPanels().get(1).getAlignment();
1687 AlignmentAnnotation view2aa = newviewAl.getSequenceAt(0).getAnnotation()[0];
1689 // annotations are shared across alignment views - so should still have an identical pair of annotations.
1690 Assert.assertTrue(view1aa==view2aa);
1691 // identical annotations means identical contact matrix mappings
1692 Assert.assertEquals(newAl.getDataset().getSequenceAt(0).getContactMaps().size(), 1);
1694 // TODO Verify when distinct mappable PAEs are created, only one PAE dataset is actually held.
1695 // Assert.assertTrue(view1aa!=view2aa);
1696 // restoredMat = newAl.getContactMatrixFor(view1aa);
1697 // newviewMat = newviewAl.getContactMatrixFor(view2aa);
1698 // Assert.assertTrue(restoredMat!=newviewMat);