Clover icon

Coverage Report

  1. Project Clover database Tue Mar 10 2026 14:58:44 GMT
  2. Package jalview.project

File Jalview2xmlTests.java

 

Code metrics

94
1,003
39
1
2,291
1,707
114
0.11
25.72
39
2.92

Classes

Class Line # Actions
Jalview2xmlTests 127 1,003 114
0.00%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
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.
11    *
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.
16    *
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.
20    */
21    package jalview.project;
22   
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;
30   
31    import java.awt.Color;
32    import java.awt.Rectangle;
33    import java.awt.event.MouseEvent;
34    import java.io.File;
35    import java.io.IOException;
36    import java.util.ArrayList;
37    import java.util.Arrays;
38    import java.util.BitSet;
39    import java.util.HashMap;
40    import java.util.List;
41    import java.util.Locale;
42    import java.util.Map;
43    import java.util.Vector;
44   
45    import javax.swing.JInternalFrame;
46   
47    import org.testng.Assert;
48    import org.testng.AssertJUnit;
49    import org.testng.annotations.AfterMethod;
50    import org.testng.annotations.BeforeClass;
51    import org.testng.annotations.Test;
52   
53    import jalview.analysis.AlignmentUtils;
54    import jalview.analysis.TreeBuilder;
55    import jalview.analysis.TreeModel;
56    import jalview.analysis.scoremodels.SimilarityParams;
57    import jalview.api.AlignViewportI;
58    import jalview.api.AlignmentViewPanel;
59    import jalview.api.FeatureColourI;
60    import jalview.api.ViewStyleI;
61    import jalview.api.structures.JalviewStructureDisplayI;
62    import jalview.bin.Cache;
63    import jalview.datamodel.AlignmentAnnotation;
64    import jalview.datamodel.AlignmentI;
65    import jalview.datamodel.Annotation;
66    import jalview.datamodel.BinaryNode;
67    import jalview.datamodel.ContactListI;
68    import jalview.datamodel.ContactMatrix;
69    import jalview.datamodel.ContactMatrixI;
70    import jalview.datamodel.DBRefEntry;
71    import jalview.datamodel.GeneLocus;
72    import jalview.datamodel.GroupSet;
73    import jalview.datamodel.HiddenMarkovModel;
74    import jalview.datamodel.HiddenSequences;
75    import jalview.datamodel.Mapping;
76    import jalview.datamodel.PDBEntry;
77    import jalview.datamodel.PDBEntry.Type;
78    import jalview.datamodel.Sequence;
79    import jalview.datamodel.Sequence.DBModList;
80    import jalview.datamodel.SequenceCollectionI;
81    import jalview.datamodel.SequenceFeature;
82    import jalview.datamodel.SequenceGroup;
83    import jalview.datamodel.SequenceI;
84    import jalview.datamodel.features.FeatureMatcher;
85    import jalview.datamodel.features.FeatureMatcherSet;
86    import jalview.datamodel.features.FeatureMatcherSetI;
87    import jalview.gui.AlignFrame;
88    import jalview.gui.AlignViewport;
89    import jalview.gui.AlignmentPanel;
90    import jalview.gui.AppJmol;
91    import jalview.gui.Desktop;
92    import jalview.gui.JvOptionPane;
93    import jalview.gui.OverviewPanel;
94    import jalview.gui.PCAPanel;
95    import jalview.gui.PopupMenu;
96    import jalview.gui.Preferences;
97    import jalview.gui.SliderPanel;
98    import jalview.gui.StructureChooser;
99    import jalview.gui.StructureViewer;
100    import jalview.gui.StructureViewer.ViewerType;
101    import jalview.gui.TreePanel;
102    import jalview.io.DataSourceType;
103    import jalview.io.FileFormat;
104    import jalview.io.FileLoader;
105    import jalview.io.Jalview2xmlBase;
106    import jalview.renderer.ResidueShaderI;
107    import jalview.schemes.AnnotationColourGradient;
108    import jalview.schemes.BuriedColourScheme;
109    import jalview.schemes.ColourSchemeI;
110    import jalview.schemes.ColourSchemeProperty;
111    import jalview.schemes.FeatureColour;
112    import jalview.schemes.JalviewColourScheme;
113    import jalview.schemes.RNAHelicesColour;
114    import jalview.schemes.StrandColourScheme;
115    import jalview.schemes.TCoffeeColourScheme;
116    import jalview.structure.StructureImportSettings;
117    import jalview.util.MapList;
118    import jalview.util.matcher.Condition;
119    import jalview.viewmodel.AlignmentViewport;
120    import jalview.viewmodel.seqfeatures.FeatureRendererModel;
121    import jalview.ws.datamodel.MappableContactMatrixI;
122    import jalview.ws.datamodel.alphafold.PAEContactMatrix;
123    import jalview.ws.sifts.SiftsSettings;
124    import junit.extensions.PA;
125   
126    @Test(singleThreaded = true)
 
127    public class Jalview2xmlTests extends Jalview2xmlBase
128    {
 
129  0 toggle @AfterMethod(alwaysRun = true)
130    public void tearDown()
131    {
132  0 Desktop.getInstance().closeAll_actionPerformed(null);
133    }
134   
 
135  0 toggle @Override
136    @BeforeClass(alwaysRun = true)
137    public void setUpJvOptionPane()
138    {
139  0 if (Desktop.getInstance() != null)
140  0 Desktop.getInstance().closeAll_actionPerformed(null);
141  0 JvOptionPane.setInteractiveMode(false);
142  0 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
143    }
144   
 
145  0 toggle @Test(groups = { "Functional" })
146    public void testRNAStructureRecovery() throws Exception
147    {
148  0 String inFile = "examples/RF00031_folded.stk";
149  0 String tfile = File.createTempFile("JalviewTest", ".jvp")
150    .getAbsolutePath();
151  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
152    DataSourceType.FILE);
153  0 assertNotNull(af, "Didn't read input file " + inFile);
154  0 int olddsann = countDsAnn(af.getViewport());
155  0 assertTrue(olddsann > 0, "Didn't find any dataset annotations");
156  0 af.changeColour_actionPerformed(
157    JalviewColourScheme.RNAHelices.toString());
158  0 assertTrue(
159    af.getViewport()
160    .getGlobalColourScheme() instanceof RNAHelicesColour,
161    "Couldn't apply RNA helices colourscheme");
162  0 af.saveAlignment(tfile, FileFormat.Jalview);
163  0 assertTrue(af.isSaveAlignmentSuccessful(),
164    "Failed to store as a project.");
165  0 af.closeMenuItem_actionPerformed(true);
166  0 af = null;
167  0 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
168    DataSourceType.FILE);
169  0 assertNotNull(af, "Failed to import new project");
170  0 int newdsann = countDsAnn(af.getViewport());
171  0 assertEquals(olddsann, newdsann,
172    "Differing numbers of dataset sequence annotation\nOriginally "
173    + olddsann + " and now " + newdsann);
174  0 System.out.println(
175    "Read in same number of annotations as originally present ("
176    + olddsann + ")");
177  0 assertTrue(
178   
179    af.getViewport()
180    .getGlobalColourScheme() instanceof RNAHelicesColour,
181    "RNA helices colourscheme was not applied on import.");
182    }
183   
 
184  0 toggle @Test(groups = { "Functional" })
185    public void testTCoffeeScores() throws Exception
186    {
187  0 String inFile = "examples/uniref50.fa",
188    inAnnot = "examples/uniref50.score_ascii";
189  0 String tfile = File.createTempFile("JalviewTest", ".jvp")
190    .getAbsolutePath();
191  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
192    DataSourceType.FILE);
193  0 assertNotNull(af, "Didn't read input file " + inFile);
194  0 af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
195  0 AlignViewportI viewport = af.getViewport();
196  0 assertSame(viewport.getGlobalColourScheme().getClass(),
197    TCoffeeColourScheme.class, "Didn't set T-coffee colourscheme");
198  0 assertNotNull(
199    ColourSchemeProperty.getColourScheme(viewport,
200    viewport.getAlignment(),
201    viewport.getGlobalColourScheme().getSchemeName()),
202    "Recognise T-Coffee score from string");
203   
204  0 af.saveAlignment(tfile, FileFormat.Jalview);
205  0 assertTrue(af.isSaveAlignmentSuccessful(),
206    "Failed to store as a project.");
207  0 af.closeMenuItem_actionPerformed(true);
208  0 af = null;
209  0 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
210    DataSourceType.FILE);
211  0 assertNotNull(af, "Failed to import new project");
212  0 assertSame(af.getViewport().getGlobalColourScheme().getClass(),
213    TCoffeeColourScheme.class,
214    "Didn't set T-coffee colourscheme for imported project.");
215  0 System.out.println(
216    "T-Coffee score shading successfully recovered from project.");
217    }
218   
 
219  0 toggle @Test(groups = { "Functional" })
220    public void testColourByAnnotScores() throws Exception
221    {
222  0 String inFile = "examples/uniref50.fa",
223    inAnnot = "examples/testdata/uniref50_iupred.jva";
224  0 String tfile = File.createTempFile("JalviewTest", ".jvp")
225    .getAbsolutePath();
226  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
227    DataSourceType.FILE);
228  0 assertNotNull(af, "Didn't read input file " + inFile);
229  0 af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
230  0 AlignmentAnnotation[] aa = af.getViewport().getAlignment()
231    .getSequenceAt(0).getAnnotation("IUPredWS (Short)");
232  0 assertTrue(
233   
234    aa != null && aa.length > 0,
235    "Didn't find any IUPred annotation to use to shade alignment.");
236  0 AnnotationColourGradient cs = new AnnotationColourGradient(aa[0], null,
237    AnnotationColourGradient.ABOVE_THRESHOLD);
238  0 AnnotationColourGradient gcs = new AnnotationColourGradient(aa[0], null,
239    AnnotationColourGradient.BELOW_THRESHOLD);
240  0 cs.setSeqAssociated(true);
241  0 gcs.setSeqAssociated(true);
242  0 af.changeColour(cs);
243  0 SequenceGroup sg = new SequenceGroup();
244  0 sg.setStartRes(57);
245  0 sg.setEndRes(92);
246  0 sg.cs.setColourScheme(gcs);
247  0 af.getViewport().getAlignment().addGroup(sg);
248  0 sg.addSequence(af.getViewport().getAlignment().getSequenceAt(1), false);
249  0 sg.addSequence(af.getViewport().getAlignment().getSequenceAt(2), true);
250  0 af.alignPanel.alignmentChanged();
251  0 af.saveAlignment(tfile, FileFormat.Jalview);
252  0 assertTrue(af.isSaveAlignmentSuccessful(),
253    "Failed to store as a project.");
254  0 af.closeMenuItem_actionPerformed(true);
255  0 af = null;
256  0 af = new FileLoader().LoadFileWaitTillLoaded(tfile,
257    DataSourceType.FILE);
258  0 assertNotNull(af, "Failed to import new project");
259   
260    // check for group and alignment colourschemes
261   
262  0 ColourSchemeI _rcs = af.getViewport().getGlobalColourScheme();
263  0 ColourSchemeI _rgcs = af.getViewport().getAlignment().getGroups().get(0)
264    .getColourScheme();
265  0 assertNotNull(_rcs, "Didn't recover global colourscheme");
266  0 assertTrue(_rcs instanceof AnnotationColourGradient,
267    "Didn't recover annotation colour global scheme");
268  0 AnnotationColourGradient __rcs = (AnnotationColourGradient) _rcs;
269  0 assertTrue(__rcs.isSeqAssociated(),
270    "Annotation colourscheme wasn't sequence associated");
271   
272  0 boolean diffseqcols = false, diffgseqcols = false;
273  0 SequenceI[] sqs = af.getViewport().getAlignment().getSequencesArray();
274  0 for (int p = 0,
275  0 pSize = af.getViewport().getAlignment().getWidth(); p < pSize
276    && (!diffseqcols || !diffgseqcols); p++)
277    {
278  0 if (_rcs.findColour(sqs[0].getCharAt(p), p, sqs[0], null, 0f) != _rcs
279    .findColour(sqs[5].getCharAt(p), p, sqs[5], null, 0f))
280    {
281  0 diffseqcols = true;
282    }
283    }
284  0 assertTrue(diffseqcols, "Got Different sequence colours");
285  0 System.out.println(
286    "Per sequence colourscheme (Background) successfully applied and recovered.");
287   
288  0 assertNotNull(_rgcs, "Didn't recover group colourscheme");
289  0 assertTrue(_rgcs instanceof AnnotationColourGradient,
290    "Didn't recover annotation colour group colourscheme");
291  0 __rcs = (AnnotationColourGradient) _rgcs;
292  0 assertTrue(__rcs.isSeqAssociated(),
293    "Group Annotation colourscheme wasn't sequence associated");
294   
295  0 for (int p = 0,
296  0 pSize = af.getViewport().getAlignment().getWidth(); p < pSize
297    && (!diffseqcols || !diffgseqcols); p++)
298    {
299  0 if (_rgcs.findColour(sqs[1].getCharAt(p), p, sqs[1], null,
300    0f) != _rgcs.findColour(sqs[2].getCharAt(p), p, sqs[2], null,
301    0f))
302    {
303  0 diffgseqcols = true;
304    }
305    }
306  0 assertTrue(diffgseqcols, "Got Different group sequence colours");
307  0 System.out.println(
308    "Per sequence (Group) colourscheme successfully applied and recovered.");
309    }
310   
 
