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