2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3 * Copyright (C) 2014 The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
23 import java.awt.Rectangle;
25 import java.lang.reflect.InvocationTargetException;
28 import java.util.Map.Entry;
29 import java.util.jar.*;
33 import org.exolab.castor.xml.*;
35 import jalview.bin.Cache;
36 import jalview.datamodel.Alignment;
37 import jalview.datamodel.AlignmentAnnotation;
38 import jalview.datamodel.AlignmentI;
39 import jalview.datamodel.SequenceI;
40 import jalview.schemabinding.version2.*;
41 import jalview.schemes.*;
42 import jalview.util.Platform;
43 import jalview.util.jarInputStreamProvider;
44 import jalview.viewmodel.AlignmentViewport;
45 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
46 import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
47 import jalview.ws.jws2.Jws2Discoverer;
48 import jalview.ws.jws2.dm.AAConSettings;
49 import jalview.ws.jws2.jabaws2.Jws2Instance;
50 import jalview.ws.params.ArgumentI;
51 import jalview.ws.params.AutoCalcSetting;
52 import jalview.ws.params.WsParamSetI;
55 * Write out the current jalview desktop state as a Jalview XML stream.
57 * Note: the vamsas objects referred to here are primitive versions of the
58 * VAMSAS project schema elements - they are not the same and most likely never
62 * @version $Revision: 1.134 $
64 public class Jalview2XML
67 * create/return unique hash string for sq
70 * @return new or existing unique string for sq
72 String seqHash(SequenceI sq)
74 if (seqsToIds == null)
78 if (seqsToIds.containsKey(sq))
80 return (String) seqsToIds.get(sq);
84 // create sequential key
85 String key = "sq" + (seqsToIds.size() + 1);
86 key = makeHashCode(sq, key); // check we don't have an external reference
88 seqsToIds.put(sq, key);
97 if (seqRefIds != null)
101 if (seqsToIds != null)
111 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
112 // seqRefIds = new Hashtable();
113 // seqsToIds = new IdentityHashMap();
119 if (seqsToIds == null)
121 seqsToIds = new IdentityHashMap();
123 if (seqRefIds == null)
125 seqRefIds = new Hashtable();
130 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
131 * of sequence objects are created.
133 java.util.IdentityHashMap seqsToIds = null;
136 * jalview XML Sequence ID to jalview sequence object reference (both dataset
137 * and alignment sequences. Populated as XML reps of sequence objects are
140 java.util.Hashtable seqRefIds = null; // key->SequenceI resolution
142 Vector frefedSequence = null;
144 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
150 public Jalview2XML(boolean raiseGUI)
152 this.raiseGUI = raiseGUI;
155 public void resolveFrefedSequences()
157 if (frefedSequence.size() > 0)
159 int r = 0, rSize = frefedSequence.size();
162 Object[] ref = (Object[]) frefedSequence.elementAt(r);
165 String sref = (String) ref[0];
166 if (seqRefIds.containsKey(sref))
168 if (ref[1] instanceof jalview.datamodel.Mapping)
170 SequenceI seq = (SequenceI) seqRefIds.get(sref);
171 while (seq.getDatasetSequence() != null)
173 seq = seq.getDatasetSequence();
175 ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
179 if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
181 SequenceI seq = (SequenceI) seqRefIds.get(sref);
182 while (seq.getDatasetSequence() != null)
184 seq = seq.getDatasetSequence();
187 && ref[2] instanceof jalview.datamodel.Mapping)
189 jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
190 ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
191 seq, mp.getTo(), mp.getMap());
196 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
197 + ref[2].getClass() + " type objects.");
203 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
204 + ref[1].getClass() + " type objects.");
207 frefedSequence.remove(r);
213 .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
215 + " with objecttype "
216 + ref[1].getClass());
223 frefedSequence.remove(r);
231 * This maintains a list of viewports, the key being the seqSetId. Important
232 * to set historyItem and redoList for multiple views
234 Hashtable viewportsAdded;
236 Hashtable annotationIds = new Hashtable();
238 String uniqueSetSuffix = "";
241 * List of pdbfiles added to Jar
243 Vector pdbfiles = null;
245 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
246 public void SaveState(File statefile)
250 FileOutputStream fos = new FileOutputStream(statefile);
251 JarOutputStream jout = new JarOutputStream(fos);
254 } catch (Exception e)
256 // TODO: inform user of the problem - they need to know if their data was
258 if (errorMessage == null)
260 errorMessage = "Couldn't write Jalview Archive to output file '"
261 + statefile + "' - See console error log for details";
265 errorMessage += "(output file was '" + statefile + "')";
273 * Writes a jalview project archive to the given Jar output stream.
277 public void SaveState(JarOutputStream jout)
279 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
286 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
291 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
292 // //////////////////////////////////////////////////
293 // NOTE ALSO new PrintWriter must be used for each new JarEntry
294 PrintWriter out = null;
296 Vector shortNames = new Vector();
299 for (int i = frames.length - 1; i > -1; i--)
301 if (frames[i] instanceof AlignFrame)
303 AlignFrame af = (AlignFrame) frames[i];
306 && skipList.containsKey(af.getViewport()
307 .getSequenceSetId()))
312 String shortName = af.getTitle();
314 if (shortName.indexOf(File.separatorChar) > -1)
316 shortName = shortName.substring(shortName
317 .lastIndexOf(File.separatorChar) + 1);
322 while (shortNames.contains(shortName))
324 if (shortName.endsWith("_" + (count - 1)))
326 shortName = shortName
327 .substring(0, shortName.lastIndexOf("_"));
330 shortName = shortName.concat("_" + count);
334 shortNames.addElement(shortName);
336 if (!shortName.endsWith(".xml"))
338 shortName = shortName + ".xml";
341 int ap, apSize = af.alignPanels.size();
343 for (ap = 0; ap < apSize; ap++)
345 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
347 String fileName = apSize == 1 ? shortName : ap + shortName;
348 if (!fileName.endsWith(".xml"))
350 fileName = fileName + ".xml";
353 SaveState(apanel, fileName, jout);
355 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
357 if (!dsses.containsKey(dssid))
359 dsses.put(dssid, af);
366 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
372 } catch (Exception foo)
377 } catch (Exception ex)
379 // TODO: inform user of the problem - they need to know if their data was
381 if (errorMessage == null)
383 errorMessage = "Couldn't write Jalview Archive - see error output for details";
385 ex.printStackTrace();
389 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
390 public boolean SaveAlignment(AlignFrame af, String jarFile,
395 int ap, apSize = af.alignPanels.size();
396 FileOutputStream fos = new FileOutputStream(jarFile);
397 JarOutputStream jout = new JarOutputStream(fos);
398 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
399 for (ap = 0; ap < apSize; ap++)
401 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
403 String jfileName = apSize == 1 ? fileName : fileName + ap;
404 if (!jfileName.endsWith(".xml"))
406 jfileName = jfileName + ".xml";
408 SaveState(apanel, jfileName, jout);
409 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
411 if (!dsses.containsKey(dssid))
413 dsses.put(dssid, af);
416 writeDatasetFor(dsses, fileName, jout);
420 } catch (Exception foo)
426 } catch (Exception ex)
428 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
429 ex.printStackTrace();
434 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
435 String fileName, JarOutputStream jout)
438 for (String dssids : dsses.keySet())
440 AlignFrame _af = dsses.get(dssids);
441 String jfileName = fileName + " Dataset for " + _af.getTitle();
442 if (!jfileName.endsWith(".xml"))
444 jfileName = jfileName + ".xml";
446 SaveState(_af.alignPanel, jfileName, true, jout);
451 * create a JalviewModel from an algnment view and marshall it to a
455 * panel to create jalview model for
457 * name of alignment panel written to output stream
463 public JalviewModel SaveState(AlignmentPanel ap, String fileName,
464 JarOutputStream jout)
466 return SaveState(ap, fileName, false, jout);
470 * create a JalviewModel from an algnment view and marshall it to a
474 * panel to create jalview model for
476 * name of alignment panel written to output stream
478 * when true, only write the dataset for the alignment, not the data
479 * associated with the view.
485 public JalviewModel SaveState(AlignmentPanel ap, String fileName,
486 boolean storeDS, JarOutputStream jout)
489 Vector jmolViewIds = new Vector(); //
490 Vector userColours = new Vector();
492 AlignViewport av = ap.av;
494 JalviewModel object = new JalviewModel();
495 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
497 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
498 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
499 "Development Build"));
501 jalview.datamodel.AlignmentI jal = av.getAlignment();
503 if (av.hasHiddenRows())
505 jal = jal.getHiddenSequences().getFullAlignment();
508 SequenceSet vamsasSet = new SequenceSet();
510 JalviewModelSequence jms = new JalviewModelSequence();
512 vamsasSet.setGapChar(jal.getGapCharacter() + "");
514 if (jal.getDataset() != null)
516 // dataset id is the dataset's hashcode
517 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
520 // switch jal and the dataset
521 jal = jal.getDataset();
524 if (jal.getProperties() != null)
526 Enumeration en = jal.getProperties().keys();
527 while (en.hasMoreElements())
529 String key = en.nextElement().toString();
530 SequenceSetProperties ssp = new SequenceSetProperties();
532 ssp.setValue(jal.getProperties().get(key).toString());
533 vamsasSet.addSequenceSetProperties(ssp);
538 Set<String> calcIdSet = new HashSet<String>();
542 jalview.datamodel.SequenceI jds, jdatasq;
543 for (int i = 0; i < jal.getHeight(); i++)
545 jds = jal.getSequenceAt(i);
546 jdatasq = jds.getDatasetSequence() == null ? jds : jds
547 .getDatasetSequence();
550 if (seqRefIds.get(id) != null)
552 // This happens for two reasons: 1. multiple views are being serialised.
553 // 2. the hashCode has collided with another sequence's code. This DOES
554 // HAPPEN! (PF00072.15.stk does this)
555 // JBPNote: Uncomment to debug writing out of files that do not read
556 // back in due to ArrayOutOfBoundExceptions.
557 // System.err.println("vamsasSeq backref: "+id+"");
558 // System.err.println(jds.getName()+"
559 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
560 // System.err.println("Hashcode: "+seqHash(jds));
561 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
562 // System.err.println(rsq.getName()+"
563 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
564 // System.err.println("Hashcode: "+seqHash(rsq));
568 vamsasSeq = createVamsasSequence(id, jds);
569 vamsasSet.addSequence(vamsasSeq);
570 seqRefIds.put(id, jds);
574 jseq.setStart(jds.getStart());
575 jseq.setEnd(jds.getEnd());
576 jseq.setColour(av.getSequenceColour(jds).getRGB());
578 jseq.setId(id); // jseq id should be a string not a number
581 // Store any sequences this sequence represents
582 if (av.hasHiddenRows())
584 jseq.setHidden(av.getAlignment().getHiddenSequences()
587 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
589 jalview.datamodel.SequenceI[] reps = av
590 .getRepresentedSequences(jal.getSequenceAt(i))
591 .getSequencesInOrder(jal);
593 for (int h = 0; h < reps.length; h++)
595 if (reps[h] != jal.getSequenceAt(i))
597 jseq.addHiddenSequences(jal.findIndex(reps[h]));
604 if (jdatasq.getSequenceFeatures() != null)
606 jalview.datamodel.SequenceFeature[] sf = jdatasq
607 .getSequenceFeatures();
609 while (index < sf.length)
611 Features features = new Features();
613 features.setBegin(sf[index].getBegin());
614 features.setEnd(sf[index].getEnd());
615 features.setDescription(sf[index].getDescription());
616 features.setType(sf[index].getType());
617 features.setFeatureGroup(sf[index].getFeatureGroup());
618 features.setScore(sf[index].getScore());
619 if (sf[index].links != null)
621 for (int l = 0; l < sf[index].links.size(); l++)
623 OtherData keyValue = new OtherData();
624 keyValue.setKey("LINK_" + l);
625 keyValue.setValue(sf[index].links.elementAt(l).toString());
626 features.addOtherData(keyValue);
629 if (sf[index].otherDetails != null)
632 Enumeration keys = sf[index].otherDetails.keys();
633 while (keys.hasMoreElements())
635 key = keys.nextElement().toString();
636 OtherData keyValue = new OtherData();
637 keyValue.setKey(key);
638 keyValue.setValue(sf[index].otherDetails.get(key).toString());
639 features.addOtherData(keyValue);
643 jseq.addFeatures(features);
648 if (jdatasq.getPDBId() != null)
650 Enumeration en = jdatasq.getPDBId().elements();
651 while (en.hasMoreElements())
653 Pdbids pdb = new Pdbids();
654 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
657 pdb.setId(entry.getId());
658 pdb.setType(entry.getType());
660 // store any JMol views associated with this seqeunce
661 // this section copes with duplicate entries in the project, so a
662 // dataset only view *should* be coped with sensibly
664 // This must have been loaded, is it still visible?
665 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
666 String matchedFile = null;
667 for (int f = frames.length - 1; f > -1; f--)
669 if (frames[f] instanceof AppJmol)
671 jmol = (AppJmol) frames[f];
672 for (int peid = 0; peid < jmol.jmb.pdbentry.length; peid++)
674 if (!jmol.jmb.pdbentry[peid].getId().equals(entry.getId())
675 && !(entry.getId().length() > 4 && entry
679 jmol.jmb.pdbentry[peid].getId()
682 if (matchedFile == null)
684 matchedFile = jmol.jmb.pdbentry[peid].getFile();
686 else if (!matchedFile.equals(jmol.jmb.pdbentry[peid]
690 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
691 + jmol.jmb.pdbentry[peid].getFile());
695 // can get at it if the ID
696 // match is ambiguous (e.g.
698 String statestring = jmol.jmb.viewer.getStateInfo();
700 for (int smap = 0; smap < jmol.jmb.sequence[peid].length; smap++)
702 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
703 if (jds == jmol.jmb.sequence[peid][smap])
705 StructureState state = new StructureState();
706 state.setVisible(true);
707 state.setXpos(jmol.getX());
708 state.setYpos(jmol.getY());
709 state.setWidth(jmol.getWidth());
710 state.setHeight(jmol.getHeight());
711 state.setViewId(jmol.getViewId());
712 state.setAlignwithAlignPanel(jmol.isUsedforaligment(ap));
713 state.setColourwithAlignPanel(jmol
714 .isUsedforcolourby(ap));
715 state.setColourByJmol(jmol.isColouredByJmol());
716 if (!jmolViewIds.contains(state.getViewId()))
718 // Make sure we only store a Jmol state once in each XML
720 jmolViewIds.addElement(state.getViewId());
721 state.setContent(statestring.replaceAll("\n", ""));
725 state.setContent("# duplicate state");
727 pdb.addStructureState(state);
735 if (matchedFile != null || entry.getFile() != null)
737 if (entry.getFile() != null)
740 matchedFile = entry.getFile();
742 pdb.setFile(matchedFile); // entry.getFile());
743 if (pdbfiles == null)
745 pdbfiles = new Vector();
748 if (!pdbfiles.contains(entry.getId()))
750 pdbfiles.addElement(entry.getId());
753 File file = new File(matchedFile);
754 if (file.exists() && jout != null)
756 byte[] data = new byte[(int) file.length()];
757 jout.putNextEntry(new JarEntry(entry.getId()));
758 DataInputStream dis = new DataInputStream(
759 new FileInputStream(file));
762 DataOutputStream dout = new DataOutputStream(jout);
763 dout.write(data, 0, data.length);
767 } catch (Exception ex)
769 ex.printStackTrace();
775 if (entry.getProperty() != null)
777 PdbentryItem item = new PdbentryItem();
778 Hashtable properties = entry.getProperty();
779 Enumeration en2 = properties.keys();
780 while (en2.hasMoreElements())
782 Property prop = new Property();
783 String key = en2.nextElement().toString();
785 prop.setValue(properties.get(key).toString());
786 item.addProperty(prop);
788 pdb.addPdbentryItem(item);
798 if (!storeDS && av.hasHiddenRows())
800 jal = av.getAlignment();
803 if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0)
805 jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames();
806 for (int i = 0; i < jac.length; i++)
808 AlcodonFrame alc = new AlcodonFrame();
809 vamsasSet.addAlcodonFrame(alc);
810 for (int p = 0; p < jac[i].aaWidth; p++)
812 Alcodon cmap = new Alcodon();
813 if (jac[i].codons[p] != null)
815 // Null codons indicate a gapped column in the translated peptide
817 cmap.setPos1(jac[i].codons[p][0]);
818 cmap.setPos2(jac[i].codons[p][1]);
819 cmap.setPos3(jac[i].codons[p][2]);
821 alc.addAlcodon(cmap);
823 if (jac[i].getProtMappings() != null
824 && jac[i].getProtMappings().length > 0)
826 SequenceI[] dnas = jac[i].getdnaSeqs();
827 jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings();
828 for (int m = 0; m < pmaps.length; m++)
830 AlcodMap alcmap = new AlcodMap();
831 alcmap.setDnasq(seqHash(dnas[m]));
832 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
834 alc.addAlcodMap(alcmap);
841 // /////////////////////////////////
842 if (!storeDS && av.currentTree != null)
844 // FIND ANY ASSOCIATED TREES
845 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
846 if (Desktop.desktop != null)
848 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
850 for (int t = 0; t < frames.length; t++)
852 if (frames[t] instanceof TreePanel)
854 TreePanel tp = (TreePanel) frames[t];
856 if (tp.treeCanvas.av.getAlignment() == jal)
858 Tree tree = new Tree();
859 tree.setTitle(tp.getTitle());
860 tree.setCurrentTree((av.currentTree == tp.getTree()));
861 tree.setNewick(tp.getTree().toString());
862 tree.setThreshold(tp.treeCanvas.threshold);
864 tree.setFitToWindow(tp.fitToWindow.getState());
865 tree.setFontName(tp.getTreeFont().getName());
866 tree.setFontSize(tp.getTreeFont().getSize());
867 tree.setFontStyle(tp.getTreeFont().getStyle());
868 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
870 tree.setShowBootstrap(tp.bootstrapMenu.getState());
871 tree.setShowDistances(tp.distanceMenu.getState());
873 tree.setHeight(tp.getHeight());
874 tree.setWidth(tp.getWidth());
875 tree.setXpos(tp.getX());
876 tree.setYpos(tp.getY());
877 tree.setId(makeHashCode(tp, null));
886 * store forward refs from an annotationRow to any groups
888 IdentityHashMap groupRefs = new IdentityHashMap();
891 for (SequenceI sq : jal.getSequences())
893 // Store annotation on dataset sequences only
894 jalview.datamodel.AlignmentAnnotation[] aa = sq.getAnnotation();
895 if (aa != null && aa.length > 0)
897 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
904 if (jal.getAlignmentAnnotation() != null)
906 // Store the annotation shown on the alignment.
907 jalview.datamodel.AlignmentAnnotation[] aa = jal
908 .getAlignmentAnnotation();
909 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
914 if (jal.getGroups() != null)
916 JGroup[] groups = new JGroup[jal.getGroups().size()];
918 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
920 groups[++i] = new JGroup();
922 groups[i].setStart(sg.getStartRes());
923 groups[i].setEnd(sg.getEndRes());
924 groups[i].setName(sg.getName());
925 if (groupRefs.containsKey(sg))
927 // group has references so set it's ID field
928 groups[i].setId(groupRefs.get(sg).toString());
932 if (sg.cs.conservationApplied())
934 groups[i].setConsThreshold(sg.cs.getConservationInc());
936 if (sg.cs instanceof jalview.schemes.UserColourScheme)
938 groups[i].setColour(SetUserColourScheme(sg.cs, userColours,
944 .setColour(ColourSchemeProperty.getColourName(sg.cs));
947 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
949 groups[i].setColour("AnnotationColourGradient");
950 groups[i].setAnnotationColours(constructAnnotationColours(
951 (jalview.schemes.AnnotationColourGradient) sg.cs,
954 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
957 .setColour(SetUserColourScheme(sg.cs, userColours, jms));
961 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
964 groups[i].setPidThreshold(sg.cs.getThreshold());
967 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
968 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
969 groups[i].setDisplayText(sg.getDisplayText());
970 groups[i].setColourText(sg.getColourText());
971 groups[i].setTextCol1(sg.textColour.getRGB());
972 groups[i].setTextCol2(sg.textColour2.getRGB());
973 groups[i].setTextColThreshold(sg.thresholdTextColour);
974 groups[i].setShowUnconserved(sg.getShowNonconserved());
975 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
976 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
977 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
978 groups[i].setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
979 for (int s = 0; s < sg.getSize(); s++)
981 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
983 groups[i].addSeq(seqHash(seq));
987 jms.setJGroup(groups);
991 // /////////SAVE VIEWPORT
992 Viewport view = new Viewport();
993 view.setTitle(ap.alignFrame.getTitle());
994 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
995 av.getSequenceSetId()));
996 view.setId(av.getViewId());
997 view.setViewName(av.viewName);
998 view.setGatheredViews(av.gatherViewsHere);
1000 if (ap.av.explodedPosition != null)
1002 view.setXpos(av.explodedPosition.x);
1003 view.setYpos(av.explodedPosition.y);
1004 view.setWidth(av.explodedPosition.width);
1005 view.setHeight(av.explodedPosition.height);
1009 view.setXpos(ap.alignFrame.getBounds().x);
1010 view.setYpos(ap.alignFrame.getBounds().y);
1011 view.setWidth(ap.alignFrame.getBounds().width);
1012 view.setHeight(ap.alignFrame.getBounds().height);
1015 view.setStartRes(av.startRes);
1016 view.setStartSeq(av.startSeq);
1018 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1020 view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(),
1023 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1025 AnnotationColours ac = constructAnnotationColours(
1026 (jalview.schemes.AnnotationColourGradient) av
1027 .getGlobalColourScheme(),
1030 view.setAnnotationColours(ac);
1031 view.setBgColour("AnnotationColourGradient");
1035 view.setBgColour(ColourSchemeProperty.getColourName(av
1036 .getGlobalColourScheme()));
1039 ColourSchemeI cs = av.getGlobalColourScheme();
1043 if (cs.conservationApplied())
1045 view.setConsThreshold(cs.getConservationInc());
1046 if (cs instanceof jalview.schemes.UserColourScheme)
1048 view.setBgColour(SetUserColourScheme(cs, userColours, jms));
1052 if (cs instanceof ResidueColourScheme)
1054 view.setPidThreshold(cs.getThreshold());
1058 view.setConservationSelected(av.getConservationSelected());
1059 view.setPidSelected(av.getAbovePIDThreshold());
1060 view.setFontName(av.font.getName());
1061 view.setFontSize(av.font.getSize());
1062 view.setFontStyle(av.font.getStyle());
1063 view.setRenderGaps(av.renderGaps);
1064 view.setShowAnnotation(av.getShowAnnotation());
1065 view.setShowBoxes(av.getShowBoxes());
1066 view.setShowColourText(av.getColourText());
1067 view.setShowFullId(av.getShowJVSuffix());
1068 view.setRightAlignIds(av.rightAlignIds);
1069 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1070 view.setShowText(av.getShowText());
1071 view.setShowUnconserved(av.getShowUnconserved());
1072 view.setWrapAlignment(av.getWrapAlignment());
1073 view.setTextCol1(av.textColour.getRGB());
1074 view.setTextCol2(av.textColour2.getRGB());
1075 view.setTextColThreshold(av.thresholdTextColour);
1076 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1077 view.setShowSequenceLogo(av.isShowSequenceLogo());
1078 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1079 view.setShowGroupConsensus(av.isShowGroupConsensus());
1080 view.setShowGroupConservation(av.isShowGroupConservation());
1081 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1082 view.setShowDbRefTooltip(av.isShowDbRefs());
1083 view.setFollowHighlight(av.followHighlight);
1084 view.setFollowSelection(av.followSelection);
1085 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1086 if (av.getFeaturesDisplayed() != null)
1088 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1090 String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1091 .getRenderOrder().toArray(new String[0]);
1093 Vector settingsAdded = new Vector();
1094 Object gstyle = null;
1095 GraduatedColor gcol = null;
1096 if (renderOrder != null)
1098 for (int ro = 0; ro < renderOrder.length; ro++)
1100 gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer()
1101 .getFeatureStyle(renderOrder[ro]);
1102 Setting setting = new Setting();
1103 setting.setType(renderOrder[ro]);
1104 if (gstyle instanceof GraduatedColor)
1106 gcol = (GraduatedColor) gstyle;
1107 setting.setColour(gcol.getMaxColor().getRGB());
1108 setting.setMincolour(gcol.getMinColor().getRGB());
1109 setting.setMin(gcol.getMin());
1110 setting.setMax(gcol.getMax());
1111 setting.setColourByLabel(gcol.isColourByLabel());
1112 setting.setAutoScale(gcol.isAutoScale());
1113 setting.setThreshold(gcol.getThresh());
1114 setting.setThreshstate(gcol.getThreshType());
1118 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1119 .getColour(renderOrder[ro]).getRGB());
1122 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1124 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1125 .getOrder(renderOrder[ro]);
1128 setting.setOrder(rorder);
1130 fs.addSetting(setting);
1131 settingsAdded.addElement(renderOrder[ro]);
1135 // Make sure we save none displayed feature settings
1136 Iterator en = ap.seqPanel.seqCanvas.getFeatureRenderer()
1137 .getFeatureColours().keySet().iterator();
1138 while (en.hasNext())
1140 String key = en.next().toString();
1141 if (settingsAdded.contains(key))
1146 Setting setting = new Setting();
1147 setting.setType(key);
1148 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1149 .getColour(key).getRGB());
1151 setting.setDisplay(false);
1152 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1156 setting.setOrder(rorder);
1158 fs.addSetting(setting);
1159 settingsAdded.addElement(key);
1161 // is groups actually supposed to be a map here ?
1162 en = ap.seqPanel.seqCanvas.getFeatureRenderer().getFeatureGroups()
1164 Vector groupsAdded = new Vector();
1165 while (en.hasNext())
1167 String grp = en.next().toString();
1168 if (groupsAdded.contains(grp))
1172 Group g = new Group();
1174 g.setDisplay(((Boolean) ap.seqPanel.seqCanvas
1175 .getFeatureRenderer().checkGroupVisibility(grp, false))
1178 groupsAdded.addElement(grp);
1180 jms.setFeatureSettings(fs);
1184 if (av.hasHiddenColumns())
1186 if (av.getColumnSelection() == null
1187 || av.getColumnSelection().getHiddenColumns() == null)
1189 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1193 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1196 int[] region = (int[]) av.getColumnSelection()
1197 .getHiddenColumns().elementAt(c);
1198 HiddenColumns hc = new HiddenColumns();
1199 hc.setStart(region[0]);
1200 hc.setEnd(region[1]);
1201 view.addHiddenColumns(hc);
1205 if (calcIdSet.size() > 0)
1207 for (String calcId : calcIdSet)
1209 if (calcId.trim().length() > 0)
1211 CalcIdParam cidp = createCalcIdParam(calcId, av);
1212 // Some calcIds have no parameters.
1215 view.addCalcIdParam(cidp);
1221 jms.addViewport(view);
1223 object.setJalviewModelSequence(jms);
1224 object.getVamsasModel().addSequenceSet(vamsasSet);
1226 if (jout != null && fileName != null)
1228 // We may not want to write the object to disk,
1229 // eg we can copy the alignViewport to a new view object
1230 // using save and then load
1233 JarEntry entry = new JarEntry(fileName);
1234 jout.putNextEntry(entry);
1235 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1237 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1239 marshaller.marshal(object);
1242 } catch (Exception ex)
1244 // TODO: raise error in GUI if marshalling failed.
1245 ex.printStackTrace();
1251 private AnnotationColours constructAnnotationColours(
1252 AnnotationColourGradient acg, Vector userColours,
1253 JalviewModelSequence jms)
1255 AnnotationColours ac = new AnnotationColours();
1256 ac.setAboveThreshold(acg.getAboveThreshold());
1257 ac.setThreshold(acg.getAnnotationThreshold());
1258 ac.setAnnotation(acg.getAnnotation());
1259 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1261 ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
1266 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1270 ac.setMaxColour(acg.getMaxColour().getRGB());
1271 ac.setMinColour(acg.getMinColour().getRGB());
1272 ac.setPerSequence(acg.isSeqAssociated());
1273 ac.setPredefinedColours(acg.isPredefinedColours());
1277 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1278 IdentityHashMap groupRefs, AlignmentViewport av,
1279 Set<String> calcIdSet, boolean storeDS, SequenceSet vamsasSet)
1282 for (int i = 0; i < aa.length; i++)
1284 Annotation an = new Annotation();
1286 if (aa[i].annotationId != null)
1288 annotationIds.put(aa[i].annotationId, aa[i]);
1291 an.setId(aa[i].annotationId);
1293 an.setVisible(aa[i].visible);
1295 an.setDescription(aa[i].description);
1297 if (aa[i].sequenceRef != null)
1299 // TODO later annotation sequenceRef should be the XML ID of the
1300 // sequence rather than its display name
1301 an.setSequenceRef(aa[i].sequenceRef.getName());
1303 if (aa[i].groupRef != null)
1305 Object groupIdr = groupRefs.get(aa[i].groupRef);
1306 if (groupIdr == null)
1308 // make a locally unique String
1309 groupRefs.put(aa[i].groupRef,
1310 groupIdr = ("" + System.currentTimeMillis()
1311 + aa[i].groupRef.getName() + groupRefs.size()));
1313 an.setGroupRef(groupIdr.toString());
1316 // store all visualization attributes for annotation
1317 an.setGraphHeight(aa[i].graphHeight);
1318 an.setCentreColLabels(aa[i].centreColLabels);
1319 an.setScaleColLabels(aa[i].scaleColLabel);
1320 an.setShowAllColLabels(aa[i].showAllColLabels);
1321 an.setBelowAlignment(aa[i].belowAlignment);
1323 if (aa[i].graph > 0)
1326 an.setGraphType(aa[i].graph);
1327 an.setGraphGroup(aa[i].graphGroup);
1328 if (aa[i].getThreshold() != null)
1330 ThresholdLine line = new ThresholdLine();
1331 line.setLabel(aa[i].getThreshold().label);
1332 line.setValue(aa[i].getThreshold().value);
1333 line.setColour(aa[i].getThreshold().colour.getRGB());
1334 an.setThresholdLine(line);
1342 an.setLabel(aa[i].label);
1344 if (aa[i] == av.getAlignmentQualityAnnot()
1345 || aa[i] == av.getAlignmentConservationAnnotation()
1346 || aa[i] == av.getAlignmentConsensusAnnotation()
1347 || aa[i].autoCalculated)
1349 // new way of indicating autocalculated annotation -
1350 an.setAutoCalculated(aa[i].autoCalculated);
1352 if (aa[i].hasScore())
1354 an.setScore(aa[i].getScore());
1357 if (aa[i].getCalcId() != null)
1359 calcIdSet.add(aa[i].getCalcId());
1360 an.setCalcId(aa[i].getCalcId());
1363 AnnotationElement ae;
1364 if (aa[i].annotations != null)
1366 an.setScoreOnly(false);
1367 for (int a = 0; a < aa[i].annotations.length; a++)
1369 if ((aa[i] == null) || (aa[i].annotations[a] == null))
1374 ae = new AnnotationElement();
1375 if (aa[i].annotations[a].description != null)
1376 ae.setDescription(aa[i].annotations[a].description);
1377 if (aa[i].annotations[a].displayCharacter != null)
1378 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
1380 if (!Float.isNaN(aa[i].annotations[a].value))
1381 ae.setValue(aa[i].annotations[a].value);
1384 if (aa[i].annotations[a].secondaryStructure != ' '
1385 && aa[i].annotations[a].secondaryStructure != '\0')
1386 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
1389 if (aa[i].annotations[a].colour != null
1390 && aa[i].annotations[a].colour != java.awt.Color.black)
1392 ae.setColour(aa[i].annotations[a].colour.getRGB());
1395 an.addAnnotationElement(ae);
1396 if (aa[i].autoCalculated)
1398 // only write one non-null entry into the annotation row -
1399 // sufficient to get the visualization attributes necessary to
1407 an.setScoreOnly(true);
1409 if (!storeDS || (storeDS && !aa[i].autoCalculated))
1411 // skip autocalculated annotation - these are only provided for
1413 vamsasSet.addAnnotation(an);
1419 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1421 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1422 if (settings != null)
1424 CalcIdParam vCalcIdParam = new CalcIdParam();
1425 vCalcIdParam.setCalcId(calcId);
1426 vCalcIdParam.addServiceURL(settings.getServiceURI());
1427 // generic URI allowing a third party to resolve another instance of the
1428 // service used for this calculation
1429 for (String urls : settings.getServiceURLs())
1431 vCalcIdParam.addServiceURL(urls);
1433 vCalcIdParam.setVersion("1.0");
1434 if (settings.getPreset() != null)
1436 WsParamSetI setting = settings.getPreset();
1437 vCalcIdParam.setName(setting.getName());
1438 vCalcIdParam.setDescription(setting.getDescription());
1442 vCalcIdParam.setName("");
1443 vCalcIdParam.setDescription("Last used parameters");
1445 // need to be able to recover 1) settings 2) user-defined presets or
1446 // recreate settings from preset 3) predefined settings provided by
1447 // service - or settings that can be transferred (or discarded)
1448 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1450 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1451 // todo - decide if updateImmediately is needed for any projects.
1453 return vCalcIdParam;
1458 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1461 if (calcIdParam.getVersion().equals("1.0"))
1463 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1464 .getPreferredServiceFor(calcIdParam.getServiceURL());
1465 if (service != null)
1467 WsParamSetI parmSet = null;
1470 parmSet = service.getParamStore().parseServiceParameterFile(
1471 calcIdParam.getName(), calcIdParam.getDescription(),
1472 calcIdParam.getServiceURL(),
1473 calcIdParam.getParameters().replace("|\\n|", "\n"));
1474 } catch (IOException x)
1476 warn("Couldn't parse parameter data for "
1477 + calcIdParam.getCalcId(), x);
1480 List<ArgumentI> argList = null;
1481 if (calcIdParam.getName().length() > 0)
1483 parmSet = service.getParamStore()
1484 .getPreset(calcIdParam.getName());
1485 if (parmSet != null)
1487 // TODO : check we have a good match with settings in AACon -
1488 // otherwise we'll need to create a new preset
1493 argList = parmSet.getArguments();
1496 AAConSettings settings = new AAConSettings(
1497 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1498 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1499 calcIdParam.isNeedsUpdate());
1504 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1508 throw new Error("Unsupported Version for calcIdparam "
1509 + calcIdParam.toString());
1513 * External mapping between jalview objects and objects yielding a valid and
1514 * unique object ID string. This is null for normal Jalview project IO, but
1515 * non-null when a jalview project is being read or written as part of a
1518 IdentityHashMap jv2vobj = null;
1521 * Construct a unique ID for jvobj using either existing bindings or if none
1522 * exist, the result of the hashcode call for the object.
1525 * jalview data object
1526 * @return unique ID for referring to jvobj
1528 private String makeHashCode(Object jvobj, String altCode)
1530 if (jv2vobj != null)
1532 Object id = jv2vobj.get(jvobj);
1535 return id.toString();
1537 // check string ID mappings
1538 if (jvids2vobj != null && jvobj instanceof String)
1540 id = jvids2vobj.get(jvobj);
1544 return id.toString();
1546 // give up and warn that something has gone wrong
1547 warn("Cannot find ID for object in external mapping : " + jvobj);
1553 * return local jalview object mapped to ID, if it exists
1557 * @return null or object bound to idcode
1559 private Object retrieveExistingObj(String idcode)
1561 if (idcode != null && vobj2jv != null)
1563 return vobj2jv.get(idcode);
1569 * binding from ID strings from external mapping table to jalview data model
1572 private Hashtable vobj2jv;
1574 private Sequence createVamsasSequence(String id, SequenceI jds)
1576 return createVamsasSequence(true, id, jds, null);
1579 private Sequence createVamsasSequence(boolean recurse, String id,
1580 SequenceI jds, SequenceI parentseq)
1582 Sequence vamsasSeq = new Sequence();
1583 vamsasSeq.setId(id);
1584 vamsasSeq.setName(jds.getName());
1585 vamsasSeq.setSequence(jds.getSequenceAsString());
1586 vamsasSeq.setDescription(jds.getDescription());
1587 jalview.datamodel.DBRefEntry[] dbrefs = null;
1588 if (jds.getDatasetSequence() != null)
1590 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1591 if (jds.getDatasetSequence().getDBRef() != null)
1593 dbrefs = jds.getDatasetSequence().getDBRef();
1598 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1599 // dataset sequences only
1600 dbrefs = jds.getDBRef();
1604 for (int d = 0; d < dbrefs.length; d++)
1606 DBRef dbref = new DBRef();
1607 dbref.setSource(dbrefs[d].getSource());
1608 dbref.setVersion(dbrefs[d].getVersion());
1609 dbref.setAccessionId(dbrefs[d].getAccessionId());
1610 if (dbrefs[d].hasMap())
1612 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1614 dbref.setMapping(mp);
1616 vamsasSeq.addDBRef(dbref);
1622 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1623 SequenceI parentseq, SequenceI jds, boolean recurse)
1626 if (jmp.getMap() != null)
1630 jalview.util.MapList mlst = jmp.getMap();
1631 int r[] = mlst.getFromRanges();
1632 for (int s = 0; s < r.length; s += 2)
1634 MapListFrom mfrom = new MapListFrom();
1635 mfrom.setStart(r[s]);
1636 mfrom.setEnd(r[s + 1]);
1637 mp.addMapListFrom(mfrom);
1639 r = mlst.getToRanges();
1640 for (int s = 0; s < r.length; s += 2)
1642 MapListTo mto = new MapListTo();
1644 mto.setEnd(r[s + 1]);
1645 mp.addMapListTo(mto);
1647 mp.setMapFromUnit(mlst.getFromRatio());
1648 mp.setMapToUnit(mlst.getToRatio());
1649 if (jmp.getTo() != null)
1651 MappingChoice mpc = new MappingChoice();
1653 && (parentseq != jmp.getTo() || parentseq
1654 .getDatasetSequence() != jmp.getTo()))
1656 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1662 SequenceI ps = null;
1663 if (parentseq != jmp.getTo()
1664 && parentseq.getDatasetSequence() != jmp.getTo())
1666 // chaining dbref rather than a handshaking one
1667 jmpid = seqHash(ps = jmp.getTo());
1671 jmpid = seqHash(ps = parentseq);
1673 mpc.setDseqFor(jmpid);
1674 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1676 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1677 seqRefIds.put(mpc.getDseqFor(), ps);
1681 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1684 mp.setMappingChoice(mpc);
1690 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1691 Vector userColours, JalviewModelSequence jms)
1694 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1695 boolean newucs = false;
1696 if (!userColours.contains(ucs))
1698 userColours.add(ucs);
1701 id = "ucs" + userColours.indexOf(ucs);
1704 // actually create the scheme's entry in the XML model
1705 java.awt.Color[] colours = ucs.getColours();
1706 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1707 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1709 for (int i = 0; i < colours.length; i++)
1711 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1712 col.setName(ResidueProperties.aa[i]);
1713 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1714 jbucs.addColour(col);
1716 if (ucs.getLowerCaseColours() != null)
1718 colours = ucs.getLowerCaseColours();
1719 for (int i = 0; i < colours.length; i++)
1721 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1722 col.setName(ResidueProperties.aa[i].toLowerCase());
1723 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1724 jbucs.addColour(col);
1729 uc.setUserColourScheme(jbucs);
1730 jms.addUserColours(uc);
1736 jalview.schemes.UserColourScheme GetUserColourScheme(
1737 JalviewModelSequence jms, String id)
1739 UserColours[] uc = jms.getUserColours();
1740 UserColours colours = null;
1742 for (int i = 0; i < uc.length; i++)
1744 if (uc[i].getId().equals(id))
1752 java.awt.Color[] newColours = new java.awt.Color[24];
1754 for (int i = 0; i < 24; i++)
1756 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1757 .getUserColourScheme().getColour(i).getRGB(), 16));
1760 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1763 if (colours.getUserColourScheme().getColourCount() > 24)
1765 newColours = new java.awt.Color[23];
1766 for (int i = 0; i < 23; i++)
1768 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1769 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1771 ucs.setLowerCaseColours(newColours);
1778 * contains last error message (if any) encountered by XML loader.
1780 String errorMessage = null;
1783 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1784 * exceptions are raised during project XML parsing
1786 public boolean attemptversion1parse = true;
1789 * Load a jalview project archive from a jar file
1792 * - HTTP URL or filename
1794 public AlignFrame LoadJalviewAlign(final String file)
1797 jalview.gui.AlignFrame af = null;
1801 // create list to store references for any new Jmol viewers created
1802 newStructureViewers = new Vector<AppJmol>();
1803 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1804 // Workaround is to make sure caller implements the JarInputStreamProvider
1806 // so we can re-open the jar input stream for each entry.
1808 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1809 af = LoadJalviewAlign(jprovider);
1811 } catch (MalformedURLException e)
1813 errorMessage = "Invalid URL format for '" + file + "'";
1819 SwingUtilities.invokeAndWait(new Runnable()
1823 setLoadingFinishedForNewStructureViewers();
1826 } catch (Exception x)
1834 private jarInputStreamProvider createjarInputStreamProvider(
1835 final String file) throws MalformedURLException
1838 errorMessage = null;
1839 uniqueSetSuffix = null;
1841 viewportsAdded = null;
1842 frefedSequence = null;
1844 if (file.startsWith("http://"))
1846 url = new URL(file);
1848 final URL _url = url;
1849 return new jarInputStreamProvider()
1853 public JarInputStream getJarInputStream() throws IOException
1857 return new JarInputStream(_url.openStream());
1861 return new JarInputStream(new FileInputStream(file));
1866 public String getFilename()
1874 * Recover jalview session from a jalview project archive. Caller may
1875 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1876 * themselves. Any null fields will be initialised with default values,
1877 * non-null fields are left alone.
1882 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1884 errorMessage = null;
1885 if (uniqueSetSuffix == null)
1887 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1889 if (seqRefIds == null)
1891 seqRefIds = new Hashtable();
1893 if (viewportsAdded == null)
1895 viewportsAdded = new Hashtable();
1897 if (frefedSequence == null)
1899 frefedSequence = new Vector();
1902 jalview.gui.AlignFrame af = null, _af = null;
1903 Hashtable gatherToThisFrame = new Hashtable();
1904 final String file = jprovider.getFilename();
1907 JarInputStream jin = null;
1908 JarEntry jarentry = null;
1913 jin = jprovider.getJarInputStream();
1914 for (int i = 0; i < entryCount; i++)
1916 jarentry = jin.getNextJarEntry();
1919 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1921 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1922 JalviewModel object = new JalviewModel();
1924 Unmarshaller unmar = new Unmarshaller(object);
1925 unmar.setValidation(false);
1926 object = (JalviewModel) unmar.unmarshal(in);
1927 if (true) // !skipViewport(object))
1929 _af = LoadFromObject(object, file, true, jprovider);
1930 if (object.getJalviewModelSequence().getViewportCount() > 0)
1933 if (af.viewport.gatherViewsHere)
1935 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
1941 else if (jarentry != null)
1943 // Some other file here.
1946 } while (jarentry != null);
1947 resolveFrefedSequences();
1948 } catch (java.io.FileNotFoundException ex)
1950 ex.printStackTrace();
1951 errorMessage = "Couldn't locate Jalview XML file : " + file;
1952 System.err.println("Exception whilst loading jalview XML file : "
1954 } catch (java.net.UnknownHostException ex)
1956 ex.printStackTrace();
1957 errorMessage = "Couldn't locate Jalview XML file : " + file;
1958 System.err.println("Exception whilst loading jalview XML file : "
1960 } catch (Exception ex)
1962 System.err.println("Parsing as Jalview Version 2 file failed.");
1963 ex.printStackTrace(System.err);
1964 if (attemptversion1parse)
1966 // Is Version 1 Jar file?
1969 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
1970 } catch (Exception ex2)
1972 System.err.println("Exception whilst loading as jalviewXMLV1:");
1973 ex2.printStackTrace();
1977 if (Desktop.instance != null)
1979 Desktop.instance.stopLoading();
1983 System.out.println("Successfully loaded archive file");
1986 ex.printStackTrace();
1988 System.err.println("Exception whilst loading jalview XML file : "
1990 } catch (OutOfMemoryError e)
1992 // Don't use the OOM Window here
1993 errorMessage = "Out of memory loading jalview XML file";
1994 System.err.println("Out of memory whilst loading jalview XML file");
1995 e.printStackTrace();
1998 if (Desktop.instance != null)
2000 Desktop.instance.stopLoading();
2003 Enumeration en = gatherToThisFrame.elements();
2004 while (en.hasMoreElements())
2006 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
2008 if (errorMessage != null)
2016 * check errorMessage for a valid error message and raise an error box in the
2017 * GUI or write the current errorMessage to stderr and then clear the error
2020 protected void reportErrors()
2022 reportErrors(false);
2025 protected void reportErrors(final boolean saving)
2027 if (errorMessage != null)
2029 final String finalErrorMessage = errorMessage;
2032 javax.swing.SwingUtilities.invokeLater(new Runnable()
2037 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2038 finalErrorMessage, "Error "
2039 + (saving ? "saving" : "loading")
2040 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2046 System.err.println("Problem loading Jalview file: " + errorMessage);
2049 errorMessage = null;
2052 Hashtable alreadyLoadedPDB;
2055 * when set, local views will be updated from view stored in JalviewXML
2056 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2057 * sync if this is set to true.
2059 private final boolean updateLocalViews = false;
2061 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2063 if (alreadyLoadedPDB == null)
2064 alreadyLoadedPDB = new Hashtable();
2066 if (alreadyLoadedPDB.containsKey(pdbId))
2067 return alreadyLoadedPDB.get(pdbId).toString();
2071 JarInputStream jin = jprovider.getJarInputStream();
2073 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2074 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2075 * FileInputStream(jprovider)); }
2078 JarEntry entry = null;
2081 entry = jin.getNextJarEntry();
2082 } while (entry != null && !entry.getName().equals(pdbId));
2085 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
2086 File outFile = File.createTempFile("jalview_pdb", ".txt");
2087 outFile.deleteOnExit();
2088 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
2091 while ((data = in.readLine()) != null)
2098 } catch (Exception foo)
2103 String t = outFile.getAbsolutePath();
2104 alreadyLoadedPDB.put(pdbId, t);
2109 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
2111 } catch (Exception ex)
2113 ex.printStackTrace();
2119 private class JvAnnotRow
2121 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2128 * persisted version of annotation row from which to take vis properties
2130 public jalview.datamodel.AlignmentAnnotation template;
2133 * original position of the annotation row in the alignment
2139 * Load alignment frame from jalview XML DOM object
2144 * filename source string
2145 * @param loadTreesAndStructures
2146 * when false only create Viewport
2148 * data source provider
2149 * @return alignment frame created from view stored in DOM
2151 AlignFrame LoadFromObject(JalviewModel object, String file,
2152 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2154 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2155 Sequence[] vamsasSeq = vamsasSet.getSequence();
2157 JalviewModelSequence jms = object.getJalviewModelSequence();
2159 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2162 // ////////////////////////////////
2165 Vector hiddenSeqs = null;
2166 jalview.datamodel.Sequence jseq;
2168 ArrayList tmpseqs = new ArrayList();
2170 boolean multipleView = false;
2172 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
2173 int vi = 0; // counter in vamsasSeq array
2174 for (int i = 0; i < JSEQ.length; i++)
2176 String seqId = JSEQ[i].getId();
2178 if (seqRefIds.get(seqId) != null)
2180 tmpseqs.add(seqRefIds.get(seqId));
2181 multipleView = true;
2185 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2186 vamsasSeq[vi].getSequence());
2187 jseq.setDescription(vamsasSeq[vi].getDescription());
2188 jseq.setStart(JSEQ[i].getStart());
2189 jseq.setEnd(JSEQ[i].getEnd());
2190 jseq.setVamsasId(uniqueSetSuffix + seqId);
2191 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2196 if (JSEQ[i].getHidden())
2198 if (hiddenSeqs == null)
2200 hiddenSeqs = new Vector();
2203 hiddenSeqs.addElement(seqRefIds.get(seqId));
2209 // Create the alignment object from the sequence set
2210 // ///////////////////////////////
2211 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2214 tmpseqs.toArray(orderedSeqs);
2216 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2219 // / Add the alignment properties
2220 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2222 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2223 al.setProperty(ssp.getKey(), ssp.getValue());
2227 // SequenceFeatures are added to the DatasetSequence,
2228 // so we must create or recover the dataset before loading features
2229 // ///////////////////////////////
2230 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2232 // older jalview projects do not have a dataset id.
2233 al.setDataset(null);
2237 recoverDatasetFor(vamsasSet, al);
2239 // ///////////////////////////////
2241 Hashtable pdbloaded = new Hashtable();
2244 // load sequence features, database references and any associated PDB
2245 // structures for the alignment
2246 for (int i = 0; i < vamsasSeq.length; i++)
2248 if (JSEQ[i].getFeaturesCount() > 0)
2250 Features[] features = JSEQ[i].getFeatures();
2251 for (int f = 0; f < features.length; f++)
2253 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2254 features[f].getType(), features[f].getDescription(),
2255 features[f].getStatus(), features[f].getBegin(),
2256 features[f].getEnd(), features[f].getFeatureGroup());
2258 sf.setScore(features[f].getScore());
2259 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2261 OtherData keyValue = features[f].getOtherData(od);
2262 if (keyValue.getKey().startsWith("LINK"))
2264 sf.addLink(keyValue.getValue());
2268 sf.setValue(keyValue.getKey(), keyValue.getValue());
2273 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2276 if (vamsasSeq[i].getDBRefCount() > 0)
2278 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2280 if (JSEQ[i].getPdbidsCount() > 0)
2282 Pdbids[] ids = JSEQ[i].getPdbids();
2283 for (int p = 0; p < ids.length; p++)
2285 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2286 entry.setId(ids[p].getId());
2287 entry.setType(ids[p].getType());
2288 if (ids[p].getFile() != null)
2290 if (!pdbloaded.containsKey(ids[p].getFile()))
2292 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2296 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2300 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2304 } // end !multipleview
2306 // ///////////////////////////////
2307 // LOAD SEQUENCE MAPPINGS
2309 if (vamsasSet.getAlcodonFrameCount() > 0)
2311 // TODO Potentially this should only be done once for all views of an
2313 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2314 for (int i = 0; i < alc.length; i++)
2316 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2317 alc[i].getAlcodonCount());
2318 if (alc[i].getAlcodonCount() > 0)
2320 Alcodon[] alcods = alc[i].getAlcodon();
2321 for (int p = 0; p < cf.codons.length; p++)
2323 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2324 && alcods[p].hasPos3())
2326 // translated codons require three valid positions
2327 cf.codons[p] = new int[3];
2328 cf.codons[p][0] = (int) alcods[p].getPos1();
2329 cf.codons[p][1] = (int) alcods[p].getPos2();
2330 cf.codons[p][2] = (int) alcods[p].getPos3();
2334 cf.codons[p] = null;
2338 if (alc[i].getAlcodMapCount() > 0)
2340 AlcodMap[] maps = alc[i].getAlcodMap();
2341 for (int m = 0; m < maps.length; m++)
2343 SequenceI dnaseq = (SequenceI) seqRefIds
2344 .get(maps[m].getDnasq());
2346 jalview.datamodel.Mapping mapping = null;
2347 // attach to dna sequence reference.
2348 if (maps[m].getMapping() != null)
2350 mapping = addMapping(maps[m].getMapping());
2354 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2359 frefedSequence.add(new Object[]
2360 { maps[m].getDnasq(), cf, mapping });
2364 al.addCodonFrame(cf);
2369 // ////////////////////////////////
2371 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2373 * store any annotations which forward reference a group's ID
2375 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2377 if (vamsasSet.getAnnotationCount() > 0)
2379 Annotation[] an = vamsasSet.getAnnotation();
2381 for (int i = 0; i < an.length; i++)
2384 * test if annotation is automatically calculated for this view only
2386 boolean autoForView = false;
2387 if (an[i].getLabel().equals("Quality")
2388 || an[i].getLabel().equals("Conservation")
2389 || an[i].getLabel().equals("Consensus"))
2391 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2393 if (!an[i].hasAutoCalculated())
2395 an[i].setAutoCalculated(true);
2399 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2401 // remove ID - we don't recover annotation from other views for
2402 // view-specific annotation
2406 // set visiblity for other annotation in this view
2407 if (an[i].getId() != null
2408 && annotationIds.containsKey(an[i].getId()))
2410 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2411 .get(an[i].getId());
2412 // in principle Visible should always be true for annotation displayed
2413 // in multiple views
2414 if (an[i].hasVisible())
2415 jda.visible = an[i].getVisible();
2417 al.addAnnotation(jda);
2421 // Construct new annotation from model.
2422 AnnotationElement[] ae = an[i].getAnnotationElement();
2423 jalview.datamodel.Annotation[] anot = null;
2424 java.awt.Color firstColour = null;
2426 if (!an[i].getScoreOnly())
2428 anot = new jalview.datamodel.Annotation[al.getWidth()];
2429 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2431 anpos = ae[aa].getPosition();
2433 if (anpos >= anot.length)
2436 anot[anpos] = new jalview.datamodel.Annotation(
2438 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2439 (ae[aa].getSecondaryStructure() == null || ae[aa]
2440 .getSecondaryStructure().length() == 0) ? ' '
2441 : ae[aa].getSecondaryStructure().charAt(0),
2445 // JBPNote: Consider verifying dataflow for IO of secondary
2446 // structure annotation read from Stockholm files
2447 // this was added to try to ensure that
2448 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2450 // anot[ae[aa].getPosition()].displayCharacter = "";
2452 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2453 if (firstColour == null)
2455 firstColour = anot[anpos].colour;
2459 jalview.datamodel.AlignmentAnnotation jaa = null;
2461 if (an[i].getGraph())
2463 float llim = 0, hlim = 0;
2464 // if (autoForView || an[i].isAutoCalculated()) {
2467 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2468 an[i].getDescription(), anot, llim, hlim,
2469 an[i].getGraphType());
2471 jaa.graphGroup = an[i].getGraphGroup();
2472 jaa._linecolour = firstColour;
2473 if (an[i].getThresholdLine() != null)
2475 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2476 .getThresholdLine().getValue(), an[i]
2477 .getThresholdLine().getLabel(), new java.awt.Color(
2478 an[i].getThresholdLine().getColour())));
2481 if (autoForView || an[i].isAutoCalculated())
2483 // Hardwire the symbol display line to ensure that labels for
2484 // histograms are displayed
2490 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2491 an[i].getDescription(), anot);
2492 jaa._linecolour = firstColour;
2494 // register new annotation
2495 if (an[i].getId() != null)
2497 annotationIds.put(an[i].getId(), jaa);
2498 jaa.annotationId = an[i].getId();
2500 // recover sequence association
2501 if (an[i].getSequenceRef() != null)
2503 if (al.findName(an[i].getSequenceRef()) != null)
2505 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2507 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2510 // and make a note of any group association
2511 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2513 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2514 .get(an[i].getGroupRef());
2517 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2518 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2523 if (an[i].hasScore())
2525 jaa.setScore(an[i].getScore());
2527 if (an[i].hasVisible())
2528 jaa.visible = an[i].getVisible();
2530 if (an[i].hasCentreColLabels())
2531 jaa.centreColLabels = an[i].getCentreColLabels();
2533 if (an[i].hasScaleColLabels())
2535 jaa.scaleColLabel = an[i].getScaleColLabels();
2537 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2539 // newer files have an 'autoCalculated' flag and store calculation
2540 // state in viewport properties
2541 jaa.autoCalculated = true; // means annotation will be marked for
2542 // update at end of load.
2544 if (an[i].hasGraphHeight())
2546 jaa.graphHeight = an[i].getGraphHeight();
2548 if (an[i].hasBelowAlignment())
2550 jaa.belowAlignment = an[i].isBelowAlignment();
2552 jaa.setCalcId(an[i].getCalcId());
2554 if (jaa.autoCalculated)
2556 autoAlan.add(new JvAnnotRow(i, jaa));
2559 // if (!autoForView)
2561 // add autocalculated group annotation and any user created annotation
2563 al.addAnnotation(jaa);
2567 // ///////////////////////
2569 // Create alignment markup and styles for this view
2570 if (jms.getJGroupCount() > 0)
2572 JGroup[] groups = jms.getJGroup();
2573 boolean addAnnotSchemeGroup = false;
2574 for (int i = 0; i < groups.length; i++)
2576 ColourSchemeI cs = null;
2578 if (groups[i].getColour() != null)
2580 if (groups[i].getColour().startsWith("ucs"))
2582 cs = GetUserColourScheme(jms, groups[i].getColour());
2584 else if (groups[i].getColour().equals("AnnotationColourGradient")
2585 && groups[i].getAnnotationColours() != null)
2587 addAnnotSchemeGroup = true;
2592 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2597 cs.setThreshold(groups[i].getPidThreshold(), true);
2601 Vector seqs = new Vector();
2603 for (int s = 0; s < groups[i].getSeqCount(); s++)
2605 String seqId = groups[i].getSeq(s) + "";
2606 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2611 seqs.addElement(ts);
2615 if (seqs.size() < 1)
2620 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2621 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2622 groups[i].getDisplayText(), groups[i].getColourText(),
2623 groups[i].getStart(), groups[i].getEnd());
2625 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2627 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2628 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2629 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2630 .isShowUnconserved() : false);
2631 sg.thresholdTextColour = groups[i].getTextColThreshold();
2632 if (groups[i].hasShowConsensusHistogram())
2634 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2637 if (groups[i].hasShowSequenceLogo())
2639 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2641 if (groups[i].hasNormaliseSequenceLogo())
2643 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2645 if (groups[i].hasIgnoreGapsinConsensus())
2647 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2649 if (groups[i].getConsThreshold() != 0)
2651 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2652 "All", ResidueProperties.propHash, 3,
2653 sg.getSequences(null), 0, sg.getWidth() - 1);
2655 c.verdict(false, 25);
2656 sg.cs.setConservation(c);
2659 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2661 // re-instate unique group/annotation row reference
2662 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2663 .get(groups[i].getId());
2666 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2669 if (jaa.autoCalculated)
2671 // match up and try to set group autocalc alignment row for this
2673 if (jaa.label.startsWith("Consensus for "))
2675 sg.setConsensus(jaa);
2677 // match up and try to set group autocalc alignment row for this
2679 if (jaa.label.startsWith("Conservation for "))
2681 sg.setConservationRow(jaa);
2688 if (addAnnotSchemeGroup)
2690 // reconstruct the annotation colourscheme
2691 sg.cs = constructAnnotationColour(
2692 groups[i].getAnnotationColours(), null, al, jms, false);
2698 // only dataset in this model, so just return.
2701 // ///////////////////////////////
2704 // If we just load in the same jar file again, the sequenceSetId
2705 // will be the same, and we end up with multiple references
2706 // to the same sequenceSet. We must modify this id on load
2707 // so that each load of the file gives a unique id
2708 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2709 String viewId = (view.getId() == null ? null : view.getId()
2711 AlignFrame af = null;
2712 AlignViewport av = null;
2713 // now check to see if we really need to create a new viewport.
2714 if (multipleView && viewportsAdded.size() == 0)
2716 // We recovered an alignment for which a viewport already exists.
2717 // TODO: fix up any settings necessary for overlaying stored state onto
2718 // state recovered from another document. (may not be necessary).
2719 // we may need a binding from a viewport in memory to one recovered from
2721 // and then recover its containing af to allow the settings to be applied.
2722 // TODO: fix for vamsas demo
2724 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2726 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2727 if (seqsetobj != null)
2729 if (seqsetobj instanceof String)
2731 uniqueSeqSetId = (String) seqsetobj;
2733 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2739 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2745 * indicate that annotation colours are applied across all groups (pre
2746 * Jalview 2.8.1 behaviour)
2748 boolean doGroupAnnColour = isVersionStringLaterThan("2.8.1",
2749 object.getVersion());
2751 AlignmentPanel ap = null;
2752 boolean isnewview = true;
2755 // Check to see if this alignment already has a view id == viewId
2756 jalview.gui.AlignmentPanel views[] = Desktop
2757 .getAlignmentPanels(uniqueSeqSetId);
2758 if (views != null && views.length > 0)
2760 for (int v = 0; v < views.length; v++)
2762 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2764 // recover the existing alignpanel, alignframe, viewport
2765 af = views[v].alignFrame;
2768 // TODO: could even skip resetting view settings if we don't want to
2769 // change the local settings from other jalview processes
2778 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2779 uniqueSeqSetId, viewId, autoAlan);
2784 // /////////////////////////////////////
2785 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2789 for (int t = 0; t < jms.getTreeCount(); t++)
2792 Tree tree = jms.getTree(t);
2794 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2797 tp = af.ShowNewickTree(
2798 new jalview.io.NewickFile(tree.getNewick()),
2799 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2800 tree.getXpos(), tree.getYpos());
2801 if (tree.getId() != null)
2803 // perhaps bind the tree id to something ?
2808 // update local tree attributes ?
2809 // TODO: should check if tp has been manipulated by user - if so its
2810 // settings shouldn't be modified
2811 tp.setTitle(tree.getTitle());
2812 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2813 .getWidth(), tree.getHeight()));
2814 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2817 tp.treeCanvas.av = av; // af.viewport;
2818 tp.treeCanvas.ap = ap; // af.alignPanel;
2823 warn("There was a problem recovering stored Newick tree: \n"
2824 + tree.getNewick());
2828 tp.fitToWindow.setState(tree.getFitToWindow());
2829 tp.fitToWindow_actionPerformed(null);
2831 if (tree.getFontName() != null)
2833 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2834 .getFontStyle(), tree.getFontSize()));
2838 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2839 .getFontStyle(), tree.getFontSize()));
2842 tp.showPlaceholders(tree.getMarkUnlinked());
2843 tp.showBootstrap(tree.getShowBootstrap());
2844 tp.showDistances(tree.getShowDistances());
2846 tp.treeCanvas.threshold = tree.getThreshold();
2848 if (tree.getCurrentTree())
2850 af.viewport.setCurrentTree(tp.getTree());
2854 } catch (Exception ex)
2856 ex.printStackTrace();
2860 // //LOAD STRUCTURES
2861 if (loadTreesAndStructures)
2863 // run through all PDB ids on the alignment, and collect mappings between
2864 // jmol view ids and all sequences referring to it
2865 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2867 for (int i = 0; i < JSEQ.length; i++)
2869 if (JSEQ[i].getPdbidsCount() > 0)
2871 Pdbids[] ids = JSEQ[i].getPdbids();
2872 for (int p = 0; p < ids.length; p++)
2874 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2876 // check to see if we haven't already created this structure view
2877 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2878 : ids[p].getStructureState(s).getViewId()
2880 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2881 // Originally : ids[p].getFile()
2882 // : TODO: verify external PDB file recovery still works in normal
2883 // jalview project load
2884 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2885 jpdb.setId(ids[p].getId());
2887 int x = ids[p].getStructureState(s).getXpos();
2888 int y = ids[p].getStructureState(s).getYpos();
2889 int width = ids[p].getStructureState(s).getWidth();
2890 int height = ids[p].getStructureState(s).getHeight();
2892 // Probably don't need to do this anymore...
2893 // Desktop.desktop.getComponentAt(x, y);
2894 // TODO: NOW: check that this recovers the PDB file correctly.
2895 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2896 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2897 .get(JSEQ[i].getId() + "");
2898 if (sviewid == null)
2900 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2903 if (!jmolViewIds.containsKey(sviewid))
2905 jmolViewIds.put(sviewid, new Object[]
2907 { x, y, width, height }, "",
2908 new Hashtable<String, Object[]>(), new boolean[]
2909 { false, false, true } });
2910 // Legacy pre-2.7 conversion JAL-823 :
2911 // do not assume any view has to be linked for colour by
2915 // assemble String[] { pdb files }, String[] { id for each
2916 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2917 // seqs_file 2}, boolean[] {
2918 // linkAlignPanel,superposeWithAlignpanel}} from hash
2919 Object[] jmoldat = jmolViewIds.get(sviewid);
2920 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2921 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
2922 s).getAlignwithAlignPanel() : false;
2923 // never colour by linked panel if not specified
2924 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
2925 .hasColourwithAlignPanel() ? ids[p]
2926 .getStructureState(s).getColourwithAlignPanel()
2928 // default for pre-2.7 projects is that Jmol colouring is enabled
2929 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
2930 .hasColourByJmol() ? ids[p].getStructureState(s)
2931 .getColourByJmol() : true;
2933 if (((String) jmoldat[1]).length() < ids[p]
2934 .getStructureState(s).getContent().length())
2937 jmoldat[1] = ids[p].getStructureState(s).getContent();
2940 if (ids[p].getFile() != null)
2942 File mapkey = new File(ids[p].getFile());
2943 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
2945 if (seqstrmaps == null)
2947 ((Hashtable) jmoldat[2]).put(mapkey,
2948 seqstrmaps = new Object[]
2949 { pdbFile, ids[p].getId(), new Vector(),
2952 if (!((Vector) seqstrmaps[2]).contains(seq))
2954 ((Vector) seqstrmaps[2]).addElement(seq);
2955 // ((Vector)seqstrmaps[3]).addElement(n) :
2956 // in principle, chains
2957 // should be stored here : do we need to
2958 // TODO: store and recover seq/pdb_id :
2964 errorMessage = ("The Jmol views in this project were imported\nfrom an older version of Jalview.\nPlease review the sequence colour associations\nin the Colour by section of the Jmol View menu.\n\nIn the case of problems, see note at\nhttp://issues.jalview.org/browse/JAL-747");
2973 // Instantiate the associated Jmol views
2974 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
2976 String sviewid = entry.getKey();
2977 Object[] svattrib = entry.getValue();
2978 int[] geom = (int[]) svattrib[0];
2979 String state = (String) svattrib[1];
2980 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
2981 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
2982 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
2983 // collate the pdbfile -> sequence mappings from this view
2984 Vector<String> pdbfilenames = new Vector<String>();
2985 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
2986 Vector<String> pdbids = new Vector<String>();
2988 // Search to see if we've already created this Jmol view
2989 AppJmol comp = null;
2990 JInternalFrame[] frames = null;
2995 frames = Desktop.desktop.getAllFrames();
2996 } catch (ArrayIndexOutOfBoundsException e)
2998 // occasional No such child exceptions are thrown here...
3003 } catch (Exception f)
3008 } while (frames == null);
3009 // search for any Jmol windows already open from other
3010 // alignment views that exactly match the stored structure state
3011 for (int f = 0; comp == null && f < frames.length; f++)
3013 if (frames[f] instanceof AppJmol)
3016 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
3018 // post jalview 2.4 schema includes structure view id
3019 comp = (AppJmol) frames[f];
3021 else if (frames[f].getX() == x && frames[f].getY() == y
3022 && frames[f].getHeight() == height
3023 && frames[f].getWidth() == width)
3025 comp = (AppJmol) frames[f];
3032 // create a new Jmol window.
3033 // First parse the Jmol state to translate filenames loaded into the
3034 // view, and record the order in which files are shown in the Jmol
3035 // view, so we can add the sequence mappings in same order.
3036 StringBuffer newFileLoc = null;
3037 int cp = 0, ncp, ecp;
3038 while ((ncp = state.indexOf("load ", cp)) > -1)
3040 if (newFileLoc == null)
3042 newFileLoc = new StringBuffer();
3046 // look for next filename in load statement
3047 newFileLoc.append(state.substring(cp,
3048 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3049 String oldfilenam = state.substring(ncp,
3050 ecp = state.indexOf("\"", ncp));
3051 // recover the new mapping data for this old filename
3052 // have to normalize filename - since Jmol and jalview do
3054 // translation differently.
3055 Object[] filedat = oldFiles.get(new File(oldfilenam));
3056 newFileLoc.append(Platform
3057 .escapeString((String) filedat[0]));
3058 pdbfilenames.addElement((String) filedat[0]);
3059 pdbids.addElement((String) filedat[1]);
3060 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3061 .toArray(new SequenceI[0]));
3062 newFileLoc.append("\"");
3063 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3064 // look for next file statement.
3065 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3069 // just append rest of state
3070 newFileLoc.append(state.substring(cp));
3075 .print("Ignoring incomplete Jmol state for PDB ids: ");
3076 newFileLoc = new StringBuffer(state);
3077 newFileLoc.append("; load append ");
3078 for (File id : oldFiles.keySet())
3080 // add this and any other pdb files that should be present in
3082 Object[] filedat = oldFiles.get(id);
3084 newFileLoc.append(((String) filedat[0]));
3085 pdbfilenames.addElement((String) filedat[0]);
3086 pdbids.addElement((String) filedat[1]);
3087 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3088 .toArray(new SequenceI[0]));
3089 newFileLoc.append(" \"");
3090 newFileLoc.append((String) filedat[0]);
3091 newFileLoc.append("\"");
3094 newFileLoc.append(";");
3097 if (newFileLoc != null)
3099 int histbug = newFileLoc.indexOf("history = ");
3101 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
3103 String val = (diff == -1) ? null : newFileLoc.substring(
3105 if (val != null && val.length() >= 4)
3107 if (val.contains("e"))
3109 if (val.trim().equals("true"))
3117 newFileLoc.replace(histbug, diff, val);
3120 // TODO: assemble String[] { pdb files }, String[] { id for each
3121 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3122 // seqs_file 2}} from hash
3123 final String[] pdbf = pdbfilenames
3124 .toArray(new String[pdbfilenames.size()]), id = pdbids
3125 .toArray(new String[pdbids.size()]);
3126 final SequenceI[][] sq = seqmaps
3127 .toArray(new SequenceI[seqmaps.size()][]);
3128 final String fileloc = newFileLoc.toString(), vid = sviewid;
3129 final AlignFrame alf = af;
3130 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
3134 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3139 AppJmol sview = null;
3142 sview = new AppJmol(pdbf, id, sq, alf.alignPanel,
3143 useinJmolsuperpos, usetoColourbyseq,
3144 jmolColouring, fileloc, rect, vid);
3145 addNewStructureViewer(sview);
3146 } catch (OutOfMemoryError ex)
3148 new OOMWarning("restoring structure view for PDB id "
3149 + id, (OutOfMemoryError) ex.getCause());
3150 if (sview != null && sview.isVisible())
3152 sview.closeViewer();
3153 sview.setVisible(false);
3159 } catch (InvocationTargetException ex)
3161 warn("Unexpected error when opening Jmol view.", ex);
3163 } catch (InterruptedException e)
3165 // e.printStackTrace();
3171 // if (comp != null)
3173 // NOTE: if the jalview project is part of a shared session then
3174 // view synchronization should/could be done here.
3176 // add mapping for sequences in this view to an already open Jmol
3178 for (File id : oldFiles.keySet())
3180 // add this and any other pdb files that should be present in the
3182 Object[] filedat = oldFiles.get(id);
3183 String pdbFile = (String) filedat[0];
3184 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3185 .toArray(new SequenceI[0]);
3186 comp.jmb.ssm.setMapping(seq, null, pdbFile,
3187 jalview.io.AppletFormatAdapter.FILE);
3188 comp.jmb.addSequenceForStructFile(pdbFile, seq);
3190 // and add the AlignmentPanel's reference to the Jmol view
3191 comp.addAlignmentPanel(ap);
3192 if (useinJmolsuperpos)
3194 comp.useAlignmentPanelForSuperposition(ap);
3198 comp.excludeAlignmentPanelForSuperposition(ap);
3200 if (usetoColourbyseq)
3202 comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3206 comp.excludeAlignmentPanelForColourbyseq(ap);
3212 // and finally return.
3219 * - minimum version we are comparing against
3221 * - version of data being processsed.
3222 * @return true if version is development/null or evaluates to the same or
3223 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
3225 private boolean isVersionStringLaterThan(String supported, String version)
3227 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
3228 || version.equalsIgnoreCase("Test")
3229 || version.equalsIgnoreCase("AUTOMATED BUILD"))
3231 System.err.println("Assuming project file with "
3232 + (version == null ? "null" : version)
3233 + " is compatible with Jalview version " + supported);
3238 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
3240 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
3242 // convert b to decimal to catch bugfix releases within a series
3243 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
3244 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
3247 if (Float.valueOf(curT) > Float.valueOf(fileT))
3249 // current version is newer than the version that wrote the file
3252 } catch (NumberFormatException nfe)
3255 .println("** WARNING: Version comparison failed for tokens ("
3259 + ")\n** Current: '"
3260 + supported + "' and Version: '" + version + "'");
3263 if (currentV.hasMoreElements())
3265 // fileV has no minor version but identical series to current
3272 Vector<AppJmol> newStructureViewers = null;
3274 protected void addNewStructureViewer(AppJmol sview)
3276 if (newStructureViewers != null)
3278 sview.jmb.setFinishedLoadingFromArchive(false);
3279 newStructureViewers.add(sview);
3283 protected void setLoadingFinishedForNewStructureViewers()
3285 if (newStructureViewers != null)
3287 for (AppJmol sview : newStructureViewers)
3289 sview.jmb.setFinishedLoadingFromArchive(true);
3291 newStructureViewers.clear();
3292 newStructureViewers = null;
3296 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3297 Alignment al, JalviewModelSequence jms, Viewport view,
3298 String uniqueSeqSetId, String viewId,
3299 ArrayList<JvAnnotRow> autoAlan)
3301 AlignFrame af = null;
3302 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3303 uniqueSeqSetId, viewId);
3305 af.setFileName(file, "Jalview");
3307 for (int i = 0; i < JSEQ.length; i++)
3309 af.viewport.setSequenceColour(af.viewport.getAlignment()
3310 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3313 af.viewport.gatherViewsHere = view.getGatheredViews();
3315 if (view.getSequenceSetId() != null)
3317 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3318 .get(uniqueSeqSetId);
3320 af.viewport.setSequenceSetId(uniqueSeqSetId);
3323 // propagate shared settings to this new view
3324 af.viewport.historyList = av.historyList;
3325 af.viewport.redoList = av.redoList;
3329 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3331 // TODO: check if this method can be called repeatedly without
3332 // side-effects if alignpanel already registered.
3333 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3335 // apply Hidden regions to view.
3336 if (hiddenSeqs != null)
3338 for (int s = 0; s < JSEQ.length; s++)
3340 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3342 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3345 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3347 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3350 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3353 for (int s = 0; s < hiddenSeqs.size(); s++)
3355 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3358 af.viewport.hideSequence(hseqs);
3361 // recover view properties and display parameters
3362 if (view.getViewName() != null)
3364 af.viewport.viewName = view.getViewName();
3365 af.setInitialTabVisible();
3367 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3370 af.viewport.setShowAnnotation(view.getShowAnnotation());
3371 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3373 af.viewport.setColourText(view.getShowColourText());
3375 af.viewport.setConservationSelected(view.getConservationSelected());
3376 af.viewport.setShowJVSuffix(view.getShowFullId());
3377 af.viewport.rightAlignIds = view.getRightAlignIds();
3378 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3379 .getFontStyle(), view.getFontSize()));
3380 af.alignPanel.fontChanged();
3381 af.viewport.setRenderGaps(view.getRenderGaps());
3382 af.viewport.setWrapAlignment(view.getWrapAlignment());
3383 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3384 af.viewport.setShowAnnotation(view.getShowAnnotation());
3385 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3387 af.viewport.setShowBoxes(view.getShowBoxes());
3389 af.viewport.setShowText(view.getShowText());
3391 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3392 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3393 af.viewport.thresholdTextColour = view.getTextColThreshold();
3394 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3395 .isShowUnconserved() : false);
3396 af.viewport.setStartRes(view.getStartRes());
3397 af.viewport.setStartSeq(view.getStartSeq());
3399 ColourSchemeI cs = null;
3400 // apply colourschemes
3401 if (view.getBgColour() != null)
3403 if (view.getBgColour().startsWith("ucs"))
3405 cs = GetUserColourScheme(jms, view.getBgColour());
3407 else if (view.getBgColour().startsWith("Annotation"))
3409 AnnotationColours viewAnnColour = view.getAnnotationColours();
3410 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
3417 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3422 cs.setThreshold(view.getPidThreshold(), true);
3423 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3427 af.viewport.setGlobalColourScheme(cs);
3428 af.viewport.setColourAppliesToAllGroups(false);
3430 if (view.getConservationSelected() && cs != null)
3432 cs.setConservationInc(view.getConsThreshold());
3435 af.changeColour(cs);
3437 af.viewport.setColourAppliesToAllGroups(true);
3439 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
3441 if (view.hasCentreColumnLabels())
3443 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3445 if (view.hasIgnoreGapsinConsensus())
3447 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3450 if (view.hasFollowHighlight())
3452 af.viewport.followHighlight = view.getFollowHighlight();
3454 if (view.hasFollowSelection())
3456 af.viewport.followSelection = view.getFollowSelection();
3458 if (view.hasShowConsensusHistogram())
3460 af.viewport.setShowConsensusHistogram(view
3461 .getShowConsensusHistogram());
3465 af.viewport.setShowConsensusHistogram(true);
3467 if (view.hasShowSequenceLogo())
3469 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3473 af.viewport.setShowSequenceLogo(false);
3475 if (view.hasNormaliseSequenceLogo())
3477 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3479 if (view.hasShowDbRefTooltip())
3481 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3483 if (view.hasShowNPfeatureTooltip())
3485 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3487 if (view.hasShowGroupConsensus())
3489 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3493 af.viewport.setShowGroupConsensus(false);
3495 if (view.hasShowGroupConservation())
3497 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3501 af.viewport.setShowGroupConservation(false);
3504 // recover featre settings
3505 if (jms.getFeatureSettings() != null)
3507 FeaturesDisplayed fdi;
3508 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
3509 String[] renderOrder = new String[jms.getFeatureSettings()
3510 .getSettingCount()];
3511 Hashtable featureGroups = new Hashtable();
3512 Hashtable featureColours = new Hashtable();
3513 Hashtable featureOrder = new Hashtable();
3515 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3517 Setting setting = jms.getFeatureSettings().getSetting(fs);
3518 if (setting.hasMincolour())
3520 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3521 new java.awt.Color(setting.getMincolour()),
3522 new java.awt.Color(setting.getColour()),
3523 setting.getMin(), setting.getMax()) : new GraduatedColor(
3524 new java.awt.Color(setting.getMincolour()),
3525 new java.awt.Color(setting.getColour()), 0, 1);
3526 if (setting.hasThreshold())
3528 gc.setThresh(setting.getThreshold());
3529 gc.setThreshType(setting.getThreshstate());
3531 gc.setAutoScaled(true); // default
3532 if (setting.hasAutoScale())
3534 gc.setAutoScaled(setting.getAutoScale());
3536 if (setting.hasColourByLabel())
3538 gc.setColourByLabel(setting.getColourByLabel());
3540 // and put in the feature colour table.
3541 featureColours.put(setting.getType(), gc);
3545 featureColours.put(setting.getType(),
3546 new java.awt.Color(setting.getColour()));
3548 renderOrder[fs] = setting.getType();
3549 if (setting.hasOrder())
3551 featureOrder.put(setting.getType(), setting.getOrder());
3555 featureOrder.put(setting.getType(), new Float(fs
3556 / jms.getFeatureSettings().getSettingCount()));
3558 if (setting.getDisplay())
3560 fdi.setVisible(setting.getType());
3563 Hashtable fgtable = new Hashtable();
3564 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3566 Group grp = jms.getFeatureSettings().getGroup(gs);
3567 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3569 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
3570 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
3571 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
3572 FeatureRendererSettings frs = new FeatureRendererSettings(
3573 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
3574 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer()
3575 .transferSettings(frs);
3579 if (view.getHiddenColumnsCount() > 0)
3581 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3583 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3584 .getHiddenColumns(c).getEnd() // +1
3588 if (view.getCalcIdParam() != null)
3590 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3592 if (calcIdParam != null)
3594 if (recoverCalcIdParam(calcIdParam, af.viewport))
3599 warn("Couldn't recover parameters for "
3600 + calcIdParam.getCalcId());
3605 af.setMenusFromViewport(af.viewport);
3606 // TODO: we don't need to do this if the viewport is aready visible.
3607 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3609 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3610 reorderAutoannotation(af, al, autoAlan);
3611 af.alignPanel.alignmentChanged();
3615 private ColourSchemeI constructAnnotationColour(
3616 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
3617 JalviewModelSequence jms, boolean checkGroupAnnColour)
3619 boolean propagateAnnColour = false;
3620 ColourSchemeI cs = null;
3621 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
3622 if (checkGroupAnnColour && al.getGroups() != null
3623 && al.getGroups().size() > 0)
3625 // pre 2.8.1 behaviour
3626 // check to see if we should transfer annotation colours
3627 propagateAnnColour = true;
3628 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
3630 if (sg.cs instanceof AnnotationColourGradient)
3632 propagateAnnColour = false;
3636 // int find annotation
3637 if (annAlignment.getAlignmentAnnotation() != null)
3639 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
3641 if (annAlignment.getAlignmentAnnotation()[i].label
3642 .equals(viewAnnColour.getAnnotation()))
3644 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
3646 annAlignment.getAlignmentAnnotation()[i]
3647 .setThreshold(new jalview.datamodel.GraphLine(
3648 viewAnnColour.getThreshold(), "Threshold",
3649 java.awt.Color.black)
3654 if (viewAnnColour.getColourScheme().equals("None"))
3656 cs = new AnnotationColourGradient(
3657 annAlignment.getAlignmentAnnotation()[i],
3658 new java.awt.Color(viewAnnColour.getMinColour()),
3659 new java.awt.Color(viewAnnColour.getMaxColour()),
3660 viewAnnColour.getAboveThreshold());
3662 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
3664 cs = new AnnotationColourGradient(
3665 annAlignment.getAlignmentAnnotation()[i],
3666 GetUserColourScheme(jms,
3667 viewAnnColour.getColourScheme()),
3668 viewAnnColour.getAboveThreshold());
3672 cs = new AnnotationColourGradient(
3673 annAlignment.getAlignmentAnnotation()[i],
3674 ColourSchemeProperty.getColour(al,
3675 viewAnnColour.getColourScheme()),
3676 viewAnnColour.getAboveThreshold());
3678 if (viewAnnColour.hasPerSequence())
3680 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
3683 if (viewAnnColour.hasPredefinedColours())
3685 ((AnnotationColourGradient) cs)
3686 .setPredefinedColours(viewAnnColour
3687 .isPredefinedColours());
3689 if (propagateAnnColour && al.getGroups() != null)
3691 // Also use these settings for all the groups
3692 for (int g = 0; g < al.getGroups().size(); g++)
3694 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
3702 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
3703 * new AnnotationColourGradient(
3704 * annAlignment.getAlignmentAnnotation()[i], new
3705 * java.awt.Color(viewAnnColour. getMinColour()), new
3706 * java.awt.Color(viewAnnColour. getMaxColour()),
3707 * viewAnnColour.getAboveThreshold()); } else
3710 sg.cs = new AnnotationColourGradient(
3711 annAlignment.getAlignmentAnnotation()[i], sg.cs,
3712 viewAnnColour.getAboveThreshold());
3713 if (cs instanceof AnnotationColourGradient)
3715 if (viewAnnColour.hasPerSequence())
3717 ((AnnotationColourGradient) cs)
3718 .setSeqAssociated(viewAnnColour.isPerSequence());
3720 if (viewAnnColour.hasPredefinedColours())
3722 ((AnnotationColourGradient) cs)
3723 .setPredefinedColours(viewAnnColour
3724 .isPredefinedColours());
3740 private void reorderAutoannotation(AlignFrame af, Alignment al,
3741 ArrayList<JvAnnotRow> autoAlan)
3743 // copy over visualization settings for autocalculated annotation in the
3745 if (al.getAlignmentAnnotation() != null)
3748 * Kludge for magic autoannotation names (see JAL-811)
3750 String[] magicNames = new String[]
3751 { "Consensus", "Quality", "Conservation" };
3752 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3753 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3754 for (String nm : magicNames)
3756 visan.put(nm, nullAnnot);
3758 for (JvAnnotRow auan : autoAlan)
3760 visan.put(auan.template.label
3761 + (auan.template.getCalcId() == null ? "" : "\t"
3762 + auan.template.getCalcId()), auan);
3764 int hSize = al.getAlignmentAnnotation().length;
3765 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3766 // work through any autoCalculated annotation already on the view
3767 // removing it if it should be placed in a different location on the
3768 // annotation panel.
3769 List<String> remains = new ArrayList(visan.keySet());
3770 for (int h = 0; h < hSize; h++)
3772 jalview.datamodel.AlignmentAnnotation jalan = al
3773 .getAlignmentAnnotation()[h];
3774 if (jalan.autoCalculated)
3777 JvAnnotRow valan = visan.get(k = jalan.label);
3778 if (jalan.getCalcId() != null)
3780 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
3785 // delete the auto calculated row from the alignment
3786 al.deleteAnnotation(jalan, false);
3790 if (valan != nullAnnot)
3792 if (jalan != valan.template)
3794 // newly created autoannotation row instance
3795 // so keep a reference to the visible annotation row
3796 // and copy over all relevant attributes
3797 if (valan.template.graphHeight >= 0)
3800 jalan.graphHeight = valan.template.graphHeight;
3802 jalan.visible = valan.template.visible;
3804 reorder.add(new JvAnnotRow(valan.order, jalan));
3809 // Add any (possibly stale) autocalculated rows that were not appended to
3810 // the view during construction
3811 for (String other : remains)
3813 JvAnnotRow othera = visan.get(other);
3814 if (othera != nullAnnot && othera.template.getCalcId() != null
3815 && othera.template.getCalcId().length() > 0)
3817 reorder.add(othera);
3820 // now put the automatic annotation in its correct place
3821 int s = 0, srt[] = new int[reorder.size()];
3822 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3823 for (JvAnnotRow jvar : reorder)
3826 srt[s++] = jvar.order;
3829 jalview.util.QuickSort.sort(srt, rws);
3830 // and re-insert the annotation at its correct position
3831 for (JvAnnotRow jvar : rws)
3833 al.addAnnotation(jvar.template, jvar.order);
3835 af.alignPanel.adjustAnnotationHeight();
3839 Hashtable skipList = null;
3842 * TODO remove this method
3845 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3846 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3847 * throw new Error("Implementation Error. No skipList defined for this
3848 * Jalview2XML instance."); } return (AlignFrame)
3849 * skipList.get(view.getSequenceSetId()); }
3853 * Check if the Jalview view contained in object should be skipped or not.
3856 * @return true if view's sequenceSetId is a key in skipList
3858 private boolean skipViewport(JalviewModel object)
3860 if (skipList == null)
3865 if (skipList.containsKey(id = object.getJalviewModelSequence()
3866 .getViewport()[0].getSequenceSetId()))
3868 if (Cache.log != null && Cache.log.isDebugEnabled())
3870 Cache.log.debug("Skipping seuqence set id " + id);
3877 public void AddToSkipList(AlignFrame af)
3879 if (skipList == null)
3881 skipList = new Hashtable();
3883 skipList.put(af.getViewport().getSequenceSetId(), af);
3886 public void clearSkipList()
3888 if (skipList != null)
3895 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3897 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3898 Vector dseqs = null;
3901 // create a list of new dataset sequences
3902 dseqs = new Vector();
3904 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3906 Sequence vamsasSeq = vamsasSet.getSequence(i);
3907 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
3909 // create a new dataset
3912 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3913 dseqs.copyInto(dsseqs);
3914 ds = new jalview.datamodel.Alignment(dsseqs);
3915 debug("Created new dataset " + vamsasSet.getDatasetId()
3916 + " for alignment " + System.identityHashCode(al));
3917 addDatasetRef(vamsasSet.getDatasetId(), ds);
3919 // set the dataset for the newly imported alignment.
3920 if (al.getDataset() == null)
3929 * sequence definition to create/merge dataset sequence for
3933 * vector to add new dataset sequence to
3935 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
3936 AlignmentI ds, Vector dseqs)
3938 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
3940 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
3941 .get(vamsasSeq.getId());
3942 jalview.datamodel.SequenceI dsq = null;
3943 if (sq != null && sq.getDatasetSequence() != null)
3945 dsq = sq.getDatasetSequence();
3948 String sqid = vamsasSeq.getDsseqid();
3951 // need to create or add a new dataset sequence reference to this sequence
3954 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
3959 // make a new dataset sequence
3960 dsq = sq.createDatasetSequence();
3963 // make up a new dataset reference for this sequence
3964 sqid = seqHash(dsq);
3966 dsq.setVamsasId(uniqueSetSuffix + sqid);
3967 seqRefIds.put(sqid, dsq);
3972 dseqs.addElement(dsq);
3977 ds.addSequence(dsq);
3983 { // make this dataset sequence sq's dataset sequence
3984 sq.setDatasetSequence(dsq);
3985 // and update the current dataset alignment
3990 if (!dseqs.contains(dsq))
3997 if (ds.findIndex(dsq) < 0)
3999 ds.addSequence(dsq);
4006 // TODO: refactor this as a merge dataset sequence function
4007 // now check that sq (the dataset sequence) sequence really is the union of
4008 // all references to it
4009 // boolean pre = sq.getStart() < dsq.getStart();
4010 // boolean post = sq.getEnd() > dsq.getEnd();
4014 StringBuffer sb = new StringBuffer();
4015 String newres = jalview.analysis.AlignSeq.extractGaps(
4016 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4017 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4018 && newres.length() > dsq.getLength())
4020 // Update with the longer sequence.
4024 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4025 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4026 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4027 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4029 dsq.setSequence(newres);
4031 // TODO: merges will never happen if we 'know' we have the real dataset
4032 // sequence - this should be detected when id==dssid
4034 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4035 // + (pre ? "prepended" : "") + " "
4036 // + (post ? "appended" : ""));
4041 java.util.Hashtable datasetIds = null;
4043 java.util.IdentityHashMap dataset2Ids = null;
4045 private Alignment getDatasetFor(String datasetId)
4047 if (datasetIds == null)
4049 datasetIds = new Hashtable();
4052 if (datasetIds.containsKey(datasetId))
4054 return (Alignment) datasetIds.get(datasetId);
4059 private void addDatasetRef(String datasetId, Alignment dataset)
4061 if (datasetIds == null)
4063 datasetIds = new Hashtable();
4065 datasetIds.put(datasetId, dataset);
4069 * make a new dataset ID for this jalview dataset alignment
4074 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
4076 if (dataset.getDataset() != null)
4078 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4080 String datasetId = makeHashCode(dataset, null);
4081 if (datasetId == null)
4083 // make a new datasetId and record it
4084 if (dataset2Ids == null)
4086 dataset2Ids = new IdentityHashMap();
4090 datasetId = (String) dataset2Ids.get(dataset);
4092 if (datasetId == null)
4094 datasetId = "ds" + dataset2Ids.size() + 1;
4095 dataset2Ids.put(dataset, datasetId);
4101 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4103 for (int d = 0; d < sequence.getDBRefCount(); d++)
4105 DBRef dr = sequence.getDBRef(d);
4106 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4107 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4108 .getVersion(), sequence.getDBRef(d).getAccessionId());
4109 if (dr.getMapping() != null)
4111 entry.setMap(addMapping(dr.getMapping()));
4113 datasetSequence.addDBRef(entry);
4117 private jalview.datamodel.Mapping addMapping(Mapping m)
4119 SequenceI dsto = null;
4120 // Mapping m = dr.getMapping();
4121 int fr[] = new int[m.getMapListFromCount() * 2];
4122 Enumeration f = m.enumerateMapListFrom();
4123 for (int _i = 0; f.hasMoreElements(); _i += 2)
4125 MapListFrom mf = (MapListFrom) f.nextElement();
4126 fr[_i] = mf.getStart();
4127 fr[_i + 1] = mf.getEnd();
4129 int fto[] = new int[m.getMapListToCount() * 2];
4130 f = m.enumerateMapListTo();
4131 for (int _i = 0; f.hasMoreElements(); _i += 2)
4133 MapListTo mf = (MapListTo) f.nextElement();
4134 fto[_i] = mf.getStart();
4135 fto[_i + 1] = mf.getEnd();
4137 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4138 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4139 if (m.getMappingChoice() != null)
4141 MappingChoice mc = m.getMappingChoice();
4142 if (mc.getDseqFor() != null)
4144 String dsfor = "" + mc.getDseqFor();
4145 if (seqRefIds.containsKey(dsfor))
4150 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
4154 frefedSequence.add(new Object[]
4161 * local sequence definition
4163 Sequence ms = mc.getSequence();
4164 jalview.datamodel.Sequence djs = null;
4165 String sqid = ms.getDsseqid();
4166 if (sqid != null && sqid.length() > 0)
4169 * recover dataset sequence
4171 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
4176 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
4177 sqid = ((Object) ms).toString(); // make up a new hascode for
4178 // undefined dataset sequence hash
4179 // (unlikely to happen)
4185 * make a new dataset sequence and add it to refIds hash
4187 djs = new jalview.datamodel.Sequence(ms.getName(),
4189 djs.setStart(jmap.getMap().getToLowest());
4190 djs.setEnd(jmap.getMap().getToHighest());
4191 djs.setVamsasId(uniqueSetSuffix + sqid);
4193 seqRefIds.put(sqid, djs);
4196 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
4205 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
4206 boolean keepSeqRefs)
4209 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
4215 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
4219 uniqueSetSuffix = "";
4220 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
4225 if (this.frefedSequence == null)
4227 frefedSequence = new Vector();
4230 viewportsAdded = new Hashtable();
4232 AlignFrame af = LoadFromObject(jm, null, false, null);
4233 af.alignPanels.clear();
4234 af.closeMenuItem_actionPerformed(true);
4237 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
4238 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
4239 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
4240 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
4241 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
4244 return af.alignPanel;
4248 * flag indicating if hashtables should be cleared on finalization TODO this
4249 * flag may not be necessary
4251 private final boolean _cleartables = true;
4253 private Hashtable jvids2vobj;
4258 * @see java.lang.Object#finalize()
4261 protected void finalize() throws Throwable
4263 // really make sure we have no buried refs left.
4268 this.seqRefIds = null;
4269 this.seqsToIds = null;
4273 private void warn(String msg)
4278 private void warn(String msg, Exception e)
4280 if (Cache.log != null)
4284 Cache.log.warn(msg, e);
4288 Cache.log.warn(msg);
4293 System.err.println("Warning: " + msg);
4296 e.printStackTrace();
4301 private void debug(String string)
4303 debug(string, null);
4306 private void debug(String msg, Exception e)
4308 if (Cache.log != null)
4312 Cache.log.debug(msg, e);
4316 Cache.log.debug(msg);
4321 System.err.println("Warning: " + msg);
4324 e.printStackTrace();
4330 * set the object to ID mapping tables used to write/recover objects and XML
4331 * ID strings for the jalview project. If external tables are provided then
4332 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4333 * object goes out of scope. - also populates the datasetIds hashtable with
4334 * alignment objects containing dataset sequences
4337 * Map from ID strings to jalview datamodel
4339 * Map from jalview datamodel to ID strings
4343 public void setObjectMappingTables(Hashtable vobj2jv,
4344 IdentityHashMap jv2vobj)
4346 this.jv2vobj = jv2vobj;
4347 this.vobj2jv = vobj2jv;
4348 Iterator ds = jv2vobj.keySet().iterator();
4350 while (ds.hasNext())
4352 Object jvobj = ds.next();
4353 id = jv2vobj.get(jvobj).toString();
4354 if (jvobj instanceof jalview.datamodel.Alignment)
4356 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4358 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4361 else if (jvobj instanceof jalview.datamodel.Sequence)
4363 // register sequence object so the XML parser can recover it.
4364 if (seqRefIds == null)
4366 seqRefIds = new Hashtable();
4368 if (seqsToIds == null)
4370 seqsToIds = new IdentityHashMap();
4372 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
4373 seqsToIds.put(jvobj, id);
4375 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4377 if (annotationIds == null)
4379 annotationIds = new Hashtable();
4382 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4383 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4384 if (jvann.annotationId == null)
4386 jvann.annotationId = anid;
4388 if (!jvann.annotationId.equals(anid))
4390 // TODO verify that this is the correct behaviour
4391 this.warn("Overriding Annotation ID for " + anid
4392 + " from different id : " + jvann.annotationId);
4393 jvann.annotationId = anid;
4396 else if (jvobj instanceof String)
4398 if (jvids2vobj == null)
4400 jvids2vobj = new Hashtable();
4401 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4405 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4410 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4411 * objects created from the project archive. If string is null (default for
4412 * construction) then suffix will be set automatically.
4416 public void setUniqueSetSuffix(String string)
4418 uniqueSetSuffix = string;
4423 * uses skipList2 as the skipList for skipping views on sequence sets
4424 * associated with keys in the skipList
4428 public void setSkipList(Hashtable skipList2)
4430 skipList = skipList2;