311  0 toggle @Test(groups = { "Functional" })
312    public void gatherViewsHere() throws Exception
313    {
314  0 int origCount = Desktop.getDesktopAlignFrames() == null ? 0
315    : Desktop.getDesktopAlignFrames().length;
316  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
317    "examples/exampleFile_2_7.jar", DataSourceType.FILE);
318  0 assertNotNull(af, "Didn't read in the example file correctly.");
319  0 assertTrue(Desktop.getDesktopAlignFrames().length == 1 + origCount,
320    "Didn't gather the views in the example file.");
321   
322    }
323   
324    /**
325    * Test for JAL-2223 - multiple mappings in View Mapping report
326    *
327    * @throws Exception
328    */
 
329  0 toggle @Test(groups = { "Functional" })
330    public void noDuplicatePdbMappingsMade() throws Exception
331    {
332  0 boolean oldmws = SiftsSettings.isMapWithSifts();
333  0 SiftsSettings.setMapWithSifts(false);
334  0 StructureImportSettings.setProcessSecondaryStructure(true);
335  0 StructureImportSettings.setVisibleChainAnnotation(true);
336  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
337    "examples/exampleFile_2_7.jar", DataSourceType.FILE);
338  0 assertNotNull(af, "Didn't read in the example file correctly.");
339    // TODO JAL-4107 - we need to wait a sec here whilst PDB mappings are
340    // instantiated on the alignment
341    // TODO JAL-4107 - should LoadFileWaitTillLoaded not return till *after* all
342    // that business is done ?
343   
344  0 try
345    {
346  0 Thread.sleep(1000);
347    } catch (InterruptedException foo)
348    {
349    }
350   
351    // locate Jmol viewer
352    // count number of PDB mappings the structure selection manager holds -
353  0 String pdbFile = af.getCurrentView().getStructureSelectionManager()
354    .findFileForPDBId("1A70");
355  0 assertEquals(
356    af.getCurrentView().getStructureSelectionManager()
357    .getMapping(pdbFile).length,
358    2, "Expected only two mappings for 1A70");
359  0 SiftsSettings.setMapWithSifts(oldmws);
360   
361    }
362   
 
363  0 toggle @Test(groups = { "Functional" })
364    public void viewRefPdbAnnotation() throws Exception
365    {
366  0 StructureImportSettings.setProcessSecondaryStructure(true);
367  0 StructureImportSettings.setVisibleChainAnnotation(true);
368  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
369    "examples/exampleFile_2_7.jar", DataSourceType.FILE);
370  0 assertNotNull(af, "Didn't read in the example file correctly.");
371  0 AlignmentViewPanel sps = null;
372  0 for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
373    {
374  0 if ("Spinach Feredoxin Structure".equals(ap.getViewName()))
375    {
376  0 sps = ap;
377  0 break;
378    }
379    }
380  0 assertNotNull(sps, "Couldn't find the structure view");
381  0 AlignmentAnnotation refan = null;
382  0 for (AlignmentAnnotation ra : sps.getAlignment()
383    .getAlignmentAnnotation())
384    {
385  0 if (ra.graph != 0)
386    {
387  0 refan = ra;
388  0 break;
389    }
390    }
391  0 assertNotNull(refan, "Annotation secondary structure not found.");
392  0 SequenceI sq = sps.getAlignment().findName("1A70|");
393  0 assertNotNull(sq, "Couldn't find 1a70 null chain");
394    // compare the manually added temperature factor annotation
395    // to the track automatically transferred from the pdb structure on load
396  0 assertNotNull(sq.getDatasetSequence().getAnnotation(),
397    "1a70 has no annotation");
398  0 for (AlignmentAnnotation ala : sq.getDatasetSequence().getAnnotation())
399    {
400  0 AlignmentAnnotation alaa;
401  0 sq.addAlignmentAnnotation(alaa = new AlignmentAnnotation(ala));
402  0 alaa.adjustForAlignment();
403  0 if (ala.graph == refan.graph)
404    {
405  0 for (int p = 0; p < ala.annotations.length; p++)
406    {
407  0 sq.findPosition(p);
408  0 try
409    {
410  0 assertTrue((alaa.annotations[p] == null
411    && refan.annotations[p] == null)
412    || alaa.annotations[p].value == refan.annotations[p].value,
413    "Mismatch at alignment position " + p);
414    } catch (NullPointerException q)
415    {
416  0 Assert.fail("Mismatch of alignment annotations at position " + p
417    + " Ref seq ann: " + refan.annotations[p]
418    + " alignment " + alaa.annotations[p]);
419    }
420    }
421    }
422    }
423   
424    }
425   
 
426  0 toggle @Test(groups = { "Functional" })
427    public void testCopyViewSettings() throws Exception
428    {
429  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
430    "examples/exampleFile_2_7.jar", DataSourceType.FILE);
431  0 assertNotNull(af, "Didn't read in the example file correctly.");
432  0 AlignmentViewPanel sps = null, groups = null;
433  0 for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
434    {
435  0 if ("Spinach Feredoxin Structure".equals(ap.getViewName()))
436    {
437  0 sps = ap;
438    }
439  0 if (ap.getViewName().contains("MAFFT"))
440    {
441  0 groups = ap;
442    }
443    }
444  0 assertNotNull(sps, "Couldn't find the structure view");
445  0 assertNotNull(groups, "Couldn't find the MAFFT view");
446   
447  0 ViewStyleI structureStyle = sps.getAlignViewport().getViewStyle();
448  0 ViewStyleI groupStyle = groups.getAlignViewport().getViewStyle();
449  0 AssertJUnit.assertFalse(structureStyle.sameStyle(groupStyle));
450   
451  0 groups.getAlignViewport().setViewStyle(structureStyle);
452  0 AssertJUnit.assertFalse(
453    groupStyle.sameStyle(groups.getAlignViewport().getViewStyle()));
454  0 Assert.assertTrue(structureStyle
455    .sameStyle(groups.getAlignViewport().getViewStyle()));
456   
457    }
458   
459    /**
460    * test store and recovery of expanded views
461    *
462    * @throws Exception
463    */
 
464  0 toggle @Test(groups = { "Functional" }, enabled = true)
465    public void testStoreAndRecoverExpandedviews() throws Exception
466    {
467  0 Desktop.getInstance().closeAll_actionPerformed(null);
468   
469  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
470    "examples/exampleFile_2_7.jar", DataSourceType.FILE);
471  0 Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 1);
472  0 String afid = af.getViewport().getSequenceSetId();
473   
474    // check FileLoader returned a reference to the one alignFrame that is
475    // actually on the Desktop
476  0 assertSame(af, Desktop.getAlignFrameFor(af.getViewport()),
477    "Jalview2XML.loadAlignFrame() didn't return correct AlignFrame reference for multiple view window");
478   
479  0 Desktop.explodeViews(af);
480   
481  0 int oldviews = Desktop.getDesktopAlignFrames().length;
482  0 Assert.assertEquals(Desktop.getDesktopAlignFrames().length,
483    Desktop.getAlignmentPanels(afid).length);
484  0 File tfile = File.createTempFile("testStoreAndRecoverExpanded", ".jvp");
485  0 try
486    {
487  0 new Jalview2XML(false).saveState(tfile);
488    } catch (Error e)
489    {
490  0 Assert.fail("Didn't save the expanded view state", e);
491    } catch (Exception e)
492    {
493  0 Assert.fail("Didn't save the expanded view state", e);
494    }
495  0 Desktop.getInstance().closeAll_actionPerformed(null);
496  0 if (Desktop.getDesktopAlignFrames() != null)
497    {
498  0 Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 0);
499    }
500  0 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
501    DataSourceType.FILE);
502  0 Assert.assertNotNull(af);
503  0 Assert.assertEquals(Desktop.getDesktopAlignFrames().length,
504    Desktop.getAlignmentPanels(
505    af.getViewport().getSequenceSetId()).length);
506  0 Assert.assertEquals(Desktop
507    .getAlignmentPanels(af.getViewport().getSequenceSetId()).length,
508    oldviews);
509    }
510   
511    /**
512    * Test save and reload of a project with a different representative sequence
513    * in each view.
514    *
515    * @throws Exception
516    */
 
517  0 toggle @Test(groups = { "Functional" })
518    public void testStoreAndRecoverReferenceSeqSettings() throws Exception
519    {
520  0 Desktop.getInstance().closeAll_actionPerformed(null);
521  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
522    "examples/exampleFile_2_7.jar", DataSourceType.FILE);
523  0 assertNotNull(af, "Didn't read in the example file correctly.");
524  0 String afid = af.getViewport().getSequenceSetId();
525   
526    // remember reference sequence for each panel
527  0 Map<String, SequenceI> refseqs = new HashMap<>();
528   
529    /*
530    * mark sequence 2, 3, 4.. in panels 1, 2, 3...
531    * as reference sequence for itself and the preceding sequence
532    */
533  0 int n = 1;
534  0 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
535    {
536  0 AlignViewportI av = ap.getAlignViewport();
537  0 AlignmentI alignment = ap.getAlignment();
538  0 int repIndex = n % alignment.getHeight();
539  0 SequenceI rep = alignment.getSequenceAt(repIndex);
540  0 refseqs.put(ap.getViewName(), rep);
541   
542    // code from mark/unmark sequence as reference in jalview.gui.PopupMenu
543    // todo refactor this to an alignment view controller
544  0 av.setDisplayReferenceSeq(true);
545  0 av.setColourByReferenceSeq(true);
546  0 av.getAlignment().setSeqrep(rep);
547   
548  0 n++;
549    }
550  0 File tfile = File.createTempFile("testStoreAndRecoverReferenceSeq",
551    ".jvp");
552  0 try
553    {
554  0 new Jalview2XML(false).saveState(tfile);
555    } catch (Throwable e)
556    {
557  0 Assert.fail("Didn't save the expanded view state", e);
558    }
559  0 Desktop.getInstance().closeAll_actionPerformed(null);
560  0 if (Desktop.getDesktopAlignFrames() != null)
561    {
562  0 Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 0);
563    }
564   
565  0 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
566    DataSourceType.FILE);
567  0 afid = af.getViewport().getSequenceSetId();
568   
569  0 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
570    {
571    // check representative
572  0 AlignmentI alignment = ap.getAlignment();
573  0 SequenceI rep = alignment.getSeqrep();
574  0 Assert.assertNotNull(rep,
575    "Couldn't restore sequence representative from project");
576    // can't use a strong equals here, because by definition, the sequence IDs
577    // will be different.
578    // could set vamsas session save/restore flag to preserve IDs across
579    // load/saves.
580  0 Assert.assertEquals(refseqs.get(ap.getViewName()).toString(),
581    rep.toString(),
582    "Representative wasn't the same when recovered.");
583  0 Assert.assertTrue(ap.getAlignViewport().isDisplayReferenceSeq(),
584    "Display reference sequence view setting not set.");
585  0 Assert.assertTrue(ap.getAlignViewport().isColourByReferenceSeq(),
586    "Colour By Reference Seq view setting not set.");
587    }
588    }
589   
 
590  0 toggle @Test(groups = { "Functional" })
591    public void testIsVersionStringLaterThan()
592    {
593    /*
594    * No version / development / test / autobuild is leniently assumed to be
595    * compatible
596    */
597  0 assertTrue(Jalview2XML.isVersionStringLaterThan(null, null));
598  0 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", null));
599  0 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "2.8.3"));
600  0 assertTrue(Jalview2XML.isVersionStringLaterThan(null,
601    "Development Build"));
602  0 assertTrue(Jalview2XML.isVersionStringLaterThan(null,
603    "DEVELOPMENT BUILD"));
604  0 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
605    "Development Build"));
606  0 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "Test"));
607  0 assertTrue(Jalview2XML.isVersionStringLaterThan(null, "TEST"));
608  0 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "Test"));
609  0 assertTrue(
610    Jalview2XML.isVersionStringLaterThan(null, "Automated Build"));
611  0 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
612    "Automated Build"));
613  0 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
614    "AUTOMATED BUILD"));
615   
616    /*
617    * same version returns true i.e. compatible
618    */
619  0 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8", "2.8"));
620  0 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.3"));
621  0 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3b1"));
622  0 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3B1", "2.8.3b1"));
623  0 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3B1"));
624   
625    /*
626    * later version returns true
627    */
628  0 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.4"));
629  0 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.9"));
630  0 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.9.2"));
631  0 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8", "2.8.3"));
632  0 assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.3b1"));
633   
634    /*
635    * earlier version returns false
636    */
637  0 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8"));
638  0 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.4", "2.8.3"));
639  0 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3"));
640  0 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.2b1"));
641  0 assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.0b2", "2.8.0b1"));
642    /*
643    * test for patch release versions
644    */
645  0 assertFalse(Jalview2XML.isVersionStringLaterThan("2.11.3.0", "2.11.2"));
646  0 assertTrue(Jalview2XML.isVersionStringLaterThan("2.11.3.0", "2.11.4"));
647  0 assertFalse(
648    Jalview2XML.isVersionStringLaterThan("2.12.2.0b1", "2.12.2.0"));
649  0 assertFalse(
650    Jalview2XML.isVersionStringLaterThan("2.12.2.3", "2.12.2.2"));
651   
652    }
653   
654    /**
655    * Test save and reload of a project with a different sequence group (and
656    * representative sequence) in each view.
657    *
658    * @throws Exception
659    */
 
