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.datamodel.AlignmentAnnotation;
36 import jalview.datamodel.AlignmentI;
37 import jalview.datamodel.HiddenSequences;
38 import jalview.datamodel.PDBEntry;
39 import jalview.datamodel.PDBEntry.Type;
40 import jalview.datamodel.SequenceCollectionI;
41 import jalview.datamodel.SequenceFeature;
42 import jalview.datamodel.SequenceGroup;
43 import jalview.datamodel.SequenceI;
44 import jalview.datamodel.features.FeatureMatcher;
45 import jalview.datamodel.features.FeatureMatcherSet;
46 import jalview.datamodel.features.FeatureMatcherSetI;
47 import jalview.gui.AlignFrame;
48 import jalview.gui.AlignViewport;
49 import jalview.gui.AlignmentPanel;
50 import jalview.gui.Desktop;
51 import jalview.gui.FeatureRenderer;
52 import jalview.gui.JvOptionPane;
53 import jalview.gui.PCAPanel;
54 import jalview.gui.PopupMenu;
55 import jalview.gui.SliderPanel;
56 import jalview.io.DataSourceType;
57 import jalview.io.FileFormat;
58 import jalview.io.FileLoader;
59 import jalview.io.Jalview2xmlBase;
60 import jalview.renderer.ResidueShaderI;
61 import jalview.schemes.AnnotationColourGradient;
62 import jalview.schemes.BuriedColourScheme;
63 import jalview.schemes.ColourSchemeI;
64 import jalview.schemes.ColourSchemeProperty;
65 import jalview.schemes.FeatureColour;
66 import jalview.schemes.JalviewColourScheme;
67 import jalview.schemes.RNAHelicesColour;
68 import jalview.schemes.StrandColourScheme;
69 import jalview.schemes.TCoffeeColourScheme;
70 import jalview.structure.StructureImportSettings;
71 import jalview.util.matcher.Condition;
72 import jalview.viewmodel.AlignmentViewport;
74 import java.awt.Color;
76 import java.io.IOException;
77 import java.util.ArrayList;
78 import java.util.HashMap;
79 import java.util.List;
82 import javax.swing.JInternalFrame;
84 import org.testng.Assert;
85 import org.testng.AssertJUnit;
86 import org.testng.annotations.BeforeClass;
87 import org.testng.annotations.Test;
89 @Test(singleThreaded = true)
90 public class Jalview2xmlTests extends Jalview2xmlBase
94 @BeforeClass(alwaysRun = true)
95 public void setUpJvOptionPane()
97 JvOptionPane.setInteractiveMode(false);
98 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
101 @Test(groups = { "Functional" })
102 public void testRNAStructureRecovery() throws Exception
104 String inFile = "examples/RF00031_folded.stk";
105 String tfile = File.createTempFile("JalviewTest", ".jvp")
107 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
108 DataSourceType.FILE);
109 assertNotNull(af, "Didn't read input file " + inFile);
110 int olddsann = countDsAnn(af.getViewport());
111 assertTrue(olddsann > 0, "Didn't find any dataset annotations");
112 af.changeColour_actionPerformed(
113 JalviewColourScheme.RNAHelices.toString());
116 .getGlobalColourScheme() instanceof RNAHelicesColour,
117 "Couldn't apply RNA helices colourscheme");
118 assertTrue(af.saveAlignment(tfile, FileFormat.Jalview),
119 "Failed to store as a project.");
120 af.closeMenuItem_actionPerformed(true);
122 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
123 DataSourceType.FILE);
124 assertNotNull(af, "Failed to import new project");
125 int newdsann = countDsAnn(af.getViewport());
126 assertEquals(olddsann, newdsann,
127 "Differing numbers of dataset sequence annotation\nOriginally "
128 + olddsann + " and now " + newdsann);
130 "Read in same number of annotations as originally present ("
135 .getGlobalColourScheme() instanceof RNAHelicesColour,
136 "RNA helices colourscheme was not applied on import.");
139 @Test(groups = { "Functional" })
140 public void testTCoffeeScores() throws Exception
142 String inFile = "examples/uniref50.fa",
143 inAnnot = "examples/uniref50.score_ascii";
144 String tfile = File.createTempFile("JalviewTest", ".jvp")
146 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
147 DataSourceType.FILE);
148 assertNotNull(af, "Didn't read input file " + inFile);
149 af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
150 AlignViewport viewport = af.getViewport();
151 assertSame(viewport.getGlobalColourScheme().getClass(),
152 TCoffeeColourScheme.class, "Didn't set T-coffee colourscheme");
154 ColourSchemeProperty.getColourScheme(viewport,
155 viewport.getAlignment(),
156 viewport.getGlobalColourScheme()
158 "Recognise T-Coffee score from string");
160 assertTrue(af.saveAlignment(tfile, FileFormat.Jalview),
161 "Failed to store as a project.");
162 af.closeMenuItem_actionPerformed(true);
164 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
165 DataSourceType.FILE);
166 assertNotNull(af, "Failed to import new project");
167 assertSame(af.getViewport().getGlobalColourScheme().getClass(),
168 TCoffeeColourScheme.class,
169 "Didn't set T-coffee colourscheme for imported project.");
171 "T-Coffee score shading successfully recovered from project.");
174 @Test(groups = { "Functional" })
175 public void testColourByAnnotScores() throws Exception
177 String inFile = "examples/uniref50.fa",
178 inAnnot = "examples/testdata/uniref50_iupred.jva";
179 String tfile = File.createTempFile("JalviewTest", ".jvp")
181 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
182 DataSourceType.FILE);
183 assertNotNull(af, "Didn't read input file " + inFile);
184 af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
185 AlignmentAnnotation[] aa = af.getViewport().getAlignment()
186 .getSequenceAt(0).getAnnotation("IUPredWS (Short)");
189 aa != null && aa.length > 0,
190 "Didn't find any IUPred annotation to use to shade alignment.");
191 AnnotationColourGradient cs = new AnnotationColourGradient(aa[0], null,
192 AnnotationColourGradient.ABOVE_THRESHOLD);
193 AnnotationColourGradient gcs = new AnnotationColourGradient(aa[0], null,
194 AnnotationColourGradient.BELOW_THRESHOLD);
195 cs.setSeqAssociated(true);
196 gcs.setSeqAssociated(true);
198 SequenceGroup sg = new SequenceGroup();
201 sg.cs.setColourScheme(gcs);
202 af.getViewport().getAlignment().addGroup(sg);
203 sg.addSequence(af.getViewport().getAlignment().getSequenceAt(1), false);
204 sg.addSequence(af.getViewport().getAlignment().getSequenceAt(2), true);
205 af.alignPanel.alignmentChanged();
206 assertTrue(af.saveAlignment(tfile, FileFormat.Jalview),
207 "Failed to store as a project.");
208 af.closeMenuItem_actionPerformed(true);
210 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
211 DataSourceType.FILE);
212 assertNotNull(af, "Failed to import new project");
214 // check for group and alignment colourschemes
216 ColourSchemeI _rcs = af.getViewport().getGlobalColourScheme();
217 ColourSchemeI _rgcs = af.getViewport().getAlignment().getGroups().get(0)
219 assertNotNull(_rcs, "Didn't recover global colourscheme");
220 assertTrue(_rcs instanceof AnnotationColourGradient,
221 "Didn't recover annotation colour global scheme");
222 AnnotationColourGradient __rcs = (AnnotationColourGradient) _rcs;
223 assertTrue(__rcs.isSeqAssociated(),
224 "Annotation colourscheme wasn't sequence associated");
226 boolean diffseqcols = false, diffgseqcols = false;
227 SequenceI[] sqs = af.getViewport().getAlignment().getSequencesArray();
228 for (int p = 0, pSize = af.getViewport().getAlignment()
229 .getWidth(); p < pSize && (!diffseqcols || !diffgseqcols); p++)
231 if (_rcs.findColour(sqs[0].getCharAt(p), p, sqs[0], null, 0f) != _rcs
232 .findColour(sqs[5].getCharAt(p), p, sqs[5], null, 0f))
237 assertTrue(diffseqcols, "Got Different sequence colours");
239 "Per sequence colourscheme (Background) successfully applied and recovered.");
241 assertNotNull(_rgcs, "Didn't recover group colourscheme");
242 assertTrue(_rgcs instanceof AnnotationColourGradient,
243 "Didn't recover annotation colour group colourscheme");
244 __rcs = (AnnotationColourGradient) _rgcs;
245 assertTrue(__rcs.isSeqAssociated(),
246 "Group Annotation colourscheme wasn't sequence associated");
248 for (int p = 0, pSize = af.getViewport().getAlignment()
249 .getWidth(); p < pSize && (!diffseqcols || !diffgseqcols); p++)
251 if (_rgcs.findColour(sqs[1].getCharAt(p), p, sqs[1], null,
252 0f) != _rgcs.findColour(sqs[2].getCharAt(p), p, sqs[2], null,
258 assertTrue(diffgseqcols, "Got Different group sequence colours");
260 "Per sequence (Group) colourscheme successfully applied and recovered.");
263 @Test(groups = { "Functional" })
264 public void gatherViewsHere() throws Exception
266 int origCount = Desktop.getAlignFrames() == null ? 0
267 : Desktop.getAlignFrames().length;
268 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
269 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
270 assertNotNull(af, "Didn't read in the example file correctly.");
271 assertTrue(Desktop.getAlignFrames().length == 1 + origCount,
272 "Didn't gather the views in the example file.");
277 * Test for JAL-2223 - multiple mappings in View Mapping report
281 @Test(groups = { "Functional" })
282 public void noDuplicatePdbMappingsMade() throws Exception
284 StructureImportSettings.setProcessSecondaryStructure(true);
285 StructureImportSettings.setVisibleChainAnnotation(true);
286 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
287 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
288 assertNotNull(af, "Didn't read in the example file correctly.");
290 // locate Jmol viewer
291 // count number of PDB mappings the structure selection manager holds -
292 String pdbFile = af.getCurrentView().getStructureSelectionManager()
293 .findFileForPDBId("1A70");
295 af.getCurrentView().getStructureSelectionManager()
296 .getMapping(pdbFile).length,
297 2, "Expected only two mappings for 1A70");
301 @Test(groups = { "Functional" })
302 public void viewRefPdbAnnotation() throws Exception
304 StructureImportSettings.setProcessSecondaryStructure(true);
305 StructureImportSettings.setVisibleChainAnnotation(true);
306 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
307 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
308 assertNotNull(af, "Didn't read in the example file correctly.");
309 AlignmentViewPanel sps = null;
310 for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
312 if ("Spinach Feredoxin Structure".equals(ap.getViewName()))
318 assertNotNull(sps, "Couldn't find the structure view");
319 AlignmentAnnotation refan = null;
320 for (AlignmentAnnotation ra : sps.getAlignment()
321 .getAlignmentAnnotation())
329 assertNotNull(refan, "Annotation secondary structure not found.");
330 SequenceI sq = sps.getAlignment().findName("1A70|");
331 assertNotNull(sq, "Couldn't find 1a70 null chain");
332 // compare the manually added temperature factor annotation
333 // to the track automatically transferred from the pdb structure on load
334 assertNotNull(sq.getDatasetSequence().getAnnotation(),
335 "1a70 has no annotation");
336 for (AlignmentAnnotation ala : sq.getDatasetSequence().getAnnotation())
338 AlignmentAnnotation alaa;
339 sq.addAlignmentAnnotation(alaa = new AlignmentAnnotation(ala));
340 alaa.adjustForAlignment();
341 if (ala.graph == refan.graph)
343 for (int p = 0; p < ala.annotations.length; p++)
348 assertTrue((alaa.annotations[p] == null
349 && refan.annotations[p] == null)
350 || alaa.annotations[p].value == refan.annotations[p].value,
351 "Mismatch at alignment position " + p);
352 } catch (NullPointerException q)
354 Assert.fail("Mismatch of alignment annotations at position " + p
355 + " Ref seq ann: " + refan.annotations[p]
356 + " alignment " + alaa.annotations[p]);
364 @Test(groups = { "Functional" })
365 public void testCopyViewSettings() throws Exception
367 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
368 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
369 assertNotNull(af, "Didn't read in the example file correctly.");
370 AlignmentViewPanel sps = null, groups = null;
371 for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
373 if ("Spinach Feredoxin Structure".equals(ap.getViewName()))
377 if (ap.getViewName().contains("MAFFT"))
382 assertNotNull(sps, "Couldn't find the structure view");
383 assertNotNull(groups, "Couldn't find the MAFFT view");
385 ViewStyleI structureStyle = sps.getAlignViewport().getViewStyle();
386 ViewStyleI groupStyle = groups.getAlignViewport().getViewStyle();
387 AssertJUnit.assertFalse(structureStyle.sameStyle(groupStyle));
389 groups.getAlignViewport().setViewStyle(structureStyle);
390 AssertJUnit.assertFalse(
391 groupStyle.sameStyle(groups.getAlignViewport().getViewStyle()));
392 Assert.assertTrue(structureStyle
393 .sameStyle(groups.getAlignViewport().getViewStyle()));
398 * test store and recovery of expanded views
402 @Test(groups = { "Functional" }, enabled = true)
403 public void testStoreAndRecoverExpandedviews() throws Exception
405 Desktop.instance.closeAll_actionPerformed(null);
407 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
408 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
409 Assert.assertEquals(Desktop.getAlignFrames().length, 1);
410 String afid = af.getViewport().getSequenceSetId();
412 // check FileLoader returned a reference to the one alignFrame that is
413 // actually on the Desktop
414 assertSame(af, Desktop.getAlignFrameFor(af.getViewport()),
415 "Jalview2XML.loadAlignFrame() didn't return correct AlignFrame reference for multiple view window");
417 Desktop.explodeViews(af);
419 int oldviews = Desktop.getAlignFrames().length;
420 Assert.assertEquals(Desktop.getAlignFrames().length,
421 Desktop.getAlignmentPanels(afid).length);
422 File tfile = File.createTempFile("testStoreAndRecoverExpanded", ".jvp");
425 new Jalview2XML(false).saveState(tfile);
428 Assert.fail("Didn't save the expanded view state", e);
429 } catch (Exception e)
431 Assert.fail("Didn't save the expanded view state", e);
433 Desktop.instance.closeAll_actionPerformed(null);
434 if (Desktop.getAlignFrames() != null)
436 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
438 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
439 DataSourceType.FILE);
440 Assert.assertNotNull(af);
441 Assert.assertEquals(Desktop.getAlignFrames().length,
442 Desktop.getAlignmentPanels(
443 af.getViewport().getSequenceSetId()).length);
445 Desktop.getAlignmentPanels(
446 af.getViewport().getSequenceSetId()).length,
451 * Test save and reload of a project with a different representative sequence
456 @Test(groups = { "Functional" })
457 public void testStoreAndRecoverReferenceSeqSettings() throws Exception
459 Desktop.instance.closeAll_actionPerformed(null);
460 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
461 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
462 assertNotNull(af, "Didn't read in the example file correctly.");
463 String afid = af.getViewport().getSequenceSetId();
465 // remember reference sequence for each panel
466 Map<String, SequenceI> refseqs = new HashMap<>();
469 * mark sequence 2, 3, 4.. in panels 1, 2, 3...
470 * as reference sequence for itself and the preceding sequence
473 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
475 AlignViewportI av = ap.getAlignViewport();
476 AlignmentI alignment = ap.getAlignment();
477 int repIndex = n % alignment.getHeight();
478 SequenceI rep = alignment.getSequenceAt(repIndex);
479 refseqs.put(ap.getViewName(), rep);
481 // code from mark/unmark sequence as reference in jalview.gui.PopupMenu
482 // todo refactor this to an alignment view controller
483 av.setDisplayReferenceSeq(true);
484 av.setColourByReferenceSeq(true);
485 av.getAlignment().setSeqrep(rep);
489 File tfile = File.createTempFile("testStoreAndRecoverReferenceSeq",
493 new Jalview2XML(false).saveState(tfile);
494 } catch (Throwable e)
496 Assert.fail("Didn't save the expanded view state", e);
498 Desktop.instance.closeAll_actionPerformed(null);
499 if (Desktop.getAlignFrames() != null)
501 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
504 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
505 DataSourceType.FILE);
506 afid = af.getViewport().getSequenceSetId();
508 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
510 // check representative
511 AlignmentI alignment = ap.getAlignment();
512 SequenceI rep = alignment.getSeqrep();
513 Assert.assertNotNull(rep,
514 "Couldn't restore sequence representative from project");
515 // can't use a strong equals here, because by definition, the sequence IDs
516 // will be different.
517 // could set vamsas session save/restore flag to preserve IDs across
519 Assert.assertEquals(refseqs.get(ap.getViewName()).toString(),
521 "Representative wasn't the same when recovered.");
522 Assert.assertTrue(ap.getAlignViewport().isDisplayReferenceSeq(),
523 "Display reference sequence view setting not set.");
524 Assert.assertTrue(ap.getAlignViewport().isColourByReferenceSeq(),
525 "Colour By Reference Seq view setting not set.");
529 @Test(groups = { "Functional" })
530 public void testIsVersionStringLaterThan()
533 * No version / development / test / autobuild is leniently assumed to be
536 assertTrue(Jalview2XML.isVersionStringLaterThan(null, null));
537 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", null));
538 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "2.8.3"));
539 assertTrue(Jalview2XML.isVersionStringLaterThan(null,
540 "Development Build"));
541 assertTrue(Jalview2XML.isVersionStringLaterThan(null,
542 "DEVELOPMENT BUILD"));
543 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
544 "Development Build"));
545 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "Test"));
546 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "TEST"));
547 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "Test"));
549 Jalview2XML.isVersionStringLaterThan(null, "Automated Build"));
550 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
552 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
556 * same version returns true i.e. compatible
558 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8", "2.8"));
559 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.3"));
560 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3b1"));
561 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3B1", "2.8.3b1"));
562 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3B1"));
565 * later version returns true
567 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.4"));
568 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.9"));
569 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.9.2"));
570 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8", "2.8.3"));
571 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.3b1"));
574 * earlier version returns false
576 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8"));
577 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.4", "2.8.3"));
578 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3"));
579 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.2b1"));
580 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.0b2", "2.8.0b1"));
584 * Test save and reload of a project with a different sequence group (and
585 * representative sequence) in each view.
589 @Test(groups = { "Functional" })
590 public void testStoreAndRecoverGroupRepSeqs() throws Exception
592 Desktop.instance.closeAll_actionPerformed(null);
593 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
594 "examples/uniref50.fa", DataSourceType.FILE);
595 assertNotNull(af, "Didn't read in the example file correctly.");
596 String afid = af.getViewport().getSequenceSetId();
597 // make a second view of the alignment
598 af.newView_actionPerformed(null);
601 * remember representative and hidden sequences marked
604 Map<String, SequenceI> repSeqs = new HashMap<>();
605 Map<String, List<String>> hiddenSeqNames = new HashMap<>();
608 * mark sequence 2, 3, 4.. in panels 1, 2, 3...
609 * as reference sequence for itself and the preceding sequence
612 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
614 AlignViewportI av = ap.getAlignViewport();
615 AlignmentI alignment = ap.getAlignment();
616 int repIndex = n % alignment.getHeight();
617 // ensure at least one preceding sequence i.e. index >= 1
618 repIndex = Math.max(repIndex, 1);
619 SequenceI repSeq = alignment.getSequenceAt(repIndex);
620 repSeqs.put(ap.getViewName(), repSeq);
621 List<String> hiddenNames = new ArrayList<>();
622 hiddenSeqNames.put(ap.getViewName(), hiddenNames);
625 * have rep sequence represent itself and the one before it
626 * this hides the group (except for the rep seq)
628 SequenceGroup sg = new SequenceGroup();
629 sg.addSequence(repSeq, false);
630 SequenceI precedingSeq = alignment.getSequenceAt(repIndex - 1);
631 sg.addSequence(precedingSeq, false);
632 sg.setSeqrep(repSeq);
633 assertTrue(sg.getSequences().contains(repSeq));
634 assertTrue(sg.getSequences().contains(precedingSeq));
635 av.setSelectionGroup(sg);
636 assertSame(repSeq, sg.getSeqrep());
639 * represent group with sequence adds to a map of hidden rep sequences
640 * (it does not create a group on the alignment)
642 ((AlignmentViewport) av).hideSequences(repSeq, true);
643 assertSame(repSeq, sg.getSeqrep());
644 assertTrue(sg.getSequences().contains(repSeq));
645 assertTrue(sg.getSequences().contains(precedingSeq));
646 assertTrue(alignment.getGroups().isEmpty(), "alignment has groups");
647 Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av
648 .getHiddenRepSequences();
649 assertNotNull(hiddenRepSeqsMap);
650 assertEquals(1, hiddenRepSeqsMap.size());
651 assertSame(sg, hiddenRepSeqsMap.get(repSeq));
652 assertTrue(alignment.getHiddenSequences().isHidden(precedingSeq));
653 assertFalse(alignment.getHiddenSequences().isHidden(repSeq));
654 hiddenNames.add(precedingSeq.getName());
658 File tfile = File.createTempFile("testStoreAndRecoverGroupReps",
662 new Jalview2XML(false).saveState(tfile);
663 } catch (Throwable e)
665 Assert.fail("Didn't save the expanded view state", e);
667 Desktop.instance.closeAll_actionPerformed(null);
668 if (Desktop.getAlignFrames() != null)
670 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
673 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
674 DataSourceType.FILE);
675 afid = af.getViewport().getSequenceSetId();
677 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
679 String viewName = ap.getViewName();
680 AlignViewportI av = ap.getAlignViewport();
681 AlignmentI alignment = ap.getAlignment();
682 List<SequenceGroup> groups = alignment.getGroups();
683 assertNotNull(groups);
684 assertTrue(groups.isEmpty(), "Alignment has groups");
685 Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av
686 .getHiddenRepSequences();
687 assertNotNull(hiddenRepSeqsMap, "No hidden represented sequences");
688 assertEquals(1, hiddenRepSeqsMap.size());
689 assertEquals(repSeqs.get(viewName).getDisplayId(true),
690 hiddenRepSeqsMap.keySet().iterator().next()
691 .getDisplayId(true));
694 * verify hidden sequences in restored panel
696 List<String> hidden = hiddenSeqNames.get(ap.getViewName());
697 HiddenSequences hs = alignment.getHiddenSequences();
698 assertEquals(hidden.size(), hs.getSize(),
699 "wrong number of restored hidden sequences in "
705 * Test save and reload of PDBEntry in Jalview project
709 @Test(groups = { "Functional" })
710 public void testStoreAndRecoverPDBEntry() throws Exception
712 Desktop.instance.closeAll_actionPerformed(null);
713 String exampleFile = "examples/3W5V.pdb";
714 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
715 DataSourceType.FILE);
716 assertNotNull(af, "Didn't read in the example file correctly.");
717 String afid = af.getViewport().getSequenceSetId();
719 AlignmentPanel[] alignPanels = Desktop.getAlignmentPanels(afid);
720 System.out.println();
721 AlignmentViewPanel ap = alignPanels[0];
722 String tfileBase = new File(".").getAbsolutePath().replace(".", "");
723 String testFile = tfileBase + exampleFile;
724 AlignmentI alignment = ap.getAlignment();
725 System.out.println("blah");
726 SequenceI[] seqs = alignment.getSequencesArray();
727 Assert.assertNotNull(seqs[0]);
728 Assert.assertNotNull(seqs[1]);
729 Assert.assertNotNull(seqs[2]);
730 Assert.assertNotNull(seqs[3]);
731 Assert.assertNotNull(seqs[0].getDatasetSequence());
732 Assert.assertNotNull(seqs[1].getDatasetSequence());
733 Assert.assertNotNull(seqs[2].getDatasetSequence());
734 Assert.assertNotNull(seqs[3].getDatasetSequence());
735 PDBEntry[] pdbEntries = new PDBEntry[4];
736 pdbEntries[0] = new PDBEntry("3W5V", "A", Type.PDB, testFile);
737 pdbEntries[1] = new PDBEntry("3W5V", "B", Type.PDB, testFile);
738 pdbEntries[2] = new PDBEntry("3W5V", "C", Type.PDB, testFile);
739 pdbEntries[3] = new PDBEntry("3W5V", "D", Type.PDB, testFile);
741 seqs[0].getDatasetSequence().getAllPDBEntries().get(0),
744 seqs[1].getDatasetSequence().getAllPDBEntries().get(0),
747 seqs[2].getDatasetSequence().getAllPDBEntries().get(0),
750 seqs[3].getDatasetSequence().getAllPDBEntries().get(0),
753 File tfile = File.createTempFile("testStoreAndRecoverPDBEntry", ".jvp");
756 new Jalview2XML(false).saveState(tfile);
757 } catch (Throwable e)
759 Assert.fail("Didn't save the state", e);
761 Desktop.instance.closeAll_actionPerformed(null);
762 if (Desktop.getAlignFrames() != null)
764 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
767 AlignFrame restoredFrame = new FileLoader().LoadFileWaitTillLoaded(
768 tfile.getAbsolutePath(), DataSourceType.FILE);
769 String rfid = restoredFrame.getViewport().getSequenceSetId();
770 AlignmentPanel[] rAlignPanels = Desktop.getAlignmentPanels(rfid);
771 AlignmentViewPanel rap = rAlignPanels[0];
772 AlignmentI rAlignment = rap.getAlignment();
773 System.out.println("blah");
774 SequenceI[] rseqs = rAlignment.getSequencesArray();
775 Assert.assertNotNull(rseqs[0]);
776 Assert.assertNotNull(rseqs[1]);
777 Assert.assertNotNull(rseqs[2]);
778 Assert.assertNotNull(rseqs[3]);
779 Assert.assertNotNull(rseqs[0].getDatasetSequence());
780 Assert.assertNotNull(rseqs[1].getDatasetSequence());
781 Assert.assertNotNull(rseqs[2].getDatasetSequence());
782 Assert.assertNotNull(rseqs[3].getDatasetSequence());
784 // The Asserts below are expected to fail until the PDB chainCode is
785 // recoverable from a Jalview projects
786 for (int chain = 0; chain < 4; chain++)
788 PDBEntry recov = rseqs[chain].getDatasetSequence().getAllPDBEntries()
790 PDBEntry expected = pdbEntries[chain];
791 Assert.assertEquals(recov.getId(), expected.getId(),
793 Assert.assertEquals(recov.getChainCode(), expected.getChainCode(),
795 Assert.assertEquals(recov.getType(), expected.getType(),
796 "Mismatch PDBEntry 'Type'");
797 Assert.assertNotNull(recov.getFile(),
798 "Recovered PDBEntry should have a non-null file entry");
803 * Configure an alignment and a sub-group each with distinct colour schemes,
804 * Conservation and PID thresholds, and confirm these are restored from the
807 * @throws IOException
809 @Test(groups = { "Functional" })
810 public void testStoreAndRecoverColourThresholds() throws IOException
812 Desktop.instance.closeAll_actionPerformed(null);
813 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
814 "examples/uniref50.fa", DataSourceType.FILE);
816 AlignViewport av = af.getViewport();
817 AlignmentI al = av.getAlignment();
820 * Colour alignment by Buried Index, Above 10% PID, By Conservation 20%
822 av.setColourAppliesToAllGroups(false);
823 af.changeColour_actionPerformed(JalviewColourScheme.Buried.toString());
824 assertTrue(av.getGlobalColourScheme() instanceof BuriedColourScheme);
825 af.abovePIDThreshold_actionPerformed(true);
826 SliderPanel sp = SliderPanel.getSliderPanel();
827 assertFalse(sp.isForConservation());
829 af.conservationMenuItem_actionPerformed(true);
830 sp = SliderPanel.getSliderPanel();
831 assertTrue(sp.isForConservation());
833 ResidueShaderI rs = av.getResidueShading();
834 assertEquals(rs.getThreshold(), 10);
835 assertTrue(rs.conservationApplied());
836 assertEquals(rs.getConservationInc(), 20);
839 * create a group with Strand colouring, 30% Conservation
840 * and 40% PID threshold
842 SequenceGroup sg = new SequenceGroup();
843 sg.addSequence(al.getSequenceAt(0), false);
846 av.setSelectionGroup(sg);
847 PopupMenu popupMenu = new PopupMenu(af.alignPanel, null, null);
848 popupMenu.changeColour_actionPerformed(
849 JalviewColourScheme.Strand.toString());
850 assertTrue(sg.getColourScheme() instanceof StrandColourScheme);
851 assertEquals(al.getGroups().size(), 1);
852 assertSame(al.getGroups().get(0), sg);
853 popupMenu.conservationMenuItem_actionPerformed(true);
854 sp = SliderPanel.getSliderPanel();
855 assertTrue(sp.isForConservation());
857 popupMenu.abovePIDColour_actionPerformed(true);
858 sp = SliderPanel.getSliderPanel();
859 assertFalse(sp.isForConservation());
861 assertTrue(sg.getGroupColourScheme().conservationApplied());
862 assertEquals(sg.getGroupColourScheme().getConservationInc(), 30);
863 assertEquals(sg.getGroupColourScheme().getThreshold(), 40);
866 * save project, close windows, reload project, verify
868 File tfile = File.createTempFile("testStoreAndRecoverColourThresholds",
870 tfile.deleteOnExit();
871 new Jalview2XML(false).saveState(tfile);
872 Desktop.instance.closeAll_actionPerformed(null);
873 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
874 DataSourceType.FILE);
875 Assert.assertNotNull(af, "Failed to reload project");
878 * verify alignment (background) colouring
880 rs = af.getViewport().getResidueShading();
881 assertTrue(rs.getColourScheme() instanceof BuriedColourScheme);
882 assertEquals(rs.getThreshold(), 10);
883 assertTrue(rs.conservationApplied());
884 assertEquals(rs.getConservationInc(), 20);
887 * verify group colouring
889 assertEquals(1, af.getViewport().getAlignment().getGroups().size(), 1);
890 rs = af.getViewport().getAlignment().getGroups().get(0)
891 .getGroupColourScheme();
892 assertTrue(rs.getColourScheme() instanceof StrandColourScheme);
893 assertEquals(rs.getThreshold(), 40);
894 assertTrue(rs.conservationApplied());
895 assertEquals(rs.getConservationInc(), 30);
899 * Test save and reload of feature colour schemes and filter settings
901 * @throws IOException
903 @Test(groups = { "Functional" })
904 public void testSaveLoadFeatureColoursAndFilters() throws IOException
906 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
907 ">Seq1\nACDEFGHIKLM", DataSourceType.PASTE);
908 SequenceI seq1 = af.getViewport().getAlignment().getSequenceAt(0);
911 * add some features to the sequence
914 addFeatures(seq1, "type1", score++);
915 addFeatures(seq1, "type2", score++);
916 addFeatures(seq1, "type3", score++);
917 addFeatures(seq1, "type4", score++);
918 addFeatures(seq1, "type5", score++);
921 * set colour schemes for features
923 FeatureRenderer fr = af.getFeatureRenderer();
924 fr.findAllFeatures(true);
927 fr.setColour("type1", new FeatureColour(Color.red));
930 FeatureColourI byLabel = new FeatureColour();
931 byLabel.setColourByLabel(true);
932 fr.setColour("type2", byLabel);
934 // type3: by score above threshold
935 FeatureColourI byScore = new FeatureColour(null, Color.BLACK,
936 Color.BLUE, null, 1, 10);
937 byScore.setAboveThreshold(true);
938 byScore.setThreshold(2f);
939 fr.setColour("type3", byScore);
941 // type4: by attribute AF
942 FeatureColourI byAF = new FeatureColour();
943 byAF.setColourByLabel(true);
944 byAF.setAttributeName("AF");
945 fr.setColour("type4", byAF);
947 // type5: by attribute CSQ:PolyPhen below threshold
948 FeatureColourI byPolyPhen = new FeatureColour(null, Color.BLACK,
949 Color.BLUE, null, 1, 10);
950 byPolyPhen.setBelowThreshold(true);
951 byPolyPhen.setThreshold(3f);
952 byPolyPhen.setAttributeName("CSQ", "PolyPhen");
953 fr.setColour("type5", byPolyPhen);
956 * set filters for feature types
959 // filter type1 features by (label contains "x")
960 FeatureMatcherSetI filterByX = new FeatureMatcherSet();
961 filterByX.and(FeatureMatcher.byLabel(Condition.Contains, "x"));
962 fr.setFeatureFilter("type1", filterByX);
964 // filter type2 features by (score <= 2.4 and score > 1.1)
965 FeatureMatcherSetI filterByScore = new FeatureMatcherSet();
966 filterByScore.and(FeatureMatcher.byScore(Condition.LE, "2.4"));
967 filterByScore.and(FeatureMatcher.byScore(Condition.GT, "1.1"));
968 fr.setFeatureFilter("type2", filterByScore);
970 // filter type3 features by (AF contains X OR CSQ:PolyPhen != 0)
971 FeatureMatcherSetI filterByXY = new FeatureMatcherSet();
973 .and(FeatureMatcher.byAttribute(Condition.Contains, "X", "AF"));
974 filterByXY.or(FeatureMatcher.byAttribute(Condition.NE, "0", "CSQ",
976 fr.setFeatureFilter("type3", filterByXY);
979 * save as Jalview project
981 File tfile = File.createTempFile("JalviewTest", ".jvp");
982 tfile.deleteOnExit();
983 String filePath = tfile.getAbsolutePath();
984 assertTrue(af.saveAlignment(filePath, FileFormat.Jalview),
985 "Failed to store as a project.");
988 * close current alignment and load the saved project
990 af.closeMenuItem_actionPerformed(true);
992 af = new FileLoader().LoadFileWaitTillLoaded(filePath,
993 DataSourceType.FILE);
994 assertNotNull(af, "Failed to import new project");
997 * verify restored feature colour schemes and filters
999 fr = af.getFeatureRenderer();
1000 FeatureColourI fc = fr.getFeatureStyle("type1");
1001 assertTrue(fc.isSimpleColour());
1002 assertEquals(fc.getColour(), Color.red);
1003 fc = fr.getFeatureStyle("type2");
1004 assertTrue(fc.isColourByLabel());
1005 fc = fr.getFeatureStyle("type3");
1006 assertTrue(fc.isGraduatedColour());
1007 assertNull(fc.getAttributeName());
1008 assertTrue(fc.isAboveThreshold());
1009 assertEquals(fc.getThreshold(), 2f);
1010 fc = fr.getFeatureStyle("type4");
1011 assertTrue(fc.isColourByLabel());
1012 assertTrue(fc.isColourByAttribute());
1013 assertEquals(fc.getAttributeName(), new String[] { "AF" });
1014 fc = fr.getFeatureStyle("type5");
1015 assertTrue(fc.isGraduatedColour());
1016 assertTrue(fc.isColourByAttribute());
1017 assertEquals(fc.getAttributeName(), new String[] { "CSQ", "PolyPhen" });
1018 assertTrue(fc.isBelowThreshold());
1019 assertEquals(fc.getThreshold(), 3f);
1021 assertEquals(fr.getFeatureFilter("type1").toStableString(),
1022 "Label Contains x");
1023 assertEquals(fr.getFeatureFilter("type2").toStableString(),
1024 "(Score LE 2.4) AND (Score GT 1.1)");
1025 assertEquals(fr.getFeatureFilter("type3").toStableString(),
1026 "(AF Contains X) OR (CSQ:PolyPhen NE 0.0)");
1029 private void addFeature(SequenceI seq, String featureType, int score)
1031 SequenceFeature sf = new SequenceFeature(featureType, "desc", 1, 2,
1033 sf.setValue("AF", score);
1034 sf.setValue("CSQ", new HashMap<String, String>()
1037 put("PolyPhen", Integer.toString(score));
1040 seq.addSequenceFeature(sf);
1044 * Adds two features of the given type to the given sequence, also setting the
1045 * score as the value of attribute "AF" and sub-attribute "CSQ:PolyPhen"
1048 * @param featureType
1051 private void addFeatures(SequenceI seq, String featureType, int score)
1053 addFeature(seq, featureType, score++);
1054 addFeature(seq, featureType, score);
1058 * pre 2.11 - jalview 2.10 erroneously created new dataset entries for each
1059 * view (JAL-3171) this test ensures we can import and merge those views
1061 @Test(groups = { "Functional" })
1062 public void testMergeDatasetsforViews() throws IOException
1064 // simple project - two views on one alignment
1065 AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
1066 "examples/testdata/projects/twoViews.jvp", DataSourceType.FILE);
1068 assertTrue(af.getAlignPanels().size() > 1);
1073 * pre 2.11 - jalview 2.10 erroneously created new dataset entries for each
1074 * view (JAL-3171) this test ensures we can import and merge those views This
1075 * is a more complex project
1077 @Test(groups = { "Functional" })
1078 public void testMergeDatasetsforManyViews() throws IOException
1080 Desktop.instance.closeAll_actionPerformed(null);
1082 // complex project - one dataset, several views on several alignments
1083 AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
1084 "examples/testdata/projects/manyViews.jvp",
1085 DataSourceType.FILE);
1088 AlignmentI ds = null;
1089 for (AlignFrame alignFrame : Desktop.getAlignFrames())
1093 ds = verifyDs(alignFrame);
1097 // check that this frame's dataset matches the last
1098 assertTrue(ds == verifyDs(alignFrame));
1103 private AlignmentI verifyDs(AlignFrame af)
1105 AlignmentI ds = null;
1106 for (AlignmentViewPanel ap : af.getAlignPanels())
1110 ds = ap.getAlignment().getDataset();
1114 assertTrue(ap.getAlignment().getDataset() == ds,
1115 "Dataset was not the same for imported 2.10.5 project with several alignment views");
1121 @Test(groups = "Functional")
1122 public void testPcaViewAssociation() throws IOException
1124 Desktop.instance.closeAll_actionPerformed(null);
1125 final String PCAVIEWNAME = "With PCA";
1126 // create a new tempfile
1127 File tempfile = File.createTempFile("jvPCAviewAssoc", "jvp");
1130 String exampleFile = "examples/uniref50.fa";
1131 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
1132 DataSourceType.FILE);
1133 assertNotNull(af, "Didn't read in the example file correctly.");
1134 AlignmentPanel origView = (AlignmentPanel) af.getAlignPanels().get(0);
1135 AlignmentPanel newview = af.newView(PCAVIEWNAME, true);
1136 // create another for good measure
1137 af.newView("Not the PCA View", true);
1138 PCAPanel pcaPanel = new PCAPanel(origView, "BLOSUM62",
1139 new SimilarityParams(true, true, true, false));
1140 // we're in the test exec thread, so we can just run synchronously here
1143 // now switch the linked view
1144 pcaPanel.selectAssociatedView(newview);
1146 assertTrue(pcaPanel.getAlignViewport() == newview.getAlignViewport(),
1147 "PCA should be associated with 'With PCA' view: test is broken");
1149 // now save and reload project
1150 Jalview2XML jv2xml = new jalview.project.Jalview2XML(false);
1152 jv2xml.saveState(tempfile);
1153 assertTrue(jv2xml.errorMessage == null,
1154 "Failed to save dummy project with PCA: test broken");
1158 Desktop.instance.closeAll_actionPerformed(null);
1159 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1160 tempfile.getCanonicalPath(), DataSourceType.FILE);
1161 JInternalFrame[] frames = Desktop.instance.getAllFrames();
1162 // PCA and the tabbed alignment view should be the only two windows on the
1164 assertEquals(frames.length, 2,
1165 "PCA and the tabbed alignment view should be the only two windows on the desktop");
1166 PCAPanel pcaPanel = (PCAPanel) frames[frames[0] == af ? 1 : 0];
1168 AlignmentViewPanel restoredNewView = null;
1169 for (AlignmentViewPanel alignpanel : Desktop.getAlignmentPanels(null))
1171 if (alignpanel.getAlignViewport() == pcaPanel.getAlignViewport())
1173 restoredNewView = alignpanel;
1176 assertEquals(restoredNewView.getViewName(), PCAVIEWNAME);
1178 restoredNewView.getAlignViewport() == pcaPanel
1179 .getAlignViewport(),
1180 "Didn't restore correct view association for the PCA view");