store dataset references, sequence dataset ids, and reconstruct dataset alignment...
[jalview.git] / src / jalview / gui / Jalview2XML.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer
3  * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18  */
19 package jalview.gui;
20
21 import java.io.*;
22 import java.net.*;
23 import java.util.*;
24 import java.util.jar.*;
25
26 import javax.swing.*;
27
28 import org.exolab.castor.xml.*;
29
30 import uk.ac.vamsas.objects.utils.MapList;
31 import jalview.datamodel.Alignment;
32 import jalview.datamodel.AlignmentI;
33 import jalview.datamodel.SequenceI;
34 import jalview.schemabinding.version2.*;
35 import jalview.schemes.*;
36 import jalview.structure.StructureSelectionManager;
37
38 /**
39  * Write out the current jalview desktop state
40  * as a Jalview XML stream.
41  * 
42  * Note: the vamsas objects referred to here are primitive
43  * versions of the VAMSAS project schema elements - they are
44  * not the same and most likely never will be :)
45  *
46  * @author $author$
47  * @version $Revision$
48  */
49 public class Jalview2XML
50 {
51
52   Hashtable seqRefIds = null;
53
54   Vector frefedSequence = null;
55
56   public void resolveFrefedSequences()
57   {
58     if (frefedSequence.size() > 0)
59     {
60       int r = 0, rSize = frefedSequence.size();
61       while (r < rSize)
62       {
63         Object[] ref = (Object[]) frefedSequence.elementAt(r);
64         if (ref != null)
65         {
66           String sref = (String) ref[0];
67           if (seqRefIds.containsKey(sref))
68           {
69             if (ref[1] instanceof jalview.datamodel.Mapping)
70             {
71               SequenceI seq = (SequenceI) seqRefIds.get(sref);
72               while (seq.getDatasetSequence() != null)
73               {
74                 seq = seq.getDatasetSequence();
75               }
76               ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
77             }
78             else
79             {
80               System.err
81                       .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
82                               + ref[1].getClass() + " type objects.");
83             }
84             frefedSequence.remove(r);
85             rSize--;
86           }
87           else
88           {
89             r++;
90           }
91         }
92         else
93         {
94           frefedSequence.remove(r);
95           rSize--;
96         }
97       }
98     }
99   }
100
101   /**
102    * This maintains a list of viewports, the key being the
103    * seqSetId. Important to set historyItem and redoList
104    * for multiple views
105    */
106   Hashtable viewportsAdded;
107
108   Hashtable annotationIds = new Hashtable();
109
110   String uniqueSetSuffix = "";
111
112   /**
113    * List of pdbfiles added to Jar
114    */
115   Vector pdbfiles = null;
116
117   // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
118   public void SaveState(File statefile)
119   {
120     JInternalFrame[] frames = Desktop.desktop.getAllFrames();
121
122     if (frames == null)
123     {
124       return;
125     }
126
127     try
128     {
129       FileOutputStream fos = new FileOutputStream(statefile);
130       JarOutputStream jout = new JarOutputStream(fos);
131
132       //NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
133       ////////////////////////////////////////////////////
134       PrintWriter out = new PrintWriter(new OutputStreamWriter(jout,
135               "UTF-8"));
136
137       Vector shortNames = new Vector();
138
139       //REVERSE ORDER
140       for (int i = frames.length - 1; i > -1; i--)
141       {
142         if (frames[i] instanceof AlignFrame)
143         {
144           AlignFrame af = (AlignFrame) frames[i];
145
146           String shortName = af.getTitle();
147
148           if (shortName.indexOf(File.separatorChar) > -1)
149           {
150             shortName = shortName.substring(shortName
151                     .lastIndexOf(File.separatorChar) + 1);
152           }
153
154           int count = 1;
155
156           while (shortNames.contains(shortName))
157           {
158             if (shortName.endsWith("_" + (count - 1)))
159             {
160               shortName = shortName
161                       .substring(0, shortName.lastIndexOf("_"));
162             }
163
164             shortName = shortName.concat("_" + count);
165             count++;
166           }
167
168           shortNames.addElement(shortName);
169
170           if (!shortName.endsWith(".xml"))
171           {
172             shortName = shortName + ".xml";
173           }
174
175           int ap, apSize = af.alignPanels.size();
176           for (ap = 0; ap < apSize; ap++)
177           {
178             AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
179                     .elementAt(ap);
180
181             SaveState(apanel, apSize == 1 ? shortName : ap + shortName,
182                     jout, out);
183           }
184         }
185       }
186
187       out.close();
188       jout.close();
189     } catch (Exception ex)
190     {
191       ex.printStackTrace();
192     }
193   }
194
195   // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
196   public boolean SaveAlignment(AlignFrame af, String jarFile,
197           String fileName)
198   {
199     try
200     {
201       int ap, apSize = af.alignPanels.size();
202       FileOutputStream fos = new FileOutputStream(jarFile);
203       JarOutputStream jout = new JarOutputStream(fos);
204       PrintWriter out = new PrintWriter(new OutputStreamWriter(jout,
205               "UTF-8"));
206       for (ap = 0; ap < apSize; ap++)
207       {
208         AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
209                 .elementAt(ap);
210
211         SaveState(apanel, apSize == 1 ? fileName : fileName + ap, jout, out);
212       }
213
214       out.close();
215       jout.close();
216       return true;
217     } catch (Exception ex)
218     {
219       ex.printStackTrace();
220       return false;
221     }
222   }
223
224   /**
225    * DOCUMENT ME!
226    *
227    * @param af DOCUMENT ME!
228    * @param timeStamp DOCUMENT ME!
229    * @param fileName DOCUMENT ME!
230    * @param jout DOCUMENT ME!
231    * @param out DOCUMENT ME!
232    */
233   public JalviewModel SaveState(AlignmentPanel ap, String fileName,
234           JarOutputStream jout, PrintWriter out)
235   {
236     if (seqRefIds == null)
237     {
238       seqRefIds = new Hashtable();
239     }
240
241     Vector userColours = new Vector();
242
243     AlignViewport av = ap.av;
244
245     JalviewModel object = new JalviewModel();
246     object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
247
248     object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
249     object.setVersion(jalview.bin.Cache.getProperty("VERSION"));
250
251     jalview.datamodel.AlignmentI jal = av.alignment;
252
253     if (av.hasHiddenRows)
254     {
255       jal = jal.getHiddenSequences().getFullAlignment();
256     }
257
258     SequenceSet vamsasSet = new SequenceSet();
259     Sequence vamsasSeq;
260     JalviewModelSequence jms = new JalviewModelSequence();
261
262     vamsasSet.setGapChar(jal.getGapCharacter() + "");
263
264     if (jal.getDataset() != null)
265     {
266       // dataset id is the dataset's hashcode
267       vamsasSet.setDatasetId(jal.getDataset().hashCode() + "");
268     }
269     if (jal.getProperties() != null)
270     {
271       Enumeration en = jal.getProperties().keys();
272       while (en.hasMoreElements())
273       {
274         String key = en.nextElement().toString();
275         SequenceSetProperties ssp = new SequenceSetProperties();
276         ssp.setKey(key);
277         ssp.setValue(jal.getProperties().get(key).toString());
278         vamsasSet.addSequenceSetProperties(ssp);
279       }
280     }
281
282     JSeq jseq;
283
284     //SAVE SEQUENCES
285     int id = 0;
286     jalview.datamodel.SequenceI jds;
287     for (int i = 0; i < jal.getHeight(); i++)
288     {
289       jds = jal.getSequenceAt(i);
290       id = jds.hashCode();
291
292       if (seqRefIds.get(id + "") != null)
293       {
294
295       }
296       else
297       {
298         vamsasSeq = createVamsasSequence(id, jds);
299         vamsasSet.addSequence(vamsasSeq);
300         seqRefIds.put(id + "", jal.getSequenceAt(i));
301       }
302
303       jseq = new JSeq();
304       jseq.setStart(jds.getStart());
305       jseq.setEnd(jds.getEnd());
306       jseq.setColour(av.getSequenceColour(jds).getRGB());
307
308       jseq.setId(id);
309
310       if (av.hasHiddenRows)
311       {
312         jseq.setHidden(av.alignment.getHiddenSequences().isHidden(jds));
313
314         if (av.hiddenRepSequences != null
315                 && av.hiddenRepSequences.containsKey(jal.getSequenceAt(i)))
316         {
317           jalview.datamodel.SequenceI[] reps = ((jalview.datamodel.SequenceGroup) av.hiddenRepSequences
318                   .get(jal.getSequenceAt(i))).getSequencesInOrder(jal);
319
320           for (int h = 0; h < reps.length; h++)
321           {
322             if (reps[h] != jal.getSequenceAt(i))
323             {
324               jseq.addHiddenSequences(jal.findIndex(reps[h]));
325             }
326           }
327         }
328       }
329
330       if (jds.getDatasetSequence().getSequenceFeatures() != null)
331       {
332         jalview.datamodel.SequenceFeature[] sf = jds.getDatasetSequence()
333                 .getSequenceFeatures();
334         int index = 0;
335         while (index < sf.length)
336         {
337           Features features = new Features();
338
339           features.setBegin(sf[index].getBegin());
340           features.setEnd(sf[index].getEnd());
341           features.setDescription(sf[index].getDescription());
342           features.setType(sf[index].getType());
343           features.setFeatureGroup(sf[index].getFeatureGroup());
344           features.setScore(sf[index].getScore());
345           if (sf[index].links != null)
346           {
347             for (int l = 0; l < sf[index].links.size(); l++)
348             {
349               OtherData keyValue = new OtherData();
350               keyValue.setKey("LINK_" + l);
351               keyValue.setValue(sf[index].links.elementAt(l).toString());
352               features.addOtherData(keyValue);
353             }
354           }
355           if (sf[index].otherDetails != null)
356           {
357             String key;
358             Enumeration keys = sf[index].otherDetails.keys();
359             while (keys.hasMoreElements())
360             {
361               key = keys.nextElement().toString();
362               OtherData keyValue = new OtherData();
363               keyValue.setKey(key);
364               keyValue.setValue(sf[index].otherDetails.get(key).toString());
365               features.addOtherData(keyValue);
366             }
367           }
368
369           jseq.addFeatures(features);
370           index++;
371         }
372       }
373
374       if (jds.getDatasetSequence().getPDBId() != null)
375       {
376         Enumeration en = jds.getDatasetSequence().getPDBId().elements();
377         while (en.hasMoreElements())
378         {
379           Pdbids pdb = new Pdbids();
380           jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
381                   .nextElement();
382
383           pdb.setId(entry.getId());
384           pdb.setType(entry.getType());
385
386           AppJmol jmol;
387           //This must have been loaded, is it still visible?
388           JInternalFrame[] frames = Desktop.desktop.getAllFrames();
389           for (int f = frames.length - 1; f > -1; f--)
390           {
391             if (frames[f] instanceof AppJmol)
392             {
393               jmol = (AppJmol) frames[f];
394               if (!jmol.pdbentry.getId().equals(entry.getId()))
395                 continue;
396
397               StructureState state = new StructureState();
398               state.setVisible(true);
399               state.setXpos(jmol.getX());
400               state.setYpos(jmol.getY());
401               state.setWidth(jmol.getWidth());
402               state.setHeight(jmol.getHeight());
403
404               String statestring = jmol.viewer.getStateInfo();
405               if (state != null)
406               {
407                 state.setContent(statestring.replaceAll("\n", ""));
408               }
409               for (int s = 0; s < jmol.sequence.length; s++)
410               {
411                 if (jal.findIndex(jmol.sequence[s]) > -1)
412                 {
413                   pdb.addStructureState(state);
414                 }
415               }
416             }
417           }
418
419           if (entry.getFile() != null)
420           {
421             pdb.setFile(entry.getFile());
422             if (pdbfiles == null)
423             {
424               pdbfiles = new Vector();
425             }
426
427             if (!pdbfiles.contains(entry.getId()))
428             {
429               pdbfiles.addElement(entry.getId());
430               try
431               {
432                 File file = new File(entry.getFile());
433                 if (file.exists() && jout != null)
434                 {
435                   byte[] data = new byte[(int) file.length()];
436                   jout.putNextEntry(new JarEntry(entry.getId()));
437                   DataInputStream dis = new DataInputStream(
438                           new FileInputStream(file));
439                   dis.readFully(data);
440
441                   DataOutputStream dout = new DataOutputStream(jout);
442                   dout.write(data, 0, data.length);
443                   jout.closeEntry();
444                 }
445               } catch (Exception ex)
446               {
447                 ex.printStackTrace();
448               }
449
450             }
451           }
452
453           if (entry.getProperty() != null)
454           {
455             PdbentryItem item = new PdbentryItem();
456             Hashtable properties = entry.getProperty();
457             Enumeration en2 = properties.keys();
458             while (en2.hasMoreElements())
459             {
460               Property prop = new Property();
461               String key = en2.nextElement().toString();
462               prop.setName(key);
463               prop.setValue(properties.get(key).toString());
464               item.addProperty(prop);
465             }
466             pdb.addPdbentryItem(item);
467           }
468
469           jseq.addPdbids(pdb);
470         }
471       }
472
473       jms.addJSeq(jseq);
474     }
475
476     if (av.hasHiddenRows)
477     {
478       jal = av.alignment;
479     }
480     // SAVE MAPPINGS
481     if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0)
482     {
483       jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames();
484       for (int i = 0; i < jac.length; i++)
485       {
486         AlcodonFrame alc = new AlcodonFrame();
487         vamsasSet.addAlcodonFrame(alc);
488         for (int p = 0; p < jac[i].aaWidth; i++)
489         {
490           Alcodon cmap = new Alcodon();
491           cmap.setPos1(jac[i].codons[p][0]);
492           cmap.setPos2(jac[i].codons[p][1]);
493           cmap.setPos3(jac[i].codons[p][2]);
494           alc.addAlcodon(cmap);
495         }
496         if (jac[i].getProtMappings() != null
497                 && jac[i].getProtMappings().length > 0)
498         {
499           SequenceI[] dnas = jac[i].getdnaSeqs();
500           jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings();
501           for (int m = 0; m < pmaps.length; m++)
502           {
503             AlcodMap alcmap = new AlcodMap();
504             alcmap.setDnasq("" + dnas[m].hashCode());
505             alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
506                     false));
507             alc.addAlcodMap(alcmap);
508           }
509         }
510       }
511     }
512
513     //SAVE TREES
514     ///////////////////////////////////
515     if (av.currentTree != null)
516     {
517       // FIND ANY ASSOCIATED TREES
518       // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
519       if (Desktop.desktop != null)
520       {
521         JInternalFrame[] frames = Desktop.desktop.getAllFrames();
522
523         for (int t = 0; t < frames.length; t++)
524         {
525           if (frames[t] instanceof TreePanel)
526           {
527             TreePanel tp = (TreePanel) frames[t];
528
529             if (tp.treeCanvas.av.alignment == jal)
530             {
531               Tree tree = new Tree();
532               tree.setTitle(tp.getTitle());
533               tree.setCurrentTree((av.currentTree == tp.getTree()));
534               tree.setNewick(tp.getTree().toString());
535               tree.setThreshold(tp.treeCanvas.threshold);
536
537               tree.setFitToWindow(tp.fitToWindow.getState());
538               tree.setFontName(tp.getTreeFont().getName());
539               tree.setFontSize(tp.getTreeFont().getSize());
540               tree.setFontStyle(tp.getTreeFont().getStyle());
541               tree.setMarkUnlinked(tp.placeholdersMenu.getState());
542
543               tree.setShowBootstrap(tp.bootstrapMenu.getState());
544               tree.setShowDistances(tp.distanceMenu.getState());
545
546               tree.setHeight(tp.getHeight());
547               tree.setWidth(tp.getWidth());
548               tree.setXpos(tp.getX());
549               tree.setYpos(tp.getY());
550
551               jms.addTree(tree);
552             }
553           }
554         }
555       }
556     }
557
558     //SAVE ANNOTATIONS
559     if (jal.getAlignmentAnnotation() != null)
560     {
561       jalview.datamodel.AlignmentAnnotation[] aa = jal
562               .getAlignmentAnnotation();
563
564       for (int i = 0; i < aa.length; i++)
565       {
566         Annotation an = new Annotation();
567
568         if (aa[i].annotationId != null)
569         {
570           annotationIds.put(aa[i].annotationId, aa[i]);
571         }
572
573         an.setId(aa[i].annotationId);
574
575         if (aa[i] == av.quality || aa[i] == av.conservation
576                 || aa[i] == av.consensus)
577         {
578           an.setLabel(aa[i].label);
579           an.setGraph(true);
580           vamsasSet.addAnnotation(an);
581           continue;
582         }
583
584         an.setVisible(aa[i].visible);
585
586         an.setDescription(aa[i].description);
587
588         if (aa[i].sequenceRef != null)
589         {
590           an.setSequenceRef(aa[i].sequenceRef.getName());
591         }
592
593         if (aa[i].graph > 0)
594         {
595           an.setGraph(true);
596           an.setGraphType(aa[i].graph);
597           an.setGraphGroup(aa[i].graphGroup);
598           if (aa[i].getThreshold() != null)
599           {
600             ThresholdLine line = new ThresholdLine();
601             line.setLabel(aa[i].getThreshold().label);
602             line.setValue(aa[i].getThreshold().value);
603             line.setColour(aa[i].getThreshold().colour.getRGB());
604             an.setThresholdLine(line);
605           }
606         }
607         else
608         {
609           an.setGraph(false);
610         }
611
612         an.setLabel(aa[i].label);
613         if (aa[i].hasScore())
614         {
615           an.setScore(aa[i].getScore());
616         }
617         AnnotationElement ae;
618         if (aa[i].annotations != null)
619         {
620           an.setScoreOnly(false);
621           for (int a = 0; a < aa[i].annotations.length; a++)
622           {
623             if ((aa[i] == null) || (aa[i].annotations[a] == null))
624             {
625               continue;
626             }
627
628             ae = new AnnotationElement();
629             if (aa[i].annotations[a].description != null)
630               ae.setDescription(aa[i].annotations[a].description);
631             if (aa[i].annotations[a].displayCharacter != null)
632               ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
633
634             if (!Float.isNaN(aa[i].annotations[a].value))
635               ae.setValue(aa[i].annotations[a].value);
636
637             ae.setPosition(a);
638             if (aa[i].annotations[a].secondaryStructure != ' '
639                     && aa[i].annotations[a].secondaryStructure != '\0')
640               ae
641                       .setSecondaryStructure(aa[i].annotations[a].secondaryStructure
642                               + "");
643
644             if (aa[i].annotations[a].colour != null
645                     && aa[i].annotations[a].colour != java.awt.Color.black)
646             {
647               ae.setColour(aa[i].annotations[a].colour.getRGB());
648             }
649
650             an.addAnnotationElement(ae);
651           }
652         }
653         else
654         {
655           an.setScoreOnly(true);
656         }
657         vamsasSet.addAnnotation(an);
658       }
659     }
660
661     //SAVE GROUPS
662     if (jal.getGroups() != null)
663     {
664       JGroup[] groups = new JGroup[jal.getGroups().size()];
665
666       for (int i = 0; i < groups.length; i++)
667       {
668         groups[i] = new JGroup();
669
670         jalview.datamodel.SequenceGroup sg = (jalview.datamodel.SequenceGroup) jal
671                 .getGroups().elementAt(i);
672         groups[i].setStart(sg.getStartRes());
673         groups[i].setEnd(sg.getEndRes());
674         groups[i].setName(sg.getName());
675         if (sg.cs != null)
676         {
677           if (sg.cs.conservationApplied())
678           {
679             groups[i].setConsThreshold(sg.cs.getConservationInc());
680
681             if (sg.cs instanceof jalview.schemes.UserColourScheme)
682             {
683               groups[i].setColour(SetUserColourScheme(sg.cs, userColours,
684                       jms));
685             }
686             else
687             {
688               groups[i]
689                       .setColour(ColourSchemeProperty.getColourName(sg.cs));
690             }
691           }
692           else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
693           {
694             groups[i]
695                     .setColour(ColourSchemeProperty
696                             .getColourName(((jalview.schemes.AnnotationColourGradient) sg.cs)
697                                     .getBaseColour()));
698           }
699           else if (sg.cs instanceof jalview.schemes.UserColourScheme)
700           {
701             groups[i]
702                     .setColour(SetUserColourScheme(sg.cs, userColours, jms));
703           }
704           else
705           {
706             groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
707           }
708
709           groups[i].setPidThreshold(sg.cs.getThreshold());
710         }
711
712         groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
713         groups[i].setDisplayBoxes(sg.getDisplayBoxes());
714         groups[i].setDisplayText(sg.getDisplayText());
715         groups[i].setColourText(sg.getColourText());
716         groups[i].setTextCol1(sg.textColour.getRGB());
717         groups[i].setTextCol2(sg.textColour2.getRGB());
718         groups[i].setTextColThreshold(sg.thresholdTextColour);
719
720         for (int s = 0; s < sg.getSize(); s++)
721         {
722           jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
723                   .getSequenceAt(s);
724           groups[i].addSeq(seq.hashCode());
725         }
726       }
727
728       jms.setJGroup(groups);
729     }
730
731     ///////////SAVE VIEWPORT
732     Viewport view = new Viewport();
733     view.setTitle(ap.alignFrame.getTitle());
734     view.setSequenceSetId(av.getSequenceSetId());
735     view.setViewName(av.viewName);
736     view.setGatheredViews(av.gatherViewsHere);
737
738     if (ap.av.explodedPosition != null)
739     {
740       view.setXpos(av.explodedPosition.x);
741       view.setYpos(av.explodedPosition.y);
742       view.setWidth(av.explodedPosition.width);
743       view.setHeight(av.explodedPosition.height);
744     }
745     else
746     {
747       view.setXpos(ap.alignFrame.getBounds().x);
748       view.setYpos(ap.alignFrame.getBounds().y);
749       view.setWidth(ap.alignFrame.getBounds().width);
750       view.setHeight(ap.alignFrame.getBounds().height);
751     }
752
753     view.setStartRes(av.startRes);
754     view.setStartSeq(av.startSeq);
755
756     if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
757     {
758       view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(),
759               userColours, jms));
760     }
761     else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
762     {
763       jalview.schemes.AnnotationColourGradient acg = (jalview.schemes.AnnotationColourGradient) av
764               .getGlobalColourScheme();
765
766       AnnotationColours ac = new AnnotationColours();
767       ac.setAboveThreshold(acg.getAboveThreshold());
768       ac.setThreshold(acg.getAnnotationThreshold());
769       ac.setAnnotation(acg.getAnnotation());
770       if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
771       {
772         ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
773                 userColours, jms));
774       }
775       else
776       {
777         ac.setColourScheme(ColourSchemeProperty.getColourName(acg
778                 .getBaseColour()));
779       }
780
781       ac.setMaxColour(acg.getMaxColour().getRGB());
782       ac.setMinColour(acg.getMinColour().getRGB());
783       view.setAnnotationColours(ac);
784       view.setBgColour("AnnotationColourGradient");
785     }
786     else
787     {
788       view.setBgColour(ColourSchemeProperty.getColourName(av
789               .getGlobalColourScheme()));
790     }
791
792     ColourSchemeI cs = av.getGlobalColourScheme();
793
794     if (cs != null)
795     {
796       if (cs.conservationApplied())
797       {
798         view.setConsThreshold(cs.getConservationInc());
799         if (cs instanceof jalview.schemes.UserColourScheme)
800         {
801           view.setBgColour(SetUserColourScheme(cs, userColours, jms));
802         }
803       }
804
805       if (cs instanceof ResidueColourScheme)
806       {
807         view.setPidThreshold(cs.getThreshold());
808       }
809     }
810
811     view.setConservationSelected(av.getConservationSelected());
812     view.setPidSelected(av.getAbovePIDThreshold());
813     view.setFontName(av.font.getName());
814     view.setFontSize(av.font.getSize());
815     view.setFontStyle(av.font.getStyle());
816     view.setRenderGaps(av.renderGaps);
817     view.setShowAnnotation(av.getShowAnnotation());
818     view.setShowBoxes(av.getShowBoxes());
819     view.setShowColourText(av.getColourText());
820     view.setShowFullId(av.getShowJVSuffix());
821     view.setRightAlignIds(av.rightAlignIds);
822     view.setShowSequenceFeatures(av.showSequenceFeatures);
823     view.setShowText(av.getShowText());
824     view.setWrapAlignment(av.getWrapAlignment());
825     view.setTextCol1(av.textColour.getRGB());
826     view.setTextCol2(av.textColour2.getRGB());
827     view.setTextColThreshold(av.thresholdTextColour);
828
829     if (av.featuresDisplayed != null)
830     {
831       jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
832
833       String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;
834
835       Vector settingsAdded = new Vector();
836       for (int ro = 0; ro < renderOrder.length; ro++)
837       {
838         Setting setting = new Setting();
839         setting.setType(renderOrder[ro]);
840         setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
841                 .getColour(renderOrder[ro]).getRGB());
842
843         setting.setDisplay(av.featuresDisplayed
844                 .containsKey(renderOrder[ro]));
845         float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer().getOrder(
846                 renderOrder[ro]);
847         if (rorder > -1)
848         {
849           setting.setOrder(rorder);
850         }
851         fs.addSetting(setting);
852         settingsAdded.addElement(renderOrder[ro]);
853       }
854
855       //Make sure we save none displayed feature settings
856       Enumeration en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours
857               .keys();
858       while (en.hasMoreElements())
859       {
860         String key = en.nextElement().toString();
861         if (settingsAdded.contains(key))
862         {
863           continue;
864         }
865
866         Setting setting = new Setting();
867         setting.setType(key);
868         setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
869                 .getColour(key).getRGB());
870
871         setting.setDisplay(false);
872         float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer().getOrder(
873                 key);
874         if (rorder > -1)
875         {
876           setting.setOrder(rorder);
877         }
878         fs.addSetting(setting);
879         settingsAdded.addElement(key);
880       }
881       en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups.keys();
882       Vector groupsAdded = new Vector();
883       while (en.hasMoreElements())
884       {
885         String grp = en.nextElement().toString();
886         if (groupsAdded.contains(grp))
887         {
888           continue;
889         }
890         Group g = new Group();
891         g.setName(grp);
892         g
893                 .setDisplay(((Boolean) ap.seqPanel.seqCanvas
894                         .getFeatureRenderer().featureGroups.get(grp))
895                         .booleanValue());
896         fs.addGroup(g);
897         groupsAdded.addElement(grp);
898       }
899       jms.setFeatureSettings(fs);
900
901     }
902
903     if (av.hasHiddenColumns)
904     {
905       for (int c = 0; c < av.getColumnSelection().getHiddenColumns().size(); c++)
906       {
907         int[] region = (int[]) av.getColumnSelection().getHiddenColumns()
908                 .elementAt(c);
909         HiddenColumns hc = new HiddenColumns();
910         hc.setStart(region[0]);
911         hc.setEnd(region[1]);
912         view.addHiddenColumns(hc);
913       }
914     }
915
916     jms.addViewport(view);
917
918     object.setJalviewModelSequence(jms);
919     object.getVamsasModel().addSequenceSet(vamsasSet);
920
921     if (out != null)
922     {
923       //We may not want to right the object to disk,
924       //eg we can copy the alignViewport to a new view object
925       //using save and then load
926       try
927       {
928         if (!fileName.endsWith(".xml"))
929         {
930           fileName = fileName + ".xml";
931         }
932
933         JarEntry entry = new JarEntry(fileName);
934         jout.putNextEntry(entry);
935
936         object.marshal(out);
937       } catch (Exception ex)
938       {
939         ex.printStackTrace();
940       }
941     }
942     return object;
943   }
944
945   private Sequence createVamsasSequence(int id, SequenceI jds)
946   {
947     return createVamsasSequence(true, id, jds, null);
948   }
949
950   private Sequence createVamsasSequence(boolean recurse, int id,
951           SequenceI jds, SequenceI parentseq)
952   {
953     Sequence vamsasSeq = new Sequence();
954     vamsasSeq.setId(id + "");
955     vamsasSeq.setName(jds.getName());
956     vamsasSeq.setSequence(jds.getSequenceAsString());
957     vamsasSeq.setDescription(jds.getDescription());
958     jalview.datamodel.DBRefEntry[] dbrefs = null;
959     if (jds.getDatasetSequence() != null)
960     {
961       vamsasSeq.setDsseqid(jds.getDatasetSequence().hashCode() + "");
962       if (jds.getDatasetSequence().getDBRef() != null)
963       {
964         dbrefs = jds.getDatasetSequence().getDBRef();
965       }
966     }
967     else
968     {
969       dbrefs = jds.getDBRef();
970     }
971     if (jds.getDBRef() != null)
972     {
973       for (int d = 0; d < dbrefs.length; d++)
974       {
975         DBRef dbref = new DBRef();
976         dbref.setSource(dbrefs[d].getSource());
977         dbref.setVersion(dbrefs[d].getVersion());
978         dbref.setAccessionId(dbrefs[d].getAccessionId());
979         if (dbrefs[d].hasMap())
980         {
981           Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
982                   jds, recurse);
983           dbref.setMapping(mp);
984         }
985         vamsasSeq.addDBRef(dbref);
986       }
987     }
988     return vamsasSeq;
989   }
990
991   private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
992           SequenceI parentseq, SequenceI jds, boolean recurse)
993   {
994     Mapping mp = null;
995     if (jmp.getMap() != null)
996     {
997       mp = new Mapping();
998
999       jalview.util.MapList mlst = jmp.getMap();
1000       int r[] = mlst.getFromRanges();
1001       for (int s = 0; s < r.length; s += 2)
1002       {
1003         MapListFrom mfrom = new MapListFrom();
1004         mfrom.setStart(r[s]);
1005         mfrom.setEnd(r[s + 1]);
1006         mp.addMapListFrom(mfrom);
1007       }
1008       r = mlst.getToRanges();
1009       for (int s = 0; s < r.length; s += 2)
1010       {
1011         MapListTo mto = new MapListTo();
1012         mto.setStart(r[s]);
1013         mto.setEnd(r[s + 1]);
1014         mp.addMapListTo(mto);
1015       }
1016       mp.setMapFromUnit(mlst.getFromRatio());
1017       mp.setMapToUnit(mlst.getToRatio());
1018       if (jmp.getTo() != null)
1019       {
1020         MappingChoice mpc = new MappingChoice();
1021         if (recurse
1022                 && (parentseq != jmp.getTo() || parentseq
1023                         .getDatasetSequence() != jmp.getTo()))
1024         {
1025           mpc.setSequence(createVamsasSequence(false, jmp.getTo()
1026                   .hashCode(), jmp.getTo(), jds));
1027         }
1028         else
1029         {
1030           long jmpid = 0;
1031           SequenceI ps = null;
1032           if (parentseq != jmp.getTo()
1033                   && parentseq.getDatasetSequence() != jmp.getTo())
1034           {
1035             // chaining dbref rather than a handshaking one
1036             jmpid = (ps = jmp.getTo()).hashCode();
1037           }
1038           else
1039           {
1040             jmpid = (ps = parentseq).hashCode();
1041           }
1042           mpc.setDseqFor("" + jmpid);
1043           if (!seqRefIds.containsKey(mpc.getDseqFor()))
1044           {
1045             jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1046             seqRefIds.put(mpc.getDseqFor(), ps);
1047           }
1048           else
1049           {
1050             jalview.bin.Cache.log.debug("reusing DseqFor ID");
1051           }
1052         }
1053         mp.setMappingChoice(mpc);
1054       }
1055     }
1056     return mp;
1057   }
1058
1059   String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1060           Vector userColours, JalviewModelSequence jms)
1061   {
1062     String id = null;
1063     jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1064
1065     if (!userColours.contains(ucs))
1066     {
1067       userColours.add(ucs);
1068
1069       java.awt.Color[] colours = ucs.getColours();
1070       jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1071       jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1072
1073       for (int i = 0; i < colours.length; i++)
1074       {
1075         jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1076         col.setName(ResidueProperties.aa[i]);
1077         col.setRGB(jalview.util.Format.getHexString(colours[i]));
1078         jbucs.addColour(col);
1079       }
1080       if (ucs.getLowerCaseColours() != null)
1081       {
1082         colours = ucs.getLowerCaseColours();
1083         for (int i = 0; i < colours.length; i++)
1084         {
1085           jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1086           col.setName(ResidueProperties.aa[i].toLowerCase());
1087           col.setRGB(jalview.util.Format.getHexString(colours[i]));
1088           jbucs.addColour(col);
1089         }
1090       }
1091
1092       id = "ucs" + userColours.indexOf(ucs);
1093       uc.setId(id);
1094       uc.setUserColourScheme(jbucs);
1095       jms.addUserColours(uc);
1096     }
1097
1098     return id;
1099   }
1100
1101   jalview.schemes.UserColourScheme GetUserColourScheme(
1102           JalviewModelSequence jms, String id)
1103   {
1104     UserColours[] uc = jms.getUserColours();
1105     UserColours colours = null;
1106
1107     for (int i = 0; i < uc.length; i++)
1108     {
1109       if (uc[i].getId().equals(id))
1110       {
1111         colours = uc[i];
1112
1113         break;
1114       }
1115     }
1116
1117     java.awt.Color[] newColours = new java.awt.Color[24];
1118
1119     for (int i = 0; i < 24; i++)
1120     {
1121       newColours[i] = new java.awt.Color(Integer.parseInt(colours
1122               .getUserColourScheme().getColour(i).getRGB(), 16));
1123     }
1124
1125     jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1126             newColours);
1127
1128     if (colours.getUserColourScheme().getColourCount() > 24)
1129     {
1130       newColours = new java.awt.Color[23];
1131       for (int i = 0; i < 23; i++)
1132       {
1133         newColours[i] = new java.awt.Color(Integer.parseInt(colours
1134                 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1135       }
1136       ucs.setLowerCaseColours(newColours);
1137     }
1138
1139     return ucs;
1140   }
1141
1142   /**
1143    * DOCUMENT ME!
1144    *
1145    * @param file DOCUMENT ME!
1146    */
1147   public AlignFrame LoadJalviewAlign(final String file)
1148   {
1149     uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1150
1151     jalview.gui.AlignFrame af = null;
1152
1153     seqRefIds = new Hashtable();
1154     viewportsAdded = new Hashtable();
1155     frefedSequence = new Vector();
1156     Hashtable gatherToThisFrame = new Hashtable();
1157
1158     String errorMessage = null;
1159
1160     try
1161     {
1162       //UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1163       URL url = null;
1164
1165       if (file.startsWith("http://"))
1166       {
1167         url = new URL(file);
1168       }
1169
1170       JarInputStream jin = null;
1171       JarEntry jarentry = null;
1172       int entryCount = 1;
1173
1174       do
1175       {
1176         if (url != null)
1177         {
1178           jin = new JarInputStream(url.openStream());
1179         }
1180         else
1181         {
1182           jin = new JarInputStream(new FileInputStream(file));
1183         }
1184
1185         for (int i = 0; i < entryCount; i++)
1186         {
1187           jarentry = jin.getNextJarEntry();
1188         }
1189
1190         if (jarentry != null && jarentry.getName().endsWith(".xml"))
1191         {
1192           InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1193           JalviewModel object = new JalviewModel();
1194
1195           Unmarshaller unmar = new Unmarshaller(object);
1196           unmar.setValidation(false);
1197           object = (JalviewModel) unmar.unmarshal(in);
1198
1199           af = LoadFromObject(object, file, true);
1200           if (af.viewport.gatherViewsHere)
1201           {
1202             gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
1203           }
1204           entryCount++;
1205         }
1206         else if (jarentry != null)
1207         {
1208           //Some other file here.
1209           entryCount++;
1210         }
1211       } while (jarentry != null);
1212       resolveFrefedSequences();
1213     } catch (java.io.FileNotFoundException ex)
1214     {
1215       ex.printStackTrace();
1216       errorMessage = "Couldn't locate Jalview XML file : " + file;
1217       System.err.println("Exception whilst loading jalview XML file : "
1218               + ex + "\n");
1219     } catch (java.net.UnknownHostException ex)
1220     {
1221       ex.printStackTrace();
1222       errorMessage = "Couldn't locate Jalview XML file : " + file;
1223       System.err.println("Exception whilst loading jalview XML file : "
1224               + ex + "\n");
1225     } catch (Exception ex)
1226     {
1227       //Is Version 1 Jar file?
1228       af = new Jalview2XML_V1().LoadJalviewAlign(file);
1229
1230       if (af != null)
1231       {
1232         System.out.println("Successfully loaded archive file");
1233         return af;
1234       }
1235       ex.printStackTrace();
1236
1237       System.err.println("Exception whilst loading jalview XML file : "
1238               + ex + "\n");
1239     }
1240
1241     if (Desktop.instance != null)
1242     {
1243       Desktop.instance.stopLoading();
1244     }
1245
1246     Enumeration en = gatherToThisFrame.elements();
1247     while (en.hasMoreElements())
1248     {
1249       Desktop.instance.gatherViews((AlignFrame) en.nextElement());
1250     }
1251
1252     if (errorMessage != null)
1253     {
1254       final String finalErrorMessage = errorMessage;
1255       javax.swing.SwingUtilities.invokeLater(new Runnable()
1256       {
1257         public void run()
1258         {
1259           JOptionPane.showInternalMessageDialog(Desktop.desktop,
1260                   finalErrorMessage, "Error loading Jalview file",
1261                   JOptionPane.WARNING_MESSAGE);
1262         }
1263       });
1264     }
1265
1266     return af;
1267   }
1268
1269   Hashtable alreadyLoadedPDB;
1270
1271   String loadPDBFile(String file, String pdbId)
1272   {
1273     if (alreadyLoadedPDB == null)
1274       alreadyLoadedPDB = new Hashtable();
1275
1276     if (alreadyLoadedPDB.containsKey(pdbId))
1277       return alreadyLoadedPDB.get(pdbId).toString();
1278
1279     try
1280     {
1281       JarInputStream jin = null;
1282
1283       if (file.startsWith("http://"))
1284       {
1285         jin = new JarInputStream(new URL(file).openStream());
1286       }
1287       else
1288       {
1289         jin = new JarInputStream(new FileInputStream(file));
1290       }
1291
1292       JarEntry entry = null;
1293       do
1294       {
1295         entry = jin.getNextJarEntry();
1296       } while (!entry.getName().equals(pdbId));
1297
1298       BufferedReader in = new BufferedReader(new InputStreamReader(jin));
1299       File outFile = File.createTempFile("jalview_pdb", ".txt");
1300       outFile.deleteOnExit();
1301       PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
1302       String data;
1303
1304       while ((data = in.readLine()) != null)
1305       {
1306         out.println(data);
1307       }
1308       out.close();
1309
1310       alreadyLoadedPDB.put(pdbId, outFile.getAbsolutePath());
1311       return outFile.getAbsolutePath();
1312
1313     } catch (Exception ex)
1314     {
1315       ex.printStackTrace();
1316     }
1317
1318     return null;
1319   }
1320
1321   AlignFrame LoadFromObject(JalviewModel object, String file,
1322           boolean loadTreesAndStructures)
1323   {
1324     SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
1325     Sequence[] vamsasSeq = vamsasSet.getSequence();
1326
1327     JalviewModelSequence jms = object.getJalviewModelSequence();
1328
1329     Viewport view = jms.getViewport(0);
1330
1331     //////////////////////////////////
1332     //LOAD SEQUENCES
1333
1334     Vector hiddenSeqs = null;
1335     jalview.datamodel.Sequence jseq;
1336
1337     ArrayList tmpseqs = new ArrayList();
1338
1339     boolean multipleView = false;
1340
1341     JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
1342     for (int i = 0; i < JSEQ.length; i++)
1343     {
1344       String seqId = JSEQ[i].getId() + "";
1345
1346       if (seqRefIds.get(seqId) != null)
1347       {
1348         tmpseqs.add((jalview.datamodel.Sequence) seqRefIds.get(seqId));
1349         multipleView = true;
1350       }
1351       else
1352       {
1353         jseq = new jalview.datamodel.Sequence(vamsasSeq[i].getName(),
1354                 vamsasSeq[i].getSequence());
1355         jseq.setDescription(vamsasSeq[i].getDescription());
1356         jseq.setStart(JSEQ[i].getStart());
1357         jseq.setEnd(JSEQ[i].getEnd());
1358         jseq.setVamsasId(uniqueSetSuffix + seqId);
1359         seqRefIds.put(vamsasSeq[i].getId(), jseq);
1360         tmpseqs.add(jseq);
1361       }
1362
1363       if (JSEQ[i].getHidden())
1364       {
1365         if (hiddenSeqs == null)
1366         {
1367           hiddenSeqs = new Vector();
1368         }
1369
1370         hiddenSeqs.addElement((jalview.datamodel.Sequence) seqRefIds
1371                 .get(seqId));
1372       }
1373
1374     }
1375
1376     ///
1377     // Create the alignment object from the sequence set
1378     /////////////////////////////////
1379     jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
1380             .size()];
1381
1382     tmpseqs.toArray(orderedSeqs);
1383
1384     jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
1385             orderedSeqs);
1386
1387     /// Add the alignment properties
1388     for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
1389     {
1390       SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
1391       al.setProperty(ssp.getKey(), ssp.getValue());
1392     }
1393
1394     ///
1395     // SequenceFeatures are added to the DatasetSequence,
1396     // so we must create or recover the dataset before loading features
1397     /////////////////////////////////
1398     if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
1399     {
1400       // older jalview projects do not have a dataset id.
1401       al.setDataset(null);
1402       // addDatasetRef(al.getDataset());
1403     }
1404     else
1405     {
1406       recoverDatasetFor(vamsasSet, al);
1407     }
1408     /////////////////////////////////
1409
1410     Hashtable pdbloaded = new Hashtable();
1411     if (!multipleView)
1412     {
1413       for (int i = 0; i < vamsasSeq.length; i++)
1414       {
1415         if (JSEQ[i].getFeaturesCount() > 0)
1416         {
1417           Features[] features = JSEQ[i].getFeatures();
1418           for (int f = 0; f < features.length; f++)
1419           {
1420             jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
1421                     features[f].getType(), features[f].getDescription(),
1422                     features[f].getStatus(), features[f].getBegin(),
1423                     features[f].getEnd(), features[f].getFeatureGroup());
1424
1425             sf.setScore(features[f].getScore());
1426             for (int od = 0; od < features[f].getOtherDataCount(); od++)
1427             {
1428               OtherData keyValue = features[f].getOtherData(od);
1429               if (keyValue.getKey().startsWith("LINK"))
1430               {
1431                 sf.addLink(keyValue.getValue());
1432               }
1433               else
1434               {
1435                 sf.setValue(keyValue.getKey(), keyValue.getValue());
1436               }
1437
1438             }
1439
1440             al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
1441           }
1442         }
1443
1444         if (JSEQ[i].getPdbidsCount() > 0)
1445         {
1446           Pdbids[] ids = JSEQ[i].getPdbids();
1447           for (int p = 0; p < ids.length; p++)
1448           {
1449             jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
1450             entry.setId(ids[p].getId());
1451             entry.setType(ids[p].getType());
1452             if (ids[p].getFile() != null)
1453             {
1454               if (!pdbloaded.containsKey(ids[p].getFile()))
1455               {
1456                 entry.setFile(loadPDBFile(file, ids[p].getId()));
1457               }
1458               else
1459               {
1460                 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
1461               }
1462             }
1463
1464             al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
1465           }
1466         }
1467         if (vamsasSeq[i].getDBRefCount() > 0)
1468         {
1469           addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
1470         }
1471       }
1472     }
1473
1474     /////////////////////////////////
1475     // LOAD SEQUENCE MAPPINGS
1476     if (vamsasSet.getAlcodonFrameCount() > 0)
1477     {
1478       AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
1479       for (int i = 0; i < alc.length; i++)
1480       {
1481         jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
1482                 alc[i].getAlcodonCount());
1483         if (alc[i].getAlcodonCount() > 0)
1484         {
1485           Alcodon[] alcods = alc[i].getAlcodon();
1486           for (int p = 0; p < cf.codons.length; p++)
1487           {
1488             cf.codons[p] = new int[3];
1489             cf.codons[p][0] = (int) alcods[p].getPos1();
1490             cf.codons[p][1] = (int) alcods[p].getPos2();
1491             cf.codons[p][2] = (int) alcods[p].getPos3();
1492           }
1493         }
1494         if (alc[i].getAlcodMapCount() > 0)
1495         {
1496           AlcodMap[] maps = alc[i].getAlcodMap();
1497           for (int m = 0; m < maps.length; m++)
1498           {
1499             SequenceI dnaseq = (SequenceI) seqRefIds
1500                     .get(maps[m].getDnasq());
1501             // Load Mapping
1502             // attach to dna sequence reference.
1503             if (dnaseq != null)
1504             {
1505               if (maps[m].getMapping() != null)
1506               {
1507                 jalview.datamodel.Mapping mapping = addMapping(maps[m]
1508                         .getMapping());
1509                 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
1510               }
1511             }
1512           }
1513         }
1514         al.addCodonFrame(cf);
1515       }
1516
1517     }
1518
1519     //////////////////////////////////
1520     //LOAD ANNOTATIONS
1521     boolean hideQuality = true, hideConservation = true, hideConsensus = true;
1522
1523     if (vamsasSet.getAnnotationCount() > 0)
1524     {
1525       Annotation[] an = vamsasSet.getAnnotation();
1526
1527       for (int i = 0; i < an.length; i++)
1528       {
1529         if (an[i].getLabel().equals("Quality"))
1530         {
1531           hideQuality = false;
1532           continue;
1533         }
1534         else if (an[i].getLabel().equals("Conservation"))
1535         {
1536           hideConservation = false;
1537           continue;
1538         }
1539         else if (an[i].getLabel().equals("Consensus"))
1540         {
1541           hideConsensus = false;
1542           continue;
1543         }
1544
1545         if (an[i].getId() != null
1546                 && annotationIds.containsKey(an[i].getId()))
1547         {
1548           jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
1549                   .get(an[i].getId());
1550           if (an[i].hasVisible())
1551             jda.visible = an[i].getVisible();
1552
1553           al.addAnnotation(jda);
1554
1555           continue;
1556         }
1557
1558         AnnotationElement[] ae = an[i].getAnnotationElement();
1559         jalview.datamodel.Annotation[] anot = null;
1560
1561         if (!an[i].getScoreOnly())
1562         {
1563           anot = new jalview.datamodel.Annotation[al.getWidth()];
1564
1565           for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
1566           {
1567             if (ae[aa].getPosition() >= anot.length)
1568               continue;
1569
1570             anot[ae[aa].getPosition()] = new jalview.datamodel.Annotation(
1571
1572             ae[aa].getDisplayCharacter(), ae[aa].getDescription(), (ae[aa]
1573                     .getSecondaryStructure() == null || ae[aa]
1574                     .getSecondaryStructure().length() == 0) ? ' ' : ae[aa]
1575                     .getSecondaryStructure().charAt(0), ae[aa].getValue()
1576
1577             );
1578
1579             anot[ae[aa].getPosition()].colour = new java.awt.Color(ae[aa]
1580                     .getColour());
1581           }
1582         }
1583         jalview.datamodel.AlignmentAnnotation jaa = null;
1584
1585         if (an[i].getGraph())
1586         {
1587           jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
1588                   an[i].getDescription(), anot, 0, 0, an[i].getGraphType());
1589
1590           jaa.graphGroup = an[i].getGraphGroup();
1591
1592           if (an[i].getThresholdLine() != null)
1593           {
1594             jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
1595                     .getThresholdLine().getValue(), an[i]
1596                     .getThresholdLine().getLabel(), new java.awt.Color(
1597                     an[i].getThresholdLine().getColour())));
1598
1599           }
1600
1601         }
1602         else
1603         {
1604           jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
1605                   an[i].getDescription(), anot);
1606         }
1607
1608         if (an[i].getId() != null)
1609         {
1610           annotationIds.put(an[i].getId(), jaa);
1611           jaa.annotationId = an[i].getId();
1612         }
1613
1614         if (an[i].getSequenceRef() != null)
1615         {
1616           if (al.findName(an[i].getSequenceRef()) != null)
1617           {
1618             jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
1619                     1, true);
1620             al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
1621           }
1622         }
1623         if (an[i].hasScore())
1624         {
1625           jaa.setScore(an[i].getScore());
1626         }
1627
1628         if (an[i].hasVisible())
1629           jaa.visible = an[i].getVisible();
1630
1631         al.addAnnotation(jaa);
1632       }
1633     }
1634
1635     /////////////////////////
1636     //LOAD GROUPS
1637     if (jms.getJGroupCount() > 0)
1638     {
1639       JGroup[] groups = jms.getJGroup();
1640
1641       for (int i = 0; i < groups.length; i++)
1642       {
1643         ColourSchemeI cs = null;
1644
1645         if (groups[i].getColour() != null)
1646         {
1647           if (groups[i].getColour().startsWith("ucs"))
1648           {
1649             cs = GetUserColourScheme(jms, groups[i].getColour());
1650           }
1651           else
1652           {
1653             cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
1654           }
1655
1656           if (cs != null)
1657           {
1658             cs.setThreshold(groups[i].getPidThreshold(), true);
1659           }
1660         }
1661
1662         Vector seqs = new Vector();
1663
1664         for (int s = 0; s < groups[i].getSeqCount(); s++)
1665         {
1666           String seqId = groups[i].getSeq(s) + "";
1667           jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
1668                   .get(seqId);
1669
1670           if (ts != null)
1671           {
1672             seqs.addElement(ts);
1673           }
1674         }
1675
1676         if (seqs.size() < 1)
1677         {
1678           continue;
1679         }
1680
1681         jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
1682                 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
1683                 groups[i].getDisplayText(), groups[i].getColourText(),
1684                 groups[i].getStart(), groups[i].getEnd());
1685
1686         sg
1687                 .setOutlineColour(new java.awt.Color(groups[i]
1688                         .getOutlineColour()));
1689
1690         sg.textColour = new java.awt.Color(groups[i].getTextCol1());
1691         sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
1692         sg.thresholdTextColour = groups[i].getTextColThreshold();
1693
1694         if (groups[i].getConsThreshold() != 0)
1695         {
1696           jalview.analysis.Conservation c = new jalview.analysis.Conservation(
1697                   "All", ResidueProperties.propHash, 3, sg
1698                           .getSequences(null), 0, sg.getWidth() - 1);
1699           c.calculate();
1700           c.verdict(false, 25);
1701           sg.cs.setConservation(c);
1702         }
1703
1704         al.addGroup(sg);
1705       }
1706     }
1707
1708     /////////////////////////////////
1709     // LOAD VIEWPORT
1710
1711     AlignFrame af = new AlignFrame(al, view.getWidth(), view.getHeight());
1712
1713     af.setFileName(file, "Jalview");
1714
1715     for (int i = 0; i < JSEQ.length; i++)
1716     {
1717       af.viewport.setSequenceColour(af.viewport.alignment.getSequenceAt(i),
1718               new java.awt.Color(JSEQ[i].getColour()));
1719     }
1720
1721     //If we just load in the same jar file again, the sequenceSetId
1722     //will be the same, and we end up with multiple references
1723     //to the same sequenceSet. We must modify this id on load
1724     //so that each load of the file gives a unique id
1725     String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
1726
1727     af.viewport.gatherViewsHere = view.getGatheredViews();
1728
1729     if (view.getSequenceSetId() != null)
1730     {
1731       jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
1732               .get(uniqueSeqSetId);
1733
1734       af.viewport.sequenceSetID = uniqueSeqSetId;
1735       if (av != null)
1736       {
1737
1738         af.viewport.historyList = av.historyList;
1739         af.viewport.redoList = av.redoList;
1740       }
1741       else
1742       {
1743         viewportsAdded.put(uniqueSeqSetId, af.viewport);
1744       }
1745
1746       PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
1747     }
1748     if (hiddenSeqs != null)
1749     {
1750       for (int s = 0; s < JSEQ.length; s++)
1751       {
1752         jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
1753
1754         for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
1755         {
1756           hidden.addSequence(al
1757                   .getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
1758         }
1759         af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
1760       }
1761
1762       jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
1763               .size()];
1764
1765       for (int s = 0; s < hiddenSeqs.size(); s++)
1766       {
1767         hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
1768       }
1769
1770       af.viewport.hideSequence(hseqs);
1771
1772     }
1773
1774     if ((hideConsensus || hideQuality || hideConservation)
1775             && al.getAlignmentAnnotation() != null)
1776     {
1777       int hSize = al.getAlignmentAnnotation().length;
1778       for (int h = 0; h < hSize; h++)
1779       {
1780         if ((hideConsensus && al.getAlignmentAnnotation()[h].label
1781                 .equals("Consensus"))
1782                 || (hideQuality && al.getAlignmentAnnotation()[h].label
1783                         .equals("Quality"))
1784                 || (hideConservation && al.getAlignmentAnnotation()[h].label
1785                         .equals("Conservation")))
1786         {
1787           al.deleteAnnotation(al.getAlignmentAnnotation()[h]);
1788           hSize--;
1789           h--;
1790         }
1791       }
1792       af.alignPanel.adjustAnnotationHeight();
1793     }
1794
1795     if (view.getViewName() != null)
1796     {
1797       af.viewport.viewName = view.getViewName();
1798       af.setInitialTabVisible();
1799     }
1800     af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(), view
1801             .getHeight());
1802
1803     af.viewport.setShowAnnotation(view.getShowAnnotation());
1804     af.viewport.setAbovePIDThreshold(view.getPidSelected());
1805
1806     af.viewport.setColourText(view.getShowColourText());
1807
1808     af.viewport.setConservationSelected(view.getConservationSelected());
1809     af.viewport.setShowJVSuffix(view.getShowFullId());
1810     af.viewport.rightAlignIds = view.getRightAlignIds();
1811     af.viewport.setFont(new java.awt.Font(view.getFontName(), view
1812             .getFontStyle(), view.getFontSize()));
1813     af.alignPanel.fontChanged();
1814     af.viewport.setRenderGaps(view.getRenderGaps());
1815     af.viewport.setWrapAlignment(view.getWrapAlignment());
1816     af.alignPanel.setWrapAlignment(view.getWrapAlignment());
1817     af.viewport.setShowAnnotation(view.getShowAnnotation());
1818     af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
1819
1820     af.viewport.setShowBoxes(view.getShowBoxes());
1821
1822     af.viewport.setShowText(view.getShowText());
1823
1824     af.viewport.textColour = new java.awt.Color(view.getTextCol1());
1825     af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
1826     af.viewport.thresholdTextColour = view.getTextColThreshold();
1827
1828     af.viewport.setStartRes(view.getStartRes());
1829     af.viewport.setStartSeq(view.getStartSeq());
1830
1831     ColourSchemeI cs = null;
1832
1833     if (view.getBgColour() != null)
1834     {
1835       if (view.getBgColour().startsWith("ucs"))
1836       {
1837         cs = GetUserColourScheme(jms, view.getBgColour());
1838       }
1839       else if (view.getBgColour().startsWith("Annotation"))
1840       {
1841         //int find annotation
1842         for (int i = 0; i < af.viewport.alignment.getAlignmentAnnotation().length; i++)
1843         {
1844           if (af.viewport.alignment.getAlignmentAnnotation()[i].label
1845                   .equals(view.getAnnotationColours().getAnnotation()))
1846           {
1847             if (af.viewport.alignment.getAlignmentAnnotation()[i]
1848                     .getThreshold() == null)
1849             {
1850               af.viewport.alignment.getAlignmentAnnotation()[i]
1851                       .setThreshold(new jalview.datamodel.GraphLine(view
1852                               .getAnnotationColours().getThreshold(),
1853                               "Threshold", java.awt.Color.black)
1854
1855                       );
1856             }
1857
1858             if (view.getAnnotationColours().getColourScheme()
1859                     .equals("None"))
1860             {
1861               cs = new AnnotationColourGradient(af.viewport.alignment
1862                       .getAlignmentAnnotation()[i], new java.awt.Color(view
1863                       .getAnnotationColours().getMinColour()),
1864                       new java.awt.Color(view.getAnnotationColours()
1865                               .getMaxColour()), view.getAnnotationColours()
1866                               .getAboveThreshold());
1867             }
1868             else if (view.getAnnotationColours().getColourScheme()
1869                     .startsWith("ucs"))
1870             {
1871               cs = new AnnotationColourGradient(af.viewport.alignment
1872                       .getAlignmentAnnotation()[i], GetUserColourScheme(
1873                       jms, view.getAnnotationColours().getColourScheme()),
1874                       view.getAnnotationColours().getAboveThreshold());
1875             }
1876             else
1877             {
1878               cs = new AnnotationColourGradient(af.viewport.alignment
1879                       .getAlignmentAnnotation()[i], ColourSchemeProperty
1880                       .getColour(al, view.getAnnotationColours()
1881                               .getColourScheme()), view
1882                       .getAnnotationColours().getAboveThreshold());
1883             }
1884
1885             // Also use these settings for all the groups
1886             if (al.getGroups() != null)
1887             {
1888               for (int g = 0; g < al.getGroups().size(); g++)
1889               {
1890                 jalview.datamodel.SequenceGroup sg = (jalview.datamodel.SequenceGroup) al
1891                         .getGroups().elementAt(g);
1892
1893                 if (sg.cs == null)
1894                 {
1895                   continue;
1896                 }
1897
1898                 /*    if (view.getAnnotationColours().getColourScheme().equals("None"))
1899                     {
1900                       sg.cs = new AnnotationColourGradient(
1901                           af.viewport.alignment.getAlignmentAnnotation()[i],
1902                           new java.awt.Color(view.getAnnotationColours().
1903                                              getMinColour()),
1904                           new java.awt.Color(view.getAnnotationColours().
1905                                              getMaxColour()),
1906                           view.getAnnotationColours().getAboveThreshold());
1907                     }
1908                     else*/
1909                 {
1910                   sg.cs = new AnnotationColourGradient(
1911                           af.viewport.alignment.getAlignmentAnnotation()[i],
1912                           sg.cs, view.getAnnotationColours()
1913                                   .getAboveThreshold());
1914                 }
1915
1916               }
1917             }
1918
1919             break;
1920           }
1921
1922         }
1923       }
1924       else
1925       {
1926         cs = ColourSchemeProperty.getColour(al, view.getBgColour());
1927       }
1928
1929       if (cs != null)
1930       {
1931         cs.setThreshold(view.getPidThreshold(), true);
1932         cs.setConsensus(af.viewport.hconsensus);
1933       }
1934     }
1935
1936     af.viewport.setGlobalColourScheme(cs);
1937     af.viewport.setColourAppliesToAllGroups(false);
1938
1939     if (view.getConservationSelected() && cs != null)
1940     {
1941       cs.setConservationInc(view.getConsThreshold());
1942     }
1943
1944     af.changeColour(cs);
1945
1946     af.viewport.setColourAppliesToAllGroups(true);
1947
1948     if (view.getShowSequenceFeatures())
1949     {
1950       af.viewport.showSequenceFeatures = true;
1951     }
1952
1953     if (jms.getFeatureSettings() != null)
1954     {
1955       af.viewport.featuresDisplayed = new Hashtable();
1956       String[] renderOrder = new String[jms.getFeatureSettings()
1957               .getSettingCount()];
1958       for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
1959       {
1960         Setting setting = jms.getFeatureSettings().getSetting(fs);
1961
1962         af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
1963                 setting.getType(), new java.awt.Color(setting.getColour()));
1964         renderOrder[fs] = setting.getType();
1965         if (setting.hasOrder())
1966           af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
1967                   setting.getType(), setting.getOrder());
1968         else
1969           af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
1970                   setting.getType(),
1971                   fs / jms.getFeatureSettings().getSettingCount());
1972         if (setting.getDisplay())
1973         {
1974           af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
1975                   setting.getColour()));
1976         }
1977       }
1978       af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
1979       Hashtable fgtable;
1980       af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
1981       for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
1982       {
1983         Group grp = jms.getFeatureSettings().getGroup(gs);
1984         fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
1985       }
1986     }
1987
1988     if (view.getHiddenColumnsCount() > 0)
1989     {
1990       for (int c = 0; c < view.getHiddenColumnsCount(); c++)
1991       {
1992         af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
1993                 .getHiddenColumns(c).getEnd() //+1
1994                 );
1995       }
1996     }
1997
1998     af.setMenusFromViewport(af.viewport);
1999
2000     Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(), view
2001             .getHeight());
2002
2003     //LOAD TREES
2004     ///////////////////////////////////////
2005     if (loadTreesAndStructures && jms.getTreeCount() > 0)
2006     {
2007       try
2008       {
2009         for (int t = 0; t < jms.getTreeCount(); t++)
2010         {
2011
2012           Tree tree = jms.getTree(t);
2013
2014           TreePanel tp = af.ShowNewickTree(new jalview.io.NewickFile(tree
2015                   .getNewick()), tree.getTitle(), tree.getWidth(), tree
2016                   .getHeight(), tree.getXpos(), tree.getYpos());
2017
2018           tp.fitToWindow.setState(tree.getFitToWindow());
2019           tp.fitToWindow_actionPerformed(null);
2020
2021           if (tree.getFontName() != null)
2022           {
2023             tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2024                     .getFontStyle(), tree.getFontSize()));
2025           }
2026           else
2027           {
2028             tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2029                     .getFontStyle(), tree.getFontSize()));
2030           }
2031
2032           tp.showPlaceholders(tree.getMarkUnlinked());
2033           tp.showBootstrap(tree.getShowBootstrap());
2034           tp.showDistances(tree.getShowDistances());
2035
2036           tp.treeCanvas.threshold = tree.getThreshold();
2037
2038           if (tree.getCurrentTree())
2039           {
2040             af.viewport.setCurrentTree(tp.getTree());
2041           }
2042         }
2043
2044       } catch (Exception ex)
2045       {
2046         ex.printStackTrace();
2047       }
2048     }
2049
2050     ////LOAD STRUCTURES
2051     if (loadTreesAndStructures)
2052     {
2053       for (int i = 0; i < JSEQ.length; i++)
2054       {
2055         if (JSEQ[i].getPdbidsCount() > 0)
2056         {
2057           Pdbids[] ids = JSEQ[i].getPdbids();
2058           for (int p = 0; p < ids.length; p++)
2059           {
2060             for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2061             {
2062               jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2063
2064               jpdb.setFile(loadPDBFile(ids[p].getFile(), ids[p].getId()));
2065               jpdb.setId(ids[p].getId());
2066
2067               int x = ids[p].getStructureState(s).getXpos();
2068               int y = ids[p].getStructureState(s).getYpos();
2069               int width = ids[p].getStructureState(s).getWidth();
2070               int height = ids[p].getStructureState(s).getHeight();
2071
2072               java.awt.Component comp = null;
2073
2074               JInternalFrame[] frames = Desktop.desktop.getAllFrames();
2075               for (int f = 0; f < frames.length; f++)
2076               {
2077                 if (frames[f] instanceof AppJmol)
2078                 {
2079                   if (frames[f].getX() == x && frames[f].getY() == y
2080                           && frames[f].getHeight() == height
2081                           && frames[f].getWidth() == width)
2082                   {
2083                     comp = frames[f];
2084                     break;
2085                   }
2086                 }
2087               }
2088
2089               Desktop.desktop.getComponentAt(x, y);
2090
2091               String pdbFile = loadPDBFile(file, ids[p].getId());
2092
2093               jalview.datamodel.SequenceI[] seq = new jalview.datamodel.SequenceI[]
2094               { (jalview.datamodel.SequenceI) seqRefIds.get(JSEQ[i].getId()
2095                       + "") };
2096
2097               if (comp == null)
2098               {
2099                 String state = ids[p].getStructureState(s).getContent();
2100
2101                 StringBuffer newFileLoc = new StringBuffer(state.substring(
2102                         0, state.indexOf("\"", state.indexOf("load")) + 1));
2103
2104                 newFileLoc.append(jpdb.getFile());
2105                 newFileLoc.append(state.substring(state.indexOf("\"", state
2106                         .indexOf("load \"") + 6)));
2107
2108                 new AppJmol(pdbFile, ids[p].getId(), seq, af.alignPanel,
2109                         newFileLoc.toString(), new java.awt.Rectangle(x, y,
2110                                 width, height));
2111
2112               }
2113               else if (comp != null)
2114               {
2115                 StructureSelectionManager.getStructureSelectionManager()
2116                         .setMapping(seq, null, pdbFile,
2117                                 jalview.io.AppletFormatAdapter.FILE);
2118
2119                 ((AppJmol) comp).addSequence(seq);
2120               }
2121             }
2122           }
2123         }
2124       }
2125     }
2126
2127     return af;
2128   }
2129
2130   private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
2131   {
2132     jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
2133     Vector dseqs = null;
2134     if (ds == null)
2135     {
2136       // create a list of new dataset sequences
2137       dseqs = new Vector();
2138     }
2139     for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
2140     {
2141       Sequence vamsasSeq = vamsasSet.getSequence(i);
2142       jalview.datamodel.Sequence sq = null;
2143       String sqid = vamsasSeq.getDsseqid();
2144       if (sqid != null)
2145       {
2146         sq = (jalview.datamodel.Sequence) seqRefIds.get(vamsasSeq
2147                 .getDsseqid());
2148       }
2149       if (sq == null)
2150       {
2151         sq = (jalview.datamodel.Sequence) seqRefIds.get(vamsasSeq.getId());
2152         jalview.datamodel.SequenceI dsq = sq.createDatasetSequence();
2153         if (sqid == null)
2154         {
2155           // make up a new dataset reference for this sequence
2156           sqid = "" + dsq.hashCode();
2157         }
2158         ((SequenceI) dsq).setVamsasId(uniqueSetSuffix + sqid);
2159         seqRefIds.put(sqid, dsq);
2160         if (ds == null)
2161         {
2162           dseqs.addElement(dsq);
2163         }
2164         else
2165         {
2166           ds.addSequence(dsq);
2167         }
2168        
2169       }
2170       // TODO: refactor: This is a low-level sequence operation - effectively merging one dataset sequence into another.
2171       // check that dataset sequence really is the union of all references to it
2172       boolean pre = sq.getStart() < sq.getDatasetSequence().getStart();
2173       boolean post = sq.getEnd() > sq.getDatasetSequence().getEnd();
2174       if (pre || post)
2175       {
2176         SequenceI dsq = sq.getDatasetSequence();
2177         StringBuffer sb = new StringBuffer();
2178         String newres = jalview.analysis.AlignSeq.extractGaps(
2179                 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
2180         synchronized (dsq)
2181         {
2182           sb.append(dsq.getSequence());
2183           if (pre)
2184           {
2185             sb.insert(0, newres
2186                     .substring(0, dsq.getStart() - sq.getStart()));
2187             dsq.setStart(sq.getStart());
2188           }
2189           if (post)
2190           {
2191             sb.append(newres.substring(newres.length() - sq.getEnd()
2192                     - dsq.getEnd()));
2193             dsq.setEnd(sq.getEnd());
2194           }
2195           dsq.setSequence(sb.toString());
2196         }
2197         System.err
2198                 .println("DEBUG Notice:  Merged dataset sequence ("
2199                         + (pre ? "prepended" : "") + " "
2200                         + (post ? "appended" : ""));
2201       }
2202     }
2203     // create a new dataset
2204     if (ds == null)
2205     {
2206       SequenceI[] dsseqs = new SequenceI[dseqs.size()];
2207       dseqs.copyInto(dsseqs);
2208       ds = new jalview.datamodel.Alignment(dsseqs);
2209       addDatasetRef(vamsasSet.getDatasetId(), ds);
2210     }
2211     // set the dataset for the newly imported alignment.
2212     if (al.getDataset() == null)
2213     {
2214       al.setDataset(ds);
2215     }
2216   }
2217
2218   java.util.Hashtable datasetIds = null;
2219
2220   private Alignment getDatasetFor(String datasetId)
2221   {
2222     if (datasetIds == null)
2223     {
2224       datasetIds = new Hashtable();
2225       return null;
2226     }
2227     if (datasetIds.containsKey(datasetId))
2228     {
2229       return (Alignment) datasetIds.get(datasetId);
2230     }
2231     return null;
2232   }
2233
2234   private void addDatasetRef(String datasetId, Alignment dataset)
2235   {
2236     if (datasetIds == null)
2237     {
2238       datasetIds = new Hashtable();
2239     }
2240     datasetIds.put(datasetId, dataset);
2241   }
2242
2243   private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
2244   {
2245     for (int d = 0; d < sequence.getDBRefCount(); d++)
2246     {
2247       DBRef dr = sequence.getDBRef(d);
2248       jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
2249               sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
2250                       .getVersion(), sequence.getDBRef(d).getAccessionId());
2251       if (dr.getMapping() != null)
2252       {
2253         entry.setMap(addMapping(dr.getMapping()));
2254       }
2255       datasetSequence.addDBRef(entry);
2256     }
2257   }
2258
2259   private jalview.datamodel.Mapping addMapping(Mapping m)
2260   {
2261     SequenceI dsto = null;
2262     // Mapping m = dr.getMapping();
2263     int fr[] = new int[m.getMapListFromCount() * 2];
2264     Enumeration f = m.enumerateMapListFrom();
2265     for (int _i = 0; f.hasMoreElements(); _i += 2)
2266     {
2267       MapListFrom mf = (MapListFrom) f.nextElement();
2268       fr[_i] = mf.getStart();
2269       fr[_i + 1] = mf.getEnd();
2270     }
2271     int fto[] = new int[m.getMapListToCount() * 2];
2272     f = m.enumerateMapListTo();
2273     for (int _i = 0; f.hasMoreElements(); _i += 2)
2274     {
2275       MapListTo mf = (MapListTo) f.nextElement();
2276       fto[_i] = mf.getStart();
2277       fto[_i + 1] = mf.getEnd();
2278     }
2279     jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
2280             fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
2281     if (m.getMappingChoice() != null)
2282     {
2283       MappingChoice mc = m.getMappingChoice();
2284       if (mc.getDseqFor() != null)
2285       {
2286         if (seqRefIds.containsKey(mc.getDseqFor()))
2287         {
2288           /**
2289            * recover from hash
2290            */
2291           jmap.setTo((SequenceI) seqRefIds.get(mc.getDseqFor()));
2292         }
2293         else
2294         {
2295           frefedSequence.add(new Object[]
2296           { mc.getDseqFor(), jmap });
2297         }
2298       }
2299       else
2300       {
2301         /**
2302          * make a new sequence and add it to refIds hash
2303          */
2304         Sequence ms = mc.getSequence();
2305         jalview.datamodel.Sequence djs = new jalview.datamodel.Sequence(ms
2306                 .getName(), ms.getSequence());
2307         djs.setStart(jmap.getMap().getToLowest());
2308         djs.setEnd(jmap.getMap().getToHighest());
2309         djs.setVamsasId(uniqueSetSuffix + ms.getId());
2310         jmap.setTo(djs);
2311         seqRefIds.put(ms.getId(), djs);
2312         jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
2313         addDBRefs(djs, ms);
2314       }
2315     }
2316     return (jmap);
2317
2318   }
2319
2320   public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
2321           boolean keepSeqRefs)
2322   {
2323     jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
2324             null, null);
2325
2326     if (!keepSeqRefs)
2327     {
2328       seqRefIds.clear();
2329       jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
2330     }
2331     else
2332     {
2333       uniqueSetSuffix = "";
2334     }
2335
2336     viewportsAdded = new Hashtable();
2337
2338     AlignFrame af = LoadFromObject(jm, null, false);
2339     af.alignPanels.clear();
2340     af.closeMenuItem_actionPerformed(true);
2341
2342     /*  if(ap.av.alignment.getAlignmentAnnotation()!=null)
2343       {
2344         for(int i=0; i<ap.av.alignment.getAlignmentAnnotation().length; i++)
2345         {
2346           if(!ap.av.alignment.getAlignmentAnnotation()[i].autoCalculated)
2347           {
2348             af.alignPanel.av.alignment.getAlignmentAnnotation()[i] =
2349                 ap.av.alignment.getAlignmentAnnotation()[i];
2350           }
2351         }
2352       }   */
2353
2354     return af.alignPanel;
2355   }
2356 }