660  0 toggle @Test(groups = { "Functional" })
661    public void testStoreAndRecoverGroupRepSeqs() throws Exception
662    {
663  0 Desktop.getInstance().closeAll_actionPerformed(null);
664  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
665    "examples/uniref50.fa", DataSourceType.FILE);
666  0 assertNotNull(af, "Didn't read in the example file correctly.");
667  0 String afid = af.getViewport().getSequenceSetId();
668    // make a second view of the alignment
669  0 af.newView_actionPerformed(null);
670   
671    /*
672    * remember representative and hidden sequences marked
673    * on each panel
674    */
675  0 Map<String, SequenceI> repSeqs = new HashMap<>();
676  0 Map<String, List<String>> hiddenSeqNames = new HashMap<>();
677   
678    /*
679    * mark sequence 2, 3, 4.. in panels 1, 2, 3...
680    * as reference sequence for itself and the preceding sequence
681    */
682  0 int n = 1;
683  0 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
684    {
685  0 AlignViewportI av = ap.getAlignViewport();
686  0 AlignmentI alignment = ap.getAlignment();
687  0 int repIndex = n % alignment.getHeight();
688    // ensure at least one preceding sequence i.e. index >= 1
689  0 repIndex = Math.max(repIndex, 1);
690  0 SequenceI repSeq = alignment.getSequenceAt(repIndex);
691  0 repSeqs.put(ap.getViewName(), repSeq);
692  0 List<String> hiddenNames = new ArrayList<>();
693  0 hiddenSeqNames.put(ap.getViewName(), hiddenNames);
694   
695    /*
696    * have rep sequence represent itself and the one before it
697    * this hides the group (except for the rep seq)
698    */
699  0 SequenceGroup sg = new SequenceGroup();
700  0 sg.addSequence(repSeq, false);
701  0 SequenceI precedingSeq = alignment.getSequenceAt(repIndex - 1);
702  0 sg.addSequence(precedingSeq, false);
703  0 sg.setSeqrep(repSeq);
704  0 assertTrue(sg.getSequences().contains(repSeq));
705  0 assertTrue(sg.getSequences().contains(precedingSeq));
706  0 av.setSelectionGroup(sg);
707  0 assertSame(repSeq, sg.getSeqrep());
708   
709    /*
710    * represent group with sequence adds to a map of hidden rep sequences
711    * (it does not create a group on the alignment)
712    */
713  0 ((AlignmentViewport) av).hideSequences(repSeq, true);
714  0 assertSame(repSeq, sg.getSeqrep());
715  0 assertTrue(sg.getSequences().contains(repSeq));
716  0 assertTrue(sg.getSequences().contains(precedingSeq));
717  0 assertTrue(alignment.getGroups().isEmpty(), "alignment has groups");
718  0 Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av
719    .getHiddenRepSequences();
720  0 assertNotNull(hiddenRepSeqsMap);
721  0 assertEquals(1, hiddenRepSeqsMap.size());
722  0 assertSame(sg, hiddenRepSeqsMap.get(repSeq));
723  0 assertTrue(alignment.getHiddenSequences().isHidden(precedingSeq));
724  0 assertFalse(alignment.getHiddenSequences().isHidden(repSeq));
725  0 hiddenNames.add(precedingSeq.getName());
726   
727  0 n++;
728    }
729  0 File tfile = File.createTempFile("testStoreAndRecoverGroupReps",
730    ".jvp");
731  0 try
732    {
733  0 new Jalview2XML(false).saveState(tfile);
734    } catch (Throwable e)
735    {
736  0 Assert.fail("Didn't save the expanded view state", e);
737    }
738  0 Desktop.getInstance().closeAll_actionPerformed(null);
739  0 if (Desktop.getDesktopAlignFrames() != null)
740    {
741  0 Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 0);
742    }
743   
744  0 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
745    DataSourceType.FILE);
746  0 afid = af.getViewport().getSequenceSetId();
747   
748  0 for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
749    {
750  0 String viewName = ap.getViewName();
751  0 AlignViewportI av = ap.getAlignViewport();
752  0 AlignmentI alignment = ap.getAlignment();
753  0 List<SequenceGroup> groups = alignment.getGroups();
754  0 assertNotNull(groups);
755  0 assertTrue(groups.isEmpty(), "Alignment has groups");
756  0 Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av
757    .getHiddenRepSequences();
758  0 assertNotNull(hiddenRepSeqsMap, "No hidden represented sequences");
759  0 assertEquals(1, hiddenRepSeqsMap.size());
760  0 assertEquals(repSeqs.get(viewName).getDisplayId(true),
761    hiddenRepSeqsMap.keySet().iterator().next()
762    .getDisplayId(true));
763   
764    /*
765    * verify hidden sequences in restored panel
766    */
767  0 List<String> hidden = hiddenSeqNames.get(ap.getViewName());
768  0 HiddenSequences hs = alignment.getHiddenSequences();
769  0 assertEquals(hidden.size(), hs.getSize(),
770    "wrong number of restored hidden sequences in "
771    + ap.getViewName());
772    }
773    }
774   
775    /**
776    * Test save and reload of PDBEntry in Jalview project
777    *
778    * @throws Exception
779    */
 
780  0 toggle @Test(groups = { "Functional" })
781    public void testStoreAndRecoverPDBEntry() throws Exception
782    {
783  0 Desktop.getInstance().closeAll_actionPerformed(null);
784  0 String exampleFile = "examples/3W5V.pdb";
785  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
786    DataSourceType.FILE);
787  0 assertNotNull(af, "Didn't read in the example file correctly.");
788  0 String afid = af.getViewport().getSequenceSetId();
789   
790  0 AlignmentViewPanel[] alignPanels = Desktop.getAlignmentPanels(afid);
791  0 System.out.println();
792  0 AlignmentViewPanel ap = alignPanels[0];
793  0 String tfileBase = new File(".").getAbsolutePath().replace(".", "");
794  0 String testFile = tfileBase + exampleFile;
795  0 AlignmentI alignment = ap.getAlignment();
796  0 System.out.println("blah");
797  0 SequenceI[] seqs = alignment.getSequencesArray();
798  0 Assert.assertNotNull(seqs[0]);
799  0 Assert.assertNotNull(seqs[1]);
800  0 Assert.assertNotNull(seqs[2]);
801  0 Assert.assertNotNull(seqs[3]);
802  0 Assert.assertNotNull(seqs[0].getDatasetSequence());
803  0 Assert.assertNotNull(seqs[1].getDatasetSequence());
804  0 Assert.assertNotNull(seqs[2].getDatasetSequence());
805  0 Assert.assertNotNull(seqs[3].getDatasetSequence());
806  0 PDBEntry[] pdbEntries = new PDBEntry[4];
807  0 pdbEntries[0] = new PDBEntry("3W5V", "A", Type.PDB, testFile);
808  0 pdbEntries[1] = new PDBEntry("3W5V", "B", Type.PDB, testFile);
809  0 pdbEntries[2] = new PDBEntry("3W5V", "C", Type.PDB, testFile);
810  0 pdbEntries[3] = new PDBEntry("3W5V", "D", Type.PDB, testFile);
811  0 Assert.assertEquals(
812    seqs[0].getDatasetSequence().getAllPDBEntries().get(0),
813    pdbEntries[0]);
814  0 Assert.assertEquals(
815    seqs[1].getDatasetSequence().getAllPDBEntries().get(0),
816    pdbEntries[1]);
817  0 Assert.assertEquals(
818    seqs[2].getDatasetSequence().getAllPDBEntries().get(0),
819    pdbEntries[2]);
820  0 Assert.assertEquals(
821    seqs[3].getDatasetSequence().getAllPDBEntries().get(0),
822    pdbEntries[3]);
823   
824  0 File tfile = File.createTempFile("testStoreAndRecoverPDBEntry", ".jvp");
825  0 try
826    {
827  0 new Jalview2XML(false).saveState(tfile);
828    } catch (Throwable e)
829    {
830  0 Assert.fail("Didn't save the state", e);
831    }
832  0 Desktop.getInstance().closeAll_actionPerformed(null);
833  0 if (Desktop.getDesktopAlignFrames() != null)
834    {
835  0 Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 0);
836    }
837   
838  0 AlignFrame restoredFrame = new FileLoader().LoadFileWaitTillLoaded(
839    tfile.getAbsolutePath(), DataSourceType.FILE);
840  0 String rfid = restoredFrame.getViewport().getSequenceSetId();
841  0 AlignmentViewPanel[] rAlignPanels = Desktop.getAlignmentPanels(rfid);
842  0 AlignmentViewPanel rap = rAlignPanels[0];
843  0 AlignmentI rAlignment = rap.getAlignment();
844  0 System.out.println("blah");
845  0 SequenceI[] rseqs = rAlignment.getSequencesArray();
846  0 Assert.assertNotNull(rseqs[0]);
847  0 Assert.assertNotNull(rseqs[1]);
848  0 Assert.assertNotNull(rseqs[2]);
849  0 Assert.assertNotNull(rseqs[3]);
850  0 Assert.assertNotNull(rseqs[0].getDatasetSequence());
851  0 Assert.assertNotNull(rseqs[1].getDatasetSequence());
852  0 Assert.assertNotNull(rseqs[2].getDatasetSequence());
853  0 Assert.assertNotNull(rseqs[3].getDatasetSequence());
854   
855    // The Asserts below are expected to fail until the PDB chainCode is
856    // recoverable from a Jalview projects
857  0 for (int chain = 0; chain < 4; chain++)
858    {
859  0 PDBEntry recov = rseqs[chain].getDatasetSequence().getAllPDBEntries()
860    .get(0);
861  0 PDBEntry expected = pdbEntries[chain];
862  0 Assert.assertEquals(recov.getId(), expected.getId(),
863    "Mismatch PDB ID");
864  0 Assert.assertEquals(recov.getChainCode(), expected.getChainCode(),
865    "Mismatch PDB ID");
866  0 Assert.assertEquals(recov.getType(), expected.getType(),
867    "Mismatch PDBEntry 'Type'");
868  0 Assert.assertNotNull(recov.getFile(),
869    "Recovered PDBEntry should have a non-null file entry");
870  0 Assert.assertEquals(
871    recov.getFile().toLowerCase(Locale.ENGLISH)
872    .lastIndexOf("pdb"),
873    recov.getFile().length() - 3,
874    "Recovered PDBEntry file should have PDB suffix");
875    }
876    }
877   
878    /**
879    * Test save and reload of Jmol view in Jalview project is restored to same
880    * location/etc Currently fails (2.11.4.2 onwards and 2.12)
881    *
882    * @throws Exception
883    */
 
