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.assertNull;
27 import static org.testng.Assert.assertSame;
28 import static org.testng.Assert.assertTrue;
30 import jalview.analysis.scoremodels.SimilarityParams;
31 import jalview.api.AlignViewportI;
32 import jalview.api.AlignmentViewPanel;
33 import jalview.api.FeatureColourI;
34 import jalview.api.ViewStyleI;
35 import jalview.bin.Jalview;
36 import jalview.datamodel.AlignmentAnnotation;
37 import jalview.datamodel.AlignmentI;
38 import jalview.datamodel.HiddenSequences;
39 import jalview.datamodel.PDBEntry;
40 import jalview.datamodel.PDBEntry.Type;
41 import jalview.datamodel.SequenceCollectionI;
42 import jalview.datamodel.SequenceFeature;
43 import jalview.datamodel.SequenceGroup;
44 import jalview.datamodel.SequenceI;
45 import jalview.datamodel.features.FeatureMatcher;
46 import jalview.datamodel.features.FeatureMatcherSet;
47 import jalview.datamodel.features.FeatureMatcherSetI;
48 import jalview.gui.AlignFrame;
49 import jalview.gui.AlignViewport;
50 import jalview.gui.AlignmentPanel;
51 import jalview.gui.Desktop;
52 import jalview.gui.FeatureRenderer;
53 import jalview.gui.JvOptionPane;
54 import jalview.gui.PCAPanel;
55 import jalview.gui.PopupMenu;
56 import jalview.gui.SliderPanel;
57 import jalview.io.DataSourceType;
58 import jalview.io.FileFormat;
59 import jalview.io.FileLoader;
60 import jalview.io.Jalview2xmlBase;
61 import jalview.renderer.ResidueShaderI;
62 import jalview.schemes.AnnotationColourGradient;
63 import jalview.schemes.BuriedColourScheme;
64 import jalview.schemes.ColourSchemeI;
65 import jalview.schemes.ColourSchemeProperty;
66 import jalview.schemes.FeatureColour;
67 import jalview.schemes.JalviewColourScheme;
68 import jalview.schemes.RNAHelicesColour;
69 import jalview.schemes.StrandColourScheme;
70 import jalview.schemes.TCoffeeColourScheme;
71 import jalview.structure.StructureImportSettings;
72 import jalview.structure.StructureMapping;
73 import jalview.util.matcher.Condition;
74 import jalview.viewmodel.AlignmentViewport;
76 import java.awt.Color;
78 import java.io.IOException;
79 import java.util.ArrayList;
80 import java.util.HashMap;
81 import java.util.List;
84 import javax.swing.JInternalFrame;
86 import org.testng.Assert;
87 import org.testng.AssertJUnit;
88 import org.testng.annotations.BeforeClass;
89 import org.testng.annotations.Test;
91 @Test(singleThreaded = true)
92 public class Jalview2xmlTests extends Jalview2xmlBase
96 @BeforeClass(alwaysRun = true)
97 public void setUpJvOptionPane()
99 JvOptionPane.setInteractiveMode(false);
100 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
101 Jalview.setSynchronous(true);
104 @Test(groups = { "Functional" })
105 public void testRNAStructureRecovery() throws Exception
107 String inFile = "examples/RF00031_folded.stk";
108 String tfile = File.createTempFile("JalviewTest", ".jvp")
110 // Jalview.setSynchronous(true);
111 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
112 DataSourceType.FILE);
113 assertNotNull(af, "Didn't read input file " + inFile);
114 int olddsann = countDsAnn(af.getViewport());
115 assertTrue(olddsann > 0, "Didn't find any dataset annotations");
116 af.changeColour_actionPerformed(
117 JalviewColourScheme.RNAHelices.toString());
120 .getGlobalColourScheme() instanceof RNAHelicesColour,
121 "Couldn't apply RNA helices colourscheme");
122 af.saveAlignment(tfile, FileFormat.Jalview);
123 assertTrue(af.isSaveAlignmentSuccessful(),
124 "Failed to store as a project.");
125 af.closeMenuItem_actionPerformed(true);
126 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
127 DataSourceType.FILE);
128 assertNotNull(af, "Failed to import new project");
129 int newdsann = countDsAnn(af.getViewport());
130 assertEquals(olddsann, newdsann,
131 "Differing numbers of dataset sequence annotation\nOriginally "
132 + olddsann + " and now " + newdsann);
134 "Read in same number of annotations as originally present ("
139 .getGlobalColourScheme() instanceof RNAHelicesColour,
140 "RNA helices colourscheme was not applied on import.");
143 @Test(groups = { "Functional" })
144 public void testTCoffeeScores() throws Exception
146 String inFile = "examples/uniref50.fa",
147 inAnnot = "examples/uniref50.score_ascii";
148 String tfile = File.createTempFile("JalviewTest", ".jvp")
150 // Jalview.setSynchronous(true);
151 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
152 DataSourceType.FILE);
153 assertNotNull(af, "Didn't read input file " + inFile);
154 af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
155 AlignViewport viewport = af.getViewport();
156 assertSame(viewport.getGlobalColourScheme().getClass(),
157 TCoffeeColourScheme.class, "Didn't set T-coffee colourscheme");
159 ColourSchemeProperty.getColourScheme(viewport,
160 viewport.getAlignment(),
161 viewport.getGlobalColourScheme()
163 "Recognise T-Coffee score from string");
165 af.saveAlignment(tfile, FileFormat.Jalview);
166 assertTrue(af.isSaveAlignmentSuccessful(),
167 "Failed to store as a project.");
168 af.closeMenuItem_actionPerformed(true);
169 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
170 DataSourceType.FILE);
171 assertNotNull(af, "Failed to import new project");
172 assertSame(af.getViewport().getGlobalColourScheme().getClass(),
173 TCoffeeColourScheme.class,
174 "Didn't set T-coffee colourscheme for imported project.");
176 "T-Coffee score shading successfully recovered from project.");
179 @Test(groups = { "Functional" })
180 public void testColourByAnnotScores() throws Exception
182 String inFile = "examples/uniref50.fa",
183 inAnnot = "examples/testdata/uniref50_iupred.jva";
184 String tfile = File.createTempFile("JalviewTest", ".jvp")
186 // Jalview.setSynchronous(true);
187 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
188 DataSourceType.FILE);
189 assertNotNull(af, "Didn't read input file " + inFile);
190 af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
191 AlignmentAnnotation[] aa = af.getViewport().getAlignment()
192 .getSequenceAt(0).getAnnotation("IUPredWS (Short)");
195 aa != null && aa.length > 0,
196 "Didn't find any IUPred annotation to use to shade alignment.");
197 AnnotationColourGradient cs = new AnnotationColourGradient(aa[0], null,
198 AnnotationColourGradient.ABOVE_THRESHOLD);
199 AnnotationColourGradient gcs = new AnnotationColourGradient(aa[0], null,
200 AnnotationColourGradient.BELOW_THRESHOLD);
201 cs.setSeqAssociated(true);
202 gcs.setSeqAssociated(true);
204 SequenceGroup sg = new SequenceGroup();
207 sg.cs.setColourScheme(gcs);
208 af.getViewport().getAlignment().addGroup(sg);
209 sg.addSequence(af.getViewport().getAlignment().getSequenceAt(1), false);
210 sg.addSequence(af.getViewport().getAlignment().getSequenceAt(2), true);
211 af.alignPanel.alignmentChanged();
212 af.saveAlignment(tfile, FileFormat.Jalview);
213 assertTrue(af.isSaveAlignmentSuccessful(),
214 "Failed to store as a project.");
215 af.closeMenuItem_actionPerformed(true);
217 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
218 DataSourceType.FILE);
219 assertNotNull(af, "Failed to import new project");
221 // check for group and alignment colourschemes
223 ColourSchemeI _rcs = af.getViewport().getGlobalColourScheme();
224 ColourSchemeI _rgcs = af.getViewport().getAlignment().getGroups().get(0)
226 assertNotNull(_rcs, "Didn't recover global colourscheme");
227 assertTrue(_rcs instanceof AnnotationColourGradient,
228 "Didn't recover annotation colour global scheme");
229 AnnotationColourGradient __rcs = (AnnotationColourGradient) _rcs;
230 assertTrue(__rcs.isSeqAssociated(),
231 "Annotation colourscheme wasn't sequence associated");
233 boolean diffseqcols = false, diffgseqcols = false;
234 SequenceI[] sqs = af.getViewport().getAlignment().getSequencesArray();
235 for (int p = 0, pSize = af.getViewport().getAlignment()
236 .getWidth(); p < pSize && (!diffseqcols || !diffgseqcols); p++)
238 if (_rcs.findColour(sqs[0].getCharAt(p), p, sqs[0], null, 0f) != _rcs
239 .findColour(sqs[5].getCharAt(p), p, sqs[5], null, 0f))
244 assertTrue(diffseqcols, "Got Different sequence colours");
246 "Per sequence colourscheme (Background) successfully applied and recovered.");
248 assertNotNull(_rgcs, "Didn't recover group colourscheme");
249 assertTrue(_rgcs instanceof AnnotationColourGradient,
250 "Didn't recover annotation colour group colourscheme");
251 __rcs = (AnnotationColourGradient) _rgcs;
252 assertTrue(__rcs.isSeqAssociated(),
253 "Group Annotation colourscheme wasn't sequence associated");
255 for (int p = 0, pSize = af.getViewport().getAlignment()
256 .getWidth(); p < pSize && (!diffseqcols || !diffgseqcols); p++)
258 if (_rgcs.findColour(sqs[1].getCharAt(p), p, sqs[1], null,
259 0f) != _rgcs.findColour(sqs[2].getCharAt(p), p, sqs[2], null,
265 assertTrue(diffgseqcols, "Got Different group sequence colours");
267 "Per sequence (Group) colourscheme successfully applied and recovered.");
270 @Test(groups = { "Functional" })
271 public void gatherViewsHere() throws Exception
273 int origCount = Desktop.getAlignFrames() == null ? 0
274 : Desktop.getAlignFrames().length;
275 // Jalview.setSynchronous(true);
276 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
277 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
278 assertNotNull(af, "Didn't read in the example file correctly.");
279 assertTrue(Desktop.getAlignFrames().length == 1 + origCount,
280 "Didn't gather the views in the example file.");
285 * Test for JAL-2223 - multiple mappings in View Mapping report
289 @Test(groups = { "Functional" })
290 public void noDuplicatePdbMappingsMade() throws Exception
292 StructureImportSettings.setProcessSecondaryStructure(true);
293 StructureImportSettings.setVisibleChainAnnotation(true);
294 // Jalview.setSynchronous(true);
295 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
296 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
297 assertNotNull(af, "Didn't read in the example file correctly.");
299 // locate Jmol viewer
300 // count number of PDB mappings the structure selection manager holds -
301 String pdbFile = af.getCurrentView().getStructureSelectionManager()
302 .findFileForPDBId("1A70");
303 StructureMapping[] x = af.getCurrentView()
304 .getStructureSelectionManager()//
305 .getMapping(pdbFile);
306 assertEquals(x.length,
307 2, "Expected only two mappings for 1A70");
311 @Test(groups = { "Functional" })
312 public void viewRefPdbAnnotation() throws Exception
314 StructureImportSettings.setProcessSecondaryStructure(true);
315 StructureImportSettings.setVisibleChainAnnotation(true);
316 // Jalview.setSynchronous(true);
317 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
318 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
319 assertNotNull(af, "Didn't read in the example file correctly.");
320 AlignmentViewPanel sps = null;
321 for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
323 if ("Spinach Feredoxin Structure".equals(ap.getViewName()))
329 assertNotNull(sps, "Couldn't find the structure view");
330 AlignmentAnnotation refan = null;
331 for (AlignmentAnnotation ra : sps.getAlignment()
332 .getAlignmentAnnotation())
340 assertNotNull(refan, "Annotation secondary structure not found.");
341 SequenceI sq = sps.getAlignment().findName("1A70|");
342 assertNotNull(sq, "Couldn't find 1a70 null chain");
343 // compare the manually added temperature factor annotation
344 // to the track automatically transferred from the pdb structure on load
345 assertNotNull(sq.getDatasetSequence().getAnnotation(),
346 "1a70 has no annotation");
347 for (AlignmentAnnotation ala : sq.getDatasetSequence().getAnnotation())
349 AlignmentAnnotation alaa;
350 sq.addAlignmentAnnotation(alaa = new AlignmentAnnotation(ala));
351 alaa.adjustForAlignment();
352 if (ala.graph == refan.graph)
354 for (int p = 0; p < ala.annotations.length; p++)
359 assertTrue((alaa.annotations[p] == null
360 && refan.annotations[p] == null)
361 || alaa.annotations[p].value == refan.annotations[p].value,
362 "Mismatch at alignment position " + p);
363 } catch (NullPointerException q)
365 Assert.fail("Mismatch of alignment annotations at position " + p
366 + " Ref seq ann: " + refan.annotations[p]
367 + " alignment " + alaa.annotations[p]);
375 @Test(groups = { "Functional" })
376 public void testCopyViewSettings() throws Exception
378 // Jalview.setSynchronous(true);
379 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
380 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
381 assertNotNull(af, "Didn't read in the example file correctly.");
382 AlignmentViewPanel sps = null, groups = null;
383 for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
385 if ("Spinach Feredoxin Structure".equals(ap.getViewName()))
389 if (ap.getViewName().contains("MAFFT"))
394 assertNotNull(sps, "Couldn't find the structure view");
395 assertNotNull(groups, "Couldn't find the MAFFT view");
397 ViewStyleI structureStyle = sps.getAlignViewport().getViewStyle();
398 ViewStyleI groupStyle = groups.getAlignViewport().getViewStyle();
399 AssertJUnit.assertFalse(structureStyle.sameStyle(groupStyle));
401 groups.getAlignViewport().setViewStyle(structureStyle);
402 AssertJUnit.assertFalse(
403 groupStyle.sameStyle(groups.getAlignViewport().getViewStyle()));
404 Assert.assertTrue(structureStyle
405 .sameStyle(groups.getAlignViewport().getViewStyle()));
410 * test store and recovery of expanded views
414 @Test(groups = { "Functional" }, enabled = true)
415 public void testStoreAndRecoverExpandedviews() throws Exception
417 Desktop.getInstance().closeAll_actionPerformed(null);
418 // Jalview.setSynchronous(true);
419 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
420 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
421 Assert.assertEquals(Desktop.getAlignFrames().length, 1);
422 String afid = af.getViewport().getSequenceSetId();
424 // check FileLoader returned a reference to the one alignFrame that is
425 // actually on the Desktop
426 assertSame(af, Desktop.getAlignFrameFor(af.getViewport()),
427 "Jalview2XML.loadAlignFrame() didn't return correct AlignFrame reference for multiple view window");
429 Desktop.explodeViews(af);
431 int oldviews = Desktop.getAlignFrames().length;
432 Assert.assertEquals(Desktop.getAlignFrames().length,
433 Desktop.getAlignmentPanels(afid).length);
434 File tfile = File.createTempFile("testStoreAndRecoverExpanded", ".jvp");
437 new Jalview2XML(false).saveState(tfile);
440 Assert.fail("Didn't save the expanded view state", e);
441 } catch (Exception e)
443 Assert.fail("Didn't save the expanded view state", e);
445 Desktop.getInstance().closeAll_actionPerformed(null);
446 if (Desktop.getAlignFrames() != null)
448 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
450 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
451 DataSourceType.FILE);
452 Assert.assertNotNull(af);
453 Assert.assertEquals(Desktop.getAlignFrames().length,
454 Desktop.getAlignmentPanels(
455 af.getViewport().getSequenceSetId()).length);
457 Desktop.getAlignmentPanels(
458 af.getViewport().getSequenceSetId()).length,
463 * Test save and reload of a project with a different representative sequence
468 @Test(groups = { "Functional" })
469 public void testStoreAndRecoverReferenceSeqSettings() throws Exception
471 Desktop.getInstance().closeAll_actionPerformed(null);
472 // Jalview.setSynchronous(true);
473 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
474 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
475 assertNotNull(af, "Didn't read in the example file correctly.");
476 String afid = af.getViewport().getSequenceSetId();
478 // remember reference sequence for each panel
479 Map<String, SequenceI> refseqs = new HashMap<>();
482 * mark sequence 2, 3, 4.. in panels 1, 2, 3...
483 * as reference sequence for itself and the preceding sequence
486 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
488 AlignViewportI av = ap.getAlignViewport();
489 AlignmentI alignment = ap.getAlignment();
490 int repIndex = n % alignment.getHeight();
491 SequenceI rep = alignment.getSequenceAt(repIndex);
492 refseqs.put(ap.getViewName(), rep);
494 // code from mark/unmark sequence as reference in jalview.gui.PopupMenu
495 // todo refactor this to an alignment view controller
496 av.setDisplayReferenceSeq(true);
497 av.setColourByReferenceSeq(true);
498 av.getAlignment().setSeqrep(rep);
502 File tfile = File.createTempFile("testStoreAndRecoverReferenceSeq",
506 new Jalview2XML(false).saveState(tfile);
507 } catch (Throwable e)
509 Assert.fail("Didn't save the expanded view state", e);
511 Desktop.getInstance().closeAll_actionPerformed(null);
512 if (Desktop.getAlignFrames() != null)
514 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
517 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
518 DataSourceType.FILE);
519 afid = af.getViewport().getSequenceSetId();
521 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
523 // check representative
524 AlignmentI alignment = ap.getAlignment();
525 SequenceI rep = alignment.getSeqrep();
526 Assert.assertNotNull(rep,
527 "Couldn't restore sequence representative from project");
528 // can't use a strong equals here, because by definition, the sequence IDs
529 // will be different.
530 // could set vamsas session save/restore flag to preserve IDs across
532 Assert.assertEquals(refseqs.get(ap.getViewName()).toString(),
534 "Representative wasn't the same when recovered.");
535 Assert.assertTrue(ap.getAlignViewport().isDisplayReferenceSeq(),
536 "Display reference sequence view setting not set.");
537 Assert.assertTrue(ap.getAlignViewport().isColourByReferenceSeq(),
538 "Colour By Reference Seq view setting not set.");
542 @Test(groups = { "Functional" })
543 public void testIsVersionStringLaterThan()
546 * No version / development / test / autobuild is leniently assumed to be
549 assertTrue(Jalview2XML.isVersionStringLaterThan(null, null));
550 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", null));
551 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "2.8.3"));
552 assertTrue(Jalview2XML.isVersionStringLaterThan(null,
553 "Development Build"));
554 assertTrue(Jalview2XML.isVersionStringLaterThan(null,
555 "DEVELOPMENT BUILD"));
556 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
557 "Development Build"));
558 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "Test"));
559 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "TEST"));
560 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "Test"));
562 Jalview2XML.isVersionStringLaterThan(null, "Automated Build"));
563 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
565 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
569 * same version returns true i.e. compatible
571 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8", "2.8"));
572 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.3"));
573 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3b1"));
574 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3B1", "2.8.3b1"));
575 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3B1"));
578 * later version returns true
580 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.4"));
581 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.9"));
582 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.9.2"));
583 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8", "2.8.3"));
584 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.3b1"));
587 * earlier version returns false
589 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8"));
590 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.4", "2.8.3"));
591 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3"));
592 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.2b1"));
593 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.0b2", "2.8.0b1"));
597 * Test save and reload of a project with a different sequence group (and
598 * representative sequence) in each view.
602 @Test(groups = { "Functional" })
603 public void testStoreAndRecoverGroupRepSeqs() throws Exception
605 Desktop.getInstance().closeAll_actionPerformed(null);
606 // Jalview.setSynchronous(true);
607 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
608 "examples/uniref50.fa", DataSourceType.FILE);
609 assertNotNull(af, "Didn't read in the example file correctly.");
610 String afid = af.getViewport().getSequenceSetId();
611 // make a second view of the alignment
612 af.newView_actionPerformed(null);
615 * remember representative and hidden sequences marked
618 Map<String, SequenceI> repSeqs = new HashMap<>();
619 Map<String, List<String>> hiddenSeqNames = new HashMap<>();
622 * mark sequence 2, 3, 4.. in panels 1, 2, 3...
623 * as reference sequence for itself and the preceding sequence
626 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
628 AlignViewportI av = ap.getAlignViewport();
629 AlignmentI alignment = ap.getAlignment();
630 int repIndex = n % alignment.getHeight();
631 // ensure at least one preceding sequence i.e. index >= 1
632 repIndex = Math.max(repIndex, 1);
633 SequenceI repSeq = alignment.getSequenceAt(repIndex);
634 repSeqs.put(ap.getViewName(), repSeq);
635 List<String> hiddenNames = new ArrayList<>();
636 hiddenSeqNames.put(ap.getViewName(), hiddenNames);
639 * have rep sequence represent itself and the one before it
640 * this hides the group (except for the rep seq)
642 SequenceGroup sg = new SequenceGroup();
643 sg.addSequence(repSeq, false);
644 SequenceI precedingSeq = alignment.getSequenceAt(repIndex - 1);
645 sg.addSequence(precedingSeq, false);
646 sg.setSeqrep(repSeq);
647 assertTrue(sg.getSequences().contains(repSeq));
648 assertTrue(sg.getSequences().contains(precedingSeq));
649 av.setSelectionGroup(sg);
650 assertSame(repSeq, sg.getSeqrep());
653 * represent group with sequence adds to a map of hidden rep sequences
654 * (it does not create a group on the alignment)
656 ((AlignmentViewport) av).hideSequences(repSeq, true);
657 assertSame(repSeq, sg.getSeqrep());
658 assertTrue(sg.getSequences().contains(repSeq));
659 assertTrue(sg.getSequences().contains(precedingSeq));
660 assertTrue(alignment.getGroups().isEmpty(), "alignment has groups");
661 Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av
662 .getHiddenRepSequences();
663 assertNotNull(hiddenRepSeqsMap);
664 assertEquals(1, hiddenRepSeqsMap.size());
665 assertSame(sg, hiddenRepSeqsMap.get(repSeq));
666 assertTrue(alignment.getHiddenSequences().isHidden(precedingSeq));
667 assertFalse(alignment.getHiddenSequences().isHidden(repSeq));
668 hiddenNames.add(precedingSeq.getName());
672 File tfile = File.createTempFile("testStoreAndRecoverGroupReps",
676 new Jalview2XML(false).saveState(tfile);
677 } catch (Throwable e)
679 Assert.fail("Didn't save the expanded view state", e);
681 Desktop.getInstance().closeAll_actionPerformed(null);
682 if (Desktop.getAlignFrames() != null)
684 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
687 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
688 DataSourceType.FILE);
689 afid = af.getViewport().getSequenceSetId();
691 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
693 String viewName = ap.getViewName();
694 AlignViewportI av = ap.getAlignViewport();
695 AlignmentI alignment = ap.getAlignment();
696 List<SequenceGroup> groups = alignment.getGroups();
697 assertNotNull(groups);
698 assertTrue(groups.isEmpty(), "Alignment has groups");
699 Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av
700 .getHiddenRepSequences();
701 assertNotNull(hiddenRepSeqsMap, "No hidden represented sequences");
702 assertEquals(1, hiddenRepSeqsMap.size());
703 assertEquals(repSeqs.get(viewName).getDisplayId(true),
704 hiddenRepSeqsMap.keySet().iterator().next()
705 .getDisplayId(true));
708 * verify hidden sequences in restored panel
710 List<String> hidden = hiddenSeqNames.get(ap.getViewName());
711 HiddenSequences hs = alignment.getHiddenSequences();
712 assertEquals(hidden.size(), hs.getSize(),
713 "wrong number of restored hidden sequences in "
719 * Test save and reload of PDBEntry in Jalview project
723 @Test(groups = { "Functional" })
724 public void testStoreAndRecoverPDBEntry() throws Exception
726 Desktop.getInstance().closeAll_actionPerformed(null);
727 String exampleFile = "examples/3W5V.pdb";
728 // Jalview.setSynchronous(true);
729 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
730 DataSourceType.FILE);
731 assertNotNull(af, "Didn't read in the example file correctly.");
732 String afid = af.getViewport().getSequenceSetId();
734 AlignmentPanel[] alignPanels = Desktop.getAlignmentPanels(afid);
735 System.out.println();
736 AlignmentViewPanel ap = alignPanels[0];
737 String tfileBase = new File(".").getAbsolutePath().replace(".", "");
738 String testFile = tfileBase + exampleFile;
739 AlignmentI alignment = ap.getAlignment();
740 System.out.println("blah");
741 SequenceI[] seqs = alignment.getSequencesArray();
742 Assert.assertNotNull(seqs[0]);
743 Assert.assertNotNull(seqs[1]);
744 Assert.assertNotNull(seqs[2]);
745 Assert.assertNotNull(seqs[3]);
746 Assert.assertNotNull(seqs[0].getDatasetSequence());
747 Assert.assertNotNull(seqs[1].getDatasetSequence());
748 Assert.assertNotNull(seqs[2].getDatasetSequence());
749 Assert.assertNotNull(seqs[3].getDatasetSequence());
750 PDBEntry[] pdbEntries = new PDBEntry[4];
751 pdbEntries[0] = new PDBEntry("3W5V", "A", Type.PDB, testFile);
752 pdbEntries[1] = new PDBEntry("3W5V", "B", Type.PDB, testFile);
753 pdbEntries[2] = new PDBEntry("3W5V", "C", Type.PDB, testFile);
754 pdbEntries[3] = new PDBEntry("3W5V", "D", Type.PDB, testFile);
756 seqs[0].getDatasetSequence().getAllPDBEntries().get(0),
759 seqs[1].getDatasetSequence().getAllPDBEntries().get(0),
762 seqs[2].getDatasetSequence().getAllPDBEntries().get(0),
765 seqs[3].getDatasetSequence().getAllPDBEntries().get(0),
768 File tfile = File.createTempFile("testStoreAndRecoverPDBEntry", ".jvp");
771 new Jalview2XML(false).saveState(tfile);
772 } catch (Throwable e)
774 Assert.fail("Didn't save the state", e);
776 Desktop.getInstance().closeAll_actionPerformed(null);
777 if (Desktop.getAlignFrames() != null)
779 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
782 AlignFrame restoredFrame = new FileLoader().LoadFileWaitTillLoaded(
783 tfile.getAbsolutePath(), DataSourceType.FILE);
784 String rfid = restoredFrame.getViewport().getSequenceSetId();
785 AlignmentPanel[] rAlignPanels = Desktop.getAlignmentPanels(rfid);
786 AlignmentViewPanel rap = rAlignPanels[0];
787 AlignmentI rAlignment = rap.getAlignment();
788 System.out.println("blah");
789 SequenceI[] rseqs = rAlignment.getSequencesArray();
790 Assert.assertNotNull(rseqs[0]);
791 Assert.assertNotNull(rseqs[1]);
792 Assert.assertNotNull(rseqs[2]);
793 Assert.assertNotNull(rseqs[3]);
794 Assert.assertNotNull(rseqs[0].getDatasetSequence());
795 Assert.assertNotNull(rseqs[1].getDatasetSequence());
796 Assert.assertNotNull(rseqs[2].getDatasetSequence());
797 Assert.assertNotNull(rseqs[3].getDatasetSequence());
799 // The Asserts below are expected to fail until the PDB chainCode is
800 // recoverable from a Jalview projects
801 for (int chain = 0; chain < 4; chain++)
803 PDBEntry recov = rseqs[chain].getDatasetSequence().getAllPDBEntries()
805 PDBEntry expected = pdbEntries[chain];
806 Assert.assertEquals(recov.getId(), expected.getId(),
808 Assert.assertEquals(recov.getChainCode(), expected.getChainCode(),
810 Assert.assertEquals(recov.getType(), expected.getType(),
811 "Mismatch PDBEntry 'Type'");
812 Assert.assertNotNull(recov.getFile(),
813 "Recovered PDBEntry should have a non-null file entry");
818 * Configure an alignment and a sub-group each with distinct colour schemes,
819 * Conservation and PID thresholds, and confirm these are restored from the
822 * @throws IOException
824 @Test(groups = { "Functional" })
825 public void testStoreAndRecoverColourThresholds() throws IOException
827 Desktop.getInstance().closeAll_actionPerformed(null);
828 // Jalview.setSynchronous(true);
829 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
830 "examples/uniref50.fa", DataSourceType.FILE);
832 AlignViewport av = af.getViewport();
833 AlignmentI al = av.getAlignment();
836 * Colour alignment by Buried Index, Above 10% PID, By Conservation 20%
838 av.setColourAppliesToAllGroups(false);
839 af.changeColour_actionPerformed(JalviewColourScheme.Buried.toString());
840 assertTrue(av.getGlobalColourScheme() instanceof BuriedColourScheme);
841 af.abovePIDThreshold_actionPerformed(true);
842 SliderPanel sp = SliderPanel.getSliderPanel();
843 assertFalse(sp.isForConservation());
845 af.conservationMenuItem_actionPerformed(true);
846 sp = SliderPanel.getSliderPanel();
847 assertTrue(sp.isForConservation());
849 ResidueShaderI rs = av.getResidueShading();
850 assertEquals(rs.getThreshold(), 10);
851 assertTrue(rs.conservationApplied());
852 assertEquals(rs.getConservationInc(), 20);
855 * create a group with Strand colouring, 30% Conservation
856 * and 40% PID threshold
858 SequenceGroup sg = new SequenceGroup();
859 sg.addSequence(al.getSequenceAt(0), false);
862 av.setSelectionGroup(sg);
863 PopupMenu popupMenu = new PopupMenu(af.alignPanel, null, null);
864 popupMenu.changeColour_actionPerformed(
865 JalviewColourScheme.Strand.toString());
866 assertTrue(sg.getColourScheme() instanceof StrandColourScheme);
867 assertEquals(al.getGroups().size(), 1);
868 assertSame(al.getGroups().get(0), sg);
869 popupMenu.conservationMenuItem_actionPerformed(true);
870 sp = SliderPanel.getSliderPanel();
871 assertTrue(sp.isForConservation());
873 popupMenu.abovePIDColour_actionPerformed(true);
874 sp = SliderPanel.getSliderPanel();
875 assertFalse(sp.isForConservation());
877 assertTrue(sg.getGroupColourScheme().conservationApplied());
878 assertEquals(sg.getGroupColourScheme().getConservationInc(), 30);
879 assertEquals(sg.getGroupColourScheme().getThreshold(), 40);
882 * save project, close windows, reload project, verify
884 File tfile = File.createTempFile("testStoreAndRecoverColourThresholds",
886 tfile.deleteOnExit();
887 new Jalview2XML(false).saveState(tfile);
888 Desktop.getInstance().closeAll_actionPerformed(null);
889 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
890 DataSourceType.FILE);
891 Assert.assertNotNull(af, "Failed to reload project");
894 * verify alignment (background) colouring
896 rs = af.getViewport().getResidueShading();
897 assertTrue(rs.getColourScheme() instanceof BuriedColourScheme);
898 assertEquals(rs.getThreshold(), 10);
899 assertTrue(rs.conservationApplied());
900 assertEquals(rs.getConservationInc(), 20);
903 * verify group colouring
905 assertEquals(1, af.getViewport().getAlignment().getGroups().size(), 1);
906 rs = af.getViewport().getAlignment().getGroups().get(0)
907 .getGroupColourScheme();
908 assertTrue(rs.getColourScheme() instanceof StrandColourScheme);
909 assertEquals(rs.getThreshold(), 40);
910 assertTrue(rs.conservationApplied());
911 assertEquals(rs.getConservationInc(), 30);
915 * Test save and reload of feature colour schemes and filter settings
917 * @throws IOException
919 @Test(groups = { "Functional" })
920 public void testSaveLoadFeatureColoursAndFilters() throws IOException
922 // Jalview.setSynchronous(true);
923 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
924 ">Seq1\nACDEFGHIKLM", DataSourceType.PASTE);
925 SequenceI seq1 = af.getViewport().getAlignment().getSequenceAt(0);
928 * add some features to the sequence
931 addFeatures(seq1, "type1", score++);
932 addFeatures(seq1, "type2", score++);
933 addFeatures(seq1, "type3", score++);
934 addFeatures(seq1, "type4", score++);
935 addFeatures(seq1, "type5", score++);
938 * set colour schemes for features
940 FeatureRenderer fr = af.getFeatureRenderer();
941 fr.findAllFeatures(true);
944 fr.setColour("type1", new FeatureColour(Color.red));
947 FeatureColourI byLabel = new FeatureColour();
948 byLabel.setColourByLabel(true);
949 fr.setColour("type2", byLabel);
951 // type3: by score above threshold
952 FeatureColourI byScore = new FeatureColour(null, Color.BLACK,
953 Color.BLUE, null, 1, 10);
954 byScore.setAboveThreshold(true);
955 byScore.setThreshold(2f);
956 fr.setColour("type3", byScore);
958 // type4: by attribute AF
959 FeatureColourI byAF = new FeatureColour();
960 byAF.setColourByLabel(true);
961 byAF.setAttributeName("AF");
962 fr.setColour("type4", byAF);
964 // type5: by attribute CSQ:PolyPhen below threshold
965 FeatureColourI byPolyPhen = new FeatureColour(null, Color.BLACK,
966 Color.BLUE, null, 1, 10);
967 byPolyPhen.setBelowThreshold(true);
968 byPolyPhen.setThreshold(3f);
969 byPolyPhen.setAttributeName("CSQ", "PolyPhen");
970 fr.setColour("type5", byPolyPhen);
973 * set filters for feature types
976 // filter type1 features by (label contains "x")
977 FeatureMatcherSetI filterByX = new FeatureMatcherSet();
978 filterByX.and(FeatureMatcher.byLabel(Condition.Contains, "x"));
979 fr.setFeatureFilter("type1", filterByX);
981 // filter type2 features by (score <= 2.4 and score > 1.1)
982 FeatureMatcherSetI filterByScore = new FeatureMatcherSet();
983 filterByScore.and(FeatureMatcher.byScore(Condition.LE, "2.4"));
984 filterByScore.and(FeatureMatcher.byScore(Condition.GT, "1.1"));
985 fr.setFeatureFilter("type2", filterByScore);
987 // filter type3 features by (AF contains X OR CSQ:PolyPhen != 0)
988 FeatureMatcherSetI filterByXY = new FeatureMatcherSet();
990 .and(FeatureMatcher.byAttribute(Condition.Contains, "X", "AF"));
991 filterByXY.or(FeatureMatcher.byAttribute(Condition.NE, "0", "CSQ",
993 fr.setFeatureFilter("type3", filterByXY);
996 * save as Jalview project
998 File tfile = File.createTempFile("JalviewTest", ".jvp");
999 tfile.deleteOnExit();
1000 String filePath = tfile.getAbsolutePath();
1001 af.saveAlignment(filePath, FileFormat.Jalview);
1002 assertTrue(af.isSaveAlignmentSuccessful(),
1003 "Failed to store as a project.");
1006 * close current alignment and load the saved project
1008 af.closeMenuItem_actionPerformed(true);
1010 af = new FileLoader().LoadFileWaitTillLoaded(filePath,
1011 DataSourceType.FILE);
1012 assertNotNull(af, "Failed to import new project");
1015 * verify restored feature colour schemes and filters
1017 fr = af.getFeatureRenderer();
1018 FeatureColourI fc = fr.getFeatureStyle("type1");
1019 assertTrue(fc.isSimpleColour());
1020 assertEquals(fc.getColour(), Color.red);
1021 fc = fr.getFeatureStyle("type2");
1022 assertTrue(fc.isColourByLabel());
1023 fc = fr.getFeatureStyle("type3");
1024 assertTrue(fc.isGraduatedColour());
1025 assertNull(fc.getAttributeName());
1026 assertTrue(fc.isAboveThreshold());
1027 assertEquals(fc.getThreshold(), 2f);
1028 fc = fr.getFeatureStyle("type4");
1029 assertTrue(fc.isColourByLabel());
1030 assertTrue(fc.isColourByAttribute());
1031 assertEquals(fc.getAttributeName(), new String[] { "AF" });
1032 fc = fr.getFeatureStyle("type5");
1033 assertTrue(fc.isGraduatedColour());
1034 assertTrue(fc.isColourByAttribute());
1035 assertEquals(fc.getAttributeName(), new String[] { "CSQ", "PolyPhen" });
1036 assertTrue(fc.isBelowThreshold());
1037 assertEquals(fc.getThreshold(), 3f);
1039 assertEquals(fr.getFeatureFilter("type1").toStableString(),
1040 "Label Contains x");
1041 assertEquals(fr.getFeatureFilter("type2").toStableString(),
1042 "(Score LE 2.4) AND (Score GT 1.1)");
1043 assertEquals(fr.getFeatureFilter("type3").toStableString(),
1044 "(AF Contains X) OR (CSQ:PolyPhen NE 0.0)");
1047 private void addFeature(SequenceI seq, String featureType, int score)
1049 SequenceFeature sf = new SequenceFeature(featureType, "desc", 1, 2,
1051 sf.setValue("AF", score);
1052 sf.setValue("CSQ", new HashMap<String, String>()
1055 put("PolyPhen", Integer.toString(score));
1058 seq.addSequenceFeature(sf);
1062 * Adds two features of the given type to the given sequence, also setting the
1063 * score as the value of attribute "AF" and sub-attribute "CSQ:PolyPhen"
1066 * @param featureType
1069 private void addFeatures(SequenceI seq, String featureType, int score)
1071 addFeature(seq, featureType, score++);
1072 addFeature(seq, featureType, score);
1076 * pre 2.11 - jalview 2.10 erroneously created new dataset entries for each
1077 * view (JAL-3171) this test ensures we can import and merge those views
1079 @Test(groups = { "Functional" })
1080 public void testMergeDatasetsforViews() throws IOException
1082 // simple project - two views on one alignment
1083 // Jalview.setSynchronous(true);
1084 AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
1085 "examples/testdata/projects/twoViews.jvp", DataSourceType.FILE);
1087 assertTrue(af.getAlignPanels().size() > 1);
1092 * pre 2.11 - jalview 2.10 erroneously created new dataset entries for each
1093 * view (JAL-3171) this test ensures we can import and merge those views This
1094 * is a more complex project
1096 @Test(groups = { "Functional" })
1097 public void testMergeDatasetsforManyViews() throws IOException
1099 Desktop.getInstance().closeAll_actionPerformed(null);
1101 // complex project - one dataset, several views on several alignments
1102 // Jalview.setSynchronous(true);
1103 AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
1104 "examples/testdata/projects/manyViews.jvp",
1105 DataSourceType.FILE);
1108 AlignmentI ds = null;
1109 for (AlignFrame alignFrame : Desktop.getAlignFrames())
1113 ds = verifyDs(alignFrame);
1117 // check that this frame's dataset matches the last
1118 assertTrue(ds == verifyDs(alignFrame));
1123 private AlignmentI verifyDs(AlignFrame af)
1125 AlignmentI ds = null;
1126 for (AlignmentViewPanel ap : af.getAlignPanels())
1130 ds = ap.getAlignment().getDataset();
1134 assertTrue(ap.getAlignment().getDataset() == ds,
1135 "Dataset was not the same for imported 2.10.5 project with several alignment views");
1141 @Test(groups = "Functional")
1142 public void testPcaViewAssociation() throws IOException
1144 Desktop.getInstance().closeAll_actionPerformed(null);
1145 // Jalview.setSynchronous(true);
1146 final String PCAVIEWNAME = "With PCA";
1147 // create a new tempfile
1148 File tempfile = File.createTempFile("jvPCAviewAssoc", "jvp");
1151 String exampleFile = "examples/uniref50.fa";
1152 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
1153 DataSourceType.FILE);
1154 assertNotNull(af, "Didn't read in the example file correctly.");
1155 AlignmentPanel origView = (AlignmentPanel) af.getAlignPanels().get(0);
1156 AlignmentPanel newview = af.newView(PCAVIEWNAME, true);
1157 // create another for good measure
1158 af.newView("Not the PCA View", true);
1159 PCAPanel pcaPanel = new PCAPanel(origView, "BLOSUM62",
1160 new SimilarityParams(true, true, true, false));
1161 // we're in the test exec thread, so we can just run synchronously here
1164 // now switch the linked view
1165 pcaPanel.selectAssociatedView(newview);
1167 assertTrue(pcaPanel.getAlignViewport() == newview.getAlignViewport(),
1168 "PCA should be associated with 'With PCA' view: test is broken");
1170 // now save and reload project
1171 Jalview2XML jv2xml = new jalview.project.Jalview2XML(false);
1173 jv2xml.saveState(tempfile);
1174 assertTrue(jv2xml.errorMessage == null,
1175 "Failed to save dummy project with PCA: test broken");
1179 Desktop.getInstance().closeAll_actionPerformed(null);
1180 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1181 tempfile.getCanonicalPath(), DataSourceType.FILE);
1182 JInternalFrame[] frames = Desktop.getInstance().getAllFrames();
1183 // PCA and the tabbed alignment view should be the only two windows on the
1185 assertEquals(frames.length, 2,
1186 "PCA and the tabbed alignment view should be the only two windows on the desktop");
1187 PCAPanel pcaPanel = (PCAPanel) frames[frames[0] == af ? 1 : 0];
1189 AlignmentViewPanel restoredNewView = null;
1190 for (AlignmentViewPanel alignpanel : Desktop.getAlignmentPanels(null))
1192 if (alignpanel.getAlignViewport() == pcaPanel.getAlignViewport())
1194 restoredNewView = alignpanel;
1197 assertEquals(restoredNewView.getViewName(), PCAVIEWNAME);
1199 restoredNewView.getAlignViewport() == pcaPanel
1200 .getAlignViewport(),
1201 "Didn't restore correct view association for the PCA view");