JAL-2089 patch broken merge to master for Release 2.10.0b1
[jalview.git] / test / jalview / io / Jalview2xmlTests.java
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.io;
22
23 import static org.testng.AssertJUnit.assertEquals;
24 import static org.testng.AssertJUnit.assertFalse;
25 import static org.testng.AssertJUnit.assertNotNull;
26 import static org.testng.AssertJUnit.assertSame;
27 import static org.testng.AssertJUnit.assertTrue;
28
29 import jalview.api.AlignViewportI;
30 import jalview.api.AlignmentViewPanel;
31 import jalview.api.ViewStyleI;
32 import jalview.datamodel.AlignmentAnnotation;
33 import jalview.datamodel.AlignmentI;
34 import jalview.datamodel.HiddenSequences;
35 import jalview.datamodel.PDBEntry;
36 import jalview.datamodel.PDBEntry.Type;
37 import jalview.datamodel.SequenceCollectionI;
38 import jalview.datamodel.SequenceGroup;
39 import jalview.datamodel.SequenceI;
40 import jalview.gui.AlignFrame;
41 import jalview.gui.AlignmentPanel;
42 import jalview.gui.Desktop;
43 import jalview.gui.Jalview2XML;
44 import jalview.schemes.AnnotationColourGradient;
45 import jalview.schemes.ColourSchemeI;
46 import jalview.schemes.ColourSchemeProperty;
47 import jalview.schemes.TCoffeeColourScheme;
48 import jalview.structure.StructureImportSettings;
49 import jalview.viewmodel.AlignmentViewport;
50
51 import java.io.File;
52 import java.util.ArrayList;
53 import java.util.HashMap;
54 import java.util.List;
55 import java.util.Map;
56
57 import org.testng.Assert;
58 import org.testng.AssertJUnit;
59 import org.testng.annotations.Test;
60
61 @Test(singleThreaded = true)
62 public class Jalview2xmlTests extends Jalview2xmlBase
63 {
64
65   @Test(groups = { "Functional" })
66   public void testRNAStructureRecovery() throws Exception
67   {
68     String inFile = "examples/RF00031_folded.stk";
69     String tfile = File.createTempFile("JalviewTest", ".jvp")
70             .getAbsolutePath();
71     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
72             FormatAdapter.FILE);
73     assertNotNull("Didn't read input file " + inFile, af);
74     int olddsann = countDsAnn(af.getViewport());
75     assertTrue("Didn't find any dataset annotations", olddsann > 0);
76     af.rnahelicesColour_actionPerformed(null);
77     assertTrue(
78             "Couldn't apply RNA helices colourscheme",
79             af.getViewport().getGlobalColourScheme() instanceof jalview.schemes.RNAHelicesColour);
80     assertTrue("Failed to store as a project.",
81             af.saveAlignment(tfile, "Jalview"));
82     af.closeMenuItem_actionPerformed(true);
83     af = null;
84     af = new FileLoader().LoadFileWaitTillLoaded(tfile, FormatAdapter.FILE);
85     assertNotNull("Failed to import new project", af);
86     int newdsann = countDsAnn(af.getViewport());
87     assertTrue(
88             "Differing numbers of dataset sequence annotation\nOriginally "
89                     + olddsann + " and now " + newdsann,
90             olddsann == newdsann);
91     System.out
92             .println("Read in same number of annotations as originally present ("
93                     + olddsann + ")");
94     assertTrue(
95             "RNA helices colourscheme was not applied on import.",
96             af.getViewport().getGlobalColourScheme() instanceof jalview.schemes.RNAHelicesColour);
97   }
98
99   @Test(groups = { "Functional" })
100   public void testTCoffeeScores() throws Exception
101   {
102     String inFile = "examples/uniref50.fa", inAnnot = "examples/uniref50.score_ascii";
103     String tfile = File.createTempFile("JalviewTest", ".jvp")
104             .getAbsolutePath();
105     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
106             FormatAdapter.FILE);
107     assertNotNull("Didn't read input file " + inFile, af);
108     af.loadJalviewDataFile(inAnnot, FormatAdapter.FILE, null, null);
109     assertSame("Didn't set T-coffee colourscheme", af.getViewport()
110             .getGlobalColourScheme().getClass(), TCoffeeColourScheme.class);
111     assertNotNull("Recognise T-Coffee score from string",
112             jalview.schemes.ColourSchemeProperty.getColour(af.getViewport()
113                     .getAlignment(), ColourSchemeProperty.getColourName(af
114                     .getViewport().getGlobalColourScheme())));
115
116     assertTrue("Failed to store as a project.",
117             af.saveAlignment(tfile, "Jalview"));
118     af.closeMenuItem_actionPerformed(true);
119     af = null;
120     af = new FileLoader().LoadFileWaitTillLoaded(tfile, FormatAdapter.FILE);
121     assertNotNull("Failed to import new project", af);
122     assertSame("Didn't set T-coffee colourscheme for imported project.", af
123             .getViewport().getGlobalColourScheme().getClass(),
124             TCoffeeColourScheme.class);
125     System.out
126             .println("T-Coffee score shading successfully recovered from project.");
127   }
128
129   @Test(groups = { "Functional" })
130   public void testColourByAnnotScores() throws Exception
131   {
132     String inFile = "examples/uniref50.fa", inAnnot = "examples/testdata/uniref50_iupred.jva";
133     String tfile = File.createTempFile("JalviewTest", ".jvp")
134             .getAbsolutePath();
135     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(inFile,
136             FormatAdapter.FILE);
137     assertNotNull("Didn't read input file " + inFile, af);
138     af.loadJalviewDataFile(inAnnot, FormatAdapter.FILE, null, null);
139     AlignmentAnnotation[] aa = af.getViewport().getAlignment()
140             .getSequenceAt(0).getAnnotation("IUPredWS (Short)");
141     assertTrue(
142             "Didn't find any IUPred annotation to use to shade alignment.",
143             aa != null && aa.length > 0);
144     AnnotationColourGradient cs = new AnnotationColourGradient(aa[0], null,
145             AnnotationColourGradient.ABOVE_THRESHOLD);
146     AnnotationColourGradient gcs = new AnnotationColourGradient(aa[0],
147             null, AnnotationColourGradient.BELOW_THRESHOLD);
148     cs.setSeqAssociated(true);
149     gcs.setSeqAssociated(true);
150     af.changeColour(cs);
151     SequenceGroup sg = new SequenceGroup();
152     sg.setStartRes(57);
153     sg.setEndRes(92);
154     sg.cs = gcs;
155     af.getViewport().getAlignment().addGroup(sg);
156     sg.addSequence(af.getViewport().getAlignment().getSequenceAt(1), false);
157     sg.addSequence(af.getViewport().getAlignment().getSequenceAt(2), true);
158     af.alignPanel.alignmentChanged();
159     assertTrue("Failed to store as a project.",
160             af.saveAlignment(tfile, "Jalview"));
161     af.closeMenuItem_actionPerformed(true);
162     af = null;
163     af = new FileLoader().LoadFileWaitTillLoaded(tfile, FormatAdapter.FILE);
164     assertNotNull("Failed to import new project", af);
165
166     // check for group and alignment colourschemes
167
168     ColourSchemeI _rcs = af.getViewport().getGlobalColourScheme();
169     ColourSchemeI _rgcs = af.getViewport().getAlignment().getGroups()
170             .get(0).cs;
171     assertNotNull("Didn't recover global colourscheme", _rcs);
172     assertTrue("Didn't recover annotation colour global scheme",
173             _rcs instanceof AnnotationColourGradient);
174     AnnotationColourGradient __rcs = (AnnotationColourGradient) _rcs;
175     assertTrue("Annotation colourscheme wasn't sequence associated",
176             __rcs.isSeqAssociated());
177
178     boolean diffseqcols = false, diffgseqcols = false;
179     SequenceI[] sqs = af.getViewport().getAlignment().getSequencesArray();
180     for (int p = 0, pSize = af.getViewport().getAlignment().getWidth(); p < pSize
181             && (!diffseqcols || !diffgseqcols); p++)
182     {
183       if (_rcs.findColour(sqs[0].getCharAt(p), p, sqs[0]) != _rcs
184               .findColour(sqs[5].getCharAt(p), p, sqs[5]))
185       {
186         diffseqcols = true;
187       }
188     }
189     assertTrue("Got Different sequence colours", diffseqcols);
190     System.out
191             .println("Per sequence colourscheme (Background) successfully applied and recovered.");
192
193     assertNotNull("Didn't recover group colourscheme", _rgcs);
194     assertTrue("Didn't recover annotation colour group colourscheme",
195             _rgcs instanceof AnnotationColourGradient);
196     __rcs = (AnnotationColourGradient) _rgcs;
197     assertTrue("Group Annotation colourscheme wasn't sequence associated",
198             __rcs.isSeqAssociated());
199
200     for (int p = 0, pSize = af.getViewport().getAlignment().getWidth(); p < pSize
201             && (!diffseqcols || !diffgseqcols); p++)
202     {
203       if (_rgcs.findColour(sqs[1].getCharAt(p), p, sqs[1]) != _rgcs
204               .findColour(sqs[2].getCharAt(p), p, sqs[2]))
205       {
206         diffgseqcols = true;
207       }
208     }
209     assertTrue("Got Different group sequence colours", diffgseqcols);
210     System.out
211             .println("Per sequence (Group) colourscheme successfully applied and recovered.");
212   }
213
214   @Test(groups = { "Functional" })
215   public void gatherViewsHere() throws Exception
216   {
217     int origCount = Desktop.getAlignFrames() == null ? 0 : Desktop
218             .getAlignFrames().length;
219     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
220             "examples/exampleFile_2_7.jar", FormatAdapter.FILE);
221     assertNotNull("Didn't read in the example file correctly.", af);
222     assertTrue("Didn't gather the views in the example file.",
223             Desktop.getAlignFrames().length == 1 + origCount);
224
225   }
226
227   @Test(groups = { "Functional" })
228   public void viewRefPdbAnnotation() throws Exception
229   {
230     StructureImportSettings.setProcessSecondaryStructure(true);
231     StructureImportSettings.setVisibleChainAnnotation(true);
232     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
233             "examples/exampleFile_2_7.jar", FormatAdapter.FILE);
234     assertNotNull("Didn't read in the example file correctly.", af);
235     AlignmentViewPanel sps = null;
236     for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
237     {
238       if ("Spinach Feredoxin Structure".equals(ap.getViewName()))
239       {
240         sps = ap;
241         break;
242       }
243     }
244     assertNotNull("Couldn't find the structure view", sps);
245     AlignmentAnnotation refan = null;
246     for (AlignmentAnnotation ra : sps.getAlignment()
247             .getAlignmentAnnotation())
248     {
249       if (ra.graph != 0)
250       {
251         refan = ra;
252         break;
253       }
254     }
255     assertNotNull("Annotation secondary structure not found.", refan);
256     SequenceI sq = sps.getAlignment().findName("1A70|");
257     assertNotNull("Couldn't find 1a70 null chain", sq);
258     // compare the manually added temperature factor annotation
259     // to the track automatically transferred from the pdb structure on load
260     assertNotNull("1a70 has no annotation", sq.getDatasetSequence()
261             .getAnnotation());
262     for (AlignmentAnnotation ala : sq.getDatasetSequence().getAnnotation())
263     {
264       AlignmentAnnotation alaa;
265       sq.addAlignmentAnnotation(alaa = new AlignmentAnnotation(ala));
266       alaa.adjustForAlignment();
267       if (ala.graph == refan.graph)
268       {
269         for (int p = 0; p < ala.annotations.length; p++)
270         {
271           sq.findPosition(p);
272           try
273           {
274             assertTrue(
275                     "Mismatch at alignment position " + p,
276                     (alaa.annotations[p] == null && refan.annotations[p] == null)
277                             || alaa.annotations[p].value == refan.annotations[p].value);
278           } catch (NullPointerException q)
279           {
280             Assert.fail("Mismatch of alignment annotations at position "
281                     + p + " Ref seq ann: " + refan.annotations[p]
282                     + " alignment " + alaa.annotations[p]);
283           }
284         }
285       }
286     }
287
288   }
289
290   @Test(groups = { "Functional" })
291   public void testCopyViewSettings() throws Exception
292   {
293     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
294             "examples/exampleFile_2_7.jar", FormatAdapter.FILE);
295     assertNotNull("Didn't read in the example file correctly.", af);
296     AlignmentViewPanel sps = null, groups = null;
297     for (AlignmentViewPanel ap : af.alignPanel.alignFrame.getAlignPanels())
298     {
299       if ("Spinach Feredoxin Structure".equals(ap.getViewName()))
300       {
301         sps = ap;
302       }
303       if (ap.getViewName().contains("MAFFT"))
304       {
305         groups = ap;
306       }
307     }
308     assertNotNull("Couldn't find the structure view", sps);
309     assertNotNull("Couldn't find the MAFFT view", groups);
310
311     ViewStyleI structureStyle = sps.getAlignViewport().getViewStyle();
312     ViewStyleI groupStyle = groups.getAlignViewport().getViewStyle();
313     AssertJUnit.assertFalse(structureStyle.sameStyle(groupStyle));
314
315     groups.getAlignViewport().setViewStyle(structureStyle);
316     AssertJUnit.assertFalse(groupStyle.sameStyle(groups.getAlignViewport()
317             .getViewStyle()));
318     Assert.assertTrue(structureStyle.sameStyle(groups.getAlignViewport()
319             .getViewStyle()));
320
321   }
322
323   /**
324    * test store and recovery of expanded views
325    * 
326    * @throws Exception
327    */
328   @Test(groups = { "Functional" }, enabled = true)
329   public void testStoreAndRecoverExpandedviews() throws Exception
330   {
331     Desktop.instance.closeAll_actionPerformed(null);
332
333     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
334             "examples/exampleFile_2_7.jar", FormatAdapter.FILE);
335     Assert.assertEquals(Desktop.getAlignFrames().length, 1);
336     String afid = af.getViewport().getSequenceSetId();
337
338     // check FileLoader returned a reference to the one alignFrame that is
339     // actually on the Desktop
340     assertTrue(
341             "Jalview2XML.loadAlignFrame() didn't return correct AlignFrame reference for multiple view window",
342             af == Desktop.getAlignFrameFor(af.getViewport()));
343
344     Desktop.explodeViews(af);
345
346     int oldviews = Desktop.getAlignFrames().length;
347     Assert.assertEquals(Desktop.getAlignFrames().length,
348             Desktop.getAlignmentPanels(afid).length);
349     File tfile = File.createTempFile("testStoreAndRecoverExpanded", ".jvp");
350     try
351     {
352       new Jalview2XML(false).saveState(tfile);
353     } catch (Error e)
354     {
355       Assert.fail("Didn't save the expanded view state", e);
356     } catch (Exception e)
357     {
358       Assert.fail("Didn't save the expanded view state", e);
359     }
360     Desktop.instance.closeAll_actionPerformed(null);
361     if (Desktop.getAlignFrames() != null)
362     {
363       Assert.assertEquals(Desktop.getAlignFrames().length, 0);
364     }
365     af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
366             FormatAdapter.FILE);
367     Assert.assertNotNull(af);
368     Assert.assertEquals(
369             Desktop.getAlignFrames().length,
370             Desktop.getAlignmentPanels(af.getViewport().getSequenceSetId()).length);
371     Assert.assertEquals(
372             oldviews,
373             Desktop.getAlignmentPanels(af.getViewport().getSequenceSetId()).length);
374   }
375
376   /**
377    * Test save and reload of a project with a different representative sequence
378    * in each view.
379    * 
380    * @throws Exception
381    */
382   @Test(groups = { "Functional" })
383   public void testStoreAndRecoverReferenceSeqSettings() throws Exception
384   {
385     Desktop.instance.closeAll_actionPerformed(null);
386     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
387             "examples/exampleFile_2_7.jar", FormatAdapter.FILE);
388     assertNotNull("Didn't read in the example file correctly.", af);
389     String afid = af.getViewport().getSequenceSetId();
390
391     // remember reference sequence for each panel
392     Map<String, SequenceI> refseqs = new HashMap<String, SequenceI>();
393
394     /*
395      * mark sequence 2, 3, 4.. in panels 1, 2, 3...
396      * as reference sequence for itself and the preceding sequence
397      */
398     int n = 1;
399     for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
400     {
401       AlignViewportI av = ap.getAlignViewport();
402       AlignmentI alignment = ap.getAlignment();
403       int repIndex = n % alignment.getHeight();
404       SequenceI rep = alignment.getSequenceAt(repIndex);
405       refseqs.put(ap.getViewName(), rep);
406
407       // code from mark/unmark sequence as reference in jalview.gui.PopupMenu
408       // todo refactor this to an alignment view controller
409       av.setDisplayReferenceSeq(true);
410       av.setColourByReferenceSeq(true);
411       av.getAlignment().setSeqrep(rep);
412
413       n++;
414     }
415     File tfile = File.createTempFile("testStoreAndRecoverReferenceSeq",
416             ".jvp");
417     try
418     {
419       new Jalview2XML(false).saveState(tfile);
420     } catch (Throwable e)
421     {
422       Assert.fail("Didn't save the expanded view state", e);
423     }
424     Desktop.instance.closeAll_actionPerformed(null);
425     if (Desktop.getAlignFrames() != null)
426     {
427       Assert.assertEquals(Desktop.getAlignFrames().length, 0);
428     }
429
430     af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
431             FormatAdapter.FILE);
432     afid = af.getViewport().getSequenceSetId();
433
434     for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
435     {
436       // check representative
437       AlignmentI alignment = ap.getAlignment();
438       SequenceI rep = alignment.getSeqrep();
439       Assert.assertNotNull(rep,
440               "Couldn't restore sequence representative from project");
441       // can't use a strong equals here, because by definition, the sequence IDs
442       // will be different.
443       // could set vamsas session save/restore flag to preserve IDs across
444       // load/saves.
445       Assert.assertEquals(refseqs.get(ap.getViewName()).toString(),
446               rep.toString(),
447               "Representative wasn't the same when recovered.");
448       Assert.assertTrue(ap.getAlignViewport().isDisplayReferenceSeq(),
449               "Display reference sequence view setting not set.");
450       Assert.assertTrue(ap.getAlignViewport().isColourByReferenceSeq(),
451               "Colour By Reference Seq view setting not set.");
452     }
453   }
454
455   @Test(groups = { "Functional" })
456   public void testIsVersionStringLaterThan()
457   {
458     /*
459      * No version / development / test / autobuild is leniently assumed to be
460      * compatible
461      */
462     assertTrue(Jalview2XML.isVersionStringLaterThan(null, null));
463     assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", null));
464     assertTrue(Jalview2XML.isVersionStringLaterThan(null, "2.8.3"));
465     assertTrue(Jalview2XML.isVersionStringLaterThan(null,
466             "Development Build"));
467     assertTrue(Jalview2XML.isVersionStringLaterThan(null,
468             "DEVELOPMENT BUILD"));
469     assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
470             "Development Build"));
471     assertTrue(Jalview2XML.isVersionStringLaterThan(null, "Test"));
472     assertTrue(Jalview2XML.isVersionStringLaterThan(null, "TEST"));
473     assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "Test"));
474     assertTrue(Jalview2XML
475             .isVersionStringLaterThan(null, "Automated Build"));
476     assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
477             "Automated Build"));
478     assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3",
479             "AUTOMATED BUILD"));
480
481     /*
482      * same version returns true i.e. compatible
483      */
484     assertTrue(Jalview2XML.isVersionStringLaterThan("2.8", "2.8"));
485     assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.3"));
486     assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3b1"));
487     assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3B1", "2.8.3b1"));
488     assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3B1"));
489
490     /*
491      * later version returns true
492      */
493     assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.4"));
494     assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.9"));
495     assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.9.2"));
496     assertTrue(Jalview2XML.isVersionStringLaterThan("2.8", "2.8.3"));
497     assertTrue(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.3b1"));
498
499     /*
500      * earlier version returns false
501      */
502     assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8"));
503     assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.4", "2.8.3"));
504     assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3b1", "2.8.3"));
505     assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.3", "2.8.2b1"));
506     assertFalse(Jalview2XML.isVersionStringLaterThan("2.8.0b2", "2.8.0b1"));
507   }
508
509   /**
510    * Test save and reload of a project with a different sequence group (and
511    * representative sequence) in each view.
512    * 
513    * @throws Exception
514    */
515   @Test(groups = { "Functional" })
516   public void testStoreAndRecoverGroupRepSeqs() throws Exception
517   {
518     Desktop.instance.closeAll_actionPerformed(null);
519     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
520             "examples/uniref50.fa", FormatAdapter.FILE);
521     assertNotNull("Didn't read in the example file correctly.", af);
522     String afid = af.getViewport().getSequenceSetId();
523     // make a second view of the alignment
524     af.newView_actionPerformed(null);
525
526     /*
527      * remember representative and hidden sequences marked 
528      * on each panel
529      */
530     Map<String, SequenceI> repSeqs = new HashMap<String, SequenceI>();
531     Map<String, List<String>> hiddenSeqNames = new HashMap<String, List<String>>();
532
533     /*
534      * mark sequence 2, 3, 4.. in panels 1, 2, 3...
535      * as reference sequence for itself and the preceding sequence
536      */
537     int n = 1;
538     for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
539     {
540       AlignViewportI av = ap.getAlignViewport();
541       AlignmentI alignment = ap.getAlignment();
542       int repIndex = n % alignment.getHeight();
543       // ensure at least one preceding sequence i.e. index >= 1
544       repIndex = Math.max(repIndex, 1);
545       SequenceI repSeq = alignment.getSequenceAt(repIndex);
546       repSeqs.put(ap.getViewName(), repSeq);
547       List<String> hiddenNames = new ArrayList<String>();
548       hiddenSeqNames.put(ap.getViewName(), hiddenNames);
549
550       /*
551        * have rep sequence represent itself and the one before it
552        * this hides the group (except for the rep seq)
553        */
554       SequenceGroup sg = new SequenceGroup();
555       sg.addSequence(repSeq, false);
556       SequenceI precedingSeq = alignment.getSequenceAt(repIndex - 1);
557       sg.addSequence(precedingSeq, false);
558       sg.setSeqrep(repSeq);
559       assertTrue(sg.getSequences().contains(repSeq));
560       assertTrue(sg.getSequences().contains(precedingSeq));
561       av.setSelectionGroup(sg);
562       assertSame(repSeq, sg.getSeqrep());
563
564       /*
565        * represent group with sequence adds to a map of hidden rep sequences
566        * (it does not create a group on the alignment) 
567        */
568       ((AlignmentViewport) av).hideSequences(repSeq, true);
569       assertSame(repSeq, sg.getSeqrep());
570       assertTrue(sg.getSequences().contains(repSeq));
571       assertTrue(sg.getSequences().contains(precedingSeq));
572       assertTrue("alignment has groups", alignment.getGroups().isEmpty());
573       Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av
574               .getHiddenRepSequences();
575       assertNotNull(hiddenRepSeqsMap);
576       assertEquals(1, hiddenRepSeqsMap.size());
577       assertSame(sg, hiddenRepSeqsMap.get(repSeq));
578       assertTrue(alignment.getHiddenSequences().isHidden(precedingSeq));
579       assertFalse(alignment.getHiddenSequences().isHidden(repSeq));
580       hiddenNames.add(precedingSeq.getName());
581
582       n++;
583     }
584     File tfile = File
585             .createTempFile("testStoreAndRecoverGroupReps", ".jvp");
586     try
587     {
588       new Jalview2XML(false).saveState(tfile);
589     } catch (Throwable e)
590     {
591       Assert.fail("Didn't save the expanded view state", e);
592     }
593     Desktop.instance.closeAll_actionPerformed(null);
594     if (Desktop.getAlignFrames() != null)
595     {
596       Assert.assertEquals(Desktop.getAlignFrames().length, 0);
597     }
598
599     af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
600             FormatAdapter.FILE);
601     afid = af.getViewport().getSequenceSetId();
602
603     for (AlignmentViewPanel ap : Desktop.getAlignmentPanels(afid))
604     {
605       String viewName = ap.getViewName();
606       AlignViewportI av = ap.getAlignViewport();
607       AlignmentI alignment = ap.getAlignment();
608       List<SequenceGroup> groups = alignment.getGroups();
609       assertNotNull(groups);
610       assertTrue("Alignment has groups", groups.isEmpty());
611       Map<SequenceI, SequenceCollectionI> hiddenRepSeqsMap = av
612               .getHiddenRepSequences();
613       assertNotNull("No hidden represented sequences", hiddenRepSeqsMap);
614       assertEquals(1, hiddenRepSeqsMap.size());
615       assertEquals(repSeqs.get(viewName).getDisplayId(true),
616               hiddenRepSeqsMap.keySet().iterator().next()
617                       .getDisplayId(true));
618
619       /*
620        * verify hidden sequences in restored panel
621        */
622       List<String> hidden = hiddenSeqNames.get(ap.getViewName());
623       HiddenSequences hs = alignment.getHiddenSequences();
624       assertEquals(
625               "wrong number of restored hidden sequences in "
626                       + ap.getViewName(), hidden.size(), hs.getSize());
627     }
628   }
629
630   /**
631    * Test save and reload of PDBEntry in Jalview project
632    * 
633    * @throws Exception
634    */
635   @Test(groups = { "Functional" })
636   public void testStoreAndRecoverPDBEntry() throws Exception
637   {
638     Desktop.instance.closeAll_actionPerformed(null);
639     String exampleFile = "examples/3W5V.pdb";
640     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(exampleFile,
641             FormatAdapter.FILE);
642     assertNotNull("Didn't read in the example file correctly.", af);
643     String afid = af.getViewport().getSequenceSetId();
644
645     AlignmentPanel[] alignPanels = Desktop.getAlignmentPanels(afid);
646     System.out.println();
647     AlignmentViewPanel ap = alignPanels[0];
648     String tfileBase = new File(".").getAbsolutePath().replace(".", "");
649     String testFile = tfileBase + exampleFile;
650     AlignmentI alignment = ap.getAlignment();
651     System.out.println("blah");
652     SequenceI[] seqs = alignment.getSequencesArray();
653     Assert.assertNotNull(seqs[0]);
654     Assert.assertNotNull(seqs[1]);
655     Assert.assertNotNull(seqs[2]);
656     Assert.assertNotNull(seqs[3]);
657     Assert.assertNotNull(seqs[0].getDatasetSequence());
658     Assert.assertNotNull(seqs[1].getDatasetSequence());
659     Assert.assertNotNull(seqs[2].getDatasetSequence());
660     Assert.assertNotNull(seqs[3].getDatasetSequence());
661     PDBEntry[] pdbEntries = new PDBEntry[4];
662     pdbEntries[0] = new PDBEntry("3W5V", "A", Type.PDB, testFile);
663     pdbEntries[1] = new PDBEntry("3W5V", "B", Type.PDB, testFile);
664     pdbEntries[2] = new PDBEntry("3W5V", "C", Type.PDB, testFile);
665     pdbEntries[3] = new PDBEntry("3W5V", "D", Type.PDB, testFile);
666     Assert.assertEquals(seqs[0].getDatasetSequence().getAllPDBEntries()
667             .get(0), pdbEntries[0]);
668     Assert.assertEquals(seqs[1].getDatasetSequence().getAllPDBEntries()
669             .get(0), pdbEntries[1]);
670     Assert.assertEquals(seqs[2].getDatasetSequence().getAllPDBEntries()
671             .get(0), pdbEntries[2]);
672     Assert.assertEquals(seqs[3].getDatasetSequence().getAllPDBEntries()
673             .get(0), pdbEntries[3]);
674
675     File tfile = File.createTempFile("testStoreAndRecoverPDBEntry", ".jvp");
676     try
677     {
678       new Jalview2XML(false).saveState(tfile);
679     } catch (Throwable e)
680     {
681       Assert.fail("Didn't save the state", e);
682     }
683     Desktop.instance.closeAll_actionPerformed(null);
684     if (Desktop.getAlignFrames() != null)
685     {
686       Assert.assertEquals(Desktop.getAlignFrames().length, 0);
687     }
688
689     AlignFrame restoredFrame = new FileLoader().LoadFileWaitTillLoaded(
690             tfile.getAbsolutePath(), FormatAdapter.FILE);
691     String rfid = restoredFrame.getViewport().getSequenceSetId();
692     AlignmentPanel[] rAlignPanels = Desktop.getAlignmentPanels(rfid);
693     AlignmentViewPanel rap = rAlignPanels[0];
694     AlignmentI rAlignment = rap.getAlignment();
695     System.out.println("blah");
696     SequenceI[] rseqs = rAlignment.getSequencesArray();
697     Assert.assertNotNull(rseqs[0]);
698     Assert.assertNotNull(rseqs[1]);
699     Assert.assertNotNull(rseqs[2]);
700     Assert.assertNotNull(rseqs[3]);
701     Assert.assertNotNull(rseqs[0].getDatasetSequence());
702     Assert.assertNotNull(rseqs[1].getDatasetSequence());
703     Assert.assertNotNull(rseqs[2].getDatasetSequence());
704     Assert.assertNotNull(rseqs[3].getDatasetSequence());
705
706     // The Asserts below are expected to fail until the PDB chainCode is
707     // recoverable from a Jalview projects
708     for (int chain = 0; chain < 4; chain++)
709     {
710       PDBEntry recov = rseqs[chain].getDatasetSequence().getAllPDBEntries()
711               .get(0);
712       PDBEntry expected = pdbEntries[chain];
713       Assert.assertEquals(recov.getId(), expected.getId(),
714               "Mismatch PDB ID");
715       Assert.assertEquals(recov.getChainCode(), expected.getChainCode(),
716               "Mismatch PDB ID");
717       Assert.assertEquals(recov.getType(), expected.getType(),
718               "Mismatch PDBEntry 'Type'");
719       Assert.assertNotNull(recov.getFile(),
720               "Recovered PDBEntry should have a non-null file entry");
721     }
722   }
723 }