884  0 toggle @Test(groups = { "Functional" }, enabled = false)
885    public void testStoreAndRecoverStructView() throws Exception
886    {
887  0 Desktop.getInstance().closeAll_actionPerformed(null);
888  0 String exampleFile = "examples/3W5V.pdb";
889  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
890    DataSourceType.FILE);
891  0 assertNotNull(af, "Didn't read in the example file correctly.");
892  0 StructureViewer sv[] = new StructureViewer[] { null };
893  0 Thread t = new Thread(new Runnable()
894    {
 
895  0 toggle @Override
896    public void run()
897    {
898  0 sv[0] = StructureChooser.openStructureFileForSequence(
899    af.alignPanel.getStructureSelectionManager(), null,
900    af.alignPanel,
901   
902    af.getViewport().getAlignment().getSequenceAt(0), false,
903    exampleFile, null, null, false, false, false,
904    ViewerType.JMOL);
905    }
906    });
907  0 t.start();
908  0 int n = 1;
909  0 do
910    {
911  0 try
912    {
913  0 Thread.sleep(50 * n);
914    } catch (InterruptedException x)
915    {
916    }
917  0 ;
918  0 } while (!(sv[0] != null && sv[0].getJalviewStructureDisplay() != null
919    && sv[0].getJalviewStructureDisplay().getWidth() > 0)
920    && t.isAlive() && n++ < 10);
921  0 Assert.assertNotNull(sv[0]);
922  0 ((AppJmol) sv[0].getJalviewStructureDisplay()).setLocation(65, 75);
923  0 int x = sv[0].getJalviewStructureDisplay().getX(),
924    y = sv[0].getJalviewStructureDisplay().getY();
925    // shouldn't be square!
926  0 Assert.assertTrue(x != y);
927   
928  0 File tfile = File.createTempFile("testStoreAndRecoverPDBEntry", ".jvp");
929  0 try
930    {
931  0 new Jalview2XML(false).saveState(tfile);
932    } catch (Throwable e)
933    {
934  0 Assert.fail("Didn't save the state", e);
935    }
936  0 Desktop.getInstance().closeAll_actionPerformed(null);
937  0 if (Desktop.getDesktopAlignFrames() != null)
938    {
939  0 Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 0);
940    }
941   
942  0 JalviewStructureDisplayI newDisplay = null;
943  0 AlignFrame restoredFrame = new FileLoader().LoadFileWaitTillLoaded(
944    tfile.getAbsolutePath(), DataSourceType.FILE);
945  0 for (JInternalFrame f : Desktop.getInstance().getAllFrames())
946    {
947  0 if (f instanceof JalviewStructureDisplayI)
948    {
949  0 Assert.assertNull(newDisplay,
950    "More than one structure viewer was created in test. Unexpected fail.");
951  0 newDisplay = (JalviewStructureDisplayI) f;
952    }
953    }
954    // wait around again
955  0 n = 1;
956  0 do
957    {
958  0 try
959    {
960  0 Thread.sleep(50 * n);
961    } catch (InterruptedException iex)
962    {
963    }
964  0 ;
965  0 } while (!(newDisplay.getWidth() > 0));
966   
967  0 Assert.assertEquals(restoredFrame.getX(), x);
968  0 Assert.assertEquals(restoredFrame.getY(), y);
969    }
970   
971    /**
972    * Configure an alignment and a sub-group each with distinct colour schemes,
973    * Conservation and PID thresholds, and confirm these are restored from the
974    * saved project.
975    *
976    * @throws IOException
977    */
 
978  0 toggle @Test(groups = { "Functional" })
979    public void testStoreAndRecoverAnnotationRowElementColours()
980    throws IOException
981    {
982  0 Desktop.getInstance().closeAll_actionPerformed(null);
983  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded("SEQ\tMNQ",
984    DataSourceType.PASTE);
985   
986  0 AlignViewport av = af.getViewport();
987  0 AlignmentI al = av.getAlignment();
988  0 SequenceI fsq;
989  0 fsq = al.getSequenceAt(0);
990  0 Annotation annots[] = new Annotation[fsq.getLength()];
991  0 AlignmentAnnotation ala = new AlignmentAnnotation("Colour", "Annots",
992    annots);
993  0 annots[0] = new Annotation(1.0f);
994  0 annots[1] = new Annotation(2.0f);
995  0 annots[2] = new Annotation(3.0f);
996  0 annots[0].colour = Color.RED;
997  0 annots[1].colour = Color.GREEN;
998  0 annots[2].colour = Color.BLUE;
999  0 ala.validateRangeAndDisplay();
1000  0 al.getSequenceAt(0).addAlignmentAnnotation(ala);
1001  0 al.addAnnotation(ala);
1002    /*
1003    * and colour by annotation
1004    */
1005  0 AnnotationColourGradient acg = new AnnotationColourGradient(ala,
1006    af.alignPanel.av.getGlobalColourScheme(), 0);
1007  0 acg.setSeqAssociated(true);
1008  0 acg.setPredefinedColours(true);
1009  0 af.changeColour(acg);
1010  0 Color seqcol[] = new Color[3];
1011  0 for (int iStart = fsq.findIndex(fsq.getStart()), i = 0; i < 3; i++)
1012    {
1013  0 seqcol[i] = af.alignPanel.getSeqPanel().seqCanvas
1014    .getSequenceRenderer()
1015    .getResidueColour(fsq, iStart + i, null);
1016    }
1017    /*
1018    * save project, close windows, reload project, verify
1019    */
1020  0 File tfile = File.createTempFile(
1021    "testStoreAndRecoverAnnotRowElemColors", ".jvp");
1022  0 tfile.deleteOnExit();
1023  0 new Jalview2XML(false).saveState(tfile);
1024    // Desktop.instance.closeAll_actionPerformed(null);
1025  0 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
1026    DataSourceType.FILE);
1027  0 Assert.assertNotNull(af, "Failed to reload project");
1028    /*
1029    * verify alignment annotation has colors
1030    */
1031  0 av = af.getViewport();
1032   
1033  0 ColourSchemeI loadedCscheme = av.getGlobalColourScheme();
1034  0 Assert.assertTrue(loadedCscheme instanceof AnnotationColourGradient,
1035    "Didn't apply Annotation colour gradient");
1036  0 acg = (AnnotationColourGradient) loadedCscheme;
1037  0 assertTrue(acg.isSeqAssociated());
1038  0 assertTrue(acg.isPredefinedColours());
1039   
1040  0 al = av.getAlignment();
1041  0 fsq = al.getSequenceAt(0);
1042  0 ala = fsq.getAnnotation()[0];
1043  0 Assert.assertNotNull(ala, "No annotation row recovered");
1044  0 Assert.assertNotNull(ala.annotations);
1045  0 for (int iStart = al.getSequenceAt(0)
1046  0 .findIndex(al.getSequenceAt(0).getStart()), i = 0; i < 3; i++)
1047    {
1048  0 Assert.assertTrue(ala.annotations[i].colour != null);
1049  0 Assert.assertTrue(ala.annotations[i].colour.equals(annots[i].colour));
1050  0 Color newseqcol = af.alignPanel.getSeqPanel().seqCanvas
1051    .getSequenceRenderer()
1052    .getResidueColour(fsq, iStart + i, null);
1053  0 Assert.assertTrue(seqcol[i].equals(newseqcol),
1054    "Sequence shading is different");
1055   
1056    }
1057   
1058    }
1059   
1060    /**
1061    * Configure an alignment and a sub-group each with distinct colour schemes,
1062    * Conservation and PID thresholds, and confirm these are restored from the
1063    * saved project.
1064    *
1065    * @throws IOException
1066    */
 
1067  0 toggle @Test(groups = { "Functional" })
1068    public void testStoreAndRecoverColourThresholds() throws IOException
1069    {
1070  0 Desktop.getInstance().closeAll_actionPerformed(null);
1071  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1072    "examples/uniref50.fa", DataSourceType.FILE);
1073   
1074  0 AlignViewportI av = af.getViewport();
1075  0 AlignmentI al = av.getAlignment();
1076   
1077    /*
1078    * Colour alignment by Buried Index, Above 10% PID, By Conservation 20%
1079    */
1080  0 av.setColourAppliesToAllGroups(false);
1081  0 af.changeColour_actionPerformed(JalviewColourScheme.Buried.toString());
1082  0 assertTrue(av.getGlobalColourScheme() instanceof BuriedColourScheme);
1083  0 af.abovePIDThreshold_actionPerformed(true);
1084  0 SliderPanel sp = SliderPanel.getSliderPanel();
1085  0 assertFalse(sp.isForConservation());
1086  0 sp.valueChanged(10);
1087  0 af.conservationMenuItem_actionPerformed(true);
1088  0 sp = SliderPanel.getSliderPanel();
1089  0 assertTrue(sp.isForConservation());
1090  0 sp.valueChanged(20);
1091  0 ResidueShaderI rs = av.getResidueShading();
1092  0 assertEquals(rs.getThreshold(), 10);
1093  0 assertTrue(rs.conservationApplied());
1094  0 assertEquals(rs.getConservationInc(), 20);
1095   
1096    /*
1097    * create a group with Strand colouring, 30% Conservation
1098    * and 40% PID threshold
1099    * (notice menu action applies to selection group even if mouse click
1100    * is at a sequence not in the group)
1101    */
1102  0 SequenceGroup sg = new SequenceGroup();
1103  0 sg.addSequence(al.getSequenceAt(0), false);
1104  0 sg.setStartRes(15);
1105  0 sg.setEndRes(25);
1106  0 av.setSelectionGroup(sg);
1107  0 PopupMenu popupMenu = new PopupMenu(af.alignPanel, al.getSequenceAt(2),
1108    null);
1109  0 popupMenu.changeColour_actionPerformed(
1110    JalviewColourScheme.Strand.toString());
1111  0 assertTrue(sg.getColourScheme() instanceof StrandColourScheme);
1112  0 assertEquals(al.getGroups().size(), 1);
1113  0 assertSame(al.getGroups().get(0), sg);
1114  0 popupMenu.conservationMenuItem_actionPerformed(true);
1115  0 sp = SliderPanel.getSliderPanel();
1116  0 assertTrue(sp.isForConservation());
1117  0 sp.valueChanged(30);
1118  0 popupMenu.abovePIDColour_actionPerformed(true);
1119  0 sp = SliderPanel.getSliderPanel();
1120  0 assertFalse(sp.isForConservation());
1121  0 sp.valueChanged(40);
1122  0 assertTrue(sg.getGroupColourScheme().conservationApplied());
1123  0 assertEquals(sg.getGroupColourScheme().getConservationInc(), 30);
1124  0 assertEquals(sg.getGroupColourScheme().getThreshold(), 40);
1125   
1126    /*
1127    * save project, close windows, reload project, verify
1128    */
1129  0 File tfile = File.createTempFile("testStoreAndRecoverColourThresholds",
1130    ".jvp");
1131  0 tfile.deleteOnExit();
1132  0 new Jalview2XML(false).saveState(tfile);
1133  0 Desktop.getInstance().closeAll_actionPerformed(null);
1134  0 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
1135    DataSourceType.FILE);
1136  0 Assert.assertNotNull(af, "Failed to reload project");
1137   
1138    /*
1139    * verify alignment (background) colouring
1140    */
1141  0 rs = af.getViewport().getResidueShading();
1142  0 assertTrue(rs.getColourScheme() instanceof BuriedColourScheme);
1143  0 assertEquals(rs.getThreshold(), 10);
1144  0 assertTrue(rs.conservationApplied());
1145  0 assertEquals(rs.getConservationInc(), 20);
1146   
1147    /*
1148    * verify group colouring
1149    */
1150  0 assertEquals(1, af.getViewport().getAlignment().getGroups().size(), 1);
1151  0 rs = af.getViewport().getAlignment().getGroups().get(0)
1152    .getGroupColourScheme();
1153  0 assertTrue(rs.getColourScheme() instanceof StrandColourScheme);
1154  0 assertEquals(rs.getThreshold(), 40);
1155  0 assertTrue(rs.conservationApplied());
1156  0 assertEquals(rs.getConservationInc(), 30);
1157    }
1158   
1159    /**
1160    * Test save and reload of feature colour schemes and filter settings
1161    *
1162    * @throws IOException
1163    */
 
