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.math.BigInteger;
36 import java.util.ArrayList;
37 import java.util.BitSet;
38 import java.util.HashMap;
39 import java.util.List;
40 import java.util.Locale;
43 import javax.swing.JInternalFrame;
45 import org.testng.Assert;
46 import org.testng.AssertJUnit;
47 import org.testng.annotations.BeforeClass;
48 import org.testng.annotations.Test;
50 import jalview.analysis.AlignmentUtils;
51 import jalview.analysis.scoremodels.SimilarityParams;
52 import jalview.api.AlignViewportI;
53 import jalview.api.AlignmentViewPanel;
54 import jalview.api.FeatureColourI;
55 import jalview.api.ViewStyleI;
56 import jalview.bin.Cache;
57 import jalview.datamodel.AlignmentAnnotation;
58 import jalview.datamodel.AlignmentI;
59 import jalview.datamodel.Annotation;
60 import jalview.datamodel.ContactListI;
61 import jalview.datamodel.ContactMatrix;
62 import jalview.datamodel.ContactMatrixI;
63 import jalview.datamodel.DBRefEntry;
64 import jalview.datamodel.GeneLocus;
65 import jalview.datamodel.GroupSet;
66 import jalview.datamodel.HiddenSequences;
67 import jalview.datamodel.Mapping;
68 import jalview.datamodel.PDBEntry;
69 import jalview.datamodel.PDBEntry.Type;
70 import jalview.datamodel.Sequence;
71 import jalview.datamodel.Sequence.DBModList;
72 import jalview.datamodel.SequenceCollectionI;
73 import jalview.datamodel.SequenceFeature;
74 import jalview.datamodel.SequenceGroup;
75 import jalview.datamodel.SequenceI;
76 import jalview.datamodel.features.FeatureMatcher;
77 import jalview.datamodel.features.FeatureMatcherSet;
78 import jalview.datamodel.features.FeatureMatcherSetI;
79 import jalview.gui.AlignFrame;
80 import jalview.gui.AlignViewport;
81 import jalview.gui.AlignmentPanel;
82 import jalview.gui.Desktop;
83 import jalview.gui.JvOptionPane;
84 import jalview.gui.OverviewPanel;
85 import jalview.gui.PCAPanel;
86 import jalview.gui.PopupMenu;
87 import jalview.gui.Preferences;
88 import jalview.gui.SliderPanel;
89 import jalview.io.DataSourceType;
90 import jalview.io.FileFormat;
91 import jalview.io.FileLoader;
92 import jalview.io.Jalview2xmlBase;
93 import jalview.renderer.ResidueShaderI;
94 import jalview.schemes.AnnotationColourGradient;
95 import jalview.schemes.BuriedColourScheme;
96 import jalview.schemes.ColourSchemeI;
97 import jalview.schemes.ColourSchemeProperty;
98 import jalview.schemes.FeatureColour;
99 import jalview.schemes.JalviewColourScheme;
100 import jalview.schemes.RNAHelicesColour;
101 import jalview.schemes.StrandColourScheme;
102 import jalview.schemes.TCoffeeColourScheme;
103 import jalview.structure.StructureImportSettings;
104 import jalview.util.MapList;
105 import jalview.util.Platform;
106 import jalview.util.matcher.Condition;
107 import jalview.viewmodel.AlignmentViewport;
108 import jalview.viewmodel.seqfeatures.FeatureRendererModel;
109 import jalview.ws.datamodel.MappableContactMatrixI;
110 import jalview.ws.datamodel.alphafold.PAEContactMatrix;
112 @Test(singleThreaded = true)
113 public class Jalview2xmlTests extends Jalview2xmlBase
117 @BeforeClass(alwaysRun = true)
118 public void setUpJvOptionPane()
120 if (Desktop.instance != null)
121 Desktop.instance.closeAll_actionPerformed(null);
122 JvOptionPane.setInteractiveMode(false);
123 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
126 @Test(groups = { "Functional" })
127 public void testRNAStructureRecovery() throws Exception
129 String inFile = "examples/RF00031_folded.stk";
130 String tfile = File.createTempFile("JalviewTest", ".jvp")
132 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
133 DataSourceType.FILE);
134 assertNotNull(af, "Didn't read input file " + inFile);
135 int olddsann = countDsAnn(af.getViewport());
136 assertTrue(olddsann > 0, "Didn't find any dataset annotations");
137 af.changeColour_actionPerformed(
138 JalviewColourScheme.RNAHelices.toString());
141 .getGlobalColourScheme() instanceof RNAHelicesColour,
142 "Couldn't apply RNA helices colourscheme");
143 af.saveAlignment(tfile, FileFormat.Jalview);
144 assertTrue(af.isSaveAlignmentSuccessful(),
145 "Failed to store as a project.");
146 af.closeMenuItem_actionPerformed(true);
148 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
149 DataSourceType.FILE);
150 assertNotNull(af, "Failed to import new project");
151 int newdsann = countDsAnn(af.getViewport());
152 assertEquals(olddsann, newdsann,
153 "Differing numbers of dataset sequence annotation\nOriginally "
154 + olddsann + " and now " + newdsann);
156 "Read in same number of annotations as originally present ("
161 .getGlobalColourScheme() instanceof RNAHelicesColour,
162 "RNA helices colourscheme was not applied on import.");
165 @Test(groups = { "Functional" })
166 public void testTCoffeeScores() throws Exception
168 String inFile = "examples/uniref50.fa",
169 inAnnot = "examples/uniref50.score_ascii";
170 String tfile = File.createTempFile("JalviewTest", ".jvp")
172 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
173 DataSourceType.FILE);
174 assertNotNull(af, "Didn't read input file " + inFile);
175 af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
176 AlignViewport viewport = af.getViewport();
177 assertSame(viewport.getGlobalColourScheme().getClass(),
178 TCoffeeColourScheme.class, "Didn't set T-coffee colourscheme");
180 ColourSchemeProperty.getColourScheme(viewport,
181 viewport.getAlignment(),
182 viewport.getGlobalColourScheme().getSchemeName()),
183 "Recognise T-Coffee score from string");
185 af.saveAlignment(tfile, FileFormat.Jalview);
186 assertTrue(af.isSaveAlignmentSuccessful(),
187 "Failed to store as a project.");
188 af.closeMenuItem_actionPerformed(true);
190 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
191 DataSourceType.FILE);
192 assertNotNull(af, "Failed to import new project");
193 assertSame(af.getViewport().getGlobalColourScheme().getClass(),
194 TCoffeeColourScheme.class,
195 "Didn't set T-coffee colourscheme for imported project.");
197 "T-Coffee score shading successfully recovered from project.");
200 @Test(groups = { "Functional" })
201 public void testColourByAnnotScores() throws Exception
203 String inFile = "examples/uniref50.fa",
204 inAnnot = "examples/testdata/uniref50_iupred.jva";
205 String tfile = File.createTempFile("JalviewTest", ".jvp")
207 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
208 DataSourceType.FILE);
209 assertNotNull(af, "Didn't read input file " + inFile);
210 af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
211 AlignmentAnnotation[] aa = af.getViewport().getAlignment()
212 .getSequenceAt(0).getAnnotation("IUPredWS (Short)");
215 aa != null && aa.length > 0,
216 "Didn't find any IUPred annotation to use to shade alignment.");
217 AnnotationColourGradient cs = new AnnotationColourGradient(aa[0], null,
218 AnnotationColourGradient.ABOVE_THRESHOLD);
219 AnnotationColourGradient gcs = new AnnotationColourGradient(aa[0], null,
220 AnnotationColourGradient.BELOW_THRESHOLD);
221 cs.setSeqAssociated(true);
222 gcs.setSeqAssociated(true);
224 SequenceGroup sg = new SequenceGroup();
227 sg.cs.setColourScheme(gcs);
228 af.getViewport().getAlignment().addGroup(sg);
229 sg.addSequence(af.getViewport().getAlignment().getSequenceAt(1), false);
230 sg.addSequence(af.getViewport().getAlignment().getSequenceAt(2), true);
231 af.alignPanel.alignmentChanged();
232 af.saveAlignment(tfile, FileFormat.Jalview);
233 assertTrue(af.isSaveAlignmentSuccessful(),
234 "Failed to store as a project.");
235 af.closeMenuItem_actionPerformed(true);
237 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
238 DataSourceType.FILE);
239 assertNotNull(af, "Failed to import new project");
241 // check for group and alignment colourschemes
243 ColourSchemeI _rcs = af.getViewport().getGlobalColourScheme();
244 ColourSchemeI _rgcs = af.getViewport().getAlignment().getGroups().get(0)
246 assertNotNull(_rcs, "Didn't recover global colourscheme");
247 assertTrue(_rcs instanceof AnnotationColourGradient,
248 "Didn't recover annotation colour global scheme");
249 AnnotationColourGradient __rcs = (AnnotationColourGradient) _rcs;
250 assertTrue(__rcs.isSeqAssociated(),
251 "Annotation colourscheme wasn't sequence associated");
253 boolean diffseqcols = false, diffgseqcols = false;
254 SequenceI[] sqs = af.getViewport().getAlignment().getSequencesArray();
255 for (int p = 0, pSize = af.getViewport().getAlignment()
256 .getWidth(); p < pSize && (!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");
275 for (int p = 0, pSize = af.getViewport().getAlignment()
276 .getWidth(); p < pSize && (!diffseqcols || !diffgseqcols); p++)
278 if (_rgcs.findColour(sqs[1].getCharAt(p), p, sqs[1], null,
279 0f) != _rgcs.findColour(sqs[2].getCharAt(p), p, sqs[2], null,
285 assertTrue(diffgseqcols, "Got Different group sequence colours");
287 "Per sequence (Group) colourscheme successfully applied and recovered.");
290 @Test(groups = { "Functional" })
291 public void gatherViewsHere() throws Exception
293 int origCount = Desktop.getDesktopAlignFrames() == null ? 0
294 : Desktop.getDesktopAlignFrames().length;
295 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
296 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
297 assertNotNull(af, "Didn't read in the example file correctly.");
298 assertTrue(Desktop.getDesktopAlignFrames().length == 1 + origCount,
299 "Didn't gather the views in the example file.");
304 * Test for JAL-2223 - multiple mappings in View Mapping report
308 @Test(groups = { "Functional" })
309 public void noDuplicatePdbMappingsMade() throws Exception
311 StructureImportSettings.setProcessSecondaryStructure(true);
312 StructureImportSettings.setVisibleChainAnnotation(true);
313 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
314 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
315 assertNotNull(af, "Didn't read in the example file correctly.");
317 // locate Jmol viewer
318 // count number of PDB mappings the structure selection manager holds -
319 String pdbFile = af.getCurrentView().getStructureSelectionManager()
320 .findFileForPDBId("1A70");
322 af.getCurrentView().getStructureSelectionManager()
323 .getMapping(pdbFile).length,
324 2, "Expected only two mappings for 1A70");
328 @Test(groups = { "Functional" })
329 public void viewRefPdbAnnotation() throws Exception
331 StructureImportSettings.setProcessSecondaryStructure(true);
332 StructureImportSettings.setVisibleChainAnnotation(true);
333 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
334 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
335 assertNotNull(af, "Didn't read in the example file correctly.");
336 AlignmentViewPanel sps = null;
337 for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
339 if ("Spinach Feredoxin Structure".equals(ap.getViewName()))
345 assertNotNull(sps, "Couldn't find the structure view");
346 AlignmentAnnotation refan = null;
347 for (AlignmentAnnotation ra : sps.getAlignment()
348 .getAlignmentAnnotation())
356 assertNotNull(refan, "Annotation secondary structure not found.");
357 SequenceI sq = sps.getAlignment().findName("1A70|");
358 assertNotNull(sq, "Couldn't find 1a70 null chain");
359 // compare the manually added temperature factor annotation
360 // to the track automatically transferred from the pdb structure on load
361 assertNotNull(sq.getDatasetSequence().getAnnotation(),
362 "1a70 has no annotation");
363 for (AlignmentAnnotation ala : sq.getDatasetSequence().getAnnotation())
365 AlignmentAnnotation alaa;
366 sq.addAlignmentAnnotation(alaa = new AlignmentAnnotation(ala));
367 alaa.adjustForAlignment();
368 if (ala.graph == refan.graph)
370 for (int p = 0; p < ala.annotations.length; p++)
375 assertTrue((alaa.annotations[p] == null
376 && refan.annotations[p] == null)
377 || alaa.annotations[p].value == refan.annotations[p].value,
378 "Mismatch at alignment position " + p);
379 } catch (NullPointerException q)
381 Assert.fail("Mismatch of alignment annotations at position " + p
382 + " Ref seq ann: " + refan.annotations[p]
383 + " alignment " + alaa.annotations[p]);
391 @Test(groups = { "Functional" })
392 public void testCopyViewSettings() throws Exception
394 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
395 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
396 assertNotNull(af, "Didn't read in the example file correctly.");
397 AlignmentViewPanel sps = null, groups = null;
398 for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
400 if ("Spinach Feredoxin Structure".equals(ap.getViewName()))
404 if (ap.getViewName().contains("MAFFT"))
409 assertNotNull(sps, "Couldn't find the structure view");
410 assertNotNull(groups, "Couldn't find the MAFFT view");
412 ViewStyleI structureStyle = sps.getAlignViewport().getViewStyle();
413 ViewStyleI groupStyle = groups.getAlignViewport().getViewStyle();
414 AssertJUnit.assertFalse(structureStyle.sameStyle(groupStyle));
416 groups.getAlignViewport().setViewStyle(structureStyle);
417 AssertJUnit.assertFalse(
418 groupStyle.sameStyle(groups.getAlignViewport().getViewStyle()));
419 Assert.assertTrue(structureStyle
420 .sameStyle(groups.getAlignViewport().getViewStyle()));
425 * test store and recovery of expanded views
429 @Test(groups = { "Functional" }, enabled = true)
430 public void testStoreAndRecoverExpandedviews() throws Exception
432 Desktop.instance.closeAll_actionPerformed(null);
434 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
435 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
436 Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 1);
437 String afid = af.getViewport().getSequenceSetId();
439 // check FileLoader returned a reference to the one alignFrame that is
440 // actually on the Desktop
441 assertSame(af, Desktop.getAlignFrameFor(af.getViewport()),
442 "Jalview2XML.loadAlignFrame() didn't return correct AlignFrame reference for multiple view window");
444 Desktop.explodeViews(af);
446 int oldviews = Desktop.getDesktopAlignFrames().length;
447 Assert.assertEquals(Desktop.getDesktopAlignFrames().length,
448 Desktop.getAlignmentPanels(afid).length);
449 File tfile = File.createTempFile("testStoreAndRecoverExpanded", ".jvp");
452 new Jalview2XML(false).saveState(tfile);
455 Assert.fail("Didn't save the expanded view state", e);
456 } catch (Exception e)
458 Assert.fail("Didn't save the expanded view state", e);
460 Desktop.instance.closeAll_actionPerformed(null);
461 if (Desktop.getDesktopAlignFrames() != null)
463 Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 0);
465 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
466 DataSourceType.FILE);
467 Assert.assertNotNull(af);
468 Assert.assertEquals(Desktop.getDesktopAlignFrames().length,
469 Desktop.getAlignmentPanels(
470 af.getViewport().getSequenceSetId()).length);
471 Assert.assertEquals(Desktop
472 .getAlignmentPanels(af.getViewport().getSequenceSetId()).length,
477 * Test save and reload of a project with a different representative sequence
482 @Test(groups = { "Functional" })
483 public void testStoreAndRecoverReferenceSeqSettings() throws Exception
485 Desktop.instance.closeAll_actionPerformed(null);
486 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
487 "examples/exampleFile_2_7.jar", DataSourceType.FILE);
488 assertNotNull(af, "Didn't read in the example file correctly.");
489 String afid = af.getViewport().getSequenceSetId();
491 // remember reference sequence for each panel
492 Map<String, SequenceI> refseqs = new HashMap<>();
495 * mark sequence 2, 3, 4.. in panels 1, 2, 3...
496 * as reference sequence for itself and the preceding sequence
499 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
501 AlignViewportI av = ap.getAlignViewport();
502 AlignmentI alignment = ap.getAlignment();
503 int repIndex = n % alignment.getHeight();
504 SequenceI rep = alignment.getSequenceAt(repIndex);
505 refseqs.put(ap.getViewName(), rep);
507 // code from mark/unmark sequence as reference in jalview.gui.PopupMenu
508 // todo refactor this to an alignment view controller
509 av.setDisplayReferenceSeq(true);
510 av.setColourByReferenceSeq(true);
511 av.getAlignment().setSeqrep(rep);
515 File tfile = File.createTempFile("testStoreAndRecoverReferenceSeq",
519 new Jalview2XML(false).saveState(tfile);
520 } catch (Throwable e)
522 Assert.fail("Didn't save the expanded view state", e);
524 Desktop.instance.closeAll_actionPerformed(null);
525 if (Desktop.getDesktopAlignFrames() != null)
527 Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 0);
530 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
531 DataSourceType.FILE);
532 afid = af.getViewport().getSequenceSetId();
534 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
536 // check representative
537 AlignmentI alignment = ap.getAlignment();
538 SequenceI rep = alignment.getSeqrep();
539 Assert.assertNotNull(rep,
540 "Couldn't restore sequence representative from project");
541 // can't use a strong equals here, because by definition, the sequence IDs
542 // will be different.
543 // could set vamsas session save/restore flag to preserve IDs across
545 Assert.assertEquals(refseqs.get(ap.getViewName()).toString(),
547 "Representative wasn't the same when recovered.");
548 Assert.assertTrue(ap.getAlignViewport().isDisplayReferenceSeq(),
549 "Display reference sequence view setting not set.");
550 Assert.assertTrue(ap.getAlignViewport().isColourByReferenceSeq(),
551 "Colour By Reference Seq view setting not set.");
555 @Test(groups = { "Functional" })
556 public void testIsVersionStringLaterThan()
559 * No version / development / test / autobuild is leniently assumed to be
562 assertTrue(Jalview2XML.isVersionStringLaterThan(null, null));
563 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", null));
564 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "2.8.3"));
565 assertTrue(Jalview2XML.isVersionStringLaterThan(null,
566 "Development Build"));
567 assertTrue(Jalview2XML.isVersionStringLaterThan(null,
568 "DEVELOPMENT BUILD"));
569 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
570 "Development Build"));
571 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "Test"));
572 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "TEST"));
573 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "Test"));
575 Jalview2XML.isVersionStringLaterThan(null, "Automated Build"));
576 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
578 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
582 * same version returns true i.e. compatible
584 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8", "2.8"));
585 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.3"));
586 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3b1"));
587 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3B1", "2.8.3b1"));
588 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3B1"));
591 * later version returns true
593 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.4"));
594 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.9"));
595 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.9.2"));
596 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8", "2.8.3"));
597 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.3b1"));
600 * earlier version returns false
602 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8"));
603 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.4", "2.8.3"));
604 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3"));
605 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.2b1"));
606 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.0b2", "2.8.0b1"));
608 * test for patch release versions
610 assertFalse(Jalview2XML.isVersionStringLaterThan("2.11.3.0", "2.11.2"));
611 assertTrue(Jalview2XML.isVersionStringLaterThan("2.11.3.0", "2.11.4"));
613 Jalview2XML.isVersionStringLaterThan("2.12.2.0b1", "2.12.2.0"));
615 Jalview2XML.isVersionStringLaterThan("2.12.2.3", "2.12.2.2"));
620 * Test save and reload of a project with a different sequence group (and
621 * representative sequence) in each view.
625 @Test(groups = { "Functional" })
626 public void testStoreAndRecoverGroupRepSeqs() throws Exception
628 Desktop.instance.closeAll_actionPerformed(null);
629 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
630 "examples/uniref50.fa", DataSourceType.FILE);
631 assertNotNull(af, "Didn't read in the example file correctly.");
632 String afid = af.getViewport().getSequenceSetId();
633 // make a second view of the alignment
634 af.newView_actionPerformed(null);
637 * remember representative and hidden sequences marked
640 Map<String, SequenceI> repSeqs = new HashMap<>();
641 Map<String, List<String>> hiddenSeqNames = new HashMap<>();
644 * mark sequence 2, 3, 4.. in panels 1, 2, 3...
645 * as reference sequence for itself and the preceding sequence
648 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
650 AlignViewportI av = ap.getAlignViewport();
651 AlignmentI alignment = ap.getAlignment();
652 int repIndex = n % alignment.getHeight();
653 // ensure at least one preceding sequence i.e. index >= 1
654 repIndex = Math.max(repIndex, 1);
655 SequenceI repSeq = alignment.getSequenceAt(repIndex);
656 repSeqs.put(ap.getViewName(), repSeq);
657 List<String> hiddenNames = new ArrayList<>();
658 hiddenSeqNames.put(ap.getViewName(), hiddenNames);
661 * have rep sequence represent itself and the one before it
662 * this hides the group (except for the rep seq)
664 SequenceGroup sg = new SequenceGroup();
665 sg.addSequence(repSeq, false);
666 SequenceI precedingSeq = alignment.getSequenceAt(repIndex - 1);
667 sg.addSequence(precedingSeq, false);
668 sg.setSeqrep(repSeq);
669 assertTrue(sg.getSequences().contains(repSeq));
670 assertTrue(sg.getSequences().contains(precedingSeq));
671 av.setSelectionGroup(sg);
672 assertSame(repSeq, sg.getSeqrep());
675 * represent group with sequence adds to a map of hidden rep sequences
676 * (it does not create a group on the alignment)
678 ((AlignmentViewport) av).hideSequences(repSeq, true);
679 assertSame(repSeq, sg.getSeqrep());
680 assertTrue(sg.getSequences().contains(repSeq));
681 assertTrue(sg.getSequences().contains(precedingSeq));
682 assertTrue(alignment.getGroups().isEmpty(), "alignment has groups");
683 Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av
684 .getHiddenRepSequences();
685 assertNotNull(hiddenRepSeqsMap);
686 assertEquals(1, hiddenRepSeqsMap.size());
687 assertSame(sg, hiddenRepSeqsMap.get(repSeq));
688 assertTrue(alignment.getHiddenSequences().isHidden(precedingSeq));
689 assertFalse(alignment.getHiddenSequences().isHidden(repSeq));
690 hiddenNames.add(precedingSeq.getName());
694 File tfile = File.createTempFile("testStoreAndRecoverGroupReps",
698 new Jalview2XML(false).saveState(tfile);
699 } catch (Throwable e)
701 Assert.fail("Didn't save the expanded view state", e);
703 Desktop.instance.closeAll_actionPerformed(null);
704 if (Desktop.getDesktopAlignFrames() != null)
706 Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 0);
709 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
710 DataSourceType.FILE);
711 afid = af.getViewport().getSequenceSetId();
713 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
715 String viewName = ap.getViewName();
716 AlignViewportI av = ap.getAlignViewport();
717 AlignmentI alignment = ap.getAlignment();
718 List<SequenceGroup> groups = alignment.getGroups();
719 assertNotNull(groups);
720 assertTrue(groups.isEmpty(), "Alignment has groups");
721 Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av
722 .getHiddenRepSequences();
723 assertNotNull(hiddenRepSeqsMap, "No hidden represented sequences");
724 assertEquals(1, hiddenRepSeqsMap.size());
725 assertEquals(repSeqs.get(viewName).getDisplayId(true),
726 hiddenRepSeqsMap.keySet().iterator().next()
727 .getDisplayId(true));
730 * verify hidden sequences in restored panel
732 List<String> hidden = hiddenSeqNames.get(ap.getViewName());
733 HiddenSequences hs = alignment.getHiddenSequences();
734 assertEquals(hidden.size(), hs.getSize(),
735 "wrong number of restored hidden sequences in "
741 * Test save and reload of PDBEntry in Jalview project
745 @Test(groups = { "Functional" })
746 public void testStoreAndRecoverPDBEntry() throws Exception
748 Desktop.instance.closeAll_actionPerformed(null);
749 String exampleFile = "examples/3W5V.pdb";
750 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
751 DataSourceType.FILE);
752 assertNotNull(af, "Didn't read in the example file correctly.");
753 String afid = af.getViewport().getSequenceSetId();
755 AlignmentPanel[] alignPanels = Desktop.getAlignmentPanels(afid);
756 System.out.println();
757 AlignmentViewPanel ap = alignPanels[0];
758 String tfileBase = new File(".").getAbsolutePath().replace(".", "");
759 String testFile = tfileBase + exampleFile;
760 AlignmentI alignment = ap.getAlignment();
761 System.out.println("blah");
762 SequenceI[] seqs = alignment.getSequencesArray();
763 Assert.assertNotNull(seqs[0]);
764 Assert.assertNotNull(seqs[1]);
765 Assert.assertNotNull(seqs[2]);
766 Assert.assertNotNull(seqs[3]);
767 Assert.assertNotNull(seqs[0].getDatasetSequence());
768 Assert.assertNotNull(seqs[1].getDatasetSequence());
769 Assert.assertNotNull(seqs[2].getDatasetSequence());
770 Assert.assertNotNull(seqs[3].getDatasetSequence());
771 PDBEntry[] pdbEntries = new PDBEntry[4];
772 pdbEntries[0] = new PDBEntry("3W5V", "A", Type.PDB, testFile);
773 pdbEntries[1] = new PDBEntry("3W5V", "B", Type.PDB, testFile);
774 pdbEntries[2] = new PDBEntry("3W5V", "C", Type.PDB, testFile);
775 pdbEntries[3] = new PDBEntry("3W5V", "D", Type.PDB, testFile);
777 seqs[0].getDatasetSequence().getAllPDBEntries().get(0),
780 seqs[1].getDatasetSequence().getAllPDBEntries().get(0),
783 seqs[2].getDatasetSequence().getAllPDBEntries().get(0),
786 seqs[3].getDatasetSequence().getAllPDBEntries().get(0),
789 File tfile = File.createTempFile("testStoreAndRecoverPDBEntry", ".jvp");
792 new Jalview2XML(false).saveState(tfile);
793 } catch (Throwable e)
795 Assert.fail("Didn't save the state", e);
797 Desktop.instance.closeAll_actionPerformed(null);
798 if (Desktop.getDesktopAlignFrames() != null)
800 Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 0);
803 AlignFrame restoredFrame = new FileLoader().LoadFileWaitTillLoaded(
804 tfile.getAbsolutePath(), DataSourceType.FILE);
805 String rfid = restoredFrame.getViewport().getSequenceSetId();
806 AlignmentPanel[] rAlignPanels = Desktop.getAlignmentPanels(rfid);
807 AlignmentViewPanel rap = rAlignPanels[0];
808 AlignmentI rAlignment = rap.getAlignment();
809 System.out.println("blah");
810 SequenceI[] rseqs = rAlignment.getSequencesArray();
811 Assert.assertNotNull(rseqs[0]);
812 Assert.assertNotNull(rseqs[1]);
813 Assert.assertNotNull(rseqs[2]);
814 Assert.assertNotNull(rseqs[3]);
815 Assert.assertNotNull(rseqs[0].getDatasetSequence());
816 Assert.assertNotNull(rseqs[1].getDatasetSequence());
817 Assert.assertNotNull(rseqs[2].getDatasetSequence());
818 Assert.assertNotNull(rseqs[3].getDatasetSequence());
820 // The Asserts below are expected to fail until the PDB chainCode is
821 // recoverable from a Jalview projects
822 for (int chain = 0; chain < 4; chain++)
824 PDBEntry recov = rseqs[chain].getDatasetSequence().getAllPDBEntries()
826 PDBEntry expected = pdbEntries[chain];
827 Assert.assertEquals(recov.getId(), expected.getId(),
829 Assert.assertEquals(recov.getChainCode(), expected.getChainCode(),
831 Assert.assertEquals(recov.getType(), expected.getType(),
832 "Mismatch PDBEntry 'Type'");
833 Assert.assertNotNull(recov.getFile(),
834 "Recovered PDBEntry should have a non-null file entry");
836 recov.getFile().toLowerCase(Locale.ENGLISH)
838 recov.getFile().length() - 3,
839 "Recovered PDBEntry file should have PDB suffix");
844 * Configure an alignment and a sub-group each with distinct colour schemes,
845 * Conservation and PID thresholds, and confirm these are restored from the
848 * @throws IOException
850 @Test(groups = { "Functional" })
851 public void testStoreAndRecoverAnnotationRowElementColours()
854 Desktop.instance.closeAll_actionPerformed(null);
855 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded("SEQ\tMNQ",
856 DataSourceType.PASTE);
858 AlignViewport av = af.getViewport();
859 AlignmentI al = av.getAlignment();
861 fsq = al.getSequenceAt(0);
862 Annotation annots[] = new Annotation[fsq.getLength()];
863 AlignmentAnnotation ala = new AlignmentAnnotation("Colour", "Annots",
865 annots[0] = new Annotation(1.0f);
866 annots[1] = new Annotation(2.0f);
867 annots[2] = new Annotation(3.0f);
868 annots[0].colour = Color.RED;
869 annots[1].colour = Color.GREEN;
870 annots[2].colour = Color.BLUE;
871 ala.validateRangeAndDisplay();
872 al.getSequenceAt(0).addAlignmentAnnotation(ala);
873 al.addAnnotation(ala);
875 * and colour by annotation
877 AnnotationColourGradient acg = new AnnotationColourGradient(ala,
878 af.alignPanel.av.getGlobalColourScheme(), 0);
879 acg.setSeqAssociated(true);
880 acg.setPredefinedColours(true);
881 af.changeColour(acg);
882 Color seqcol[] = new Color[3];
883 for (int iStart = fsq.findIndex(fsq.getStart()), i = 0; i < 3; i++)
885 seqcol[i] = af.alignPanel.getSeqPanel().seqCanvas
886 .getSequenceRenderer()
887 .getResidueColour(fsq, iStart + i, null);
890 * save project, close windows, reload project, verify
892 File tfile = File.createTempFile(
893 "testStoreAndRecoverAnnotRowElemColors", ".jvp");
894 tfile.deleteOnExit();
895 new Jalview2XML(false).saveState(tfile);
896 // Desktop.instance.closeAll_actionPerformed(null);
897 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
898 DataSourceType.FILE);
899 Assert.assertNotNull(af, "Failed to reload project");
901 * verify alignment annotation has colors
903 av = af.getViewport();
905 ColourSchemeI loadedCscheme = av.getGlobalColourScheme();
906 Assert.assertTrue(loadedCscheme instanceof AnnotationColourGradient,
907 "Didn't apply Annotation colour gradient");
908 acg = (AnnotationColourGradient) loadedCscheme;
909 assertTrue(acg.isSeqAssociated());
910 assertTrue(acg.isPredefinedColours());
912 al = av.getAlignment();
913 fsq = al.getSequenceAt(0);
914 ala = fsq.getAnnotation()[0];
915 Assert.assertNotNull(ala, "No annotation row recovered");
916 Assert.assertNotNull(ala.annotations);
917 for (int iStart = al.getSequenceAt(0)
918 .findIndex(al.getSequenceAt(0).getStart()), i = 0; i < 3; i++)
920 Assert.assertTrue(ala.annotations[i].colour != null);
921 Assert.assertTrue(ala.annotations[i].colour.equals(annots[i].colour));
922 Color newseqcol = af.alignPanel.getSeqPanel().seqCanvas
923 .getSequenceRenderer()
924 .getResidueColour(fsq, iStart + i, null);
925 Assert.assertTrue(seqcol[i].equals(newseqcol),
926 "Sequence shading is different");
933 * Configure an alignment and a sub-group each with distinct colour schemes,
934 * Conservation and PID thresholds, and confirm these are restored from the
937 * @throws IOException
939 @Test(groups = { "Functional" })
940 public void testStoreAndRecoverColourThresholds() throws IOException
942 Desktop.instance.closeAll_actionPerformed(null);
943 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
944 "examples/uniref50.fa", DataSourceType.FILE);
946 AlignViewport av = af.getViewport();
947 AlignmentI al = av.getAlignment();
950 * Colour alignment by Buried Index, Above 10% PID, By Conservation 20%
952 av.setColourAppliesToAllGroups(false);
953 af.changeColour_actionPerformed(JalviewColourScheme.Buried.toString());
954 assertTrue(av.getGlobalColourScheme() instanceof BuriedColourScheme);
955 af.abovePIDThreshold_actionPerformed(true);
956 SliderPanel sp = SliderPanel.getSliderPanel();
957 assertFalse(sp.isForConservation());
959 af.conservationMenuItem_actionPerformed(true);
960 sp = SliderPanel.getSliderPanel();
961 assertTrue(sp.isForConservation());
963 ResidueShaderI rs = av.getResidueShading();
964 assertEquals(rs.getThreshold(), 10);
965 assertTrue(rs.conservationApplied());
966 assertEquals(rs.getConservationInc(), 20);
969 * create a group with Strand colouring, 30% Conservation
970 * and 40% PID threshold
971 * (notice menu action applies to selection group even if mouse click
972 * is at a sequence not in the group)
974 SequenceGroup sg = new SequenceGroup();
975 sg.addSequence(al.getSequenceAt(0), false);
978 av.setSelectionGroup(sg);
979 PopupMenu popupMenu = new PopupMenu(af.alignPanel, al.getSequenceAt(2),
981 popupMenu.changeColour_actionPerformed(
982 JalviewColourScheme.Strand.toString());
983 assertTrue(sg.getColourScheme() instanceof StrandColourScheme);
984 assertEquals(al.getGroups().size(), 1);
985 assertSame(al.getGroups().get(0), sg);
986 popupMenu.conservationMenuItem_actionPerformed(true);
987 sp = SliderPanel.getSliderPanel();
988 assertTrue(sp.isForConservation());
990 popupMenu.abovePIDColour_actionPerformed(true);
991 sp = SliderPanel.getSliderPanel();
992 assertFalse(sp.isForConservation());
994 assertTrue(sg.getGroupColourScheme().conservationApplied());
995 assertEquals(sg.getGroupColourScheme().getConservationInc(), 30);
996 assertEquals(sg.getGroupColourScheme().getThreshold(), 40);
999 * save project, close windows, reload project, verify
1001 File tfile = File.createTempFile("testStoreAndRecoverColourThresholds",
1003 tfile.deleteOnExit();
1004 new Jalview2XML(false).saveState(tfile);
1005 Desktop.instance.closeAll_actionPerformed(null);
1006 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
1007 DataSourceType.FILE);
1008 Assert.assertNotNull(af, "Failed to reload project");
1011 * verify alignment (background) colouring
1013 rs = af.getViewport().getResidueShading();
1014 assertTrue(rs.getColourScheme() instanceof BuriedColourScheme);
1015 assertEquals(rs.getThreshold(), 10);
1016 assertTrue(rs.conservationApplied());
1017 assertEquals(rs.getConservationInc(), 20);
1020 * verify group colouring
1022 assertEquals(1, af.getViewport().getAlignment().getGroups().size(), 1);
1023 rs = af.getViewport().getAlignment().getGroups().get(0)
1024 .getGroupColourScheme();
1025 assertTrue(rs.getColourScheme() instanceof StrandColourScheme);
1026 assertEquals(rs.getThreshold(), 40);
1027 assertTrue(rs.conservationApplied());
1028 assertEquals(rs.getConservationInc(), 30);
1032 * Test save and reload of feature colour schemes and filter settings
1034 * @throws IOException
1036 @Test(groups = { "Functional" })
1037 public void testSaveLoadFeatureColoursAndFilters() throws IOException
1039 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1040 ">Seq1\nACDEFGHIKLM", DataSourceType.PASTE);
1041 SequenceI seq1 = af.getViewport().getAlignment().getSequenceAt(0);
1044 * add some features to the sequence
1047 addFeatures(seq1, "type1", score++);
1048 addFeatures(seq1, "type2", score++);
1049 addFeatures(seq1, "type3", score++);
1050 addFeatures(seq1, "type4", score++);
1051 addFeatures(seq1, "type5", score++);
1054 * set colour schemes for features
1056 FeatureRendererModel fr = af.getFeatureRenderer();
1057 fr.findAllFeatures(true);
1060 fr.setColour("type1", new FeatureColour(Color.red));
1063 FeatureColourI byLabel = new FeatureColour();
1064 byLabel.setColourByLabel(true);
1065 fr.setColour("type2", byLabel);
1067 // type3: by score above threshold
1068 FeatureColourI byScore = new FeatureColour(null, Color.BLACK,
1069 Color.BLUE, null, 1, 10);
1070 byScore.setAboveThreshold(true);
1071 byScore.setThreshold(2f);
1072 fr.setColour("type3", byScore);
1074 // type4: by attribute AF
1075 FeatureColourI byAF = new FeatureColour();
1076 byAF.setColourByLabel(true);
1077 byAF.setAttributeName("AF");
1078 fr.setColour("type4", byAF);
1080 // type5: by attribute CSQ:PolyPhen below threshold
1081 FeatureColourI byPolyPhen = new FeatureColour(null, Color.BLACK,
1082 Color.BLUE, null, 1, 10);
1083 byPolyPhen.setBelowThreshold(true);
1084 byPolyPhen.setThreshold(3f);
1085 byPolyPhen.setAttributeName("CSQ", "PolyPhen");
1086 fr.setColour("type5", byPolyPhen);
1089 * set filters for feature types
1092 // filter type1 features by (label contains "x")
1093 FeatureMatcherSetI filterByX = new FeatureMatcherSet();
1094 filterByX.and(FeatureMatcher.byLabel(Condition.Contains, "x"));
1095 fr.setFeatureFilter("type1", filterByX);
1097 // filter type2 features by (score <= 2.4 and score > 1.1)
1098 FeatureMatcherSetI filterByScore = new FeatureMatcherSet();
1099 filterByScore.and(FeatureMatcher.byScore(Condition.LE, "2.4"));
1100 filterByScore.and(FeatureMatcher.byScore(Condition.GT, "1.1"));
1101 fr.setFeatureFilter("type2", filterByScore);
1103 // filter type3 features by (AF contains X OR CSQ:PolyPhen != 0)
1104 FeatureMatcherSetI filterByXY = new FeatureMatcherSet();
1106 .and(FeatureMatcher.byAttribute(Condition.Contains, "X", "AF"));
1107 filterByXY.or(FeatureMatcher.byAttribute(Condition.NE, "0", "CSQ",
1109 fr.setFeatureFilter("type3", filterByXY);
1112 * save as Jalview project
1114 File tfile = File.createTempFile("JalviewTest", ".jvp");
1115 tfile.deleteOnExit();
1116 String filePath = tfile.getAbsolutePath();
1117 af.saveAlignment(filePath, FileFormat.Jalview);
1118 assertTrue(af.isSaveAlignmentSuccessful(),
1119 "Failed to store as a project.");
1122 * close current alignment and load the saved project
1124 af.closeMenuItem_actionPerformed(true);
1126 af = new FileLoader().LoadFileWaitTillLoaded(filePath,
1127 DataSourceType.FILE);
1128 assertNotNull(af, "Failed to import new project");
1131 * verify restored feature colour schemes and filters
1133 fr = af.getFeatureRenderer();
1134 FeatureColourI fc = fr.getFeatureStyle("type1");
1135 assertTrue(fc.isSimpleColour());
1136 assertEquals(fc.getColour(), Color.red);
1137 fc = fr.getFeatureStyle("type2");
1138 assertTrue(fc.isColourByLabel());
1139 fc = fr.getFeatureStyle("type3");
1140 assertTrue(fc.isGraduatedColour());
1141 assertNull(fc.getAttributeName());
1142 assertTrue(fc.isAboveThreshold());
1143 assertEquals(fc.getThreshold(), 2f);
1144 fc = fr.getFeatureStyle("type4");
1145 assertTrue(fc.isColourByLabel());
1146 assertTrue(fc.isColourByAttribute());
1147 assertEquals(fc.getAttributeName(), new String[] { "AF" });
1148 fc = fr.getFeatureStyle("type5");
1149 assertTrue(fc.isGraduatedColour());
1150 assertTrue(fc.isColourByAttribute());
1151 assertEquals(fc.getAttributeName(), new String[] { "CSQ", "PolyPhen" });
1152 assertTrue(fc.isBelowThreshold());
1153 assertEquals(fc.getThreshold(), 3f);
1155 assertEquals(fr.getFeatureFilter("type1").toStableString(),
1156 "Label Contains x");
1157 assertEquals(fr.getFeatureFilter("type2").toStableString(),
1158 "(Score LE 2.4) AND (Score GT 1.1)");
1159 assertEquals(fr.getFeatureFilter("type3").toStableString(),
1160 "(AF Contains X) OR (CSQ:PolyPhen NE 0)");
1163 private void addFeature(SequenceI seq, String featureType, int score)
1165 SequenceFeature sf = new SequenceFeature(featureType, "desc", 1, 2,
1167 sf.setValue("AF", score);
1168 sf.setValue("CSQ", new HashMap<String, String>()
1171 put("PolyPhen", Integer.toString(score));
1174 seq.addSequenceFeature(sf);
1178 * Adds two features of the given type to the given sequence, also setting the
1179 * score as the value of attribute "AF" and sub-attribute "CSQ:PolyPhen"
1182 * @param featureType
1185 private void addFeatures(SequenceI seq, String featureType, int score)
1187 addFeature(seq, featureType, score++);
1188 addFeature(seq, featureType, score);
1192 * pre 2.11 - jalview 2.10 erroneously created new dataset entries for each
1193 * view (JAL-3171) this test ensures we can import and merge those views
1195 @Test(groups = { "Functional" })
1196 public void testMergeDatasetsforViews() throws IOException
1198 // simple project - two views on one alignment
1199 AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
1200 "examples/testdata/projects/twoViews.jvp", DataSourceType.FILE);
1202 assertTrue(af.getAlignPanels().size() > 1);
1207 * pre 2.11 - jalview 2.10 erroneously created new dataset entries for each
1208 * view (JAL-3171) this test ensures we can import and merge those views This
1209 * is a more complex project
1211 @Test(groups = { "Functional" })
1212 public void testMergeDatasetsforManyViews() throws IOException
1214 Desktop.instance.closeAll_actionPerformed(null);
1216 // complex project - one dataset, several views on several alignments
1217 AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
1218 "examples/testdata/projects/manyViews.jvp",
1219 DataSourceType.FILE);
1222 AlignmentI ds = null;
1223 for (AlignFrame alignFrame : Desktop.getDesktopAlignFrames())
1227 ds = verifyDs(alignFrame);
1231 // check that this frame's dataset matches the last
1232 assertTrue(ds == verifyDs(alignFrame));
1237 private AlignmentI verifyDs(AlignFrame af)
1239 AlignmentI ds = null;
1240 for (AlignmentViewPanel ap : af.getAlignPanels())
1244 ds = ap.getAlignment().getDataset();
1248 assertTrue(ap.getAlignment().getDataset() == ds,
1249 "Dataset was not the same for imported 2.10.5 project with several alignment views");
1255 @Test(groups = "Functional")
1256 public void testPcaViewAssociation() throws IOException
1258 Desktop.instance.closeAll_actionPerformed(null);
1259 final String PCAVIEWNAME = "With PCA";
1260 // create a new tempfile
1261 File tempfile = File.createTempFile("jvPCAviewAssoc", "jvp");
1264 String exampleFile = "examples/uniref50.fa";
1265 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
1266 DataSourceType.FILE);
1267 assertNotNull(af, "Didn't read in the example file correctly.");
1268 AlignmentPanel origView = (AlignmentPanel) af.getAlignPanels().get(0);
1269 AlignmentPanel newview = af.newView(PCAVIEWNAME, true);
1270 // create another for good measure
1271 af.newView("Not the PCA View", true);
1272 PCAPanel pcaPanel = new PCAPanel(origView, "BLOSUM62",
1273 new SimilarityParams(true, true, true, false));
1274 // we're in the test exec thread, so we can just run synchronously here
1277 // now switch the linked view
1278 pcaPanel.selectAssociatedView(newview);
1280 assertTrue(pcaPanel.getAlignViewport() == newview.getAlignViewport(),
1281 "PCA should be associated with 'With PCA' view: test is broken");
1283 // now save and reload project
1284 Jalview2XML jv2xml = new jalview.project.Jalview2XML(false);
1286 jv2xml.saveState(tempfile);
1287 assertTrue(jv2xml.errorMessage == null,
1288 "Failed to save dummy project with PCA: test broken");
1292 Desktop.instance.closeAll_actionPerformed(null);
1293 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1294 tempfile.getCanonicalPath(), DataSourceType.FILE);
1295 JInternalFrame[] frames = Desktop.instance.getAllFrames();
1296 // PCA and the tabbed alignment view should be the only two windows on the
1298 assertEquals(frames.length, 2,
1299 "PCA and the tabbed alignment view should be the only two windows on the desktop");
1300 PCAPanel pcaPanel = (PCAPanel) frames[frames[0] == af ? 1 : 0];
1302 AlignmentViewPanel restoredNewView = null;
1303 for (AlignmentViewPanel alignpanel : Desktop.getAlignmentPanels(null))
1305 if (alignpanel.getAlignViewport() == pcaPanel.getAlignViewport())
1307 restoredNewView = alignpanel;
1310 assertEquals(restoredNewView.getViewName(), PCAVIEWNAME);
1312 restoredNewView.getAlignViewport() == pcaPanel
1313 .getAlignViewport(),
1314 "Didn't restore correct view association for the PCA view");
1318 * Test save and reload of DBRefEntry including GeneLocus in project
1322 @Test(groups = { "Functional" })
1323 public void testStoreAndRecoverGeneLocus() throws Exception
1325 Desktop.instance.closeAll_actionPerformed(null);
1326 String seqData = ">P30419\nACDE\n>X1235\nGCCTGTGACGAA";
1327 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(seqData,
1328 DataSourceType.PASTE);
1329 assertNotNull(af, "Didn't read in the example file correctly.");
1331 AlignmentViewPanel ap = Desktop.getAlignmentPanels(null)[0];
1332 SequenceI pep = ap.getAlignment().getSequenceAt(0);
1333 SequenceI cds = ap.getAlignment().getSequenceAt(1);
1336 * give 'protein' a dbref to self, a dbref with map to CDS,
1337 * and a dbref with map to gene 'locus'
1339 DBRefEntry dbref1 = new DBRefEntry("Uniprot", "1", "P30419", null);
1340 pep.addDBRef(dbref1);
1341 Mapping cdsmap = new Mapping(cds,
1342 new MapList(new int[]
1343 { 1, 4 }, new int[] { 1, 12 }, 1, 3));
1344 DBRefEntry dbref2 = new DBRefEntry("EMBLCDS", "2", "X1235", cdsmap);
1345 pep.addDBRef(dbref2);
1346 Mapping locusmap = new Mapping(null,
1347 new MapList(new int[]
1348 { 1, 4 }, new int[] { 2674123, 2674135 }, 1, 3));
1349 DBRefEntry dbref3 = new GeneLocus("human", "GRCh38", "5", locusmap);
1350 pep.addDBRef(dbref3);
1352 File tfile = File.createTempFile("testStoreAndRecoverGeneLocus",
1356 new Jalview2XML(false).saveState(tfile);
1357 } catch (Throwable e)
1359 Assert.fail("Didn't save the state", e);
1361 Desktop.instance.closeAll_actionPerformed(null);
1363 new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
1364 DataSourceType.FILE);
1365 AlignmentViewPanel rap = Desktop.getAlignmentPanels(null)[0];
1366 SequenceI rpep = rap.getAlignment().getSequenceAt(0);
1367 DBModList<DBRefEntry> dbrefs = rpep.getDBRefs();
1368 assertEquals(rpep.getName(), "P30419");
1369 assertEquals(dbrefs.size(), 3);
1370 DBRefEntry dbRef = dbrefs.get(0);
1371 assertFalse(dbRef instanceof GeneLocus);
1372 assertNull(dbRef.getMap());
1373 assertEquals(dbRef, dbref1);
1376 * restored dbrefs with mapping have a different 'map to'
1377 * sequence but otherwise match the original dbrefs
1379 dbRef = dbrefs.get(1);
1380 assertFalse(dbRef instanceof GeneLocus);
1381 assertTrue(dbRef.equalRef(dbref2));
1382 assertNotNull(dbRef.getMap());
1383 SequenceI rcds = rap.getAlignment().getSequenceAt(1);
1384 assertSame(dbRef.getMap().getTo(), rcds);
1385 // compare MapList but not map.to
1386 assertEquals(dbRef.getMap().getMap(), dbref2.getMap().getMap());
1389 * GeneLocus map.to is null so can compare Mapping objects
1391 dbRef = dbrefs.get(2);
1392 assertTrue(dbRef instanceof GeneLocus);
1393 assertEquals(dbRef, dbref3);
1397 * test store and recovery of Overview windows
1401 @Test(groups = { "Functional" }, enabled = true)
1402 public void testStoreAndRecoverOverview() throws Exception
1404 Desktop.instance.closeAll_actionPerformed(null);
1406 Cache.setProperty("SHOW_OVERVIEW", "false");
1407 Cache.setProperty(Preferences.USE_LEGACY_GAP, "false");
1408 Cache.setColourProperty(Preferences.GAP_COLOUR, Color.green);
1409 Cache.setColourProperty(Preferences.HIDDEN_COLOUR, Color.yellow);
1410 Cache.setProperty(Preferences.SHOW_OV_HIDDEN_AT_START, "true");
1412 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1413 "examples/uniref50.fa", DataSourceType.FILE);
1416 * open and resize / reposition overview
1418 af.overviewMenuItem_actionPerformed(null);
1419 OverviewPanel ov1 = af.alignPanel.getOverviewPanel();
1421 ov1.setFrameBounds(20, 30, 200, 400);
1422 assertEquals(ov1.getTitle(), "Overview examples/uniref50.fa");
1423 assertTrue(ov1.isShowHiddenRegions());
1426 * open a New View and its Overview and reposition it
1428 af.newView_actionPerformed(null);
1429 af.overviewMenuItem_actionPerformed(null);
1430 OverviewPanel ov2 = af.alignPanel.getOverviewPanel();
1432 assertNotSame(ov1, ov2);
1433 ov2.setFrameBounds(25, 35, 205, 405);
1434 assertEquals(ov1.getTitle(), "Overview examples/uniref50.fa Original");
1435 assertEquals(ov2.getTitle(), "Overview examples/uniref50.fa View 1");
1437 File tfile = File.createTempFile("testStoreAndRecoverOverview", ".jvp");
1438 new Jalview2XML(false).saveState(tfile);
1439 Desktop.instance.closeAll_actionPerformed(null);
1442 * change preferences (should _not_ affect reloaded Overviews)
1444 Cache.setProperty("SHOW_OVERVIEW", "true");
1445 Cache.setProperty(Preferences.USE_LEGACY_GAP, "true");
1446 Cache.setColourProperty(Preferences.GAP_COLOUR, Color.blue);
1447 Cache.setColourProperty(Preferences.HIDDEN_COLOUR, Color.orange);
1448 Cache.setProperty(Preferences.SHOW_OV_HIDDEN_AT_START, "false");
1450 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
1451 DataSourceType.FILE);
1454 * workaround: explicitly select View 1 (not in focus after restore)
1456 af.tabSelectionChanged(1);
1459 * verify restored overview for View 1
1461 ov2 = af.alignPanel.getOverviewPanel();
1462 assertEquals(ov2.getCanvas().getGapColour(), Color.green);
1463 // 'non-legacy' colouring uses white for non-gapped residues
1464 assertEquals(ov2.getCanvas().getResidueColour(), Color.white);
1465 assertEquals(ov2.getCanvas().getHiddenColour(), Color.yellow);
1466 assertEquals(ov2.getTitle(), "Overview examples/uniref50.fa View 1");
1467 assertEquals(ov2.getFrameBounds(), new Rectangle(25, 35, 205, 405));
1468 assertTrue(ov2.isShowHiddenRegions());
1471 * verify restored overview for Original view
1473 af.tabSelectionChanged(0);
1474 ov1 = af.alignPanel.getOverviewPanel();
1475 assertEquals(ov1.getCanvas().getGapColour(), Color.green);
1476 // 'non-legacy' colouring uses white for non-gapped residues
1477 assertEquals(ov1.getCanvas().getResidueColour(), Color.white);
1478 assertEquals(ov1.getCanvas().getHiddenColour(), Color.yellow);
1479 assertEquals(ov1.getTitle(), "Overview examples/uniref50.fa Original");
1480 assertEquals(ov1.getFrameBounds(), new Rectangle(20, 30, 200, 400));
1481 assertTrue(ov1.isShowHiddenRegions());
1485 * Test that a view with no Overview is restored with no Overview, even if
1486 * 'Open Overview' is selected in Preferences
1490 @Test(groups = { "Functional" }, enabled = true)
1491 public void testStoreAndRecoverNoOverview() throws Exception
1493 Cache.setProperty("SHOW_OVERVIEW", "false");
1494 Desktop.instance.closeAll_actionPerformed(null);
1495 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1496 ">seq1\nMATRSQFLVNF\n", DataSourceType.PASTE);
1498 File tfile = File.createTempFile("testStoreAndRecoverOverview", ".jvp");
1499 new Jalview2XML(false).saveState(tfile);
1500 Desktop.instance.closeAll_actionPerformed(null);
1502 Cache.setProperty("SHOW_OVERVIEW", "true");
1503 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
1504 DataSourceType.FILE);
1506 assertNull(af.alignPanel.getOverviewPanel());
1510 * Test that a view from an older version of Jalview is restored with Overview
1511 * automatically shown when the preference is set
1515 @Test(groups = { "Functional" }, enabled = true)
1516 public void testAutoShowOverviewForLegacyProjects() throws Exception
1518 Desktop.instance.closeAll_actionPerformed(null);
1519 Cache.setProperty("SHOW_OVERVIEW", "true");
1520 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1521 "examples/exampleFile.jvp", DataSourceType.FILE);
1523 Cache.setProperty("SHOW_OVERVIEW", "false");
1524 assertNotNull(af.alignPanel.getOverviewPanel());
1528 * Test that loading example.jvp, doing some stuff, then hitting reload
1529 * doesn't leave the modified window still open
1531 * See JAL-4127 - interactively performing the same actions and reloading
1532 * works fine, but programmatically they do not
1536 @Test(groups = { "Functional" }, enabled = false)
1537 public void testReloadActuallyReloads() throws Exception
1539 Desktop.instance.closeAll_actionPerformed(null);
1540 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1541 "examples/exampleFile.jvp", DataSourceType.FILE);
1542 af.getViewport().getColumnSelection().addElement(3);
1543 af.hideSelColumns_actionPerformed(null);
1544 af.newView("new", true);
1545 af.reload_actionPerformed(null);
1547 // af exists still but isn't shown
1548 assertTrue(af.isClosed());
1551 @Test(groups = { "Functional" })
1552 public void testMatrixToFloatsAndBack()
1556 SequenceI sq = new Sequence("dummy", "SEQ");
1557 while (sq.getLength() < i)
1559 sq.setSequence(sq.getSequenceAsString() + 'Q');
1561 float[][] paevals = new float[i][i];
1562 for (i = imax - 1; i >= 0; i--)
1564 for (int j = 0; j <= i; j++)
1566 paevals[i][j] = ((i - j < 2)
1567 || ((i > 1 && i < 5) && (j > 1 && i < 5))) ? 1 : 0f;
1568 paevals[j][i] = -paevals[i][j];
1571 PAEContactMatrix dummyMat = new PAEContactMatrix(sq, paevals);
1572 String content = ContactMatrix.contactToFloatString(dummyMat);
1573 Assert.assertTrue(content.contains("\t1.")); // at least one element must be
1575 float[][] vals = ContactMatrix.fromFloatStringToContacts(content,
1576 sq.getLength(), sq.getLength());
1577 assertEquals(vals[3][4], paevals[3][4]);
1578 assertEquals(vals[4][3], paevals[4][3]);
1581 for (i = 0; i < imax; i++)
1583 for (int j = 0; j < imax; j++)
1585 assertEquals(vals[i][j], paevals[i][j]);
1590 @Test(groups = { "Functional" })
1591 public void testPAEsaveRestore() throws Exception
1593 Desktop.instance.closeAll_actionPerformed(null);
1594 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1595 ">seq1\nMATRSQFLVNF\n", DataSourceType.PASTE);
1596 AlignmentI al = af.getViewport().getAlignment();
1597 // PAE matrices are added as reference annotation to the dataset sequence
1598 // at least for now.
1599 SequenceI sq = al.getSequenceAt(0).getDatasetSequence();
1600 int i = sq.getLength();
1601 float[][] paevals = new float[i][i];
1602 for (i = i - 1; i >= 0; i--)
1604 for (int j = 0; j <= i; j++)
1606 paevals[i][j] = ((i - j < 2)
1607 || ((i > 1 && i < 5) && (j > 1 && i < 5))) ? 1 : 0f;
1608 paevals[j][i] = -paevals[i][j];
1611 PAEContactMatrix dummyMat = new PAEContactMatrix(sq, paevals);
1612 String content = ContactMatrix.contactToFloatString(dummyMat);
1613 Assert.assertTrue(content.contains("\t1.")); // at least one element must be
1615 float[][] vals = ContactMatrix.fromFloatStringToContacts(content,
1616 sq.getLength(), sq.getLength());
1617 assertEquals(vals[3][4], paevals[3][4]);
1618 assertEquals(vals[4][3], paevals[4][3]);
1619 dummyMat.setGroupSet(GroupSet.makeGroups(dummyMat, false, 0.5f, false));
1620 Assert.assertNotSame(dummyMat.getNewick(), "");
1621 AlignmentAnnotation paeCm = sq.addContactList(dummyMat);
1622 al.addAnnotation(paeCm);
1623 // verify store/restore of group bitsets
1624 for (BitSet gp : dummyMat.getGroups())
1626 StringBuilder sb = new StringBuilder();
1627 for (long val : gp.toLongArray())
1629 if (sb.length() > 0)
1635 String[] longvals = sb.toString().split(",");
1636 long[] newlongvals = new long[longvals.length];
1637 for (int lv = 0; lv < longvals.length; lv++)
1641 newlongvals[lv] = Long.valueOf(longvals[lv]);
1642 } catch (Exception x)
1644 Assert.fail("failed to deserialise bitset element ");
1647 BitSet newGp = BitSet.valueOf(newlongvals);
1648 assertTrue(gp.equals(newGp));
1650 File tfile = File.createTempFile("testStoreAndRecoverPAEmatrix",
1652 new Jalview2XML(false).saveState(tfile);
1653 Desktop.instance.closeAll_actionPerformed(null);
1655 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
1656 DataSourceType.FILE);
1657 AlignmentI newAl = af.getViewport().getAlignment();
1658 SequenceI newSeq = newAl.getSequenceAt(0).getDatasetSequence();
1659 // check annotation of the expected type exists
1660 Assert.assertEquals(newSeq.getAnnotation().length, 1);
1661 Assert.assertEquals(newSeq.getAnnotation()[0].graph, paeCm.graph);
1663 // check a contact matrix was recovered
1664 Assert.assertEquals(newSeq.getContactMaps().size(), 1);
1665 // and can be found for the annotation on the sequence
1666 ContactMatrixI restoredMat = newSeq
1667 .getContactMatrixFor(newSeq.getAnnotation()[0]);
1668 Assert.assertNotNull(restoredMat);
1669 MapList oldMap = ((MappableContactMatrixI) dummyMat).getMapFor(sq);
1670 MapList newMap = ((MappableContactMatrixI) restoredMat)
1672 Assert.assertEquals(oldMap.getFromRanges(), newMap.getFromRanges());
1673 Assert.assertEquals(oldMap.getToRanges(), newMap.getToRanges());
1674 Assert.assertEquals(oldMap.getFromRatio(), newMap.getFromRatio());
1675 Assert.assertEquals(oldMap.getToRatio(), newMap.getToRatio());
1676 for (i = sq.getLength() - 1; i >= 0; i--)
1678 ContactListI oldCM = dummyMat.getContactList(i),
1679 newCM = restoredMat.getContactList(i);
1680 for (int j = oldCM.getContactHeight(); j >= 0; j--)
1682 double old_j = oldCM.getContactAt(j);
1683 double new_j = newCM.getContactAt(j);
1684 Assert.assertEquals(old_j, new_j);
1687 Assert.assertEquals(restoredMat.hasGroups(), dummyMat.hasGroups());
1688 Assert.assertEquals(restoredMat.getGroups(), dummyMat.getGroups());
1689 Assert.assertEquals(restoredMat.hasTree(), dummyMat.hasTree());
1690 Assert.assertEquals(restoredMat.getNewick(), dummyMat.getNewick());
1692 // verify no duplicate PAE matrix data when new view created and saved
1694 // add reference annotations to view first, then copy
1695 AlignmentUtils.addReferenceAnnotationTo(newAl, newAl.getSequenceAt(0),
1696 newSeq.getAnnotation()[0], null);
1698 AlignmentViewPanel newview = af.newView("copy of PAE", true);
1700 // redundant asserts here check all is good with the new view firest...
1701 AlignmentI newviewAl = newview.getAlignment();
1702 SequenceI newviewSeq = newviewAl.getSequenceAt(0);
1703 // check annotation of the expected type exists
1704 Assert.assertEquals(newviewSeq.getAnnotation().length, 1);
1705 Assert.assertEquals(newviewSeq.getAnnotation()[0].graph, paeCm.graph);
1706 // check we have just one contact matrix mapping
1707 Assert.assertEquals(newviewSeq.getContactMaps().size(), 1);
1709 // and can be found for the annotation on the sequence
1710 ContactMatrixI newviewMat = newviewSeq
1711 .getContactMatrixFor(newviewSeq.getAnnotation()[0]);
1712 Assert.assertNotNull(newviewMat);
1714 Assert.assertTrue(newviewMat == restoredMat);
1716 // save the two views and restore. Now look at visible annotation to check
1717 // all views have shared refs.
1719 tfile = File.createTempFile("testStoreAndRecoverPAEmatrixTwoViews",
1721 new Jalview2XML(false).saveState(tfile);
1722 Desktop.instance.closeAll_actionPerformed(null);
1724 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
1725 DataSourceType.FILE);
1726 newAl = af.getAlignPanels().get(0).getAlignment();
1727 AlignmentAnnotation view1aa = newAl.getSequenceAt(0).getAnnotation()[0];
1729 newviewAl = af.getAlignPanels().get(1).getAlignment();
1730 AlignmentAnnotation view2aa = newviewAl.getSequenceAt(0)
1731 .getAnnotation()[0];
1733 // annotations are shared across alignment views - so should still have an
1734 // identical pair of annotations.
1735 Assert.assertTrue(view1aa == view2aa);
1736 // identical annotations means identical contact matrix mappings
1737 Assert.assertEquals(
1738 newAl.getDataset().getSequenceAt(0).getContactMaps().size(), 1);
1740 // TODO Verify when distinct mappable PAEs are created, only one PAE dataset
1741 // is actually held.
1742 // Assert.assertTrue(view1aa!=view2aa);
1743 // restoredMat = newAl.getContactMatrixFor(view1aa);
1744 // newviewMat = newviewAl.getContactMatrixFor(view2aa);
1745 // Assert.assertTrue(restoredMat!=newviewMat);
1749 @Test(groups = "Functional")
1750 public void testStoreAndRestoreIDwidthAndAnnotationHeight()
1753 Desktop.instance.closeAll_actionPerformed(null);
1754 final String SECONDVIEW = "With Diffferent IDwidth";
1755 // create a new tempfile
1756 File tempfile = File.createTempFile("jvIdWidthStoreRestore", "jvp");
1758 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1759 "examples/exampleFile.jvp", DataSourceType.FILE);
1760 assertNotNull(af, "Didn't read in the example file correctly.");
1761 // FIXME JAL-4281 test made platform dependent to pass, but probably
1762 // shouldn't be platform dependent
1763 assertEquals(af.alignPanel.getAlignViewport().getIdWidth(),
1764 Platform.isAMacAndNotJS() ? 144 : 138,
1765 "Legacy project import should have fixed ID width");
1767 af.alignPanel.getIdPanel().getIdCanvas().isManuallyAdjusted());
1769 af.alignPanel.getAlignViewport().setIdWidth(100);
1770 af.alignPanel.updateLayout();
1772 af.alignPanel.getIdPanel().getIdCanvas().isManuallyAdjusted());
1774 Jalview2XML jv2xml = new jalview.project.Jalview2XML(false);
1776 jv2xml.saveState(tempfile);
1777 assertTrue(jv2xml.errorMessage == null,
1778 "Failed to save dummy project with PCA: test broken");
1781 Desktop.instance.closeAll_actionPerformed(null);
1782 af = new FileLoader().LoadFileWaitTillLoaded(
1783 tempfile.getCanonicalPath(), DataSourceType.FILE);
1785 af.alignPanel.getIdPanel().getIdCanvas().isManuallyAdjusted());
1786 assertEquals(af.alignPanel.getAlignViewport().getIdWidth(), 100,
1787 "New project exported and import should have adjusted ID width");
1789 af.alignPanel.getAlignViewport().setIdWidth(100);
1790 af.alignPanel.updateLayout();
1792 af.alignPanel.getIdPanel().getIdCanvas().isManuallyAdjusted());
1794 // now make it autoadjusted
1795 af.alignPanel.getAlignViewport().setIdWidth(-1);
1796 af.alignPanel.getIdPanel().getIdCanvas().setManuallyAdjusted(false);
1797 af.alignPanel.updateLayout();
1799 af.alignPanel.getIdPanel().getIdCanvas().isManuallyAdjusted());
1800 assertTrue(af.alignPanel.getAlignViewport().getIdWidth() > -1,
1801 "New project exported and import should have adjusted ID width");
1803 jv2xml = new jalview.project.Jalview2XML(false);
1805 jv2xml.saveState(tempfile);
1806 assertTrue(jv2xml.errorMessage == null,
1807 "Failed to save dummy project with PCA: test broken");
1810 Desktop.instance.closeAll_actionPerformed(null);
1811 af = new FileLoader().LoadFileWaitTillLoaded(
1812 tempfile.getCanonicalPath(), DataSourceType.FILE);
1814 af.alignPanel.getIdPanel().getIdCanvas().isManuallyAdjusted());
1815 assertTrue(af.alignPanel.getAlignViewport().getIdWidth() > -1,
1816 "New project exported and import should have adjusted ID width");