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.HiddenMarkovModel;
38 import jalview.datamodel.HiddenSequences;
39 import jalview.datamodel.Mapping;
40 import jalview.datamodel.PDBEntry;
41 import jalview.datamodel.PDBEntry.Type;
42 import jalview.datamodel.SequenceCollectionI;
43 import jalview.datamodel.SequenceFeature;
44 import jalview.datamodel.SequenceGroup;
45 import jalview.datamodel.SequenceI;
46 import jalview.datamodel.features.FeatureMatcher;
47 import jalview.datamodel.features.FeatureMatcherSet;
48 import jalview.datamodel.features.FeatureMatcherSetI;
49 import jalview.gui.AlignFrame;
50 import jalview.gui.AlignmentPanel;
51 import jalview.gui.Desktop;
52 import jalview.gui.FeatureRenderer;
53 import jalview.gui.JvOptionPane;
54 import jalview.gui.PCAPanel;
55 import jalview.gui.PopupMenu;
56 import jalview.gui.SliderPanel;
57 import jalview.io.DataSourceType;
58 import jalview.io.FileFormat;
59 import jalview.io.FileLoader;
60 import jalview.io.Jalview2xmlBase;
61 import jalview.renderer.ResidueShaderI;
62 import jalview.schemes.AnnotationColourGradient;
63 import jalview.schemes.BuriedColourScheme;
64 import jalview.schemes.ColourSchemeI;
65 import jalview.schemes.ColourSchemeProperty;
66 import jalview.schemes.FeatureColour;
67 import jalview.schemes.JalviewColourScheme;
68 import jalview.schemes.RNAHelicesColour;
69 import jalview.schemes.StrandColourScheme;
70 import jalview.schemes.TCoffeeColourScheme;
71 import jalview.structure.StructureImportSettings;
72 import jalview.util.matcher.Condition;
73 import jalview.viewmodel.AlignmentViewport;
75 import java.awt.Color;
77 import java.io.IOException;
78 import java.util.ArrayList;
79 import java.util.HashMap;
80 import java.util.List;
83 import javax.swing.JInternalFrame;
85 import org.testng.Assert;
86 import org.testng.AssertJUnit;
87 import org.testng.annotations.BeforeClass;
88 import org.testng.annotations.Test;
90 import junit.extensions.PA;
92 @Test(singleThreaded = true)
93 public class Jalview2xmlTests extends Jalview2xmlBase
97 @BeforeClass(alwaysRun = true)
98 public void setUpJvOptionPane()
100 JvOptionPane.setInteractiveMode(false);
101 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
104 @Test(groups = { "Functional" })
105 public void testRNAStructureRecovery() throws Exception
107 String inFile = "examples/RF00031_folded.stk";
108 String tfile = File.createTempFile("JalviewTest", ".jvp")
110 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
111 DataSourceType.FILE);
112 assertNotNull(af, "Didn't read input file " + inFile);
113 int olddsann = countDsAnn(af.getViewport());
114 assertTrue(olddsann > 0, "Didn't find any dataset annotations");
115 af.changeColour_actionPerformed(
116 JalviewColourScheme.RNAHelices.toString());
119 .getGlobalColourScheme() instanceof RNAHelicesColour,
120 "Couldn't apply RNA helices colourscheme");
121 assertTrue(af.saveAlignment(tfile, FileFormat.Jalview),
122 "Failed to store as a project.");
123 af.closeMenuItem_actionPerformed(true);
125 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
126 DataSourceType.FILE);
127 assertNotNull(af, "Failed to import new project");
128 int newdsann = countDsAnn(af.getViewport());
129 assertEquals(olddsann, newdsann,
130 "Differing numbers of dataset sequence annotation\nOriginally "
131 + olddsann + " and now " + newdsann);
133 "Read in same number of annotations as originally present ("
138 .getGlobalColourScheme() instanceof RNAHelicesColour,
139 "RNA helices colourscheme was not applied on import.");
142 @Test(groups = { "Functional" })
143 public void testTCoffeeScores() throws Exception
145 String inFile = "examples/uniref50.fa",
146 inAnnot = "examples/uniref50.score_ascii";
147 String tfile = File.createTempFile("JalviewTest", ".jvp")
149 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
150 DataSourceType.FILE);
151 assertNotNull(af, "Didn't read input file " + inFile);
152 af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
153 AlignViewport viewport = af.getViewport();
154 assertSame(viewport.getGlobalColourScheme().getClass(),
155 TCoffeeColourScheme.class, "Didn't set T-coffee colourscheme");
157 ColourSchemeProperty.getColourScheme(viewport,
158 viewport.getAlignment(),
159 viewport.getGlobalColourScheme()
161 "Recognise T-Coffee score from string");
163 assertTrue(af.saveAlignment(tfile, FileFormat.Jalview),
164 "Failed to store as a project.");
165 af.closeMenuItem_actionPerformed(true);
167 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
168 DataSourceType.FILE);
169 assertNotNull(af, "Failed to import new project");
170 assertSame(af.getViewport().getGlobalColourScheme().getClass(),
171 TCoffeeColourScheme.class,
172 "Didn't set T-coffee colourscheme for imported project.");
174 "T-Coffee score shading successfully recovered from project.");
177 @Test(groups = { "Functional" })
178 public void testColourByAnnotScores() throws Exception
180 String inFile = "examples/uniref50.fa",
181 inAnnot = "examples/testdata/uniref50_iupred.jva";
182 String tfile = File.createTempFile("JalviewTest", ".jvp")
184 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
185 DataSourceType.FILE);
186 assertNotNull(af, "Didn't read input file " + inFile);
187 af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
188 AlignmentAnnotation[] aa = af.getViewport().getAlignment()
189 .getSequenceAt(0).getAnnotation("IUPredWS (Short)");
192 aa != null && aa.length > 0,
193 "Didn't find any IUPred annotation to use to shade alignment.");
194 AnnotationColourGradient cs = new AnnotationColourGradient(aa[0], null,
195 AnnotationColourGradient.ABOVE_THRESHOLD);
196 AnnotationColourGradient gcs = new AnnotationColourGradient(aa[0], null,
197 AnnotationColourGradient.BELOW_THRESHOLD);
198 cs.setSeqAssociated(true);
199 gcs.setSeqAssociated(true);
201 SequenceGroup sg = new SequenceGroup();
204 sg.cs.setColourScheme(gcs);
205 af.getViewport().getAlignment().addGroup(sg);
206 sg.addSequence(af.getViewport().getAlignment().getSequenceAt(1), false);
207 sg.addSequence(af.getViewport().getAlignment().getSequenceAt(2), true);
208 af.alignPanel.alignmentChanged();
209 assertTrue(af.saveAlignment(tfile, FileFormat.Jalview),
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 AlignViewportI 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 testStoreAndRecoverFeatureColoursAndFilters()
910 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
911 ">Seq1\nACDEFGHIKLM", DataSourceType.PASTE);
912 SequenceI seq1 = af.getViewport().getAlignment().getSequenceAt(0);
915 * add some features to the sequence
918 addFeatures(seq1, "type1", score++);
919 addFeatures(seq1, "type2", score++);
920 addFeatures(seq1, "type3", score++);
921 addFeatures(seq1, "type4", score++);
922 addFeatures(seq1, "type5", score++);
925 * set colour schemes for features
927 FeatureRenderer fr = af.getFeatureRenderer();
928 fr.findAllFeatures(true);
931 fr.setColour("type1", new FeatureColour(Color.red));
934 FeatureColourI byLabel = new FeatureColour();
935 byLabel.setColourByLabel(true);
936 fr.setColour("type2", byLabel);
938 // type3: by score above threshold
939 FeatureColourI byScore = new FeatureColour(null, Color.BLACK,
940 Color.BLUE, null, 1, 10);
941 byScore.setAboveThreshold(true);
942 byScore.setThreshold(2f);
943 fr.setColour("type3", byScore);
945 // type4: by attribute AF
946 FeatureColourI byAF = new FeatureColour();
947 byAF.setColourByLabel(true);
948 byAF.setAttributeName("AF");
949 fr.setColour("type4", byAF);
951 // type5: by attribute CSQ:PolyPhen below threshold
952 FeatureColourI byPolyPhen = new FeatureColour(null, Color.BLACK,
953 Color.BLUE, null, 1, 10);
954 byPolyPhen.setBelowThreshold(true);
955 byPolyPhen.setThreshold(3f);
956 byPolyPhen.setAttributeName("CSQ", "PolyPhen");
957 fr.setColour("type5", byPolyPhen);
960 * set filters for feature types
963 // filter type1 features by (label contains "x")
964 FeatureMatcherSetI filterByX = new FeatureMatcherSet();
965 filterByX.and(FeatureMatcher.byLabel(Condition.Contains, "x"));
966 fr.setFeatureFilter("type1", filterByX);
968 // filter type2 features by (score <= 2.4 and score > 1.1)
969 FeatureMatcherSetI filterByScore = new FeatureMatcherSet();
970 filterByScore.and(FeatureMatcher.byScore(Condition.LE, "2.4"));
971 filterByScore.and(FeatureMatcher.byScore(Condition.GT, "1.1"));
972 fr.setFeatureFilter("type2", filterByScore);
974 // filter type3 features by (AF contains X OR CSQ:PolyPhen != 0)
975 FeatureMatcherSetI filterByXY = new FeatureMatcherSet();
977 .and(FeatureMatcher.byAttribute(Condition.Contains, "X", "AF"));
978 filterByXY.or(FeatureMatcher.byAttribute(Condition.NE, "0", "CSQ",
980 fr.setFeatureFilter("type3", filterByXY);
983 * save as Jalview project
985 File tfile = File.createTempFile("JalviewTest", ".jvp");
986 tfile.deleteOnExit();
987 String filePath = tfile.getAbsolutePath();
988 assertTrue(af.saveAlignment(filePath, FileFormat.Jalview),
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 * Load an HMM profile to an alignment, and confirm it is correctly restored
1063 * when reloaded from project
1065 * @throws IOException
1067 @Test(groups = { "Functional" })
1068 public void testStoreAndRecoverHmmProfile() throws IOException
1070 Desktop.instance.closeAll_actionPerformed(null);
1071 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1072 "examples/uniref50.fa", DataSourceType.FILE);
1074 AlignViewportI av = af.getViewport();
1075 AlignmentI al = av.getAlignment();
1078 * mimic drag and drop of hmm file on to alignment
1080 AlignFrame af2 = new FileLoader().LoadFileWaitTillLoaded(
1081 "examples/uniref50.hmm", DataSourceType.FILE);
1082 al.insertSequenceAt(0,
1083 af2.getViewport().getAlignment().getSequenceAt(0));
1086 * check it loaded in
1088 SequenceI hmmSeq = al.getSequenceAt(0);
1089 assertTrue(hmmSeq.hasHMMProfile());
1090 HiddenMarkovModel hmm = hmmSeq.getHMM();
1091 assertSame(hmm.getConsensusSequence(), hmmSeq);
1094 * save project, close windows, reload project, verify
1096 File tfile = File.createTempFile("testStoreAndRecoverHmmProfile",
1098 tfile.deleteOnExit();
1099 new Jalview2XML(false).saveState(tfile);
1100 Desktop.instance.closeAll_actionPerformed(null);
1101 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
1102 DataSourceType.FILE);
1103 Assert.assertNotNull(af, "Failed to reload project");
1105 hmmSeq = al.getSequenceAt(0);
1106 assertTrue(hmmSeq.hasHMMProfile());
1107 assertSame(hmm.getConsensusSequence(), hmmSeq);
1108 Mapping mapToHmmConsensus = (Mapping) PA.getValue(hmm,
1109 "mapToHmmConsensus");
1110 assertNotNull(mapToHmmConsensus);
1111 assertSame(mapToHmmConsensus.getTo(), hmmSeq.getDatasetSequence());
1115 * pre 2.11 - jalview 2.10 erroneously created new dataset entries for each
1116 * view (JAL-3171) this test ensures we can import and merge those views
1118 @Test(groups = { "Functional" })
1119 public void testMergeDatasetsforViews() throws IOException
1121 // simple project - two views on one alignment
1122 AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
1123 "examples/testdata/projects/twoViews.jvp", DataSourceType.FILE);
1125 assertTrue(af.getAlignPanels().size() > 1);
1130 * pre 2.11 - jalview 2.10 erroneously created new dataset entries for each
1131 * view (JAL-3171) this test ensures we can import and merge those views This
1132 * is a more complex project
1134 @Test(groups = { "Functional" })
1135 public void testMergeDatasetsforManyViews() throws IOException
1137 Desktop.instance.closeAll_actionPerformed(null);
1139 // complex project - one dataset, several views on several alignments
1140 AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
1141 "examples/testdata/projects/manyViews.jvp",
1142 DataSourceType.FILE);
1145 AlignmentI ds = null;
1146 for (AlignFrame alignFrame : Desktop.getAlignFrames())
1150 ds = verifyDs(alignFrame);
1154 // check that this frame's dataset matches the last
1155 assertTrue(ds == verifyDs(alignFrame));
1160 private AlignmentI verifyDs(AlignFrame af)
1162 AlignmentI ds = null;
1163 for (AlignmentViewPanel ap : af.getAlignPanels())
1167 ds = ap.getAlignment().getDataset();
1171 assertTrue(ap.getAlignment().getDataset() == ds,
1172 "Dataset was not the same for imported 2.10.5 project with several alignment views");
1178 @Test(groups = "Functional")
1179 public void testPcaViewAssociation() throws IOException
1181 Desktop.instance.closeAll_actionPerformed(null);
1182 final String PCAVIEWNAME = "With PCA";
1183 // create a new tempfile
1184 File tempfile = File.createTempFile("jvPCAviewAssoc", "jvp");
1187 String exampleFile = "examples/uniref50.fa";
1188 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
1189 DataSourceType.FILE);
1190 assertNotNull(af, "Didn't read in the example file correctly.");
1191 AlignmentPanel origView = (AlignmentPanel) af.getAlignPanels().get(0);
1192 AlignmentPanel newview = af.newView(PCAVIEWNAME, true);
1193 // create another for good measure
1194 af.newView("Not the PCA View", true);
1195 PCAPanel pcaPanel = new PCAPanel(origView, "BLOSUM62",
1196 new SimilarityParams(true, true, true, false));
1197 // we're in the test exec thread, so we can just run synchronously here
1200 // now switch the linked view
1201 pcaPanel.selectAssociatedView(newview);
1203 assertTrue(pcaPanel.getAlignViewport() == newview.getAlignViewport(),
1204 "PCA should be associated with 'With PCA' view: test is broken");
1206 // now save and reload project
1207 Jalview2XML jv2xml = new jalview.project.Jalview2XML(false);
1209 jv2xml.saveState(tempfile);
1210 assertTrue(jv2xml.errorMessage == null,
1211 "Failed to save dummy project with PCA: test broken");
1215 Desktop.instance.closeAll_actionPerformed(null);
1216 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1217 tempfile.getCanonicalPath(), DataSourceType.FILE);
1218 JInternalFrame[] frames = Desktop.instance.getAllFrames();
1219 // PCA and the tabbed alignment view should be the only two windows on the
1221 assertEquals(frames.length, 2,
1222 "PCA and the tabbed alignment view should be the only two windows on the desktop");
1223 PCAPanel pcaPanel = (PCAPanel) frames[frames[0] == af ? 1 : 0];
1225 AlignmentViewPanel restoredNewView = null;
1226 for (AlignmentViewPanel alignpanel : Desktop.getAlignmentPanels(null))
1228 if (alignpanel.getAlignViewport() == pcaPanel.getAlignViewport())
1230 restoredNewView = alignpanel;
1233 assertEquals(restoredNewView.getViewName(), PCAVIEWNAME);
1235 restoredNewView.getAlignViewport() == pcaPanel
1236 .getAlignViewport(),
1237 "Didn't restore correct view association for the PCA view");