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 af.saveAlignment(tfile, FileFormat.Jalview);
119 assertTrue(af.isSaveAlignmentSuccessful(),
120 "Failed to store as a project.");
121 af.closeMenuItem_actionPerformed(true);
123 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
124 DataSourceType.FILE);
125 assertNotNull(af, "Failed to import new project");
126 int newdsann = countDsAnn(af.getViewport());
127 assertEquals(olddsann, newdsann,
128 "Differing numbers of dataset sequence annotation\nOriginally "
129 + olddsann + " and now " + newdsann);
131 "Read in same number of annotations as originally present ("
136 .getGlobalColourScheme() instanceof RNAHelicesColour,
137 "RNA helices colourscheme was not applied on import.");
140 @Test(groups = { "Functional" })
141 public void testTCoffeeScores() throws Exception
143 String inFile = "examples/uniref50.fa",
144 inAnnot = "examples/uniref50.score_ascii";
145 String tfile = File.createTempFile("JalviewTest", ".jvp")
147 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
148 DataSourceType.FILE);
149 assertNotNull(af, "Didn't read input file " + inFile);
150 af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
151 AlignViewport viewport = af.getViewport();
152 assertSame(viewport.getGlobalColourScheme().getClass(),
153 TCoffeeColourScheme.class, "Didn't set T-coffee colourscheme");
155 ColourSchemeProperty.getColourScheme(viewport,
156 viewport.getAlignment(),
157 viewport.getGlobalColourScheme()
159 "Recognise T-Coffee score from string");
161 af.saveAlignment(tfile, FileFormat.Jalview);
162 assertTrue(af.isSaveAlignmentSuccessful(),
163 "Failed to store as a project.");
164 af.closeMenuItem_actionPerformed(true);
166 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
167 DataSourceType.FILE);
168 assertNotNull(af, "Failed to import new project");
169 assertSame(af.getViewport().getGlobalColourScheme().getClass(),
170 TCoffeeColourScheme.class,
171 "Didn't set T-coffee colourscheme for imported project.");
173 "T-Coffee score shading successfully recovered from project.");
176 @Test(groups = { "Functional" })
177 public void testColourByAnnotScores() throws Exception
179 String inFile = "examples/uniref50.fa",
180 inAnnot = "examples/testdata/uniref50_iupred.jva";
181 String tfile = File.createTempFile("JalviewTest", ".jvp")
183 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
184 DataSourceType.FILE);
185 assertNotNull(af, "Didn't read input file " + inFile);
186 af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
187 AlignmentAnnotation[] aa = af.getViewport().getAlignment()
188 .getSequenceAt(0).getAnnotation("IUPredWS (Short)");
191 aa != null && aa.length > 0,
192 "Didn't find any IUPred annotation to use to shade alignment.");
193 AnnotationColourGradient cs = new AnnotationColourGradient(aa[0], null,
194 AnnotationColourGradient.ABOVE_THRESHOLD);
195 AnnotationColourGradient gcs = new AnnotationColourGradient(aa[0], null,
196 AnnotationColourGradient.BELOW_THRESHOLD);
197 cs.setSeqAssociated(true);
198 gcs.setSeqAssociated(true);
200 SequenceGroup sg = new SequenceGroup();
203 sg.cs.setColourScheme(gcs);
204 af.getViewport().getAlignment().addGroup(sg);
205 sg.addSequence(af.getViewport().getAlignment().getSequenceAt(1), false);
206 sg.addSequence(af.getViewport().getAlignment().getSequenceAt(2), true);
207 af.alignPanel.alignmentChanged();
208 af.saveAlignment(tfile, FileFormat.Jalview);
209 assertTrue(af.isSaveAlignmentSuccessful(),
210 "Failed to store as a project.");
211 af.closeMenuItem_actionPerformed(true);
213 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
214 DataSourceType.FILE);
215 assertNotNull(af, "Failed to import new project");
217 // check for group and alignment colourschemes
219 ColourSchemeI _rcs = af.getViewport().getGlobalColourScheme();
220 ColourSchemeI _rgcs = af.getViewport().getAlignment().getGroups().get(0)
222 assertNotNull(_rcs, "Didn't recover global colourscheme");
223 assertTrue(_rcs instanceof AnnotationColourGradient,
224 "Didn't recover annotation colour global scheme");
225 AnnotationColourGradient __rcs = (AnnotationColourGradient) _rcs;
226 assertTrue(__rcs.isSeqAssociated(),
227 "Annotation colourscheme wasn't sequence associated");
229 boolean diffseqcols = false, diffgseqcols = false;
230 SequenceI[] sqs = af.getViewport().getAlignment().getSequencesArray();
231 for (int p = 0, pSize = af.getViewport().getAlignment()
232 .getWidth(); p < pSize && (!diffseqcols || !diffgseqcols); p++)
234 if (_rcs.findColour(sqs[0].getCharAt(p), p, sqs[0], null, 0f) != _rcs
235 .findColour(sqs[5].getCharAt(p), p, sqs[5], null, 0f))
240 assertTrue(diffseqcols, "Got Different sequence colours");
242 "Per sequence colourscheme (Background) successfully applied and recovered.");
244 assertNotNull(_rgcs, "Didn't recover group colourscheme");
245 assertTrue(_rgcs instanceof AnnotationColourGradient,
246 "Didn't recover annotation colour group colourscheme");
247 __rcs = (AnnotationColourGradient) _rgcs;
248 assertTrue(__rcs.isSeqAssociated(),
249 "Group Annotation colourscheme wasn't sequence associated");
251 for (int p = 0, pSize = af.getViewport().getAlignment()
252 .getWidth(); p < pSize && (!diffseqcols || !diffgseqcols); p++)
254 if (_rgcs.findColour(sqs[1].getCharAt(p), p, sqs[1], null,
255 0f) != _rgcs.findColour(sqs[2].getCharAt(p), p, sqs[2], null,
261 assertTrue(diffgseqcols, "Got Different group sequence colours");
263 "Per sequence (Group) colourscheme successfully applied and recovered.");
266 @Test(groups = { "Functional" })
267 public void gatherViewsHere() throws Exception
269 int origCount = Desktop.getAlignFrames() == null ? 0
270 : Desktop.getAlignFrames().length;
271 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
272 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
273 assertNotNull(af, "Didn't read in the example file correctly.");
274 assertTrue(Desktop.getAlignFrames().length == 1 + origCount,
275 "Didn't gather the views in the example file.");
280 * Test for JAL-2223 - multiple mappings in View Mapping report
284 @Test(groups = { "Functional" })
285 public void noDuplicatePdbMappingsMade() throws Exception
287 StructureImportSettings.setProcessSecondaryStructure(true);
288 StructureImportSettings.setVisibleChainAnnotation(true);
289 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
290 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
291 assertNotNull(af, "Didn't read in the example file correctly.");
293 // locate Jmol viewer
294 // count number of PDB mappings the structure selection manager holds -
295 String pdbFile = af.getCurrentView().getStructureSelectionManager()
296 .findFileForPDBId("1A70");
298 af.getCurrentView().getStructureSelectionManager()
299 .getMapping(pdbFile).length,
300 2, "Expected only two mappings for 1A70");
304 @Test(groups = { "Functional" })
305 public void viewRefPdbAnnotation() throws Exception
307 StructureImportSettings.setProcessSecondaryStructure(true);
308 StructureImportSettings.setVisibleChainAnnotation(true);
309 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
310 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
311 assertNotNull(af, "Didn't read in the example file correctly.");
312 AlignmentViewPanel sps = null;
313 for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
315 if ("Spinach Feredoxin Structure".equals(ap.getViewName()))
321 assertNotNull(sps, "Couldn't find the structure view");
322 AlignmentAnnotation refan = null;
323 for (AlignmentAnnotation ra : sps.getAlignment()
324 .getAlignmentAnnotation())
332 assertNotNull(refan, "Annotation secondary structure not found.");
333 SequenceI sq = sps.getAlignment().findName("1A70|");
334 assertNotNull(sq, "Couldn't find 1a70 null chain");
335 // compare the manually added temperature factor annotation
336 // to the track automatically transferred from the pdb structure on load
337 assertNotNull(sq.getDatasetSequence().getAnnotation(),
338 "1a70 has no annotation");
339 for (AlignmentAnnotation ala : sq.getDatasetSequence().getAnnotation())
341 AlignmentAnnotation alaa;
342 sq.addAlignmentAnnotation(alaa = new AlignmentAnnotation(ala));
343 alaa.adjustForAlignment();
344 if (ala.graph == refan.graph)
346 for (int p = 0; p < ala.annotations.length; p++)
351 assertTrue((alaa.annotations[p] == null
352 && refan.annotations[p] == null)
353 || alaa.annotations[p].value == refan.annotations[p].value,
354 "Mismatch at alignment position " + p);
355 } catch (NullPointerException q)
357 Assert.fail("Mismatch of alignment annotations at position " + p
358 + " Ref seq ann: " + refan.annotations[p]
359 + " alignment " + alaa.annotations[p]);
367 @Test(groups = { "Functional" })
368 public void testCopyViewSettings() throws Exception
370 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
371 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
372 assertNotNull(af, "Didn't read in the example file correctly.");
373 AlignmentViewPanel sps = null, groups = null;
374 for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
376 if ("Spinach Feredoxin Structure".equals(ap.getViewName()))
380 if (ap.getViewName().contains("MAFFT"))
385 assertNotNull(sps, "Couldn't find the structure view");
386 assertNotNull(groups, "Couldn't find the MAFFT view");
388 ViewStyleI structureStyle = sps.getAlignViewport().getViewStyle();
389 ViewStyleI groupStyle = groups.getAlignViewport().getViewStyle();
390 AssertJUnit.assertFalse(structureStyle.sameStyle(groupStyle));
392 groups.getAlignViewport().setViewStyle(structureStyle);
393 AssertJUnit.assertFalse(
394 groupStyle.sameStyle(groups.getAlignViewport().getViewStyle()));
395 Assert.assertTrue(structureStyle
396 .sameStyle(groups.getAlignViewport().getViewStyle()));
401 * test store and recovery of expanded views
405 @Test(groups = { "Functional" }, enabled = true)
406 public void testStoreAndRecoverExpandedviews() throws Exception
408 Desktop.instance.closeAll_actionPerformed(null);
410 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
411 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
412 Assert.assertEquals(Desktop.getAlignFrames().length, 1);
413 String afid = af.getViewport().getSequenceSetId();
415 // check FileLoader returned a reference to the one alignFrame that is
416 // actually on the Desktop
417 assertSame(af, Desktop.getAlignFrameFor(af.getViewport()),
418 "Jalview2XML.loadAlignFrame() didn't return correct AlignFrame reference for multiple view window");
420 Desktop.explodeViews(af);
422 int oldviews = Desktop.getAlignFrames().length;
423 Assert.assertEquals(Desktop.getAlignFrames().length,
424 Desktop.getAlignmentPanels(afid).length);
425 File tfile = File.createTempFile("testStoreAndRecoverExpanded", ".jvp");
428 new Jalview2XML(false).saveState(tfile);
431 Assert.fail("Didn't save the expanded view state", e);
432 } catch (Exception e)
434 Assert.fail("Didn't save the expanded view state", e);
436 Desktop.instance.closeAll_actionPerformed(null);
437 if (Desktop.getAlignFrames() != null)
439 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
441 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
442 DataSourceType.FILE);
443 Assert.assertNotNull(af);
444 Assert.assertEquals(Desktop.getAlignFrames().length,
445 Desktop.getAlignmentPanels(
446 af.getViewport().getSequenceSetId()).length);
448 Desktop.getAlignmentPanels(
449 af.getViewport().getSequenceSetId()).length,
454 * Test save and reload of a project with a different representative sequence
459 @Test(groups = { "Functional" })
460 public void testStoreAndRecoverReferenceSeqSettings() throws Exception
462 Desktop.instance.closeAll_actionPerformed(null);
463 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
464 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
465 assertNotNull(af, "Didn't read in the example file correctly.");
466 String afid = af.getViewport().getSequenceSetId();
468 // remember reference sequence for each panel
469 Map<String, SequenceI> refseqs = new HashMap<>();
472 * mark sequence 2, 3, 4.. in panels 1, 2, 3...
473 * as reference sequence for itself and the preceding sequence
476 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
478 AlignViewportI av = ap.getAlignViewport();
479 AlignmentI alignment = ap.getAlignment();
480 int repIndex = n % alignment.getHeight();
481 SequenceI rep = alignment.getSequenceAt(repIndex);
482 refseqs.put(ap.getViewName(), rep);
484 // code from mark/unmark sequence as reference in jalview.gui.PopupMenu
485 // todo refactor this to an alignment view controller
486 av.setDisplayReferenceSeq(true);
487 av.setColourByReferenceSeq(true);
488 av.getAlignment().setSeqrep(rep);
492 File tfile = File.createTempFile("testStoreAndRecoverReferenceSeq",
496 new Jalview2XML(false).saveState(tfile);
497 } catch (Throwable e)
499 Assert.fail("Didn't save the expanded view state", e);
501 Desktop.instance.closeAll_actionPerformed(null);
502 if (Desktop.getAlignFrames() != null)
504 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
507 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
508 DataSourceType.FILE);
509 afid = af.getViewport().getSequenceSetId();
511 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
513 // check representative
514 AlignmentI alignment = ap.getAlignment();
515 SequenceI rep = alignment.getSeqrep();
516 Assert.assertNotNull(rep,
517 "Couldn't restore sequence representative from project");
518 // can't use a strong equals here, because by definition, the sequence IDs
519 // will be different.
520 // could set vamsas session save/restore flag to preserve IDs across
522 Assert.assertEquals(refseqs.get(ap.getViewName()).toString(),
524 "Representative wasn't the same when recovered.");
525 Assert.assertTrue(ap.getAlignViewport().isDisplayReferenceSeq(),
526 "Display reference sequence view setting not set.");
527 Assert.assertTrue(ap.getAlignViewport().isColourByReferenceSeq(),
528 "Colour By Reference Seq view setting not set.");
532 @Test(groups = { "Functional" })
533 public void testIsVersionStringLaterThan()
536 * No version / development / test / autobuild is leniently assumed to be
539 assertTrue(Jalview2XML.isVersionStringLaterThan(null, null));
540 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", null));
541 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "2.8.3"));
542 assertTrue(Jalview2XML.isVersionStringLaterThan(null,
543 "Development Build"));
544 assertTrue(Jalview2XML.isVersionStringLaterThan(null,
545 "DEVELOPMENT BUILD"));
546 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
547 "Development Build"));
548 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "Test"));
549 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "TEST"));
550 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "Test"));
552 Jalview2XML.isVersionStringLaterThan(null, "Automated Build"));
553 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
555 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
559 * same version returns true i.e. compatible
561 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8", "2.8"));
562 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.3"));
563 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3b1"));
564 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3B1", "2.8.3b1"));
565 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3B1"));
568 * later version returns true
570 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.4"));
571 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.9"));
572 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.9.2"));
573 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8", "2.8.3"));
574 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.3b1"));
577 * earlier version returns false
579 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8"));
580 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.4", "2.8.3"));
581 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3"));
582 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.2b1"));
583 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.0b2", "2.8.0b1"));
587 * Test save and reload of a project with a different sequence group (and
588 * representative sequence) in each view.
592 @Test(groups = { "Functional" })
593 public void testStoreAndRecoverGroupRepSeqs() throws Exception
595 Desktop.instance.closeAll_actionPerformed(null);
596 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
597 "examples/uniref50.fa", DataSourceType.FILE);
598 assertNotNull(af, "Didn't read in the example file correctly.");
599 String afid = af.getViewport().getSequenceSetId();
600 // make a second view of the alignment
601 af.newView_actionPerformed(null);
604 * remember representative and hidden sequences marked
607 Map<String, SequenceI> repSeqs = new HashMap<>();
608 Map<String, List<String>> hiddenSeqNames = new HashMap<>();
611 * mark sequence 2, 3, 4.. in panels 1, 2, 3...
612 * as reference sequence for itself and the preceding sequence
615 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
617 AlignViewportI av = ap.getAlignViewport();
618 AlignmentI alignment = ap.getAlignment();
619 int repIndex = n % alignment.getHeight();
620 // ensure at least one preceding sequence i.e. index >= 1
621 repIndex = Math.max(repIndex, 1);
622 SequenceI repSeq = alignment.getSequenceAt(repIndex);
623 repSeqs.put(ap.getViewName(), repSeq);
624 List<String> hiddenNames = new ArrayList<>();
625 hiddenSeqNames.put(ap.getViewName(), hiddenNames);
628 * have rep sequence represent itself and the one before it
629 * this hides the group (except for the rep seq)
631 SequenceGroup sg = new SequenceGroup();
632 sg.addSequence(repSeq, false);
633 SequenceI precedingSeq = alignment.getSequenceAt(repIndex - 1);
634 sg.addSequence(precedingSeq, false);
635 sg.setSeqrep(repSeq);
636 assertTrue(sg.getSequences().contains(repSeq));
637 assertTrue(sg.getSequences().contains(precedingSeq));
638 av.setSelectionGroup(sg);
639 assertSame(repSeq, sg.getSeqrep());
642 * represent group with sequence adds to a map of hidden rep sequences
643 * (it does not create a group on the alignment)
645 ((AlignmentViewport) av).hideSequences(repSeq, true);
646 assertSame(repSeq, sg.getSeqrep());
647 assertTrue(sg.getSequences().contains(repSeq));
648 assertTrue(sg.getSequences().contains(precedingSeq));
649 assertTrue(alignment.getGroups().isEmpty(), "alignment has groups");
650 Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av
651 .getHiddenRepSequences();
652 assertNotNull(hiddenRepSeqsMap);
653 assertEquals(1, hiddenRepSeqsMap.size());
654 assertSame(sg, hiddenRepSeqsMap.get(repSeq));
655 assertTrue(alignment.getHiddenSequences().isHidden(precedingSeq));
656 assertFalse(alignment.getHiddenSequences().isHidden(repSeq));
657 hiddenNames.add(precedingSeq.getName());
661 File tfile = File.createTempFile("testStoreAndRecoverGroupReps",
665 new Jalview2XML(false).saveState(tfile);
666 } catch (Throwable e)
668 Assert.fail("Didn't save the expanded view state", e);
670 Desktop.instance.closeAll_actionPerformed(null);
671 if (Desktop.getAlignFrames() != null)
673 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
676 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
677 DataSourceType.FILE);
678 afid = af.getViewport().getSequenceSetId();
680 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
682 String viewName = ap.getViewName();
683 AlignViewportI av = ap.getAlignViewport();
684 AlignmentI alignment = ap.getAlignment();
685 List<SequenceGroup> groups = alignment.getGroups();
686 assertNotNull(groups);
687 assertTrue(groups.isEmpty(), "Alignment has groups");
688 Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av
689 .getHiddenRepSequences();
690 assertNotNull(hiddenRepSeqsMap, "No hidden represented sequences");
691 assertEquals(1, hiddenRepSeqsMap.size());
692 assertEquals(repSeqs.get(viewName).getDisplayId(true),
693 hiddenRepSeqsMap.keySet().iterator().next()
694 .getDisplayId(true));
697 * verify hidden sequences in restored panel
699 List<String> hidden = hiddenSeqNames.get(ap.getViewName());
700 HiddenSequences hs = alignment.getHiddenSequences();
701 assertEquals(hidden.size(), hs.getSize(),
702 "wrong number of restored hidden sequences in "
708 * Test save and reload of PDBEntry in Jalview project
712 @Test(groups = { "Functional" })
713 public void testStoreAndRecoverPDBEntry() throws Exception
715 Desktop.instance.closeAll_actionPerformed(null);
716 String exampleFile = "examples/3W5V.pdb";
717 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
718 DataSourceType.FILE);
719 assertNotNull(af, "Didn't read in the example file correctly.");
720 String afid = af.getViewport().getSequenceSetId();
722 AlignmentPanel[] alignPanels = Desktop.getAlignmentPanels(afid);
723 System.out.println();
724 AlignmentViewPanel ap = alignPanels[0];
725 String tfileBase = new File(".").getAbsolutePath().replace(".", "");
726 String testFile = tfileBase + exampleFile;
727 AlignmentI alignment = ap.getAlignment();
728 System.out.println("blah");
729 SequenceI[] seqs = alignment.getSequencesArray();
730 Assert.assertNotNull(seqs[0]);
731 Assert.assertNotNull(seqs[1]);
732 Assert.assertNotNull(seqs[2]);
733 Assert.assertNotNull(seqs[3]);
734 Assert.assertNotNull(seqs[0].getDatasetSequence());
735 Assert.assertNotNull(seqs[1].getDatasetSequence());
736 Assert.assertNotNull(seqs[2].getDatasetSequence());
737 Assert.assertNotNull(seqs[3].getDatasetSequence());
738 PDBEntry[] pdbEntries = new PDBEntry[4];
739 pdbEntries[0] = new PDBEntry("3W5V", "A", Type.PDB, testFile);
740 pdbEntries[1] = new PDBEntry("3W5V", "B", Type.PDB, testFile);
741 pdbEntries[2] = new PDBEntry("3W5V", "C", Type.PDB, testFile);
742 pdbEntries[3] = new PDBEntry("3W5V", "D", Type.PDB, testFile);
744 seqs[0].getDatasetSequence().getAllPDBEntries().get(0),
747 seqs[1].getDatasetSequence().getAllPDBEntries().get(0),
750 seqs[2].getDatasetSequence().getAllPDBEntries().get(0),
753 seqs[3].getDatasetSequence().getAllPDBEntries().get(0),
756 File tfile = File.createTempFile("testStoreAndRecoverPDBEntry", ".jvp");
759 new Jalview2XML(false).saveState(tfile);
760 } catch (Throwable e)
762 Assert.fail("Didn't save the state", e);
764 Desktop.instance.closeAll_actionPerformed(null);
765 if (Desktop.getAlignFrames() != null)
767 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
770 AlignFrame restoredFrame = new FileLoader().LoadFileWaitTillLoaded(
771 tfile.getAbsolutePath(), DataSourceType.FILE);
772 String rfid = restoredFrame.getViewport().getSequenceSetId();
773 AlignmentPanel[] rAlignPanels = Desktop.getAlignmentPanels(rfid);
774 AlignmentViewPanel rap = rAlignPanels[0];
775 AlignmentI rAlignment = rap.getAlignment();
776 System.out.println("blah");
777 SequenceI[] rseqs = rAlignment.getSequencesArray();
778 Assert.assertNotNull(rseqs[0]);
779 Assert.assertNotNull(rseqs[1]);
780 Assert.assertNotNull(rseqs[2]);
781 Assert.assertNotNull(rseqs[3]);
782 Assert.assertNotNull(rseqs[0].getDatasetSequence());
783 Assert.assertNotNull(rseqs[1].getDatasetSequence());
784 Assert.assertNotNull(rseqs[2].getDatasetSequence());
785 Assert.assertNotNull(rseqs[3].getDatasetSequence());
787 // The Asserts below are expected to fail until the PDB chainCode is
788 // recoverable from a Jalview projects
789 for (int chain = 0; chain < 4; chain++)
791 PDBEntry recov = rseqs[chain].getDatasetSequence().getAllPDBEntries()
793 PDBEntry expected = pdbEntries[chain];
794 Assert.assertEquals(recov.getId(), expected.getId(),
796 Assert.assertEquals(recov.getChainCode(), expected.getChainCode(),
798 Assert.assertEquals(recov.getType(), expected.getType(),
799 "Mismatch PDBEntry 'Type'");
800 Assert.assertNotNull(recov.getFile(),
801 "Recovered PDBEntry should have a non-null file entry");
806 * Configure an alignment and a sub-group each with distinct colour schemes,
807 * Conservation and PID thresholds, and confirm these are restored from the
810 * @throws IOException
812 @Test(groups = { "Functional" })
813 public void testStoreAndRecoverColourThresholds() throws IOException
815 Desktop.instance.closeAll_actionPerformed(null);
816 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
817 "examples/uniref50.fa", DataSourceType.FILE);
819 AlignViewport av = af.getViewport();
820 AlignmentI al = av.getAlignment();
823 * Colour alignment by Buried Index, Above 10% PID, By Conservation 20%
825 av.setColourAppliesToAllGroups(false);
826 af.changeColour_actionPerformed(JalviewColourScheme.Buried.toString());
827 assertTrue(av.getGlobalColourScheme() instanceof BuriedColourScheme);
828 af.abovePIDThreshold_actionPerformed(true);
829 SliderPanel sp = SliderPanel.getSliderPanel();
830 assertFalse(sp.isForConservation());
832 af.conservationMenuItem_actionPerformed(true);
833 sp = SliderPanel.getSliderPanel();
834 assertTrue(sp.isForConservation());
836 ResidueShaderI rs = av.getResidueShading();
837 assertEquals(rs.getThreshold(), 10);
838 assertTrue(rs.conservationApplied());
839 assertEquals(rs.getConservationInc(), 20);
842 * create a group with Strand colouring, 30% Conservation
843 * and 40% PID threshold
845 SequenceGroup sg = new SequenceGroup();
846 sg.addSequence(al.getSequenceAt(0), false);
849 av.setSelectionGroup(sg);
850 PopupMenu popupMenu = new PopupMenu(af.alignPanel, null, null);
851 popupMenu.changeColour_actionPerformed(
852 JalviewColourScheme.Strand.toString());
853 assertTrue(sg.getColourScheme() instanceof StrandColourScheme);
854 assertEquals(al.getGroups().size(), 1);
855 assertSame(al.getGroups().get(0), sg);
856 popupMenu.conservationMenuItem_actionPerformed(true);
857 sp = SliderPanel.getSliderPanel();
858 assertTrue(sp.isForConservation());
860 popupMenu.abovePIDColour_actionPerformed(true);
861 sp = SliderPanel.getSliderPanel();
862 assertFalse(sp.isForConservation());
864 assertTrue(sg.getGroupColourScheme().conservationApplied());
865 assertEquals(sg.getGroupColourScheme().getConservationInc(), 30);
866 assertEquals(sg.getGroupColourScheme().getThreshold(), 40);
869 * save project, close windows, reload project, verify
871 File tfile = File.createTempFile("testStoreAndRecoverColourThresholds",
873 tfile.deleteOnExit();
874 new Jalview2XML(false).saveState(tfile);
875 Desktop.instance.closeAll_actionPerformed(null);
876 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
877 DataSourceType.FILE);
878 Assert.assertNotNull(af, "Failed to reload project");
881 * verify alignment (background) colouring
883 rs = af.getViewport().getResidueShading();
884 assertTrue(rs.getColourScheme() instanceof BuriedColourScheme);
885 assertEquals(rs.getThreshold(), 10);
886 assertTrue(rs.conservationApplied());
887 assertEquals(rs.getConservationInc(), 20);
890 * verify group colouring
892 assertEquals(1, af.getViewport().getAlignment().getGroups().size(), 1);
893 rs = af.getViewport().getAlignment().getGroups().get(0)
894 .getGroupColourScheme();
895 assertTrue(rs.getColourScheme() instanceof StrandColourScheme);
896 assertEquals(rs.getThreshold(), 40);
897 assertTrue(rs.conservationApplied());
898 assertEquals(rs.getConservationInc(), 30);
902 * Test save and reload of feature colour schemes and filter settings
904 * @throws IOException
906 @Test(groups = { "Functional" })
907 public void testSaveLoadFeatureColoursAndFilters() throws IOException
909 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
910 ">Seq1\nACDEFGHIKLM", DataSourceType.PASTE);
911 SequenceI seq1 = af.getViewport().getAlignment().getSequenceAt(0);
914 * add some features to the sequence
917 addFeatures(seq1, "type1", score++);
918 addFeatures(seq1, "type2", score++);
919 addFeatures(seq1, "type3", score++);
920 addFeatures(seq1, "type4", score++);
921 addFeatures(seq1, "type5", score++);
924 * set colour schemes for features
926 FeatureRenderer fr = af.getFeatureRenderer();
927 fr.findAllFeatures(true);
930 fr.setColour("type1", new FeatureColour(Color.red));
933 FeatureColourI byLabel = new FeatureColour();
934 byLabel.setColourByLabel(true);
935 fr.setColour("type2", byLabel);
937 // type3: by score above threshold
938 FeatureColourI byScore = new FeatureColour(null, Color.BLACK,
939 Color.BLUE, null, 1, 10);
940 byScore.setAboveThreshold(true);
941 byScore.setThreshold(2f);
942 fr.setColour("type3", byScore);
944 // type4: by attribute AF
945 FeatureColourI byAF = new FeatureColour();
946 byAF.setColourByLabel(true);
947 byAF.setAttributeName("AF");
948 fr.setColour("type4", byAF);
950 // type5: by attribute CSQ:PolyPhen below threshold
951 FeatureColourI byPolyPhen = new FeatureColour(null, Color.BLACK,
952 Color.BLUE, null, 1, 10);
953 byPolyPhen.setBelowThreshold(true);
954 byPolyPhen.setThreshold(3f);
955 byPolyPhen.setAttributeName("CSQ", "PolyPhen");
956 fr.setColour("type5", byPolyPhen);
959 * set filters for feature types
962 // filter type1 features by (label contains "x")
963 FeatureMatcherSetI filterByX = new FeatureMatcherSet();
964 filterByX.and(FeatureMatcher.byLabel(Condition.Contains, "x"));
965 fr.setFeatureFilter("type1", filterByX);
967 // filter type2 features by (score <= 2.4 and score > 1.1)
968 FeatureMatcherSetI filterByScore = new FeatureMatcherSet();
969 filterByScore.and(FeatureMatcher.byScore(Condition.LE, "2.4"));
970 filterByScore.and(FeatureMatcher.byScore(Condition.GT, "1.1"));
971 fr.setFeatureFilter("type2", filterByScore);
973 // filter type3 features by (AF contains X OR CSQ:PolyPhen != 0)
974 FeatureMatcherSetI filterByXY = new FeatureMatcherSet();
976 .and(FeatureMatcher.byAttribute(Condition.Contains, "X", "AF"));
977 filterByXY.or(FeatureMatcher.byAttribute(Condition.NE, "0", "CSQ",
979 fr.setFeatureFilter("type3", filterByXY);
982 * save as Jalview project
984 File tfile = File.createTempFile("JalviewTest", ".jvp");
985 tfile.deleteOnExit();
986 String filePath = tfile.getAbsolutePath();
987 af.saveAlignment(filePath, FileFormat.Jalview);
988 assertTrue(af.isSaveAlignmentSuccessful(),
989 "Failed to store as a project.");
992 * close current alignment and load the saved project
994 af.closeMenuItem_actionPerformed(true);
996 af = new FileLoader().LoadFileWaitTillLoaded(filePath,
997 DataSourceType.FILE);
998 assertNotNull(af, "Failed to import new project");
1001 * verify restored feature colour schemes and filters
1003 fr = af.getFeatureRenderer();
1004 FeatureColourI fc = fr.getFeatureStyle("type1");
1005 assertTrue(fc.isSimpleColour());
1006 assertEquals(fc.getColour(), Color.red);
1007 fc = fr.getFeatureStyle("type2");
1008 assertTrue(fc.isColourByLabel());
1009 fc = fr.getFeatureStyle("type3");
1010 assertTrue(fc.isGraduatedColour());
1011 assertNull(fc.getAttributeName());
1012 assertTrue(fc.isAboveThreshold());
1013 assertEquals(fc.getThreshold(), 2f);
1014 fc = fr.getFeatureStyle("type4");
1015 assertTrue(fc.isColourByLabel());
1016 assertTrue(fc.isColourByAttribute());
1017 assertEquals(fc.getAttributeName(), new String[] { "AF" });
1018 fc = fr.getFeatureStyle("type5");
1019 assertTrue(fc.isGraduatedColour());
1020 assertTrue(fc.isColourByAttribute());
1021 assertEquals(fc.getAttributeName(), new String[] { "CSQ", "PolyPhen" });
1022 assertTrue(fc.isBelowThreshold());
1023 assertEquals(fc.getThreshold(), 3f);
1025 assertEquals(fr.getFeatureFilter("type1").toStableString(),
1026 "Label Contains x");
1027 assertEquals(fr.getFeatureFilter("type2").toStableString(),
1028 "(Score LE 2.4) AND (Score GT 1.1)");
1029 assertEquals(fr.getFeatureFilter("type3").toStableString(),
1030 "(AF Contains X) OR (CSQ:PolyPhen NE 0.0)");
1033 private void addFeature(SequenceI seq, String featureType, int score)
1035 SequenceFeature sf = new SequenceFeature(featureType, "desc", 1, 2,
1037 sf.setValue("AF", score);
1038 sf.setValue("CSQ", new HashMap<String, String>()
1041 put("PolyPhen", Integer.toString(score));
1044 seq.addSequenceFeature(sf);
1048 * Adds two features of the given type to the given sequence, also setting the
1049 * score as the value of attribute "AF" and sub-attribute "CSQ:PolyPhen"
1052 * @param featureType
1055 private void addFeatures(SequenceI seq, String featureType, int score)
1057 addFeature(seq, featureType, score++);
1058 addFeature(seq, featureType, score);
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
1065 @Test(groups = { "Functional" })
1066 public void testMergeDatasetsforViews() throws IOException
1068 // simple project - two views on one alignment
1069 AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
1070 "examples/testdata/projects/twoViews.jvp", DataSourceType.FILE);
1072 assertTrue(af.getAlignPanels().size() > 1);
1077 * pre 2.11 - jalview 2.10 erroneously created new dataset entries for each
1078 * view (JAL-3171) this test ensures we can import and merge those views This
1079 * is a more complex project
1081 @Test(groups = { "Functional" })
1082 public void testMergeDatasetsforManyViews() throws IOException
1084 Desktop.instance.closeAll_actionPerformed(null);
1086 // complex project - one dataset, several views on several alignments
1087 AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
1088 "examples/testdata/projects/manyViews.jvp",
1089 DataSourceType.FILE);
1092 AlignmentI ds = null;
1093 for (AlignFrame alignFrame : Desktop.getAlignFrames())
1097 ds = verifyDs(alignFrame);
1101 // check that this frame's dataset matches the last
1102 assertTrue(ds == verifyDs(alignFrame));
1107 private AlignmentI verifyDs(AlignFrame af)
1109 AlignmentI ds = null;
1110 for (AlignmentViewPanel ap : af.getAlignPanels())
1114 ds = ap.getAlignment().getDataset();
1118 assertTrue(ap.getAlignment().getDataset() == ds,
1119 "Dataset was not the same for imported 2.10.5 project with several alignment views");
1125 @Test(groups = "Functional")
1126 public void testPcaViewAssociation() throws IOException
1128 Desktop.instance.closeAll_actionPerformed(null);
1129 final String PCAVIEWNAME = "With PCA";
1130 // create a new tempfile
1131 File tempfile = File.createTempFile("jvPCAviewAssoc", "jvp");
1134 String exampleFile = "examples/uniref50.fa";
1135 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
1136 DataSourceType.FILE);
1137 assertNotNull(af, "Didn't read in the example file correctly.");
1138 AlignmentPanel origView = (AlignmentPanel) af.getAlignPanels().get(0);
1139 AlignmentPanel newview = af.newView(PCAVIEWNAME, true);
1140 // create another for good measure
1141 af.newView("Not the PCA View", true);
1142 PCAPanel pcaPanel = new PCAPanel(origView, "BLOSUM62",
1143 new SimilarityParams(true, true, true, false));
1144 // we're in the test exec thread, so we can just run synchronously here
1147 // now switch the linked view
1148 pcaPanel.selectAssociatedView(newview);
1150 assertTrue(pcaPanel.getAlignViewport() == newview.getAlignViewport(),
1151 "PCA should be associated with 'With PCA' view: test is broken");
1153 // now save and reload project
1154 Jalview2XML jv2xml = new jalview.project.Jalview2XML(false);
1156 jv2xml.saveState(tempfile);
1157 assertTrue(jv2xml.errorMessage == null,
1158 "Failed to save dummy project with PCA: test broken");
1162 Desktop.instance.closeAll_actionPerformed(null);
1163 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1164 tempfile.getCanonicalPath(), DataSourceType.FILE);
1165 JInternalFrame[] frames = Desktop.instance.getAllFrames();
1166 // PCA and the tabbed alignment view should be the only two windows on the
1168 assertEquals(frames.length, 2,
1169 "PCA and the tabbed alignment view should be the only two windows on the desktop");
1170 PCAPanel pcaPanel = (PCAPanel) frames[frames[0] == af ? 1 : 0];
1172 AlignmentViewPanel restoredNewView = null;
1173 for (AlignmentViewPanel alignpanel : Desktop.getAlignmentPanels(null))
1175 if (alignpanel.getAlignViewport() == pcaPanel.getAlignViewport())
1177 restoredNewView = alignpanel;
1180 assertEquals(restoredNewView.getViewName(), PCAVIEWNAME);
1182 restoredNewView.getAlignViewport() == pcaPanel
1183 .getAlignViewport(),
1184 "Didn't restore correct view association for the PCA view");