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.api.structures.JalviewStructureDisplayI;
36 import jalview.bin.Cache;
37 import jalview.datamodel.Alignment;
38 import jalview.datamodel.AlignmentAnnotation;
39 import jalview.datamodel.AlignmentI;
40 import jalview.datamodel.SequenceI;
41 import jalview.schemabinding.version2.*;
42 import jalview.schemes.*;
43 import jalview.util.MessageManager;
44 import jalview.util.Platform;
45 import jalview.util.jarInputStreamProvider;
46 import jalview.viewmodel.AlignmentViewport;
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 = MessageManager.formatMessage("label.dataset_for", new String[]{fileName,_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.showSequenceFeatures);
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.featuresDisplayed != null)
1088 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1090 String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;
1092 Vector settingsAdded = new Vector();
1093 Object gstyle = null;
1094 GraduatedColor gcol = null;
1095 if (renderOrder != null)
1097 for (int ro = 0; ro < renderOrder.length; ro++)
1099 gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer()
1100 .getFeatureStyle(renderOrder[ro]);
1101 Setting setting = new Setting();
1102 setting.setType(renderOrder[ro]);
1103 if (gstyle instanceof GraduatedColor)
1105 gcol = (GraduatedColor) gstyle;
1106 setting.setColour(gcol.getMaxColor().getRGB());
1107 setting.setMincolour(gcol.getMinColor().getRGB());
1108 setting.setMin(gcol.getMin());
1109 setting.setMax(gcol.getMax());
1110 setting.setColourByLabel(gcol.isColourByLabel());
1111 setting.setAutoScale(gcol.isAutoScale());
1112 setting.setThreshold(gcol.getThresh());
1113 setting.setThreshstate(gcol.getThreshType());
1117 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1118 .getColour(renderOrder[ro]).getRGB());
1121 setting.setDisplay(av.featuresDisplayed
1122 .containsKey(renderOrder[ro]));
1123 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1124 .getOrder(renderOrder[ro]);
1127 setting.setOrder(rorder);
1129 fs.addSetting(setting);
1130 settingsAdded.addElement(renderOrder[ro]);
1134 // Make sure we save none displayed feature settings
1135 Iterator en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours
1136 .keySet().iterator();
1137 while (en.hasNext())
1139 String key = en.next().toString();
1140 if (settingsAdded.contains(key))
1145 Setting setting = new Setting();
1146 setting.setType(key);
1147 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1148 .getColour(key).getRGB());
1150 setting.setDisplay(false);
1151 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1155 setting.setOrder(rorder);
1157 fs.addSetting(setting);
1158 settingsAdded.addElement(key);
1160 en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1161 .keySet().iterator();
1162 Vector groupsAdded = new Vector();
1163 while (en.hasNext())
1165 String grp = en.next().toString();
1166 if (groupsAdded.contains(grp))
1170 Group g = new Group();
1172 g.setDisplay(((Boolean) ap.seqPanel.seqCanvas
1173 .getFeatureRenderer().featureGroups.get(grp))
1176 groupsAdded.addElement(grp);
1178 jms.setFeatureSettings(fs);
1182 if (av.hasHiddenColumns())
1184 if (av.getColumnSelection() == null
1185 || av.getColumnSelection().getHiddenColumns() == null)
1187 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1191 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1194 int[] region = (int[]) av.getColumnSelection()
1195 .getHiddenColumns().elementAt(c);
1196 HiddenColumns hc = new HiddenColumns();
1197 hc.setStart(region[0]);
1198 hc.setEnd(region[1]);
1199 view.addHiddenColumns(hc);
1203 if (calcIdSet.size() > 0)
1205 for (String calcId : calcIdSet)
1207 if (calcId.trim().length() > 0)
1209 CalcIdParam cidp = createCalcIdParam(calcId, av);
1210 // Some calcIds have no parameters.
1213 view.addCalcIdParam(cidp);
1219 jms.addViewport(view);
1221 object.setJalviewModelSequence(jms);
1222 object.getVamsasModel().addSequenceSet(vamsasSet);
1224 if (jout != null && fileName != null)
1226 // We may not want to write the object to disk,
1227 // eg we can copy the alignViewport to a new view object
1228 // using save and then load
1231 JarEntry entry = new JarEntry(fileName);
1232 jout.putNextEntry(entry);
1233 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1235 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1237 marshaller.marshal(object);
1240 } catch (Exception ex)
1242 // TODO: raise error in GUI if marshalling failed.
1243 ex.printStackTrace();
1249 private AnnotationColours constructAnnotationColours(
1250 AnnotationColourGradient acg, Vector userColours,
1251 JalviewModelSequence jms)
1253 AnnotationColours ac = new AnnotationColours();
1254 ac.setAboveThreshold(acg.getAboveThreshold());
1255 ac.setThreshold(acg.getAnnotationThreshold());
1256 ac.setAnnotation(acg.getAnnotation());
1257 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1259 ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
1264 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1268 ac.setMaxColour(acg.getMaxColour().getRGB());
1269 ac.setMinColour(acg.getMinColour().getRGB());
1270 ac.setPerSequence(acg.isSeqAssociated());
1271 ac.setPredefinedColours(acg.isPredefinedColours());
1275 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1276 IdentityHashMap groupRefs, AlignmentViewport av,
1277 Set<String> calcIdSet, boolean storeDS, SequenceSet vamsasSet)
1280 for (int i = 0; i < aa.length; i++)
1282 Annotation an = new Annotation();
1284 if (aa[i].annotationId != null)
1286 annotationIds.put(aa[i].annotationId, aa[i]);
1289 an.setId(aa[i].annotationId);
1291 an.setVisible(aa[i].visible);
1293 an.setDescription(aa[i].description);
1295 if (aa[i].sequenceRef != null)
1297 // TODO later annotation sequenceRef should be the XML ID of the
1298 // sequence rather than its display name
1299 an.setSequenceRef(aa[i].sequenceRef.getName());
1301 if (aa[i].groupRef != null)
1303 Object groupIdr = groupRefs.get(aa[i].groupRef);
1304 if (groupIdr == null)
1306 // make a locally unique String
1307 groupRefs.put(aa[i].groupRef,
1308 groupIdr = ("" + System.currentTimeMillis()
1309 + aa[i].groupRef.getName() + groupRefs.size()));
1311 an.setGroupRef(groupIdr.toString());
1314 // store all visualization attributes for annotation
1315 an.setGraphHeight(aa[i].graphHeight);
1316 an.setCentreColLabels(aa[i].centreColLabels);
1317 an.setScaleColLabels(aa[i].scaleColLabel);
1318 an.setShowAllColLabels(aa[i].showAllColLabels);
1319 an.setBelowAlignment(aa[i].belowAlignment);
1321 if (aa[i].graph > 0)
1324 an.setGraphType(aa[i].graph);
1325 an.setGraphGroup(aa[i].graphGroup);
1326 if (aa[i].getThreshold() != null)
1328 ThresholdLine line = new ThresholdLine();
1329 line.setLabel(aa[i].getThreshold().label);
1330 line.setValue(aa[i].getThreshold().value);
1331 line.setColour(aa[i].getThreshold().colour.getRGB());
1332 an.setThresholdLine(line);
1340 an.setLabel(aa[i].label);
1342 if (aa[i] == av.getAlignmentQualityAnnot()
1343 || aa[i] == av.getAlignmentConservationAnnotation()
1344 || aa[i] == av.getAlignmentConsensusAnnotation()
1345 || aa[i].autoCalculated)
1347 // new way of indicating autocalculated annotation -
1348 an.setAutoCalculated(aa[i].autoCalculated);
1350 if (aa[i].hasScore())
1352 an.setScore(aa[i].getScore());
1355 if (aa[i].getCalcId() != null)
1357 calcIdSet.add(aa[i].getCalcId());
1358 an.setCalcId(aa[i].getCalcId());
1361 AnnotationElement ae;
1362 if (aa[i].annotations != null)
1364 an.setScoreOnly(false);
1365 for (int a = 0; a < aa[i].annotations.length; a++)
1367 if ((aa[i] == null) || (aa[i].annotations[a] == null))
1372 ae = new AnnotationElement();
1373 if (aa[i].annotations[a].description != null)
1374 ae.setDescription(aa[i].annotations[a].description);
1375 if (aa[i].annotations[a].displayCharacter != null)
1376 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
1378 if (!Float.isNaN(aa[i].annotations[a].value))
1379 ae.setValue(aa[i].annotations[a].value);
1382 if (aa[i].annotations[a].secondaryStructure != ' '
1383 && aa[i].annotations[a].secondaryStructure != '\0')
1384 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
1387 if (aa[i].annotations[a].colour != null
1388 && aa[i].annotations[a].colour != java.awt.Color.black)
1390 ae.setColour(aa[i].annotations[a].colour.getRGB());
1393 an.addAnnotationElement(ae);
1394 if (aa[i].autoCalculated)
1396 // only write one non-null entry into the annotation row -
1397 // sufficient to get the visualization attributes necessary to
1405 an.setScoreOnly(true);
1407 if (!storeDS || (storeDS && !aa[i].autoCalculated))
1409 // skip autocalculated annotation - these are only provided for
1411 vamsasSet.addAnnotation(an);
1417 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1419 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1420 if (settings != null)
1422 CalcIdParam vCalcIdParam = new CalcIdParam();
1423 vCalcIdParam.setCalcId(calcId);
1424 vCalcIdParam.addServiceURL(settings.getServiceURI());
1425 // generic URI allowing a third party to resolve another instance of the
1426 // service used for this calculation
1427 for (String urls : settings.getServiceURLs())
1429 vCalcIdParam.addServiceURL(urls);
1431 vCalcIdParam.setVersion("1.0");
1432 if (settings.getPreset() != null)
1434 WsParamSetI setting = settings.getPreset();
1435 vCalcIdParam.setName(setting.getName());
1436 vCalcIdParam.setDescription(setting.getDescription());
1440 vCalcIdParam.setName("");
1441 vCalcIdParam.setDescription("Last used parameters");
1443 // need to be able to recover 1) settings 2) user-defined presets or
1444 // recreate settings from preset 3) predefined settings provided by
1445 // service - or settings that can be transferred (or discarded)
1446 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1448 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1449 // todo - decide if updateImmediately is needed for any projects.
1451 return vCalcIdParam;
1456 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1459 if (calcIdParam.getVersion().equals("1.0"))
1461 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1462 .getPreferredServiceFor(calcIdParam.getServiceURL());
1463 if (service != null)
1465 WsParamSetI parmSet = null;
1468 parmSet = service.getParamStore().parseServiceParameterFile(
1469 calcIdParam.getName(), calcIdParam.getDescription(),
1470 calcIdParam.getServiceURL(),
1471 calcIdParam.getParameters().replace("|\\n|", "\n"));
1472 } catch (IOException x)
1474 warn("Couldn't parse parameter data for "
1475 + calcIdParam.getCalcId(), x);
1478 List<ArgumentI> argList = null;
1479 if (calcIdParam.getName().length() > 0)
1481 parmSet = service.getParamStore()
1482 .getPreset(calcIdParam.getName());
1483 if (parmSet != null)
1485 // TODO : check we have a good match with settings in AACon -
1486 // otherwise we'll need to create a new preset
1491 argList = parmSet.getArguments();
1494 AAConSettings settings = new AAConSettings(
1495 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1496 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1497 calcIdParam.isNeedsUpdate());
1502 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1506 throw new Error(MessageManager.formatMessage("error.unsupported_version_calcIdparam", new String[]{calcIdParam.toString()}));
1510 * External mapping between jalview objects and objects yielding a valid and
1511 * unique object ID string. This is null for normal Jalview project IO, but
1512 * non-null when a jalview project is being read or written as part of a
1515 IdentityHashMap jv2vobj = null;
1518 * Construct a unique ID for jvobj using either existing bindings or if none
1519 * exist, the result of the hashcode call for the object.
1522 * jalview data object
1523 * @return unique ID for referring to jvobj
1525 private String makeHashCode(Object jvobj, String altCode)
1527 if (jv2vobj != null)
1529 Object id = jv2vobj.get(jvobj);
1532 return id.toString();
1534 // check string ID mappings
1535 if (jvids2vobj != null && jvobj instanceof String)
1537 id = jvids2vobj.get(jvobj);
1541 return id.toString();
1543 // give up and warn that something has gone wrong
1544 warn("Cannot find ID for object in external mapping : " + jvobj);
1550 * return local jalview object mapped to ID, if it exists
1554 * @return null or object bound to idcode
1556 private Object retrieveExistingObj(String idcode)
1558 if (idcode != null && vobj2jv != null)
1560 return vobj2jv.get(idcode);
1566 * binding from ID strings from external mapping table to jalview data model
1569 private Hashtable vobj2jv;
1571 private Sequence createVamsasSequence(String id, SequenceI jds)
1573 return createVamsasSequence(true, id, jds, null);
1576 private Sequence createVamsasSequence(boolean recurse, String id,
1577 SequenceI jds, SequenceI parentseq)
1579 Sequence vamsasSeq = new Sequence();
1580 vamsasSeq.setId(id);
1581 vamsasSeq.setName(jds.getName());
1582 vamsasSeq.setSequence(jds.getSequenceAsString());
1583 vamsasSeq.setDescription(jds.getDescription());
1584 jalview.datamodel.DBRefEntry[] dbrefs = null;
1585 if (jds.getDatasetSequence() != null)
1587 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1588 if (jds.getDatasetSequence().getDBRef() != null)
1590 dbrefs = jds.getDatasetSequence().getDBRef();
1595 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1596 // dataset sequences only
1597 dbrefs = jds.getDBRef();
1601 for (int d = 0; d < dbrefs.length; d++)
1603 DBRef dbref = new DBRef();
1604 dbref.setSource(dbrefs[d].getSource());
1605 dbref.setVersion(dbrefs[d].getVersion());
1606 dbref.setAccessionId(dbrefs[d].getAccessionId());
1607 if (dbrefs[d].hasMap())
1609 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1611 dbref.setMapping(mp);
1613 vamsasSeq.addDBRef(dbref);
1619 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1620 SequenceI parentseq, SequenceI jds, boolean recurse)
1623 if (jmp.getMap() != null)
1627 jalview.util.MapList mlst = jmp.getMap();
1628 int r[] = mlst.getFromRanges();
1629 for (int s = 0; s < r.length; s += 2)
1631 MapListFrom mfrom = new MapListFrom();
1632 mfrom.setStart(r[s]);
1633 mfrom.setEnd(r[s + 1]);
1634 mp.addMapListFrom(mfrom);
1636 r = mlst.getToRanges();
1637 for (int s = 0; s < r.length; s += 2)
1639 MapListTo mto = new MapListTo();
1641 mto.setEnd(r[s + 1]);
1642 mp.addMapListTo(mto);
1644 mp.setMapFromUnit(mlst.getFromRatio());
1645 mp.setMapToUnit(mlst.getToRatio());
1646 if (jmp.getTo() != null)
1648 MappingChoice mpc = new MappingChoice();
1650 && (parentseq != jmp.getTo() || parentseq
1651 .getDatasetSequence() != jmp.getTo()))
1653 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1659 SequenceI ps = null;
1660 if (parentseq != jmp.getTo()
1661 && parentseq.getDatasetSequence() != jmp.getTo())
1663 // chaining dbref rather than a handshaking one
1664 jmpid = seqHash(ps = jmp.getTo());
1668 jmpid = seqHash(ps = parentseq);
1670 mpc.setDseqFor(jmpid);
1671 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1673 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1674 seqRefIds.put(mpc.getDseqFor(), ps);
1678 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1681 mp.setMappingChoice(mpc);
1687 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1688 Vector userColours, JalviewModelSequence jms)
1691 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1692 boolean newucs = false;
1693 if (!userColours.contains(ucs))
1695 userColours.add(ucs);
1698 id = "ucs" + userColours.indexOf(ucs);
1701 // actually create the scheme's entry in the XML model
1702 java.awt.Color[] colours = ucs.getColours();
1703 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1704 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1706 for (int i = 0; i < colours.length; i++)
1708 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1709 col.setName(ResidueProperties.aa[i]);
1710 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1711 jbucs.addColour(col);
1713 if (ucs.getLowerCaseColours() != null)
1715 colours = ucs.getLowerCaseColours();
1716 for (int i = 0; i < colours.length; i++)
1718 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1719 col.setName(ResidueProperties.aa[i].toLowerCase());
1720 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1721 jbucs.addColour(col);
1726 uc.setUserColourScheme(jbucs);
1727 jms.addUserColours(uc);
1733 jalview.schemes.UserColourScheme GetUserColourScheme(
1734 JalviewModelSequence jms, String id)
1736 UserColours[] uc = jms.getUserColours();
1737 UserColours colours = null;
1739 for (int i = 0; i < uc.length; i++)
1741 if (uc[i].getId().equals(id))
1749 java.awt.Color[] newColours = new java.awt.Color[24];
1751 for (int i = 0; i < 24; i++)
1753 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1754 .getUserColourScheme().getColour(i).getRGB(), 16));
1757 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1760 if (colours.getUserColourScheme().getColourCount() > 24)
1762 newColours = new java.awt.Color[23];
1763 for (int i = 0; i < 23; i++)
1765 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1766 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1768 ucs.setLowerCaseColours(newColours);
1775 * contains last error message (if any) encountered by XML loader.
1777 String errorMessage = null;
1780 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1781 * exceptions are raised during project XML parsing
1783 public boolean attemptversion1parse = true;
1786 * Load a jalview project archive from a jar file
1789 * - HTTP URL or filename
1791 public AlignFrame LoadJalviewAlign(final String file)
1794 jalview.gui.AlignFrame af = null;
1798 // create list to store references for any new Jmol viewers created
1799 newStructureViewers = new Vector<JalviewStructureDisplayI>();
1800 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1801 // Workaround is to make sure caller implements the JarInputStreamProvider
1803 // so we can re-open the jar input stream for each entry.
1805 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1806 af = LoadJalviewAlign(jprovider);
1808 } catch (MalformedURLException e)
1810 errorMessage = "Invalid URL format for '" + file + "'";
1816 SwingUtilities.invokeAndWait(new Runnable()
1820 setLoadingFinishedForNewStructureViewers();
1823 } catch (Exception x)
1831 private jarInputStreamProvider createjarInputStreamProvider(
1832 final String file) throws MalformedURLException
1835 errorMessage = null;
1836 uniqueSetSuffix = null;
1838 viewportsAdded = null;
1839 frefedSequence = null;
1841 if (file.startsWith("http://"))
1843 url = new URL(file);
1845 final URL _url = url;
1846 return new jarInputStreamProvider()
1850 public JarInputStream getJarInputStream() throws IOException
1854 return new JarInputStream(_url.openStream());
1858 return new JarInputStream(new FileInputStream(file));
1863 public String getFilename()
1871 * Recover jalview session from a jalview project archive. Caller may
1872 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1873 * themselves. Any null fields will be initialised with default values,
1874 * non-null fields are left alone.
1879 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1881 errorMessage = null;
1882 if (uniqueSetSuffix == null)
1884 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1886 if (seqRefIds == null)
1888 seqRefIds = new Hashtable();
1890 if (viewportsAdded == null)
1892 viewportsAdded = new Hashtable();
1894 if (frefedSequence == null)
1896 frefedSequence = new Vector();
1899 jalview.gui.AlignFrame af = null, _af = null;
1900 Hashtable gatherToThisFrame = new Hashtable();
1901 final String file = jprovider.getFilename();
1904 JarInputStream jin = null;
1905 JarEntry jarentry = null;
1910 jin = jprovider.getJarInputStream();
1911 for (int i = 0; i < entryCount; i++)
1913 jarentry = jin.getNextJarEntry();
1916 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1918 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1919 JalviewModel object = new JalviewModel();
1921 Unmarshaller unmar = new Unmarshaller(object);
1922 unmar.setValidation(false);
1923 object = (JalviewModel) unmar.unmarshal(in);
1924 if (true) // !skipViewport(object))
1926 _af = LoadFromObject(object, file, true, jprovider);
1927 if (object.getJalviewModelSequence().getViewportCount() > 0)
1930 if (af.viewport.gatherViewsHere)
1932 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
1938 else if (jarentry != null)
1940 // Some other file here.
1943 } while (jarentry != null);
1944 resolveFrefedSequences();
1945 } catch (java.io.FileNotFoundException ex)
1947 ex.printStackTrace();
1948 errorMessage = "Couldn't locate Jalview XML file : " + file;
1949 System.err.println("Exception whilst loading jalview XML file : "
1951 } catch (java.net.UnknownHostException ex)
1953 ex.printStackTrace();
1954 errorMessage = "Couldn't locate Jalview XML file : " + file;
1955 System.err.println("Exception whilst loading jalview XML file : "
1957 } catch (Exception ex)
1959 System.err.println("Parsing as Jalview Version 2 file failed.");
1960 ex.printStackTrace(System.err);
1961 if (attemptversion1parse)
1963 // Is Version 1 Jar file?
1966 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
1967 } catch (Exception ex2)
1969 System.err.println("Exception whilst loading as jalviewXMLV1:");
1970 ex2.printStackTrace();
1974 if (Desktop.instance != null)
1976 Desktop.instance.stopLoading();
1980 System.out.println("Successfully loaded archive file");
1983 ex.printStackTrace();
1985 System.err.println("Exception whilst loading jalview XML file : "
1987 } catch (OutOfMemoryError e)
1989 // Don't use the OOM Window here
1990 errorMessage = "Out of memory loading jalview XML file";
1991 System.err.println("Out of memory whilst loading jalview XML file");
1992 e.printStackTrace();
1995 if (Desktop.instance != null)
1997 Desktop.instance.stopLoading();
2000 Enumeration en = gatherToThisFrame.elements();
2001 while (en.hasMoreElements())
2003 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
2005 if (errorMessage != null)
2013 * check errorMessage for a valid error message and raise an error box in the
2014 * GUI or write the current errorMessage to stderr and then clear the error
2017 protected void reportErrors()
2019 reportErrors(false);
2022 protected void reportErrors(final boolean saving)
2024 if (errorMessage != null)
2026 final String finalErrorMessage = errorMessage;
2029 javax.swing.SwingUtilities.invokeLater(new Runnable()
2034 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2035 finalErrorMessage, "Error "
2036 + (saving ? "saving" : "loading")
2037 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2043 System.err.println("Problem loading Jalview file: " + errorMessage);
2046 errorMessage = null;
2049 Hashtable alreadyLoadedPDB;
2052 * when set, local views will be updated from view stored in JalviewXML
2053 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2054 * sync if this is set to true.
2056 private final boolean updateLocalViews = false;
2058 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2060 if (alreadyLoadedPDB == null)
2061 alreadyLoadedPDB = new Hashtable();
2063 if (alreadyLoadedPDB.containsKey(pdbId))
2064 return alreadyLoadedPDB.get(pdbId).toString();
2068 JarInputStream jin = jprovider.getJarInputStream();
2070 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2071 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2072 * FileInputStream(jprovider)); }
2075 JarEntry entry = null;
2078 entry = jin.getNextJarEntry();
2079 } while (entry != null && !entry.getName().equals(pdbId));
2082 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
2083 File outFile = File.createTempFile("jalview_pdb", ".txt");
2084 outFile.deleteOnExit();
2085 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
2088 while ((data = in.readLine()) != null)
2095 } catch (Exception foo)
2100 String t = outFile.getAbsolutePath();
2101 alreadyLoadedPDB.put(pdbId, t);
2106 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
2108 } catch (Exception ex)
2110 ex.printStackTrace();
2116 private class JvAnnotRow
2118 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2125 * persisted version of annotation row from which to take vis properties
2127 public jalview.datamodel.AlignmentAnnotation template;
2130 * original position of the annotation row in the alignment
2136 * Load alignment frame from jalview XML DOM object
2141 * filename source string
2142 * @param loadTreesAndStructures
2143 * when false only create Viewport
2145 * data source provider
2146 * @return alignment frame created from view stored in DOM
2148 AlignFrame LoadFromObject(JalviewModel object, String file,
2149 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2151 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2152 Sequence[] vamsasSeq = vamsasSet.getSequence();
2154 JalviewModelSequence jms = object.getJalviewModelSequence();
2156 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2159 // ////////////////////////////////
2162 Vector hiddenSeqs = null;
2163 jalview.datamodel.Sequence jseq;
2165 ArrayList tmpseqs = new ArrayList();
2167 boolean multipleView = false;
2169 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
2170 int vi = 0; // counter in vamsasSeq array
2171 for (int i = 0; i < JSEQ.length; i++)
2173 String seqId = JSEQ[i].getId();
2175 if (seqRefIds.get(seqId) != null)
2177 tmpseqs.add(seqRefIds.get(seqId));
2178 multipleView = true;
2182 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2183 vamsasSeq[vi].getSequence());
2184 jseq.setDescription(vamsasSeq[vi].getDescription());
2185 jseq.setStart(JSEQ[i].getStart());
2186 jseq.setEnd(JSEQ[i].getEnd());
2187 jseq.setVamsasId(uniqueSetSuffix + seqId);
2188 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2193 if (JSEQ[i].getHidden())
2195 if (hiddenSeqs == null)
2197 hiddenSeqs = new Vector();
2200 hiddenSeqs.addElement(seqRefIds.get(seqId));
2206 // Create the alignment object from the sequence set
2207 // ///////////////////////////////
2208 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2211 tmpseqs.toArray(orderedSeqs);
2213 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2216 // / Add the alignment properties
2217 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2219 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2220 al.setProperty(ssp.getKey(), ssp.getValue());
2224 // SequenceFeatures are added to the DatasetSequence,
2225 // so we must create or recover the dataset before loading features
2226 // ///////////////////////////////
2227 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2229 // older jalview projects do not have a dataset id.
2230 al.setDataset(null);
2234 recoverDatasetFor(vamsasSet, al);
2236 // ///////////////////////////////
2238 Hashtable pdbloaded = new Hashtable();
2241 // load sequence features, database references and any associated PDB
2242 // structures for the alignment
2243 for (int i = 0; i < vamsasSeq.length; i++)
2245 if (JSEQ[i].getFeaturesCount() > 0)
2247 Features[] features = JSEQ[i].getFeatures();
2248 for (int f = 0; f < features.length; f++)
2250 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2251 features[f].getType(), features[f].getDescription(),
2252 features[f].getStatus(), features[f].getBegin(),
2253 features[f].getEnd(), features[f].getFeatureGroup());
2255 sf.setScore(features[f].getScore());
2256 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2258 OtherData keyValue = features[f].getOtherData(od);
2259 if (keyValue.getKey().startsWith("LINK"))
2261 sf.addLink(keyValue.getValue());
2265 sf.setValue(keyValue.getKey(), keyValue.getValue());
2270 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2273 if (vamsasSeq[i].getDBRefCount() > 0)
2275 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2277 if (JSEQ[i].getPdbidsCount() > 0)
2279 Pdbids[] ids = JSEQ[i].getPdbids();
2280 for (int p = 0; p < ids.length; p++)
2282 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2283 entry.setId(ids[p].getId());
2284 entry.setType(ids[p].getType());
2285 if (ids[p].getFile() != null)
2287 if (!pdbloaded.containsKey(ids[p].getFile()))
2289 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2293 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2297 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2301 } // end !multipleview
2303 // ///////////////////////////////
2304 // LOAD SEQUENCE MAPPINGS
2306 if (vamsasSet.getAlcodonFrameCount() > 0)
2308 // TODO Potentially this should only be done once for all views of an
2310 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2311 for (int i = 0; i < alc.length; i++)
2313 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2314 alc[i].getAlcodonCount());
2315 if (alc[i].getAlcodonCount() > 0)
2317 Alcodon[] alcods = alc[i].getAlcodon();
2318 for (int p = 0; p < cf.codons.length; p++)
2320 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2321 && alcods[p].hasPos3())
2323 // translated codons require three valid positions
2324 cf.codons[p] = new int[3];
2325 cf.codons[p][0] = (int) alcods[p].getPos1();
2326 cf.codons[p][1] = (int) alcods[p].getPos2();
2327 cf.codons[p][2] = (int) alcods[p].getPos3();
2331 cf.codons[p] = null;
2335 if (alc[i].getAlcodMapCount() > 0)
2337 AlcodMap[] maps = alc[i].getAlcodMap();
2338 for (int m = 0; m < maps.length; m++)
2340 SequenceI dnaseq = (SequenceI) seqRefIds
2341 .get(maps[m].getDnasq());
2343 jalview.datamodel.Mapping mapping = null;
2344 // attach to dna sequence reference.
2345 if (maps[m].getMapping() != null)
2347 mapping = addMapping(maps[m].getMapping());
2351 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2356 frefedSequence.add(new Object[]
2357 { maps[m].getDnasq(), cf, mapping });
2361 al.addCodonFrame(cf);
2366 // ////////////////////////////////
2368 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2370 * store any annotations which forward reference a group's ID
2372 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2374 if (vamsasSet.getAnnotationCount() > 0)
2376 Annotation[] an = vamsasSet.getAnnotation();
2378 for (int i = 0; i < an.length; i++)
2381 * test if annotation is automatically calculated for this view only
2383 boolean autoForView = false;
2384 if (an[i].getLabel().equals("Quality")
2385 || an[i].getLabel().equals("Conservation")
2386 || an[i].getLabel().equals("Consensus"))
2388 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2390 if (!an[i].hasAutoCalculated())
2392 an[i].setAutoCalculated(true);
2396 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2398 // remove ID - we don't recover annotation from other views for
2399 // view-specific annotation
2403 // set visiblity for other annotation in this view
2404 if (an[i].getId() != null
2405 && annotationIds.containsKey(an[i].getId()))
2407 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2408 .get(an[i].getId());
2409 // in principle Visible should always be true for annotation displayed
2410 // in multiple views
2411 if (an[i].hasVisible())
2412 jda.visible = an[i].getVisible();
2414 al.addAnnotation(jda);
2418 // Construct new annotation from model.
2419 AnnotationElement[] ae = an[i].getAnnotationElement();
2420 jalview.datamodel.Annotation[] anot = null;
2421 java.awt.Color firstColour = null;
2423 if (!an[i].getScoreOnly())
2425 anot = new jalview.datamodel.Annotation[al.getWidth()];
2426 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2428 anpos = ae[aa].getPosition();
2430 if (anpos >= anot.length)
2433 anot[anpos] = new jalview.datamodel.Annotation(
2435 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2436 (ae[aa].getSecondaryStructure() == null || ae[aa]
2437 .getSecondaryStructure().length() == 0) ? ' '
2438 : ae[aa].getSecondaryStructure().charAt(0),
2442 // JBPNote: Consider verifying dataflow for IO of secondary
2443 // structure annotation read from Stockholm files
2444 // this was added to try to ensure that
2445 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2447 // anot[ae[aa].getPosition()].displayCharacter = "";
2449 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2450 if (firstColour == null)
2452 firstColour = anot[anpos].colour;
2456 jalview.datamodel.AlignmentAnnotation jaa = null;
2458 if (an[i].getGraph())
2460 float llim = 0, hlim = 0;
2461 // if (autoForView || an[i].isAutoCalculated()) {
2464 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2465 an[i].getDescription(), anot, llim, hlim,
2466 an[i].getGraphType());
2468 jaa.graphGroup = an[i].getGraphGroup();
2469 jaa._linecolour = firstColour;
2470 if (an[i].getThresholdLine() != null)
2472 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2473 .getThresholdLine().getValue(), an[i]
2474 .getThresholdLine().getLabel(), new java.awt.Color(
2475 an[i].getThresholdLine().getColour())));
2478 if (autoForView || an[i].isAutoCalculated())
2480 // Hardwire the symbol display line to ensure that labels for
2481 // histograms are displayed
2487 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2488 an[i].getDescription(), anot);
2489 jaa._linecolour = firstColour;
2491 // register new annotation
2492 if (an[i].getId() != null)
2494 annotationIds.put(an[i].getId(), jaa);
2495 jaa.annotationId = an[i].getId();
2497 // recover sequence association
2498 if (an[i].getSequenceRef() != null)
2500 if (al.findName(an[i].getSequenceRef()) != null)
2502 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2504 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2507 // and make a note of any group association
2508 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2510 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2511 .get(an[i].getGroupRef());
2514 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2515 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2520 if (an[i].hasScore())
2522 jaa.setScore(an[i].getScore());
2524 if (an[i].hasVisible())
2525 jaa.visible = an[i].getVisible();
2527 if (an[i].hasCentreColLabels())
2528 jaa.centreColLabels = an[i].getCentreColLabels();
2530 if (an[i].hasScaleColLabels())
2532 jaa.scaleColLabel = an[i].getScaleColLabels();
2534 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2536 // newer files have an 'autoCalculated' flag and store calculation
2537 // state in viewport properties
2538 jaa.autoCalculated = true; // means annotation will be marked for
2539 // update at end of load.
2541 if (an[i].hasGraphHeight())
2543 jaa.graphHeight = an[i].getGraphHeight();
2545 if (an[i].hasBelowAlignment())
2547 jaa.belowAlignment = an[i].isBelowAlignment();
2549 jaa.setCalcId(an[i].getCalcId());
2551 if (jaa.autoCalculated)
2553 autoAlan.add(new JvAnnotRow(i, jaa));
2556 // if (!autoForView)
2558 // add autocalculated group annotation and any user created annotation
2560 al.addAnnotation(jaa);
2564 // ///////////////////////
2566 // Create alignment markup and styles for this view
2567 if (jms.getJGroupCount() > 0)
2569 JGroup[] groups = jms.getJGroup();
2570 boolean addAnnotSchemeGroup = false;
2571 for (int i = 0; i < groups.length; i++)
2573 ColourSchemeI cs = null;
2575 if (groups[i].getColour() != null)
2577 if (groups[i].getColour().startsWith("ucs"))
2579 cs = GetUserColourScheme(jms, groups[i].getColour());
2581 else if (groups[i].getColour().equals("AnnotationColourGradient")
2582 && groups[i].getAnnotationColours() != null)
2584 addAnnotSchemeGroup = true;
2589 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2594 cs.setThreshold(groups[i].getPidThreshold(), true);
2598 Vector seqs = new Vector();
2600 for (int s = 0; s < groups[i].getSeqCount(); s++)
2602 String seqId = groups[i].getSeq(s) + "";
2603 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2608 seqs.addElement(ts);
2612 if (seqs.size() < 1)
2617 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2618 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2619 groups[i].getDisplayText(), groups[i].getColourText(),
2620 groups[i].getStart(), groups[i].getEnd());
2622 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2624 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2625 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2626 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2627 .isShowUnconserved() : false);
2628 sg.thresholdTextColour = groups[i].getTextColThreshold();
2629 if (groups[i].hasShowConsensusHistogram())
2631 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2634 if (groups[i].hasShowSequenceLogo())
2636 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2638 if (groups[i].hasNormaliseSequenceLogo())
2640 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2642 if (groups[i].hasIgnoreGapsinConsensus())
2644 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2646 if (groups[i].getConsThreshold() != 0)
2648 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2649 "All", ResidueProperties.propHash, 3,
2650 sg.getSequences(null), 0, sg.getWidth() - 1);
2652 c.verdict(false, 25);
2653 sg.cs.setConservation(c);
2656 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2658 // re-instate unique group/annotation row reference
2659 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2660 .get(groups[i].getId());
2663 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2666 if (jaa.autoCalculated)
2668 // match up and try to set group autocalc alignment row for this
2670 if (jaa.label.startsWith("Consensus for "))
2672 sg.setConsensus(jaa);
2674 // match up and try to set group autocalc alignment row for this
2676 if (jaa.label.startsWith("Conservation for "))
2678 sg.setConservationRow(jaa);
2685 if (addAnnotSchemeGroup)
2687 // reconstruct the annotation colourscheme
2688 sg.cs = constructAnnotationColour(
2689 groups[i].getAnnotationColours(), null, al, jms, false);
2695 // only dataset in this model, so just return.
2698 // ///////////////////////////////
2701 // If we just load in the same jar file again, the sequenceSetId
2702 // will be the same, and we end up with multiple references
2703 // to the same sequenceSet. We must modify this id on load
2704 // so that each load of the file gives a unique id
2705 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2706 String viewId = (view.getId() == null ? null : view.getId()
2708 AlignFrame af = null;
2709 AlignViewport av = null;
2710 // now check to see if we really need to create a new viewport.
2711 if (multipleView && viewportsAdded.size() == 0)
2713 // We recovered an alignment for which a viewport already exists.
2714 // TODO: fix up any settings necessary for overlaying stored state onto
2715 // state recovered from another document. (may not be necessary).
2716 // we may need a binding from a viewport in memory to one recovered from
2718 // and then recover its containing af to allow the settings to be applied.
2719 // TODO: fix for vamsas demo
2721 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2723 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2724 if (seqsetobj != null)
2726 if (seqsetobj instanceof String)
2728 uniqueSeqSetId = (String) seqsetobj;
2730 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2736 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2742 * indicate that annotation colours are applied across all groups (pre
2743 * Jalview 2.8.1 behaviour)
2745 boolean doGroupAnnColour = isVersionStringLaterThan("2.8.1",
2746 object.getVersion());
2748 AlignmentPanel ap = null;
2749 boolean isnewview = true;
2752 // Check to see if this alignment already has a view id == viewId
2753 jalview.gui.AlignmentPanel views[] = Desktop
2754 .getAlignmentPanels(uniqueSeqSetId);
2755 if (views != null && views.length > 0)
2757 for (int v = 0; v < views.length; v++)
2759 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2761 // recover the existing alignpanel, alignframe, viewport
2762 af = views[v].alignFrame;
2765 // TODO: could even skip resetting view settings if we don't want to
2766 // change the local settings from other jalview processes
2775 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2776 uniqueSeqSetId, viewId, autoAlan);
2781 // /////////////////////////////////////
2782 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2786 for (int t = 0; t < jms.getTreeCount(); t++)
2789 Tree tree = jms.getTree(t);
2791 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2794 tp = af.ShowNewickTree(
2795 new jalview.io.NewickFile(tree.getNewick()),
2796 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2797 tree.getXpos(), tree.getYpos());
2798 if (tree.getId() != null)
2800 // perhaps bind the tree id to something ?
2805 // update local tree attributes ?
2806 // TODO: should check if tp has been manipulated by user - if so its
2807 // settings shouldn't be modified
2808 tp.setTitle(tree.getTitle());
2809 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2810 .getWidth(), tree.getHeight()));
2811 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2814 tp.treeCanvas.av = av; // af.viewport;
2815 tp.treeCanvas.ap = ap; // af.alignPanel;
2820 warn("There was a problem recovering stored Newick tree: \n"
2821 + tree.getNewick());
2825 tp.fitToWindow.setState(tree.getFitToWindow());
2826 tp.fitToWindow_actionPerformed(null);
2828 if (tree.getFontName() != null)
2830 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2831 .getFontStyle(), tree.getFontSize()));
2835 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2836 .getFontStyle(), tree.getFontSize()));
2839 tp.showPlaceholders(tree.getMarkUnlinked());
2840 tp.showBootstrap(tree.getShowBootstrap());
2841 tp.showDistances(tree.getShowDistances());
2843 tp.treeCanvas.threshold = tree.getThreshold();
2845 if (tree.getCurrentTree())
2847 af.viewport.setCurrentTree(tp.getTree());
2851 } catch (Exception ex)
2853 ex.printStackTrace();
2857 // //LOAD STRUCTURES
2858 if (loadTreesAndStructures)
2860 // run through all PDB ids on the alignment, and collect mappings between
2861 // jmol view ids and all sequences referring to it
2862 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2864 for (int i = 0; i < JSEQ.length; i++)
2866 if (JSEQ[i].getPdbidsCount() > 0)
2868 Pdbids[] ids = JSEQ[i].getPdbids();
2869 for (int p = 0; p < ids.length; p++)
2871 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2873 // check to see if we haven't already created this structure view
2874 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2875 : ids[p].getStructureState(s).getViewId()
2877 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2878 // Originally : ids[p].getFile()
2879 // : TODO: verify external PDB file recovery still works in normal
2880 // jalview project load
2881 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2882 jpdb.setId(ids[p].getId());
2884 int x = ids[p].getStructureState(s).getXpos();
2885 int y = ids[p].getStructureState(s).getYpos();
2886 int width = ids[p].getStructureState(s).getWidth();
2887 int height = ids[p].getStructureState(s).getHeight();
2889 // Probably don't need to do this anymore...
2890 // Desktop.desktop.getComponentAt(x, y);
2891 // TODO: NOW: check that this recovers the PDB file correctly.
2892 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2893 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2894 .get(JSEQ[i].getId() + "");
2895 if (sviewid == null)
2897 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2900 if (!jmolViewIds.containsKey(sviewid))
2902 jmolViewIds.put(sviewid, new Object[]
2904 { x, y, width, height }, "",
2905 new Hashtable<String, Object[]>(), new boolean[]
2906 { false, false, true } });
2907 // Legacy pre-2.7 conversion JAL-823 :
2908 // do not assume any view has to be linked for colour by
2912 // assemble String[] { pdb files }, String[] { id for each
2913 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2914 // seqs_file 2}, boolean[] {
2915 // linkAlignPanel,superposeWithAlignpanel}} from hash
2916 Object[] jmoldat = jmolViewIds.get(sviewid);
2917 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2918 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
2919 s).getAlignwithAlignPanel() : false;
2920 // never colour by linked panel if not specified
2921 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
2922 .hasColourwithAlignPanel() ? ids[p]
2923 .getStructureState(s).getColourwithAlignPanel()
2925 // default for pre-2.7 projects is that Jmol colouring is enabled
2926 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
2927 .hasColourByJmol() ? ids[p].getStructureState(s)
2928 .getColourByJmol() : true;
2930 if (((String) jmoldat[1]).length() < ids[p]
2931 .getStructureState(s).getContent().length())
2934 jmoldat[1] = ids[p].getStructureState(s).getContent();
2937 if (ids[p].getFile() != null)
2939 File mapkey = new File(ids[p].getFile());
2940 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
2942 if (seqstrmaps == null)
2944 ((Hashtable) jmoldat[2]).put(mapkey,
2945 seqstrmaps = new Object[]
2946 { pdbFile, ids[p].getId(), new Vector(),
2949 if (!((Vector) seqstrmaps[2]).contains(seq))
2951 ((Vector) seqstrmaps[2]).addElement(seq);
2952 // ((Vector)seqstrmaps[3]).addElement(n) :
2953 // in principle, chains
2954 // should be stored here : do we need to
2955 // TODO: store and recover seq/pdb_id :
2961 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");
2970 // Instantiate the associated Jmol views
2971 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
2973 String sviewid = entry.getKey();
2974 Object[] svattrib = entry.getValue();
2975 int[] geom = (int[]) svattrib[0];
2976 String state = (String) svattrib[1];
2977 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
2978 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
2979 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
2980 // collate the pdbfile -> sequence mappings from this view
2981 Vector<String> pdbfilenames = new Vector<String>();
2982 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
2983 Vector<String> pdbids = new Vector<String>();
2985 // Search to see if we've already created this Jmol view
2986 AppJmol comp = null;
2987 JInternalFrame[] frames = null;
2992 frames = Desktop.desktop.getAllFrames();
2993 } catch (ArrayIndexOutOfBoundsException e)
2995 // occasional No such child exceptions are thrown here...
3000 } catch (Exception f)
3005 } while (frames == null);
3006 // search for any Jmol windows already open from other
3007 // alignment views that exactly match the stored structure state
3008 for (int f = 0; comp == null && f < frames.length; f++)
3010 if (frames[f] instanceof AppJmol)
3013 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
3015 // post jalview 2.4 schema includes structure view id
3016 comp = (AppJmol) frames[f];
3018 else if (frames[f].getX() == x && frames[f].getY() == y
3019 && frames[f].getHeight() == height
3020 && frames[f].getWidth() == width)
3022 comp = (AppJmol) frames[f];
3029 // create a new Jmol window.
3030 // First parse the Jmol state to translate filenames loaded into the
3031 // view, and record the order in which files are shown in the Jmol
3032 // view, so we can add the sequence mappings in same order.
3033 StringBuffer newFileLoc = null;
3034 int cp = 0, ncp, ecp;
3035 while ((ncp = state.indexOf("load ", cp)) > -1)
3037 if (newFileLoc == null)
3039 newFileLoc = new StringBuffer();
3043 // look for next filename in load statement
3044 newFileLoc.append(state.substring(cp,
3045 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3046 String oldfilenam = state.substring(ncp,
3047 ecp = state.indexOf("\"", ncp));
3048 // recover the new mapping data for this old filename
3049 // have to normalize filename - since Jmol and jalview do
3051 // translation differently.
3052 Object[] filedat = oldFiles.get(new File(oldfilenam));
3053 newFileLoc.append(Platform
3054 .escapeString((String) filedat[0]));
3055 pdbfilenames.addElement((String) filedat[0]);
3056 pdbids.addElement((String) filedat[1]);
3057 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3058 .toArray(new SequenceI[0]));
3059 newFileLoc.append("\"");
3060 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3061 // look for next file statement.
3062 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3066 // just append rest of state
3067 newFileLoc.append(state.substring(cp));
3072 .print("Ignoring incomplete Jmol state for PDB ids: ");
3073 newFileLoc = new StringBuffer(state);
3074 newFileLoc.append("; load append ");
3075 for (File id : oldFiles.keySet())
3077 // add this and any other pdb files that should be present in
3079 Object[] filedat = oldFiles.get(id);
3081 newFileLoc.append(((String) filedat[0]));
3082 pdbfilenames.addElement((String) filedat[0]);
3083 pdbids.addElement((String) filedat[1]);
3084 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3085 .toArray(new SequenceI[0]));
3086 newFileLoc.append(" \"");
3087 newFileLoc.append((String) filedat[0]);
3088 newFileLoc.append("\"");
3091 newFileLoc.append(";");
3094 if (newFileLoc != null)
3096 int histbug = newFileLoc.indexOf("history = ");
3098 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
3100 String val = (diff == -1) ? null : newFileLoc.substring(
3102 if (val != null && val.length() >= 4)
3104 if (val.contains("e"))
3106 if (val.trim().equals("true"))
3114 newFileLoc.replace(histbug, diff, val);
3117 // TODO: assemble String[] { pdb files }, String[] { id for each
3118 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3119 // seqs_file 2}} from hash
3120 final String[] pdbf = pdbfilenames
3121 .toArray(new String[pdbfilenames.size()]), id = pdbids
3122 .toArray(new String[pdbids.size()]);
3123 final SequenceI[][] sq = seqmaps
3124 .toArray(new SequenceI[seqmaps.size()][]);
3125 final String fileloc = newFileLoc.toString(), vid = sviewid;
3126 final AlignFrame alf = af;
3127 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
3131 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3136 JalviewStructureDisplayI sview = null;
3139 // JAL-1333 note - we probably can't migrate Jmol views to UCSF Chimera!
3140 sview = new StructureViewer(alf.alignPanel.getStructureSelectionManager()).createView(StructureViewer.Viewer.JMOL, pdbf, id, sq, alf.alignPanel,
3141 useinJmolsuperpos, usetoColourbyseq,
3142 jmolColouring, fileloc, rect, vid);
3143 addNewStructureViewer(sview);
3144 } catch (OutOfMemoryError ex)
3146 new OOMWarning("restoring structure view for PDB id "
3147 + id, (OutOfMemoryError) ex.getCause());
3148 if (sview != null && sview.isVisible())
3150 sview.closeViewer();
3151 sview.setVisible(false);
3157 } catch (InvocationTargetException ex)
3159 warn("Unexpected error when opening Jmol view.", ex);
3161 } catch (InterruptedException e)
3163 // e.printStackTrace();
3169 // if (comp != null)
3171 // NOTE: if the jalview project is part of a shared session then
3172 // view synchronization should/could be done here.
3174 // add mapping for sequences in this view to an already open Jmol
3176 for (File id : oldFiles.keySet())
3178 // add this and any other pdb files that should be present in the
3180 Object[] filedat = oldFiles.get(id);
3181 String pdbFile = (String) filedat[0];
3182 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3183 .toArray(new SequenceI[0]);
3184 comp.jmb.ssm.setMapping(seq, null, pdbFile,
3185 jalview.io.AppletFormatAdapter.FILE);
3186 comp.jmb.addSequenceForStructFile(pdbFile, seq);
3188 // and add the AlignmentPanel's reference to the Jmol view
3189 comp.addAlignmentPanel(ap);
3190 if (useinJmolsuperpos)
3192 comp.useAlignmentPanelForSuperposition(ap);
3196 comp.excludeAlignmentPanelForSuperposition(ap);
3198 if (usetoColourbyseq)
3200 comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3204 comp.excludeAlignmentPanelForColourbyseq(ap);
3210 // and finally return.
3217 * - minimum version we are comparing against
3219 * - version of data being processsed.
3220 * @return true if version is development/null or evaluates to the same or
3221 * later X.Y.Z (where X,Y,Z are like [0-9]+b?[0-9]*)
3223 private boolean isVersionStringLaterThan(String supported, String version)
3225 if (version == null || version.equalsIgnoreCase("DEVELOPMENT BUILD")
3226 || version.equalsIgnoreCase("Test")
3227 || version.equalsIgnoreCase("AUTOMATED BUILD"))
3229 System.err.println("Assuming project file with "
3230 + (version == null ? "null" : version)
3231 + " is compatible with Jalview version " + supported);
3236 StringTokenizer currentV = new StringTokenizer(supported, "."), fileV = new StringTokenizer(
3238 while (currentV.hasMoreTokens() && fileV.hasMoreTokens())
3240 // convert b to decimal to catch bugfix releases within a series
3241 String curT = currentV.nextToken().toLowerCase().replace('b', '.');
3242 String fileT = fileV.nextToken().toLowerCase().replace('b', '.');
3245 if (Float.valueOf(curT) > Float.valueOf(fileT))
3247 // current version is newer than the version that wrote the file
3250 } catch (NumberFormatException nfe)
3253 .println("** WARNING: Version comparison failed for tokens ("
3257 + ")\n** Current: '"
3258 + supported + "' and Version: '" + version + "'");
3261 if (currentV.hasMoreElements())
3263 // fileV has no minor version but identical series to current
3270 Vector<JalviewStructureDisplayI> newStructureViewers = null;
3272 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
3274 if (newStructureViewers != null)
3276 sview.getBinding().setFinishedLoadingFromArchive(false);
3277 newStructureViewers.add(sview);
3281 protected void setLoadingFinishedForNewStructureViewers()
3283 if (newStructureViewers != null)
3285 for (JalviewStructureDisplayI sview : newStructureViewers)
3287 sview.getBinding().setFinishedLoadingFromArchive(true);
3289 newStructureViewers.clear();
3290 newStructureViewers = null;
3294 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3295 Alignment al, JalviewModelSequence jms, Viewport view,
3296 String uniqueSeqSetId, String viewId,
3297 ArrayList<JvAnnotRow> autoAlan)
3299 AlignFrame af = null;
3300 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3301 uniqueSeqSetId, viewId);
3303 af.setFileName(file, "Jalview");
3305 for (int i = 0; i < JSEQ.length; i++)
3307 af.viewport.setSequenceColour(af.viewport.getAlignment()
3308 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3311 af.viewport.gatherViewsHere = view.getGatheredViews();
3313 if (view.getSequenceSetId() != null)
3315 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3316 .get(uniqueSeqSetId);
3318 af.viewport.setSequenceSetId(uniqueSeqSetId);
3321 // propagate shared settings to this new view
3322 af.viewport.historyList = av.historyList;
3323 af.viewport.redoList = av.redoList;
3327 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3329 // TODO: check if this method can be called repeatedly without
3330 // side-effects if alignpanel already registered.
3331 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3333 // apply Hidden regions to view.
3334 if (hiddenSeqs != null)
3336 for (int s = 0; s < JSEQ.length; s++)
3338 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3340 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3343 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3345 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3348 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3351 for (int s = 0; s < hiddenSeqs.size(); s++)
3353 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3356 af.viewport.hideSequence(hseqs);
3359 // recover view properties and display parameters
3360 if (view.getViewName() != null)
3362 af.viewport.viewName = view.getViewName();
3363 af.setInitialTabVisible();
3365 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3368 af.viewport.setShowAnnotation(view.getShowAnnotation());
3369 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3371 af.viewport.setColourText(view.getShowColourText());
3373 af.viewport.setConservationSelected(view.getConservationSelected());
3374 af.viewport.setShowJVSuffix(view.getShowFullId());
3375 af.viewport.rightAlignIds = view.getRightAlignIds();
3376 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3377 .getFontStyle(), view.getFontSize()));
3378 af.alignPanel.fontChanged();
3379 af.viewport.setRenderGaps(view.getRenderGaps());
3380 af.viewport.setWrapAlignment(view.getWrapAlignment());
3381 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3382 af.viewport.setShowAnnotation(view.getShowAnnotation());
3383 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3385 af.viewport.setShowBoxes(view.getShowBoxes());
3387 af.viewport.setShowText(view.getShowText());
3389 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3390 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3391 af.viewport.thresholdTextColour = view.getTextColThreshold();
3392 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3393 .isShowUnconserved() : false);
3394 af.viewport.setStartRes(view.getStartRes());
3395 af.viewport.setStartSeq(view.getStartSeq());
3397 ColourSchemeI cs = null;
3398 // apply colourschemes
3399 if (view.getBgColour() != null)
3401 if (view.getBgColour().startsWith("ucs"))
3403 cs = GetUserColourScheme(jms, view.getBgColour());
3405 else if (view.getBgColour().startsWith("Annotation"))
3407 AnnotationColours viewAnnColour = view.getAnnotationColours();
3408 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
3415 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3420 cs.setThreshold(view.getPidThreshold(), true);
3421 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3425 af.viewport.setGlobalColourScheme(cs);
3426 af.viewport.setColourAppliesToAllGroups(false);
3428 if (view.getConservationSelected() && cs != null)
3430 cs.setConservationInc(view.getConsThreshold());
3433 af.changeColour(cs);
3435 af.viewport.setColourAppliesToAllGroups(true);
3437 if (view.getShowSequenceFeatures())
3439 af.viewport.showSequenceFeatures = true;
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 af.viewport.featuresDisplayed = new Hashtable();
3508 String[] renderOrder = new String[jms.getFeatureSettings()
3509 .getSettingCount()];
3510 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3512 Setting setting = jms.getFeatureSettings().getSetting(fs);
3513 if (setting.hasMincolour())
3515 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3516 new java.awt.Color(setting.getMincolour()),
3517 new java.awt.Color(setting.getColour()),
3518 setting.getMin(), setting.getMax()) : new GraduatedColor(
3519 new java.awt.Color(setting.getMincolour()),
3520 new java.awt.Color(setting.getColour()), 0, 1);
3521 if (setting.hasThreshold())
3523 gc.setThresh(setting.getThreshold());
3524 gc.setThreshType(setting.getThreshstate());
3526 gc.setAutoScaled(true); // default
3527 if (setting.hasAutoScale())
3529 gc.setAutoScaled(setting.getAutoScale());
3531 if (setting.hasColourByLabel())
3533 gc.setColourByLabel(setting.getColourByLabel());
3535 // and put in the feature colour table.
3536 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3537 setting.getType(), gc);
3541 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3543 new java.awt.Color(setting.getColour()));
3545 renderOrder[fs] = setting.getType();
3546 if (setting.hasOrder())
3547 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3548 setting.getType(), setting.getOrder());
3550 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3552 fs / jms.getFeatureSettings().getSettingCount());
3553 if (setting.getDisplay())
3555 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3556 setting.getColour()));
3559 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3561 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3562 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3564 Group grp = jms.getFeatureSettings().getGroup(gs);
3565 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3569 if (view.getHiddenColumnsCount() > 0)
3571 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3573 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3574 .getHiddenColumns(c).getEnd() // +1
3578 if (view.getCalcIdParam() != null)
3580 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3582 if (calcIdParam != null)
3584 if (recoverCalcIdParam(calcIdParam, af.viewport))
3589 warn("Couldn't recover parameters for "
3590 + calcIdParam.getCalcId());
3595 af.setMenusFromViewport(af.viewport);
3596 // TODO: we don't need to do this if the viewport is aready visible.
3597 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3599 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3600 reorderAutoannotation(af, al, autoAlan);
3601 af.alignPanel.alignmentChanged();
3605 private ColourSchemeI constructAnnotationColour(
3606 AnnotationColours viewAnnColour, AlignFrame af, Alignment al,
3607 JalviewModelSequence jms, boolean checkGroupAnnColour)
3609 boolean propagateAnnColour = false;
3610 ColourSchemeI cs = null;
3611 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
3612 if (checkGroupAnnColour && al.getGroups() != null
3613 && al.getGroups().size() > 0)
3615 // pre 2.8.1 behaviour
3616 // check to see if we should transfer annotation colours
3617 propagateAnnColour = true;
3618 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
3620 if (sg.cs instanceof AnnotationColourGradient)
3622 propagateAnnColour = false;
3626 // int find annotation
3627 if (annAlignment.getAlignmentAnnotation() != null)
3629 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
3631 if (annAlignment.getAlignmentAnnotation()[i].label
3632 .equals(viewAnnColour.getAnnotation()))
3634 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
3636 annAlignment.getAlignmentAnnotation()[i]
3637 .setThreshold(new jalview.datamodel.GraphLine(
3638 viewAnnColour.getThreshold(), "Threshold",
3639 java.awt.Color.black)
3644 if (viewAnnColour.getColourScheme().equals("None"))
3646 cs = new AnnotationColourGradient(
3647 annAlignment.getAlignmentAnnotation()[i],
3648 new java.awt.Color(viewAnnColour.getMinColour()),
3649 new java.awt.Color(viewAnnColour.getMaxColour()),
3650 viewAnnColour.getAboveThreshold());
3652 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
3654 cs = new AnnotationColourGradient(
3655 annAlignment.getAlignmentAnnotation()[i],
3656 GetUserColourScheme(jms,
3657 viewAnnColour.getColourScheme()),
3658 viewAnnColour.getAboveThreshold());
3662 cs = new AnnotationColourGradient(
3663 annAlignment.getAlignmentAnnotation()[i],
3664 ColourSchemeProperty.getColour(al,
3665 viewAnnColour.getColourScheme()),
3666 viewAnnColour.getAboveThreshold());
3668 if (viewAnnColour.hasPerSequence())
3670 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
3673 if (viewAnnColour.hasPredefinedColours())
3675 ((AnnotationColourGradient) cs)
3676 .setPredefinedColours(viewAnnColour
3677 .isPredefinedColours());
3679 if (propagateAnnColour && al.getGroups() != null)
3681 // Also use these settings for all the groups
3682 for (int g = 0; g < al.getGroups().size(); g++)
3684 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
3692 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
3693 * new AnnotationColourGradient(
3694 * annAlignment.getAlignmentAnnotation()[i], new
3695 * java.awt.Color(viewAnnColour. getMinColour()), new
3696 * java.awt.Color(viewAnnColour. getMaxColour()),
3697 * viewAnnColour.getAboveThreshold()); } else
3700 sg.cs = new AnnotationColourGradient(
3701 annAlignment.getAlignmentAnnotation()[i], sg.cs,
3702 viewAnnColour.getAboveThreshold());
3703 if (cs instanceof AnnotationColourGradient)
3705 if (viewAnnColour.hasPerSequence())
3707 ((AnnotationColourGradient) cs)
3708 .setSeqAssociated(viewAnnColour.isPerSequence());
3710 if (viewAnnColour.hasPredefinedColours())
3712 ((AnnotationColourGradient) cs)
3713 .setPredefinedColours(viewAnnColour
3714 .isPredefinedColours());
3730 private void reorderAutoannotation(AlignFrame af, Alignment al,
3731 ArrayList<JvAnnotRow> autoAlan)
3733 // copy over visualization settings for autocalculated annotation in the
3735 if (al.getAlignmentAnnotation() != null)
3738 * Kludge for magic autoannotation names (see JAL-811)
3740 String[] magicNames = new String[]
3741 { "Consensus", "Quality", "Conservation" };
3742 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3743 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3744 for (String nm : magicNames)
3746 visan.put(nm, nullAnnot);
3748 for (JvAnnotRow auan : autoAlan)
3750 visan.put(auan.template.label
3751 + (auan.template.getCalcId() == null ? "" : "\t"
3752 + auan.template.getCalcId()), auan);
3754 int hSize = al.getAlignmentAnnotation().length;
3755 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3756 // work through any autoCalculated annotation already on the view
3757 // removing it if it should be placed in a different location on the
3758 // annotation panel.
3759 List<String> remains = new ArrayList(visan.keySet());
3760 for (int h = 0; h < hSize; h++)
3762 jalview.datamodel.AlignmentAnnotation jalan = al
3763 .getAlignmentAnnotation()[h];
3764 if (jalan.autoCalculated)
3767 JvAnnotRow valan = visan.get(k = jalan.label);
3768 if (jalan.getCalcId() != null)
3770 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
3775 // delete the auto calculated row from the alignment
3776 al.deleteAnnotation(jalan, false);
3780 if (valan != nullAnnot)
3782 if (jalan != valan.template)
3784 // newly created autoannotation row instance
3785 // so keep a reference to the visible annotation row
3786 // and copy over all relevant attributes
3787 if (valan.template.graphHeight >= 0)
3790 jalan.graphHeight = valan.template.graphHeight;
3792 jalan.visible = valan.template.visible;
3794 reorder.add(new JvAnnotRow(valan.order, jalan));
3799 // Add any (possibly stale) autocalculated rows that were not appended to
3800 // the view during construction
3801 for (String other : remains)
3803 JvAnnotRow othera = visan.get(other);
3804 if (othera != nullAnnot && othera.template.getCalcId() != null
3805 && othera.template.getCalcId().length() > 0)
3807 reorder.add(othera);
3810 // now put the automatic annotation in its correct place
3811 int s = 0, srt[] = new int[reorder.size()];
3812 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3813 for (JvAnnotRow jvar : reorder)
3816 srt[s++] = jvar.order;
3819 jalview.util.QuickSort.sort(srt, rws);
3820 // and re-insert the annotation at its correct position
3821 for (JvAnnotRow jvar : rws)
3823 al.addAnnotation(jvar.template, jvar.order);
3825 af.alignPanel.adjustAnnotationHeight();
3829 Hashtable skipList = null;
3832 * TODO remove this method
3835 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3836 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3837 * throw new Error("Implementation Error. No skipList defined for this
3838 * Jalview2XML instance."); } return (AlignFrame)
3839 * skipList.get(view.getSequenceSetId()); }
3843 * Check if the Jalview view contained in object should be skipped or not.
3846 * @return true if view's sequenceSetId is a key in skipList
3848 private boolean skipViewport(JalviewModel object)
3850 if (skipList == null)
3855 if (skipList.containsKey(id = object.getJalviewModelSequence()
3856 .getViewport()[0].getSequenceSetId()))
3858 if (Cache.log != null && Cache.log.isDebugEnabled())
3860 Cache.log.debug("Skipping seuqence set id " + id);
3867 public void AddToSkipList(AlignFrame af)
3869 if (skipList == null)
3871 skipList = new Hashtable();
3873 skipList.put(af.getViewport().getSequenceSetId(), af);
3876 public void clearSkipList()
3878 if (skipList != null)
3885 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3887 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3888 Vector dseqs = null;
3891 // create a list of new dataset sequences
3892 dseqs = new Vector();
3894 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3896 Sequence vamsasSeq = vamsasSet.getSequence(i);
3897 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
3899 // create a new dataset
3902 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3903 dseqs.copyInto(dsseqs);
3904 ds = new jalview.datamodel.Alignment(dsseqs);
3905 debug("Created new dataset " + vamsasSet.getDatasetId()
3906 + " for alignment " + System.identityHashCode(al));
3907 addDatasetRef(vamsasSet.getDatasetId(), ds);
3909 // set the dataset for the newly imported alignment.
3910 if (al.getDataset() == null)
3919 * sequence definition to create/merge dataset sequence for
3923 * vector to add new dataset sequence to
3925 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
3926 AlignmentI ds, Vector dseqs)
3928 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
3930 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
3931 .get(vamsasSeq.getId());
3932 jalview.datamodel.SequenceI dsq = null;
3933 if (sq != null && sq.getDatasetSequence() != null)
3935 dsq = sq.getDatasetSequence();
3938 String sqid = vamsasSeq.getDsseqid();
3941 // need to create or add a new dataset sequence reference to this sequence
3944 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
3949 // make a new dataset sequence
3950 dsq = sq.createDatasetSequence();
3953 // make up a new dataset reference for this sequence
3954 sqid = seqHash(dsq);
3956 dsq.setVamsasId(uniqueSetSuffix + sqid);
3957 seqRefIds.put(sqid, dsq);
3962 dseqs.addElement(dsq);
3967 ds.addSequence(dsq);
3973 { // make this dataset sequence sq's dataset sequence
3974 sq.setDatasetSequence(dsq);
3975 // and update the current dataset alignment
3980 if (!dseqs.contains(dsq))
3987 if (ds.findIndex(dsq) < 0)
3989 ds.addSequence(dsq);
3996 // TODO: refactor this as a merge dataset sequence function
3997 // now check that sq (the dataset sequence) sequence really is the union of
3998 // all references to it
3999 // boolean pre = sq.getStart() < dsq.getStart();
4000 // boolean post = sq.getEnd() > dsq.getEnd();
4004 StringBuffer sb = new StringBuffer();
4005 String newres = jalview.analysis.AlignSeq.extractGaps(
4006 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4007 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4008 && newres.length() > dsq.getLength())
4010 // Update with the longer sequence.
4014 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4015 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4016 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4017 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4019 dsq.setSequence(newres);
4021 // TODO: merges will never happen if we 'know' we have the real dataset
4022 // sequence - this should be detected when id==dssid
4024 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4025 // + (pre ? "prepended" : "") + " "
4026 // + (post ? "appended" : ""));
4031 java.util.Hashtable datasetIds = null;
4033 java.util.IdentityHashMap dataset2Ids = null;
4035 private Alignment getDatasetFor(String datasetId)
4037 if (datasetIds == null)
4039 datasetIds = new Hashtable();
4042 if (datasetIds.containsKey(datasetId))
4044 return (Alignment) datasetIds.get(datasetId);
4049 private void addDatasetRef(String datasetId, Alignment dataset)
4051 if (datasetIds == null)
4053 datasetIds = new Hashtable();
4055 datasetIds.put(datasetId, dataset);
4059 * make a new dataset ID for this jalview dataset alignment
4064 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
4066 if (dataset.getDataset() != null)
4068 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
4070 String datasetId = makeHashCode(dataset, null);
4071 if (datasetId == null)
4073 // make a new datasetId and record it
4074 if (dataset2Ids == null)
4076 dataset2Ids = new IdentityHashMap();
4080 datasetId = (String) dataset2Ids.get(dataset);
4082 if (datasetId == null)
4084 datasetId = "ds" + dataset2Ids.size() + 1;
4085 dataset2Ids.put(dataset, datasetId);
4091 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
4093 for (int d = 0; d < sequence.getDBRefCount(); d++)
4095 DBRef dr = sequence.getDBRef(d);
4096 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
4097 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
4098 .getVersion(), sequence.getDBRef(d).getAccessionId());
4099 if (dr.getMapping() != null)
4101 entry.setMap(addMapping(dr.getMapping()));
4103 datasetSequence.addDBRef(entry);
4107 private jalview.datamodel.Mapping addMapping(Mapping m)
4109 SequenceI dsto = null;
4110 // Mapping m = dr.getMapping();
4111 int fr[] = new int[m.getMapListFromCount() * 2];
4112 Enumeration f = m.enumerateMapListFrom();
4113 for (int _i = 0; f.hasMoreElements(); _i += 2)
4115 MapListFrom mf = (MapListFrom) f.nextElement();
4116 fr[_i] = mf.getStart();
4117 fr[_i + 1] = mf.getEnd();
4119 int fto[] = new int[m.getMapListToCount() * 2];
4120 f = m.enumerateMapListTo();
4121 for (int _i = 0; f.hasMoreElements(); _i += 2)
4123 MapListTo mf = (MapListTo) f.nextElement();
4124 fto[_i] = mf.getStart();
4125 fto[_i + 1] = mf.getEnd();
4127 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
4128 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
4129 if (m.getMappingChoice() != null)
4131 MappingChoice mc = m.getMappingChoice();
4132 if (mc.getDseqFor() != null)
4134 String dsfor = "" + mc.getDseqFor();
4135 if (seqRefIds.containsKey(dsfor))
4140 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
4144 frefedSequence.add(new Object[]
4151 * local sequence definition
4153 Sequence ms = mc.getSequence();
4154 jalview.datamodel.Sequence djs = null;
4155 String sqid = ms.getDsseqid();
4156 if (sqid != null && sqid.length() > 0)
4159 * recover dataset sequence
4161 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
4166 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
4167 sqid = ((Object) ms).toString(); // make up a new hascode for
4168 // undefined dataset sequence hash
4169 // (unlikely to happen)
4175 * make a new dataset sequence and add it to refIds hash
4177 djs = new jalview.datamodel.Sequence(ms.getName(),
4179 djs.setStart(jmap.getMap().getToLowest());
4180 djs.setEnd(jmap.getMap().getToHighest());
4181 djs.setVamsasId(uniqueSetSuffix + sqid);
4183 seqRefIds.put(sqid, djs);
4186 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
4195 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
4196 boolean keepSeqRefs)
4199 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
4205 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
4209 uniqueSetSuffix = "";
4210 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
4215 if (this.frefedSequence == null)
4217 frefedSequence = new Vector();
4220 viewportsAdded = new Hashtable();
4222 AlignFrame af = LoadFromObject(jm, null, false, null);
4223 af.alignPanels.clear();
4224 af.closeMenuItem_actionPerformed(true);
4227 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
4228 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
4229 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
4230 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
4231 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
4234 return af.alignPanel;
4238 * flag indicating if hashtables should be cleared on finalization TODO this
4239 * flag may not be necessary
4241 private final boolean _cleartables = true;
4243 private Hashtable jvids2vobj;
4248 * @see java.lang.Object#finalize()
4251 protected void finalize() throws Throwable
4253 // really make sure we have no buried refs left.
4258 this.seqRefIds = null;
4259 this.seqsToIds = null;
4263 private void warn(String msg)
4268 private void warn(String msg, Exception e)
4270 if (Cache.log != null)
4274 Cache.log.warn(msg, e);
4278 Cache.log.warn(msg);
4283 System.err.println("Warning: " + msg);
4286 e.printStackTrace();
4291 private void debug(String string)
4293 debug(string, null);
4296 private void debug(String msg, Exception e)
4298 if (Cache.log != null)
4302 Cache.log.debug(msg, e);
4306 Cache.log.debug(msg);
4311 System.err.println("Warning: " + msg);
4314 e.printStackTrace();
4320 * set the object to ID mapping tables used to write/recover objects and XML
4321 * ID strings for the jalview project. If external tables are provided then
4322 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4323 * object goes out of scope. - also populates the datasetIds hashtable with
4324 * alignment objects containing dataset sequences
4327 * Map from ID strings to jalview datamodel
4329 * Map from jalview datamodel to ID strings
4333 public void setObjectMappingTables(Hashtable vobj2jv,
4334 IdentityHashMap jv2vobj)
4336 this.jv2vobj = jv2vobj;
4337 this.vobj2jv = vobj2jv;
4338 Iterator ds = jv2vobj.keySet().iterator();
4340 while (ds.hasNext())
4342 Object jvobj = ds.next();
4343 id = jv2vobj.get(jvobj).toString();
4344 if (jvobj instanceof jalview.datamodel.Alignment)
4346 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4348 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4351 else if (jvobj instanceof jalview.datamodel.Sequence)
4353 // register sequence object so the XML parser can recover it.
4354 if (seqRefIds == null)
4356 seqRefIds = new Hashtable();
4358 if (seqsToIds == null)
4360 seqsToIds = new IdentityHashMap();
4362 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
4363 seqsToIds.put(jvobj, id);
4365 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4367 if (annotationIds == null)
4369 annotationIds = new Hashtable();
4372 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4373 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4374 if (jvann.annotationId == null)
4376 jvann.annotationId = anid;
4378 if (!jvann.annotationId.equals(anid))
4380 // TODO verify that this is the correct behaviour
4381 this.warn("Overriding Annotation ID for " + anid
4382 + " from different id : " + jvann.annotationId);
4383 jvann.annotationId = anid;
4386 else if (jvobj instanceof String)
4388 if (jvids2vobj == null)
4390 jvids2vobj = new Hashtable();
4391 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4395 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4400 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4401 * objects created from the project archive. If string is null (default for
4402 * construction) then suffix will be set automatically.
4406 public void setUniqueSetSuffix(String string)
4408 uniqueSetSuffix = string;
4413 * uses skipList2 as the skipList for skipping views on sequence sets
4414 * associated with keys in the skipList
4418 public void setSkipList(Hashtable skipList2)
4420 skipList = skipList2;