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.bin.Instance;
36 import jalview.datamodel.AlignmentAnnotation;
37 import jalview.datamodel.AlignmentI;
38 import jalview.datamodel.HiddenSequences;
39 import jalview.datamodel.PDBEntry;
40 import jalview.datamodel.PDBEntry.Type;
41 import jalview.datamodel.SequenceCollectionI;
42 import jalview.datamodel.SequenceFeature;
43 import jalview.datamodel.SequenceGroup;
44 import jalview.datamodel.SequenceI;
45 import jalview.datamodel.features.FeatureMatcher;
46 import jalview.datamodel.features.FeatureMatcherSet;
47 import jalview.datamodel.features.FeatureMatcherSetI;
48 import jalview.gui.AlignFrame;
49 import jalview.gui.AlignViewport;
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 @Test(singleThreaded = true)
91 public class Jalview2xmlTests extends Jalview2xmlBase
95 @BeforeClass(alwaysRun = true)
96 public void setUpJvOptionPane()
98 JvOptionPane.setInteractiveMode(false);
99 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
102 @Test(groups = { "Functional" })
103 public void testRNAStructureRecovery() throws Exception
105 String inFile = "examples/RF00031_folded.stk";
106 String tfile = File.createTempFile("JalviewTest", ".jvp")
108 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
109 DataSourceType.FILE);
110 assertNotNull(af, "Didn't read input file " + inFile);
111 int olddsann = countDsAnn(af.getViewport());
112 assertTrue(olddsann > 0, "Didn't find any dataset annotations");
113 af.changeColour_actionPerformed(
114 JalviewColourScheme.RNAHelices.toString());
117 .getGlobalColourScheme() instanceof RNAHelicesColour,
118 "Couldn't apply RNA helices colourscheme");
119 af.saveAlignment(tfile, FileFormat.Jalview);
120 assertTrue(af.isSaveAlignmentSuccessful(),
121 "Failed to store as a project.");
122 af.closeMenuItem_actionPerformed(true);
124 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
125 DataSourceType.FILE);
126 assertNotNull(af, "Failed to import new project");
127 int newdsann = countDsAnn(af.getViewport());
128 assertEquals(olddsann, newdsann,
129 "Differing numbers of dataset sequence annotation\nOriginally "
130 + olddsann + " and now " + newdsann);
132 "Read in same number of annotations as originally present ("
137 .getGlobalColourScheme() instanceof RNAHelicesColour,
138 "RNA helices colourscheme was not applied on import.");
141 @Test(groups = { "Functional" })
142 public void testTCoffeeScores() throws Exception
144 String inFile = "examples/uniref50.fa",
145 inAnnot = "examples/uniref50.score_ascii";
146 String tfile = File.createTempFile("JalviewTest", ".jvp")
148 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
149 DataSourceType.FILE);
150 assertNotNull(af, "Didn't read input file " + inFile);
151 af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
152 AlignViewport viewport = af.getViewport();
153 assertSame(viewport.getGlobalColourScheme().getClass(),
154 TCoffeeColourScheme.class, "Didn't set T-coffee colourscheme");
156 ColourSchemeProperty.getColourScheme(viewport,
157 viewport.getAlignment(),
158 viewport.getGlobalColourScheme()
160 "Recognise T-Coffee score from string");
162 af.saveAlignment(tfile, FileFormat.Jalview);
163 assertTrue(af.isSaveAlignmentSuccessful(),
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 af.saveAlignment(tfile, FileFormat.Jalview);
210 assertTrue(af.isSaveAlignmentSuccessful(),
211 "Failed to store as a project.");
212 af.closeMenuItem_actionPerformed(true);
214 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
215 DataSourceType.FILE);
216 assertNotNull(af, "Failed to import new project");
218 // check for group and alignment colourschemes
220 ColourSchemeI _rcs = af.getViewport().getGlobalColourScheme();
221 ColourSchemeI _rgcs = af.getViewport().getAlignment().getGroups().get(0)
223 assertNotNull(_rcs, "Didn't recover global colourscheme");
224 assertTrue(_rcs instanceof AnnotationColourGradient,
225 "Didn't recover annotation colour global scheme");
226 AnnotationColourGradient __rcs = (AnnotationColourGradient) _rcs;
227 assertTrue(__rcs.isSeqAssociated(),
228 "Annotation colourscheme wasn't sequence associated");
230 boolean diffseqcols = false, diffgseqcols = false;
231 SequenceI[] sqs = af.getViewport().getAlignment().getSequencesArray();
232 for (int p = 0, pSize = af.getViewport().getAlignment()
233 .getWidth(); p < pSize && (!diffseqcols || !diffgseqcols); p++)
235 if (_rcs.findColour(sqs[0].getCharAt(p), p, sqs[0], null, 0f) != _rcs
236 .findColour(sqs[5].getCharAt(p), p, sqs[5], null, 0f))
241 assertTrue(diffseqcols, "Got Different sequence colours");
243 "Per sequence colourscheme (Background) successfully applied and recovered.");
245 assertNotNull(_rgcs, "Didn't recover group colourscheme");
246 assertTrue(_rgcs instanceof AnnotationColourGradient,
247 "Didn't recover annotation colour group colourscheme");
248 __rcs = (AnnotationColourGradient) _rgcs;
249 assertTrue(__rcs.isSeqAssociated(),
250 "Group Annotation colourscheme wasn't sequence associated");
252 for (int p = 0, pSize = af.getViewport().getAlignment()
253 .getWidth(); p < pSize && (!diffseqcols || !diffgseqcols); p++)
255 if (_rgcs.findColour(sqs[1].getCharAt(p), p, sqs[1], null,
256 0f) != _rgcs.findColour(sqs[2].getCharAt(p), p, sqs[2], null,
262 assertTrue(diffgseqcols, "Got Different group sequence colours");
264 "Per sequence (Group) colourscheme successfully applied and recovered.");
267 @Test(groups = { "Functional" })
268 public void gatherViewsHere() throws Exception
270 int origCount = Desktop.getAlignFrames() == null ? 0
271 : Desktop.getAlignFrames().length;
272 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
273 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
274 assertNotNull(af, "Didn't read in the example file correctly.");
275 assertTrue(Desktop.getAlignFrames().length == 1 + origCount,
276 "Didn't gather the views in the example file.");
281 * Test for JAL-2223 - multiple mappings in View Mapping report
285 @Test(groups = { "Functional" })
286 public void noDuplicatePdbMappingsMade() throws Exception
288 StructureImportSettings.setProcessSecondaryStructure(true);
289 StructureImportSettings.setVisibleChainAnnotation(true);
290 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
291 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
292 assertNotNull(af, "Didn't read in the example file correctly.");
294 // locate Jmol viewer
295 // count number of PDB mappings the structure selection manager holds -
296 String pdbFile = af.getCurrentView().getStructureSelectionManager()
297 .findFileForPDBId("1A70");
299 af.getCurrentView().getStructureSelectionManager()
300 .getMapping(pdbFile).length,
301 2, "Expected only two mappings for 1A70");
305 @Test(groups = { "Functional" })
306 public void viewRefPdbAnnotation() throws Exception
308 StructureImportSettings.setProcessSecondaryStructure(true);
309 StructureImportSettings.setVisibleChainAnnotation(true);
310 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
311 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
312 assertNotNull(af, "Didn't read in the example file correctly.");
313 AlignmentViewPanel sps = null;
314 for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
316 if ("Spinach Feredoxin Structure".equals(ap.getViewName()))
322 assertNotNull(sps, "Couldn't find the structure view");
323 AlignmentAnnotation refan = null;
324 for (AlignmentAnnotation ra : sps.getAlignment()
325 .getAlignmentAnnotation())
333 assertNotNull(refan, "Annotation secondary structure not found.");
334 SequenceI sq = sps.getAlignment().findName("1A70|");
335 assertNotNull(sq, "Couldn't find 1a70 null chain");
336 // compare the manually added temperature factor annotation
337 // to the track automatically transferred from the pdb structure on load
338 assertNotNull(sq.getDatasetSequence().getAnnotation(),
339 "1a70 has no annotation");
340 for (AlignmentAnnotation ala : sq.getDatasetSequence().getAnnotation())
342 AlignmentAnnotation alaa;
343 sq.addAlignmentAnnotation(alaa = new AlignmentAnnotation(ala));
344 alaa.adjustForAlignment();
345 if (ala.graph == refan.graph)
347 for (int p = 0; p < ala.annotations.length; p++)
352 assertTrue((alaa.annotations[p] == null
353 && refan.annotations[p] == null)
354 || alaa.annotations[p].value == refan.annotations[p].value,
355 "Mismatch at alignment position " + p);
356 } catch (NullPointerException q)
358 Assert.fail("Mismatch of alignment annotations at position " + p
359 + " Ref seq ann: " + refan.annotations[p]
360 + " alignment " + alaa.annotations[p]);
368 @Test(groups = { "Functional" })
369 public void testCopyViewSettings() throws Exception
371 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
372 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
373 assertNotNull(af, "Didn't read in the example file correctly.");
374 AlignmentViewPanel sps = null, groups = null;
375 for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
377 if ("Spinach Feredoxin Structure".equals(ap.getViewName()))
381 if (ap.getViewName().contains("MAFFT"))
386 assertNotNull(sps, "Couldn't find the structure view");
387 assertNotNull(groups, "Couldn't find the MAFFT view");
389 ViewStyleI structureStyle = sps.getAlignViewport().getViewStyle();
390 ViewStyleI groupStyle = groups.getAlignViewport().getViewStyle();
391 AssertJUnit.assertFalse(structureStyle.sameStyle(groupStyle));
393 groups.getAlignViewport().setViewStyle(structureStyle);
394 AssertJUnit.assertFalse(
395 groupStyle.sameStyle(groups.getAlignViewport().getViewStyle()));
396 Assert.assertTrue(structureStyle
397 .sameStyle(groups.getAlignViewport().getViewStyle()));
402 * test store and recovery of expanded views
406 @Test(groups = { "Functional" }, enabled = true)
407 public void testStoreAndRecoverExpandedviews() throws Exception
409 Instance.getDesktop().closeAll_actionPerformed(null);
411 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
412 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
413 Assert.assertEquals(Desktop.getAlignFrames().length, 1);
414 String afid = af.getViewport().getSequenceSetId();
416 // check FileLoader returned a reference to the one alignFrame that is
417 // actually on the Desktop
418 assertSame(af, Desktop.getAlignFrameFor(af.getViewport()),
419 "Jalview2XML.loadAlignFrame() didn't return correct AlignFrame reference for multiple view window");
421 Desktop.explodeViews(af);
423 int oldviews = Desktop.getAlignFrames().length;
424 Assert.assertEquals(Desktop.getAlignFrames().length,
425 Desktop.getAlignmentPanels(afid).length);
426 File tfile = File.createTempFile("testStoreAndRecoverExpanded", ".jvp");
429 new Jalview2XML(false).saveState(tfile);
432 Assert.fail("Didn't save the expanded view state", e);
433 } catch (Exception e)
435 Assert.fail("Didn't save the expanded view state", e);
437 Instance.getDesktop().closeAll_actionPerformed(null);
438 if (Desktop.getAlignFrames() != null)
440 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
442 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
443 DataSourceType.FILE);
444 Assert.assertNotNull(af);
445 Assert.assertEquals(Desktop.getAlignFrames().length,
446 Desktop.getAlignmentPanels(
447 af.getViewport().getSequenceSetId()).length);
449 Desktop.getAlignmentPanels(
450 af.getViewport().getSequenceSetId()).length,
455 * Test save and reload of a project with a different representative sequence
460 @Test(groups = { "Functional" })
461 public void testStoreAndRecoverReferenceSeqSettings() throws Exception
463 Instance.getDesktop().closeAll_actionPerformed(null);
464 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
465 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
466 assertNotNull(af, "Didn't read in the example file correctly.");
467 String afid = af.getViewport().getSequenceSetId();
469 // remember reference sequence for each panel
470 Map<String, SequenceI> refseqs = new HashMap<>();
473 * mark sequence 2, 3, 4.. in panels 1, 2, 3...
474 * as reference sequence for itself and the preceding sequence
477 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
479 AlignViewportI av = ap.getAlignViewport();
480 AlignmentI alignment = ap.getAlignment();
481 int repIndex = n % alignment.getHeight();
482 SequenceI rep = alignment.getSequenceAt(repIndex);
483 refseqs.put(ap.getViewName(), rep);
485 // code from mark/unmark sequence as reference in jalview.gui.PopupMenu
486 // todo refactor this to an alignment view controller
487 av.setDisplayReferenceSeq(true);
488 av.setColourByReferenceSeq(true);
489 av.getAlignment().setSeqrep(rep);
493 File tfile = File.createTempFile("testStoreAndRecoverReferenceSeq",
497 new Jalview2XML(false).saveState(tfile);
498 } catch (Throwable e)
500 Assert.fail("Didn't save the expanded view state", e);
502 Instance.getDesktop().closeAll_actionPerformed(null);
503 if (Desktop.getAlignFrames() != null)
505 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
508 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
509 DataSourceType.FILE);
510 afid = af.getViewport().getSequenceSetId();
512 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
514 // check representative
515 AlignmentI alignment = ap.getAlignment();
516 SequenceI rep = alignment.getSeqrep();
517 Assert.assertNotNull(rep,
518 "Couldn't restore sequence representative from project");
519 // can't use a strong equals here, because by definition, the sequence IDs
520 // will be different.
521 // could set vamsas session save/restore flag to preserve IDs across
523 Assert.assertEquals(refseqs.get(ap.getViewName()).toString(),
525 "Representative wasn't the same when recovered.");
526 Assert.assertTrue(ap.getAlignViewport().isDisplayReferenceSeq(),
527 "Display reference sequence view setting not set.");
528 Assert.assertTrue(ap.getAlignViewport().isColourByReferenceSeq(),
529 "Colour By Reference Seq view setting not set.");
533 @Test(groups = { "Functional" })
534 public void testIsVersionStringLaterThan()
537 * No version / development / test / autobuild is leniently assumed to be
540 assertTrue(Jalview2XML.isVersionStringLaterThan(null, null));
541 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", null));
542 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "2.8.3"));
543 assertTrue(Jalview2XML.isVersionStringLaterThan(null,
544 "Development Build"));
545 assertTrue(Jalview2XML.isVersionStringLaterThan(null,
546 "DEVELOPMENT BUILD"));
547 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
548 "Development Build"));
549 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "Test"));
550 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "TEST"));
551 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "Test"));
553 Jalview2XML.isVersionStringLaterThan(null, "Automated Build"));
554 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
556 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
560 * same version returns true i.e. compatible
562 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8", "2.8"));
563 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.3"));
564 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3b1"));
565 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3B1", "2.8.3b1"));
566 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3B1"));
569 * later version returns true
571 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.4"));
572 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.9"));
573 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.9.2"));
574 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8", "2.8.3"));
575 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.3b1"));
578 * earlier version returns false
580 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8"));
581 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.4", "2.8.3"));
582 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3"));
583 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.2b1"));
584 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.0b2", "2.8.0b1"));
588 * Test save and reload of a project with a different sequence group (and
589 * representative sequence) in each view.
593 @Test(groups = { "Functional" })
594 public void testStoreAndRecoverGroupRepSeqs() throws Exception
596 Instance.getDesktop().closeAll_actionPerformed(null);
597 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
598 "examples/uniref50.fa", DataSourceType.FILE);
599 assertNotNull(af, "Didn't read in the example file correctly.");
600 String afid = af.getViewport().getSequenceSetId();
601 // make a second view of the alignment
602 af.newView_actionPerformed(null);
605 * remember representative and hidden sequences marked
608 Map<String, SequenceI> repSeqs = new HashMap<>();
609 Map<String, List<String>> hiddenSeqNames = new HashMap<>();
612 * mark sequence 2, 3, 4.. in panels 1, 2, 3...
613 * as reference sequence for itself and the preceding sequence
616 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
618 AlignViewportI av = ap.getAlignViewport();
619 AlignmentI alignment = ap.getAlignment();
620 int repIndex = n % alignment.getHeight();
621 // ensure at least one preceding sequence i.e. index >= 1
622 repIndex = Math.max(repIndex, 1);
623 SequenceI repSeq = alignment.getSequenceAt(repIndex);
624 repSeqs.put(ap.getViewName(), repSeq);
625 List<String> hiddenNames = new ArrayList<>();
626 hiddenSeqNames.put(ap.getViewName(), hiddenNames);
629 * have rep sequence represent itself and the one before it
630 * this hides the group (except for the rep seq)
632 SequenceGroup sg = new SequenceGroup();
633 sg.addSequence(repSeq, false);
634 SequenceI precedingSeq = alignment.getSequenceAt(repIndex - 1);
635 sg.addSequence(precedingSeq, false);
636 sg.setSeqrep(repSeq);
637 assertTrue(sg.getSequences().contains(repSeq));
638 assertTrue(sg.getSequences().contains(precedingSeq));
639 av.setSelectionGroup(sg);
640 assertSame(repSeq, sg.getSeqrep());
643 * represent group with sequence adds to a map of hidden rep sequences
644 * (it does not create a group on the alignment)
646 ((AlignmentViewport) av).hideSequences(repSeq, true);
647 assertSame(repSeq, sg.getSeqrep());
648 assertTrue(sg.getSequences().contains(repSeq));
649 assertTrue(sg.getSequences().contains(precedingSeq));
650 assertTrue(alignment.getGroups().isEmpty(), "alignment has groups");
651 Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av
652 .getHiddenRepSequences();
653 assertNotNull(hiddenRepSeqsMap);
654 assertEquals(1, hiddenRepSeqsMap.size());
655 assertSame(sg, hiddenRepSeqsMap.get(repSeq));
656 assertTrue(alignment.getHiddenSequences().isHidden(precedingSeq));
657 assertFalse(alignment.getHiddenSequences().isHidden(repSeq));
658 hiddenNames.add(precedingSeq.getName());
662 File tfile = File.createTempFile("testStoreAndRecoverGroupReps",
666 new Jalview2XML(false).saveState(tfile);
667 } catch (Throwable e)
669 Assert.fail("Didn't save the expanded view state", e);
671 Instance.getDesktop().closeAll_actionPerformed(null);
672 if (Desktop.getAlignFrames() != null)
674 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
677 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
678 DataSourceType.FILE);
679 afid = af.getViewport().getSequenceSetId();
681 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
683 String viewName = ap.getViewName();
684 AlignViewportI av = ap.getAlignViewport();
685 AlignmentI alignment = ap.getAlignment();
686 List<SequenceGroup> groups = alignment.getGroups();
687 assertNotNull(groups);
688 assertTrue(groups.isEmpty(), "Alignment has groups");
689 Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av
690 .getHiddenRepSequences();
691 assertNotNull(hiddenRepSeqsMap, "No hidden represented sequences");
692 assertEquals(1, hiddenRepSeqsMap.size());
693 assertEquals(repSeqs.get(viewName).getDisplayId(true),
694 hiddenRepSeqsMap.keySet().iterator().next()
695 .getDisplayId(true));
698 * verify hidden sequences in restored panel
700 List<String> hidden = hiddenSeqNames.get(ap.getViewName());
701 HiddenSequences hs = alignment.getHiddenSequences();
702 assertEquals(hidden.size(), hs.getSize(),
703 "wrong number of restored hidden sequences in "
709 * Test save and reload of PDBEntry in Jalview project
713 @Test(groups = { "Functional" })
714 public void testStoreAndRecoverPDBEntry() throws Exception
716 Instance.getDesktop().closeAll_actionPerformed(null);
717 String exampleFile = "examples/3W5V.pdb";
718 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
719 DataSourceType.FILE);
720 assertNotNull(af, "Didn't read in the example file correctly.");
721 String afid = af.getViewport().getSequenceSetId();
723 AlignmentPanel[] alignPanels = Desktop.getAlignmentPanels(afid);
724 System.out.println();
725 AlignmentViewPanel ap = alignPanels[0];
726 String tfileBase = new File(".").getAbsolutePath().replace(".", "");
727 String testFile = tfileBase + exampleFile;
728 AlignmentI alignment = ap.getAlignment();
729 System.out.println("blah");
730 SequenceI[] seqs = alignment.getSequencesArray();
731 Assert.assertNotNull(seqs[0]);
732 Assert.assertNotNull(seqs[1]);
733 Assert.assertNotNull(seqs[2]);
734 Assert.assertNotNull(seqs[3]);
735 Assert.assertNotNull(seqs[0].getDatasetSequence());
736 Assert.assertNotNull(seqs[1].getDatasetSequence());
737 Assert.assertNotNull(seqs[2].getDatasetSequence());
738 Assert.assertNotNull(seqs[3].getDatasetSequence());
739 PDBEntry[] pdbEntries = new PDBEntry[4];
740 pdbEntries[0] = new PDBEntry("3W5V", "A", Type.PDB, testFile);
741 pdbEntries[1] = new PDBEntry("3W5V", "B", Type.PDB, testFile);
742 pdbEntries[2] = new PDBEntry("3W5V", "C", Type.PDB, testFile);
743 pdbEntries[3] = new PDBEntry("3W5V", "D", Type.PDB, testFile);
745 seqs[0].getDatasetSequence().getAllPDBEntries().get(0),
748 seqs[1].getDatasetSequence().getAllPDBEntries().get(0),
751 seqs[2].getDatasetSequence().getAllPDBEntries().get(0),
754 seqs[3].getDatasetSequence().getAllPDBEntries().get(0),
757 File tfile = File.createTempFile("testStoreAndRecoverPDBEntry", ".jvp");
760 new Jalview2XML(false).saveState(tfile);
761 } catch (Throwable e)
763 Assert.fail("Didn't save the state", e);
765 Instance.getDesktop().closeAll_actionPerformed(null);
766 if (Desktop.getAlignFrames() != null)
768 Assert.assertEquals(Desktop.getAlignFrames().length, 0);
771 AlignFrame restoredFrame = new FileLoader().LoadFileWaitTillLoaded(
772 tfile.getAbsolutePath(), DataSourceType.FILE);
773 String rfid = restoredFrame.getViewport().getSequenceSetId();
774 AlignmentPanel[] rAlignPanels = Desktop.getAlignmentPanels(rfid);
775 AlignmentViewPanel rap = rAlignPanels[0];
776 AlignmentI rAlignment = rap.getAlignment();
777 System.out.println("blah");
778 SequenceI[] rseqs = rAlignment.getSequencesArray();
779 Assert.assertNotNull(rseqs[0]);
780 Assert.assertNotNull(rseqs[1]);
781 Assert.assertNotNull(rseqs[2]);
782 Assert.assertNotNull(rseqs[3]);
783 Assert.assertNotNull(rseqs[0].getDatasetSequence());
784 Assert.assertNotNull(rseqs[1].getDatasetSequence());
785 Assert.assertNotNull(rseqs[2].getDatasetSequence());
786 Assert.assertNotNull(rseqs[3].getDatasetSequence());
788 // The Asserts below are expected to fail until the PDB chainCode is
789 // recoverable from a Jalview projects
790 for (int chain = 0; chain < 4; chain++)
792 PDBEntry recov = rseqs[chain].getDatasetSequence().getAllPDBEntries()
794 PDBEntry expected = pdbEntries[chain];
795 Assert.assertEquals(recov.getId(), expected.getId(),
797 Assert.assertEquals(recov.getChainCode(), expected.getChainCode(),
799 Assert.assertEquals(recov.getType(), expected.getType(),
800 "Mismatch PDBEntry 'Type'");
801 Assert.assertNotNull(recov.getFile(),
802 "Recovered PDBEntry should have a non-null file entry");
807 * Configure an alignment and a sub-group each with distinct colour schemes,
808 * Conservation and PID thresholds, and confirm these are restored from the
811 * @throws IOException
813 @Test(groups = { "Functional" })
814 public void testStoreAndRecoverColourThresholds() throws IOException
816 Instance.getDesktop().closeAll_actionPerformed(null);
817 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
818 "examples/uniref50.fa", DataSourceType.FILE);
820 AlignViewport av = af.getViewport();
821 AlignmentI al = av.getAlignment();
824 * Colour alignment by Buried Index, Above 10% PID, By Conservation 20%
826 av.setColourAppliesToAllGroups(false);
827 af.changeColour_actionPerformed(JalviewColourScheme.Buried.toString());
828 assertTrue(av.getGlobalColourScheme() instanceof BuriedColourScheme);
829 af.abovePIDThreshold_actionPerformed(true);
830 SliderPanel sp = SliderPanel.getSliderPanel();
831 assertFalse(sp.isForConservation());
833 af.conservationMenuItem_actionPerformed(true);
834 sp = SliderPanel.getSliderPanel();
835 assertTrue(sp.isForConservation());
837 ResidueShaderI rs = av.getResidueShading();
838 assertEquals(rs.getThreshold(), 10);
839 assertTrue(rs.conservationApplied());
840 assertEquals(rs.getConservationInc(), 20);
843 * create a group with Strand colouring, 30% Conservation
844 * and 40% PID threshold
846 SequenceGroup sg = new SequenceGroup();
847 sg.addSequence(al.getSequenceAt(0), false);
850 av.setSelectionGroup(sg);
851 PopupMenu popupMenu = new PopupMenu(af.alignPanel, null, null);
852 popupMenu.changeColour_actionPerformed(
853 JalviewColourScheme.Strand.toString());
854 assertTrue(sg.getColourScheme() instanceof StrandColourScheme);
855 assertEquals(al.getGroups().size(), 1);
856 assertSame(al.getGroups().get(0), sg);
857 popupMenu.conservationMenuItem_actionPerformed(true);
858 sp = SliderPanel.getSliderPanel();
859 assertTrue(sp.isForConservation());
861 popupMenu.abovePIDColour_actionPerformed(true);
862 sp = SliderPanel.getSliderPanel();
863 assertFalse(sp.isForConservation());
865 assertTrue(sg.getGroupColourScheme().conservationApplied());
866 assertEquals(sg.getGroupColourScheme().getConservationInc(), 30);
867 assertEquals(sg.getGroupColourScheme().getThreshold(), 40);
870 * save project, close windows, reload project, verify
872 File tfile = File.createTempFile("testStoreAndRecoverColourThresholds",
874 tfile.deleteOnExit();
875 new Jalview2XML(false).saveState(tfile);
876 Instance.getDesktop().closeAll_actionPerformed(null);
877 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
878 DataSourceType.FILE);
879 Assert.assertNotNull(af, "Failed to reload project");
882 * verify alignment (background) colouring
884 rs = af.getViewport().getResidueShading();
885 assertTrue(rs.getColourScheme() instanceof BuriedColourScheme);
886 assertEquals(rs.getThreshold(), 10);
887 assertTrue(rs.conservationApplied());
888 assertEquals(rs.getConservationInc(), 20);
891 * verify group colouring
893 assertEquals(1, af.getViewport().getAlignment().getGroups().size(), 1);
894 rs = af.getViewport().getAlignment().getGroups().get(0)
895 .getGroupColourScheme();
896 assertTrue(rs.getColourScheme() instanceof StrandColourScheme);
897 assertEquals(rs.getThreshold(), 40);
898 assertTrue(rs.conservationApplied());
899 assertEquals(rs.getConservationInc(), 30);
903 * Test save and reload of feature colour schemes and filter settings
905 * @throws IOException
907 @Test(groups = { "Functional" })
908 public void testSaveLoadFeatureColoursAndFilters() throws IOException
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 af.saveAlignment(filePath, FileFormat.Jalview);
989 assertTrue(af.isSaveAlignmentSuccessful(),
990 "Failed to store as a project.");
993 * close current alignment and load the saved project
995 af.closeMenuItem_actionPerformed(true);
997 af = new FileLoader().LoadFileWaitTillLoaded(filePath,
998 DataSourceType.FILE);
999 assertNotNull(af, "Failed to import new project");
1002 * verify restored feature colour schemes and filters
1004 fr = af.getFeatureRenderer();
1005 FeatureColourI fc = fr.getFeatureStyle("type1");
1006 assertTrue(fc.isSimpleColour());
1007 assertEquals(fc.getColour(), Color.red);
1008 fc = fr.getFeatureStyle("type2");
1009 assertTrue(fc.isColourByLabel());
1010 fc = fr.getFeatureStyle("type3");
1011 assertTrue(fc.isGraduatedColour());
1012 assertNull(fc.getAttributeName());
1013 assertTrue(fc.isAboveThreshold());
1014 assertEquals(fc.getThreshold(), 2f);
1015 fc = fr.getFeatureStyle("type4");
1016 assertTrue(fc.isColourByLabel());
1017 assertTrue(fc.isColourByAttribute());
1018 assertEquals(fc.getAttributeName(), new String[] { "AF" });
1019 fc = fr.getFeatureStyle("type5");
1020 assertTrue(fc.isGraduatedColour());
1021 assertTrue(fc.isColourByAttribute());
1022 assertEquals(fc.getAttributeName(), new String[] { "CSQ", "PolyPhen" });
1023 assertTrue(fc.isBelowThreshold());
1024 assertEquals(fc.getThreshold(), 3f);
1026 assertEquals(fr.getFeatureFilter("type1").toStableString(),
1027 "Label Contains x");
1028 assertEquals(fr.getFeatureFilter("type2").toStableString(),
1029 "(Score LE 2.4) AND (Score GT 1.1)");
1030 assertEquals(fr.getFeatureFilter("type3").toStableString(),
1031 "(AF Contains X) OR (CSQ:PolyPhen NE 0.0)");
1034 private void addFeature(SequenceI seq, String featureType, int score)
1036 SequenceFeature sf = new SequenceFeature(featureType, "desc", 1, 2,
1038 sf.setValue("AF", score);
1039 sf.setValue("CSQ", new HashMap<String, String>()
1042 put("PolyPhen", Integer.toString(score));
1045 seq.addSequenceFeature(sf);
1049 * Adds two features of the given type to the given sequence, also setting the
1050 * score as the value of attribute "AF" and sub-attribute "CSQ:PolyPhen"
1053 * @param featureType
1056 private void addFeatures(SequenceI seq, String featureType, int score)
1058 addFeature(seq, featureType, score++);
1059 addFeature(seq, featureType, score);
1063 * pre 2.11 - jalview 2.10 erroneously created new dataset entries for each
1064 * view (JAL-3171) this test ensures we can import and merge those views
1066 @Test(groups = { "Functional" })
1067 public void testMergeDatasetsforViews() throws IOException
1069 // simple project - two views on one alignment
1070 AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
1071 "examples/testdata/projects/twoViews.jvp", DataSourceType.FILE);
1073 assertTrue(af.getAlignPanels().size() > 1);
1078 * pre 2.11 - jalview 2.10 erroneously created new dataset entries for each
1079 * view (JAL-3171) this test ensures we can import and merge those views This
1080 * is a more complex project
1082 @Test(groups = { "Functional" })
1083 public void testMergeDatasetsforManyViews() throws IOException
1085 Instance.getDesktop().closeAll_actionPerformed(null);
1087 // complex project - one dataset, several views on several alignments
1088 AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
1089 "examples/testdata/projects/manyViews.jvp",
1090 DataSourceType.FILE);
1093 AlignmentI ds = null;
1094 for (AlignFrame alignFrame : Desktop.getAlignFrames())
1098 ds = verifyDs(alignFrame);
1102 // check that this frame's dataset matches the last
1103 assertTrue(ds == verifyDs(alignFrame));
1108 private AlignmentI verifyDs(AlignFrame af)
1110 AlignmentI ds = null;
1111 for (AlignmentViewPanel ap : af.getAlignPanels())
1115 ds = ap.getAlignment().getDataset();
1119 assertTrue(ap.getAlignment().getDataset() == ds,
1120 "Dataset was not the same for imported 2.10.5 project with several alignment views");
1126 @Test(groups = "Functional")
1127 public void testPcaViewAssociation() throws IOException
1129 Instance.getDesktop().closeAll_actionPerformed(null);
1130 final String PCAVIEWNAME = "With PCA";
1131 // create a new tempfile
1132 File tempfile = File.createTempFile("jvPCAviewAssoc", "jvp");
1135 String exampleFile = "examples/uniref50.fa";
1136 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
1137 DataSourceType.FILE);
1138 assertNotNull(af, "Didn't read in the example file correctly.");
1139 AlignmentPanel origView = (AlignmentPanel) af.getAlignPanels().get(0);
1140 AlignmentPanel newview = af.newView(PCAVIEWNAME, true);
1141 // create another for good measure
1142 af.newView("Not the PCA View", true);
1143 PCAPanel pcaPanel = new PCAPanel(origView, "BLOSUM62",
1144 new SimilarityParams(true, true, true, false));
1145 // we're in the test exec thread, so we can just run synchronously here
1148 // now switch the linked view
1149 pcaPanel.selectAssociatedView(newview);
1151 assertTrue(pcaPanel.getAlignViewport() == newview.getAlignViewport(),
1152 "PCA should be associated with 'With PCA' view: test is broken");
1154 // now save and reload project
1155 Jalview2XML jv2xml = new jalview.project.Jalview2XML(false);
1157 jv2xml.saveState(tempfile);
1158 assertTrue(jv2xml.errorMessage == null,
1159 "Failed to save dummy project with PCA: test broken");
1163 Instance.getDesktop().closeAll_actionPerformed(null);
1164 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1165 tempfile.getCanonicalPath(), DataSourceType.FILE);
1166 JInternalFrame[] frames = Instance.getDesktop().getAllFrames();
1167 // PCA and the tabbed alignment view should be the only two windows on the
1169 assertEquals(frames.length, 2,
1170 "PCA and the tabbed alignment view should be the only two windows on the desktop");
1171 PCAPanel pcaPanel = (PCAPanel) frames[frames[0] == af ? 1 : 0];
1173 AlignmentViewPanel restoredNewView = null;
1174 for (AlignmentViewPanel alignpanel : Desktop.getAlignmentPanels(null))
1176 if (alignpanel.getAlignViewport() == pcaPanel.getAlignViewport())
1178 restoredNewView = alignpanel;
1181 assertEquals(restoredNewView.getViewName(), PCAVIEWNAME);
1183 restoredNewView.getAlignViewport() == pcaPanel
1184 .getAlignViewport(),
1185 "Didn't restore correct view association for the PCA view");