1164  0 toggle @Test(groups = { "Functional" })
1165    public void testSaveLoadFeatureColoursAndFilters() throws IOException
1166    {
1167  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1168    ">Seq1\nACDEFGHIKLM", DataSourceType.PASTE);
1169  0 SequenceI seq1 = af.getViewport().getAlignment().getSequenceAt(0);
1170   
1171    /*
1172    * add some features to the sequence
1173    */
1174  0 int score = 1;
1175  0 addFeatures(seq1, "type1", score++);
1176  0 addFeatures(seq1, "type2", score++);
1177  0 addFeatures(seq1, "type3", score++);
1178  0 addFeatures(seq1, "type4", score++);
1179  0 addFeatures(seq1, "type5", score++);
1180   
1181    /*
1182    * set colour schemes for features
1183    */
1184  0 FeatureRendererModel fr = af.getFeatureRenderer();
1185  0 fr.findAllFeatures(true);
1186   
1187    // type1: red
1188  0 fr.setColour("type1", new FeatureColour(Color.red));
1189   
1190    // type2: by label
1191  0 FeatureColourI byLabel = new FeatureColour();
1192  0 byLabel.setColourByLabel(true);
1193  0 fr.setColour("type2", byLabel);
1194   
1195    // type3: by score above threshold
1196  0 FeatureColourI byScore = new FeatureColour(null, Color.BLACK,
1197    Color.BLUE, null, 1, 10);
1198  0 byScore.setAboveThreshold(true);
1199  0 byScore.setThreshold(2f);
1200  0 fr.setColour("type3", byScore);
1201   
1202    // type4: by attribute AF
1203  0 FeatureColourI byAF = new FeatureColour();
1204  0 byAF.setColourByLabel(true);
1205  0 byAF.setAttributeName("AF");
1206  0 fr.setColour("type4", byAF);
1207   
1208    // type5: by attribute CSQ:PolyPhen below threshold
1209  0 FeatureColourI byPolyPhen = new FeatureColour(null, Color.BLACK,
1210    Color.BLUE, null, 1, 10);
1211  0 byPolyPhen.setBelowThreshold(true);
1212  0 byPolyPhen.setThreshold(3f);
1213  0 byPolyPhen.setAttributeName("CSQ", "PolyPhen");
1214  0 fr.setColour("type5", byPolyPhen);
1215   
1216    /*
1217    * set filters for feature types
1218    */
1219   
1220    // filter type1 features by (label contains "x")
1221  0 FeatureMatcherSetI filterByX = new FeatureMatcherSet();
1222  0 filterByX.and(FeatureMatcher.byLabel(Condition.Contains, "x"));
1223  0 fr.setFeatureFilter("type1", filterByX);
1224   
1225    // filter type2 features by (score <= 2.4 and score > 1.1)
1226  0 FeatureMatcherSetI filterByScore = new FeatureMatcherSet();
1227  0 filterByScore.and(FeatureMatcher.byScore(Condition.LE, "2.4"));
1228  0 filterByScore.and(FeatureMatcher.byScore(Condition.GT, "1.1"));
1229  0 fr.setFeatureFilter("type2", filterByScore);
1230   
1231    // filter type3 features by (AF contains X OR CSQ:PolyPhen != 0)
1232  0 FeatureMatcherSetI filterByXY = new FeatureMatcherSet();
1233  0 filterByXY
1234    .and(FeatureMatcher.byAttribute(Condition.Contains, "X", "AF"));
1235  0 filterByXY.or(FeatureMatcher.byAttribute(Condition.NE, "0", "CSQ",
1236    "PolyPhen"));
1237  0 fr.setFeatureFilter("type3", filterByXY);
1238   
1239    /*
1240    * save as Jalview project
1241    */
1242  0 File tfile = File.createTempFile("JalviewTest", ".jvp");
1243  0 tfile.deleteOnExit();
1244  0 String filePath = tfile.getAbsolutePath();
1245  0 af.saveAlignment(filePath, FileFormat.Jalview);
1246  0 assertTrue(af.isSaveAlignmentSuccessful(),
1247    "Failed to store as a project.");
1248   
1249    /*
1250    * close current alignment and load the saved project
1251    */
1252  0 af.closeMenuItem_actionPerformed(true);
1253  0 af = null;
1254  0 af = new FileLoader().LoadFileWaitTillLoaded(filePath,
1255    DataSourceType.FILE);
1256  0 assertNotNull(af, "Failed to import new project");
1257   
1258    /*
1259    * verify restored feature colour schemes and filters
1260    */
1261  0 fr = af.getFeatureRenderer();
1262  0 FeatureColourI fc = fr.getFeatureStyle("type1");
1263  0 assertTrue(fc.isSimpleColour());
1264  0 assertEquals(fc.getColour(), Color.red);
1265  0 fc = fr.getFeatureStyle("type2");
1266  0 assertTrue(fc.isColourByLabel());
1267  0 fc = fr.getFeatureStyle("type3");
1268  0 assertTrue(fc.isGraduatedColour());
1269  0 assertNull(fc.getAttributeName());
1270  0 assertTrue(fc.isAboveThreshold());
1271  0 assertEquals(fc.getThreshold(), 2f);
1272  0 fc = fr.getFeatureStyle("type4");
1273  0 assertTrue(fc.isColourByLabel());
1274  0 assertTrue(fc.isColourByAttribute());
1275  0 assertEquals(fc.getAttributeName(), new String[] { "AF" });
1276  0 fc = fr.getFeatureStyle("type5");
1277  0 assertTrue(fc.isGraduatedColour());
1278  0 assertTrue(fc.isColourByAttribute());
1279  0 assertEquals(fc.getAttributeName(), new String[] { "CSQ", "PolyPhen" });
1280  0 assertTrue(fc.isBelowThreshold());
1281  0 assertEquals(fc.getThreshold(), 3f);
1282   
1283  0 assertEquals(fr.getFeatureFilter("type1").toStableString(),
1284    "Label Contains x");
1285  0 assertEquals(fr.getFeatureFilter("type2").toStableString(),
1286    "(Score LE 2.4) AND (Score GT 1.1)");
1287  0 assertEquals(fr.getFeatureFilter("type3").toStableString(),
1288    "(AF Contains X) OR (CSQ:PolyPhen NE 0)");
1289    }
1290   
 
1291  0 toggle private void addFeature(SequenceI seq, String featureType, int score)
1292    {
1293  0 SequenceFeature sf = new SequenceFeature(featureType, "desc", 1, 2,
1294    score, "grp");
1295  0 sf.setValue("AF", score);
1296  0 sf.setValue("CSQ", new HashMap<String, String>()
1297    {
 
1298  0 toggle {
1299  0 put("PolyPhen", Integer.toString(score));
1300    }
1301    });
1302  0 seq.addSequenceFeature(sf);
1303    }
1304   
1305    /**
1306    * Adds two features of the given type to the given sequence, also setting the
1307    * score as the value of attribute "AF" and sub-attribute "CSQ:PolyPhen"
1308    *
1309    * @param seq
1310    * @param featureType
1311    * @param score
1312    */
 
1313  0 toggle private void addFeatures(SequenceI seq, String featureType, int score)
1314    {
1315  0 addFeature(seq, featureType, score++);
1316  0 addFeature(seq, featureType, score);
1317    }
1318   
1319    /**
1320    * Load an HMM profile to an alignment, and confirm it is correctly restored
1321    * when reloaded from project
1322    *
1323    * @throws IOException
1324    */
 
1325  0 toggle @Test(groups = { "Functional" })
1326    public void testStoreAndRecoverHmmProfile() throws IOException
1327    {
1328  0 Desktop.getInstance().closeAll_actionPerformed(null);
1329  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1330    "examples/uniref50.fa", DataSourceType.FILE);
1331   
1332  0 AlignViewportI av = af.getViewport();
1333  0 AlignmentI al = av.getAlignment();
1334   
1335    /*
1336    * mimic drag and drop of hmm file on to alignment
1337    */
1338  0 AlignFrame af2 = new FileLoader().LoadFileWaitTillLoaded(
1339    "examples/uniref50.hmm", DataSourceType.FILE);
1340  0 al.insertSequenceAt(0,
1341    af2.getViewport().getAlignment().getSequenceAt(0));
1342   
1343    /*
1344    * check it loaded in
1345    */
1346  0 SequenceI hmmSeq = al.getSequenceAt(0);
1347  0 assertTrue(hmmSeq.hasHMMProfile());
1348  0 HiddenMarkovModel hmm = hmmSeq.getHMM();
1349  0 assertSame(hmm.getConsensusSequence(), hmmSeq);
1350   
1351    /*
1352    * save project, close windows, reload project, verify
1353    */
1354  0 File tfile = File.createTempFile("testStoreAndRecoverHmmProfile",
1355    ".jvp");
1356  0 tfile.deleteOnExit();
1357  0 new Jalview2XML(false).saveState(tfile);
1358  0 Desktop.getInstance().closeAll_actionPerformed(null);
1359  0 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
1360    DataSourceType.FILE);
1361  0 Assert.assertNotNull(af, "Failed to reload project");
1362   
1363  0 hmmSeq = al.getSequenceAt(0);
1364  0 assertTrue(hmmSeq.hasHMMProfile());
1365  0 assertSame(hmm.getConsensusSequence(), hmmSeq);
1366  0 Mapping mapToHmmConsensus = (Mapping) PA.getValue(hmm,
1367    "mapToHmmConsensus");
1368  0 assertNotNull(mapToHmmConsensus);
1369  0 assertSame(mapToHmmConsensus.getTo(), hmmSeq.getDatasetSequence());
1370    }
1371   
1372    /**
1373    * pre 2.11 - jalview 2.10 erroneously created new dataset entries for each
1374    * view (JAL-3171) this test ensures we can import and merge those views
1375    */
 
1376  0 toggle @Test(groups = { "Functional" })
1377    public void testMergeDatasetsforViews() throws IOException
1378    {
1379    // simple project - two views on one alignment
1380  0 AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
1381    "examples/testdata/projects/twoViews.jvp", DataSourceType.FILE);
1382  0 assertNotNull(af);
1383  0 assertTrue(af.getAlignPanels().size() > 1);
1384  0 verifyDs(af);
1385    }
1386   
1387    /**
1388    * pre 2.11 - jalview 2.10 erroneously created new dataset entries for each
1389    * view (JAL-3171) this test ensures we can import and merge those views This
1390    * is a more complex project
1391    */
 
1392  0 toggle @Test(groups = { "Functional" })
1393    public void testMergeDatasetsforManyViews() throws IOException
1394    {
1395  0 Desktop.getInstance().closeAll_actionPerformed(null);
1396   
1397    // complex project - one dataset, several views on several alignments
1398  0 AlignFrame af = new FileLoader(false).LoadFileWaitTillLoaded(
1399    "examples/testdata/projects/manyViews.jvp",
1400    DataSourceType.FILE);
1401  0 assertNotNull(af);
1402   
1403  0 AlignmentI ds = null;
1404  0 for (AlignFrame alignFrame : Desktop.getDesktopAlignFrames())
1405    {
1406  0 if (ds == null)
1407    {
1408  0 ds = verifyDs(alignFrame);
1409    }
1410    else
1411    {
1412    // check that this frame's dataset matches the last
1413  0 assertTrue(ds == verifyDs(alignFrame));
1414    }
1415    }
1416    }
1417   
 
1418  0 toggle private AlignmentI verifyDs(AlignFrame af)
1419    {
1420  0 AlignmentI ds = null;
1421  0 for (AlignmentViewPanel ap : af.getAlignPanels())
1422    {
1423  0 if (ds == null)
1424    {
1425  0 ds = ap.getAlignment().getDataset();
1426    }
1427    else
1428    {
1429  0 assertTrue(ap.getAlignment().getDataset() == ds,
1430    "Dataset was not the same for imported 2.10.5 project with several alignment views");
1431    }
1432    }
1433  0 return ds;
1434    }
1435   
 
1436  0 toggle @Test(groups = "Functional")
1437    public void testPcaViewAssociation() throws IOException
1438    {
1439  0 Desktop.getInstance().closeAll_actionPerformed(null);
1440  0 final String PCAVIEWNAME = "With PCA";
1441    // create a new tempfile
1442  0 File tempfile = File.createTempFile("jvPCAviewAssoc", "jvp");
1443   
1444    {
1445  0 String exampleFile = "examples/uniref50.fa";
1446  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
1447    DataSourceType.FILE);
1448  0 assertNotNull(af, "Didn't read in the example file correctly.");
1449  0 AlignmentPanel origView = (AlignmentPanel) af.getAlignPanels().get(0);
1450  0 AlignmentPanel newview = af.newView(PCAVIEWNAME, true);
1451    // create another for good measure
1452  0 af.newView("Not the PCA View", true);
1453  0 PCAPanel pcaPanel = new PCAPanel(origView, "BLOSUM62",
1454    new SimilarityParams(true, true, true, false));
1455    // we're in the test exec thread, so we can just run synchronously here
1456  0 pcaPanel.run();
1457   
1458    // now switch the linked view
1459  0 pcaPanel.selectAssociatedView(newview);
1460   
1461  0 assertTrue(pcaPanel.getAlignViewport() == newview.getAlignViewport(),
1462    "PCA should be associated with 'With PCA' view: test is broken");
1463   
1464    // now save and reload project
1465  0 Jalview2XML jv2xml = new jalview.project.Jalview2XML(false);
1466  0 tempfile.delete();
1467  0 jv2xml.saveState(tempfile);
1468  0 assertTrue(jv2xml.errorMessage == null,
1469    "Failed to save dummy project with PCA: test broken");
1470    }
1471   
1472    // load again.
1473  0 Desktop.getInstance().closeAll_actionPerformed(null);
1474  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1475    tempfile.getCanonicalPath(), DataSourceType.FILE);
1476  0 JInternalFrame[] frames = Desktop.getInstance().getAllFrames();
1477    // PCA and the tabbed alignment view should be the only two windows on the
1478    // desktop
1479  0 assertEquals(frames.length, 2,
1480    "PCA and the tabbed alignment view should be the only two windows on the desktop");
1481  0 PCAPanel pcaPanel = (PCAPanel) frames[frames[0] == af ? 1 : 0];
1482   
1483  0 AlignmentViewPanel restoredNewView = null;
1484  0 for (AlignmentViewPanel alignpanel : Desktop.getAlignmentPanels(null))
1485    {
1486  0 if (alignpanel.getAlignViewport() == pcaPanel.getAlignViewport())
1487    {
1488  0 restoredNewView = alignpanel;
1489    }
1490    }
1491  0 assertEquals(restoredNewView.getViewName(), PCAVIEWNAME);
1492  0 assertTrue(
1493    restoredNewView.getAlignViewport() == pcaPanel
1494    .getAlignViewport(),
1495    "Didn't restore correct view association for the PCA view");
1496    }
1497   
1498   
 
