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