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 assertSame(af.getViewport().getGlobalColourScheme().getClass(),
151 TCoffeeColourScheme.class, "Didn't set T-coffee colourscheme");
153 ColourSchemeProperty.getColourScheme(
154 af.getViewport().getAlignment(),
155 af.getViewport().getGlobalColourScheme()
157 "Recognise T-Coffee score from string");
159 assertTrue(af.saveAlignment(tfile, FileFormat.Jalview),
160 "Failed to store as a project.");
161 af.closeMenuItem_actionPerformed(true);
163 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
164 DataSourceType.FILE);
165 assertNotNull(af, "Failed to import new project");
166 assertSame(af.getViewport().getGlobalColourScheme().getClass(),
167 TCoffeeColourScheme.class,
168 "Didn't set T-coffee colourscheme for imported project.");
170 "T-Coffee score shading successfully recovered from project.");
173 @Test(groups = { "Functional" })
174 public void testColourByAnnotScores() throws Exception
176 String inFile = "examples/uniref50.fa",
177 inAnnot = "examples/testdata/uniref50_iupred.jva";
178 String tfile = File.createTempFile("JalviewTest", ".jvp")
180 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
181 DataSourceType.FILE);
182 assertNotNull(af, "Didn't read input file " + inFile);
183 af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
184 AlignmentAnnotation[] aa = af.getViewport().getAlignment()
185 .getSequenceAt(0).getAnnotation("IUPredWS (Short)");
188 aa != null && aa.length > 0,
189 "Didn't find any IUPred annotation to use to shade alignment.");
190 AnnotationColourGradient cs = new AnnotationColourGradient(aa[0], null,
191 AnnotationColourGradient.ABOVE_THRESHOLD);
192 AnnotationColourGradient gcs = new AnnotationColourGradient(aa[0], null,
193 AnnotationColourGradient.BELOW_THRESHOLD);
194 cs.setSeqAssociated(true);
195 gcs.setSeqAssociated(true);
197 SequenceGroup sg = new SequenceGroup();
200 sg.cs.setColourScheme(gcs);
201 af.getViewport().getAlignment().addGroup(sg);
202 sg.addSequence(af.getViewport().getAlignment().getSequenceAt(1), false);
203 sg.addSequence(af.getViewport().getAlignment().getSequenceAt(2), true);
204 af.alignPanel.alignmentChanged();
205 assertTrue(af.saveAlignment(tfile, FileFormat.Jalview),
206 "Failed to store as a project.");
207 af.closeMenuItem_actionPerformed(true);
209 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
210 DataSourceType.FILE);
211 assertNotNull(af, "Failed to import new project");
213 // check for group and alignment colourschemes
215 ColourSchemeI _rcs = af.getViewport().getGlobalColourScheme();
216 ColourSchemeI _rgcs = af.getViewport().getAlignment().getGroups().get(0)
218 assertNotNull(_rcs, "Didn't recover global colourscheme");
219 assertTrue(_rcs instanceof AnnotationColourGradient,
220 "Didn't recover annotation colour global scheme");
221 AnnotationColourGradient __rcs = (AnnotationColourGradient) _rcs;
222 assertTrue(__rcs.isSeqAssociated(),
223 "Annotation colourscheme wasn't sequence associated");
225 boolean diffseqcols = false, diffgseqcols = false;
226 SequenceI[] sqs = af.getViewport().getAlignment().getSequencesArray();
227 for (int p = 0, pSize = af.getViewport().getAlignment()
228 .getWidth(); p < pSize && (!diffseqcols || !diffgseqcols); p++)
230 if (_rcs.findColour(sqs[0].getCharAt(p), p, sqs[0], null, 0f) != _rcs
231 .findColour(sqs[5].getCharAt(p), p, sqs[5], null, 0f))
236 assertTrue(diffseqcols, "Got Different sequence colours");
238 "Per sequence colourscheme (Background) successfully applied and recovered.");
240 assertNotNull(_rgcs, "Didn't recover group colourscheme");
241 assertTrue(_rgcs instanceof AnnotationColourGradient,
242 "Didn't recover annotation colour group colourscheme");
243 __rcs = (AnnotationColourGradient) _rgcs;
244 assertTrue(__rcs.isSeqAssociated(),
245 "Group Annotation colourscheme wasn't sequence associated");
247 for (int p = 0, pSize = af.getViewport().getAlignment()
248 .getWidth(); p < pSize && (!diffseqcols || !diffgseqcols); p++)
250 if (_rgcs.findColour(sqs[1].getCharAt(p), p, sqs[1], null,
251 0f) != _rgcs.findColour(sqs[2].getCharAt(p), p, sqs[2], null,
257 assertTrue(diffgseqcols, "Got Different group sequence colours");
259 "Per sequence (Group) colourscheme successfully applied and recovered.");
262 @Test(groups = { "Functional" })
263 public void gatherViewsHere() throws Exception
265 int origCount = Desktop.getAlignFrames() == null ? 0
266 : Desktop.getAlignFrames().length;
267 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
268 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
269 assertNotNull(af, "Didn't read in the example file correctly.");
270 assertTrue(Desktop.getAlignFrames().length == 1 + origCount,
271 "Didn't gather the views in the example file.");
276 * Test for JAL-2223 - multiple mappings in View Mapping report
280 @Test(groups = { "Functional" })
281 public void noDuplicatePdbMappingsMade() throws Exception
283 StructureImportSettings.setProcessSecondaryStructure(true);
284 StructureImportSettings.setVisibleChainAnnotation(true);
285 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
286 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
287 assertNotNull(af, "Didn't read in the example file correctly.");
289 // locate Jmol viewer
290 // count number of PDB mappings the structure selection manager holds -
291 String pdbFile = af.getCurrentView().getStructureSelectionManager()
292 .findFileForPDBId("1A70");
294 af.getCurrentView().getStructureSelectionManager()
295 .getMapping(pdbFile).length,
296 2, "Expected only two mappings for 1A70");
300 @Test(groups = { "Functional" })
301 public void viewRefPdbAnnotation() throws Exception
303 StructureImportSettings.setProcessSecondaryStructure(true);
304 StructureImportSettings.setVisibleChainAnnotation(true);
305 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
306 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
307 assertNotNull(af, "Didn't read in the example file correctly.");
308 AlignmentViewPanel sps = null;
309 for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
311 if ("Spinach Feredoxin Structure".equals(ap.getViewName()))
317 assertNotNull(sps, "Couldn't find the structure view");
318 AlignmentAnnotation refan = null;
319 for (AlignmentAnnotation ra : sps.getAlignment()
320 .getAlignmentAnnotation())
328 assertNotNull(refan, "Annotation secondary structure not found.");
329 SequenceI sq = sps.getAlignment().findName("1A70|");
330 assertNotNull(sq, "Couldn't find 1a70 null chain");
331 // compare the manually added temperature factor annotation
332 // to the track automatically transferred from the pdb structure on load
333 assertNotNull(sq.getDatasetSequence().getAnnotation(),
334 "1a70 has no annotation");
335 for (AlignmentAnnotation ala : sq.getDatasetSequence().getAnnotation())
337 AlignmentAnnotation alaa;
338 sq.addAlignmentAnnotation(alaa = new AlignmentAnnotation(ala));
339 alaa.adjustForAlignment();
340 if (ala.graph == refan.graph)
342 for (int p = 0; p < ala.annotations.length; p++)
347 assertTrue((alaa.annotations[p] == null
348 && refan.annotations[p] == null)
349 || alaa.annotations[p].value == refan.annotations[p].value,
350 "Mismatch at alignment position " + p);
351 } catch (NullPointerException q)
353 Assert.fail("Mismatch of alignment annotations at position " + p
354 + " Ref seq ann: " + refan.annotations[p]
355 + " alignment " + alaa.annotations[p]);
363 @Test(groups = { "Functional" })
364 public void testCopyViewSettings() throws Exception
366 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
367 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
368 assertNotNull(af, "Didn't read in the example file correctly.");
369 AlignmentViewPanel sps = null, groups = null;
370 for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
372 if ("Spinach Feredoxin Structure".equals(ap.getViewName()))
376 if (ap.getViewName().contains("MAFFT"))
381 assertNotNull(sps, "Couldn't find the structure view");
382 assertNotNull(groups, "Couldn't find the MAFFT view");
384 ViewStyleI structureStyle = sps.getAlignViewport().getViewStyle();
385 ViewStyleI groupStyle = groups.getAlignViewport().getViewStyle();
386 AssertJUnit.assertFalse(structureStyle.sameStyle(groupStyle));
388 groups.getAlignViewport().setViewStyle(structureStyle);
389 AssertJUnit.assertFalse(
390 groupStyle.sameStyle(groups.getAlignViewport().getViewStyle()));
391 Assert.assertTrue(structureStyle
392 .sameStyle(groups.getAlignViewport().getViewStyle()));
397 * test store and recovery of expanded views
401 @Test(groups = { "Functional" }, enabled = true)
402 public void testStoreAndRecoverExpandedviews() throws Exception
404 Desktop.instance.closeAll_actionPerformed(null);
406 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
407 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
408 Assert.assertEquals(Desktop.getAlignFrames().length, 1);
409 String afid = af.getViewport().getSequenceSetId();
411 // check FileLoader returned a reference to the one alignFrame that is
412 // actually on the Desktop
413 assertSame(af, Desktop.getAlignFrameFor(af.getViewport()),
414 "Jalview2XML.loadAlignFrame() didn't return correct AlignFrame reference for multiple view window");
416 Desktop.explodeViews(af);
418 int oldviews = Desktop.getAlignFrames().length;
419 Assert.assertEquals(Desktop.getAlignFrames().length,
420 Desktop.getAlignmentPanels(afid).length);
421 File tfile = File.createTempFile("testStoreAndRecoverExpanded", ".jvp");
424 new Jalview2XML(false).saveState(tfile);
427 Assert.fail("Didn't save the expanded view state", e);
428 } catch (Exception e)
430 Assert.fail("Didn't save the expanded view state", e);
432 Desktop.instance.closeAll_actionPerformed(null);
433 if (Desktop.getAlignFrames() != null)
435 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
437 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
438 DataSourceType.FILE);
439 Assert.assertNotNull(af);
440 Assert.assertEquals(Desktop.getAlignFrames().length,
441 Desktop.getAlignmentPanels(
442 af.getViewport().getSequenceSetId()).length);
444 Desktop.getAlignmentPanels(
445 af.getViewport().getSequenceSetId()).length,
450 * Test save and reload of a project with a different representative sequence
455 @Test(groups = { "Functional" })
456 public void testStoreAndRecoverReferenceSeqSettings() throws Exception
458 Desktop.instance.closeAll_actionPerformed(null);
459 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
460 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
461 assertNotNull(af, "Didn't read in the example file correctly.");
462 String afid = af.getViewport().getSequenceSetId();
464 // remember reference sequence for each panel
465 Map<String, SequenceI> refseqs = new HashMap<>();
468 * mark sequence 2, 3, 4.. in panels 1, 2, 3...
469 * as reference sequence for itself and the preceding sequence
472 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
474 AlignViewportI av = ap.getAlignViewport();
475 AlignmentI alignment = ap.getAlignment();
476 int repIndex = n % alignment.getHeight();
477 SequenceI rep = alignment.getSequenceAt(repIndex);
478 refseqs.put(ap.getViewName(), rep);
480 // code from mark/unmark sequence as reference in jalview.gui.PopupMenu
481 // todo refactor this to an alignment view controller
482 av.setDisplayReferenceSeq(true);
483 av.setColourByReferenceSeq(true);
484 av.getAlignment().setSeqrep(rep);
488 File tfile = File.createTempFile("testStoreAndRecoverReferenceSeq",
492 new Jalview2XML(false).saveState(tfile);
493 } catch (Throwable e)
495 Assert.fail("Didn't save the expanded view state", e);
497 Desktop.instance.closeAll_actionPerformed(null);
498 if (Desktop.getAlignFrames() != null)
500 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
503 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
504 DataSourceType.FILE);
505 afid = af.getViewport().getSequenceSetId();
507 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
509 // check representative
510 AlignmentI alignment = ap.getAlignment();
511 SequenceI rep = alignment.getSeqrep();
512 Assert.assertNotNull(rep,
513 "Couldn't restore sequence representative from project");
514 // can't use a strong equals here, because by definition, the sequence IDs
515 // will be different.
516 // could set vamsas session save/restore flag to preserve IDs across
518 Assert.assertEquals(refseqs.get(ap.getViewName()).toString(),
520 "Representative wasn't the same when recovered.");
521 Assert.assertTrue(ap.getAlignViewport().isDisplayReferenceSeq(),
522 "Display reference sequence view setting not set.");
523 Assert.assertTrue(ap.getAlignViewport().isColourByReferenceSeq(),
524 "Colour By Reference Seq view setting not set.");
528 @Test(groups = { "Functional" })
529 public void testIsVersionStringLaterThan()
532 * No version / development / test / autobuild is leniently assumed to be
535 assertTrue(Jalview2XML.isVersionStringLaterThan(null, null));
536 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", null));
537 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "2.8.3"));
538 assertTrue(Jalview2XML.isVersionStringLaterThan(null,
539 "Development Build"));
540 assertTrue(Jalview2XML.isVersionStringLaterThan(null,
541 "DEVELOPMENT BUILD"));
542 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
543 "Development Build"));
544 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "Test"));
545 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "TEST"));
546 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "Test"));
548 Jalview2XML.isVersionStringLaterThan(null, "Automated Build"));
549 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
551 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
555 * same version returns true i.e. compatible
557 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8", "2.8"));
558 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.3"));
559 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3b1"));
560 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3B1", "2.8.3b1"));
561 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3B1"));
564 * later version returns true
566 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.4"));
567 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.9"));
568 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.9.2"));
569 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8", "2.8.3"));
570 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.3b1"));
573 * earlier version returns false
575 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8"));
576 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.4", "2.8.3"));
577 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3"));
578 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.2b1"));
579 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.0b2", "2.8.0b1"));
583 * Test save and reload of a project with a different sequence group (and
584 * representative sequence) in each view.
588 @Test(groups = { "Functional" })
589 public void testStoreAndRecoverGroupRepSeqs() throws Exception
591 Desktop.instance.closeAll_actionPerformed(null);
592 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
593 "examples/uniref50.fa", DataSourceType.FILE);
594 assertNotNull(af, "Didn't read in the example file correctly.");
595 String afid = af.getViewport().getSequenceSetId();
596 // make a second view of the alignment
597 af.newView_actionPerformed(null);
600 * remember representative and hidden sequences marked
603 Map<String, SequenceI> repSeqs = new HashMap<>();
604 Map<String, List<String>> hiddenSeqNames = new HashMap<>();
607 * mark sequence 2, 3, 4.. in panels 1, 2, 3...
608 * as reference sequence for itself and the preceding sequence
611 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
613 AlignViewportI av = ap.getAlignViewport();
614 AlignmentI alignment = ap.getAlignment();
615 int repIndex = n % alignment.getHeight();
616 // ensure at least one preceding sequence i.e. index >= 1
617 repIndex = Math.max(repIndex, 1);
618 SequenceI repSeq = alignment.getSequenceAt(repIndex);
619 repSeqs.put(ap.getViewName(), repSeq);
620 List<String> hiddenNames = new ArrayList<>();
621 hiddenSeqNames.put(ap.getViewName(), hiddenNames);
624 * have rep sequence represent itself and the one before it
625 * this hides the group (except for the rep seq)
627 SequenceGroup sg = new SequenceGroup();
628 sg.addSequence(repSeq, false);
629 SequenceI precedingSeq = alignment.getSequenceAt(repIndex - 1);
630 sg.addSequence(precedingSeq, false);
631 sg.setSeqrep(repSeq);
632 assertTrue(sg.getSequences().contains(repSeq));
633 assertTrue(sg.getSequences().contains(precedingSeq));
634 av.setSelectionGroup(sg);
635 assertSame(repSeq, sg.getSeqrep());
638 * represent group with sequence adds to a map of hidden rep sequences
639 * (it does not create a group on the alignment)
641 ((AlignmentViewport) av).hideSequences(repSeq, true);
642 assertSame(repSeq, sg.getSeqrep());
643 assertTrue(sg.getSequences().contains(repSeq));
644 assertTrue(sg.getSequences().contains(precedingSeq));
645 assertTrue(alignment.getGroups().isEmpty(), "alignment has groups");
646 Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av
647 .getHiddenRepSequences();
648 assertNotNull(hiddenRepSeqsMap);
649 assertEquals(1, hiddenRepSeqsMap.size());
650 assertSame(sg, hiddenRepSeqsMap.get(repSeq));
651 assertTrue(alignment.getHiddenSequences().isHidden(precedingSeq));
652 assertFalse(alignment.getHiddenSequences().isHidden(repSeq));
653 hiddenNames.add(precedingSeq.getName());
657 File tfile = File.createTempFile("testStoreAndRecoverGroupReps",
661 new Jalview2XML(false).saveState(tfile);
662 } catch (Throwable e)
664 Assert.fail("Didn't save the expanded view state", e);
666 Desktop.instance.closeAll_actionPerformed(null);
667 if (Desktop.getAlignFrames() != null)
669 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
672 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
673 DataSourceType.FILE);
674 afid = af.getViewport().getSequenceSetId();
676 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
678 String viewName = ap.getViewName();
679 AlignViewportI av = ap.getAlignViewport();
680 AlignmentI alignment = ap.getAlignment();
681 List<SequenceGroup> groups = alignment.getGroups();
682 assertNotNull(groups);
683 assertTrue(groups.isEmpty(), "Alignment has groups");
684 Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av
685 .getHiddenRepSequences();
686 assertNotNull(hiddenRepSeqsMap, "No hidden represented sequences");
687 assertEquals(1, hiddenRepSeqsMap.size());
688 assertEquals(repSeqs.get(viewName).getDisplayId(true),
689 hiddenRepSeqsMap.keySet().iterator().next()
690 .getDisplayId(true));
693 * verify hidden sequences in restored panel
695 List<String> hidden = hiddenSeqNames.get(ap.getViewName());
696 HiddenSequences hs = alignment.getHiddenSequences();
697 assertEquals(hidden.size(), hs.getSize(),
698 "wrong number of restored hidden sequences in "
704 * Test save and reload of PDBEntry in Jalview project
708 @Test(groups = { "Functional" })
709 public void testStoreAndRecoverPDBEntry() throws Exception
711 Desktop.instance.closeAll_actionPerformed(null);
712 String exampleFile = "examples/3W5V.pdb";
713 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
714 DataSourceType.FILE);
715 assertNotNull(af, "Didn't read in the example file correctly.");
716 String afid = af.getViewport().getSequenceSetId();
718 AlignmentPanel[] alignPanels = Desktop.getAlignmentPanels(afid);
719 System.out.println();
720 AlignmentViewPanel ap = alignPanels[0];
721 String tfileBase = new File(".").getAbsolutePath().replace(".", "");
722 String testFile = tfileBase + exampleFile;
723 AlignmentI alignment = ap.getAlignment();
724 System.out.println("blah");
725 SequenceI[] seqs = alignment.getSequencesArray();
726 Assert.assertNotNull(seqs[0]);
727 Assert.assertNotNull(seqs[1]);
728 Assert.assertNotNull(seqs[2]);
729 Assert.assertNotNull(seqs[3]);
730 Assert.assertNotNull(seqs[0].getDatasetSequence());
731 Assert.assertNotNull(seqs[1].getDatasetSequence());
732 Assert.assertNotNull(seqs[2].getDatasetSequence());
733 Assert.assertNotNull(seqs[3].getDatasetSequence());
734 PDBEntry[] pdbEntries = new PDBEntry[4];
735 pdbEntries[0] = new PDBEntry("3W5V", "A", Type.PDB, testFile);
736 pdbEntries[1] = new PDBEntry("3W5V", "B", Type.PDB, testFile);
737 pdbEntries[2] = new PDBEntry("3W5V", "C", Type.PDB, testFile);
738 pdbEntries[3] = new PDBEntry("3W5V", "D", Type.PDB, testFile);
740 seqs[0].getDatasetSequence().getAllPDBEntries().get(0),
743 seqs[1].getDatasetSequence().getAllPDBEntries().get(0),
746 seqs[2].getDatasetSequence().getAllPDBEntries().get(0),
749 seqs[3].getDatasetSequence().getAllPDBEntries().get(0),
752 File tfile = File.createTempFile("testStoreAndRecoverPDBEntry", ".jvp");
755 new Jalview2XML(false).saveState(tfile);
756 } catch (Throwable e)
758 Assert.fail("Didn't save the state", e);
760 Desktop.instance.closeAll_actionPerformed(null);
761 if (Desktop.getAlignFrames() != null)
763 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
766 AlignFrame restoredFrame = new FileLoader().LoadFileWaitTillLoaded(
767 tfile.getAbsolutePath(), DataSourceType.FILE);
768 String rfid = restoredFrame.getViewport().getSequenceSetId();
769 AlignmentPanel[] rAlignPanels = Desktop.getAlignmentPanels(rfid);
770 AlignmentViewPanel rap = rAlignPanels[0];
771 AlignmentI rAlignment = rap.getAlignment();
772 System.out.println("blah");
773 SequenceI[] rseqs = rAlignment.getSequencesArray();
774 Assert.assertNotNull(rseqs[0]);
775 Assert.assertNotNull(rseqs[1]);
776 Assert.assertNotNull(rseqs[2]);
777 Assert.assertNotNull(rseqs[3]);
778 Assert.assertNotNull(rseqs[0].getDatasetSequence());
779 Assert.assertNotNull(rseqs[1].getDatasetSequence());
780 Assert.assertNotNull(rseqs[2].getDatasetSequence());
781 Assert.assertNotNull(rseqs[3].getDatasetSequence());
783 // The Asserts below are expected to fail until the PDB chainCode is
784 // recoverable from a Jalview projects
785 for (int chain = 0; chain < 4; chain++)
787 PDBEntry recov = rseqs[chain].getDatasetSequence().getAllPDBEntries()
789 PDBEntry expected = pdbEntries[chain];
790 Assert.assertEquals(recov.getId(), expected.getId(),
792 Assert.assertEquals(recov.getChainCode(), expected.getChainCode(),
794 Assert.assertEquals(recov.getType(), expected.getType(),
795 "Mismatch PDBEntry 'Type'");
796 Assert.assertNotNull(recov.getFile(),
797 "Recovered PDBEntry should have a non-null file entry");
802 * Configure an alignment and a sub-group each with distinct colour schemes,
803 * Conservation and PID thresholds, and confirm these are restored from the
806 * @throws IOException
808 @Test(groups = { "Functional" })
809 public void testStoreAndRecoverColourThresholds() throws IOException
811 Desktop.instance.closeAll_actionPerformed(null);
812 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
813 "examples/uniref50.fa", DataSourceType.FILE);
815 AlignViewport av = af.getViewport();
816 AlignmentI al = av.getAlignment();
819 * Colour alignment by Buried Index, Above 10% PID, By Conservation 20%
821 av.setColourAppliesToAllGroups(false);
822 af.changeColour_actionPerformed(JalviewColourScheme.Buried.toString());
823 assertTrue(av.getGlobalColourScheme() instanceof BuriedColourScheme);
824 af.abovePIDThreshold_actionPerformed(true);
825 SliderPanel sp = SliderPanel.getSliderPanel();
826 assertFalse(sp.isForConservation());
828 af.conservationMenuItem_actionPerformed(true);
829 sp = SliderPanel.getSliderPanel();
830 assertTrue(sp.isForConservation());
832 ResidueShaderI rs = av.getResidueShading();
833 assertEquals(rs.getThreshold(), 10);
834 assertTrue(rs.conservationApplied());
835 assertEquals(rs.getConservationInc(), 20);
838 * create a group with Strand colouring, 30% Conservation
839 * and 40% PID threshold
841 SequenceGroup sg = new SequenceGroup();
842 sg.addSequence(al.getSequenceAt(0), false);
845 av.setSelectionGroup(sg);
846 PopupMenu popupMenu = new PopupMenu(af.alignPanel, null, null);
847 popupMenu.changeColour_actionPerformed(
848 JalviewColourScheme.Strand.toString());
849 assertTrue(sg.getColourScheme() instanceof StrandColourScheme);
850 assertEquals(al.getGroups().size(), 1);
851 assertSame(al.getGroups().get(0), sg);
852 popupMenu.conservationMenuItem_actionPerformed(true);
853 sp = SliderPanel.getSliderPanel();
854 assertTrue(sp.isForConservation());
856 popupMenu.abovePIDColour_actionPerformed(true);
857 sp = SliderPanel.getSliderPanel();
858 assertFalse(sp.isForConservation());
860 assertTrue(sg.getGroupColourScheme().conservationApplied());
861 assertEquals(sg.getGroupColourScheme().getConservationInc(), 30);
862 assertEquals(sg.getGroupColourScheme().getThreshold(), 40);
865 * save project, close windows, reload project, verify
867 File tfile = File.createTempFile("testStoreAndRecoverColourThresholds",
869 tfile.deleteOnExit();
870 new Jalview2XML(false).saveState(tfile);
871 Desktop.instance.closeAll_actionPerformed(null);
872 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
873 DataSourceType.FILE);
874 Assert.assertNotNull(af, "Failed to reload project");
877 * verify alignment (background) colouring
879 rs = af.getViewport().getResidueShading();
880 assertTrue(rs.getColourScheme() instanceof BuriedColourScheme);
881 assertEquals(rs.getThreshold(), 10);
882 assertTrue(rs.conservationApplied());
883 assertEquals(rs.getConservationInc(), 20);
886 * verify group colouring
888 assertEquals(1, af.getViewport().getAlignment().getGroups().size(), 1);
889 rs = af.getViewport().getAlignment().getGroups().get(0)
890 .getGroupColourScheme();
891 assertTrue(rs.getColourScheme() instanceof StrandColourScheme);
892 assertEquals(rs.getThreshold(), 40);
893 assertTrue(rs.conservationApplied());
894 assertEquals(rs.getConservationInc(), 30);
898 * Test save and reload of feature colour schemes and filter settings
900 * @throws IOException
902 @Test(groups = { "Functional" })
903 public void testSaveLoadFeatureColoursAndFilters() throws IOException
905 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
906 ">Seq1\nACDEFGHIKLM", DataSourceType.PASTE);
907 SequenceI seq1 = af.getViewport().getAlignment().getSequenceAt(0);
910 * add some features to the sequence
913 addFeatures(seq1, "type1", score++);
914 addFeatures(seq1, "type2", score++);
915 addFeatures(seq1, "type3", score++);
916 addFeatures(seq1, "type4", score++);
917 addFeatures(seq1, "type5", score++);
920 * set colour schemes for features
922 FeatureRenderer fr = af.getFeatureRenderer();
923 fr.findAllFeatures(true);
926 fr.setColour("type1", new FeatureColour(Color.red));
929 FeatureColourI byLabel = new FeatureColour();
930 byLabel.setColourByLabel(true);
931 fr.setColour("type2", byLabel);
933 // type3: by score above threshold
934 FeatureColourI byScore = new FeatureColour(null, Color.BLACK,
935 Color.BLUE, null, 1, 10);
936 byScore.setAboveThreshold(true);
937 byScore.setThreshold(2f);
938 fr.setColour("type3", byScore);
940 // type4: by attribute AF
941 FeatureColourI byAF = new FeatureColour();
942 byAF.setColourByLabel(true);
943 byAF.setAttributeName("AF");
944 fr.setColour("type4", byAF);
946 // type5: by attribute CSQ:PolyPhen below threshold
947 FeatureColourI byPolyPhen = new FeatureColour(null, Color.BLACK,
948 Color.BLUE, null, 1, 10);
949 byPolyPhen.setBelowThreshold(true);
950 byPolyPhen.setThreshold(3f);
951 byPolyPhen.setAttributeName("CSQ", "PolyPhen");
952 fr.setColour("type5", byPolyPhen);
955 * set filters for feature types
958 // filter type1 features by (label contains "x")
959 FeatureMatcherSetI filterByX = new FeatureMatcherSet();
960 filterByX.and(FeatureMatcher.byLabel(Condition.Contains, "x"));
961 fr.setFeatureFilter("type1", filterByX);
963 // filter type2 features by (score <= 2.4 and score > 1.1)
964 FeatureMatcherSetI filterByScore = new FeatureMatcherSet();
965 filterByScore.and(FeatureMatcher.byScore(Condition.LE, "2.4"));
966 filterByScore.and(FeatureMatcher.byScore(Condition.GT, "1.1"));
967 fr.setFeatureFilter("type2", filterByScore);
969 // filter type3 features by (AF contains X OR CSQ:PolyPhen != 0)
970 FeatureMatcherSetI filterByXY = new FeatureMatcherSet();
972 .and(FeatureMatcher.byAttribute(Condition.Contains, "X", "AF"));
973 filterByXY.or(FeatureMatcher.byAttribute(Condition.NE, "0", "CSQ",
975 fr.setFeatureFilter("type3", filterByXY);
978 * save as Jalview project
980 File tfile = File.createTempFile("JalviewTest", ".jvp");
981 tfile.deleteOnExit();
982 String filePath = tfile.getAbsolutePath();
983 assertTrue(af.saveAlignment(filePath, FileFormat.Jalview),
984 "Failed to store as a project.");
987 * close current alignment and load the saved project
989 af.closeMenuItem_actionPerformed(true);
991 af = new FileLoader().LoadFileWaitTillLoaded(filePath,
992 DataSourceType.FILE);
993 assertNotNull(af, "Failed to import new project");
996 * verify restored feature colour schemes and filters
998 fr = af.getFeatureRenderer();
999 FeatureColourI fc = fr.getFeatureStyle("type1");
1000 assertTrue(fc.isSimpleColour());
1001 assertEquals(fc.getColour(), Color.red);
1002 fc = fr.getFeatureStyle("type2");
1003 assertTrue(fc.isColourByLabel());
1004 fc = fr.getFeatureStyle("type3");
1005 assertTrue(fc.isGraduatedColour());
1006 assertNull(fc.getAttributeName());
1007 assertTrue(fc.isAboveThreshold());
1008 assertEquals(fc.getThreshold(), 2f);
1009 fc = fr.getFeatureStyle("type4");
1010 assertTrue(fc.isColourByLabel());
1011 assertTrue(fc.isColourByAttribute());
1012 assertEquals(fc.getAttributeName(), new String[] { "AF" });
1013 fc = fr.getFeatureStyle("type5");
1014 assertTrue(fc.isGraduatedColour());
1015 assertTrue(fc.isColourByAttribute());
1016 assertEquals(fc.getAttributeName(), new String[] { "CSQ", "PolyPhen" });
1017 assertTrue(fc.isBelowThreshold());
1018 assertEquals(fc.getThreshold(), 3f);
1020 assertEquals(fr.getFeatureFilter("type1").toStableString(),
1021 "Label Contains x");
1022 assertEquals(fr.getFeatureFilter("type2").toStableString(),
1023 "(Score LE 2.4) AND (Score GT 1.1)");
1024 assertEquals(fr.getFeatureFilter("type3").toStableString(),
1025 "(AF Contains X) OR (CSQ:PolyPhen NE 0.0)");
1028 private void addFeature(SequenceI seq, String featureType, int score)
1030 SequenceFeature sf = new SequenceFeature(featureType, "desc", 1, 2,
1032 sf.setValue("AF", score);
1033 sf.setValue("CSQ", new HashMap<String, String>()
1036 put("PolyPhen", Integer.toString(score));
1039 seq.addSequenceFeature(sf);
1043 * Adds two features of the given type to the given sequence, also setting the
1044 * score as the value of attribute "AF" and sub-attribute "CSQ:PolyPhen"
1047 * @param featureType
1050 private void addFeatures(SequenceI seq, String featureType, int score)
1052 addFeature(seq, featureType, score++);
1053 addFeature(seq, featureType, score);
1057 * pre 2.11 - jalview 2.10 erroneously created new dataset entries for each
1058 * view (JAL-3171) this test ensures we can import and merge those views
1060 @Test(groups = { "Functional" })
1061 public void testMergeDatasetsforViews() throws IOException
1063 // simple project - two views on one alignment
1064 AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
1065 "examples/testdata/projects/twoViews.jvp", DataSourceType.FILE);
1067 assertTrue(af.getAlignPanels().size() > 1);
1072 * pre 2.11 - jalview 2.10 erroneously created new dataset entries for each
1073 * view (JAL-3171) this test ensures we can import and merge those views This
1074 * is a more complex project
1076 @Test(groups = { "Functional" })
1077 public void testMergeDatasetsforManyViews() throws IOException
1079 Desktop.instance.closeAll_actionPerformed(null);
1081 // complex project - one dataset, several views on several alignments
1082 AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
1083 "examples/testdata/projects/manyViews.jvp",
1084 DataSourceType.FILE);
1087 AlignmentI ds = null;
1088 for (AlignFrame alignFrame : Desktop.getAlignFrames())
1092 ds = verifyDs(alignFrame);
1096 // check that this frame's dataset matches the last
1097 assertTrue(ds == verifyDs(alignFrame));
1102 private AlignmentI verifyDs(AlignFrame af)
1104 AlignmentI ds = null;
1105 for (AlignmentViewPanel ap : af.getAlignPanels())
1109 ds = ap.getAlignment().getDataset();
1113 assertTrue(ap.getAlignment().getDataset() == ds,
1114 "Dataset was not the same for imported 2.10.5 project with several alignment views");
1120 @Test(groups = "Functional")
1121 public void testPcaViewAssociation() throws IOException
1123 Desktop.instance.closeAll_actionPerformed(null);
1124 final String PCAVIEWNAME = "With PCA";
1125 // create a new tempfile
1126 File tempfile = File.createTempFile("jvPCAviewAssoc", "jvp");
1129 String exampleFile = "examples/uniref50.fa";
1130 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
1131 DataSourceType.FILE);
1132 assertNotNull(af, "Didn't read in the example file correctly.");
1133 AlignmentPanel origView = (AlignmentPanel) af.getAlignPanels().get(0);
1134 AlignmentPanel newview = af.newView(PCAVIEWNAME, true);
1135 // create another for good measure
1136 af.newView("Not the PCA View", true);
1137 PCAPanel pcaPanel = new PCAPanel(origView, "BLOSUM62",
1138 new SimilarityParams(true, true, true, false));
1139 // we're in the test exec thread, so we can just run synchronously here
1142 // now switch the linked view
1143 pcaPanel.selectAssociatedView(newview);
1145 assertTrue(pcaPanel.getAlignViewport() == newview.getAlignViewport(),
1146 "PCA should be associated with 'With PCA' view: test is broken");
1148 // now save and reload project
1149 Jalview2XML jv2xml = new jalview.project.Jalview2XML(false);
1151 jv2xml.saveState(tempfile);
1152 assertTrue(jv2xml.errorMessage == null,
1153 "Failed to save dummy project with PCA: test broken");
1157 Desktop.instance.closeAll_actionPerformed(null);
1158 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1159 tempfile.getCanonicalPath(), DataSourceType.FILE);
1160 JInternalFrame[] frames = Desktop.instance.getAllFrames();
1161 // PCA and the tabbed alignment view should be the only two windows on the
1163 assertEquals(frames.length, 2,
1164 "PCA and the tabbed alignment view should be the only two windows on the desktop");
1165 PCAPanel pcaPanel = (PCAPanel) frames[frames[0] == af ? 1 : 0];
1167 AlignmentViewPanel restoredNewView = null;
1168 for (AlignmentViewPanel alignpanel : Desktop.getAlignmentPanels(null))
1170 if (alignpanel.getAlignViewport() == pcaPanel.getAlignViewport())
1172 restoredNewView = alignpanel;
1175 assertEquals(restoredNewView.getViewName(), PCAVIEWNAME);
1177 restoredNewView.getAlignViewport() == pcaPanel
1178 .getAlignViewport(),
1179 "Didn't restore correct view association for the PCA view");