1499  0 toggle @Test(groups = "Functional")
1500    public void testSaveAndLoadAnnotationBasedPCA() throws IOException
1501    {
1502  0 Desktop.getInstance().closeAll_actionPerformed(null);
1503  0 final String PCAVIEWNAME = "With PCA";
1504    // create a new tempfile
1505  0 File tempfile = File.createTempFile("jvPCAAnnot", "jvp");
1506  0 PCAPanel pcaPanelOrig, pcaPanelReload;
1507  0 int savedTop = -1;
1508  0 String savedScoreModelName;
1509   
1510  0 int savedSeqPointsSize = -1;
1511   
1512    {
1513  0 String exampleFile = "examples/testdata/uniref50_Multiple_SS_Providers_Data.jvp";
1514   
1515  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
1516    DataSourceType.FILE);
1517  0 assertNotNull(af, "Didn't read in the example file correctly.");
1518  0 AlignmentPanel origView = (AlignmentPanel) af.getAlignPanels().get(0);
1519  0 AlignmentPanel newview = af.newView(PCAVIEWNAME, true);
1520  0 af.newView("Not the PCA View", true);
1521  0 pcaPanelOrig = new PCAPanel(origView, "Secondary Structure Similarity",
1522    new SimilarityParams(true, true, true, false));
1523  0 SimilarityParams params = new SimilarityParams(true, true, true, false);
1524   
1525  0 params.setSecondaryStructureSource("All");
1526  0 pcaPanelOrig.run();
1527   
1528  0 pcaPanelOrig.selectAssociatedView(newview);
1529   
1530  0 assertTrue(pcaPanelOrig.getAlignViewport() == newview.getAlignViewport(),
1531    "PCA should be associated with 'With PCA' view: test is broken");
1532   
1533    // now save and reload project
1534  0 Jalview2XML jv2xml = new jalview.project.Jalview2XML(false);
1535  0 tempfile.delete();
1536  0 jv2xml.saveState(tempfile);
1537  0 assertTrue(jv2xml.errorMessage == null,
1538    "Failed to save dummy project with PCA: test broken");
1539  0 savedTop = pcaPanelOrig.getPcaModel().getTop();
1540  0 savedScoreModelName = pcaPanelOrig.getPcaModel().getScoreModelName();
1541  0 savedSeqPointsSize = pcaPanelOrig.getPcaModel().getSequencePoints().size();
1542    }
1543   
1544    // load again.
1545  0 Desktop.getInstance().closeAll_actionPerformed(null);
1546  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1547    tempfile.getCanonicalPath(), DataSourceType.FILE);
1548   
1549    // Retrieve the restored pca panel
1550  0 pcaPanelReload = null;
1551  0 for (JInternalFrame frame : Desktop.getInstance().getAllFrames())
1552    {
1553  0 if (frame instanceof PCAPanel)
1554    {
1555  0 pcaPanelReload = (PCAPanel) frame;
1556  0 break;
1557    }
1558    }
1559  0 int reloadedTop = pcaPanelReload.getPcaModel().getTop();
1560  0 int reloadedSeqPointsSize = pcaPanelReload.getPcaModel().getSequencePoints().size();
1561   
1562  0 String reloadedScoreModelName = pcaPanelReload.getPcaModel().getScoreModelName();
1563   
1564  0 assertEquals(savedTop, reloadedTop);
1565  0 assertEquals(savedScoreModelName, reloadedScoreModelName);
1566  0 assertEquals(savedSeqPointsSize, reloadedSeqPointsSize);
1567   
1568    }
1569   
1570    /**
1571    * Test the save and load tree functionalities for annotation based trees
1572    *
1573    * @throws IOException
1574    */
 
1575  0 toggle @Test(groups = "Functional")
1576    public void testSaveAndLoadAnnotationBasedTree() throws IOException
1577    {
1578    // Clear existing instances
1579  0 Desktop.getInstance().closeAll_actionPerformed(null);
1580   
1581    // Create a temporary file for saving and restoring the project
1582  0 File tempfile = File.createTempFile("jvSSTree", "jvp");
1583   
1584    // Load the file
1585  0 String exampleFile = "examples/testdata/uniref50_Multiple_SS_Providers_Data.jvp";
1586  0 AlignFrame afOrig = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
1587    DataSourceType.FILE);
1588  0 assertNotNull(afOrig, "Failed to read the input alignment file.");
1589   
1590  0 AlignmentPanel origView = (AlignmentPanel) afOrig.getAlignPanels()
1591    .get(0);
1592  0 AlignmentI alignment = afOrig.getViewport().getAlignment();
1593   
1594    // Create a sequence group and add sequences
1595  0 SequenceGroup sequenceGroup = new SequenceGroup();
1596  0 sequenceGroup.setStartRes(0);
1597  0 sequenceGroup.setEndRes(100);
1598  0 for (int i = 0; i < alignment.getHeight(); i++)
1599    {
1600  0 sequenceGroup.addSequence(alignment.getSequenceAt(i), false);
1601    }
1602  0 afOrig.getViewport().setSelectionGroup(sequenceGroup);
1603   
1604    // Generate the tree
1605  0 SimilarityParams params = new SimilarityParams(true, true, true, false);
1606  0 params.setSecondaryStructureSource("PDB");
1607   
1608  0 TreePanel treePanelOrig = new TreePanel(origView,
1609    TreeBuilder.NEIGHBOUR_JOINING, "Secondary Structure Similarity",
1610    params);
1611  0 treePanelOrig.setAnnotationBased(true);
1612  0 treePanelOrig.setShowAnnotationAs("As Coloured Lines"); // annotation view
1613    // initiate mouse event to split the tree and create tree groups
1614  0 MouseEvent e = new MouseEvent(treePanelOrig, MouseEvent.MOUSE_PRESSED,
1615    0L, 0, 8, 250, 1, false);
1616  0 treePanelOrig.getTreeCanvas().mousePressed(e);
1617  0 treePanelOrig.revalidate();
1618  0 Desktop.getInstance().addInternalFrame(treePanelOrig, "", 600, 500);
1619   
1620    // Save the project
1621  0 Jalview2XML jv2xml = new Jalview2XML(false);
1622  0 tempfile.delete();
1623  0 jv2xml.saveState(tempfile);
1624  0 assertTrue(jv2xml.errorMessage == null, "Failed to save project.");
1625   
1626    // Save original tree to a temporary variable
1627  0 TreePanel treePanelOrigCopy = treePanelOrig;
1628  0 TreeModel treeOrig = treePanelOrig.getTree();
1629   
1630    // Clear all instances and reload the saved project
1631  0 assertNotNull(treeOrig, "Original tree is null before saving!");
1632  0 Desktop.getInstance().closeAll_actionPerformed(null);
1633  0 AlignFrame afRestored = new FileLoader().LoadFileWaitTillLoaded(
1634    tempfile.getCanonicalPath(), DataSourceType.FILE);
1635   
1636    // Retrieve the restored tree panel
1637  0 TreePanel treePanelRestored = null;
1638  0 for (JInternalFrame frame : Desktop.getInstance().getAllFrames())
1639    {
1640  0 if (frame instanceof TreePanel)
1641    {
1642  0 treePanelRestored = (TreePanel) frame;
1643  0 break;
1644    }
1645    }
1646  0 assertNotNull(treePanelRestored, "Restored TreePanel not found!");
1647   
1648  0 TreeModel treeRestored = treePanelRestored.getTree();
1649  0 assertNotNull(treeRestored, "Restored tree is null!");
1650   
1651    // Compare the tree structures
1652  0 assertEquals(treeOrig.getTopNode().count,
1653    treeRestored.getTopNode().count,
1654    "Mismatch in tree node count!");
1655   
1656    // Compare the tree structures
1657  0 assertEquals(treeOrig.getTopNode().count,
1658    treeRestored.getTopNode().count,
1659    "Mismatch in tree node count!");
1660   
1661    // Compare the annotation view
1662  0 assertEquals(treePanelOrigCopy.getShowAnnotationAs(),
1663    treePanelRestored.getShowAnnotationAs());
1664   
1665    // Compare the colour map key-value pairs
1666  0 assertEquals(treePanelOrigCopy.getSecondaryStructureProviderColorMap(),
1667    treePanelRestored.getSecondaryStructureProviderColorMap(),
1668    "Maps should match");
1669   
1670    // Compare leaf nodes and their annotations
1671  0 validateLeafNodes(treeOrig, treeRestored);
1672    }
1673   
1674    /**
1675    * Validates the leaf nodes of the original and restored trees. Ensures the
1676    * number of leaf nodes is the same and annotation IDs match.
1677    */
 
1678  0 toggle private void validateLeafNodes(TreeModel treeOrig, TreeModel treeRestored)
1679    {
1680  0 Vector<BinaryNode> leafNodesOrig = treeOrig
1681    .findLeaves(treeOrig.getTopNode());
1682  0 Vector<BinaryNode> leafNodesRestored = treeRestored
1683    .findLeaves(treeRestored.getTopNode());
1684   
1685  0 assertEquals(leafNodesOrig.size(), leafNodesRestored.size(),
1686    "Mismatch in the number of leaf nodes!");
1687   
1688  0 for (int i = 0; i < leafNodesOrig.size(); i++)
1689    {
1690  0 BinaryNode origLeaf = leafNodesOrig.get(i);
1691  0 BinaryNode restoredLeaf = leafNodesRestored.get(i);
1692   
1693    // Compare labels
1694  0 assertEquals(origLeaf.getLabel(), restoredLeaf.getLabel(),
1695    "Mismatch in label for leaf node: " + origLeaf.getLabel());
1696    // Compare annotation details
1697  0 assertEquals(origLeaf.getAnnotationDetails(),
1698    restoredLeaf.getAnnotationDetails(),
1699    "Mismatch in annotation details for leaf node: "
1700    + origLeaf.getLabel());
1701   
1702    // Compare annotation ids if exists
1703  0 if (origLeaf.getAlignmentAnnotation() != null)
1704    {
1705  0 assertNotNull(restoredLeaf.getAlignmentAnnotation(),
1706    "Restored leaf node has no annotation at index " + i);
1707  0 assertEquals(origLeaf.getAlignmentAnnotation().annotationId,
1708    restoredLeaf.getAlignmentAnnotation().annotationId,
1709    "Mismatch in annotation ID for leaf node: "
1710    + origLeaf.getLabel());
1711  0 assertEquals(
1712    origLeaf.getAlignmentAnnotation()
1713    .getAnnotationGroupColour(),
1714    restoredLeaf.getAlignmentAnnotation()
1715    .getAnnotationGroupColour(),
1716    "Mismatch in annotation group colour for leaf node: "
1717    + origLeaf.getLabel());
1718    }
1719    }
1720    }
1721   
1722    /**
1723    * Test the save and load annotation properties
1724    *
1725    * @throws IOException
1726    */
 
1727  0 toggle @Test(groups = "Functional")
1728    public void testSaveAndLoadAnnotationsProperties() throws IOException
1729    {
1730    // Clear existing instances
1731  0 Desktop.getInstance().closeAll_actionPerformed(null);
1732   
1733    // Create a temporary file for saving and restoring the project
1734  0 File tempfile = File.createTempFile("jvSSTree", "jvp");
1735   
1736    // Load the file
1737  0 String exampleFile = "examples/uniref50_Multiple_SS_Providers_Data.jvp";
1738  0 AlignFrame afOrig = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
1739    DataSourceType.FILE);
1740  0 assertNotNull(afOrig, "Failed to read the input alignment file.");
1741  0 AlignmentI alignment = afOrig.getViewport().getAlignment();
1742  0 AlignmentAnnotation[] annots = alignment.getAlignmentAnnotation();
1743  0 for (AlignmentAnnotation aa : annots)
1744    {
1745  0 if (aa.label.equals("Secondary Structure"))
1746    {
1747  0 aa.setProperty("SS_PROVIDER", "PDB");
1748    }
1749    }
1750   
1751    // Save the project
1752  0 Jalview2XML jv2xml = new Jalview2XML(false);
1753  0 tempfile.delete();
1754  0 jv2xml.saveState(tempfile);
1755  0 assertTrue(jv2xml.errorMessage == null, "Failed to save project.");
1756   
1757    // Clear all instances and reload the saved project
1758  0 Desktop.getInstance().closeAll_actionPerformed(null);
1759  0 AlignFrame afRestored = new FileLoader().LoadFileWaitTillLoaded(
1760    tempfile.getCanonicalPath(), DataSourceType.FILE);
1761   
1762  0 AlignmentI alignmentRestored = afRestored.getViewport().getAlignment();
1763  0 AlignmentAnnotation[] annotsRestored = alignmentRestored
1764    .getAlignmentAnnotation();
1765  0 for (AlignmentAnnotation aa : annotsRestored)
1766    {
1767  0 if (aa.label.equals("Secondary Structure"))
1768    {
1769  0 assertEquals("PDB", aa.getProperty("SS_PROVIDER"));
1770    }
1771    }
1772   
1773    }
1774   
1775    /**
1776    * Test save and reload of DBRefEntry including GeneLocus in project
1777    *
1778    * @throws Exception
1779    */
 
