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(JalviewColourScheme.RNAHelices
115 af.getViewport().getGlobalColourScheme() instanceof RNAHelicesColour,
116 "Couldn't apply RNA helices colourscheme");
117 assertTrue(af.saveAlignment(tfile, FileFormat.Jalview),
118 "Failed to store as a project.");
119 af.closeMenuItem_actionPerformed(true);
121 af = new FileLoader()
122 .LoadFileWaitTillLoaded(tfile, DataSourceType.FILE);
123 assertNotNull(af, "Failed to import new project");
124 int newdsann = countDsAnn(af.getViewport());
125 assertEquals(olddsann, newdsann,
126 "Differing numbers of dataset sequence annotation\nOriginally "
127 + olddsann + " and now " + newdsann);
129 .println("Read in same number of annotations as originally present ("
133 af.getViewport().getGlobalColourScheme() instanceof RNAHelicesColour,
134 "RNA helices colourscheme was not applied on import.");
137 @Test(groups = { "Functional" })
138 public void testTCoffeeScores() throws Exception
140 String inFile = "examples/uniref50.fa", inAnnot = "examples/uniref50.score_ascii";
141 String tfile = File.createTempFile("JalviewTest", ".jvp")
143 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
144 DataSourceType.FILE);
145 assertNotNull(af, "Didn't read input file " + inFile);
146 af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
147 assertSame(af.getViewport().getGlobalColourScheme().getClass(),
148 TCoffeeColourScheme.class, "Didn't set T-coffee colourscheme");
149 assertNotNull(ColourSchemeProperty.getColourScheme(af.getViewport()
150 .getAlignment(), af.getViewport().getGlobalColourScheme()
151 .getSchemeName()), "Recognise T-Coffee score from string");
153 assertTrue(af.saveAlignment(tfile, FileFormat.Jalview),
154 "Failed to store as a project.");
155 af.closeMenuItem_actionPerformed(true);
157 af = new FileLoader()
158 .LoadFileWaitTillLoaded(tfile, DataSourceType.FILE);
159 assertNotNull(af, "Failed to import new project");
160 assertSame(af.getViewport().getGlobalColourScheme().getClass(),
161 TCoffeeColourScheme.class,
162 "Didn't set T-coffee colourscheme for imported project.");
164 .println("T-Coffee score shading successfully recovered from project.");
167 @Test(groups = { "Functional" })
168 public void testColourByAnnotScores() throws Exception
170 String inFile = "examples/uniref50.fa", inAnnot = "examples/testdata/uniref50_iupred.jva";
171 String tfile = File.createTempFile("JalviewTest", ".jvp")
173 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
174 DataSourceType.FILE);
175 assertNotNull(af, "Didn't read input file " + inFile);
176 af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
177 AlignmentAnnotation[] aa = af.getViewport().getAlignment()
178 .getSequenceAt(0).getAnnotation("IUPredWS (Short)");
181 aa != null && aa.length > 0,
182 "Didn't find any IUPred annotation to use to shade alignment.");
183 AnnotationColourGradient cs = new AnnotationColourGradient(aa[0], null,
184 AnnotationColourGradient.ABOVE_THRESHOLD);
185 AnnotationColourGradient gcs = new AnnotationColourGradient(aa[0],
186 null, AnnotationColourGradient.BELOW_THRESHOLD);
187 cs.setSeqAssociated(true);
188 gcs.setSeqAssociated(true);
190 SequenceGroup sg = new SequenceGroup();
193 sg.cs.setColourScheme(gcs);
194 af.getViewport().getAlignment().addGroup(sg);
195 sg.addSequence(af.getViewport().getAlignment().getSequenceAt(1), false);
196 sg.addSequence(af.getViewport().getAlignment().getSequenceAt(2), true);
197 af.alignPanel.alignmentChanged();
198 assertTrue(af.saveAlignment(tfile, FileFormat.Jalview),
199 "Failed to store as a project.");
200 af.closeMenuItem_actionPerformed(true);
202 af = new FileLoader()
203 .LoadFileWaitTillLoaded(tfile, DataSourceType.FILE);
204 assertNotNull(af, "Failed to import new project");
206 // check for group and alignment colourschemes
208 ColourSchemeI _rcs = af.getViewport().getGlobalColourScheme();
209 ColourSchemeI _rgcs = af.getViewport().getAlignment().getGroups()
210 .get(0).getColourScheme();
211 assertNotNull(_rcs, "Didn't recover global colourscheme");
212 assertTrue(_rcs instanceof AnnotationColourGradient,
213 "Didn't recover annotation colour global scheme");
214 AnnotationColourGradient __rcs = (AnnotationColourGradient) _rcs;
215 assertTrue(__rcs.isSeqAssociated(),
216 "Annotation colourscheme wasn't sequence associated");
218 boolean diffseqcols = false, diffgseqcols = false;
219 SequenceI[] sqs = af.getViewport().getAlignment().getSequencesArray();
220 for (int p = 0, pSize = af.getViewport().getAlignment().getWidth(); p < pSize
221 && (!diffseqcols || !diffgseqcols); p++)
223 if (_rcs.findColour(sqs[0].getCharAt(p), p, sqs[0], null, 0f) != _rcs
224 .findColour(sqs[5].getCharAt(p), p, sqs[5], null, 0f))
229 assertTrue(diffseqcols, "Got Different sequence colours");
231 .println("Per sequence colourscheme (Background) successfully applied and recovered.");
233 assertNotNull(_rgcs, "Didn't recover group colourscheme");
234 assertTrue(_rgcs instanceof AnnotationColourGradient,
235 "Didn't recover annotation colour group colourscheme");
236 __rcs = (AnnotationColourGradient) _rgcs;
237 assertTrue(__rcs.isSeqAssociated(),
238 "Group Annotation colourscheme wasn't sequence associated");
240 for (int p = 0, pSize = af.getViewport().getAlignment().getWidth(); p < pSize
241 && (!diffseqcols || !diffgseqcols); p++)
243 if (_rgcs.findColour(sqs[1].getCharAt(p), p, sqs[1], null, 0f) != _rgcs
244 .findColour(sqs[2].getCharAt(p), p, sqs[2], null, 0f))
249 assertTrue(diffgseqcols, "Got Different group sequence colours");
251 .println("Per sequence (Group) colourscheme successfully applied and recovered.");
254 @Test(groups = { "Functional" })
255 public void gatherViewsHere() throws Exception
257 int origCount = Desktop.getAlignFrames() == null ? 0 : Desktop
258 .getAlignFrames().length;
259 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
260 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
261 assertNotNull(af, "Didn't read in the example file correctly.");
262 assertTrue(Desktop.getAlignFrames().length == 1 + origCount,
263 "Didn't gather the views in the example file.");
268 * Test for JAL-2223 - multiple mappings in View Mapping report
272 @Test(groups = { "Functional" })
273 public void noDuplicatePdbMappingsMade() throws Exception
275 StructureImportSettings.setProcessSecondaryStructure(true);
276 StructureImportSettings.setVisibleChainAnnotation(true);
277 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
278 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
279 assertNotNull(af, "Didn't read in the example file correctly.");
281 // locate Jmol viewer
282 // count number of PDB mappings the structure selection manager holds -
283 String pdbFile = af.getCurrentView().getStructureSelectionManager()
284 .findFileForPDBId("1A70");
286 af.getCurrentView().getStructureSelectionManager()
287 .getMapping(pdbFile).length,
288 2, "Expected only two mappings for 1A70");
292 @Test(groups = { "Functional" })
293 public void viewRefPdbAnnotation() throws Exception
295 StructureImportSettings.setProcessSecondaryStructure(true);
296 StructureImportSettings.setVisibleChainAnnotation(true);
297 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
298 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
299 assertNotNull(af, "Didn't read in the example file correctly.");
300 AlignmentViewPanel sps = null;
301 for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
303 if ("Spinach Feredoxin Structure".equals(ap.getViewName()))
309 assertNotNull(sps, "Couldn't find the structure view");
310 AlignmentAnnotation refan = null;
311 for (AlignmentAnnotation ra : sps.getAlignment()
312 .getAlignmentAnnotation())
320 assertNotNull(refan, "Annotation secondary structure not found.");
321 SequenceI sq = sps.getAlignment().findName("1A70|");
322 assertNotNull(sq, "Couldn't find 1a70 null chain");
323 // compare the manually added temperature factor annotation
324 // to the track automatically transferred from the pdb structure on load
325 assertNotNull(sq.getDatasetSequence().getAnnotation(),
326 "1a70 has no annotation");
327 for (AlignmentAnnotation ala : sq.getDatasetSequence().getAnnotation())
329 AlignmentAnnotation alaa;
330 sq.addAlignmentAnnotation(alaa = new AlignmentAnnotation(ala));
331 alaa.adjustForAlignment();
332 if (ala.graph == refan.graph)
334 for (int p = 0; p < ala.annotations.length; p++)
340 (alaa.annotations[p] == null && refan.annotations[p] == null)
341 || alaa.annotations[p].value == refan.annotations[p].value,
342 "Mismatch at alignment position " + p);
343 } catch (NullPointerException q)
345 Assert.fail("Mismatch of alignment annotations at position "
346 + p + " Ref seq ann: " + refan.annotations[p]
347 + " alignment " + alaa.annotations[p]);
355 @Test(groups = { "Functional" })
356 public void testCopyViewSettings() throws Exception
358 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
359 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
360 assertNotNull(af, "Didn't read in the example file correctly.");
361 AlignmentViewPanel sps = null, groups = null;
362 for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
364 if ("Spinach Feredoxin Structure".equals(ap.getViewName()))
368 if (ap.getViewName().contains("MAFFT"))
373 assertNotNull(sps, "Couldn't find the structure view");
374 assertNotNull(groups, "Couldn't find the MAFFT view");
376 ViewStyleI structureStyle = sps.getAlignViewport().getViewStyle();
377 ViewStyleI groupStyle = groups.getAlignViewport().getViewStyle();
378 AssertJUnit.assertFalse(structureStyle.sameStyle(groupStyle));
380 groups.getAlignViewport().setViewStyle(structureStyle);
381 AssertJUnit.assertFalse(groupStyle.sameStyle(groups.getAlignViewport()
383 Assert.assertTrue(structureStyle.sameStyle(groups.getAlignViewport()
389 * test store and recovery of expanded views
393 @Test(groups = { "Functional" }, enabled = true)
394 public void testStoreAndRecoverExpandedviews() throws Exception
396 Desktop.instance.closeAll_actionPerformed(null);
398 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
399 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
400 Assert.assertEquals(Desktop.getAlignFrames().length, 1);
401 String afid = af.getViewport().getSequenceSetId();
403 // check FileLoader returned a reference to the one alignFrame that is
404 // actually on the Desktop
407 Desktop.getAlignFrameFor(af.getViewport()),
408 "Jalview2XML.loadAlignFrame() didn't return correct AlignFrame reference for multiple view window");
410 Desktop.explodeViews(af);
412 int oldviews = Desktop.getAlignFrames().length;
413 Assert.assertEquals(Desktop.getAlignFrames().length,
414 Desktop.getAlignmentPanels(afid).length);
415 File tfile = File.createTempFile("testStoreAndRecoverExpanded", ".jvp");
418 new Jalview2XML(false).saveState(tfile);
421 Assert.fail("Didn't save the expanded view state", e);
422 } catch (Exception e)
424 Assert.fail("Didn't save the expanded view state", e);
426 Desktop.instance.closeAll_actionPerformed(null);
427 if (Desktop.getAlignFrames() != null)
429 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
431 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
432 DataSourceType.FILE);
433 Assert.assertNotNull(af);
435 Desktop.getAlignFrames().length,
436 Desktop.getAlignmentPanels(af.getViewport().getSequenceSetId()).length);
438 Desktop.getAlignmentPanels(af.getViewport().getSequenceSetId()).length,
443 * Test save and reload of a project with a different representative sequence
448 @Test(groups = { "Functional" })
449 public void testStoreAndRecoverReferenceSeqSettings() throws Exception
451 Desktop.instance.closeAll_actionPerformed(null);
452 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
453 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
454 assertNotNull(af, "Didn't read in the example file correctly.");
455 String afid = af.getViewport().getSequenceSetId();
457 // remember reference sequence for each panel
458 Map<String, SequenceI> refseqs = new HashMap<>();
461 * mark sequence 2, 3, 4.. in panels 1, 2, 3...
462 * as reference sequence for itself and the preceding sequence
465 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
467 AlignViewportI av = ap.getAlignViewport();
468 AlignmentI alignment = ap.getAlignment();
469 int repIndex = n % alignment.getHeight();
470 SequenceI rep = alignment.getSequenceAt(repIndex);
471 refseqs.put(ap.getViewName(), rep);
473 // code from mark/unmark sequence as reference in jalview.gui.PopupMenu
474 // todo refactor this to an alignment view controller
475 av.setDisplayReferenceSeq(true);
476 av.setColourByReferenceSeq(true);
477 av.getAlignment().setSeqrep(rep);
481 File tfile = File.createTempFile("testStoreAndRecoverReferenceSeq",
485 new Jalview2XML(false).saveState(tfile);
486 } catch (Throwable e)
488 Assert.fail("Didn't save the expanded view state", e);
490 Desktop.instance.closeAll_actionPerformed(null);
491 if (Desktop.getAlignFrames() != null)
493 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
496 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
497 DataSourceType.FILE);
498 afid = af.getViewport().getSequenceSetId();
500 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
502 // check representative
503 AlignmentI alignment = ap.getAlignment();
504 SequenceI rep = alignment.getSeqrep();
505 Assert.assertNotNull(rep,
506 "Couldn't restore sequence representative from project");
507 // can't use a strong equals here, because by definition, the sequence IDs
508 // will be different.
509 // could set vamsas session save/restore flag to preserve IDs across
511 Assert.assertEquals(refseqs.get(ap.getViewName()).toString(),
513 "Representative wasn't the same when recovered.");
514 Assert.assertTrue(ap.getAlignViewport().isDisplayReferenceSeq(),
515 "Display reference sequence view setting not set.");
516 Assert.assertTrue(ap.getAlignViewport().isColourByReferenceSeq(),
517 "Colour By Reference Seq view setting not set.");
521 @Test(groups = { "Functional" })
522 public void testIsVersionStringLaterThan()
525 * No version / development / test / autobuild is leniently assumed to be
528 assertTrue(Jalview2XML.isVersionStringLaterThan(null, null));
529 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", null));
530 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "2.8.3"));
531 assertTrue(Jalview2XML.isVersionStringLaterThan(null,
532 "Development Build"));
533 assertTrue(Jalview2XML.isVersionStringLaterThan(null,
534 "DEVELOPMENT BUILD"));
535 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
536 "Development Build"));
537 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "Test"));
538 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "TEST"));
539 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "Test"));
540 assertTrue(Jalview2XML
541 .isVersionStringLaterThan(null, "Automated Build"));
542 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
544 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
548 * same version returns true i.e. compatible
550 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8", "2.8"));
551 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.3"));
552 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3b1"));
553 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3B1", "2.8.3b1"));
554 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3B1"));
557 * later version returns true
559 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.4"));
560 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.9"));
561 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.9.2"));
562 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8", "2.8.3"));
563 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.3b1"));
566 * earlier version returns false
568 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8"));
569 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.4", "2.8.3"));
570 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3"));
571 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.2b1"));
572 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.0b2", "2.8.0b1"));
576 * Test save and reload of a project with a different sequence group (and
577 * representative sequence) in each view.
581 @Test(groups = { "Functional" })
582 public void testStoreAndRecoverGroupRepSeqs() throws Exception
584 Desktop.instance.closeAll_actionPerformed(null);
585 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
586 "examples/uniref50.fa", DataSourceType.FILE);
587 assertNotNull(af, "Didn't read in the example file correctly.");
588 String afid = af.getViewport().getSequenceSetId();
589 // make a second view of the alignment
590 af.newView_actionPerformed(null);
593 * remember representative and hidden sequences marked
596 Map<String, SequenceI> repSeqs = new HashMap<>();
597 Map<String, List<String>> hiddenSeqNames = new HashMap<>();
600 * mark sequence 2, 3, 4.. in panels 1, 2, 3...
601 * as reference sequence for itself and the preceding sequence
604 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
606 AlignViewportI av = ap.getAlignViewport();
607 AlignmentI alignment = ap.getAlignment();
608 int repIndex = n % alignment.getHeight();
609 // ensure at least one preceding sequence i.e. index >= 1
610 repIndex = Math.max(repIndex, 1);
611 SequenceI repSeq = alignment.getSequenceAt(repIndex);
612 repSeqs.put(ap.getViewName(), repSeq);
613 List<String> hiddenNames = new ArrayList<>();
614 hiddenSeqNames.put(ap.getViewName(), hiddenNames);
617 * have rep sequence represent itself and the one before it
618 * this hides the group (except for the rep seq)
620 SequenceGroup sg = new SequenceGroup();
621 sg.addSequence(repSeq, false);
622 SequenceI precedingSeq = alignment.getSequenceAt(repIndex - 1);
623 sg.addSequence(precedingSeq, false);
624 sg.setSeqrep(repSeq);
625 assertTrue(sg.getSequences().contains(repSeq));
626 assertTrue(sg.getSequences().contains(precedingSeq));
627 av.setSelectionGroup(sg);
628 assertSame(repSeq, sg.getSeqrep());
631 * represent group with sequence adds to a map of hidden rep sequences
632 * (it does not create a group on the alignment)
634 ((AlignmentViewport) av).hideSequences(repSeq, true);
635 assertSame(repSeq, sg.getSeqrep());
636 assertTrue(sg.getSequences().contains(repSeq));
637 assertTrue(sg.getSequences().contains(precedingSeq));
638 assertTrue(alignment.getGroups().isEmpty(), "alignment has groups");
639 Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av
640 .getHiddenRepSequences();
641 assertNotNull(hiddenRepSeqsMap);
642 assertEquals(1, hiddenRepSeqsMap.size());
643 assertSame(sg, hiddenRepSeqsMap.get(repSeq));
644 assertTrue(alignment.getHiddenSequences().isHidden(precedingSeq));
645 assertFalse(alignment.getHiddenSequences().isHidden(repSeq));
646 hiddenNames.add(precedingSeq.getName());
651 .createTempFile("testStoreAndRecoverGroupReps", ".jvp");
654 new Jalview2XML(false).saveState(tfile);
655 } catch (Throwable e)
657 Assert.fail("Didn't save the expanded view state", e);
659 Desktop.instance.closeAll_actionPerformed(null);
660 if (Desktop.getAlignFrames() != null)
662 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
665 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
666 DataSourceType.FILE);
667 afid = af.getViewport().getSequenceSetId();
669 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
671 String viewName = ap.getViewName();
672 AlignViewportI av = ap.getAlignViewport();
673 AlignmentI alignment = ap.getAlignment();
674 List<SequenceGroup> groups = alignment.getGroups();
675 assertNotNull(groups);
676 assertTrue(groups.isEmpty(), "Alignment has groups");
677 Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av
678 .getHiddenRepSequences();
679 assertNotNull(hiddenRepSeqsMap, "No hidden represented sequences");
680 assertEquals(1, hiddenRepSeqsMap.size());
681 assertEquals(repSeqs.get(viewName).getDisplayId(true),
682 hiddenRepSeqsMap.keySet().iterator().next()
683 .getDisplayId(true));
686 * verify hidden sequences in restored panel
688 List<String> hidden = hiddenSeqNames.get(ap.getViewName());
689 HiddenSequences hs = alignment.getHiddenSequences();
693 "wrong number of restored hidden sequences in "
699 * Test save and reload of PDBEntry in Jalview project
703 @Test(groups = { "Functional" })
704 public void testStoreAndRecoverPDBEntry() throws Exception
706 Desktop.instance.closeAll_actionPerformed(null);
707 String exampleFile = "examples/3W5V.pdb";
708 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
709 DataSourceType.FILE);
710 assertNotNull(af, "Didn't read in the example file correctly.");
711 String afid = af.getViewport().getSequenceSetId();
713 AlignmentPanel[] alignPanels = Desktop.getAlignmentPanels(afid);
714 System.out.println();
715 AlignmentViewPanel ap = alignPanels[0];
716 String tfileBase = new File(".").getAbsolutePath().replace(".", "");
717 String testFile = tfileBase + exampleFile;
718 AlignmentI alignment = ap.getAlignment();
719 System.out.println("blah");
720 SequenceI[] seqs = alignment.getSequencesArray();
721 Assert.assertNotNull(seqs[0]);
722 Assert.assertNotNull(seqs[1]);
723 Assert.assertNotNull(seqs[2]);
724 Assert.assertNotNull(seqs[3]);
725 Assert.assertNotNull(seqs[0].getDatasetSequence());
726 Assert.assertNotNull(seqs[1].getDatasetSequence());
727 Assert.assertNotNull(seqs[2].getDatasetSequence());
728 Assert.assertNotNull(seqs[3].getDatasetSequence());
729 PDBEntry[] pdbEntries = new PDBEntry[4];
730 pdbEntries[0] = new PDBEntry("3W5V", "A", Type.PDB, testFile);
731 pdbEntries[1] = new PDBEntry("3W5V", "B", Type.PDB, testFile);
732 pdbEntries[2] = new PDBEntry("3W5V", "C", Type.PDB, testFile);
733 pdbEntries[3] = new PDBEntry("3W5V", "D", Type.PDB, testFile);
734 Assert.assertEquals(seqs[0].getDatasetSequence().getAllPDBEntries()
735 .get(0), pdbEntries[0]);
736 Assert.assertEquals(seqs[1].getDatasetSequence().getAllPDBEntries()
737 .get(0), pdbEntries[1]);
738 Assert.assertEquals(seqs[2].getDatasetSequence().getAllPDBEntries()
739 .get(0), pdbEntries[2]);
740 Assert.assertEquals(seqs[3].getDatasetSequence().getAllPDBEntries()
741 .get(0), pdbEntries[3]);
743 File tfile = File.createTempFile("testStoreAndRecoverPDBEntry", ".jvp");
746 new Jalview2XML(false).saveState(tfile);
747 } catch (Throwable e)
749 Assert.fail("Didn't save the state", e);
751 Desktop.instance.closeAll_actionPerformed(null);
752 if (Desktop.getAlignFrames() != null)
754 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
757 AlignFrame restoredFrame = new FileLoader().LoadFileWaitTillLoaded(
758 tfile.getAbsolutePath(), DataSourceType.FILE);
759 String rfid = restoredFrame.getViewport().getSequenceSetId();
760 AlignmentPanel[] rAlignPanels = Desktop.getAlignmentPanels(rfid);
761 AlignmentViewPanel rap = rAlignPanels[0];
762 AlignmentI rAlignment = rap.getAlignment();
763 System.out.println("blah");
764 SequenceI[] rseqs = rAlignment.getSequencesArray();
765 Assert.assertNotNull(rseqs[0]);
766 Assert.assertNotNull(rseqs[1]);
767 Assert.assertNotNull(rseqs[2]);
768 Assert.assertNotNull(rseqs[3]);
769 Assert.assertNotNull(rseqs[0].getDatasetSequence());
770 Assert.assertNotNull(rseqs[1].getDatasetSequence());
771 Assert.assertNotNull(rseqs[2].getDatasetSequence());
772 Assert.assertNotNull(rseqs[3].getDatasetSequence());
774 // The Asserts below are expected to fail until the PDB chainCode is
775 // recoverable from a Jalview projects
776 for (int chain = 0; chain < 4; chain++)
778 PDBEntry recov = rseqs[chain].getDatasetSequence().getAllPDBEntries()
780 PDBEntry expected = pdbEntries[chain];
781 Assert.assertEquals(recov.getId(), expected.getId(),
783 Assert.assertEquals(recov.getChainCode(), expected.getChainCode(),
785 Assert.assertEquals(recov.getType(), expected.getType(),
786 "Mismatch PDBEntry 'Type'");
787 Assert.assertNotNull(recov.getFile(),
788 "Recovered PDBEntry should have a non-null file entry");
793 * Configure an alignment and a sub-group each with distinct colour schemes,
794 * Conservation and PID thresholds, and confirm these are restored from the
797 * @throws IOException
799 @Test(groups = { "Functional" })
800 public void testStoreAndRecoverColourThresholds() throws IOException
802 Desktop.instance.closeAll_actionPerformed(null);
803 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
804 "examples/uniref50.fa", DataSourceType.FILE);
806 AlignViewport av = af.getViewport();
807 AlignmentI al = av.getAlignment();
810 * Colour alignment by Buried Index, Above 10% PID, By Conservation 20%
812 af.changeColour_actionPerformed(JalviewColourScheme.Buried.toString());
813 assertTrue(av.getGlobalColourScheme() instanceof BuriedColourScheme);
814 af.abovePIDThreshold_actionPerformed(true);
815 SliderPanel sp = SliderPanel.getSliderPanel();
816 assertFalse(sp.isForConservation());
818 af.conservationMenuItem_actionPerformed(true);
819 sp = SliderPanel.getSliderPanel();
820 assertTrue(sp.isForConservation());
822 ResidueShaderI rs = av.getResidueShading();
823 assertEquals(rs.getThreshold(), 10);
824 assertTrue(rs.conservationApplied());
825 assertEquals(rs.getConservationInc(), 20);
828 * create a group with Strand colouring, 30% Conservation
829 * and 40% PID threshold
831 SequenceGroup sg = new SequenceGroup();
832 sg.addSequence(al.getSequenceAt(0), false);
835 av.setSelectionGroup(sg);
836 PopupMenu popupMenu = new PopupMenu(af.alignPanel, null, null);
837 popupMenu.changeColour_actionPerformed(JalviewColourScheme.Strand
839 assertTrue(sg.getColourScheme() instanceof StrandColourScheme);
840 assertEquals(al.getGroups().size(), 1);
841 assertSame(al.getGroups().get(0), sg);
842 popupMenu.conservationMenuItem_actionPerformed(true);
843 sp = SliderPanel.getSliderPanel();
844 assertTrue(sp.isForConservation());
846 popupMenu.abovePIDColour_actionPerformed(true);
847 sp = SliderPanel.getSliderPanel();
848 assertFalse(sp.isForConservation());
850 assertTrue(sg.getGroupColourScheme().conservationApplied());
851 assertEquals(sg.getGroupColourScheme().getConservationInc(), 30);
852 assertEquals(sg.getGroupColourScheme().getThreshold(), 40);
855 * save project, close windows, reload project, verify
857 File tfile = File.createTempFile("testStoreAndRecoverColourThresholds",
859 tfile.deleteOnExit();
860 new Jalview2XML(false).saveState(tfile);
861 Desktop.instance.closeAll_actionPerformed(null);
862 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
863 DataSourceType.FILE);
864 Assert.assertNotNull(af, "Failed to reload project");
867 * verify alignment (background) colouring
869 rs = af.getViewport().getResidueShading();
870 assertTrue(rs.getColourScheme() instanceof BuriedColourScheme);
871 assertEquals(rs.getThreshold(), 10);
872 assertTrue(rs.conservationApplied());
873 assertEquals(rs.getConservationInc(), 20);
876 * verify group colouring
878 assertEquals(1, af.getViewport().getAlignment().getGroups().size(), 1);
879 rs = af.getViewport().getAlignment().getGroups().get(0)
880 .getGroupColourScheme();
881 assertTrue(rs.getColourScheme() instanceof StrandColourScheme);
882 assertEquals(rs.getThreshold(), 40);
883 assertTrue(rs.conservationApplied());
884 assertEquals(rs.getConservationInc(), 30);
888 * Test save and reload of feature colour schemes and filter settings
890 * @throws IOException
892 @Test(groups = { "Functional" })
893 public void testSaveLoadFeatureColoursAndFilters() throws IOException
895 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
896 ">Seq1\nACDEFGHIKLM", DataSourceType.PASTE);
897 SequenceI seq1 = af.getViewport().getAlignment().getSequenceAt(0);
900 * add some features to the sequence
903 addFeatures(seq1, "type1", score++);
904 addFeatures(seq1, "type2", score++);
905 addFeatures(seq1, "type3", score++);
906 addFeatures(seq1, "type4", score++);
907 addFeatures(seq1, "type5", score++);
910 * set colour schemes for features
912 FeatureRenderer fr = af.getFeatureRenderer();
913 fr.findAllFeatures(true);
916 fr.setColour("type1", new FeatureColour(Color.red));
919 FeatureColourI byLabel = new FeatureColour();
920 byLabel.setColourByLabel(true);
921 fr.setColour("type2", byLabel);
923 // type3: by score above threshold
924 FeatureColourI byScore = new FeatureColour(Color.BLACK, Color.BLUE, 1,
926 byScore.setAboveThreshold(true);
927 byScore.setThreshold(2f);
928 fr.setColour("type3", byScore);
930 // type4: by attribute AF
931 FeatureColourI byAF = new FeatureColour();
932 byAF.setColourByLabel(true);
933 byAF.setAttributeName("AF");
934 fr.setColour("type4", byAF);
936 // type5: by attribute CSQ:PolyPhen below threshold
937 FeatureColourI byPolyPhen = new FeatureColour(Color.BLACK, Color.BLUE,
939 byPolyPhen.setBelowThreshold(true);
940 byPolyPhen.setThreshold(3f);
941 byPolyPhen.setAttributeName("CSQ", "PolyPhen");
942 fr.setColour("type5", byPolyPhen);
945 * set filters for feature types
948 // filter type1 features by (label contains "x")
949 FeatureMatcherSetI filterByX = new FeatureMatcherSet();
950 filterByX.and(FeatureMatcher.byLabel(Condition.Contains, "x"));
951 fr.setFeatureFilter("type1", filterByX);
953 // filter type2 features by (score <= 2.4 and score > 1.1)
954 FeatureMatcherSetI filterByScore = new FeatureMatcherSet();
955 filterByScore.and(FeatureMatcher.byScore(Condition.LE, "2.4"));
956 filterByScore.and(FeatureMatcher.byScore(Condition.GT, "1.1"));
957 fr.setFeatureFilter("type2", filterByScore);
959 // filter type3 features by (AF contains X OR CSQ:PolyPhen != 0)
960 FeatureMatcherSetI filterByXY = new FeatureMatcherSet();
962 .and(FeatureMatcher.byAttribute(Condition.Contains, "X", "AF"));
963 filterByXY.or(FeatureMatcher.byAttribute(Condition.NE, "0", "CSQ",
965 fr.setFeatureFilter("type3", filterByXY);
968 * save as Jalview project
970 File tfile = File.createTempFile("JalviewTest", ".jvp");
971 tfile.deleteOnExit();
972 String filePath = tfile.getAbsolutePath();
973 assertTrue(af.saveAlignment(filePath, FileFormat.Jalview),
974 "Failed to store as a project.");
977 * close current alignment and load the saved project
979 af.closeMenuItem_actionPerformed(true);
981 af = new FileLoader()
982 .LoadFileWaitTillLoaded(filePath, DataSourceType.FILE);
983 assertNotNull(af, "Failed to import new project");
986 * verify restored feature colour schemes and filters
988 fr = af.getFeatureRenderer();
989 FeatureColourI fc = fr.getFeatureStyle("type1");
990 assertTrue(fc.isSimpleColour());
991 assertEquals(fc.getColour(), Color.red);
992 fc = fr.getFeatureStyle("type2");
993 assertTrue(fc.isColourByLabel());
994 fc = fr.getFeatureStyle("type3");
995 assertTrue(fc.isGraduatedColour());
996 assertNull(fc.getAttributeName());
997 assertTrue(fc.isAboveThreshold());
998 assertEquals(fc.getThreshold(), 2f);
999 fc = fr.getFeatureStyle("type4");
1000 assertTrue(fc.isColourByLabel());
1001 assertTrue(fc.isColourByAttribute());
1002 assertEquals(fc.getAttributeName(), new String[] { "AF" });
1003 fc = fr.getFeatureStyle("type5");
1004 assertTrue(fc.isGraduatedColour());
1005 assertTrue(fc.isColourByAttribute());
1006 assertEquals(fc.getAttributeName(), new String[] { "CSQ", "PolyPhen" });
1007 assertTrue(fc.isBelowThreshold());
1008 assertEquals(fc.getThreshold(), 3f);
1010 assertEquals(fr.getFeatureFilter("type1").toStableString(),
1011 "Label Contains x");
1012 assertEquals(fr.getFeatureFilter("type2").toStableString(),
1013 "(Score LE 2.4) AND (Score GT 1.1)");
1014 assertEquals(fr.getFeatureFilter("type3").toStableString(),
1015 "(AF Contains X) OR (CSQ:PolyPhen NE 0.0)");
1018 private void addFeature(SequenceI seq, String featureType, int score)
1020 SequenceFeature sf = new SequenceFeature(featureType, "desc", 1, 2,
1022 sf.setValue("AF", score);
1023 sf.setValue("CSQ", new HashMap<String, String>()
1026 put("PolyPhen", Integer.toString(score));
1029 seq.addSequenceFeature(sf);
1033 * Adds two features of the given type to the given sequence, also setting the
1034 * score as the value of attribute "AF" and sub-attribute "CSQ:PolyPhen"
1037 * @param featureType
1040 private void addFeatures(SequenceI seq, String featureType, int score)
1042 addFeature(seq, featureType, score++);
1043 addFeature(seq, featureType, score);
1047 * pre 2.11 - jalview 2.10 erroneously created new dataset entries for each
1048 * view (JAL-3171) this test ensures we can import and merge those views
1050 @Test(groups = { "Functional" })
1051 public void testMergeDatasetsforViews() throws IOException
1053 // simple project - two views on one alignment
1054 AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
1055 "examples/testdata/projects/twoViews.jvp", DataSourceType.FILE);
1057 assertTrue(af.getAlignPanels().size() > 1);
1062 * pre 2.11 - jalview 2.10 erroneously created new dataset entries for each
1063 * view (JAL-3171) this test ensures we can import and merge those views This
1064 * is a more complex project
1066 @Test(groups = { "Functional" })
1067 public void testMergeDatasetsforManyViews() throws IOException
1069 Desktop.instance.closeAll_actionPerformed(null);
1071 // complex project - one dataset, several views on several alignments
1072 AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
1073 "examples/testdata/projects/manyViews.jvp",
1074 DataSourceType.FILE);
1077 AlignmentI ds = null;
1078 for (AlignFrame alignFrame : Desktop.getAlignFrames())
1082 ds = verifyDs(alignFrame);
1086 // check that this frame's dataset matches the last
1087 assertTrue(ds == verifyDs(alignFrame));
1092 private AlignmentI verifyDs(AlignFrame af)
1094 AlignmentI ds = null;
1095 for (AlignmentViewPanel ap : af.getAlignPanels())
1099 ds = ap.getAlignment().getDataset();
1103 assertTrue(ap.getAlignment().getDataset() == ds,
1104 "Dataset was not the same for imported 2.10.5 project with several alignment views");
1110 @Test(groups = "Functional")
1111 public void testPcaViewAssociation() throws IOException
1113 Desktop.instance.closeAll_actionPerformed(null);
1114 final String PCAVIEWNAME = "With PCA";
1115 // create a new tempfile
1116 File tempfile = File.createTempFile("jvPCAviewAssoc", "jvp");
1119 String exampleFile = "examples/uniref50.fa";
1120 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
1121 DataSourceType.FILE);
1122 assertNotNull(af, "Didn't read in the example file correctly.");
1123 AlignmentPanel newview = af.newView(PCAVIEWNAME, true);
1124 // create another for good measure
1125 af.newView("Not the PCA View", true);
1126 PCAPanel pcaPanel = new PCAPanel(newview, "BLOSUM62",
1127 new SimilarityParams(true, true, true, false));
1129 // we're in the test exec thread, so we can just run synchronously here
1132 assertTrue(pcaPanel.getAlignViewport() == newview.getAlignViewport(),
1133 "PCA should be associated with 'With PCA' view: test is broken");
1135 // now save and reload project
1136 Jalview2XML jv2xml = new jalview.project.Jalview2XML(false);
1138 jv2xml.saveState(tempfile);
1139 assertTrue(jv2xml.errorMessage == null,
1140 "Failed to save dummy project with PCA: test broken");
1144 Desktop.instance.closeAll_actionPerformed(null);
1145 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1146 tempfile.getCanonicalPath(), DataSourceType.FILE);
1147 JInternalFrame[] frames = Desktop.instance.getAllFrames();
1148 // PCA and the tabbed alignment view should be the only two windows on the
1150 assertEquals(frames.length, 2,
1151 "PCA and the tabbed alignment view should be the only two windows on the desktop");
1152 PCAPanel pcaPanel = (PCAPanel) frames[frames[0] == af ? 1 : 0];
1154 AlignmentViewPanel restoredNewView = af.getAlignPanels().get(1);
1155 assertEquals(restoredNewView.getViewName(), PCAVIEWNAME);
1157 restoredNewView.getAlignViewport() == pcaPanel
1158 .getAlignViewport(),
1159 "Didn't restore correct view association for the PCA view");