2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.0b1)
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 of the License, or (at your option) any later version.
11 * Jalview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
17 * The Jalview Authors are detailed in the 'AUTHORS' file.
21 import java.awt.Rectangle;
23 import java.lang.reflect.InvocationTargetException;
26 import java.util.Map.Entry;
27 import java.util.jar.*;
31 import org.exolab.castor.xml.*;
33 import jalview.bin.Cache;
34 import jalview.datamodel.Alignment;
35 import jalview.datamodel.AlignmentAnnotation;
36 import jalview.datamodel.AlignmentI;
37 import jalview.datamodel.SequenceI;
38 import jalview.schemabinding.version2.*;
39 import jalview.schemes.*;
40 import jalview.util.Platform;
41 import jalview.util.jarInputStreamProvider;
42 import jalview.ws.jws2.Jws2Discoverer;
43 import jalview.ws.jws2.dm.AAConSettings;
44 import jalview.ws.jws2.jabaws2.Jws2Instance;
45 import jalview.ws.params.ArgumentI;
46 import jalview.ws.params.AutoCalcSetting;
47 import jalview.ws.params.WsParamSetI;
50 * Write out the current jalview desktop state as a Jalview XML stream.
52 * Note: the vamsas objects referred to here are primitive versions of the
53 * VAMSAS project schema elements - they are not the same and most likely never
57 * @version $Revision: 1.134 $
59 public class Jalview2XML
62 * create/return unique hash string for sq
65 * @return new or existing unique string for sq
67 String seqHash(SequenceI sq)
69 if (seqsToIds == null)
73 if (seqsToIds.containsKey(sq))
75 return (String) seqsToIds.get(sq);
79 // create sequential key
80 String key = "sq" + (seqsToIds.size() + 1);
81 key = makeHashCode(sq, key); // check we don't have an external reference
83 seqsToIds.put(sq, key);
92 if (seqRefIds != null)
96 if (seqsToIds != null)
106 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
107 // seqRefIds = new Hashtable();
108 // seqsToIds = new IdentityHashMap();
114 if (seqsToIds == null)
116 seqsToIds = new IdentityHashMap();
118 if (seqRefIds == null)
120 seqRefIds = new Hashtable();
125 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
126 * of sequence objects are created.
128 java.util.IdentityHashMap seqsToIds = null;
131 * jalview XML Sequence ID to jalview sequence object reference (both dataset
132 * and alignment sequences. Populated as XML reps of sequence objects are
135 java.util.Hashtable seqRefIds = null; // key->SequenceI resolution
137 Vector frefedSequence = null;
139 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
145 public Jalview2XML(boolean raiseGUI)
147 this.raiseGUI = raiseGUI;
150 public void resolveFrefedSequences()
152 if (frefedSequence.size() > 0)
154 int r = 0, rSize = frefedSequence.size();
157 Object[] ref = (Object[]) frefedSequence.elementAt(r);
160 String sref = (String) ref[0];
161 if (seqRefIds.containsKey(sref))
163 if (ref[1] instanceof jalview.datamodel.Mapping)
165 SequenceI seq = (SequenceI) seqRefIds.get(sref);
166 while (seq.getDatasetSequence() != null)
168 seq = seq.getDatasetSequence();
170 ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
174 if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
176 SequenceI seq = (SequenceI) seqRefIds.get(sref);
177 while (seq.getDatasetSequence() != null)
179 seq = seq.getDatasetSequence();
182 && ref[2] instanceof jalview.datamodel.Mapping)
184 jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
185 ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
186 seq, mp.getTo(), mp.getMap());
191 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
192 + ref[2].getClass() + " type objects.");
198 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
199 + ref[1].getClass() + " type objects.");
202 frefedSequence.remove(r);
208 .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
210 + " with objecttype "
211 + ref[1].getClass());
218 frefedSequence.remove(r);
226 * This maintains a list of viewports, the key being the seqSetId. Important
227 * to set historyItem and redoList for multiple views
229 Hashtable viewportsAdded;
231 Hashtable annotationIds = new Hashtable();
233 String uniqueSetSuffix = "";
236 * List of pdbfiles added to Jar
238 Vector pdbfiles = null;
240 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
241 public void SaveState(File statefile)
245 FileOutputStream fos = new FileOutputStream(statefile);
246 JarOutputStream jout = new JarOutputStream(fos);
249 } catch (Exception e)
251 // TODO: inform user of the problem - they need to know if their data was
253 if (errorMessage == null)
255 errorMessage = "Couldn't write Jalview Archive to output file '"
256 + statefile + "' - See console error log for details";
260 errorMessage += "(output file was '" + statefile + "')";
268 * Writes a jalview project archive to the given Jar output stream.
272 public void SaveState(JarOutputStream jout)
274 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
284 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
285 // //////////////////////////////////////////////////
286 // NOTE ALSO new PrintWriter must be used for each new JarEntry
287 PrintWriter out = null;
289 Vector shortNames = new Vector();
292 for (int i = frames.length - 1; i > -1; i--)
294 if (frames[i] instanceof AlignFrame)
296 AlignFrame af = (AlignFrame) frames[i];
299 && skipList.containsKey(af.getViewport()
300 .getSequenceSetId()))
305 String shortName = af.getTitle();
307 if (shortName.indexOf(File.separatorChar) > -1)
309 shortName = shortName.substring(shortName
310 .lastIndexOf(File.separatorChar) + 1);
315 while (shortNames.contains(shortName))
317 if (shortName.endsWith("_" + (count - 1)))
319 shortName = shortName
320 .substring(0, shortName.lastIndexOf("_"));
323 shortName = shortName.concat("_" + count);
327 shortNames.addElement(shortName);
329 if (!shortName.endsWith(".xml"))
331 shortName = shortName + ".xml";
334 int ap, apSize = af.alignPanels.size();
335 for (ap = 0; ap < apSize; ap++)
337 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
339 String fileName = apSize == 1 ? shortName : ap + shortName;
340 if (!fileName.endsWith(".xml"))
342 fileName = fileName + ".xml";
345 SaveState(apanel, fileName, jout);
352 } catch (Exception foo)
357 } catch (Exception ex)
359 // TODO: inform user of the problem - they need to know if their data was
361 if (errorMessage == null)
363 errorMessage = "Couldn't write Jalview Archive - see error output for details";
365 ex.printStackTrace();
369 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
370 public boolean SaveAlignment(AlignFrame af, String jarFile,
375 int ap, apSize = af.alignPanels.size();
376 FileOutputStream fos = new FileOutputStream(jarFile);
377 JarOutputStream jout = new JarOutputStream(fos);
378 for (ap = 0; ap < apSize; ap++)
380 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
382 String jfileName = apSize == 1 ? fileName : fileName + ap;
383 if (!jfileName.endsWith(".xml"))
385 jfileName = jfileName + ".xml";
387 SaveState(apanel, jfileName, jout);
393 } catch (Exception foo)
399 } catch (Exception ex)
401 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
402 ex.printStackTrace();
408 * create a JalviewModel from an algnment view and marshall it to a
412 * panel to create jalview model for
414 * name of alignment panel written to output stream
420 public JalviewModel SaveState(AlignmentPanel ap, String fileName,
421 JarOutputStream jout)
423 return SaveState(ap, fileName, false,jout);
426 * create a JalviewModel from an algnment view and marshall it to a
430 * panel to create jalview model for
432 * name of alignment panel written to output stream
434 * when true, only write the dataset for the alignment, not the data associated with the view.
440 public JalviewModel SaveState(AlignmentPanel ap, String fileName, boolean storeDS,
441 JarOutputStream jout)
444 Vector jmolViewIds = new Vector(); //
445 Vector userColours = new Vector();
447 AlignViewport av = ap.av;
449 JalviewModel object = new JalviewModel();
450 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
452 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
453 object.setVersion(jalview.bin.Cache.getDefault("VERSION","Development Build"));
455 jalview.datamodel.AlignmentI jal = av.getAlignment();
457 if (av.hasHiddenRows())
459 jal = jal.getHiddenSequences().getFullAlignment();
462 SequenceSet vamsasSet = new SequenceSet();
464 JalviewModelSequence jms = new JalviewModelSequence();
466 vamsasSet.setGapChar(jal.getGapCharacter() + "");
468 if (jal.getDataset() != null)
470 // dataset id is the dataset's hashcode
471 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
474 // switch jal and the dataset
475 jal = jal.getDataset();
478 if (jal.getProperties() != null)
480 Enumeration en = jal.getProperties().keys();
481 while (en.hasMoreElements())
483 String key = en.nextElement().toString();
484 SequenceSetProperties ssp = new SequenceSetProperties();
486 ssp.setValue(jal.getProperties().get(key).toString());
487 vamsasSet.addSequenceSetProperties(ssp);
492 Set<String> calcIdSet = new HashSet<String>();
496 jalview.datamodel.SequenceI jds,jdatasq;
497 for (int i = 0; i < jal.getHeight(); i++)
499 jds = jal.getSequenceAt(i);
500 jdatasq=jds.getDatasetSequence() == null ? jds : jds.getDatasetSequence();
503 if (seqRefIds.get(id) != null)
505 // This happens for two reasons: 1. multiple views are being serialised.
506 // 2. the hashCode has collided with another sequence's code. This DOES
507 // HAPPEN! (PF00072.15.stk does this)
508 // JBPNote: Uncomment to debug writing out of files that do not read
509 // back in due to ArrayOutOfBoundExceptions.
510 // System.err.println("vamsasSeq backref: "+id+"");
511 // System.err.println(jds.getName()+"
512 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
513 // System.err.println("Hashcode: "+seqHash(jds));
514 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
515 // System.err.println(rsq.getName()+"
516 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
517 // System.err.println("Hashcode: "+seqHash(rsq));
521 vamsasSeq = createVamsasSequence(id, jds);
522 vamsasSet.addSequence(vamsasSeq);
523 seqRefIds.put(id, jds);
527 jseq.setStart(jds.getStart());
528 jseq.setEnd(jds.getEnd());
529 jseq.setColour(av.getSequenceColour(jds).getRGB());
531 jseq.setId(id); // jseq id should be a string not a number
534 // Store any sequences this sequence represents
535 if (av.hasHiddenRows())
537 jseq.setHidden(av.getAlignment().getHiddenSequences()
540 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
542 jalview.datamodel.SequenceI[] reps = av
543 .getRepresentedSequences(jal.getSequenceAt(i))
544 .getSequencesInOrder(jal);
546 for (int h = 0; h < reps.length; h++)
548 if (reps[h] != jal.getSequenceAt(i))
550 jseq.addHiddenSequences(jal.findIndex(reps[h]));
557 if (jdatasq.getSequenceFeatures() != null)
559 jalview.datamodel.SequenceFeature[] sf = jdatasq
560 .getSequenceFeatures();
562 while (index < sf.length)
564 Features features = new Features();
566 features.setBegin(sf[index].getBegin());
567 features.setEnd(sf[index].getEnd());
568 features.setDescription(sf[index].getDescription());
569 features.setType(sf[index].getType());
570 features.setFeatureGroup(sf[index].getFeatureGroup());
571 features.setScore(sf[index].getScore());
572 if (sf[index].links != null)
574 for (int l = 0; l < sf[index].links.size(); l++)
576 OtherData keyValue = new OtherData();
577 keyValue.setKey("LINK_" + l);
578 keyValue.setValue(sf[index].links.elementAt(l).toString());
579 features.addOtherData(keyValue);
582 if (sf[index].otherDetails != null)
585 Enumeration keys = sf[index].otherDetails.keys();
586 while (keys.hasMoreElements())
588 key = keys.nextElement().toString();
589 OtherData keyValue = new OtherData();
590 keyValue.setKey(key);
591 keyValue.setValue(sf[index].otherDetails.get(key).toString());
592 features.addOtherData(keyValue);
596 jseq.addFeatures(features);
601 if (jdatasq.getPDBId() != null)
603 Enumeration en = jdatasq.getPDBId().elements();
604 while (en.hasMoreElements())
606 Pdbids pdb = new Pdbids();
607 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
610 pdb.setId(entry.getId());
611 pdb.setType(entry.getType());
613 // store any JMol views associated with this seqeunce
614 // this section copes with duplicate entries in the project, so a
615 // dataset only view *should* be coped with sensibly
617 // This must have been loaded, is it still visible?
618 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
619 String matchedFile = null;
620 for (int f = frames.length - 1; f > -1; f--)
622 if (frames[f] instanceof AppJmol)
624 jmol = (AppJmol) frames[f];
625 for (int peid = 0; peid < jmol.jmb.pdbentry.length; peid++)
627 if (!jmol.jmb.pdbentry[peid].getId().equals(entry.getId())
628 && !(entry.getId().length() > 4 && entry
632 jmol.jmb.pdbentry[peid].getId()
635 if (matchedFile == null)
637 matchedFile = jmol.jmb.pdbentry[peid].getFile();
639 else if (!matchedFile.equals(jmol.jmb.pdbentry[peid]
643 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
644 + jmol.jmb.pdbentry[peid].getFile());
648 // can get at it if the ID
649 // match is ambiguous (e.g.
651 String statestring = jmol.jmb.viewer.getStateInfo();
653 for (int smap = 0; smap < jmol.jmb.sequence[peid].length; smap++)
655 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
656 if (jds == jmol.jmb.sequence[peid][smap])
658 StructureState state = new StructureState();
659 state.setVisible(true);
660 state.setXpos(jmol.getX());
661 state.setYpos(jmol.getY());
662 state.setWidth(jmol.getWidth());
663 state.setHeight(jmol.getHeight());
664 state.setViewId(jmol.getViewId());
665 state.setAlignwithAlignPanel(jmol.isUsedforaligment(ap));
666 state.setColourwithAlignPanel(jmol
667 .isUsedforcolourby(ap));
668 state.setColourByJmol(jmol.isColouredByJmol());
669 if (!jmolViewIds.contains(state.getViewId()))
671 // Make sure we only store a Jmol state once in each XML
673 jmolViewIds.addElement(state.getViewId());
674 state.setContent(statestring.replaceAll("\n", ""));
678 state.setContent("# duplicate state");
680 pdb.addStructureState(state);
688 if (matchedFile != null || entry.getFile() != null)
690 if (entry.getFile() != null)
693 matchedFile = entry.getFile();
695 pdb.setFile(matchedFile); // entry.getFile());
696 if (pdbfiles == null)
698 pdbfiles = new Vector();
701 if (!pdbfiles.contains(entry.getId()))
703 pdbfiles.addElement(entry.getId());
706 File file = new File(matchedFile);
707 if (file.exists() && jout != null)
709 byte[] data = new byte[(int) file.length()];
710 jout.putNextEntry(new JarEntry(entry.getId()));
711 DataInputStream dis = new DataInputStream(
712 new FileInputStream(file));
715 DataOutputStream dout = new DataOutputStream(jout);
716 dout.write(data, 0, data.length);
720 } catch (Exception ex)
722 ex.printStackTrace();
728 if (entry.getProperty() != null)
730 PdbentryItem item = new PdbentryItem();
731 Hashtable properties = entry.getProperty();
732 Enumeration en2 = properties.keys();
733 while (en2.hasMoreElements())
735 Property prop = new Property();
736 String key = en2.nextElement().toString();
738 prop.setValue(properties.get(key).toString());
739 item.addProperty(prop);
741 pdb.addPdbentryItem(item);
751 if (!storeDS && av.hasHiddenRows())
753 jal = av.getAlignment();
756 if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0)
758 jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames();
759 for (int i = 0; i < jac.length; i++)
761 AlcodonFrame alc = new AlcodonFrame();
762 vamsasSet.addAlcodonFrame(alc);
763 for (int p = 0; p < jac[i].aaWidth; p++)
765 Alcodon cmap = new Alcodon();
766 if (jac[i].codons[p] != null)
768 // Null codons indicate a gapped column in the translated peptide
770 cmap.setPos1(jac[i].codons[p][0]);
771 cmap.setPos2(jac[i].codons[p][1]);
772 cmap.setPos3(jac[i].codons[p][2]);
774 alc.addAlcodon(cmap);
776 if (jac[i].getProtMappings() != null
777 && jac[i].getProtMappings().length > 0)
779 SequenceI[] dnas = jac[i].getdnaSeqs();
780 jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings();
781 for (int m = 0; m < pmaps.length; m++)
783 AlcodMap alcmap = new AlcodMap();
784 alcmap.setDnasq(seqHash(dnas[m]));
785 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
787 alc.addAlcodMap(alcmap);
794 // /////////////////////////////////
795 if (!storeDS && av.currentTree != null)
797 // FIND ANY ASSOCIATED TREES
798 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
799 if (Desktop.desktop != null)
801 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
803 for (int t = 0; t < frames.length; t++)
805 if (frames[t] instanceof TreePanel)
807 TreePanel tp = (TreePanel) frames[t];
809 if (tp.treeCanvas.av.getAlignment() == jal)
811 Tree tree = new Tree();
812 tree.setTitle(tp.getTitle());
813 tree.setCurrentTree((av.currentTree == tp.getTree()));
814 tree.setNewick(tp.getTree().toString());
815 tree.setThreshold(tp.treeCanvas.threshold);
817 tree.setFitToWindow(tp.fitToWindow.getState());
818 tree.setFontName(tp.getTreeFont().getName());
819 tree.setFontSize(tp.getTreeFont().getSize());
820 tree.setFontStyle(tp.getTreeFont().getStyle());
821 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
823 tree.setShowBootstrap(tp.bootstrapMenu.getState());
824 tree.setShowDistances(tp.distanceMenu.getState());
826 tree.setHeight(tp.getHeight());
827 tree.setWidth(tp.getWidth());
828 tree.setXpos(tp.getX());
829 tree.setYpos(tp.getY());
830 tree.setId(makeHashCode(tp, null));
839 * store forward refs from an annotationRow to any groups
841 IdentityHashMap groupRefs = new IdentityHashMap();
844 for (SequenceI sq:jal.getSequences())
846 // Store annotation on dataset sequences only
847 jalview.datamodel.AlignmentAnnotation[] aa = sq.getAnnotation();
848 if (aa!=null && aa.length>0)
850 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
855 if (jal.getAlignmentAnnotation() != null)
857 // Store the annotation shown on the alignment.
858 jalview.datamodel.AlignmentAnnotation[] aa = jal
859 .getAlignmentAnnotation();
860 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
865 if (jal.getGroups() != null)
867 JGroup[] groups = new JGroup[jal.getGroups().size()];
869 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
871 groups[++i] = new JGroup();
873 groups[i].setStart(sg.getStartRes());
874 groups[i].setEnd(sg.getEndRes());
875 groups[i].setName(sg.getName());
876 if (groupRefs.containsKey(sg))
878 // group has references so set it's ID field
879 groups[i].setId(groupRefs.get(sg).toString());
883 if (sg.cs.conservationApplied())
885 groups[i].setConsThreshold(sg.cs.getConservationInc());
887 if (sg.cs instanceof jalview.schemes.UserColourScheme)
889 groups[i].setColour(SetUserColourScheme(sg.cs, userColours,
895 .setColour(ColourSchemeProperty.getColourName(sg.cs));
898 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
901 .setColour(ColourSchemeProperty
902 .getColourName(((jalview.schemes.AnnotationColourGradient) sg.cs)
905 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
908 .setColour(SetUserColourScheme(sg.cs, userColours, jms));
912 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
915 groups[i].setPidThreshold(sg.cs.getThreshold());
918 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
919 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
920 groups[i].setDisplayText(sg.getDisplayText());
921 groups[i].setColourText(sg.getColourText());
922 groups[i].setTextCol1(sg.textColour.getRGB());
923 groups[i].setTextCol2(sg.textColour2.getRGB());
924 groups[i].setTextColThreshold(sg.thresholdTextColour);
925 groups[i].setShowUnconserved(sg.getShowNonconserved());
926 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
927 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
928 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
929 groups[i].setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
930 for (int s = 0; s < sg.getSize(); s++)
932 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
934 groups[i].addSeq(seqHash(seq));
938 jms.setJGroup(groups);
942 // /////////SAVE VIEWPORT
943 Viewport view = new Viewport();
944 view.setTitle(ap.alignFrame.getTitle());
945 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
946 av.getSequenceSetId()));
947 view.setId(av.getViewId());
948 view.setViewName(av.viewName);
949 view.setGatheredViews(av.gatherViewsHere);
951 if (ap.av.explodedPosition != null)
953 view.setXpos(av.explodedPosition.x);
954 view.setYpos(av.explodedPosition.y);
955 view.setWidth(av.explodedPosition.width);
956 view.setHeight(av.explodedPosition.height);
960 view.setXpos(ap.alignFrame.getBounds().x);
961 view.setYpos(ap.alignFrame.getBounds().y);
962 view.setWidth(ap.alignFrame.getBounds().width);
963 view.setHeight(ap.alignFrame.getBounds().height);
966 view.setStartRes(av.startRes);
967 view.setStartSeq(av.startSeq);
969 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
971 view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(),
974 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
976 jalview.schemes.AnnotationColourGradient acg = (jalview.schemes.AnnotationColourGradient) av
977 .getGlobalColourScheme();
979 AnnotationColours ac = new AnnotationColours();
980 ac.setAboveThreshold(acg.getAboveThreshold());
981 ac.setThreshold(acg.getAnnotationThreshold());
982 ac.setAnnotation(acg.getAnnotation());
983 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
985 ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
990 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
994 ac.setMaxColour(acg.getMaxColour().getRGB());
995 ac.setMinColour(acg.getMinColour().getRGB());
996 ac.setPerSequence(acg.isSeqAssociated());
997 ac.setPredefinedColours(acg.isPredefinedColours());
998 view.setAnnotationColours(ac);
999 view.setBgColour("AnnotationColourGradient");
1003 view.setBgColour(ColourSchemeProperty.getColourName(av
1004 .getGlobalColourScheme()));
1007 ColourSchemeI cs = av.getGlobalColourScheme();
1011 if (cs.conservationApplied())
1013 view.setConsThreshold(cs.getConservationInc());
1014 if (cs instanceof jalview.schemes.UserColourScheme)
1016 view.setBgColour(SetUserColourScheme(cs, userColours, jms));
1020 if (cs instanceof ResidueColourScheme)
1022 view.setPidThreshold(cs.getThreshold());
1026 view.setConservationSelected(av.getConservationSelected());
1027 view.setPidSelected(av.getAbovePIDThreshold());
1028 view.setFontName(av.font.getName());
1029 view.setFontSize(av.font.getSize());
1030 view.setFontStyle(av.font.getStyle());
1031 view.setRenderGaps(av.renderGaps);
1032 view.setShowAnnotation(av.getShowAnnotation());
1033 view.setShowBoxes(av.getShowBoxes());
1034 view.setShowColourText(av.getColourText());
1035 view.setShowFullId(av.getShowJVSuffix());
1036 view.setRightAlignIds(av.rightAlignIds);
1037 view.setShowSequenceFeatures(av.showSequenceFeatures);
1038 view.setShowText(av.getShowText());
1039 view.setShowUnconserved(av.getShowUnconserved());
1040 view.setWrapAlignment(av.getWrapAlignment());
1041 view.setTextCol1(av.textColour.getRGB());
1042 view.setTextCol2(av.textColour2.getRGB());
1043 view.setTextColThreshold(av.thresholdTextColour);
1044 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1045 view.setShowSequenceLogo(av.isShowSequenceLogo());
1046 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1047 view.setShowGroupConsensus(av.isShowGroupConsensus());
1048 view.setShowGroupConservation(av.isShowGroupConservation());
1049 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1050 view.setShowDbRefTooltip(av.isShowDbRefs());
1051 view.setFollowHighlight(av.followHighlight);
1052 view.setFollowSelection(av.followSelection);
1053 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1054 if (av.featuresDisplayed != null)
1056 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1058 String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;
1060 Vector settingsAdded = new Vector();
1061 Object gstyle = null;
1062 GraduatedColor gcol = null;
1063 if (renderOrder != null)
1065 for (int ro = 0; ro < renderOrder.length; ro++)
1067 gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer()
1068 .getFeatureStyle(renderOrder[ro]);
1069 Setting setting = new Setting();
1070 setting.setType(renderOrder[ro]);
1071 if (gstyle instanceof GraduatedColor)
1073 gcol = (GraduatedColor) gstyle;
1074 setting.setColour(gcol.getMaxColor().getRGB());
1075 setting.setMincolour(gcol.getMinColor().getRGB());
1076 setting.setMin(gcol.getMin());
1077 setting.setMax(gcol.getMax());
1078 setting.setColourByLabel(gcol.isColourByLabel());
1079 setting.setAutoScale(gcol.isAutoScale());
1080 setting.setThreshold(gcol.getThresh());
1081 setting.setThreshstate(gcol.getThreshType());
1085 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1086 .getColour(renderOrder[ro]).getRGB());
1089 setting.setDisplay(av.featuresDisplayed
1090 .containsKey(renderOrder[ro]));
1091 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1092 .getOrder(renderOrder[ro]);
1095 setting.setOrder(rorder);
1097 fs.addSetting(setting);
1098 settingsAdded.addElement(renderOrder[ro]);
1102 // Make sure we save none displayed feature settings
1103 Iterator en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours
1104 .keySet().iterator();
1105 while (en.hasNext())
1107 String key = en.next().toString();
1108 if (settingsAdded.contains(key))
1113 Setting setting = new Setting();
1114 setting.setType(key);
1115 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1116 .getColour(key).getRGB());
1118 setting.setDisplay(false);
1119 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1123 setting.setOrder(rorder);
1125 fs.addSetting(setting);
1126 settingsAdded.addElement(key);
1128 en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1129 .keySet().iterator();
1130 Vector groupsAdded = new Vector();
1131 while (en.hasNext())
1133 String grp = en.next().toString();
1134 if (groupsAdded.contains(grp))
1138 Group g = new Group();
1140 g.setDisplay(((Boolean) ap.seqPanel.seqCanvas
1141 .getFeatureRenderer().featureGroups.get(grp))
1144 groupsAdded.addElement(grp);
1146 jms.setFeatureSettings(fs);
1150 if (av.hasHiddenColumns())
1152 if (av.getColumnSelection() == null
1153 || av.getColumnSelection().getHiddenColumns() == null)
1155 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1159 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1162 int[] region = (int[]) av.getColumnSelection()
1163 .getHiddenColumns().elementAt(c);
1164 HiddenColumns hc = new HiddenColumns();
1165 hc.setStart(region[0]);
1166 hc.setEnd(region[1]);
1167 view.addHiddenColumns(hc);
1171 if (calcIdSet.size() > 0)
1173 for (String calcId : calcIdSet)
1175 if (calcId.trim().length() > 0)
1177 CalcIdParam cidp = createCalcIdParam(calcId, av);
1178 // Some calcIds have no parameters.
1181 view.addCalcIdParam(cidp);
1187 jms.addViewport(view);
1189 object.setJalviewModelSequence(jms);
1190 object.getVamsasModel().addSequenceSet(vamsasSet);
1192 if (jout != null && fileName != null)
1194 // We may not want to write the object to disk,
1195 // eg we can copy the alignViewport to a new view object
1196 // using save and then load
1199 JarEntry entry = new JarEntry(fileName);
1200 jout.putNextEntry(entry);
1201 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1203 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1205 marshaller.marshal(object);
1208 } catch (Exception ex)
1210 // TODO: raise error in GUI if marshalling failed.
1211 ex.printStackTrace();
1217 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa, IdentityHashMap groupRefs, AlignmentViewport av, Set<String> calcIdSet, boolean storeDS, SequenceSet vamsasSet)
1220 for (int i = 0; i < aa.length; i++)
1222 Annotation an = new Annotation();
1224 if (aa[i].annotationId != null)
1226 annotationIds.put(aa[i].annotationId, aa[i]);
1229 an.setId(aa[i].annotationId);
1231 an.setVisible(aa[i].visible);
1233 an.setDescription(aa[i].description);
1235 if (aa[i].sequenceRef != null)
1237 // TODO later annotation sequenceRef should be the XML ID of the
1238 // sequence rather than its display name
1239 an.setSequenceRef(aa[i].sequenceRef.getName());
1241 if (aa[i].groupRef != null)
1243 Object groupIdr = groupRefs.get(aa[i].groupRef);
1244 if (groupIdr == null)
1246 // make a locally unique String
1247 groupRefs.put(aa[i].groupRef,
1248 groupIdr = ("" + System.currentTimeMillis()
1249 + aa[i].groupRef.getName() + groupRefs.size()));
1251 an.setGroupRef(groupIdr.toString());
1254 // store all visualization attributes for annotation
1255 an.setGraphHeight(aa[i].graphHeight);
1256 an.setCentreColLabels(aa[i].centreColLabels);
1257 an.setScaleColLabels(aa[i].scaleColLabel);
1258 an.setShowAllColLabels(aa[i].showAllColLabels);
1259 an.setBelowAlignment(aa[i].belowAlignment);
1261 if (aa[i].graph > 0)
1264 an.setGraphType(aa[i].graph);
1265 an.setGraphGroup(aa[i].graphGroup);
1266 if (aa[i].getThreshold() != null)
1268 ThresholdLine line = new ThresholdLine();
1269 line.setLabel(aa[i].getThreshold().label);
1270 line.setValue(aa[i].getThreshold().value);
1271 line.setColour(aa[i].getThreshold().colour.getRGB());
1272 an.setThresholdLine(line);
1280 an.setLabel(aa[i].label);
1282 if (aa[i] == av.getAlignmentQualityAnnot()
1283 || aa[i] == av.getAlignmentConservationAnnotation()
1284 || aa[i] == av.getAlignmentConsensusAnnotation()
1285 || aa[i].autoCalculated)
1287 // new way of indicating autocalculated annotation -
1288 an.setAutoCalculated(aa[i].autoCalculated);
1290 if (aa[i].hasScore())
1292 an.setScore(aa[i].getScore());
1295 if (aa[i].getCalcId() != null)
1297 calcIdSet.add(aa[i].getCalcId());
1298 an.setCalcId(aa[i].getCalcId());
1301 AnnotationElement ae;
1302 if (aa[i].annotations != null)
1304 an.setScoreOnly(false);
1305 for (int a = 0; a < aa[i].annotations.length; a++)
1307 if ((aa[i] == null) || (aa[i].annotations[a] == null))
1312 ae = new AnnotationElement();
1313 if (aa[i].annotations[a].description != null)
1314 ae.setDescription(aa[i].annotations[a].description);
1315 if (aa[i].annotations[a].displayCharacter != null)
1316 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
1318 if (!Float.isNaN(aa[i].annotations[a].value))
1319 ae.setValue(aa[i].annotations[a].value);
1322 if (aa[i].annotations[a].secondaryStructure != ' '
1323 && aa[i].annotations[a].secondaryStructure != '\0')
1324 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
1327 if (aa[i].annotations[a].colour != null
1328 && aa[i].annotations[a].colour != java.awt.Color.black)
1330 ae.setColour(aa[i].annotations[a].colour.getRGB());
1333 an.addAnnotationElement(ae);
1334 if (aa[i].autoCalculated)
1336 // only write one non-null entry into the annotation row -
1337 // sufficient to get the visualization attributes necessary to
1345 an.setScoreOnly(true);
1347 if (!storeDS || (storeDS && !aa[i].autoCalculated))
1349 // skip autocalculated annotation - these are only provided for alignments
1350 vamsasSet.addAnnotation(an);
1356 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1358 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1359 if (settings != null)
1361 CalcIdParam vCalcIdParam = new CalcIdParam();
1362 vCalcIdParam.setCalcId(calcId);
1363 vCalcIdParam.addServiceURL(settings.getServiceURI());
1364 // generic URI allowing a third party to resolve another instance of the
1365 // service used for this calculation
1366 for (String urls : settings.getServiceURLs())
1368 vCalcIdParam.addServiceURL(urls);
1370 vCalcIdParam.setVersion("1.0");
1371 if (settings.getPreset() != null)
1373 WsParamSetI setting = settings.getPreset();
1374 vCalcIdParam.setName(setting.getName());
1375 vCalcIdParam.setDescription(setting.getDescription());
1379 vCalcIdParam.setName("");
1380 vCalcIdParam.setDescription("Last used parameters");
1382 // need to be able to recover 1) settings 2) user-defined presets or
1383 // recreate settings from preset 3) predefined settings provided by
1384 // service - or settings that can be transferred (or discarded)
1385 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1387 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1388 // todo - decide if updateImmediately is needed for any projects.
1390 return vCalcIdParam;
1395 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1398 if (calcIdParam.getVersion().equals("1.0"))
1400 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1401 .getPreferredServiceFor(calcIdParam.getServiceURL());
1402 if (service != null)
1404 WsParamSetI parmSet = null;
1407 parmSet = service.getParamStore().parseServiceParameterFile(
1408 calcIdParam.getName(), calcIdParam.getDescription(),
1409 calcIdParam.getServiceURL(),
1410 calcIdParam.getParameters().replace("|\\n|", "\n"));
1411 } catch (IOException x)
1413 warn("Couldn't parse parameter data for "
1414 + calcIdParam.getCalcId(), x);
1417 List<ArgumentI> argList = null;
1418 if (calcIdParam.getName().length() > 0)
1420 parmSet = service.getParamStore()
1421 .getPreset(calcIdParam.getName());
1422 if (parmSet != null)
1424 // TODO : check we have a good match with settings in AACon -
1425 // otherwise we'll need to create a new preset
1430 argList = parmSet.getArguments();
1433 AAConSettings settings = new AAConSettings(
1434 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1435 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1436 calcIdParam.isNeedsUpdate());
1441 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1445 throw new Error("Unsupported Version for calcIdparam "
1446 + calcIdParam.toString());
1450 * External mapping between jalview objects and objects yielding a valid and
1451 * unique object ID string. This is null for normal Jalview project IO, but
1452 * non-null when a jalview project is being read or written as part of a
1455 IdentityHashMap jv2vobj = null;
1458 * Construct a unique ID for jvobj using either existing bindings or if none
1459 * exist, the result of the hashcode call for the object.
1462 * jalview data object
1463 * @return unique ID for referring to jvobj
1465 private String makeHashCode(Object jvobj, String altCode)
1467 if (jv2vobj != null)
1469 Object id = jv2vobj.get(jvobj);
1472 return id.toString();
1474 // check string ID mappings
1475 if (jvids2vobj != null && jvobj instanceof String)
1477 id = jvids2vobj.get(jvobj);
1481 return id.toString();
1483 // give up and warn that something has gone wrong
1484 warn("Cannot find ID for object in external mapping : " + jvobj);
1490 * return local jalview object mapped to ID, if it exists
1494 * @return null or object bound to idcode
1496 private Object retrieveExistingObj(String idcode)
1498 if (idcode != null && vobj2jv != null)
1500 return vobj2jv.get(idcode);
1506 * binding from ID strings from external mapping table to jalview data model
1509 private Hashtable vobj2jv;
1511 private Sequence createVamsasSequence(String id, SequenceI jds)
1513 return createVamsasSequence(true, id, jds, null);
1516 private Sequence createVamsasSequence(boolean recurse, String id,
1517 SequenceI jds, SequenceI parentseq)
1519 Sequence vamsasSeq = new Sequence();
1520 vamsasSeq.setId(id);
1521 vamsasSeq.setName(jds.getName());
1522 vamsasSeq.setSequence(jds.getSequenceAsString());
1523 vamsasSeq.setDescription(jds.getDescription());
1524 jalview.datamodel.DBRefEntry[] dbrefs = null;
1525 if (jds.getDatasetSequence() != null)
1527 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1528 if (jds.getDatasetSequence().getDBRef() != null)
1530 dbrefs = jds.getDatasetSequence().getDBRef();
1535 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1536 // dataset sequences only
1537 dbrefs = jds.getDBRef();
1541 for (int d = 0; d < dbrefs.length; d++)
1543 DBRef dbref = new DBRef();
1544 dbref.setSource(dbrefs[d].getSource());
1545 dbref.setVersion(dbrefs[d].getVersion());
1546 dbref.setAccessionId(dbrefs[d].getAccessionId());
1547 if (dbrefs[d].hasMap())
1549 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1551 dbref.setMapping(mp);
1553 vamsasSeq.addDBRef(dbref);
1559 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1560 SequenceI parentseq, SequenceI jds, boolean recurse)
1563 if (jmp.getMap() != null)
1567 jalview.util.MapList mlst = jmp.getMap();
1568 int r[] = mlst.getFromRanges();
1569 for (int s = 0; s < r.length; s += 2)
1571 MapListFrom mfrom = new MapListFrom();
1572 mfrom.setStart(r[s]);
1573 mfrom.setEnd(r[s + 1]);
1574 mp.addMapListFrom(mfrom);
1576 r = mlst.getToRanges();
1577 for (int s = 0; s < r.length; s += 2)
1579 MapListTo mto = new MapListTo();
1581 mto.setEnd(r[s + 1]);
1582 mp.addMapListTo(mto);
1584 mp.setMapFromUnit(mlst.getFromRatio());
1585 mp.setMapToUnit(mlst.getToRatio());
1586 if (jmp.getTo() != null)
1588 MappingChoice mpc = new MappingChoice();
1590 && (parentseq != jmp.getTo() || parentseq
1591 .getDatasetSequence() != jmp.getTo()))
1593 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1599 SequenceI ps = null;
1600 if (parentseq != jmp.getTo()
1601 && parentseq.getDatasetSequence() != jmp.getTo())
1603 // chaining dbref rather than a handshaking one
1604 jmpid = seqHash(ps = jmp.getTo());
1608 jmpid = seqHash(ps = parentseq);
1610 mpc.setDseqFor(jmpid);
1611 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1613 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1614 seqRefIds.put(mpc.getDseqFor(), ps);
1618 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1621 mp.setMappingChoice(mpc);
1627 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1628 Vector userColours, JalviewModelSequence jms)
1631 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1632 boolean newucs = false;
1633 if (!userColours.contains(ucs))
1635 userColours.add(ucs);
1638 id = "ucs" + userColours.indexOf(ucs);
1641 // actually create the scheme's entry in the XML model
1642 java.awt.Color[] colours = ucs.getColours();
1643 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1644 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1646 for (int i = 0; i < colours.length; i++)
1648 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1649 col.setName(ResidueProperties.aa[i]);
1650 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1651 jbucs.addColour(col);
1653 if (ucs.getLowerCaseColours() != null)
1655 colours = ucs.getLowerCaseColours();
1656 for (int i = 0; i < colours.length; i++)
1658 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1659 col.setName(ResidueProperties.aa[i].toLowerCase());
1660 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1661 jbucs.addColour(col);
1666 uc.setUserColourScheme(jbucs);
1667 jms.addUserColours(uc);
1673 jalview.schemes.UserColourScheme GetUserColourScheme(
1674 JalviewModelSequence jms, String id)
1676 UserColours[] uc = jms.getUserColours();
1677 UserColours colours = null;
1679 for (int i = 0; i < uc.length; i++)
1681 if (uc[i].getId().equals(id))
1689 java.awt.Color[] newColours = new java.awt.Color[24];
1691 for (int i = 0; i < 24; i++)
1693 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1694 .getUserColourScheme().getColour(i).getRGB(), 16));
1697 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1700 if (colours.getUserColourScheme().getColourCount() > 24)
1702 newColours = new java.awt.Color[23];
1703 for (int i = 0; i < 23; i++)
1705 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1706 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1708 ucs.setLowerCaseColours(newColours);
1715 * contains last error message (if any) encountered by XML loader.
1717 String errorMessage = null;
1720 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1721 * exceptions are raised during project XML parsing
1723 public boolean attemptversion1parse = true;
1726 * Load a jalview project archive from a jar file
1729 * - HTTP URL or filename
1731 public AlignFrame LoadJalviewAlign(final String file)
1734 jalview.gui.AlignFrame af = null;
1738 // create list to store references for any new Jmol viewers created
1739 newStructureViewers=new Vector<AppJmol>();
1740 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1741 // Workaround is to make sure caller implements the JarInputStreamProvider
1743 // so we can re-open the jar input stream for each entry.
1745 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1746 af = LoadJalviewAlign(jprovider);
1748 } catch (MalformedURLException e)
1750 errorMessage = "Invalid URL format for '" + file + "'";
1756 SwingUtilities.invokeAndWait(new Runnable()
1760 setLoadingFinishedForNewStructureViewers();
1763 } catch (Exception x)
1771 private jarInputStreamProvider createjarInputStreamProvider(
1772 final String file) throws MalformedURLException
1775 errorMessage = null;
1776 uniqueSetSuffix = null;
1778 viewportsAdded = null;
1779 frefedSequence = null;
1781 if (file.startsWith("http://"))
1783 url = new URL(file);
1785 final URL _url = url;
1786 return new jarInputStreamProvider()
1790 public JarInputStream getJarInputStream() throws IOException
1794 return new JarInputStream(_url.openStream());
1798 return new JarInputStream(new FileInputStream(file));
1803 public String getFilename()
1811 * Recover jalview session from a jalview project archive. Caller may
1812 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1813 * themselves. Any null fields will be initialised with default values,
1814 * non-null fields are left alone.
1819 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1821 errorMessage = null;
1822 if (uniqueSetSuffix == null)
1824 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1826 if (seqRefIds == null)
1828 seqRefIds = new Hashtable();
1830 if (viewportsAdded == null)
1832 viewportsAdded = new Hashtable();
1834 if (frefedSequence == null)
1836 frefedSequence = new Vector();
1839 jalview.gui.AlignFrame af = null;
1840 Hashtable gatherToThisFrame = new Hashtable();
1841 final String file = jprovider.getFilename();
1844 JarInputStream jin = null;
1845 JarEntry jarentry = null;
1850 jin = jprovider.getJarInputStream();
1851 for (int i = 0; i < entryCount; i++)
1853 jarentry = jin.getNextJarEntry();
1856 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1858 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1859 JalviewModel object = new JalviewModel();
1861 Unmarshaller unmar = new Unmarshaller(object);
1862 unmar.setValidation(false);
1863 object = (JalviewModel) unmar.unmarshal(in);
1864 if (true) // !skipViewport(object))
1866 af = LoadFromObject(object, file, true, jprovider);
1867 if (af.viewport.gatherViewsHere)
1869 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
1874 else if (jarentry != null)
1876 // Some other file here.
1879 } while (jarentry != null);
1880 resolveFrefedSequences();
1881 } catch (java.io.FileNotFoundException ex)
1883 ex.printStackTrace();
1884 errorMessage = "Couldn't locate Jalview XML file : " + file;
1885 System.err.println("Exception whilst loading jalview XML file : "
1887 } catch (java.net.UnknownHostException ex)
1889 ex.printStackTrace();
1890 errorMessage = "Couldn't locate Jalview XML file : " + file;
1891 System.err.println("Exception whilst loading jalview XML file : "
1893 } catch (Exception ex)
1895 System.err.println("Parsing as Jalview Version 2 file failed.");
1896 ex.printStackTrace(System.err);
1897 if (attemptversion1parse)
1899 // Is Version 1 Jar file?
1902 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
1903 } catch (Exception ex2)
1905 System.err.println("Exception whilst loading as jalviewXMLV1:");
1906 ex2.printStackTrace();
1910 if (Desktop.instance != null)
1912 Desktop.instance.stopLoading();
1916 System.out.println("Successfully loaded archive file");
1919 ex.printStackTrace();
1921 System.err.println("Exception whilst loading jalview XML file : "
1923 } catch (OutOfMemoryError e)
1925 // Don't use the OOM Window here
1926 errorMessage = "Out of memory loading jalview XML file";
1927 System.err.println("Out of memory whilst loading jalview XML file");
1928 e.printStackTrace();
1931 if (Desktop.instance != null)
1933 Desktop.instance.stopLoading();
1936 Enumeration en = gatherToThisFrame.elements();
1937 while (en.hasMoreElements())
1939 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
1941 if (errorMessage != null)
1949 * check errorMessage for a valid error message and raise an error box in the
1950 * GUI or write the current errorMessage to stderr and then clear the error
1953 protected void reportErrors()
1955 reportErrors(false);
1958 protected void reportErrors(final boolean saving)
1960 if (errorMessage != null)
1962 final String finalErrorMessage = errorMessage;
1965 javax.swing.SwingUtilities.invokeLater(new Runnable()
1970 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1971 finalErrorMessage, "Error "
1972 + (saving ? "saving" : "loading")
1973 + " Jalview file", JOptionPane.WARNING_MESSAGE);
1979 System.err.println("Problem loading Jalview file: " + errorMessage);
1982 errorMessage = null;
1985 Hashtable alreadyLoadedPDB;
1988 * when set, local views will be updated from view stored in JalviewXML
1989 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
1990 * sync if this is set to true.
1992 private final boolean updateLocalViews = false;
1994 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
1996 if (alreadyLoadedPDB == null)
1997 alreadyLoadedPDB = new Hashtable();
1999 if (alreadyLoadedPDB.containsKey(pdbId))
2000 return alreadyLoadedPDB.get(pdbId).toString();
2004 JarInputStream jin = jprovider.getJarInputStream();
2006 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2007 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2008 * FileInputStream(jprovider)); }
2011 JarEntry entry = null;
2014 entry = jin.getNextJarEntry();
2015 } while (entry != null && !entry.getName().equals(pdbId));
2018 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
2019 File outFile = File.createTempFile("jalview_pdb", ".txt");
2020 outFile.deleteOnExit();
2021 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
2024 while ((data = in.readLine()) != null)
2031 } catch (Exception foo)
2036 String t = outFile.getAbsolutePath();
2037 alreadyLoadedPDB.put(pdbId, t);
2042 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
2044 } catch (Exception ex)
2046 ex.printStackTrace();
2052 private class JvAnnotRow
2054 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2061 * persisted version of annotation row from which to take vis properties
2063 public jalview.datamodel.AlignmentAnnotation template;
2066 * original position of the annotation row in the alignment
2072 * Load alignment frame from jalview XML DOM object
2077 * filename source string
2078 * @param loadTreesAndStructures
2079 * when false only create Viewport
2081 * data source provider
2082 * @return alignment frame created from view stored in DOM
2084 AlignFrame LoadFromObject(JalviewModel object, String file,
2085 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2087 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2088 Sequence[] vamsasSeq = vamsasSet.getSequence();
2090 JalviewModelSequence jms = object.getJalviewModelSequence();
2092 Viewport view = jms.getViewport(0);
2093 // ////////////////////////////////
2096 Vector hiddenSeqs = null;
2097 jalview.datamodel.Sequence jseq;
2099 ArrayList tmpseqs = new ArrayList();
2101 boolean multipleView = false;
2103 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
2104 int vi = 0; // counter in vamsasSeq array
2105 for (int i = 0; i < JSEQ.length; i++)
2107 String seqId = JSEQ[i].getId();
2109 if (seqRefIds.get(seqId) != null)
2111 tmpseqs.add(seqRefIds.get(seqId));
2112 multipleView = true;
2116 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2117 vamsasSeq[vi].getSequence());
2118 jseq.setDescription(vamsasSeq[vi].getDescription());
2119 jseq.setStart(JSEQ[i].getStart());
2120 jseq.setEnd(JSEQ[i].getEnd());
2121 jseq.setVamsasId(uniqueSetSuffix + seqId);
2122 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2127 if (JSEQ[i].getHidden())
2129 if (hiddenSeqs == null)
2131 hiddenSeqs = new Vector();
2134 hiddenSeqs.addElement(seqRefIds.get(seqId));
2140 // Create the alignment object from the sequence set
2141 // ///////////////////////////////
2142 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2145 tmpseqs.toArray(orderedSeqs);
2147 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2150 // / Add the alignment properties
2151 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2153 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2154 al.setProperty(ssp.getKey(), ssp.getValue());
2158 // SequenceFeatures are added to the DatasetSequence,
2159 // so we must create or recover the dataset before loading features
2160 // ///////////////////////////////
2161 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2163 // older jalview projects do not have a dataset id.
2164 al.setDataset(null);
2168 recoverDatasetFor(vamsasSet, al);
2170 // ///////////////////////////////
2172 Hashtable pdbloaded = new Hashtable();
2175 // load sequence features, database references and any associated PDB
2176 // structures for the alignment
2177 for (int i = 0; i < vamsasSeq.length; i++)
2179 if (JSEQ[i].getFeaturesCount() > 0)
2181 Features[] features = JSEQ[i].getFeatures();
2182 for (int f = 0; f < features.length; f++)
2184 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2185 features[f].getType(), features[f].getDescription(),
2186 features[f].getStatus(), features[f].getBegin(),
2187 features[f].getEnd(), features[f].getFeatureGroup());
2189 sf.setScore(features[f].getScore());
2190 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2192 OtherData keyValue = features[f].getOtherData(od);
2193 if (keyValue.getKey().startsWith("LINK"))
2195 sf.addLink(keyValue.getValue());
2199 sf.setValue(keyValue.getKey(), keyValue.getValue());
2204 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2207 if (vamsasSeq[i].getDBRefCount() > 0)
2209 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2211 if (JSEQ[i].getPdbidsCount() > 0)
2213 Pdbids[] ids = JSEQ[i].getPdbids();
2214 for (int p = 0; p < ids.length; p++)
2216 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2217 entry.setId(ids[p].getId());
2218 entry.setType(ids[p].getType());
2219 if (ids[p].getFile() != null)
2221 if (!pdbloaded.containsKey(ids[p].getFile()))
2223 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2227 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2231 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2235 } // end !multipleview
2237 // ///////////////////////////////
2238 // LOAD SEQUENCE MAPPINGS
2240 if (vamsasSet.getAlcodonFrameCount() > 0)
2242 // TODO Potentially this should only be done once for all views of an
2244 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2245 for (int i = 0; i < alc.length; i++)
2247 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2248 alc[i].getAlcodonCount());
2249 if (alc[i].getAlcodonCount() > 0)
2251 Alcodon[] alcods = alc[i].getAlcodon();
2252 for (int p = 0; p < cf.codons.length; p++)
2254 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2255 && alcods[p].hasPos3())
2257 // translated codons require three valid positions
2258 cf.codons[p] = new int[3];
2259 cf.codons[p][0] = (int) alcods[p].getPos1();
2260 cf.codons[p][1] = (int) alcods[p].getPos2();
2261 cf.codons[p][2] = (int) alcods[p].getPos3();
2265 cf.codons[p] = null;
2269 if (alc[i].getAlcodMapCount() > 0)
2271 AlcodMap[] maps = alc[i].getAlcodMap();
2272 for (int m = 0; m < maps.length; m++)
2274 SequenceI dnaseq = (SequenceI) seqRefIds
2275 .get(maps[m].getDnasq());
2277 jalview.datamodel.Mapping mapping = null;
2278 // attach to dna sequence reference.
2279 if (maps[m].getMapping() != null)
2281 mapping = addMapping(maps[m].getMapping());
2285 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2290 frefedSequence.add(new Object[]
2291 { maps[m].getDnasq(), cf, mapping });
2295 al.addCodonFrame(cf);
2300 // ////////////////////////////////
2302 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2304 * store any annotations which forward reference a group's ID
2306 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2308 if (vamsasSet.getAnnotationCount() > 0)
2310 Annotation[] an = vamsasSet.getAnnotation();
2312 for (int i = 0; i < an.length; i++)
2315 * test if annotation is automatically calculated for this view only
2317 boolean autoForView = false;
2318 if (an[i].getLabel().equals("Quality")
2319 || an[i].getLabel().equals("Conservation")
2320 || an[i].getLabel().equals("Consensus"))
2322 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2324 if (!an[i].hasAutoCalculated())
2326 an[i].setAutoCalculated(true);
2330 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2332 // remove ID - we don't recover annotation from other views for
2333 // view-specific annotation
2337 // set visiblity for other annotation in this view
2338 if (an[i].getId() != null
2339 && annotationIds.containsKey(an[i].getId()))
2341 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2342 .get(an[i].getId());
2343 // in principle Visible should always be true for annotation displayed
2344 // in multiple views
2345 if (an[i].hasVisible())
2346 jda.visible = an[i].getVisible();
2348 al.addAnnotation(jda);
2352 // Construct new annotation from model.
2353 AnnotationElement[] ae = an[i].getAnnotationElement();
2354 jalview.datamodel.Annotation[] anot = null;
2355 java.awt.Color firstColour = null;
2357 if (!an[i].getScoreOnly())
2359 anot = new jalview.datamodel.Annotation[al.getWidth()];
2360 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2362 anpos = ae[aa].getPosition();
2364 if (anpos >= anot.length)
2367 anot[anpos] = new jalview.datamodel.Annotation(
2369 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2370 (ae[aa].getSecondaryStructure() == null || ae[aa]
2371 .getSecondaryStructure().length() == 0) ? ' '
2372 : ae[aa].getSecondaryStructure().charAt(0),
2376 // JBPNote: Consider verifying dataflow for IO of secondary
2377 // structure annotation read from Stockholm files
2378 // this was added to try to ensure that
2379 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2381 // anot[ae[aa].getPosition()].displayCharacter = "";
2383 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2384 if (firstColour == null)
2386 firstColour = anot[anpos].colour;
2390 jalview.datamodel.AlignmentAnnotation jaa = null;
2392 if (an[i].getGraph())
2394 float llim = 0, hlim = 0;
2395 // if (autoForView || an[i].isAutoCalculated()) {
2398 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2399 an[i].getDescription(), anot, llim, hlim,
2400 an[i].getGraphType());
2402 jaa.graphGroup = an[i].getGraphGroup();
2403 jaa._linecolour = firstColour;
2404 if (an[i].getThresholdLine() != null)
2406 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2407 .getThresholdLine().getValue(), an[i]
2408 .getThresholdLine().getLabel(), new java.awt.Color(
2409 an[i].getThresholdLine().getColour())));
2412 if (autoForView || an[i].isAutoCalculated())
2414 // Hardwire the symbol display line to ensure that labels for
2415 // histograms are displayed
2421 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2422 an[i].getDescription(), anot);
2423 jaa._linecolour = firstColour;
2425 // register new annotation
2426 if (an[i].getId() != null)
2428 annotationIds.put(an[i].getId(), jaa);
2429 jaa.annotationId = an[i].getId();
2431 // recover sequence association
2432 if (an[i].getSequenceRef() != null)
2434 if (al.findName(an[i].getSequenceRef()) != null)
2436 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2438 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2441 // and make a note of any group association
2442 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2444 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2445 .get(an[i].getGroupRef());
2448 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2449 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2454 if (an[i].hasScore())
2456 jaa.setScore(an[i].getScore());
2458 if (an[i].hasVisible())
2459 jaa.visible = an[i].getVisible();
2461 if (an[i].hasCentreColLabels())
2462 jaa.centreColLabels = an[i].getCentreColLabels();
2464 if (an[i].hasScaleColLabels())
2466 jaa.scaleColLabel = an[i].getScaleColLabels();
2468 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2470 // newer files have an 'autoCalculated' flag and store calculation
2471 // state in viewport properties
2472 jaa.autoCalculated = true; // means annotation will be marked for
2473 // update at end of load.
2475 if (an[i].hasGraphHeight())
2477 jaa.graphHeight = an[i].getGraphHeight();
2479 if (an[i].hasBelowAlignment())
2481 jaa.belowAlignment = an[i].isBelowAlignment();
2483 jaa.setCalcId(an[i].getCalcId());
2485 if (jaa.autoCalculated)
2487 autoAlan.add(new JvAnnotRow(i, jaa));
2490 // if (!autoForView)
2492 // add autocalculated group annotation and any user created annotation
2494 al.addAnnotation(jaa);
2499 // ///////////////////////
2501 // Create alignment markup and styles for this view
2502 if (jms.getJGroupCount() > 0)
2504 JGroup[] groups = jms.getJGroup();
2506 for (int i = 0; i < groups.length; i++)
2508 ColourSchemeI cs = null;
2510 if (groups[i].getColour() != null)
2512 if (groups[i].getColour().startsWith("ucs"))
2514 cs = GetUserColourScheme(jms, groups[i].getColour());
2518 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2523 cs.setThreshold(groups[i].getPidThreshold(), true);
2527 Vector seqs = new Vector();
2529 for (int s = 0; s < groups[i].getSeqCount(); s++)
2531 String seqId = groups[i].getSeq(s) + "";
2532 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2537 seqs.addElement(ts);
2541 if (seqs.size() < 1)
2546 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2547 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2548 groups[i].getDisplayText(), groups[i].getColourText(),
2549 groups[i].getStart(), groups[i].getEnd());
2551 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2553 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2554 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2555 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2556 .isShowUnconserved() : false);
2557 sg.thresholdTextColour = groups[i].getTextColThreshold();
2558 if (groups[i].hasShowConsensusHistogram())
2560 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2563 if (groups[i].hasShowSequenceLogo())
2565 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2567 if (groups[i].hasNormaliseSequenceLogo())
2569 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2571 if (groups[i].hasIgnoreGapsinConsensus())
2573 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2575 if (groups[i].getConsThreshold() != 0)
2577 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2578 "All", ResidueProperties.propHash, 3,
2579 sg.getSequences(null), 0, sg.getWidth() - 1);
2581 c.verdict(false, 25);
2582 sg.cs.setConservation(c);
2585 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2587 // re-instate unique group/annotation row reference
2588 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2589 .get(groups[i].getId());
2592 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2595 if (jaa.autoCalculated)
2597 // match up and try to set group autocalc alignment row for this
2599 if (jaa.label.startsWith("Consensus for "))
2601 sg.setConsensus(jaa);
2603 // match up and try to set group autocalc alignment row for this
2605 if (jaa.label.startsWith("Conservation for "))
2607 sg.setConservationRow(jaa);
2618 // ///////////////////////////////
2621 // If we just load in the same jar file again, the sequenceSetId
2622 // will be the same, and we end up with multiple references
2623 // to the same sequenceSet. We must modify this id on load
2624 // so that each load of the file gives a unique id
2625 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2626 String viewId = (view.getId() == null ? null : view.getId()
2628 AlignFrame af = null;
2629 AlignViewport av = null;
2630 // now check to see if we really need to create a new viewport.
2631 if (multipleView && viewportsAdded.size() == 0)
2633 // We recovered an alignment for which a viewport already exists.
2634 // TODO: fix up any settings necessary for overlaying stored state onto
2635 // state recovered from another document. (may not be necessary).
2636 // we may need a binding from a viewport in memory to one recovered from
2638 // and then recover its containing af to allow the settings to be applied.
2639 // TODO: fix for vamsas demo
2641 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2643 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2644 if (seqsetobj != null)
2646 if (seqsetobj instanceof String)
2648 uniqueSeqSetId = (String) seqsetobj;
2650 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2656 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2661 AlignmentPanel ap = null;
2662 boolean isnewview = true;
2665 // Check to see if this alignment already has a view id == viewId
2666 jalview.gui.AlignmentPanel views[] = Desktop
2667 .getAlignmentPanels(uniqueSeqSetId);
2668 if (views != null && views.length > 0)
2670 for (int v = 0; v < views.length; v++)
2672 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2674 // recover the existing alignpanel, alignframe, viewport
2675 af = views[v].alignFrame;
2678 // TODO: could even skip resetting view settings if we don't want to
2679 // change the local settings from other jalview processes
2688 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2689 uniqueSeqSetId, viewId, autoAlan);
2694 // /////////////////////////////////////
2695 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2699 for (int t = 0; t < jms.getTreeCount(); t++)
2702 Tree tree = jms.getTree(t);
2704 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2707 tp = af.ShowNewickTree(
2708 new jalview.io.NewickFile(tree.getNewick()),
2709 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2710 tree.getXpos(), tree.getYpos());
2711 if (tree.getId() != null)
2713 // perhaps bind the tree id to something ?
2718 // update local tree attributes ?
2719 // TODO: should check if tp has been manipulated by user - if so its
2720 // settings shouldn't be modified
2721 tp.setTitle(tree.getTitle());
2722 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2723 .getWidth(), tree.getHeight()));
2724 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2727 tp.treeCanvas.av = av; // af.viewport;
2728 tp.treeCanvas.ap = ap; // af.alignPanel;
2733 warn("There was a problem recovering stored Newick tree: \n"
2734 + tree.getNewick());
2738 tp.fitToWindow.setState(tree.getFitToWindow());
2739 tp.fitToWindow_actionPerformed(null);
2741 if (tree.getFontName() != null)
2743 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2744 .getFontStyle(), tree.getFontSize()));
2748 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2749 .getFontStyle(), tree.getFontSize()));
2752 tp.showPlaceholders(tree.getMarkUnlinked());
2753 tp.showBootstrap(tree.getShowBootstrap());
2754 tp.showDistances(tree.getShowDistances());
2756 tp.treeCanvas.threshold = tree.getThreshold();
2758 if (tree.getCurrentTree())
2760 af.viewport.setCurrentTree(tp.getTree());
2764 } catch (Exception ex)
2766 ex.printStackTrace();
2770 // //LOAD STRUCTURES
2771 if (loadTreesAndStructures)
2773 // run through all PDB ids on the alignment, and collect mappings between
2774 // jmol view ids and all sequences referring to it
2775 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2777 for (int i = 0; i < JSEQ.length; i++)
2779 if (JSEQ[i].getPdbidsCount() > 0)
2781 Pdbids[] ids = JSEQ[i].getPdbids();
2782 for (int p = 0; p < ids.length; p++)
2784 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2786 // check to see if we haven't already created this structure view
2787 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2788 : ids[p].getStructureState(s).getViewId()
2790 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2791 // Originally : ids[p].getFile()
2792 // : TODO: verify external PDB file recovery still works in normal
2793 // jalview project load
2794 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2795 jpdb.setId(ids[p].getId());
2797 int x = ids[p].getStructureState(s).getXpos();
2798 int y = ids[p].getStructureState(s).getYpos();
2799 int width = ids[p].getStructureState(s).getWidth();
2800 int height = ids[p].getStructureState(s).getHeight();
2802 // Probably don't need to do this anymore...
2803 // Desktop.desktop.getComponentAt(x, y);
2804 // TODO: NOW: check that this recovers the PDB file correctly.
2805 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2806 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2807 .get(JSEQ[i].getId() + "");
2808 if (sviewid == null)
2810 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2813 if (!jmolViewIds.containsKey(sviewid))
2815 jmolViewIds.put(sviewid, new Object[]
2817 { x, y, width, height }, "",
2818 new Hashtable<String, Object[]>(), new boolean[]
2819 { false, false, true } });
2820 // Legacy pre-2.7 conversion JAL-823 :
2821 // do not assume any view has to be linked for colour by
2825 // assemble String[] { pdb files }, String[] { id for each
2826 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2827 // seqs_file 2}, boolean[] {
2828 // linkAlignPanel,superposeWithAlignpanel}} from hash
2829 Object[] jmoldat = jmolViewIds.get(sviewid);
2830 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2831 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
2832 s).getAlignwithAlignPanel() : false;
2833 // never colour by linked panel if not specified
2834 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
2835 .hasColourwithAlignPanel() ? ids[p]
2836 .getStructureState(s).getColourwithAlignPanel()
2838 // default for pre-2.7 projects is that Jmol colouring is enabled
2839 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
2840 .hasColourByJmol() ? ids[p].getStructureState(s)
2841 .getColourByJmol() : true;
2843 if (((String) jmoldat[1]).length() < ids[p]
2844 .getStructureState(s).getContent().length())
2847 jmoldat[1] = ids[p].getStructureState(s).getContent();
2850 if (ids[p].getFile() != null)
2852 File mapkey = new File(ids[p].getFile());
2853 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
2855 if (seqstrmaps == null)
2857 ((Hashtable) jmoldat[2]).put(mapkey,
2858 seqstrmaps = new Object[]
2859 { pdbFile, ids[p].getId(), new Vector(),
2862 if (!((Vector) seqstrmaps[2]).contains(seq))
2864 ((Vector) seqstrmaps[2]).addElement(seq);
2865 // ((Vector)seqstrmaps[3]).addElement(n) :
2866 // in principle, chains
2867 // should be stored here : do we need to
2868 // TODO: store and recover seq/pdb_id :
2874 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");
2883 // Instantiate the associated Jmol views
2884 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
2886 String sviewid = entry.getKey();
2887 Object[] svattrib = entry.getValue();
2888 int[] geom = (int[]) svattrib[0];
2889 String state = (String) svattrib[1];
2890 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
2891 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
2892 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
2893 // collate the pdbfile -> sequence mappings from this view
2894 Vector<String> pdbfilenames = new Vector<String>();
2895 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
2896 Vector<String> pdbids = new Vector<String>();
2898 // Search to see if we've already created this Jmol view
2899 AppJmol comp = null;
2900 JInternalFrame[] frames = null;
2905 frames = Desktop.desktop.getAllFrames();
2906 } catch (ArrayIndexOutOfBoundsException e)
2908 // occasional No such child exceptions are thrown here...
2913 } catch (Exception f)
2918 } while (frames == null);
2919 // search for any Jmol windows already open from other
2920 // alignment views that exactly match the stored structure state
2921 for (int f = 0; comp == null && f < frames.length; f++)
2923 if (frames[f] instanceof AppJmol)
2926 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
2928 // post jalview 2.4 schema includes structure view id
2929 comp = (AppJmol) frames[f];
2931 else if (frames[f].getX() == x && frames[f].getY() == y
2932 && frames[f].getHeight() == height
2933 && frames[f].getWidth() == width)
2935 comp = (AppJmol) frames[f];
2942 // create a new Jmol window.
2943 // First parse the Jmol state to translate filenames loaded into the
2944 // view, and record the order in which files are shown in the Jmol
2945 // view, so we can add the sequence mappings in same order.
2946 StringBuffer newFileLoc = null;
2947 int cp = 0, ncp, ecp;
2948 while ((ncp = state.indexOf("load ", cp)) > -1)
2950 if (newFileLoc == null)
2952 newFileLoc = new StringBuffer();
2956 // look for next filename in load statement
2957 newFileLoc.append(state.substring(cp,
2958 ncp = (state.indexOf("\"", ncp + 1) + 1)));
2959 String oldfilenam = state.substring(ncp,
2960 ecp = state.indexOf("\"", ncp));
2961 // recover the new mapping data for this old filename
2962 // have to normalize filename - since Jmol and jalview do
2964 // translation differently.
2965 Object[] filedat = oldFiles.get(new File(oldfilenam));
2966 newFileLoc.append(Platform
2967 .escapeString((String) filedat[0]));
2968 pdbfilenames.addElement((String) filedat[0]);
2969 pdbids.addElement((String) filedat[1]);
2970 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2971 .toArray(new SequenceI[0]));
2972 newFileLoc.append("\"");
2973 cp = ecp + 1; // advance beyond last \" and set cursor so we can
2974 // look for next file statement.
2975 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
2979 // just append rest of state
2980 newFileLoc.append(state.substring(cp));
2985 .print("Ignoring incomplete Jmol state for PDB ids: ");
2986 newFileLoc = new StringBuffer(state);
2987 newFileLoc.append("; load append ");
2988 for (File id : oldFiles.keySet())
2990 // add this and any other pdb files that should be present in
2992 Object[] filedat = oldFiles.get(id);
2994 newFileLoc.append(((String) filedat[0]));
2995 pdbfilenames.addElement((String) filedat[0]);
2996 pdbids.addElement((String) filedat[1]);
2997 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2998 .toArray(new SequenceI[0]));
2999 newFileLoc.append(" \"");
3000 newFileLoc.append((String) filedat[0]);
3001 newFileLoc.append("\"");
3004 newFileLoc.append(";");
3007 if (newFileLoc != null)
3009 int histbug = newFileLoc.indexOf("history = ");
3011 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
3013 String val = (diff == -1) ? null : newFileLoc.substring(
3015 if (val != null && val.length() >= 4)
3017 if (val.contains("e"))
3019 if (val.trim().equals("true"))
3027 newFileLoc.replace(histbug, diff, val);
3030 // TODO: assemble String[] { pdb files }, String[] { id for each
3031 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3032 // seqs_file 2}} from hash
3033 final String[] pdbf = pdbfilenames
3034 .toArray(new String[pdbfilenames.size()]), id = pdbids
3035 .toArray(new String[pdbids.size()]);
3036 final SequenceI[][] sq = seqmaps
3037 .toArray(new SequenceI[seqmaps.size()][]);
3038 final String fileloc = newFileLoc.toString(), vid = sviewid;
3039 final AlignFrame alf = af;
3040 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
3044 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3049 AppJmol sview = null;
3052 sview = new AppJmol(pdbf, id, sq, alf.alignPanel,
3053 useinJmolsuperpos, usetoColourbyseq,
3054 jmolColouring, fileloc, rect, vid);
3055 addNewStructureViewer(sview);
3056 } catch (OutOfMemoryError ex)
3058 new OOMWarning("restoring structure view for PDB id "
3059 + id, (OutOfMemoryError) ex.getCause());
3060 if (sview != null && sview.isVisible())
3062 sview.closeViewer();
3063 sview.setVisible(false);
3069 } catch (InvocationTargetException ex)
3071 warn("Unexpected error when opening Jmol view.", ex);
3073 } catch (InterruptedException e)
3075 // e.printStackTrace();
3081 // if (comp != null)
3083 // NOTE: if the jalview project is part of a shared session then
3084 // view synchronization should/could be done here.
3086 // add mapping for sequences in this view to an already open Jmol
3088 for (File id : oldFiles.keySet())
3090 // add this and any other pdb files that should be present in the
3092 Object[] filedat = oldFiles.get(id);
3093 String pdbFile = (String) filedat[0];
3094 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3095 .toArray(new SequenceI[0]);
3096 comp.jmb.ssm.setMapping(seq, null, pdbFile,
3097 jalview.io.AppletFormatAdapter.FILE);
3098 comp.jmb.addSequenceForStructFile(pdbFile, seq);
3100 // and add the AlignmentPanel's reference to the Jmol view
3101 comp.addAlignmentPanel(ap);
3102 if (useinJmolsuperpos)
3104 comp.useAlignmentPanelForSuperposition(ap);
3108 comp.excludeAlignmentPanelForSuperposition(ap);
3110 if (usetoColourbyseq)
3112 comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3116 comp.excludeAlignmentPanelForColourbyseq(ap);
3122 // and finally return.
3125 Vector<AppJmol> newStructureViewers=null;
3126 protected void addNewStructureViewer(AppJmol sview)
3128 if (newStructureViewers!=null)
3130 sview.jmb.setFinishedLoadingFromArchive(false);
3131 newStructureViewers.add(sview);
3134 protected void setLoadingFinishedForNewStructureViewers()
3136 if (newStructureViewers!=null)
3138 for (AppJmol sview:newStructureViewers)
3140 sview.jmb.setFinishedLoadingFromArchive(true);
3142 newStructureViewers.clear();
3143 newStructureViewers=null;
3147 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3148 Alignment al, JalviewModelSequence jms, Viewport view,
3149 String uniqueSeqSetId, String viewId,
3150 ArrayList<JvAnnotRow> autoAlan)
3152 AlignFrame af = null;
3153 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3154 uniqueSeqSetId, viewId);
3156 af.setFileName(file, "Jalview");
3158 for (int i = 0; i < JSEQ.length; i++)
3160 af.viewport.setSequenceColour(af.viewport.getAlignment()
3161 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3164 af.viewport.gatherViewsHere = view.getGatheredViews();
3166 if (view.getSequenceSetId() != null)
3168 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3169 .get(uniqueSeqSetId);
3171 af.viewport.setSequenceSetId(uniqueSeqSetId);
3174 // propagate shared settings to this new view
3175 af.viewport.historyList = av.historyList;
3176 af.viewport.redoList = av.redoList;
3180 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3182 // TODO: check if this method can be called repeatedly without
3183 // side-effects if alignpanel already registered.
3184 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3186 // apply Hidden regions to view.
3187 if (hiddenSeqs != null)
3189 for (int s = 0; s < JSEQ.length; s++)
3191 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3193 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3196 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3198 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3201 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3204 for (int s = 0; s < hiddenSeqs.size(); s++)
3206 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3209 af.viewport.hideSequence(hseqs);
3212 // recover view properties and display parameters
3213 if (view.getViewName() != null)
3215 af.viewport.viewName = view.getViewName();
3216 af.setInitialTabVisible();
3218 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3221 af.viewport.setShowAnnotation(view.getShowAnnotation());
3222 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3224 af.viewport.setColourText(view.getShowColourText());
3226 af.viewport.setConservationSelected(view.getConservationSelected());
3227 af.viewport.setShowJVSuffix(view.getShowFullId());
3228 af.viewport.rightAlignIds = view.getRightAlignIds();
3229 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3230 .getFontStyle(), view.getFontSize()));
3231 af.alignPanel.fontChanged();
3232 af.viewport.setRenderGaps(view.getRenderGaps());
3233 af.viewport.setWrapAlignment(view.getWrapAlignment());
3234 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3235 af.viewport.setShowAnnotation(view.getShowAnnotation());
3236 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3238 af.viewport.setShowBoxes(view.getShowBoxes());
3240 af.viewport.setShowText(view.getShowText());
3242 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3243 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3244 af.viewport.thresholdTextColour = view.getTextColThreshold();
3245 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3246 .isShowUnconserved() : false);
3247 af.viewport.setStartRes(view.getStartRes());
3248 af.viewport.setStartSeq(view.getStartSeq());
3250 ColourSchemeI cs = null;
3251 // apply colourschemes
3252 if (view.getBgColour() != null)
3254 if (view.getBgColour().startsWith("ucs"))
3256 cs = GetUserColourScheme(jms, view.getBgColour());
3258 else if (view.getBgColour().startsWith("Annotation"))
3260 // int find annotation
3261 if (af.viewport.getAlignment().getAlignmentAnnotation() != null)
3263 for (int i = 0; i < af.viewport.getAlignment()
3264 .getAlignmentAnnotation().length; i++)
3266 if (af.viewport.getAlignment().getAlignmentAnnotation()[i].label
3267 .equals(view.getAnnotationColours().getAnnotation()))
3269 if (af.viewport.getAlignment().getAlignmentAnnotation()[i]
3270 .getThreshold() == null)
3272 af.viewport.getAlignment().getAlignmentAnnotation()[i]
3273 .setThreshold(new jalview.datamodel.GraphLine(view
3274 .getAnnotationColours().getThreshold(),
3275 "Threshold", java.awt.Color.black)
3280 if (view.getAnnotationColours().getColourScheme()
3283 cs = new AnnotationColourGradient(af.viewport
3284 .getAlignment().getAlignmentAnnotation()[i],
3285 new java.awt.Color(view.getAnnotationColours()
3286 .getMinColour()), new java.awt.Color(view
3287 .getAnnotationColours().getMaxColour()),
3288 view.getAnnotationColours().getAboveThreshold());
3290 else if (view.getAnnotationColours().getColourScheme()
3293 cs = new AnnotationColourGradient(af.viewport
3294 .getAlignment().getAlignmentAnnotation()[i],
3295 GetUserColourScheme(jms, view
3296 .getAnnotationColours().getColourScheme()),
3297 view.getAnnotationColours().getAboveThreshold());
3301 cs = new AnnotationColourGradient(af.viewport
3302 .getAlignment().getAlignmentAnnotation()[i],
3303 ColourSchemeProperty.getColour(al, view
3304 .getAnnotationColours().getColourScheme()),
3305 view.getAnnotationColours().getAboveThreshold());
3307 if (view.getAnnotationColours().hasPerSequence())
3309 ((AnnotationColourGradient)cs).setSeqAssociated(view.getAnnotationColours().isPerSequence());
3311 if (view.getAnnotationColours().hasPredefinedColours())
3313 ((AnnotationColourGradient)cs).setPredefinedColours(view.getAnnotationColours().isPredefinedColours());
3315 // Also use these settings for all the groups
3316 if (al.getGroups() != null)
3318 for (int g = 0; g < al.getGroups().size(); g++)
3320 jalview.datamodel.SequenceGroup sg = al.getGroups()
3330 * (view.getAnnotationColours().getColourScheme().equals("None"
3331 * )) { sg.cs = new AnnotationColourGradient(
3332 * af.viewport.getAlignment().getAlignmentAnnotation()[i], new
3333 * java.awt.Color(view.getAnnotationColours().
3334 * getMinColour()), new
3335 * java.awt.Color(view.getAnnotationColours().
3337 * view.getAnnotationColours().getAboveThreshold()); } else
3340 sg.cs = new AnnotationColourGradient(af.viewport
3341 .getAlignment().getAlignmentAnnotation()[i],
3342 sg.cs, view.getAnnotationColours()
3343 .getAboveThreshold());
3344 if (cs instanceof AnnotationColourGradient)
3346 if (view.getAnnotationColours().hasPerSequence())
3348 ((AnnotationColourGradient)cs).setSeqAssociated(view.getAnnotationColours().isPerSequence());
3350 if (view.getAnnotationColours().hasPredefinedColours())
3352 ((AnnotationColourGradient)cs).setPredefinedColours(view.getAnnotationColours().isPredefinedColours());
3368 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3373 cs.setThreshold(view.getPidThreshold(), true);
3374 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3378 af.viewport.setGlobalColourScheme(cs);
3379 af.viewport.setColourAppliesToAllGroups(false);
3381 if (view.getConservationSelected() && cs != null)
3383 cs.setConservationInc(view.getConsThreshold());
3386 af.changeColour(cs);
3388 af.viewport.setColourAppliesToAllGroups(true);
3390 if (view.getShowSequenceFeatures())
3392 af.viewport.showSequenceFeatures = true;
3394 if (view.hasCentreColumnLabels())
3396 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3398 if (view.hasIgnoreGapsinConsensus())
3400 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3403 if (view.hasFollowHighlight())
3405 af.viewport.followHighlight = view.getFollowHighlight();
3407 if (view.hasFollowSelection())
3409 af.viewport.followSelection = view.getFollowSelection();
3411 if (view.hasShowConsensusHistogram())
3413 af.viewport.setShowConsensusHistogram(view
3414 .getShowConsensusHistogram());
3418 af.viewport.setShowConsensusHistogram(true);
3420 if (view.hasShowSequenceLogo())
3422 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3426 af.viewport.setShowSequenceLogo(false);
3428 if (view.hasNormaliseSequenceLogo())
3430 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3432 if (view.hasShowDbRefTooltip())
3434 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3436 if (view.hasShowNPfeatureTooltip())
3438 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3440 if (view.hasShowGroupConsensus())
3442 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3446 af.viewport.setShowGroupConsensus(false);
3448 if (view.hasShowGroupConservation())
3450 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3454 af.viewport.setShowGroupConservation(false);
3457 // recover featre settings
3458 if (jms.getFeatureSettings() != null)
3460 af.viewport.featuresDisplayed = new Hashtable();
3461 String[] renderOrder = new String[jms.getFeatureSettings()
3462 .getSettingCount()];
3463 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3465 Setting setting = jms.getFeatureSettings().getSetting(fs);
3466 if (setting.hasMincolour())
3468 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3469 new java.awt.Color(setting.getMincolour()),
3470 new java.awt.Color(setting.getColour()),
3471 setting.getMin(), setting.getMax()) : new GraduatedColor(
3472 new java.awt.Color(setting.getMincolour()),
3473 new java.awt.Color(setting.getColour()), 0, 1);
3474 if (setting.hasThreshold())
3476 gc.setThresh(setting.getThreshold());
3477 gc.setThreshType(setting.getThreshstate());
3479 gc.setAutoScaled(true); // default
3480 if (setting.hasAutoScale())
3482 gc.setAutoScaled(setting.getAutoScale());
3484 if (setting.hasColourByLabel())
3486 gc.setColourByLabel(setting.getColourByLabel());
3488 // and put in the feature colour table.
3489 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3490 setting.getType(), gc);
3494 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3496 new java.awt.Color(setting.getColour()));
3498 renderOrder[fs] = setting.getType();
3499 if (setting.hasOrder())
3500 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3501 setting.getType(), setting.getOrder());
3503 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3505 fs / jms.getFeatureSettings().getSettingCount());
3506 if (setting.getDisplay())
3508 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3509 setting.getColour()));
3512 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3514 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3515 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3517 Group grp = jms.getFeatureSettings().getGroup(gs);
3518 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3522 if (view.getHiddenColumnsCount() > 0)
3524 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3526 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3527 .getHiddenColumns(c).getEnd() // +1
3531 if (view.getCalcIdParam() != null)
3533 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3535 if (calcIdParam != null)
3537 if (recoverCalcIdParam(calcIdParam, af.viewport))
3542 warn("Couldn't recover parameters for "
3543 + calcIdParam.getCalcId());
3548 af.setMenusFromViewport(af.viewport);
3549 // TODO: we don't need to do this if the viewport is aready visible.
3550 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3552 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3553 reorderAutoannotation(af, al, autoAlan);
3554 af.alignPanel.alignmentChanged();
3558 private void reorderAutoannotation(AlignFrame af, Alignment al,
3559 ArrayList<JvAnnotRow> autoAlan)
3561 // copy over visualization settings for autocalculated annotation in the
3563 if (al.getAlignmentAnnotation() != null)
3566 * Kludge for magic autoannotation names (see JAL-811)
3568 String[] magicNames = new String[]
3569 { "Consensus", "Quality", "Conservation" };
3570 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3571 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3572 for (String nm : magicNames)
3574 visan.put(nm, nullAnnot);
3576 for (JvAnnotRow auan : autoAlan)
3578 visan.put(auan.template.label
3579 + (auan.template.getCalcId() == null ? "" : "\t"
3580 + auan.template.getCalcId()), auan);
3582 int hSize = al.getAlignmentAnnotation().length;
3583 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3584 // work through any autoCalculated annotation already on the view
3585 // removing it if it should be placed in a different location on the
3586 // annotation panel.
3587 List<String> remains = new ArrayList(visan.keySet());
3588 for (int h = 0; h < hSize; h++)
3590 jalview.datamodel.AlignmentAnnotation jalan = al
3591 .getAlignmentAnnotation()[h];
3592 if (jalan.autoCalculated)
3595 JvAnnotRow valan = visan.get(k = jalan.label);
3596 if (jalan.getCalcId() != null)
3598 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
3603 // delete the auto calculated row from the alignment
3604 al.deleteAnnotation(jalan, false);
3608 if (valan != nullAnnot)
3610 if (jalan != valan.template)
3612 // newly created autoannotation row instance
3613 // so keep a reference to the visible annotation row
3614 // and copy over all relevant attributes
3615 if (valan.template.graphHeight >= 0)
3618 jalan.graphHeight = valan.template.graphHeight;
3620 jalan.visible = valan.template.visible;
3622 reorder.add(new JvAnnotRow(valan.order, jalan));
3627 // Add any (possibly stale) autocalculated rows that were not appended to
3628 // the view during construction
3629 for (String other : remains)
3631 JvAnnotRow othera = visan.get(other);
3632 if (othera != nullAnnot && othera.template.getCalcId() != null
3633 && othera.template.getCalcId().length() > 0)
3635 reorder.add(othera);
3638 // now put the automatic annotation in its correct place
3639 int s = 0, srt[] = new int[reorder.size()];
3640 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3641 for (JvAnnotRow jvar : reorder)
3644 srt[s++] = jvar.order;
3647 jalview.util.QuickSort.sort(srt, rws);
3648 // and re-insert the annotation at its correct position
3649 for (JvAnnotRow jvar : rws)
3651 al.addAnnotation(jvar.template, jvar.order);
3653 af.alignPanel.adjustAnnotationHeight();
3657 Hashtable skipList = null;
3660 * TODO remove this method
3663 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3664 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3665 * throw new Error("Implementation Error. No skipList defined for this
3666 * Jalview2XML instance."); } return (AlignFrame)
3667 * skipList.get(view.getSequenceSetId()); }
3671 * Check if the Jalview view contained in object should be skipped or not.
3674 * @return true if view's sequenceSetId is a key in skipList
3676 private boolean skipViewport(JalviewModel object)
3678 if (skipList == null)
3683 if (skipList.containsKey(id = object.getJalviewModelSequence()
3684 .getViewport()[0].getSequenceSetId()))
3686 if (Cache.log != null && Cache.log.isDebugEnabled())
3688 Cache.log.debug("Skipping seuqence set id " + id);
3695 public void AddToSkipList(AlignFrame af)
3697 if (skipList == null)
3699 skipList = new Hashtable();
3701 skipList.put(af.getViewport().getSequenceSetId(), af);
3704 public void clearSkipList()
3706 if (skipList != null)
3713 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3715 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3716 Vector dseqs = null;
3719 // create a list of new dataset sequences
3720 dseqs = new Vector();
3722 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3724 Sequence vamsasSeq = vamsasSet.getSequence(i);
3725 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
3727 // create a new dataset
3730 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3731 dseqs.copyInto(dsseqs);
3732 ds = new jalview.datamodel.Alignment(dsseqs);
3733 debug("Created new dataset " + vamsasSet.getDatasetId()
3734 + " for alignment " + System.identityHashCode(al));
3735 addDatasetRef(vamsasSet.getDatasetId(), ds);
3737 // set the dataset for the newly imported alignment.
3738 if (al.getDataset() == null)
3747 * sequence definition to create/merge dataset sequence for
3751 * vector to add new dataset sequence to
3753 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
3754 AlignmentI ds, Vector dseqs)
3756 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
3758 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
3759 .get(vamsasSeq.getId());
3760 jalview.datamodel.SequenceI dsq = null;
3761 if (sq != null && sq.getDatasetSequence() != null)
3763 dsq = sq.getDatasetSequence();
3766 String sqid = vamsasSeq.getDsseqid();
3769 // need to create or add a new dataset sequence reference to this sequence
3772 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
3777 // make a new dataset sequence
3778 dsq = sq.createDatasetSequence();
3781 // make up a new dataset reference for this sequence
3782 sqid = seqHash(dsq);
3784 dsq.setVamsasId(uniqueSetSuffix + sqid);
3785 seqRefIds.put(sqid, dsq);
3790 dseqs.addElement(dsq);
3795 ds.addSequence(dsq);
3801 { // make this dataset sequence sq's dataset sequence
3802 sq.setDatasetSequence(dsq);
3803 // and update the current dataset alignment
3806 if (!dseqs.contains(dsq))
3811 if (ds.findIndex(dsq)<0)
3813 ds.addSequence(dsq);
3820 // TODO: refactor this as a merge dataset sequence function
3821 // now check that sq (the dataset sequence) sequence really is the union of
3822 // all references to it
3823 // boolean pre = sq.getStart() < dsq.getStart();
3824 // boolean post = sq.getEnd() > dsq.getEnd();
3828 StringBuffer sb = new StringBuffer();
3829 String newres = jalview.analysis.AlignSeq.extractGaps(
3830 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
3831 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
3832 && newres.length() > dsq.getLength())
3834 // Update with the longer sequence.
3838 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
3839 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
3840 * sb.append(newres.substring(newres.length() - sq.getEnd() -
3841 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
3843 dsq.setSequence(newres);
3845 // TODO: merges will never happen if we 'know' we have the real dataset
3846 // sequence - this should be detected when id==dssid
3847 System.err.println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
3848 // + (pre ? "prepended" : "") + " "
3849 // + (post ? "appended" : ""));
3854 java.util.Hashtable datasetIds = null;
3856 java.util.IdentityHashMap dataset2Ids = null;
3858 private Alignment getDatasetFor(String datasetId)
3860 if (datasetIds == null)
3862 datasetIds = new Hashtable();
3865 if (datasetIds.containsKey(datasetId))
3867 return (Alignment) datasetIds.get(datasetId);
3872 private void addDatasetRef(String datasetId, Alignment dataset)
3874 if (datasetIds == null)
3876 datasetIds = new Hashtable();
3878 datasetIds.put(datasetId, dataset);
3882 * make a new dataset ID for this jalview dataset alignment
3887 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
3889 if (dataset.getDataset() != null)
3891 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
3893 String datasetId = makeHashCode(dataset, null);
3894 if (datasetId == null)
3896 // make a new datasetId and record it
3897 if (dataset2Ids == null)
3899 dataset2Ids = new IdentityHashMap();
3903 datasetId = (String) dataset2Ids.get(dataset);
3905 if (datasetId == null)
3907 datasetId = "ds" + dataset2Ids.size() + 1;
3908 dataset2Ids.put(dataset, datasetId);
3914 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
3916 for (int d = 0; d < sequence.getDBRefCount(); d++)
3918 DBRef dr = sequence.getDBRef(d);
3919 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
3920 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
3921 .getVersion(), sequence.getDBRef(d).getAccessionId());
3922 if (dr.getMapping() != null)
3924 entry.setMap(addMapping(dr.getMapping()));
3926 datasetSequence.addDBRef(entry);
3930 private jalview.datamodel.Mapping addMapping(Mapping m)
3932 SequenceI dsto = null;
3933 // Mapping m = dr.getMapping();
3934 int fr[] = new int[m.getMapListFromCount() * 2];
3935 Enumeration f = m.enumerateMapListFrom();
3936 for (int _i = 0; f.hasMoreElements(); _i += 2)
3938 MapListFrom mf = (MapListFrom) f.nextElement();
3939 fr[_i] = mf.getStart();
3940 fr[_i + 1] = mf.getEnd();
3942 int fto[] = new int[m.getMapListToCount() * 2];
3943 f = m.enumerateMapListTo();
3944 for (int _i = 0; f.hasMoreElements(); _i += 2)
3946 MapListTo mf = (MapListTo) f.nextElement();
3947 fto[_i] = mf.getStart();
3948 fto[_i + 1] = mf.getEnd();
3950 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
3951 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
3952 if (m.getMappingChoice() != null)
3954 MappingChoice mc = m.getMappingChoice();
3955 if (mc.getDseqFor() != null)
3957 String dsfor = "" + mc.getDseqFor();
3958 if (seqRefIds.containsKey(dsfor))
3963 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
3967 frefedSequence.add(new Object[]
3974 * local sequence definition
3976 Sequence ms = mc.getSequence();
3977 jalview.datamodel.Sequence djs = null;
3978 String sqid = ms.getDsseqid();
3979 if (sqid != null && sqid.length() > 0)
3982 * recover dataset sequence
3984 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
3989 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
3990 sqid = ((Object) ms).toString(); // make up a new hascode for
3991 // undefined dataset sequence hash
3992 // (unlikely to happen)
3998 * make a new dataset sequence and add it to refIds hash
4000 djs = new jalview.datamodel.Sequence(ms.getName(),
4002 djs.setStart(jmap.getMap().getToLowest());
4003 djs.setEnd(jmap.getMap().getToHighest());
4004 djs.setVamsasId(uniqueSetSuffix + sqid);
4006 seqRefIds.put(sqid, djs);
4009 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
4018 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
4019 boolean keepSeqRefs)
4022 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
4028 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
4032 uniqueSetSuffix = "";
4033 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
4038 if (this.frefedSequence == null)
4040 frefedSequence = new Vector();
4043 viewportsAdded = new Hashtable();
4045 AlignFrame af = LoadFromObject(jm, null, false, null);
4046 af.alignPanels.clear();
4047 af.closeMenuItem_actionPerformed(true);
4050 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
4051 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
4052 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
4053 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
4054 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
4057 return af.alignPanel;
4061 * flag indicating if hashtables should be cleared on finalization TODO this
4062 * flag may not be necessary
4064 private final boolean _cleartables = true;
4066 private Hashtable jvids2vobj;
4071 * @see java.lang.Object#finalize()
4074 protected void finalize() throws Throwable
4076 // really make sure we have no buried refs left.
4081 this.seqRefIds = null;
4082 this.seqsToIds = null;
4086 private void warn(String msg)
4091 private void warn(String msg, Exception e)
4093 if (Cache.log != null)
4097 Cache.log.warn(msg, e);
4101 Cache.log.warn(msg);
4106 System.err.println("Warning: " + msg);
4109 e.printStackTrace();
4114 private void debug(String string)
4116 debug(string, null);
4119 private void debug(String msg, Exception e)
4121 if (Cache.log != null)
4125 Cache.log.debug(msg, e);
4129 Cache.log.debug(msg);
4134 System.err.println("Warning: " + msg);
4137 e.printStackTrace();
4143 * set the object to ID mapping tables used to write/recover objects and XML
4144 * ID strings for the jalview project. If external tables are provided then
4145 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4146 * object goes out of scope. - also populates the datasetIds hashtable with
4147 * alignment objects containing dataset sequences
4150 * Map from ID strings to jalview datamodel
4152 * Map from jalview datamodel to ID strings
4156 public void setObjectMappingTables(Hashtable vobj2jv,
4157 IdentityHashMap jv2vobj)
4159 this.jv2vobj = jv2vobj;
4160 this.vobj2jv = vobj2jv;
4161 Iterator ds = jv2vobj.keySet().iterator();
4163 while (ds.hasNext())
4165 Object jvobj = ds.next();
4166 id = jv2vobj.get(jvobj).toString();
4167 if (jvobj instanceof jalview.datamodel.Alignment)
4169 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4171 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4174 else if (jvobj instanceof jalview.datamodel.Sequence)
4176 // register sequence object so the XML parser can recover it.
4177 if (seqRefIds == null)
4179 seqRefIds = new Hashtable();
4181 if (seqsToIds == null)
4183 seqsToIds = new IdentityHashMap();
4185 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
4186 seqsToIds.put(jvobj, id);
4188 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4190 if (annotationIds == null)
4192 annotationIds = new Hashtable();
4195 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4196 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4197 if (jvann.annotationId == null)
4199 jvann.annotationId = anid;
4201 if (!jvann.annotationId.equals(anid))
4203 // TODO verify that this is the correct behaviour
4204 this.warn("Overriding Annotation ID for " + anid
4205 + " from different id : " + jvann.annotationId);
4206 jvann.annotationId = anid;
4209 else if (jvobj instanceof String)
4211 if (jvids2vobj == null)
4213 jvids2vobj = new Hashtable();
4214 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4218 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4223 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4224 * objects created from the project archive. If string is null (default for
4225 * construction) then suffix will be set automatically.
4229 public void setUniqueSetSuffix(String string)
4231 uniqueSetSuffix = string;
4236 * uses skipList2 as the skipList for skipping views on sequence sets
4237 * associated with keys in the skipList
4241 public void setSkipList(Hashtable skipList2)
4243 skipList = skipList2;