1780  0 toggle @Test(groups = { "Functional" })
1781    public void testStoreAndRecoverGeneLocus() throws Exception
1782    {
1783  0 Desktop.getInstance().closeAll_actionPerformed(null);
1784  0 String seqData = ">P30419\nACDE\n>X1235\nGCCTGTGACGAA";
1785  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(seqData,
1786    DataSourceType.PASTE);
1787  0 assertNotNull(af, "Didn't read in the example file correctly.");
1788   
1789  0 AlignmentViewPanel ap = Desktop.getAlignmentPanels(null)[0];
1790  0 SequenceI pep = ap.getAlignment().getSequenceAt(0);
1791  0 SequenceI cds = ap.getAlignment().getSequenceAt(1);
1792   
1793    /*
1794    * give 'protein' a dbref to self, a dbref with map to CDS,
1795    * and a dbref with map to gene 'locus'
1796    */
1797  0 DBRefEntry dbref1 = new DBRefEntry("Uniprot", "1", "P30419", null);
1798  0 pep.addDBRef(dbref1);
1799  0 Mapping cdsmap = new Mapping(cds,
1800    new MapList(new int[]
1801    { 1, 4 }, new int[] { 1, 12 }, 1, 3));
1802  0 DBRefEntry dbref2 = new DBRefEntry("EMBLCDS", "2", "X1235", cdsmap);
1803  0 pep.addDBRef(dbref2);
1804  0 Mapping locusmap = new Mapping(null,
1805    new MapList(new int[]
1806    { 1, 4 }, new int[] { 2674123, 2674135 }, 1, 3));
1807  0 DBRefEntry dbref3 = new GeneLocus("human", "GRCh38", "5", locusmap);
1808  0 pep.addDBRef(dbref3);
1809   
1810  0 File tfile = File.createTempFile("testStoreAndRecoverGeneLocus",
1811    ".jvp");
1812  0 try
1813    {
1814  0 new Jalview2XML(false).saveState(tfile);
1815    } catch (Throwable e)
1816    {
1817  0 Assert.fail("Didn't save the state", e);
1818    }
1819  0 Desktop.getInstance().closeAll_actionPerformed(null);
1820   
1821  0 new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
1822    DataSourceType.FILE);
1823  0 AlignmentViewPanel rap = Desktop.getAlignmentPanels(null)[0];
1824  0 SequenceI rpep = rap.getAlignment().getSequenceAt(0);
1825  0 DBModList<DBRefEntry> dbrefs = rpep.getDBRefs();
1826  0 assertEquals(rpep.getName(), "P30419");
1827  0 assertEquals(dbrefs.size(), 3);
1828  0 DBRefEntry dbRef = dbrefs.get(0);
1829  0 assertFalse(dbRef instanceof GeneLocus);
1830  0 assertNull(dbRef.getMap());
1831  0 assertEquals(dbRef, dbref1);
1832   
1833    /*
1834    * restored dbrefs with mapping have a different 'map to'
1835    * sequence but otherwise match the original dbrefs
1836    */
1837  0 dbRef = dbrefs.get(1);
1838  0 assertFalse(dbRef instanceof GeneLocus);
1839  0 assertTrue(dbRef.equalRef(dbref2));
1840  0 assertNotNull(dbRef.getMap());
1841  0 SequenceI rcds = rap.getAlignment().getSequenceAt(1);
1842  0 assertSame(dbRef.getMap().getTo(), rcds);
1843    // compare MapList but not map.to
1844  0 assertEquals(dbRef.getMap().getMap(), dbref2.getMap().getMap());
1845   
1846    /*
1847    * GeneLocus map.to is null so can compare Mapping objects
1848    */
1849  0 dbRef = dbrefs.get(2);
1850  0 assertTrue(dbRef instanceof GeneLocus);
1851  0 assertEquals(dbRef, dbref3);
1852    }
1853   
1854    /**
1855    * test store and recovery of Overview windows
1856    *
1857    * @throws Exception
1858    */
 
1859  0 toggle @Test(groups = { "Functional" }, enabled = true)
1860    public void testStoreAndRecoverOverview() throws Exception
1861    {
1862  0 Desktop.getInstance().closeAll_actionPerformed(null);
1863   
1864  0 Cache.setProperty("SHOW_OVERVIEW", "false");
1865  0 Cache.setProperty(Preferences.USE_LEGACY_GAP, "false");
1866  0 Cache.setColourPropertyNoSave(Preferences.GAP_COLOUR, Color.green);
1867  0 Cache.setColourPropertyNoSave(Preferences.HIDDEN_COLOUR, Color.yellow);
1868  0 Cache.setProperty(Preferences.SHOW_OV_HIDDEN_AT_START, "true");
1869   
1870  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1871    "examples/uniref50.fa", DataSourceType.FILE);
1872   
1873    /*
1874    * open and resize / reposition overview
1875    */
1876  0 af.overviewMenuItem_actionPerformed(null);
1877  0 OverviewPanel ov1 = af.alignPanel.getOverviewPanel();
1878  0 assertNotNull(ov1);
1879  0 ov1.setFrameBounds(20, 30, 200, 400);
1880  0 assertEquals(ov1.getTitle(), "Overview examples/uniref50.fa");
1881  0 assertTrue(ov1.isShowHiddenRegions());
1882   
1883    /*
1884    * open a New View and its Overview and reposition it
1885    */
1886  0 af.newView_actionPerformed(null);
1887  0 af.overviewMenuItem_actionPerformed(null);
1888  0 OverviewPanel ov2 = af.alignPanel.getOverviewPanel();
1889  0 assertNotNull(ov2);
1890  0 assertNotSame(ov1, ov2);
1891  0 ov2.setFrameBounds(25, 35, 205, 405);
1892  0 assertEquals(ov1.getTitle(), "Overview examples/uniref50.fa Original");
1893  0 assertEquals(ov2.getTitle(), "Overview examples/uniref50.fa View 1");
1894   
1895  0 File tfile = File.createTempFile("testStoreAndRecoverOverview", ".jvp");
1896  0 new Jalview2XML(false).saveState(tfile);
1897  0 Desktop.getInstance().closeAll_actionPerformed(null);
1898   
1899    /*
1900    * change preferences (should _not_ affect reloaded Overviews)
1901    */
1902  0 Cache.setProperty("SHOW_OVERVIEW", "true");
1903  0 Cache.setProperty(Preferences.USE_LEGACY_GAP, "true");
1904  0 Cache.setColourPropertyNoSave(Preferences.GAP_COLOUR, Color.blue);
1905  0 Cache.setColourPropertyNoSave(Preferences.HIDDEN_COLOUR, Color.orange);
1906  0 Cache.setProperty(Preferences.SHOW_OV_HIDDEN_AT_START, "false");
1907   
1908  0 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
1909    DataSourceType.FILE);
1910   
1911    /*
1912    * workaround: explicitly select View 1 (not in focus after restore)
1913    */
1914  0 af.tabSelectionChanged(1);
1915   
1916    /*
1917    * verify restored overview for View 1
1918    */
1919  0 ov2 = af.alignPanel.getOverviewPanel();
1920  0 assertEquals(ov2.getCanvas().getGapColour(), Color.green);
1921    // 'non-legacy' colouring uses white for non-gapped residues
1922  0 assertEquals(ov2.getCanvas().getResidueColour(), Color.white);
1923  0 assertEquals(ov2.getCanvas().getHiddenColour(), Color.yellow);
1924  0 assertEquals(ov2.getTitle(), "Overview examples/uniref50.fa View 1");
1925  0 assertEquals(ov2.getFrameBounds(), new Rectangle(25, 35, 205, 405));
1926  0 assertTrue(ov2.isShowHiddenRegions());
1927   
1928    /*
1929    * verify restored overview for Original view
1930    */
1931  0 af.tabSelectionChanged(0);
1932  0 ov1 = af.alignPanel.getOverviewPanel();
1933  0 assertEquals(ov1.getCanvas().getGapColour(), Color.green);
1934    // 'non-legacy' colouring uses white for non-gapped residues
1935  0 assertEquals(ov1.getCanvas().getResidueColour(), Color.white);
1936  0 assertEquals(ov1.getCanvas().getHiddenColour(), Color.yellow);
1937  0 assertEquals(ov1.getTitle(), "Overview examples/uniref50.fa Original");
1938   
1939  0 double scaling = jalview.gui.JvSwingUtilsTest.getScaling(ov1);
1940    // int width = scaling == 1.0 ? 225 : 200;
1941    // int width = scaling == 1.0 ? 225 : 200;
1942  0 Rectangle ov1Rectangle = ov1.getFrameBounds();
1943  0 assertEquals(ov1Rectangle,
1944    new Rectangle(20, 30, ov1Rectangle.width, 400));
1945  0 int width = ov1Rectangle.width;
1946  0 assertTrue(width >= 200 && width <= 225,
1947    "Rectangle width was not in the range expected (200<=width<=225; width="
1948    + width + ")");
1949  0 assertTrue(ov1.isShowHiddenRegions());
1950    }
1951   
1952    /**
1953    * Test that a view with no Overview is restored with no Overview, even if
1954    * 'Open Overview' is selected in Preferences
1955    *
1956    * @throws Exception
1957    */
 
1958  0 toggle @Test(groups = { "Functional" }, enabled = true)
1959    public void testStoreAndRecoverNoOverview() throws Exception
1960    {
1961  0 Cache.setProperty("SHOW_OVERVIEW", "false");
1962  0 Desktop.getInstance().closeAll_actionPerformed(null);
1963  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1964    ">seq1\nMATRSQFLVNF\n", DataSourceType.PASTE);
1965   
1966  0 File tfile = File.createTempFile("testStoreAndRecoverOverview", ".jvp");
1967  0 new Jalview2XML(false).saveState(tfile);
1968  0 Desktop.getInstance().closeAll_actionPerformed(null);
1969   
1970  0 Cache.setProperty("SHOW_OVERVIEW", "true");
1971  0 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
1972    DataSourceType.FILE);
1973   
1974  0 assertNull(af.alignPanel.getOverviewPanel());
1975    }
1976   
1977    /**
1978    * Test that a view from an older version of Jalview is restored with Overview
1979    * automatically shown when the preference is set
1980    *
1981    * @throws Exception
1982    */
 
1983  0 toggle @Test(groups = { "Functional" }, enabled = true)
1984    public void testAutoShowOverviewForLegacyProjects() throws Exception
1985    {
1986  0 Desktop.getInstance().closeAll_actionPerformed(null);
1987  0 Cache.setProperty("SHOW_OVERVIEW", "true");
1988  0 assertTrue("true".equals(Cache.getProperty("SHOW_OVERVIEW")));
1989  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
1990    "examples/exampleFile.jvp", DataSourceType.FILE);
1991   
1992  0 Cache.setProperty("SHOW_OVERVIEW", "false");
1993  0 assertNotNull(af.alignPanel.getOverviewPanel());
1994    }
1995   
1996    /**
1997    * Test that loading example.jvp, doing some stuff, then hitting reload
1998    * doesn't leave the modified window still open
1999    *
2000    * See JAL-4127 - interactively performing the same actions and reloading
2001    * works fine, but programmatically they do not
2002    *
2003    * @throws Exception
2004    */
 
2005  0 toggle @Test(groups = { "Functional" }, enabled = false)
2006    public void testReloadActuallyReloads() throws Exception
2007    {
2008  0 Desktop.getInstance().closeAll_actionPerformed(null);
2009  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
2010    "examples/exampleFile.jvp", DataSourceType.FILE);
2011  0 af.getViewport().getColumnSelection().addElement(3);
2012  0 af.hideSelColumns_actionPerformed(null);
2013  0 af.newView("new", true);
2014  0 af.reload_actionPerformed(null);
2015  0 Thread.sleep(30);
2016    // af exists still but isn't shown
2017  0 assertTrue(af.isClosed());
2018    }
2019   
 
2020  0 toggle @Test(groups = { "Functional" })
2021    public void testMatrixToFloatsAndBack()
2022    {
2023  0 int imax = 2000;
2024  0 int i = imax;
2025  0 SequenceI sq = new Sequence("dummy", "SEQ");
2026  0 while (sq.getLength() < i)
2027    {
2028  0 sq.setSequence(sq.getSequenceAsString() + 'Q');
2029    }
2030  0 float[][] paevals = new float[i][i];
2031  0 for (i = imax - 1; i >= 0; i--)
2032    {
2033  0 for (int j = 0; j <= i; j++)
2034    {
2035  0 paevals[i][j] = ((i - j < 2)
2036    || ((i > 1 && i < 5) && (j > 1 && i < 5))) ? 1 : 0f;
2037  0 paevals[j][i] = -paevals[i][j];
2038    }
2039    }
2040  0 PAEContactMatrix dummyMat = new PAEContactMatrix(sq, paevals);
2041  0 String content = ContactMatrix.contactToFloatString(dummyMat);
2042  0 Assert.assertTrue(content.contains("\t1.")); // at least one element must be
2043    // 1
2044  0 float[][] vals = ContactMatrix.fromFloatStringToContacts(content,
2045    sq.getLength(), sq.getLength());
2046  0 assertEquals(vals[3][4], paevals[3][4]);
2047  0 assertEquals(vals[4][3], paevals[4][3]);
2048   
2049    // test recovery
2050  0 for (i = 0; i < imax; i++)
2051    {
2052  0 for (int j = 0; j < imax; j++)
2053    {
2054  0 assertEquals(vals[i][j], paevals[i][j]);
2055    }
2056    }
2057    }
2058   
 
