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,_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 (object.getJalviewModelSequence().getViewportCount() > 0)
1870 if (object.getJalviewModelSequence().getViewportCount() > 1
1871 && af.viewport.gatherViewsHere)
1873 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
1879 else if (jarentry != null)
1881 // Some other file here.
1884 } while (jarentry != null);
1885 resolveFrefedSequences();
1886 } catch (java.io.FileNotFoundException ex)
1888 ex.printStackTrace();
1889 errorMessage = "Couldn't locate Jalview XML file : " + file;
1890 System.err.println("Exception whilst loading jalview XML file : "
1892 } catch (java.net.UnknownHostException ex)
1894 ex.printStackTrace();
1895 errorMessage = "Couldn't locate Jalview XML file : " + file;
1896 System.err.println("Exception whilst loading jalview XML file : "
1898 } catch (Exception ex)
1900 System.err.println("Parsing as Jalview Version 2 file failed.");
1901 ex.printStackTrace(System.err);
1902 if (attemptversion1parse)
1904 // Is Version 1 Jar file?
1907 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
1908 } catch (Exception ex2)
1910 System.err.println("Exception whilst loading as jalviewXMLV1:");
1911 ex2.printStackTrace();
1915 if (Desktop.instance != null)
1917 Desktop.instance.stopLoading();
1921 System.out.println("Successfully loaded archive file");
1924 ex.printStackTrace();
1926 System.err.println("Exception whilst loading jalview XML file : "
1928 } catch (OutOfMemoryError e)
1930 // Don't use the OOM Window here
1931 errorMessage = "Out of memory loading jalview XML file";
1932 System.err.println("Out of memory whilst loading jalview XML file");
1933 e.printStackTrace();
1936 if (Desktop.instance != null)
1938 Desktop.instance.stopLoading();
1941 Enumeration en = gatherToThisFrame.elements();
1942 while (en.hasMoreElements())
1944 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
1946 if (errorMessage != null)
1954 * check errorMessage for a valid error message and raise an error box in the
1955 * GUI or write the current errorMessage to stderr and then clear the error
1958 protected void reportErrors()
1960 reportErrors(false);
1963 protected void reportErrors(final boolean saving)
1965 if (errorMessage != null)
1967 final String finalErrorMessage = errorMessage;
1970 javax.swing.SwingUtilities.invokeLater(new Runnable()
1975 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1976 finalErrorMessage, "Error "
1977 + (saving ? "saving" : "loading")
1978 + " Jalview file", JOptionPane.WARNING_MESSAGE);
1984 System.err.println("Problem loading Jalview file: " + errorMessage);
1987 errorMessage = null;
1990 Hashtable alreadyLoadedPDB;
1993 * when set, local views will be updated from view stored in JalviewXML
1994 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
1995 * sync if this is set to true.
1997 private final boolean updateLocalViews = false;
1999 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2001 if (alreadyLoadedPDB == null)
2002 alreadyLoadedPDB = new Hashtable();
2004 if (alreadyLoadedPDB.containsKey(pdbId))
2005 return alreadyLoadedPDB.get(pdbId).toString();
2009 JarInputStream jin = jprovider.getJarInputStream();
2011 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2012 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2013 * FileInputStream(jprovider)); }
2016 JarEntry entry = null;
2019 entry = jin.getNextJarEntry();
2020 } while (entry != null && !entry.getName().equals(pdbId));
2023 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
2024 File outFile = File.createTempFile("jalview_pdb", ".txt");
2025 outFile.deleteOnExit();
2026 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
2029 while ((data = in.readLine()) != null)
2036 } catch (Exception foo)
2041 String t = outFile.getAbsolutePath();
2042 alreadyLoadedPDB.put(pdbId, t);
2047 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
2049 } catch (Exception ex)
2051 ex.printStackTrace();
2057 private class JvAnnotRow
2059 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2066 * persisted version of annotation row from which to take vis properties
2068 public jalview.datamodel.AlignmentAnnotation template;
2071 * original position of the annotation row in the alignment
2077 * Load alignment frame from jalview XML DOM object
2082 * filename source string
2083 * @param loadTreesAndStructures
2084 * when false only create Viewport
2086 * data source provider
2087 * @return alignment frame created from view stored in DOM
2089 AlignFrame LoadFromObject(JalviewModel object, String file,
2090 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2092 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2093 Sequence[] vamsasSeq = vamsasSet.getSequence();
2095 JalviewModelSequence jms = object.getJalviewModelSequence();
2097 Viewport view = (jms.getViewportCount()>0) ? jms.getViewport(0) : null;
2099 // ////////////////////////////////
2102 Vector hiddenSeqs = null;
2103 jalview.datamodel.Sequence jseq;
2105 ArrayList tmpseqs = new ArrayList();
2107 boolean multipleView = false;
2109 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
2110 int vi = 0; // counter in vamsasSeq array
2111 for (int i = 0; i < JSEQ.length; i++)
2113 String seqId = JSEQ[i].getId();
2115 if (seqRefIds.get(seqId) != null)
2117 tmpseqs.add(seqRefIds.get(seqId));
2118 multipleView = true;
2122 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2123 vamsasSeq[vi].getSequence());
2124 jseq.setDescription(vamsasSeq[vi].getDescription());
2125 jseq.setStart(JSEQ[i].getStart());
2126 jseq.setEnd(JSEQ[i].getEnd());
2127 jseq.setVamsasId(uniqueSetSuffix + seqId);
2128 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2133 if (JSEQ[i].getHidden())
2135 if (hiddenSeqs == null)
2137 hiddenSeqs = new Vector();
2140 hiddenSeqs.addElement(seqRefIds.get(seqId));
2146 // Create the alignment object from the sequence set
2147 // ///////////////////////////////
2148 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2151 tmpseqs.toArray(orderedSeqs);
2153 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2156 // / Add the alignment properties
2157 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2159 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2160 al.setProperty(ssp.getKey(), ssp.getValue());
2164 // SequenceFeatures are added to the DatasetSequence,
2165 // so we must create or recover the dataset before loading features
2166 // ///////////////////////////////
2167 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2169 // older jalview projects do not have a dataset id.
2170 al.setDataset(null);
2174 recoverDatasetFor(vamsasSet, al);
2176 // ///////////////////////////////
2178 Hashtable pdbloaded = new Hashtable();
2181 // load sequence features, database references and any associated PDB
2182 // structures for the alignment
2183 for (int i = 0; i < vamsasSeq.length; i++)
2185 if (JSEQ[i].getFeaturesCount() > 0)
2187 Features[] features = JSEQ[i].getFeatures();
2188 for (int f = 0; f < features.length; f++)
2190 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2191 features[f].getType(), features[f].getDescription(),
2192 features[f].getStatus(), features[f].getBegin(),
2193 features[f].getEnd(), features[f].getFeatureGroup());
2195 sf.setScore(features[f].getScore());
2196 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2198 OtherData keyValue = features[f].getOtherData(od);
2199 if (keyValue.getKey().startsWith("LINK"))
2201 sf.addLink(keyValue.getValue());
2205 sf.setValue(keyValue.getKey(), keyValue.getValue());
2210 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2213 if (vamsasSeq[i].getDBRefCount() > 0)
2215 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2217 if (JSEQ[i].getPdbidsCount() > 0)
2219 Pdbids[] ids = JSEQ[i].getPdbids();
2220 for (int p = 0; p < ids.length; p++)
2222 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2223 entry.setId(ids[p].getId());
2224 entry.setType(ids[p].getType());
2225 if (ids[p].getFile() != null)
2227 if (!pdbloaded.containsKey(ids[p].getFile()))
2229 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2233 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2237 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2241 } // end !multipleview
2243 // ///////////////////////////////
2244 // LOAD SEQUENCE MAPPINGS
2246 if (vamsasSet.getAlcodonFrameCount() > 0)
2248 // TODO Potentially this should only be done once for all views of an
2250 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2251 for (int i = 0; i < alc.length; i++)
2253 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2254 alc[i].getAlcodonCount());
2255 if (alc[i].getAlcodonCount() > 0)
2257 Alcodon[] alcods = alc[i].getAlcodon();
2258 for (int p = 0; p < cf.codons.length; p++)
2260 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2261 && alcods[p].hasPos3())
2263 // translated codons require three valid positions
2264 cf.codons[p] = new int[3];
2265 cf.codons[p][0] = (int) alcods[p].getPos1();
2266 cf.codons[p][1] = (int) alcods[p].getPos2();
2267 cf.codons[p][2] = (int) alcods[p].getPos3();
2271 cf.codons[p] = null;
2275 if (alc[i].getAlcodMapCount() > 0)
2277 AlcodMap[] maps = alc[i].getAlcodMap();
2278 for (int m = 0; m < maps.length; m++)
2280 SequenceI dnaseq = (SequenceI) seqRefIds
2281 .get(maps[m].getDnasq());
2283 jalview.datamodel.Mapping mapping = null;
2284 // attach to dna sequence reference.
2285 if (maps[m].getMapping() != null)
2287 mapping = addMapping(maps[m].getMapping());
2291 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2296 frefedSequence.add(new Object[]
2297 { maps[m].getDnasq(), cf, mapping });
2301 al.addCodonFrame(cf);
2306 // ////////////////////////////////
2308 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2310 * store any annotations which forward reference a group's ID
2312 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2314 if (vamsasSet.getAnnotationCount() > 0)
2316 Annotation[] an = vamsasSet.getAnnotation();
2318 for (int i = 0; i < an.length; i++)
2321 * test if annotation is automatically calculated for this view only
2323 boolean autoForView = false;
2324 if (an[i].getLabel().equals("Quality")
2325 || an[i].getLabel().equals("Conservation")
2326 || an[i].getLabel().equals("Consensus"))
2328 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2330 if (!an[i].hasAutoCalculated())
2332 an[i].setAutoCalculated(true);
2336 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2338 // remove ID - we don't recover annotation from other views for
2339 // view-specific annotation
2343 // set visiblity for other annotation in this view
2344 if (an[i].getId() != null
2345 && annotationIds.containsKey(an[i].getId()))
2347 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2348 .get(an[i].getId());
2349 // in principle Visible should always be true for annotation displayed
2350 // in multiple views
2351 if (an[i].hasVisible())
2352 jda.visible = an[i].getVisible();
2354 al.addAnnotation(jda);
2358 // Construct new annotation from model.
2359 AnnotationElement[] ae = an[i].getAnnotationElement();
2360 jalview.datamodel.Annotation[] anot = null;
2361 java.awt.Color firstColour = null;
2363 if (!an[i].getScoreOnly())
2365 anot = new jalview.datamodel.Annotation[al.getWidth()];
2366 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2368 anpos = ae[aa].getPosition();
2370 if (anpos >= anot.length)
2373 anot[anpos] = new jalview.datamodel.Annotation(
2375 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2376 (ae[aa].getSecondaryStructure() == null || ae[aa]
2377 .getSecondaryStructure().length() == 0) ? ' '
2378 : ae[aa].getSecondaryStructure().charAt(0),
2382 // JBPNote: Consider verifying dataflow for IO of secondary
2383 // structure annotation read from Stockholm files
2384 // this was added to try to ensure that
2385 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2387 // anot[ae[aa].getPosition()].displayCharacter = "";
2389 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2390 if (firstColour == null)
2392 firstColour = anot[anpos].colour;
2396 jalview.datamodel.AlignmentAnnotation jaa = null;
2398 if (an[i].getGraph())
2400 float llim = 0, hlim = 0;
2401 // if (autoForView || an[i].isAutoCalculated()) {
2404 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2405 an[i].getDescription(), anot, llim, hlim,
2406 an[i].getGraphType());
2408 jaa.graphGroup = an[i].getGraphGroup();
2409 jaa._linecolour = firstColour;
2410 if (an[i].getThresholdLine() != null)
2412 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2413 .getThresholdLine().getValue(), an[i]
2414 .getThresholdLine().getLabel(), new java.awt.Color(
2415 an[i].getThresholdLine().getColour())));
2418 if (autoForView || an[i].isAutoCalculated())
2420 // Hardwire the symbol display line to ensure that labels for
2421 // histograms are displayed
2427 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2428 an[i].getDescription(), anot);
2429 jaa._linecolour = firstColour;
2431 // register new annotation
2432 if (an[i].getId() != null)
2434 annotationIds.put(an[i].getId(), jaa);
2435 jaa.annotationId = an[i].getId();
2437 // recover sequence association
2438 if (an[i].getSequenceRef() != null)
2440 if (al.findName(an[i].getSequenceRef()) != null)
2442 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2444 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2447 // and make a note of any group association
2448 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2450 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2451 .get(an[i].getGroupRef());
2454 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2455 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2460 if (an[i].hasScore())
2462 jaa.setScore(an[i].getScore());
2464 if (an[i].hasVisible())
2465 jaa.visible = an[i].getVisible();
2467 if (an[i].hasCentreColLabels())
2468 jaa.centreColLabels = an[i].getCentreColLabels();
2470 if (an[i].hasScaleColLabels())
2472 jaa.scaleColLabel = an[i].getScaleColLabels();
2474 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2476 // newer files have an 'autoCalculated' flag and store calculation
2477 // state in viewport properties
2478 jaa.autoCalculated = true; // means annotation will be marked for
2479 // update at end of load.
2481 if (an[i].hasGraphHeight())
2483 jaa.graphHeight = an[i].getGraphHeight();
2485 if (an[i].hasBelowAlignment())
2487 jaa.belowAlignment = an[i].isBelowAlignment();
2489 jaa.setCalcId(an[i].getCalcId());
2491 if (jaa.autoCalculated)
2493 autoAlan.add(new JvAnnotRow(i, jaa));
2496 // if (!autoForView)
2498 // add autocalculated group annotation and any user created annotation
2500 al.addAnnotation(jaa);
2505 // ///////////////////////
2507 // Create alignment markup and styles for this view
2508 if (jms.getJGroupCount() > 0)
2510 JGroup[] groups = jms.getJGroup();
2512 for (int i = 0; i < groups.length; i++)
2514 ColourSchemeI cs = null;
2516 if (groups[i].getColour() != null)
2518 if (groups[i].getColour().startsWith("ucs"))
2520 cs = GetUserColourScheme(jms, groups[i].getColour());
2524 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2529 cs.setThreshold(groups[i].getPidThreshold(), true);
2533 Vector seqs = new Vector();
2535 for (int s = 0; s < groups[i].getSeqCount(); s++)
2537 String seqId = groups[i].getSeq(s) + "";
2538 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2543 seqs.addElement(ts);
2547 if (seqs.size() < 1)
2552 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2553 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2554 groups[i].getDisplayText(), groups[i].getColourText(),
2555 groups[i].getStart(), groups[i].getEnd());
2557 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2559 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2560 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2561 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2562 .isShowUnconserved() : false);
2563 sg.thresholdTextColour = groups[i].getTextColThreshold();
2564 if (groups[i].hasShowConsensusHistogram())
2566 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2569 if (groups[i].hasShowSequenceLogo())
2571 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2573 if (groups[i].hasNormaliseSequenceLogo())
2575 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2577 if (groups[i].hasIgnoreGapsinConsensus())
2579 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2581 if (groups[i].getConsThreshold() != 0)
2583 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2584 "All", ResidueProperties.propHash, 3,
2585 sg.getSequences(null), 0, sg.getWidth() - 1);
2587 c.verdict(false, 25);
2588 sg.cs.setConservation(c);
2591 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2593 // re-instate unique group/annotation row reference
2594 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2595 .get(groups[i].getId());
2598 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2601 if (jaa.autoCalculated)
2603 // match up and try to set group autocalc alignment row for this
2605 if (jaa.label.startsWith("Consensus for "))
2607 sg.setConsensus(jaa);
2609 // match up and try to set group autocalc alignment row for this
2611 if (jaa.label.startsWith("Conservation for "))
2613 sg.setConservationRow(jaa);
2625 // only dataset in this model, so just return.
2628 // ///////////////////////////////
2631 // If we just load in the same jar file again, the sequenceSetId
2632 // will be the same, and we end up with multiple references
2633 // to the same sequenceSet. We must modify this id on load
2634 // so that each load of the file gives a unique id
2635 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2636 String viewId = (view.getId() == null ? null : view.getId()
2638 AlignFrame af = null;
2639 AlignViewport av = null;
2640 // now check to see if we really need to create a new viewport.
2641 if (multipleView && viewportsAdded.size() == 0)
2643 // We recovered an alignment for which a viewport already exists.
2644 // TODO: fix up any settings necessary for overlaying stored state onto
2645 // state recovered from another document. (may not be necessary).
2646 // we may need a binding from a viewport in memory to one recovered from
2648 // and then recover its containing af to allow the settings to be applied.
2649 // TODO: fix for vamsas demo
2651 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2653 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2654 if (seqsetobj != null)
2656 if (seqsetobj instanceof String)
2658 uniqueSeqSetId = (String) seqsetobj;
2660 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2666 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2671 AlignmentPanel ap = null;
2672 boolean isnewview = true;
2675 // Check to see if this alignment already has a view id == viewId
2676 jalview.gui.AlignmentPanel views[] = Desktop
2677 .getAlignmentPanels(uniqueSeqSetId);
2678 if (views != null && views.length > 0)
2680 for (int v = 0; v < views.length; v++)
2682 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2684 // recover the existing alignpanel, alignframe, viewport
2685 af = views[v].alignFrame;
2688 // TODO: could even skip resetting view settings if we don't want to
2689 // change the local settings from other jalview processes
2698 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2699 uniqueSeqSetId, viewId, autoAlan);
2704 // /////////////////////////////////////
2705 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2709 for (int t = 0; t < jms.getTreeCount(); t++)
2712 Tree tree = jms.getTree(t);
2714 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2717 tp = af.ShowNewickTree(
2718 new jalview.io.NewickFile(tree.getNewick()),
2719 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2720 tree.getXpos(), tree.getYpos());
2721 if (tree.getId() != null)
2723 // perhaps bind the tree id to something ?
2728 // update local tree attributes ?
2729 // TODO: should check if tp has been manipulated by user - if so its
2730 // settings shouldn't be modified
2731 tp.setTitle(tree.getTitle());
2732 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2733 .getWidth(), tree.getHeight()));
2734 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2737 tp.treeCanvas.av = av; // af.viewport;
2738 tp.treeCanvas.ap = ap; // af.alignPanel;
2743 warn("There was a problem recovering stored Newick tree: \n"
2744 + tree.getNewick());
2748 tp.fitToWindow.setState(tree.getFitToWindow());
2749 tp.fitToWindow_actionPerformed(null);
2751 if (tree.getFontName() != null)
2753 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2754 .getFontStyle(), tree.getFontSize()));
2758 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2759 .getFontStyle(), tree.getFontSize()));
2762 tp.showPlaceholders(tree.getMarkUnlinked());
2763 tp.showBootstrap(tree.getShowBootstrap());
2764 tp.showDistances(tree.getShowDistances());
2766 tp.treeCanvas.threshold = tree.getThreshold();
2768 if (tree.getCurrentTree())
2770 af.viewport.setCurrentTree(tp.getTree());
2774 } catch (Exception ex)
2776 ex.printStackTrace();
2780 // //LOAD STRUCTURES
2781 if (loadTreesAndStructures)
2783 // run through all PDB ids on the alignment, and collect mappings between
2784 // jmol view ids and all sequences referring to it
2785 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2787 for (int i = 0; i < JSEQ.length; i++)
2789 if (JSEQ[i].getPdbidsCount() > 0)
2791 Pdbids[] ids = JSEQ[i].getPdbids();
2792 for (int p = 0; p < ids.length; p++)
2794 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2796 // check to see if we haven't already created this structure view
2797 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2798 : ids[p].getStructureState(s).getViewId()
2800 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2801 // Originally : ids[p].getFile()
2802 // : TODO: verify external PDB file recovery still works in normal
2803 // jalview project load
2804 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2805 jpdb.setId(ids[p].getId());
2807 int x = ids[p].getStructureState(s).getXpos();
2808 int y = ids[p].getStructureState(s).getYpos();
2809 int width = ids[p].getStructureState(s).getWidth();
2810 int height = ids[p].getStructureState(s).getHeight();
2812 // Probably don't need to do this anymore...
2813 // Desktop.desktop.getComponentAt(x, y);
2814 // TODO: NOW: check that this recovers the PDB file correctly.
2815 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2816 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2817 .get(JSEQ[i].getId() + "");
2818 if (sviewid == null)
2820 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2823 if (!jmolViewIds.containsKey(sviewid))
2825 jmolViewIds.put(sviewid, new Object[]
2827 { x, y, width, height }, "",
2828 new Hashtable<String, Object[]>(), new boolean[]
2829 { false, false, true } });
2830 // Legacy pre-2.7 conversion JAL-823 :
2831 // do not assume any view has to be linked for colour by
2835 // assemble String[] { pdb files }, String[] { id for each
2836 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2837 // seqs_file 2}, boolean[] {
2838 // linkAlignPanel,superposeWithAlignpanel}} from hash
2839 Object[] jmoldat = jmolViewIds.get(sviewid);
2840 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2841 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
2842 s).getAlignwithAlignPanel() : false;
2843 // never colour by linked panel if not specified
2844 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
2845 .hasColourwithAlignPanel() ? ids[p]
2846 .getStructureState(s).getColourwithAlignPanel()
2848 // default for pre-2.7 projects is that Jmol colouring is enabled
2849 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
2850 .hasColourByJmol() ? ids[p].getStructureState(s)
2851 .getColourByJmol() : true;
2853 if (((String) jmoldat[1]).length() < ids[p]
2854 .getStructureState(s).getContent().length())
2857 jmoldat[1] = ids[p].getStructureState(s).getContent();
2860 if (ids[p].getFile() != null)
2862 File mapkey = new File(ids[p].getFile());
2863 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
2865 if (seqstrmaps == null)
2867 ((Hashtable) jmoldat[2]).put(mapkey,
2868 seqstrmaps = new Object[]
2869 { pdbFile, ids[p].getId(), new Vector(),
2872 if (!((Vector) seqstrmaps[2]).contains(seq))
2874 ((Vector) seqstrmaps[2]).addElement(seq);
2875 // ((Vector)seqstrmaps[3]).addElement(n) :
2876 // in principle, chains
2877 // should be stored here : do we need to
2878 // TODO: store and recover seq/pdb_id :
2884 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");
2893 // Instantiate the associated Jmol views
2894 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
2896 String sviewid = entry.getKey();
2897 Object[] svattrib = entry.getValue();
2898 int[] geom = (int[]) svattrib[0];
2899 String state = (String) svattrib[1];
2900 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
2901 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
2902 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
2903 // collate the pdbfile -> sequence mappings from this view
2904 Vector<String> pdbfilenames = new Vector<String>();
2905 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
2906 Vector<String> pdbids = new Vector<String>();
2908 // Search to see if we've already created this Jmol view
2909 AppJmol comp = null;
2910 JInternalFrame[] frames = null;
2915 frames = Desktop.desktop.getAllFrames();
2916 } catch (ArrayIndexOutOfBoundsException e)
2918 // occasional No such child exceptions are thrown here...
2923 } catch (Exception f)
2928 } while (frames == null);
2929 // search for any Jmol windows already open from other
2930 // alignment views that exactly match the stored structure state
2931 for (int f = 0; comp == null && f < frames.length; f++)
2933 if (frames[f] instanceof AppJmol)
2936 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
2938 // post jalview 2.4 schema includes structure view id
2939 comp = (AppJmol) frames[f];
2941 else if (frames[f].getX() == x && frames[f].getY() == y
2942 && frames[f].getHeight() == height
2943 && frames[f].getWidth() == width)
2945 comp = (AppJmol) frames[f];
2952 // create a new Jmol window.
2953 // First parse the Jmol state to translate filenames loaded into the
2954 // view, and record the order in which files are shown in the Jmol
2955 // view, so we can add the sequence mappings in same order.
2956 StringBuffer newFileLoc = null;
2957 int cp = 0, ncp, ecp;
2958 while ((ncp = state.indexOf("load ", cp)) > -1)
2960 if (newFileLoc == null)
2962 newFileLoc = new StringBuffer();
2966 // look for next filename in load statement
2967 newFileLoc.append(state.substring(cp,
2968 ncp = (state.indexOf("\"", ncp + 1) + 1)));
2969 String oldfilenam = state.substring(ncp,
2970 ecp = state.indexOf("\"", ncp));
2971 // recover the new mapping data for this old filename
2972 // have to normalize filename - since Jmol and jalview do
2974 // translation differently.
2975 Object[] filedat = oldFiles.get(new File(oldfilenam));
2976 newFileLoc.append(Platform
2977 .escapeString((String) filedat[0]));
2978 pdbfilenames.addElement((String) filedat[0]);
2979 pdbids.addElement((String) filedat[1]);
2980 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2981 .toArray(new SequenceI[0]));
2982 newFileLoc.append("\"");
2983 cp = ecp + 1; // advance beyond last \" and set cursor so we can
2984 // look for next file statement.
2985 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
2989 // just append rest of state
2990 newFileLoc.append(state.substring(cp));
2995 .print("Ignoring incomplete Jmol state for PDB ids: ");
2996 newFileLoc = new StringBuffer(state);
2997 newFileLoc.append("; load append ");
2998 for (File id : oldFiles.keySet())
3000 // add this and any other pdb files that should be present in
3002 Object[] filedat = oldFiles.get(id);
3004 newFileLoc.append(((String) filedat[0]));
3005 pdbfilenames.addElement((String) filedat[0]);
3006 pdbids.addElement((String) filedat[1]);
3007 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
3008 .toArray(new SequenceI[0]));
3009 newFileLoc.append(" \"");
3010 newFileLoc.append((String) filedat[0]);
3011 newFileLoc.append("\"");
3014 newFileLoc.append(";");
3017 if (newFileLoc != null)
3019 int histbug = newFileLoc.indexOf("history = ");
3021 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
3023 String val = (diff == -1) ? null : newFileLoc.substring(
3025 if (val != null && val.length() >= 4)
3027 if (val.contains("e"))
3029 if (val.trim().equals("true"))
3037 newFileLoc.replace(histbug, diff, val);
3040 // TODO: assemble String[] { pdb files }, String[] { id for each
3041 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3042 // seqs_file 2}} from hash
3043 final String[] pdbf = pdbfilenames
3044 .toArray(new String[pdbfilenames.size()]), id = pdbids
3045 .toArray(new String[pdbids.size()]);
3046 final SequenceI[][] sq = seqmaps
3047 .toArray(new SequenceI[seqmaps.size()][]);
3048 final String fileloc = newFileLoc.toString(), vid = sviewid;
3049 final AlignFrame alf = af;
3050 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
3054 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3059 AppJmol sview = null;
3062 sview = new AppJmol(pdbf, id, sq, alf.alignPanel,
3063 useinJmolsuperpos, usetoColourbyseq,
3064 jmolColouring, fileloc, rect, vid);
3065 addNewStructureViewer(sview);
3066 } catch (OutOfMemoryError ex)
3068 new OOMWarning("restoring structure view for PDB id "
3069 + id, (OutOfMemoryError) ex.getCause());
3070 if (sview != null && sview.isVisible())
3072 sview.closeViewer();
3073 sview.setVisible(false);
3079 } catch (InvocationTargetException ex)
3081 warn("Unexpected error when opening Jmol view.", ex);
3083 } catch (InterruptedException e)
3085 // e.printStackTrace();
3091 // if (comp != null)
3093 // NOTE: if the jalview project is part of a shared session then
3094 // view synchronization should/could be done here.
3096 // add mapping for sequences in this view to an already open Jmol
3098 for (File id : oldFiles.keySet())
3100 // add this and any other pdb files that should be present in the
3102 Object[] filedat = oldFiles.get(id);
3103 String pdbFile = (String) filedat[0];
3104 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3105 .toArray(new SequenceI[0]);
3106 comp.jmb.ssm.setMapping(seq, null, pdbFile,
3107 jalview.io.AppletFormatAdapter.FILE);
3108 comp.jmb.addSequenceForStructFile(pdbFile, seq);
3110 // and add the AlignmentPanel's reference to the Jmol view
3111 comp.addAlignmentPanel(ap);
3112 if (useinJmolsuperpos)
3114 comp.useAlignmentPanelForSuperposition(ap);
3118 comp.excludeAlignmentPanelForSuperposition(ap);
3120 if (usetoColourbyseq)
3122 comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3126 comp.excludeAlignmentPanelForColourbyseq(ap);
3132 // and finally return.
3135 Vector<AppJmol> newStructureViewers=null;
3136 protected void addNewStructureViewer(AppJmol sview)
3138 if (newStructureViewers!=null)
3140 sview.jmb.setFinishedLoadingFromArchive(false);
3141 newStructureViewers.add(sview);
3144 protected void setLoadingFinishedForNewStructureViewers()
3146 if (newStructureViewers!=null)
3148 for (AppJmol sview:newStructureViewers)
3150 sview.jmb.setFinishedLoadingFromArchive(true);
3152 newStructureViewers.clear();
3153 newStructureViewers=null;
3157 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3158 Alignment al, JalviewModelSequence jms, Viewport view,
3159 String uniqueSeqSetId, String viewId,
3160 ArrayList<JvAnnotRow> autoAlan)
3162 AlignFrame af = null;
3163 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3164 uniqueSeqSetId, viewId);
3166 af.setFileName(file, "Jalview");
3168 for (int i = 0; i < JSEQ.length; i++)
3170 af.viewport.setSequenceColour(af.viewport.getAlignment()
3171 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3174 af.viewport.gatherViewsHere = view.getGatheredViews();
3176 if (view.getSequenceSetId() != null)
3178 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3179 .get(uniqueSeqSetId);
3181 af.viewport.setSequenceSetId(uniqueSeqSetId);
3184 // propagate shared settings to this new view
3185 af.viewport.historyList = av.historyList;
3186 af.viewport.redoList = av.redoList;
3190 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3192 // TODO: check if this method can be called repeatedly without
3193 // side-effects if alignpanel already registered.
3194 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3196 // apply Hidden regions to view.
3197 if (hiddenSeqs != null)
3199 for (int s = 0; s < JSEQ.length; s++)
3201 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3203 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3206 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3208 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3211 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3214 for (int s = 0; s < hiddenSeqs.size(); s++)
3216 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3219 af.viewport.hideSequence(hseqs);
3222 // recover view properties and display parameters
3223 if (view.getViewName() != null)
3225 af.viewport.viewName = view.getViewName();
3226 af.setInitialTabVisible();
3228 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3231 af.viewport.setShowAnnotation(view.getShowAnnotation());
3232 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3234 af.viewport.setColourText(view.getShowColourText());
3236 af.viewport.setConservationSelected(view.getConservationSelected());
3237 af.viewport.setShowJVSuffix(view.getShowFullId());
3238 af.viewport.rightAlignIds = view.getRightAlignIds();
3239 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3240 .getFontStyle(), view.getFontSize()));
3241 af.alignPanel.fontChanged();
3242 af.viewport.setRenderGaps(view.getRenderGaps());
3243 af.viewport.setWrapAlignment(view.getWrapAlignment());
3244 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3245 af.viewport.setShowAnnotation(view.getShowAnnotation());
3246 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3248 af.viewport.setShowBoxes(view.getShowBoxes());
3250 af.viewport.setShowText(view.getShowText());
3252 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3253 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3254 af.viewport.thresholdTextColour = view.getTextColThreshold();
3255 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3256 .isShowUnconserved() : false);
3257 af.viewport.setStartRes(view.getStartRes());
3258 af.viewport.setStartSeq(view.getStartSeq());
3260 ColourSchemeI cs = null;
3261 // apply colourschemes
3262 if (view.getBgColour() != null)
3264 if (view.getBgColour().startsWith("ucs"))
3266 cs = GetUserColourScheme(jms, view.getBgColour());
3268 else if (view.getBgColour().startsWith("Annotation"))
3270 // int find annotation
3271 if (af.viewport.getAlignment().getAlignmentAnnotation() != null)
3273 for (int i = 0; i < af.viewport.getAlignment()
3274 .getAlignmentAnnotation().length; i++)
3276 if (af.viewport.getAlignment().getAlignmentAnnotation()[i].label
3277 .equals(view.getAnnotationColours().getAnnotation()))
3279 if (af.viewport.getAlignment().getAlignmentAnnotation()[i]
3280 .getThreshold() == null)
3282 af.viewport.getAlignment().getAlignmentAnnotation()[i]
3283 .setThreshold(new jalview.datamodel.GraphLine(view
3284 .getAnnotationColours().getThreshold(),
3285 "Threshold", java.awt.Color.black)
3290 if (view.getAnnotationColours().getColourScheme()
3293 cs = new AnnotationColourGradient(af.viewport
3294 .getAlignment().getAlignmentAnnotation()[i],
3295 new java.awt.Color(view.getAnnotationColours()
3296 .getMinColour()), new java.awt.Color(view
3297 .getAnnotationColours().getMaxColour()),
3298 view.getAnnotationColours().getAboveThreshold());
3300 else if (view.getAnnotationColours().getColourScheme()
3303 cs = new AnnotationColourGradient(af.viewport
3304 .getAlignment().getAlignmentAnnotation()[i],
3305 GetUserColourScheme(jms, view
3306 .getAnnotationColours().getColourScheme()),
3307 view.getAnnotationColours().getAboveThreshold());
3311 cs = new AnnotationColourGradient(af.viewport
3312 .getAlignment().getAlignmentAnnotation()[i],
3313 ColourSchemeProperty.getColour(al, view
3314 .getAnnotationColours().getColourScheme()),
3315 view.getAnnotationColours().getAboveThreshold());
3317 if (view.getAnnotationColours().hasPerSequence())
3319 ((AnnotationColourGradient)cs).setSeqAssociated(view.getAnnotationColours().isPerSequence());
3321 if (view.getAnnotationColours().hasPredefinedColours())
3323 ((AnnotationColourGradient)cs).setPredefinedColours(view.getAnnotationColours().isPredefinedColours());
3325 // Also use these settings for all the groups
3326 if (al.getGroups() != null)
3328 for (int g = 0; g < al.getGroups().size(); g++)
3330 jalview.datamodel.SequenceGroup sg = al.getGroups()
3340 * (view.getAnnotationColours().getColourScheme().equals("None"
3341 * )) { sg.cs = new AnnotationColourGradient(
3342 * af.viewport.getAlignment().getAlignmentAnnotation()[i], new
3343 * java.awt.Color(view.getAnnotationColours().
3344 * getMinColour()), new
3345 * java.awt.Color(view.getAnnotationColours().
3347 * view.getAnnotationColours().getAboveThreshold()); } else
3350 sg.cs = new AnnotationColourGradient(af.viewport
3351 .getAlignment().getAlignmentAnnotation()[i],
3352 sg.cs, view.getAnnotationColours()
3353 .getAboveThreshold());
3354 if (cs instanceof AnnotationColourGradient)
3356 if (view.getAnnotationColours().hasPerSequence())
3358 ((AnnotationColourGradient)cs).setSeqAssociated(view.getAnnotationColours().isPerSequence());
3360 if (view.getAnnotationColours().hasPredefinedColours())
3362 ((AnnotationColourGradient)cs).setPredefinedColours(view.getAnnotationColours().isPredefinedColours());
3378 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3383 cs.setThreshold(view.getPidThreshold(), true);
3384 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3388 af.viewport.setGlobalColourScheme(cs);
3389 af.viewport.setColourAppliesToAllGroups(false);
3391 if (view.getConservationSelected() && cs != null)
3393 cs.setConservationInc(view.getConsThreshold());
3396 af.changeColour(cs);
3398 af.viewport.setColourAppliesToAllGroups(true);
3400 if (view.getShowSequenceFeatures())
3402 af.viewport.showSequenceFeatures = true;
3404 if (view.hasCentreColumnLabels())
3406 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3408 if (view.hasIgnoreGapsinConsensus())
3410 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3413 if (view.hasFollowHighlight())
3415 af.viewport.followHighlight = view.getFollowHighlight();
3417 if (view.hasFollowSelection())
3419 af.viewport.followSelection = view.getFollowSelection();
3421 if (view.hasShowConsensusHistogram())
3423 af.viewport.setShowConsensusHistogram(view
3424 .getShowConsensusHistogram());
3428 af.viewport.setShowConsensusHistogram(true);
3430 if (view.hasShowSequenceLogo())
3432 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3436 af.viewport.setShowSequenceLogo(false);
3438 if (view.hasNormaliseSequenceLogo())
3440 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3442 if (view.hasShowDbRefTooltip())
3444 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3446 if (view.hasShowNPfeatureTooltip())
3448 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3450 if (view.hasShowGroupConsensus())
3452 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3456 af.viewport.setShowGroupConsensus(false);
3458 if (view.hasShowGroupConservation())
3460 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3464 af.viewport.setShowGroupConservation(false);
3467 // recover featre settings
3468 if (jms.getFeatureSettings() != null)
3470 af.viewport.featuresDisplayed = new Hashtable();
3471 String[] renderOrder = new String[jms.getFeatureSettings()
3472 .getSettingCount()];
3473 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3475 Setting setting = jms.getFeatureSettings().getSetting(fs);
3476 if (setting.hasMincolour())
3478 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3479 new java.awt.Color(setting.getMincolour()),
3480 new java.awt.Color(setting.getColour()),
3481 setting.getMin(), setting.getMax()) : new GraduatedColor(
3482 new java.awt.Color(setting.getMincolour()),
3483 new java.awt.Color(setting.getColour()), 0, 1);
3484 if (setting.hasThreshold())
3486 gc.setThresh(setting.getThreshold());
3487 gc.setThreshType(setting.getThreshstate());
3489 gc.setAutoScaled(true); // default
3490 if (setting.hasAutoScale())
3492 gc.setAutoScaled(setting.getAutoScale());
3494 if (setting.hasColourByLabel())
3496 gc.setColourByLabel(setting.getColourByLabel());
3498 // and put in the feature colour table.
3499 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3500 setting.getType(), gc);
3504 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3506 new java.awt.Color(setting.getColour()));
3508 renderOrder[fs] = setting.getType();
3509 if (setting.hasOrder())
3510 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3511 setting.getType(), setting.getOrder());
3513 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3515 fs / jms.getFeatureSettings().getSettingCount());
3516 if (setting.getDisplay())
3518 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3519 setting.getColour()));
3522 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3524 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3525 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3527 Group grp = jms.getFeatureSettings().getGroup(gs);
3528 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3532 if (view.getHiddenColumnsCount() > 0)
3534 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3536 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3537 .getHiddenColumns(c).getEnd() // +1
3541 if (view.getCalcIdParam() != null)
3543 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3545 if (calcIdParam != null)
3547 if (recoverCalcIdParam(calcIdParam, af.viewport))
3552 warn("Couldn't recover parameters for "
3553 + calcIdParam.getCalcId());
3558 af.setMenusFromViewport(af.viewport);
3559 // TODO: we don't need to do this if the viewport is aready visible.
3560 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3562 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3563 reorderAutoannotation(af, al, autoAlan);
3564 af.alignPanel.alignmentChanged();
3568 private void reorderAutoannotation(AlignFrame af, Alignment al,
3569 ArrayList<JvAnnotRow> autoAlan)
3571 // copy over visualization settings for autocalculated annotation in the
3573 if (al.getAlignmentAnnotation() != null)
3576 * Kludge for magic autoannotation names (see JAL-811)
3578 String[] magicNames = new String[]
3579 { "Consensus", "Quality", "Conservation" };
3580 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3581 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3582 for (String nm : magicNames)
3584 visan.put(nm, nullAnnot);
3586 for (JvAnnotRow auan : autoAlan)
3588 visan.put(auan.template.label
3589 + (auan.template.getCalcId() == null ? "" : "\t"
3590 + auan.template.getCalcId()), auan);
3592 int hSize = al.getAlignmentAnnotation().length;
3593 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3594 // work through any autoCalculated annotation already on the view
3595 // removing it if it should be placed in a different location on the
3596 // annotation panel.
3597 List<String> remains = new ArrayList(visan.keySet());
3598 for (int h = 0; h < hSize; h++)
3600 jalview.datamodel.AlignmentAnnotation jalan = al
3601 .getAlignmentAnnotation()[h];
3602 if (jalan.autoCalculated)
3605 JvAnnotRow valan = visan.get(k = jalan.label);
3606 if (jalan.getCalcId() != null)
3608 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
3613 // delete the auto calculated row from the alignment
3614 al.deleteAnnotation(jalan, false);
3618 if (valan != nullAnnot)
3620 if (jalan != valan.template)
3622 // newly created autoannotation row instance
3623 // so keep a reference to the visible annotation row
3624 // and copy over all relevant attributes
3625 if (valan.template.graphHeight >= 0)
3628 jalan.graphHeight = valan.template.graphHeight;
3630 jalan.visible = valan.template.visible;
3632 reorder.add(new JvAnnotRow(valan.order, jalan));
3637 // Add any (possibly stale) autocalculated rows that were not appended to
3638 // the view during construction
3639 for (String other : remains)
3641 JvAnnotRow othera = visan.get(other);
3642 if (othera != nullAnnot && othera.template.getCalcId() != null
3643 && othera.template.getCalcId().length() > 0)
3645 reorder.add(othera);
3648 // now put the automatic annotation in its correct place
3649 int s = 0, srt[] = new int[reorder.size()];
3650 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3651 for (JvAnnotRow jvar : reorder)
3654 srt[s++] = jvar.order;
3657 jalview.util.QuickSort.sort(srt, rws);
3658 // and re-insert the annotation at its correct position
3659 for (JvAnnotRow jvar : rws)
3661 al.addAnnotation(jvar.template, jvar.order);
3663 af.alignPanel.adjustAnnotationHeight();
3667 Hashtable skipList = null;
3670 * TODO remove this method
3673 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3674 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3675 * throw new Error("Implementation Error. No skipList defined for this
3676 * Jalview2XML instance."); } return (AlignFrame)
3677 * skipList.get(view.getSequenceSetId()); }
3681 * Check if the Jalview view contained in object should be skipped or not.
3684 * @return true if view's sequenceSetId is a key in skipList
3686 private boolean skipViewport(JalviewModel object)
3688 if (skipList == null)
3693 if (skipList.containsKey(id = object.getJalviewModelSequence()
3694 .getViewport()[0].getSequenceSetId()))
3696 if (Cache.log != null && Cache.log.isDebugEnabled())
3698 Cache.log.debug("Skipping seuqence set id " + id);
3705 public void AddToSkipList(AlignFrame af)
3707 if (skipList == null)
3709 skipList = new Hashtable();
3711 skipList.put(af.getViewport().getSequenceSetId(), af);
3714 public void clearSkipList()
3716 if (skipList != null)
3723 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3725 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3726 Vector dseqs = null;
3729 // create a list of new dataset sequences
3730 dseqs = new Vector();
3732 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3734 Sequence vamsasSeq = vamsasSet.getSequence(i);
3735 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
3737 // create a new dataset
3740 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3741 dseqs.copyInto(dsseqs);
3742 ds = new jalview.datamodel.Alignment(dsseqs);
3743 debug("Created new dataset " + vamsasSet.getDatasetId()
3744 + " for alignment " + System.identityHashCode(al));
3745 addDatasetRef(vamsasSet.getDatasetId(), ds);
3747 // set the dataset for the newly imported alignment.
3748 if (al.getDataset() == null)
3757 * sequence definition to create/merge dataset sequence for
3761 * vector to add new dataset sequence to
3763 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
3764 AlignmentI ds, Vector dseqs)
3766 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
3768 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
3769 .get(vamsasSeq.getId());
3770 jalview.datamodel.SequenceI dsq = null;
3771 if (sq != null && sq.getDatasetSequence() != null)
3773 dsq = sq.getDatasetSequence();
3776 String sqid = vamsasSeq.getDsseqid();
3779 // need to create or add a new dataset sequence reference to this sequence
3782 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
3787 // make a new dataset sequence
3788 dsq = sq.createDatasetSequence();
3791 // make up a new dataset reference for this sequence
3792 sqid = seqHash(dsq);
3794 dsq.setVamsasId(uniqueSetSuffix + sqid);
3795 seqRefIds.put(sqid, dsq);
3800 dseqs.addElement(dsq);
3805 ds.addSequence(dsq);
3811 { // make this dataset sequence sq's dataset sequence
3812 sq.setDatasetSequence(dsq);
3813 // and update the current dataset alignment
3816 if (!dseqs.contains(dsq))
3821 if (ds.findIndex(dsq)<0)
3823 ds.addSequence(dsq);
3830 // TODO: refactor this as a merge dataset sequence function
3831 // now check that sq (the dataset sequence) sequence really is the union of
3832 // all references to it
3833 // boolean pre = sq.getStart() < dsq.getStart();
3834 // boolean post = sq.getEnd() > dsq.getEnd();
3838 StringBuffer sb = new StringBuffer();
3839 String newres = jalview.analysis.AlignSeq.extractGaps(
3840 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
3841 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
3842 && newres.length() > dsq.getLength())
3844 // Update with the longer sequence.
3848 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
3849 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
3850 * sb.append(newres.substring(newres.length() - sq.getEnd() -
3851 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
3853 dsq.setSequence(newres);
3855 // TODO: merges will never happen if we 'know' we have the real dataset
3856 // sequence - this should be detected when id==dssid
3857 System.err.println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
3858 // + (pre ? "prepended" : "") + " "
3859 // + (post ? "appended" : ""));
3864 java.util.Hashtable datasetIds = null;
3866 java.util.IdentityHashMap dataset2Ids = null;
3868 private Alignment getDatasetFor(String datasetId)
3870 if (datasetIds == null)
3872 datasetIds = new Hashtable();
3875 if (datasetIds.containsKey(datasetId))
3877 return (Alignment) datasetIds.get(datasetId);
3882 private void addDatasetRef(String datasetId, Alignment dataset)
3884 if (datasetIds == null)
3886 datasetIds = new Hashtable();
3888 datasetIds.put(datasetId, dataset);
3892 * make a new dataset ID for this jalview dataset alignment
3897 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
3899 if (dataset.getDataset() != null)
3901 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
3903 String datasetId = makeHashCode(dataset, null);
3904 if (datasetId == null)
3906 // make a new datasetId and record it
3907 if (dataset2Ids == null)
3909 dataset2Ids = new IdentityHashMap();
3913 datasetId = (String) dataset2Ids.get(dataset);
3915 if (datasetId == null)
3917 datasetId = "ds" + dataset2Ids.size() + 1;
3918 dataset2Ids.put(dataset, datasetId);
3924 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
3926 for (int d = 0; d < sequence.getDBRefCount(); d++)
3928 DBRef dr = sequence.getDBRef(d);
3929 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
3930 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
3931 .getVersion(), sequence.getDBRef(d).getAccessionId());
3932 if (dr.getMapping() != null)
3934 entry.setMap(addMapping(dr.getMapping()));
3936 datasetSequence.addDBRef(entry);
3940 private jalview.datamodel.Mapping addMapping(Mapping m)
3942 SequenceI dsto = null;
3943 // Mapping m = dr.getMapping();
3944 int fr[] = new int[m.getMapListFromCount() * 2];
3945 Enumeration f = m.enumerateMapListFrom();
3946 for (int _i = 0; f.hasMoreElements(); _i += 2)
3948 MapListFrom mf = (MapListFrom) f.nextElement();
3949 fr[_i] = mf.getStart();
3950 fr[_i + 1] = mf.getEnd();
3952 int fto[] = new int[m.getMapListToCount() * 2];
3953 f = m.enumerateMapListTo();
3954 for (int _i = 0; f.hasMoreElements(); _i += 2)
3956 MapListTo mf = (MapListTo) f.nextElement();
3957 fto[_i] = mf.getStart();
3958 fto[_i + 1] = mf.getEnd();
3960 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
3961 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
3962 if (m.getMappingChoice() != null)
3964 MappingChoice mc = m.getMappingChoice();
3965 if (mc.getDseqFor() != null)
3967 String dsfor = "" + mc.getDseqFor();
3968 if (seqRefIds.containsKey(dsfor))
3973 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
3977 frefedSequence.add(new Object[]
3984 * local sequence definition
3986 Sequence ms = mc.getSequence();
3987 jalview.datamodel.Sequence djs = null;
3988 String sqid = ms.getDsseqid();
3989 if (sqid != null && sqid.length() > 0)
3992 * recover dataset sequence
3994 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
3999 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
4000 sqid = ((Object) ms).toString(); // make up a new hascode for
4001 // undefined dataset sequence hash
4002 // (unlikely to happen)
4008 * make a new dataset sequence and add it to refIds hash
4010 djs = new jalview.datamodel.Sequence(ms.getName(),
4012 djs.setStart(jmap.getMap().getToLowest());
4013 djs.setEnd(jmap.getMap().getToHighest());
4014 djs.setVamsasId(uniqueSetSuffix + sqid);
4016 seqRefIds.put(sqid, djs);
4019 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
4028 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
4029 boolean keepSeqRefs)
4032 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
4038 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
4042 uniqueSetSuffix = "";
4043 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
4048 if (this.frefedSequence == null)
4050 frefedSequence = new Vector();
4053 viewportsAdded = new Hashtable();
4055 AlignFrame af = LoadFromObject(jm, null, false, null);
4056 af.alignPanels.clear();
4057 af.closeMenuItem_actionPerformed(true);
4060 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
4061 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
4062 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
4063 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
4064 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
4067 return af.alignPanel;
4071 * flag indicating if hashtables should be cleared on finalization TODO this
4072 * flag may not be necessary
4074 private final boolean _cleartables = true;
4076 private Hashtable jvids2vobj;
4081 * @see java.lang.Object#finalize()
4084 protected void finalize() throws Throwable
4086 // really make sure we have no buried refs left.
4091 this.seqRefIds = null;
4092 this.seqsToIds = null;
4096 private void warn(String msg)
4101 private void warn(String msg, Exception e)
4103 if (Cache.log != null)
4107 Cache.log.warn(msg, e);
4111 Cache.log.warn(msg);
4116 System.err.println("Warning: " + msg);
4119 e.printStackTrace();
4124 private void debug(String string)
4126 debug(string, null);
4129 private void debug(String msg, Exception e)
4131 if (Cache.log != null)
4135 Cache.log.debug(msg, e);
4139 Cache.log.debug(msg);
4144 System.err.println("Warning: " + msg);
4147 e.printStackTrace();
4153 * set the object to ID mapping tables used to write/recover objects and XML
4154 * ID strings for the jalview project. If external tables are provided then
4155 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4156 * object goes out of scope. - also populates the datasetIds hashtable with
4157 * alignment objects containing dataset sequences
4160 * Map from ID strings to jalview datamodel
4162 * Map from jalview datamodel to ID strings
4166 public void setObjectMappingTables(Hashtable vobj2jv,
4167 IdentityHashMap jv2vobj)
4169 this.jv2vobj = jv2vobj;
4170 this.vobj2jv = vobj2jv;
4171 Iterator ds = jv2vobj.keySet().iterator();
4173 while (ds.hasNext())
4175 Object jvobj = ds.next();
4176 id = jv2vobj.get(jvobj).toString();
4177 if (jvobj instanceof jalview.datamodel.Alignment)
4179 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4181 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4184 else if (jvobj instanceof jalview.datamodel.Sequence)
4186 // register sequence object so the XML parser can recover it.
4187 if (seqRefIds == null)
4189 seqRefIds = new Hashtable();
4191 if (seqsToIds == null)
4193 seqsToIds = new IdentityHashMap();
4195 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
4196 seqsToIds.put(jvobj, id);
4198 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4200 if (annotationIds == null)
4202 annotationIds = new Hashtable();
4205 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4206 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4207 if (jvann.annotationId == null)
4209 jvann.annotationId = anid;
4211 if (!jvann.annotationId.equals(anid))
4213 // TODO verify that this is the correct behaviour
4214 this.warn("Overriding Annotation ID for " + anid
4215 + " from different id : " + jvann.annotationId);
4216 jvann.annotationId = anid;
4219 else if (jvobj instanceof String)
4221 if (jvids2vobj == null)
4223 jvids2vobj = new Hashtable();
4224 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4228 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4233 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4234 * objects created from the project archive. If string is null (default for
4235 * construction) then suffix will be set automatically.
4239 public void setUniqueSetSuffix(String string)
4241 uniqueSetSuffix = string;
4246 * uses skipList2 as the skipList for skipping views on sequence sets
4247 * associated with keys in the skipList
4251 public void setSkipList(Hashtable skipList2)
4253 skipList = skipList2;