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.assertNotSame;
27 import static org.testng.Assert.assertNull;
28 import static org.testng.Assert.assertSame;
29 import static org.testng.Assert.assertTrue;
31 import java.awt.Color;
32 import java.awt.Rectangle;
34 import java.io.IOException;
35 import java.util.ArrayList;
36 import java.util.BitSet;
37 import java.util.HashMap;
38 import java.util.List;
39 import java.util.Locale;
42 import javax.swing.JInternalFrame;
44 import org.testng.Assert;
45 import org.testng.AssertJUnit;
46 import org.testng.annotations.BeforeClass;
47 import org.testng.annotations.Test;
49 import jalview.analysis.AlignmentUtils;
50 import jalview.analysis.scoremodels.SimilarityParams;
51 import jalview.api.AlignViewportI;
52 import jalview.api.AlignmentViewPanel;
53 import jalview.api.FeatureColourI;
54 import jalview.api.ViewStyleI;
55 import jalview.bin.Cache;
56 import jalview.datamodel.AlignmentAnnotation;
57 import jalview.datamodel.AlignmentI;
58 import jalview.datamodel.Annotation;
59 import jalview.datamodel.ContactListI;
60 import jalview.datamodel.ContactMatrix;
61 import jalview.datamodel.ContactMatrixI;
62 import jalview.datamodel.DBRefEntry;
63 import jalview.datamodel.GeneLocus;
64 import jalview.datamodel.GroupSet;
65 import jalview.datamodel.HiddenSequences;
66 import jalview.datamodel.Mapping;
67 import jalview.datamodel.PDBEntry;
68 import jalview.datamodel.PDBEntry.Type;
69 import jalview.datamodel.Sequence;
70 import jalview.datamodel.Sequence.DBModList;
71 import jalview.datamodel.SequenceCollectionI;
72 import jalview.datamodel.SequenceFeature;
73 import jalview.datamodel.SequenceGroup;
74 import jalview.datamodel.SequenceI;
75 import jalview.datamodel.features.FeatureMatcher;
76 import jalview.datamodel.features.FeatureMatcherSet;
77 import jalview.datamodel.features.FeatureMatcherSetI;
78 import jalview.gui.AlignFrame;
79 import jalview.gui.AlignViewport;
80 import jalview.gui.AlignmentPanel;
81 import jalview.gui.Desktop;
82 import jalview.gui.JvOptionPane;
83 import jalview.gui.OverviewPanel;
84 import jalview.gui.PCAPanel;
85 import jalview.gui.PopupMenu;
86 import jalview.gui.Preferences;
87 import jalview.gui.SliderPanel;
88 import jalview.io.DataSourceType;
89 import jalview.io.FileFormat;
90 import jalview.io.FileLoader;
91 import jalview.io.Jalview2xmlBase;
92 import jalview.renderer.ResidueShaderI;
93 import jalview.schemes.AnnotationColourGradient;
94 import jalview.schemes.BuriedColourScheme;
95 import jalview.schemes.ColourSchemeI;
96 import jalview.schemes.ColourSchemeProperty;
97 import jalview.schemes.FeatureColour;
98 import jalview.schemes.JalviewColourScheme;
99 import jalview.schemes.RNAHelicesColour;
100 import jalview.schemes.StrandColourScheme;
101 import jalview.schemes.TCoffeeColourScheme;
102 import jalview.structure.StructureImportSettings;
103 import jalview.util.MapList;
104 import jalview.util.Platform;
105 import jalview.util.matcher.Condition;
106 import jalview.viewmodel.AlignmentViewport;
107 import jalview.viewmodel.seqfeatures.FeatureRendererModel;
108 import jalview.ws.datamodel.MappableContactMatrixI;
109 import jalview.ws.datamodel.alphafold.PAEContactMatrix;
111 @Test(singleThreaded = true)
112 public class Jalview2xmlTests extends Jalview2xmlBase
116 @BeforeClass(alwaysRun = true)
117 public void setUpJvOptionPane()
119 if (Desktop.instance != null)
120 Desktop.instance.closeAll_actionPerformed(null);
121 JvOptionPane.setInteractiveMode(false);
122 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
125 @Test(groups = { "Functional" })
126 public void testRNAStructureRecovery() throws Exception
128 String inFile = "examples/RF00031_folded.stk";
129 String tfile = File.createTempFile("JalviewTest", ".jvp")
131 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
132 DataSourceType.FILE);
133 assertNotNull(af, "Didn't read input file " + inFile);
134 int olddsann = countDsAnn(af.getViewport());
135 assertTrue(olddsann > 0, "Didn't find any dataset annotations");
136 af.changeColour_actionPerformed(
137 JalviewColourScheme.RNAHelices.toString());
140 .getGlobalColourScheme() instanceof RNAHelicesColour,
141 "Couldn't apply RNA helices colourscheme");
142 af.saveAlignment(tfile, FileFormat.Jalview);
143 assertTrue(af.isSaveAlignmentSuccessful(),
144 "Failed to store as a project.");
145 af.closeMenuItem_actionPerformed(true);
147 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
148 DataSourceType.FILE);
149 assertNotNull(af, "Failed to import new project");
150 int newdsann = countDsAnn(af.getViewport());
151 assertEquals(olddsann, newdsann,
152 "Differing numbers of dataset sequence annotation\nOriginally "
153 + olddsann + " and now " + newdsann);
155 "Read in same number of annotations as originally present ("
160 .getGlobalColourScheme() instanceof RNAHelicesColour,
161 "RNA helices colourscheme was not applied on import.");
164 @Test(groups = { "Functional" })
165 public void testTCoffeeScores() throws Exception
167 String inFile = "examples/uniref50.fa",
168 inAnnot = "examples/uniref50.score_ascii";
169 String tfile = File.createTempFile("JalviewTest", ".jvp")
171 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
172 DataSourceType.FILE);
173 assertNotNull(af, "Didn't read input file " + inFile);
174 af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
175 AlignViewport viewport = af.getViewport();
176 assertSame(viewport.getGlobalColourScheme().getClass(),
177 TCoffeeColourScheme.class, "Didn't set T-coffee colourscheme");
179 ColourSchemeProperty.getColourScheme(viewport,
180 viewport.getAlignment(),
181 viewport.getGlobalColourScheme().getSchemeName()),
182 "Recognise T-Coffee score from string");
184 af.saveAlignment(tfile, FileFormat.Jalview);
185 assertTrue(af.isSaveAlignmentSuccessful(),
186 "Failed to store as a project.");
187 af.closeMenuItem_actionPerformed(true);
189 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
190 DataSourceType.FILE);
191 assertNotNull(af, "Failed to import new project");
192 assertSame(af.getViewport().getGlobalColourScheme().getClass(),
193 TCoffeeColourScheme.class,
194 "Didn't set T-coffee colourscheme for imported project.");
196 "T-Coffee score shading successfully recovered from project.");
199 @Test(groups = { "Functional" })
200 public void testColourByAnnotScores() throws Exception
202 String inFile = "examples/uniref50.fa",
203 inAnnot = "examples/testdata/uniref50_iupred.jva";
204 String tfile = File.createTempFile("JalviewTest", ".jvp")
206 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
207 DataSourceType.FILE);
208 assertNotNull(af, "Didn't read input file " + inFile);
209 af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
210 AlignmentAnnotation[] aa = af.getViewport().getAlignment()
211 .getSequenceAt(0).getAnnotation("IUPredWS (Short)");
214 aa != null && aa.length > 0,
215 "Didn't find any IUPred annotation to use to shade alignment.");
216 AnnotationColourGradient cs = new AnnotationColourGradient(aa[0], null,
217 AnnotationColourGradient.ABOVE_THRESHOLD);
218 AnnotationColourGradient gcs = new AnnotationColourGradient(aa[0], null,
219 AnnotationColourGradient.BELOW_THRESHOLD);
220 cs.setSeqAssociated(true);
221 gcs.setSeqAssociated(true);
223 SequenceGroup sg = new SequenceGroup();
226 sg.cs.setColourScheme(gcs);
227 af.getViewport().getAlignment().addGroup(sg);
228 sg.addSequence(af.getViewport().getAlignment().getSequenceAt(1), false);
229 sg.addSequence(af.getViewport().getAlignment().getSequenceAt(2), true);
230 af.alignPanel.alignmentChanged();
231 af.saveAlignment(tfile, FileFormat.Jalview);
232 assertTrue(af.isSaveAlignmentSuccessful(),
233 "Failed to store as a project.");
234 af.closeMenuItem_actionPerformed(true);
236 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
237 DataSourceType.FILE);
238 assertNotNull(af, "Failed to import new project");
240 // check for group and alignment colourschemes
242 ColourSchemeI _rcs = af.getViewport().getGlobalColourScheme();
243 ColourSchemeI _rgcs = af.getViewport().getAlignment().getGroups().get(0)
245 assertNotNull(_rcs, "Didn't recover global colourscheme");
246 assertTrue(_rcs instanceof AnnotationColourGradient,
247 "Didn't recover annotation colour global scheme");
248 AnnotationColourGradient __rcs = (AnnotationColourGradient) _rcs;
249 assertTrue(__rcs.isSeqAssociated(),
250 "Annotation colourscheme wasn't sequence associated");
252 boolean diffseqcols = false, diffgseqcols = false;
253 SequenceI[] sqs = af.getViewport().getAlignment().getSequencesArray();
255 pSize = af.getViewport().getAlignment().getWidth(); p < pSize
256 && (!diffseqcols || !diffgseqcols); p++)
258 if (_rcs.findColour(sqs[0].getCharAt(p), p, sqs[0], null, 0f) != _rcs
259 .findColour(sqs[5].getCharAt(p), p, sqs[5], null, 0f))
264 assertTrue(diffseqcols, "Got Different sequence colours");
266 "Per sequence colourscheme (Background) successfully applied and recovered.");
268 assertNotNull(_rgcs, "Didn't recover group colourscheme");
269 assertTrue(_rgcs instanceof AnnotationColourGradient,
270 "Didn't recover annotation colour group colourscheme");
271 __rcs = (AnnotationColourGradient) _rgcs;
272 assertTrue(__rcs.isSeqAssociated(),
273 "Group Annotation colourscheme wasn't sequence associated");
276 pSize = af.getViewport().getAlignment().getWidth(); p < pSize
277 && (!diffseqcols || !diffgseqcols); p++)
279 if (_rgcs.findColour(sqs[1].getCharAt(p), p, sqs[1], null,
280 0f) != _rgcs.findColour(sqs[2].getCharAt(p), p, sqs[2], null,
286 assertTrue(diffgseqcols, "Got Different group sequence colours");
288 "Per sequence (Group) colourscheme successfully applied and recovered.");
291 @Test(groups = { "Functional" })
292 public void gatherViewsHere() throws Exception
294 int origCount = Desktop.getDesktopAlignFrames() == null ? 0
295 : Desktop.getDesktopAlignFrames().length;
296 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
297 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
298 assertNotNull(af, "Didn't read in the example file correctly.");
299 assertTrue(Desktop.getDesktopAlignFrames().length == 1 + origCount,
300 "Didn't gather the views in the example file.");
305 * Test for JAL-2223 - multiple mappings in View Mapping report
309 @Test(groups = { "Functional" })
310 public void noDuplicatePdbMappingsMade() throws Exception
312 StructureImportSettings.setProcessSecondaryStructure(true);
313 StructureImportSettings.setVisibleChainAnnotation(true);
314 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
315 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
316 assertNotNull(af, "Didn't read in the example file correctly.");
318 // locate Jmol viewer
319 // count number of PDB mappings the structure selection manager holds -
320 String pdbFile = af.getCurrentView().getStructureSelectionManager()
321 .findFileForPDBId("1A70");
323 af.getCurrentView().getStructureSelectionManager()
324 .getMapping(pdbFile).length,
325 2, "Expected only two mappings for 1A70");
329 @Test(groups = { "Functional" })
330 public void viewRefPdbAnnotation() throws Exception
332 StructureImportSettings.setProcessSecondaryStructure(true);
333 StructureImportSettings.setVisibleChainAnnotation(true);
334 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
335 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
336 assertNotNull(af, "Didn't read in the example file correctly.");
337 AlignmentViewPanel sps = null;
338 for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
340 if ("Spinach Feredoxin Structure".equals(ap.getViewName()))
346 assertNotNull(sps, "Couldn't find the structure view");
347 AlignmentAnnotation refan = null;
348 for (AlignmentAnnotation ra : sps.getAlignment()
349 .getAlignmentAnnotation())
357 assertNotNull(refan, "Annotation secondary structure not found.");
358 SequenceI sq = sps.getAlignment().findName("1A70|");
359 assertNotNull(sq, "Couldn't find 1a70 null chain");
360 // compare the manually added temperature factor annotation
361 // to the track automatically transferred from the pdb structure on load
362 assertNotNull(sq.getDatasetSequence().getAnnotation(),
363 "1a70 has no annotation");
364 for (AlignmentAnnotation ala : sq.getDatasetSequence().getAnnotation())
366 AlignmentAnnotation alaa;
367 sq.addAlignmentAnnotation(alaa = new AlignmentAnnotation(ala));
368 alaa.adjustForAlignment();
369 if (ala.graph == refan.graph)
371 for (int p = 0; p < ala.annotations.length; p++)
376 assertTrue((alaa.annotations[p] == null
377 && refan.annotations[p] == null)
378 || alaa.annotations[p].value == refan.annotations[p].value,
379 "Mismatch at alignment position " + p);
380 } catch (NullPointerException q)
382 Assert.fail("Mismatch of alignment annotations at position " + p
383 + " Ref seq ann: " + refan.annotations[p]
384 + " alignment " + alaa.annotations[p]);
392 @Test(groups = { "Functional" })
393 public void testCopyViewSettings() throws Exception
395 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
396 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
397 assertNotNull(af, "Didn't read in the example file correctly.");
398 AlignmentViewPanel sps = null, groups = null;
399 for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
401 if ("Spinach Feredoxin Structure".equals(ap.getViewName()))
405 if (ap.getViewName().contains("MAFFT"))
410 assertNotNull(sps, "Couldn't find the structure view");
411 assertNotNull(groups, "Couldn't find the MAFFT view");
413 ViewStyleI structureStyle = sps.getAlignViewport().getViewStyle();
414 ViewStyleI groupStyle = groups.getAlignViewport().getViewStyle();
415 AssertJUnit.assertFalse(structureStyle.sameStyle(groupStyle));
417 groups.getAlignViewport().setViewStyle(structureStyle);
418 AssertJUnit.assertFalse(
419 groupStyle.sameStyle(groups.getAlignViewport().getViewStyle()));
420 Assert.assertTrue(structureStyle
421 .sameStyle(groups.getAlignViewport().getViewStyle()));
426 * test store and recovery of expanded views
430 @Test(groups = { "Functional" }, enabled = true)
431 public void testStoreAndRecoverExpandedviews() throws Exception
433 Desktop.instance.closeAll_actionPerformed(null);
435 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
436 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
437 Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 1);
438 String afid = af.getViewport().getSequenceSetId();
440 // check FileLoader returned a reference to the one alignFrame that is
441 // actually on the Desktop
442 assertSame(af, Desktop.getAlignFrameFor(af.getViewport()),
443 "Jalview2XML.loadAlignFrame() didn't return correct AlignFrame reference for multiple view window");
445 Desktop.explodeViews(af);
447 int oldviews = Desktop.getDesktopAlignFrames().length;
448 Assert.assertEquals(Desktop.getDesktopAlignFrames().length,
449 Desktop.getAlignmentPanels(afid).length);
450 File tfile = File.createTempFile("testStoreAndRecoverExpanded", ".jvp");
453 new Jalview2XML(false).saveState(tfile);
456 Assert.fail("Didn't save the expanded view state", e);
457 } catch (Exception e)
459 Assert.fail("Didn't save the expanded view state", e);
461 Desktop.instance.closeAll_actionPerformed(null);
462 if (Desktop.getDesktopAlignFrames() != null)
464 Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 0);
466 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
467 DataSourceType.FILE);
468 Assert.assertNotNull(af);
469 Assert.assertEquals(Desktop.getDesktopAlignFrames().length,
470 Desktop.getAlignmentPanels(
471 af.getViewport().getSequenceSetId()).length);
472 Assert.assertEquals(Desktop
473 .getAlignmentPanels(af.getViewport().getSequenceSetId()).length,
478 * Test save and reload of a project with a different representative sequence
483 @Test(groups = { "Functional" })
484 public void testStoreAndRecoverReferenceSeqSettings() throws Exception
486 Desktop.instance.closeAll_actionPerformed(null);
487 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
488 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
489 assertNotNull(af, "Didn't read in the example file correctly.");
490 String afid = af.getViewport().getSequenceSetId();
492 // remember reference sequence for each panel
493 Map<String, SequenceI> refseqs = new HashMap<>();
496 * mark sequence 2, 3, 4.. in panels 1, 2, 3...
497 * as reference sequence for itself and the preceding sequence
500 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
502 AlignViewportI av = ap.getAlignViewport();
503 AlignmentI alignment = ap.getAlignment();
504 int repIndex = n % alignment.getHeight();
505 SequenceI rep = alignment.getSequenceAt(repIndex);
506 refseqs.put(ap.getViewName(), rep);
508 // code from mark/unmark sequence as reference in jalview.gui.PopupMenu
509 // todo refactor this to an alignment view controller
510 av.setDisplayReferenceSeq(true);
511 av.setColourByReferenceSeq(true);
512 av.getAlignment().setSeqrep(rep);
516 File tfile = File.createTempFile("testStoreAndRecoverReferenceSeq",
520 new Jalview2XML(false).saveState(tfile);
521 } catch (Throwable e)
523 Assert.fail("Didn't save the expanded view state", e);
525 Desktop.instance.closeAll_actionPerformed(null);
526 if (Desktop.getDesktopAlignFrames() != null)
528 Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 0);
531 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
532 DataSourceType.FILE);
533 afid = af.getViewport().getSequenceSetId();
535 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
537 // check representative
538 AlignmentI alignment = ap.getAlignment();
539 SequenceI rep = alignment.getSeqrep();
540 Assert.assertNotNull(rep,
541 "Couldn't restore sequence representative from project");
542 // can't use a strong equals here, because by definition, the sequence IDs
543 // will be different.
544 // could set vamsas session save/restore flag to preserve IDs across
546 Assert.assertEquals(refseqs.get(ap.getViewName()).toString(),
548 "Representative wasn't the same when recovered.");
549 Assert.assertTrue(ap.getAlignViewport().isDisplayReferenceSeq(),
550 "Display reference sequence view setting not set.");
551 Assert.assertTrue(ap.getAlignViewport().isColourByReferenceSeq(),
552 "Colour By Reference Seq view setting not set.");
556 @Test(groups = { "Functional" })
557 public void testIsVersionStringLaterThan()
560 * No version / development / test / autobuild is leniently assumed to be
563 assertTrue(Jalview2XML.isVersionStringLaterThan(null, null));
564 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", null));
565 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "2.8.3"));
566 assertTrue(Jalview2XML.isVersionStringLaterThan(null,
567 "Development Build"));
568 assertTrue(Jalview2XML.isVersionStringLaterThan(null,
569 "DEVELOPMENT BUILD"));
570 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
571 "Development Build"));
572 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "Test"));
573 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "TEST"));
574 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "Test"));
576 Jalview2XML.isVersionStringLaterThan(null, "Automated Build"));
577 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
579 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
583 * same version returns true i.e. compatible
585 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8", "2.8"));
586 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.3"));
587 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3b1"));
588 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3B1", "2.8.3b1"));
589 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3B1"));
592 * later version returns true
594 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.4"));
595 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.9"));
596 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.9.2"));
597 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8", "2.8.3"));
598 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.3b1"));
601 * earlier version returns false
603 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8"));
604 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.4", "2.8.3"));
605 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3"));
606 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.2b1"));
607 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.0b2", "2.8.0b1"));
609 * test for patch release versions
611 assertFalse(Jalview2XML.isVersionStringLaterThan("2.11.3.0", "2.11.2"));
612 assertTrue(Jalview2XML.isVersionStringLaterThan("2.11.3.0", "2.11.4"));
614 Jalview2XML.isVersionStringLaterThan("2.12.2.0b1", "2.12.2.0"));
616 Jalview2XML.isVersionStringLaterThan("2.12.2.3", "2.12.2.2"));
621 * Test save and reload of a project with a different sequence group (and
622 * representative sequence) in each view.
626 @Test(groups = { "Functional" })
627 public void testStoreAndRecoverGroupRepSeqs() throws Exception
629 Desktop.instance.closeAll_actionPerformed(null);
630 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
631 "examples/uniref50.fa", DataSourceType.FILE);
632 assertNotNull(af, "Didn't read in the example file correctly.");
633 String afid = af.getViewport().getSequenceSetId();
634 // make a second view of the alignment
635 af.newView_actionPerformed(null);
638 * remember representative and hidden sequences marked
641 Map<String, SequenceI> repSeqs = new HashMap<>();
642 Map<String, List<String>> hiddenSeqNames = new HashMap<>();
645 * mark sequence 2, 3, 4.. in panels 1, 2, 3...
646 * as reference sequence for itself and the preceding sequence
649 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
651 AlignViewportI av = ap.getAlignViewport();
652 AlignmentI alignment = ap.getAlignment();
653 int repIndex = n % alignment.getHeight();
654 // ensure at least one preceding sequence i.e. index >= 1
655 repIndex = Math.max(repIndex, 1);
656 SequenceI repSeq = alignment.getSequenceAt(repIndex);
657 repSeqs.put(ap.getViewName(), repSeq);
658 List<String> hiddenNames = new ArrayList<>();
659 hiddenSeqNames.put(ap.getViewName(), hiddenNames);
662 * have rep sequence represent itself and the one before it
663 * this hides the group (except for the rep seq)
665 SequenceGroup sg = new SequenceGroup();
666 sg.addSequence(repSeq, false);
667 SequenceI precedingSeq = alignment.getSequenceAt(repIndex - 1);
668 sg.addSequence(precedingSeq, false);
669 sg.setSeqrep(repSeq);
670 assertTrue(sg.getSequences().contains(repSeq));
671 assertTrue(sg.getSequences().contains(precedingSeq));
672 av.setSelectionGroup(sg);
673 assertSame(repSeq, sg.getSeqrep());
676 * represent group with sequence adds to a map of hidden rep sequences
677 * (it does not create a group on the alignment)
679 ((AlignmentViewport) av).hideSequences(repSeq, true);
680 assertSame(repSeq, sg.getSeqrep());
681 assertTrue(sg.getSequences().contains(repSeq));
682 assertTrue(sg.getSequences().contains(precedingSeq));
683 assertTrue(alignment.getGroups().isEmpty(), "alignment has groups");
684 Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av
685 .getHiddenRepSequences();
686 assertNotNull(hiddenRepSeqsMap);
687 assertEquals(1, hiddenRepSeqsMap.size());
688 assertSame(sg, hiddenRepSeqsMap.get(repSeq));
689 assertTrue(alignment.getHiddenSequences().isHidden(precedingSeq));
690 assertFalse(alignment.getHiddenSequences().isHidden(repSeq));
691 hiddenNames.add(precedingSeq.getName());
695 File tfile = File.createTempFile("testStoreAndRecoverGroupReps",
699 new Jalview2XML(false).saveState(tfile);
700 } catch (Throwable e)
702 Assert.fail("Didn't save the expanded view state", e);
704 Desktop.instance.closeAll_actionPerformed(null);
705 if (Desktop.getDesktopAlignFrames() != null)
707 Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 0);
710 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
711 DataSourceType.FILE);
712 afid = af.getViewport().getSequenceSetId();
714 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
716 String viewName = ap.getViewName();
717 AlignViewportI av = ap.getAlignViewport();
718 AlignmentI alignment = ap.getAlignment();
719 List<SequenceGroup> groups = alignment.getGroups();
720 assertNotNull(groups);
721 assertTrue(groups.isEmpty(), "Alignment has groups");
722 Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av
723 .getHiddenRepSequences();
724 assertNotNull(hiddenRepSeqsMap, "No hidden represented sequences");
725 assertEquals(1, hiddenRepSeqsMap.size());
726 assertEquals(repSeqs.get(viewName).getDisplayId(true),
727 hiddenRepSeqsMap.keySet().iterator().next()
728 .getDisplayId(true));
731 * verify hidden sequences in restored panel
733 List<String> hidden = hiddenSeqNames.get(ap.getViewName());
734 HiddenSequences hs = alignment.getHiddenSequences();
735 assertEquals(hidden.size(), hs.getSize(),
736 "wrong number of restored hidden sequences in "
742 * Test save and reload of PDBEntry in Jalview project
746 @Test(groups = { "Functional" })
747 public void testStoreAndRecoverPDBEntry() throws Exception
749 Desktop.instance.closeAll_actionPerformed(null);
750 String exampleFile = "examples/3W5V.pdb";
751 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
752 DataSourceType.FILE);
753 assertNotNull(af, "Didn't read in the example file correctly.");
754 String afid = af.getViewport().getSequenceSetId();
756 AlignmentPanel[] alignPanels = Desktop.getAlignmentPanels(afid);
757 System.out.println();
758 AlignmentViewPanel ap = alignPanels[0];
759 String tfileBase = new File(".").getAbsolutePath().replace(".", "");
760 String testFile = tfileBase + exampleFile;
761 AlignmentI alignment = ap.getAlignment();
762 System.out.println("blah");
763 SequenceI[] seqs = alignment.getSequencesArray();
764 Assert.assertNotNull(seqs[0]);
765 Assert.assertNotNull(seqs[1]);
766 Assert.assertNotNull(seqs[2]);
767 Assert.assertNotNull(seqs[3]);
768 Assert.assertNotNull(seqs[0].getDatasetSequence());
769 Assert.assertNotNull(seqs[1].getDatasetSequence());
770 Assert.assertNotNull(seqs[2].getDatasetSequence());
771 Assert.assertNotNull(seqs[3].getDatasetSequence());
772 PDBEntry[] pdbEntries = new PDBEntry[4];
773 pdbEntries[0] = new PDBEntry("3W5V", "A", Type.PDB, testFile);
774 pdbEntries[1] = new PDBEntry("3W5V", "B", Type.PDB, testFile);
775 pdbEntries[2] = new PDBEntry("3W5V", "C", Type.PDB, testFile);
776 pdbEntries[3] = new PDBEntry("3W5V", "D", Type.PDB, testFile);
778 seqs[0].getDatasetSequence().getAllPDBEntries().get(0),
781 seqs[1].getDatasetSequence().getAllPDBEntries().get(0),
784 seqs[2].getDatasetSequence().getAllPDBEntries().get(0),
787 seqs[3].getDatasetSequence().getAllPDBEntries().get(0),
790 File tfile = File.createTempFile("testStoreAndRecoverPDBEntry", ".jvp");
793 new Jalview2XML(false).saveState(tfile);
794 } catch (Throwable e)
796 Assert.fail("Didn't save the state", e);
798 Desktop.instance.closeAll_actionPerformed(null);
799 if (Desktop.getDesktopAlignFrames() != null)
801 Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 0);
804 AlignFrame restoredFrame = new FileLoader().LoadFileWaitTillLoaded(
805 tfile.getAbsolutePath(), DataSourceType.FILE);
806 String rfid = restoredFrame.getViewport().getSequenceSetId();
807 AlignmentPanel[] rAlignPanels = Desktop.getAlignmentPanels(rfid);
808 AlignmentViewPanel rap = rAlignPanels[0];
809 AlignmentI rAlignment = rap.getAlignment();
810 System.out.println("blah");
811 SequenceI[] rseqs = rAlignment.getSequencesArray();
812 Assert.assertNotNull(rseqs[0]);
813 Assert.assertNotNull(rseqs[1]);
814 Assert.assertNotNull(rseqs[2]);
815 Assert.assertNotNull(rseqs[3]);
816 Assert.assertNotNull(rseqs[0].getDatasetSequence());
817 Assert.assertNotNull(rseqs[1].getDatasetSequence());
818 Assert.assertNotNull(rseqs[2].getDatasetSequence());
819 Assert.assertNotNull(rseqs[3].getDatasetSequence());
821 // The Asserts below are expected to fail until the PDB chainCode is
822 // recoverable from a Jalview projects
823 for (int chain = 0; chain < 4; chain++)
825 PDBEntry recov = rseqs[chain].getDatasetSequence().getAllPDBEntries()
827 PDBEntry expected = pdbEntries[chain];
828 Assert.assertEquals(recov.getId(), expected.getId(),
830 Assert.assertEquals(recov.getChainCode(), expected.getChainCode(),
832 Assert.assertEquals(recov.getType(), expected.getType(),
833 "Mismatch PDBEntry 'Type'");
834 Assert.assertNotNull(recov.getFile(),
835 "Recovered PDBEntry should have a non-null file entry");
837 recov.getFile().toLowerCase(Locale.ENGLISH)
839 recov.getFile().length() - 3,
840 "Recovered PDBEntry file should have PDB suffix");
845 * Configure an alignment and a sub-group each with distinct colour schemes,
846 * Conservation and PID thresholds, and confirm these are restored from the
849 * @throws IOException
851 @Test(groups = { "Functional" })
852 public void testStoreAndRecoverAnnotationRowElementColours()
855 Desktop.instance.closeAll_actionPerformed(null);
856 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded("SEQ\tMNQ",
857 DataSourceType.PASTE);
859 AlignViewport av = af.getViewport();
860 AlignmentI al = av.getAlignment();
862 fsq = al.getSequenceAt(0);
863 Annotation annots[] = new Annotation[fsq.getLength()];
864 AlignmentAnnotation ala = new AlignmentAnnotation("Colour", "Annots",
866 annots[0] = new Annotation(1.0f);
867 annots[1] = new Annotation(2.0f);
868 annots[2] = new Annotation(3.0f);
869 annots[0].colour = Color.RED;
870 annots[1].colour = Color.GREEN;
871 annots[2].colour = Color.BLUE;
872 ala.validateRangeAndDisplay();
873 al.getSequenceAt(0).addAlignmentAnnotation(ala);
874 al.addAnnotation(ala);
876 * and colour by annotation
878 AnnotationColourGradient acg = new AnnotationColourGradient(ala,
879 af.alignPanel.av.getGlobalColourScheme(), 0);
880 acg.setSeqAssociated(true);
881 acg.setPredefinedColours(true);
882 af.changeColour(acg);
883 Color seqcol[] = new Color[3];
884 for (int iStart = fsq.findIndex(fsq.getStart()), i = 0; i < 3; i++)
886 seqcol[i] = af.alignPanel.getSeqPanel().seqCanvas
887 .getSequenceRenderer()
888 .getResidueColour(fsq, iStart + i, null);
891 * save project, close windows, reload project, verify
893 File tfile = File.createTempFile(
894 "testStoreAndRecoverAnnotRowElemColors", ".jvp");
895 tfile.deleteOnExit();
896 new Jalview2XML(false).saveState(tfile);
897 // Desktop.instance.closeAll_actionPerformed(null);
898 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
899 DataSourceType.FILE);
900 Assert.assertNotNull(af, "Failed to reload project");
902 * verify alignment annotation has colors
904 av = af.getViewport();
906 ColourSchemeI loadedCscheme = av.getGlobalColourScheme();
907 Assert.assertTrue(loadedCscheme instanceof AnnotationColourGradient,
908 "Didn't apply Annotation colour gradient");
909 acg = (AnnotationColourGradient) loadedCscheme;
910 assertTrue(acg.isSeqAssociated());
911 assertTrue(acg.isPredefinedColours());
913 al = av.getAlignment();
914 fsq = al.getSequenceAt(0);
915 ala = fsq.getAnnotation()[0];
916 Assert.assertNotNull(ala, "No annotation row recovered");
917 Assert.assertNotNull(ala.annotations);
918 for (int iStart = al.getSequenceAt(0)
919 .findIndex(al.getSequenceAt(0).getStart()), i = 0; i < 3; i++)
921 Assert.assertTrue(ala.annotations[i].colour != null);
922 Assert.assertTrue(ala.annotations[i].colour.equals(annots[i].colour));
923 Color newseqcol = af.alignPanel.getSeqPanel().seqCanvas
924 .getSequenceRenderer()
925 .getResidueColour(fsq, iStart + i, null);
926 Assert.assertTrue(seqcol[i].equals(newseqcol),
927 "Sequence shading is different");
934 * Configure an alignment and a sub-group each with distinct colour schemes,
935 * Conservation and PID thresholds, and confirm these are restored from the
938 * @throws IOException
940 @Test(groups = { "Functional" })
941 public void testStoreAndRecoverColourThresholds() throws IOException
943 Desktop.instance.closeAll_actionPerformed(null);
944 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
945 "examples/uniref50.fa", DataSourceType.FILE);
947 AlignViewport av = af.getViewport();
948 AlignmentI al = av.getAlignment();
951 * Colour alignment by Buried Index, Above 10% PID, By Conservation 20%
953 av.setColourAppliesToAllGroups(false);
954 af.changeColour_actionPerformed(JalviewColourScheme.Buried.toString());
955 assertTrue(av.getGlobalColourScheme() instanceof BuriedColourScheme);
956 af.abovePIDThreshold_actionPerformed(true);
957 SliderPanel sp = SliderPanel.getSliderPanel();
958 assertFalse(sp.isForConservation());
960 af.conservationMenuItem_actionPerformed(true);
961 sp = SliderPanel.getSliderPanel();
962 assertTrue(sp.isForConservation());
964 ResidueShaderI rs = av.getResidueShading();
965 assertEquals(rs.getThreshold(), 10);
966 assertTrue(rs.conservationApplied());
967 assertEquals(rs.getConservationInc(), 20);
970 * create a group with Strand colouring, 30% Conservation
971 * and 40% PID threshold
972 * (notice menu action applies to selection group even if mouse click
973 * is at a sequence not in the group)
975 SequenceGroup sg = new SequenceGroup();
976 sg.addSequence(al.getSequenceAt(0), false);
979 av.setSelectionGroup(sg);
980 PopupMenu popupMenu = new PopupMenu(af.alignPanel, al.getSequenceAt(2),
982 popupMenu.changeColour_actionPerformed(
983 JalviewColourScheme.Strand.toString());
984 assertTrue(sg.getColourScheme() instanceof StrandColourScheme);
985 assertEquals(al.getGroups().size(), 1);
986 assertSame(al.getGroups().get(0), sg);
987 popupMenu.conservationMenuItem_actionPerformed(true);
988 sp = SliderPanel.getSliderPanel();
989 assertTrue(sp.isForConservation());
991 popupMenu.abovePIDColour_actionPerformed(true);
992 sp = SliderPanel.getSliderPanel();
993 assertFalse(sp.isForConservation());
995 assertTrue(sg.getGroupColourScheme().conservationApplied());
996 assertEquals(sg.getGroupColourScheme().getConservationInc(), 30);
997 assertEquals(sg.getGroupColourScheme().getThreshold(), 40);
1000 * save project, close windows, reload project, verify
1002 File tfile = File.createTempFile("testStoreAndRecoverColourThresholds",
1004 tfile.deleteOnExit();
1005 new Jalview2XML(false).saveState(tfile);
1006 Desktop.instance.closeAll_actionPerformed(null);
1007 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
1008 DataSourceType.FILE);
1009 Assert.assertNotNull(af, "Failed to reload project");
1012 * verify alignment (background) colouring
1014 rs = af.getViewport().getResidueShading();
1015 assertTrue(rs.getColourScheme() instanceof BuriedColourScheme);
1016 assertEquals(rs.getThreshold(), 10);
1017 assertTrue(rs.conservationApplied());
1018 assertEquals(rs.getConservationInc(), 20);
1021 * verify group colouring
1023 assertEquals(1, af.getViewport().getAlignment().getGroups().size(), 1);
1024 rs = af.getViewport().getAlignment().getGroups().get(0)
1025 .getGroupColourScheme();
1026 assertTrue(rs.getColourScheme() instanceof StrandColourScheme);
1027 assertEquals(rs.getThreshold(), 40);
1028 assertTrue(rs.conservationApplied());
1029 assertEquals(rs.getConservationInc(), 30);
1033 * Test save and reload of feature colour schemes and filter settings
1035 * @throws IOException
1037 @Test(groups = { "Functional" })
1038 public void testSaveLoadFeatureColoursAndFilters() throws IOException
1040 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1041 ">Seq1\nACDEFGHIKLM", DataSourceType.PASTE);
1042 SequenceI seq1 = af.getViewport().getAlignment().getSequenceAt(0);
1045 * add some features to the sequence
1048 addFeatures(seq1, "type1", score++);
1049 addFeatures(seq1, "type2", score++);
1050 addFeatures(seq1, "type3", score++);
1051 addFeatures(seq1, "type4", score++);
1052 addFeatures(seq1, "type5", score++);
1055 * set colour schemes for features
1057 FeatureRendererModel fr = af.getFeatureRenderer();
1058 fr.findAllFeatures(true);
1061 fr.setColour("type1", new FeatureColour(Color.red));
1064 FeatureColourI byLabel = new FeatureColour();
1065 byLabel.setColourByLabel(true);
1066 fr.setColour("type2", byLabel);
1068 // type3: by score above threshold
1069 FeatureColourI byScore = new FeatureColour(null, Color.BLACK,
1070 Color.BLUE, null, 1, 10);
1071 byScore.setAboveThreshold(true);
1072 byScore.setThreshold(2f);
1073 fr.setColour("type3", byScore);
1075 // type4: by attribute AF
1076 FeatureColourI byAF = new FeatureColour();
1077 byAF.setColourByLabel(true);
1078 byAF.setAttributeName("AF");
1079 fr.setColour("type4", byAF);
1081 // type5: by attribute CSQ:PolyPhen below threshold
1082 FeatureColourI byPolyPhen = new FeatureColour(null, Color.BLACK,
1083 Color.BLUE, null, 1, 10);
1084 byPolyPhen.setBelowThreshold(true);
1085 byPolyPhen.setThreshold(3f);
1086 byPolyPhen.setAttributeName("CSQ", "PolyPhen");
1087 fr.setColour("type5", byPolyPhen);
1090 * set filters for feature types
1093 // filter type1 features by (label contains "x")
1094 FeatureMatcherSetI filterByX = new FeatureMatcherSet();
1095 filterByX.and(FeatureMatcher.byLabel(Condition.Contains, "x"));
1096 fr.setFeatureFilter("type1", filterByX);
1098 // filter type2 features by (score <= 2.4 and score > 1.1)
1099 FeatureMatcherSetI filterByScore = new FeatureMatcherSet();
1100 filterByScore.and(FeatureMatcher.byScore(Condition.LE, "2.4"));
1101 filterByScore.and(FeatureMatcher.byScore(Condition.GT, "1.1"));
1102 fr.setFeatureFilter("type2", filterByScore);
1104 // filter type3 features by (AF contains X OR CSQ:PolyPhen != 0)
1105 FeatureMatcherSetI filterByXY = new FeatureMatcherSet();
1107 .and(FeatureMatcher.byAttribute(Condition.Contains, "X", "AF"));
1108 filterByXY.or(FeatureMatcher.byAttribute(Condition.NE, "0", "CSQ",
1110 fr.setFeatureFilter("type3", filterByXY);
1113 * save as Jalview project
1115 File tfile = File.createTempFile("JalviewTest", ".jvp");
1116 tfile.deleteOnExit();
1117 String filePath = tfile.getAbsolutePath();
1118 af.saveAlignment(filePath, FileFormat.Jalview);
1119 assertTrue(af.isSaveAlignmentSuccessful(),
1120 "Failed to store as a project.");
1123 * close current alignment and load the saved project
1125 af.closeMenuItem_actionPerformed(true);
1127 af = new FileLoader().LoadFileWaitTillLoaded(filePath,
1128 DataSourceType.FILE);
1129 assertNotNull(af, "Failed to import new project");
1132 * verify restored feature colour schemes and filters
1134 fr = af.getFeatureRenderer();
1135 FeatureColourI fc = fr.getFeatureStyle("type1");
1136 assertTrue(fc.isSimpleColour());
1137 assertEquals(fc.getColour(), Color.red);
1138 fc = fr.getFeatureStyle("type2");
1139 assertTrue(fc.isColourByLabel());
1140 fc = fr.getFeatureStyle("type3");
1141 assertTrue(fc.isGraduatedColour());
1142 assertNull(fc.getAttributeName());
1143 assertTrue(fc.isAboveThreshold());
1144 assertEquals(fc.getThreshold(), 2f);
1145 fc = fr.getFeatureStyle("type4");
1146 assertTrue(fc.isColourByLabel());
1147 assertTrue(fc.isColourByAttribute());
1148 assertEquals(fc.getAttributeName(), new String[] { "AF" });
1149 fc = fr.getFeatureStyle("type5");
1150 assertTrue(fc.isGraduatedColour());
1151 assertTrue(fc.isColourByAttribute());
1152 assertEquals(fc.getAttributeName(), new String[] { "CSQ", "PolyPhen" });
1153 assertTrue(fc.isBelowThreshold());
1154 assertEquals(fc.getThreshold(), 3f);
1156 assertEquals(fr.getFeatureFilter("type1").toStableString(),
1157 "Label Contains x");
1158 assertEquals(fr.getFeatureFilter("type2").toStableString(),
1159 "(Score LE 2.4) AND (Score GT 1.1)");
1160 assertEquals(fr.getFeatureFilter("type3").toStableString(),
1161 "(AF Contains X) OR (CSQ:PolyPhen NE 0)");
1164 private void addFeature(SequenceI seq, String featureType, int score)
1166 SequenceFeature sf = new SequenceFeature(featureType, "desc", 1, 2,
1168 sf.setValue("AF", score);
1169 sf.setValue("CSQ", new HashMap<String, String>()
1172 put("PolyPhen", Integer.toString(score));
1175 seq.addSequenceFeature(sf);
1179 * Adds two features of the given type to the given sequence, also setting the
1180 * score as the value of attribute "AF" and sub-attribute "CSQ:PolyPhen"
1183 * @param featureType
1186 private void addFeatures(SequenceI seq, String featureType, int score)
1188 addFeature(seq, featureType, score++);
1189 addFeature(seq, featureType, score);
1193 * pre 2.11 - jalview 2.10 erroneously created new dataset entries for each
1194 * view (JAL-3171) this test ensures we can import and merge those views
1196 @Test(groups = { "Functional" })
1197 public void testMergeDatasetsforViews() throws IOException
1199 // simple project - two views on one alignment
1200 AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
1201 "examples/testdata/projects/twoViews.jvp", DataSourceType.FILE);
1203 assertTrue(af.getAlignPanels().size() > 1);
1208 * pre 2.11 - jalview 2.10 erroneously created new dataset entries for each
1209 * view (JAL-3171) this test ensures we can import and merge those views This
1210 * is a more complex project
1212 @Test(groups = { "Functional" })
1213 public void testMergeDatasetsforManyViews() throws IOException
1215 Desktop.instance.closeAll_actionPerformed(null);
1217 // complex project - one dataset, several views on several alignments
1218 AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
1219 "examples/testdata/projects/manyViews.jvp",
1220 DataSourceType.FILE);
1223 AlignmentI ds = null;
1224 for (AlignFrame alignFrame : Desktop.getDesktopAlignFrames())
1228 ds = verifyDs(alignFrame);
1232 // check that this frame's dataset matches the last
1233 assertTrue(ds == verifyDs(alignFrame));
1238 private AlignmentI verifyDs(AlignFrame af)
1240 AlignmentI ds = null;
1241 for (AlignmentViewPanel ap : af.getAlignPanels())
1245 ds = ap.getAlignment().getDataset();
1249 assertTrue(ap.getAlignment().getDataset() == ds,
1250 "Dataset was not the same for imported 2.10.5 project with several alignment views");
1256 @Test(groups = "Functional")
1257 public void testPcaViewAssociation() throws IOException
1259 Desktop.instance.closeAll_actionPerformed(null);
1260 final String PCAVIEWNAME = "With PCA";
1261 // create a new tempfile
1262 File tempfile = File.createTempFile("jvPCAviewAssoc", "jvp");
1265 String exampleFile = "examples/uniref50.fa";
1266 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
1267 DataSourceType.FILE);
1268 assertNotNull(af, "Didn't read in the example file correctly.");
1269 AlignmentPanel origView = (AlignmentPanel) af.getAlignPanels().get(0);
1270 AlignmentPanel newview = af.newView(PCAVIEWNAME, true);
1271 // create another for good measure
1272 af.newView("Not the PCA View", true);
1273 PCAPanel pcaPanel = new PCAPanel(origView, "BLOSUM62",
1274 new SimilarityParams(true, true, true, false));
1275 // we're in the test exec thread, so we can just run synchronously here
1278 // now switch the linked view
1279 pcaPanel.selectAssociatedView(newview);
1281 assertTrue(pcaPanel.getAlignViewport() == newview.getAlignViewport(),
1282 "PCA should be associated with 'With PCA' view: test is broken");
1284 // now save and reload project
1285 Jalview2XML jv2xml = new jalview.project.Jalview2XML(false);
1287 jv2xml.saveState(tempfile);
1288 assertTrue(jv2xml.errorMessage == null,
1289 "Failed to save dummy project with PCA: test broken");
1293 Desktop.instance.closeAll_actionPerformed(null);
1294 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1295 tempfile.getCanonicalPath(), DataSourceType.FILE);
1296 JInternalFrame[] frames = Desktop.instance.getAllFrames();
1297 // PCA and the tabbed alignment view should be the only two windows on the
1299 assertEquals(frames.length, 2,
1300 "PCA and the tabbed alignment view should be the only two windows on the desktop");
1301 PCAPanel pcaPanel = (PCAPanel) frames[frames[0] == af ? 1 : 0];
1303 AlignmentViewPanel restoredNewView = null;
1304 for (AlignmentViewPanel alignpanel : Desktop.getAlignmentPanels(null))
1306 if (alignpanel.getAlignViewport() == pcaPanel.getAlignViewport())
1308 restoredNewView = alignpanel;
1311 assertEquals(restoredNewView.getViewName(), PCAVIEWNAME);
1313 restoredNewView.getAlignViewport() == pcaPanel
1314 .getAlignViewport(),
1315 "Didn't restore correct view association for the PCA view");
1319 * Test save and reload of DBRefEntry including GeneLocus in project
1323 @Test(groups = { "Functional" })
1324 public void testStoreAndRecoverGeneLocus() throws Exception
1326 Desktop.instance.closeAll_actionPerformed(null);
1327 String seqData = ">P30419\nACDE\n>X1235\nGCCTGTGACGAA";
1328 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(seqData,
1329 DataSourceType.PASTE);
1330 assertNotNull(af, "Didn't read in the example file correctly.");
1332 AlignmentViewPanel ap = Desktop.getAlignmentPanels(null)[0];
1333 SequenceI pep = ap.getAlignment().getSequenceAt(0);
1334 SequenceI cds = ap.getAlignment().getSequenceAt(1);
1337 * give 'protein' a dbref to self, a dbref with map to CDS,
1338 * and a dbref with map to gene 'locus'
1340 DBRefEntry dbref1 = new DBRefEntry("Uniprot", "1", "P30419", null);
1341 pep.addDBRef(dbref1);
1342 Mapping cdsmap = new Mapping(cds,
1343 new MapList(new int[]
1344 { 1, 4 }, new int[] { 1, 12 }, 1, 3));
1345 DBRefEntry dbref2 = new DBRefEntry("EMBLCDS", "2", "X1235", cdsmap);
1346 pep.addDBRef(dbref2);
1347 Mapping locusmap = new Mapping(null,
1348 new MapList(new int[]
1349 { 1, 4 }, new int[] { 2674123, 2674135 }, 1, 3));
1350 DBRefEntry dbref3 = new GeneLocus("human", "GRCh38", "5", locusmap);
1351 pep.addDBRef(dbref3);
1353 File tfile = File.createTempFile("testStoreAndRecoverGeneLocus",
1357 new Jalview2XML(false).saveState(tfile);
1358 } catch (Throwable e)
1360 Assert.fail("Didn't save the state", e);
1362 Desktop.instance.closeAll_actionPerformed(null);
1364 new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
1365 DataSourceType.FILE);
1366 AlignmentViewPanel rap = Desktop.getAlignmentPanels(null)[0];
1367 SequenceI rpep = rap.getAlignment().getSequenceAt(0);
1368 DBModList<DBRefEntry> dbrefs = rpep.getDBRefs();
1369 assertEquals(rpep.getName(), "P30419");
1370 assertEquals(dbrefs.size(), 3);
1371 DBRefEntry dbRef = dbrefs.get(0);
1372 assertFalse(dbRef instanceof GeneLocus);
1373 assertNull(dbRef.getMap());
1374 assertEquals(dbRef, dbref1);
1377 * restored dbrefs with mapping have a different 'map to'
1378 * sequence but otherwise match the original dbrefs
1380 dbRef = dbrefs.get(1);
1381 assertFalse(dbRef instanceof GeneLocus);
1382 assertTrue(dbRef.equalRef(dbref2));
1383 assertNotNull(dbRef.getMap());
1384 SequenceI rcds = rap.getAlignment().getSequenceAt(1);
1385 assertSame(dbRef.getMap().getTo(), rcds);
1386 // compare MapList but not map.to
1387 assertEquals(dbRef.getMap().getMap(), dbref2.getMap().getMap());
1390 * GeneLocus map.to is null so can compare Mapping objects
1392 dbRef = dbrefs.get(2);
1393 assertTrue(dbRef instanceof GeneLocus);
1394 assertEquals(dbRef, dbref3);
1398 * test store and recovery of Overview windows
1402 @Test(groups = { "Functional" }, enabled = true)
1403 public void testStoreAndRecoverOverview() throws Exception
1405 Desktop.instance.closeAll_actionPerformed(null);
1407 Cache.setProperty("SHOW_OVERVIEW", "false");
1408 Cache.setProperty(Preferences.USE_LEGACY_GAP, "false");
1409 Cache.setColourProperty(Preferences.GAP_COLOUR, Color.green);
1410 Cache.setColourProperty(Preferences.HIDDEN_COLOUR, Color.yellow);
1411 Cache.setProperty(Preferences.SHOW_OV_HIDDEN_AT_START, "true");
1413 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1414 "examples/uniref50.fa", DataSourceType.FILE);
1417 * open and resize / reposition overview
1419 af.overviewMenuItem_actionPerformed(null);
1420 OverviewPanel ov1 = af.alignPanel.getOverviewPanel();
1422 ov1.setFrameBounds(20, 30, 200, 400);
1423 assertEquals(ov1.getTitle(), "Overview examples/uniref50.fa");
1424 assertTrue(ov1.isShowHiddenRegions());
1427 * open a New View and its Overview and reposition it
1429 af.newView_actionPerformed(null);
1430 af.overviewMenuItem_actionPerformed(null);
1431 OverviewPanel ov2 = af.alignPanel.getOverviewPanel();
1433 assertNotSame(ov1, ov2);
1434 ov2.setFrameBounds(25, 35, 205, 405);
1435 assertEquals(ov1.getTitle(), "Overview examples/uniref50.fa Original");
1436 assertEquals(ov2.getTitle(), "Overview examples/uniref50.fa View 1");
1438 File tfile = File.createTempFile("testStoreAndRecoverOverview", ".jvp");
1439 new Jalview2XML(false).saveState(tfile);
1440 Desktop.instance.closeAll_actionPerformed(null);
1443 * change preferences (should _not_ affect reloaded Overviews)
1445 Cache.setProperty("SHOW_OVERVIEW", "true");
1446 Cache.setProperty(Preferences.USE_LEGACY_GAP, "true");
1447 Cache.setColourProperty(Preferences.GAP_COLOUR, Color.blue);
1448 Cache.setColourProperty(Preferences.HIDDEN_COLOUR, Color.orange);
1449 Cache.setProperty(Preferences.SHOW_OV_HIDDEN_AT_START, "false");
1451 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
1452 DataSourceType.FILE);
1455 * workaround: explicitly select View 1 (not in focus after restore)
1457 af.tabSelectionChanged(1);
1460 * verify restored overview for View 1
1462 ov2 = af.alignPanel.getOverviewPanel();
1463 assertEquals(ov2.getCanvas().getGapColour(), Color.green);
1464 // 'non-legacy' colouring uses white for non-gapped residues
1465 assertEquals(ov2.getCanvas().getResidueColour(), Color.white);
1466 assertEquals(ov2.getCanvas().getHiddenColour(), Color.yellow);
1467 assertEquals(ov2.getTitle(), "Overview examples/uniref50.fa View 1");
1468 assertEquals(ov2.getFrameBounds(), new Rectangle(25, 35, 205, 405));
1469 assertTrue(ov2.isShowHiddenRegions());
1472 * verify restored overview for Original view
1474 af.tabSelectionChanged(0);
1475 ov1 = af.alignPanel.getOverviewPanel();
1476 assertEquals(ov1.getCanvas().getGapColour(), Color.green);
1477 // 'non-legacy' colouring uses white for non-gapped residues
1478 assertEquals(ov1.getCanvas().getResidueColour(), Color.white);
1479 assertEquals(ov1.getCanvas().getHiddenColour(), Color.yellow);
1480 assertEquals(ov1.getTitle(), "Overview examples/uniref50.fa Original");
1482 double scaling = jalview.gui.JvSwingUtilsTest.getScaling(ov1);
1483 int width = scaling == 1.0 ? 225 : 200;
1484 Rectangle ov1Rectangle = ov1.getFrameBounds();
1485 assertEquals(ov1Rectangle, new Rectangle(20, 30, width, 400));
1486 assertTrue(ov1.isShowHiddenRegions());
1490 * Test that a view with no Overview is restored with no Overview, even if
1491 * 'Open Overview' is selected in Preferences
1495 @Test(groups = { "Functional" }, enabled = true)
1496 public void testStoreAndRecoverNoOverview() throws Exception
1498 Cache.setProperty("SHOW_OVERVIEW", "false");
1499 Desktop.instance.closeAll_actionPerformed(null);
1500 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1501 ">seq1\nMATRSQFLVNF\n", DataSourceType.PASTE);
1503 File tfile = File.createTempFile("testStoreAndRecoverOverview", ".jvp");
1504 new Jalview2XML(false).saveState(tfile);
1505 Desktop.instance.closeAll_actionPerformed(null);
1507 Cache.setProperty("SHOW_OVERVIEW", "true");
1508 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
1509 DataSourceType.FILE);
1511 assertNull(af.alignPanel.getOverviewPanel());
1515 * Test that a view from an older version of Jalview is restored with Overview
1516 * automatically shown when the preference is set
1520 @Test(groups = { "Functional" }, enabled = true)
1521 public void testAutoShowOverviewForLegacyProjects() throws Exception
1523 Desktop.instance.closeAll_actionPerformed(null);
1524 Cache.setProperty("SHOW_OVERVIEW", "true");
1525 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1526 "examples/exampleFile.jvp", DataSourceType.FILE);
1528 Cache.setProperty("SHOW_OVERVIEW", "false");
1529 assertNotNull(af.alignPanel.getOverviewPanel());
1533 * Test that loading example.jvp, doing some stuff, then hitting reload
1534 * doesn't leave the modified window still open
1536 * See JAL-4127 - interactively performing the same actions and reloading
1537 * works fine, but programmatically they do not
1541 @Test(groups = { "Functional" }, enabled = false)
1542 public void testReloadActuallyReloads() throws Exception
1544 Desktop.instance.closeAll_actionPerformed(null);
1545 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1546 "examples/exampleFile.jvp", DataSourceType.FILE);
1547 af.getViewport().getColumnSelection().addElement(3);
1548 af.hideSelColumns_actionPerformed(null);
1549 af.newView("new", true);
1550 af.reload_actionPerformed(null);
1552 // af exists still but isn't shown
1553 assertTrue(af.isClosed());
1556 @Test(groups = { "Functional" })
1557 public void testMatrixToFloatsAndBack()
1561 SequenceI sq = new Sequence("dummy", "SEQ");
1562 while (sq.getLength() < i)
1564 sq.setSequence(sq.getSequenceAsString() + 'Q');
1566 float[][] paevals = new float[i][i];
1567 for (i = imax - 1; i >= 0; i--)
1569 for (int j = 0; j <= i; j++)
1571 paevals[i][j] = ((i - j < 2)
1572 || ((i > 1 && i < 5) && (j > 1 && i < 5))) ? 1 : 0f;
1573 paevals[j][i] = -paevals[i][j];
1576 PAEContactMatrix dummyMat = new PAEContactMatrix(sq, paevals);
1577 String content = ContactMatrix.contactToFloatString(dummyMat);
1578 Assert.assertTrue(content.contains("\t1.")); // at least one element must be
1580 float[][] vals = ContactMatrix.fromFloatStringToContacts(content,
1581 sq.getLength(), sq.getLength());
1582 assertEquals(vals[3][4], paevals[3][4]);
1583 assertEquals(vals[4][3], paevals[4][3]);
1586 for (i = 0; i < imax; i++)
1588 for (int j = 0; j < imax; j++)
1590 assertEquals(vals[i][j], paevals[i][j]);
1595 @Test(groups = { "Functional" })
1596 public void testPAEsaveRestore() throws Exception
1598 Desktop.instance.closeAll_actionPerformed(null);
1599 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1600 ">seq1\nMATRSQFLVNF\n", DataSourceType.PASTE);
1601 AlignmentI al = af.getViewport().getAlignment();
1602 // PAE matrices are added as reference annotation to the dataset sequence
1603 // at least for now.
1604 SequenceI sq = al.getSequenceAt(0).getDatasetSequence();
1605 int i = sq.getLength();
1606 float[][] paevals = new float[i][i];
1607 for (i = i - 1; i >= 0; i--)
1609 for (int j = 0; j <= i; j++)
1611 paevals[i][j] = ((i - j < 2)
1612 || ((i > 1 && i < 5) && (j > 1 && i < 5))) ? 1 : 0f;
1613 paevals[j][i] = -paevals[i][j];
1616 PAEContactMatrix dummyMat = new PAEContactMatrix(sq, paevals);
1617 String content = ContactMatrix.contactToFloatString(dummyMat);
1618 Assert.assertTrue(content.contains("\t1.")); // at least one element must be
1620 float[][] vals = ContactMatrix.fromFloatStringToContacts(content,
1621 sq.getLength(), sq.getLength());
1622 assertEquals(vals[3][4], paevals[3][4]);
1623 assertEquals(vals[4][3], paevals[4][3]);
1624 dummyMat.setGroupSet(GroupSet.makeGroups(dummyMat, false, 0.5f, false));
1625 Assert.assertNotSame(dummyMat.getNewick(), "");
1626 AlignmentAnnotation paeCm = sq.addContactList(dummyMat);
1627 al.addAnnotation(paeCm);
1628 // verify store/restore of group bitsets
1629 for (BitSet gp : dummyMat.getGroups())
1631 StringBuilder sb = new StringBuilder();
1632 for (long val : gp.toLongArray())
1634 if (sb.length() > 0)
1640 String[] longvals = sb.toString().split(",");
1641 long[] newlongvals = new long[longvals.length];
1642 for (int lv = 0; lv < longvals.length; lv++)
1646 newlongvals[lv] = Long.valueOf(longvals[lv]);
1647 } catch (Exception x)
1649 Assert.fail("failed to deserialise bitset element ");
1652 BitSet newGp = BitSet.valueOf(newlongvals);
1653 assertTrue(gp.equals(newGp));
1655 File tfile = File.createTempFile("testStoreAndRecoverPAEmatrix",
1657 new Jalview2XML(false).saveState(tfile);
1658 Desktop.instance.closeAll_actionPerformed(null);
1660 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
1661 DataSourceType.FILE);
1662 AlignmentI newAl = af.getViewport().getAlignment();
1663 SequenceI newSeq = newAl.getSequenceAt(0).getDatasetSequence();
1664 // check annotation of the expected type exists
1665 Assert.assertEquals(newSeq.getAnnotation().length, 1);
1666 Assert.assertEquals(newSeq.getAnnotation()[0].graph, paeCm.graph);
1668 // check a contact matrix was recovered
1669 Assert.assertEquals(newSeq.getContactMaps().size(), 1);
1670 // and can be found for the annotation on the sequence
1671 ContactMatrixI restoredMat = newSeq
1672 .getContactMatrixFor(newSeq.getAnnotation()[0]);
1673 Assert.assertNotNull(restoredMat);
1674 MapList oldMap = ((MappableContactMatrixI) dummyMat).getMapFor(sq);
1675 MapList newMap = ((MappableContactMatrixI) restoredMat)
1677 Assert.assertEquals(oldMap.getFromRanges(), newMap.getFromRanges());
1678 Assert.assertEquals(oldMap.getToRanges(), newMap.getToRanges());
1679 Assert.assertEquals(oldMap.getFromRatio(), newMap.getFromRatio());
1680 Assert.assertEquals(oldMap.getToRatio(), newMap.getToRatio());
1681 for (i = sq.getLength() - 1; i >= 0; i--)
1683 ContactListI oldCM = dummyMat.getContactList(i),
1684 newCM = restoredMat.getContactList(i);
1685 for (int j = oldCM.getContactHeight(); j >= 0; j--)
1687 double old_j = oldCM.getContactAt(j);
1688 double new_j = newCM.getContactAt(j);
1689 Assert.assertEquals(old_j, new_j);
1692 Assert.assertEquals(restoredMat.hasGroups(), dummyMat.hasGroups());
1693 Assert.assertEquals(restoredMat.getGroups(), dummyMat.getGroups());
1694 Assert.assertEquals(restoredMat.hasTree(), dummyMat.hasTree());
1695 Assert.assertEquals(restoredMat.getNewick(), dummyMat.getNewick());
1697 // verify no duplicate PAE matrix data when new view created and saved
1699 // add reference annotations to view first, then copy
1700 AlignmentUtils.addReferenceAnnotationTo(newAl, newAl.getSequenceAt(0),
1701 newSeq.getAnnotation()[0], null);
1703 AlignmentViewPanel newview = af.newView("copy of PAE", true);
1705 // redundant asserts here check all is good with the new view firest...
1706 AlignmentI newviewAl = newview.getAlignment();
1707 SequenceI newviewSeq = newviewAl.getSequenceAt(0);
1708 // check annotation of the expected type exists
1709 Assert.assertEquals(newviewSeq.getAnnotation().length, 1);
1710 Assert.assertEquals(newviewSeq.getAnnotation()[0].graph, paeCm.graph);
1711 // check we have just one contact matrix mapping
1712 Assert.assertEquals(newviewSeq.getContactMaps().size(), 1);
1714 // and can be found for the annotation on the sequence
1715 ContactMatrixI newviewMat = newviewSeq
1716 .getContactMatrixFor(newviewSeq.getAnnotation()[0]);
1717 Assert.assertNotNull(newviewMat);
1719 Assert.assertTrue(newviewMat == restoredMat);
1721 // save the two views and restore. Now look at visible annotation to check
1722 // all views have shared refs.
1724 tfile = File.createTempFile("testStoreAndRecoverPAEmatrixTwoViews",
1726 new Jalview2XML(false).saveState(tfile);
1727 Desktop.instance.closeAll_actionPerformed(null);
1729 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
1730 DataSourceType.FILE);
1731 newAl = af.getAlignPanels().get(0).getAlignment();
1732 AlignmentAnnotation view1aa = newAl.getSequenceAt(0).getAnnotation()[0];
1734 newviewAl = af.getAlignPanels().get(1).getAlignment();
1735 AlignmentAnnotation view2aa = newviewAl.getSequenceAt(0)
1736 .getAnnotation()[0];
1738 // annotations are shared across alignment views - so should still have an
1739 // identical pair of annotations.
1740 Assert.assertTrue(view1aa == view2aa);
1741 // identical annotations means identical contact matrix mappings
1742 Assert.assertEquals(
1743 newAl.getDataset().getSequenceAt(0).getContactMaps().size(), 1);
1745 // TODO Verify when distinct mappable PAEs are created, only one PAE dataset
1746 // is actually held.
1747 // Assert.assertTrue(view1aa!=view2aa);
1748 // restoredMat = newAl.getContactMatrixFor(view1aa);
1749 // newviewMat = newviewAl.getContactMatrixFor(view2aa);
1750 // Assert.assertTrue(restoredMat!=newviewMat);
1754 @Test(groups = "Functional")
1755 public void testStoreAndRestoreIDwidthAndAnnotationHeight()
1758 Desktop.instance.closeAll_actionPerformed(null);
1759 final String SECONDVIEW = "With Diffferent IDwidth";
1760 // create a new tempfile
1761 File tempfile = File.createTempFile("jvIdWidthStoreRestore", "jvp");
1763 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1764 "examples/exampleFile.jvp", DataSourceType.FILE);
1765 assertNotNull(af, "Didn't read in the example file correctly.");
1766 // FIXME JAL-4281 test made platform dependent to pass, but probably
1767 // shouldn't be platform dependent
1768 int idWidth = af.alignPanel.getAlignViewport().getIdWidth();
1769 double scaling = jalview.gui.JvSwingUtilsTest.getScaling(af.alignPanel);
1770 int expectedWidth = Platform.isMac() ? 144
1771 : Platform.isLinux() ? scaling == 1.0 ? 131 : 128 : 138;
1772 System.err.println("##### scaling=" + scaling + ", idWidth=" + idWidth
1773 + ", expectedWidth=" + expectedWidth);
1774 assertEquals(idWidth, expectedWidth,
1775 "Legacy project import should have fixed ID width");
1777 af.alignPanel.getIdPanel().getIdCanvas().isManuallyAdjusted());
1779 af.alignPanel.getAlignViewport().setIdWidth(100);
1780 af.alignPanel.updateLayout();
1782 af.alignPanel.getIdPanel().getIdCanvas().isManuallyAdjusted());
1784 Jalview2XML jv2xml = new jalview.project.Jalview2XML(false);
1786 jv2xml.saveState(tempfile);
1787 assertTrue(jv2xml.errorMessage == null,
1788 "Failed to save dummy project with PCA: test broken");
1791 Desktop.instance.closeAll_actionPerformed(null);
1792 af = new FileLoader().LoadFileWaitTillLoaded(
1793 tempfile.getCanonicalPath(), DataSourceType.FILE);
1795 af.alignPanel.getIdPanel().getIdCanvas().isManuallyAdjusted());
1796 assertEquals(af.alignPanel.getAlignViewport().getIdWidth(), 100,
1797 "New project exported and import should have adjusted ID width");
1799 af.alignPanel.getAlignViewport().setIdWidth(100);
1800 af.alignPanel.updateLayout();
1802 af.alignPanel.getIdPanel().getIdCanvas().isManuallyAdjusted());
1804 // now make it autoadjusted
1805 af.alignPanel.getAlignViewport().setIdWidth(-1);
1806 af.alignPanel.getIdPanel().getIdCanvas().setManuallyAdjusted(false);
1807 af.alignPanel.updateLayout();
1809 af.alignPanel.getIdPanel().getIdCanvas().isManuallyAdjusted());
1810 assertTrue(af.alignPanel.getAlignViewport().getIdWidth() > -1,
1811 "New project exported and import should have adjusted ID width");
1813 jv2xml = new jalview.project.Jalview2XML(false);
1815 jv2xml.saveState(tempfile);
1816 assertTrue(jv2xml.errorMessage == null,
1817 "Failed to save dummy project with PCA: test broken");
1820 Desktop.instance.closeAll_actionPerformed(null);
1821 af = new FileLoader().LoadFileWaitTillLoaded(
1822 tempfile.getCanonicalPath(), DataSourceType.FILE);
1824 af.alignPanel.getIdPanel().getIdCanvas().isManuallyAdjusted());
1825 assertTrue(af.alignPanel.getAlignViewport().getIdWidth() > -1,
1826 "New project exported and import should have adjusted ID width");