2059  0 toggle @Test(groups = { "Functional" })
2060    public void testPAEsaveRestore() throws Exception
2061    {
2062  0 Desktop.getInstance().closeAll_actionPerformed(null);
2063  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
2064    ">seq1\nMATRSQFLVNF\n", DataSourceType.PASTE);
2065  0 AlignmentI al = af.getViewport().getAlignment();
2066    // PAE matrices are added as reference annotation to the dataset sequence
2067    // at least for now.
2068  0 SequenceI sq = al.getSequenceAt(0).getDatasetSequence();
2069  0 int i = sq.getLength();
2070  0 float[][] paevals = new float[i][i];
2071  0 for (i = i - 1; i >= 0; i--)
2072    {
2073  0 for (int j = 0; j <= i; j++)
2074    {
2075  0 paevals[i][j] = ((i - j < 2)
2076    || ((i > 1 && i < 5) && (j > 1 && i < 5))) ? 1 : 0f;
2077  0 paevals[j][i] = -paevals[i][j];
2078    }
2079    }
2080  0 PAEContactMatrix dummyMat = new PAEContactMatrix(sq, paevals);
2081  0 String content = ContactMatrix.contactToFloatString(dummyMat);
2082  0 Assert.assertTrue(content.contains("\t1.")); // at least one element must be
2083    // 1
2084  0 float[][] vals = ContactMatrix.fromFloatStringToContacts(content,
2085    sq.getLength(), sq.getLength());
2086  0 assertEquals(vals[3][4], paevals[3][4]);
2087  0 assertEquals(vals[4][3], paevals[4][3]);
2088  0 dummyMat.setGroupSet(GroupSet.makeGroups(dummyMat, false, 0.5f, false));
2089  0 Assert.assertNotSame(dummyMat.getNewick(), "");
2090  0 AlignmentAnnotation paeCm = sq.addContactList(dummyMat);
2091  0 al.addAnnotation(paeCm);
2092    // verify store/restore of group bitsets
2093  0 for (BitSet gp : dummyMat.getGroups())
2094    {
2095  0 StringBuilder sb = new StringBuilder();
2096  0 for (long val : gp.toLongArray())
2097    {
2098  0 if (sb.length() > 0)
2099    {
2100  0 sb.append(",");
2101    }
2102  0 sb.append(val);
2103    }
2104  0 String[] longvals = sb.toString().split(",");
2105  0 long[] newlongvals = new long[longvals.length];
2106  0 for (int lv = 0; lv < longvals.length; lv++)
2107    {
2108  0 try
2109    {
2110  0 newlongvals[lv] = Long.valueOf(longvals[lv]);
2111    } catch (Exception x)
2112    {
2113  0 Assert.fail("failed to deserialise bitset element ");
2114    }
2115    }
2116  0 BitSet newGp = BitSet.valueOf(newlongvals);
2117  0 assertTrue(gp.equals(newGp));
2118    }
2119  0 File tfile = File.createTempFile("testStoreAndRecoverPAEmatrix",
2120    ".jvp");
2121  0 new Jalview2XML(false).saveState(tfile);
2122  0 Desktop.getInstance().closeAll_actionPerformed(null);
2123   
2124  0 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
2125    DataSourceType.FILE);
2126  0 AlignmentI newAl = af.getViewport().getAlignment();
2127  0 SequenceI newSeq = newAl.getSequenceAt(0).getDatasetSequence();
2128    // check annotation of the expected type exists
2129  0 Assert.assertEquals(newSeq.getAnnotation().length, 1);
2130  0 Assert.assertEquals(newSeq.getAnnotation()[0].graph, paeCm.graph);
2131   
2132    // check a contact matrix was recovered
2133  0 Assert.assertEquals(newSeq.getContactMaps().size(), 1);
2134    // and can be found for the annotation on the sequence
2135  0 ContactMatrixI restoredMat = newSeq
2136    .getContactMatrixFor(newSeq.getAnnotation()[0]);
2137  0 Assert.assertNotNull(restoredMat);
2138  0 MapList oldMap = dummyMat.getMapFor(sq);
2139  0 MapList newMap = ((MappableContactMatrixI) restoredMat)
2140    .getMapFor(newSeq);
2141  0 Assert.assertTrue(oldMap.equals(newMap));
2142  0 for (i = sq.getLength() - 1; i >= 0; i--)
2143    {
2144  0 ContactListI oldCM = dummyMat.getContactList(i),
2145    newCM = restoredMat.getContactList(i);
2146  0 for (int j = oldCM.getContactHeight(); j >= 0; j--)
2147    {
2148  0 double old_j = oldCM.getContactAt(j);
2149  0 double new_j = newCM.getContactAt(j);
2150  0 Assert.assertEquals(old_j, new_j);
2151    }
2152    }
2153  0 Assert.assertEquals(restoredMat.hasGroups(), dummyMat.hasGroups());
2154  0 Assert.assertEquals(restoredMat.getGroups(), dummyMat.getGroups());
2155  0 Assert.assertEquals(restoredMat.hasTree(), dummyMat.hasTree());
2156  0 Assert.assertEquals(restoredMat.getNewick(), dummyMat.getNewick());
2157   
2158    // verify no duplicate PAE matrix data when new view created and saved
2159   
2160    // add reference annotations to view first, then copy
2161  0 AlignmentUtils.addReferenceAnnotationTo(newAl, newAl.getSequenceAt(0),
2162    newSeq.getAnnotation()[0], null);
2163   
2164  0 AlignmentViewPanel newview = af.newView("copy of PAE", true);
2165   
2166    // redundant asserts here check all is good with the new view firest...
2167  0 AlignmentI newviewAl = newview.getAlignment();
2168  0 SequenceI newviewSeq = newviewAl.getSequenceAt(0);
2169    // check annotation of the expected type exists
2170  0 Assert.assertEquals(newviewSeq.getAnnotation().length, 1);
2171  0 Assert.assertEquals(newviewSeq.getAnnotation()[0].graph, paeCm.graph);
2172    // check we have just one contact matrix mapping
2173  0 Assert.assertEquals(newviewSeq.getContactMaps().size(), 1);
2174   
2175    // and can be found for the annotation on the sequence
2176  0 ContactMatrixI newviewMat = newviewSeq
2177    .getContactMatrixFor(newviewSeq.getAnnotation()[0]);
2178  0 Assert.assertNotNull(newviewMat);
2179   
2180  0 Assert.assertTrue(newviewMat == restoredMat);
2181   
2182    // save the two views and restore. Now look at visible annotation to check
2183    // all views have shared refs.
2184   
2185  0 tfile = File.createTempFile("testStoreAndRecoverPAEmatrixTwoViews",
2186    ".jvp");
2187  0 new Jalview2XML(false).saveState(tfile);
2188  0 Desktop.getInstance().closeAll_actionPerformed(null);
2189   
2190  0 af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
2191    DataSourceType.FILE);
2192  0 newAl = af.getAlignPanels().get(0).getAlignment();
2193  0 AlignmentAnnotation view1aa = newAl.getSequenceAt(0).getAnnotation()[0];
2194   
2195  0 newviewAl = af.getAlignPanels().get(1).getAlignment();
2196  0 AlignmentAnnotation view2aa = newviewAl.getSequenceAt(0)
2197    .getAnnotation()[0];
2198   
2199    // annotations are shared across alignment views - so should still have an
2200    // identical pair of annotations.
2201  0 Assert.assertTrue(view1aa == view2aa);
2202    // identical annotations means identical contact matrix mappings
2203  0 Assert.assertEquals(
2204    newAl.getDataset().getSequenceAt(0).getContactMaps().size(), 1);
2205   
2206    // TODO Verify when distinct mappable PAEs are created, only one PAE dataset
2207    // is actually held.
2208    // Assert.assertTrue(view1aa!=view2aa);
2209    // restoredMat = newAl.getContactMatrixFor(view1aa);
2210    // newviewMat = newviewAl.getContactMatrixFor(view2aa);
2211    // Assert.assertTrue(restoredMat!=newviewMat);
2212   
2213    }
2214   
 
2215  0 toggle @Test(groups = "Functional")
2216    public void testStoreAndRestoreIDwidthAndAnnotationHeight()
2217    throws IOException
2218    {
2219  0 Desktop.getInstance().closeAll_actionPerformed(null);
2220  0 final String SECONDVIEW = "With Diffferent IDwidth";
2221    // create a new tempfile
2222  0 File tempfile = File.createTempFile("jvIdWidthStoreRestore", "jvp");
2223   
2224  0 AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
2225    "examples/exampleFile.jvp", DataSourceType.FILE);
2226  0 assertNotNull(af, "Didn't read in the example file correctly.");
2227    // FIXME JAL-4281 test made platform dependent to pass, but probably
2228    // shouldn't be platform dependent
2229  0 int idWidth = af.alignPanel.getAlignViewport().getIdWidth();
2230  0 double scaling = jalview.gui.JvSwingUtilsTest.getScaling(af.alignPanel);
2231    // int expectedWidth = Platform.isMac() ? 144 : Platform.isLinux() ? scaling
2232    // == 1.0 ? 131 : 128 : 138;
2233  0 int minExpectedWidth = 128;
2234  0 int maxExpectedWidth = 144;
2235  0 assertTrue(minExpectedWidth <= idWidth && maxExpectedWidth >= idWidth,
2236    "Legacy project import should have fixed ID width. Not within the expected range ("
2237    + minExpectedWidth + "-" + maxExpectedWidth + ")");
2238  0 assertTrue(
2239    af.alignPanel.getIdPanel().getIdCanvas().isManuallyAdjusted());
2240   
2241  0 af.alignPanel.getAlignViewport().setIdWidth(100);
2242  0 af.alignPanel.updateLayout();
2243  0 assertTrue(
2244    af.alignPanel.getIdPanel().getIdCanvas().isManuallyAdjusted());
2245   
2246  0 Jalview2XML jv2xml = new jalview.project.Jalview2XML(false);
2247  0 tempfile.delete();
2248  0 jv2xml.saveState(tempfile);
2249  0 assertTrue(jv2xml.errorMessage == null,
2250    "Failed to save dummy project with PCA: test broken");
2251  0 af = null;
2252    // load again.
2253  0 Desktop.getInstance().closeAll_actionPerformed(null);
2254  0 af = new FileLoader().LoadFileWaitTillLoaded(
2255    tempfile.getCanonicalPath(), DataSourceType.FILE);
2256  0 assertTrue(
2257    af.alignPanel.getIdPanel().getIdCanvas().isManuallyAdjusted());
2258  0 assertEquals(af.alignPanel.getAlignViewport().getIdWidth(), 100,
2259    "New project exported and import should have adjusted ID width");
2260   
2261  0 af.alignPanel.getAlignViewport().setIdWidth(100);
2262  0 af.alignPanel.updateLayout();
2263  0 assertTrue(
2264    af.alignPanel.getIdPanel().getIdCanvas().isManuallyAdjusted());
2265   
2266    // now make it autoadjusted
2267  0 af.alignPanel.getAlignViewport().setIdWidth(-1);
2268  0 af.alignPanel.getIdPanel().getIdCanvas().setManuallyAdjusted(false);
2269  0 af.alignPanel.updateLayout();
2270  0 assertFalse(
2271    af.alignPanel.getIdPanel().getIdCanvas().isManuallyAdjusted());
2272  0 assertTrue(af.alignPanel.getAlignViewport().getIdWidth() > -1,
2273    "New project exported and import should have adjusted ID width");
2274   
2275  0 jv2xml = new jalview.project.Jalview2XML(false);
2276  0 tempfile.delete();
2277  0 jv2xml.saveState(tempfile);
2278  0 assertTrue(jv2xml.errorMessage == null,
2279    "Failed to save dummy project with PCA: test broken");
2280  0 af = null;
2281    // load again.
2282  0 Desktop.getInstance().closeAll_actionPerformed(null);
2283  0 af = new FileLoader().LoadFileWaitTillLoaded(
2284    tempfile.getCanonicalPath(), DataSourceType.FILE);
2285  0 assertFalse(
2286    af.alignPanel.getIdPanel().getIdCanvas().isManuallyAdjusted());
2287  0 assertTrue(af.alignPanel.getAlignViewport().getIdWidth() > -1,
2288    "New project exported and import should have adjusted ID width");
2289    }
2290   
2291    }