2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
3 * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
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/>.
20 import java.awt.Rectangle;
22 import java.lang.reflect.InvocationTargetException;
25 import java.util.Map.Entry;
26 import java.util.jar.*;
30 import org.exolab.castor.xml.*;
32 import jalview.bin.Cache;
33 import jalview.datamodel.Alignment;
34 import jalview.datamodel.AlignmentAnnotation;
35 import jalview.datamodel.AlignmentI;
36 import jalview.datamodel.SequenceI;
37 import jalview.schemabinding.version2.*;
38 import jalview.schemes.*;
39 import jalview.util.Platform;
40 import jalview.util.jarInputStreamProvider;
41 import jalview.ws.jws2.AAConsClient;
42 import jalview.ws.jws2.Jws2Discoverer;
43 import jalview.ws.jws2.dm.AAConsSettings;
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)
424 Vector jmolViewIds = new Vector(); //
425 Vector userColours = new Vector();
427 AlignViewport av = ap.av;
429 JalviewModel object = new JalviewModel();
430 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
432 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
433 object.setVersion(jalview.bin.Cache.getProperty("VERSION"));
435 jalview.datamodel.AlignmentI jal = av.getAlignment();
437 if (av.hasHiddenRows())
439 jal = jal.getHiddenSequences().getFullAlignment();
442 SequenceSet vamsasSet = new SequenceSet();
444 JalviewModelSequence jms = new JalviewModelSequence();
446 vamsasSet.setGapChar(jal.getGapCharacter() + "");
448 if (jal.getDataset() != null)
450 // dataset id is the dataset's hashcode
451 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
453 if (jal.getProperties() != null)
455 Enumeration en = jal.getProperties().keys();
456 while (en.hasMoreElements())
458 String key = en.nextElement().toString();
459 SequenceSetProperties ssp = new SequenceSetProperties();
461 ssp.setValue(jal.getProperties().get(key).toString());
462 vamsasSet.addSequenceSetProperties(ssp);
467 Set<String> calcIdSet=new HashSet<String>();
471 jalview.datamodel.SequenceI jds;
472 for (int i = 0; i < jal.getHeight(); i++)
474 jds = jal.getSequenceAt(i);
477 if (seqRefIds.get(id) != null)
479 // This happens for two reasons: 1. multiple views are being serialised.
480 // 2. the hashCode has collided with another sequence's code. This DOES
481 // HAPPEN! (PF00072.15.stk does this)
482 // JBPNote: Uncomment to debug writing out of files that do not read
483 // back in due to ArrayOutOfBoundExceptions.
484 // System.err.println("vamsasSeq backref: "+id+"");
485 // System.err.println(jds.getName()+"
486 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
487 // System.err.println("Hashcode: "+seqHash(jds));
488 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
489 // System.err.println(rsq.getName()+"
490 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
491 // System.err.println("Hashcode: "+seqHash(rsq));
495 vamsasSeq = createVamsasSequence(id, jds);
496 vamsasSet.addSequence(vamsasSeq);
497 seqRefIds.put(id, jds);
501 jseq.setStart(jds.getStart());
502 jseq.setEnd(jds.getEnd());
503 jseq.setColour(av.getSequenceColour(jds).getRGB());
505 jseq.setId(id); // jseq id should be a string not a number
507 if (av.hasHiddenRows())
509 jseq.setHidden(av.getAlignment().getHiddenSequences().isHidden(jds));
511 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
513 jalview.datamodel.SequenceI[] reps = av.getRepresentedSequences(jal.getSequenceAt(i)).getSequencesInOrder(jal);
515 for (int h = 0; h < reps.length; h++)
517 if (reps[h] != jal.getSequenceAt(i))
519 jseq.addHiddenSequences(jal.findIndex(reps[h]));
525 if (jds.getDatasetSequence().getSequenceFeatures() != null)
527 jalview.datamodel.SequenceFeature[] sf = jds.getDatasetSequence()
528 .getSequenceFeatures();
530 while (index < sf.length)
532 Features features = new Features();
534 features.setBegin(sf[index].getBegin());
535 features.setEnd(sf[index].getEnd());
536 features.setDescription(sf[index].getDescription());
537 features.setType(sf[index].getType());
538 features.setFeatureGroup(sf[index].getFeatureGroup());
539 features.setScore(sf[index].getScore());
540 if (sf[index].links != null)
542 for (int l = 0; l < sf[index].links.size(); l++)
544 OtherData keyValue = new OtherData();
545 keyValue.setKey("LINK_" + l);
546 keyValue.setValue(sf[index].links.elementAt(l).toString());
547 features.addOtherData(keyValue);
550 if (sf[index].otherDetails != null)
553 Enumeration keys = sf[index].otherDetails.keys();
554 while (keys.hasMoreElements())
556 key = keys.nextElement().toString();
557 OtherData keyValue = new OtherData();
558 keyValue.setKey(key);
559 keyValue.setValue(sf[index].otherDetails.get(key).toString());
560 features.addOtherData(keyValue);
564 jseq.addFeatures(features);
569 if (jds.getDatasetSequence().getPDBId() != null)
571 Enumeration en = jds.getDatasetSequence().getPDBId().elements();
572 while (en.hasMoreElements())
574 Pdbids pdb = new Pdbids();
575 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
578 pdb.setId(entry.getId());
579 pdb.setType(entry.getType());
582 // This must have been loaded, is it still visible?
583 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
584 String matchedFile = null;
585 for (int f = frames.length - 1; f > -1; f--)
587 if (frames[f] instanceof AppJmol)
589 jmol = (AppJmol) frames[f];
590 for (int peid = 0; peid < jmol.jmb.pdbentry.length; peid++)
592 if (!jmol.jmb.pdbentry[peid].getId().equals(entry.getId())
593 && !(entry.getId().length() > 4 && entry
597 jmol.jmb.pdbentry[peid].getId()
600 if (matchedFile == null)
602 matchedFile = jmol.jmb.pdbentry[peid].getFile();
604 else if (!matchedFile.equals(jmol.jmb.pdbentry[peid]
608 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
609 + jmol.jmb.pdbentry[peid].getFile());
613 // can get at it if the ID
614 // match is ambiguous (e.g.
616 String statestring = jmol.jmb.viewer.getStateInfo();
618 for (int smap = 0; smap < jmol.jmb.sequence[peid].length; smap++)
620 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
621 if (jds==jmol.jmb.sequence[peid][smap])
623 StructureState state = new StructureState();
624 state.setVisible(true);
625 state.setXpos(jmol.getX());
626 state.setYpos(jmol.getY());
627 state.setWidth(jmol.getWidth());
628 state.setHeight(jmol.getHeight());
629 state.setViewId(jmol.getViewId());
630 state.setAlignwithAlignPanel(jmol.isUsedforaligment(ap));
631 state.setColourwithAlignPanel(jmol
632 .isUsedforcolourby(ap));
633 state.setColourByJmol(jmol.isColouredByJmol());
634 if (!jmolViewIds.contains(state.getViewId()))
636 // Make sure we only store a Jmol state once in each XML
638 jmolViewIds.addElement(state.getViewId());
639 state.setContent(statestring.replaceAll("\n", ""));
643 state.setContent("# duplicate state");
645 pdb.addStructureState(state);
652 if (matchedFile != null || entry.getFile() != null)
654 if (entry.getFile() != null)
657 matchedFile = entry.getFile();
659 pdb.setFile(matchedFile); // entry.getFile());
660 if (pdbfiles == null)
662 pdbfiles = new Vector();
665 if (!pdbfiles.contains(entry.getId()))
667 pdbfiles.addElement(entry.getId());
670 File file = new File(matchedFile);
671 if (file.exists() && jout != null)
673 byte[] data = new byte[(int) file.length()];
674 jout.putNextEntry(new JarEntry(entry.getId()));
675 DataInputStream dis = new DataInputStream(
676 new FileInputStream(file));
679 DataOutputStream dout = new DataOutputStream(jout);
680 dout.write(data, 0, data.length);
684 } catch (Exception ex)
686 ex.printStackTrace();
692 if (entry.getProperty() != null)
694 PdbentryItem item = new PdbentryItem();
695 Hashtable properties = entry.getProperty();
696 Enumeration en2 = properties.keys();
697 while (en2.hasMoreElements())
699 Property prop = new Property();
700 String key = en2.nextElement().toString();
702 prop.setValue(properties.get(key).toString());
703 item.addProperty(prop);
705 pdb.addPdbentryItem(item);
715 if (av.hasHiddenRows())
717 jal = av.getAlignment();
720 if (jal.getCodonFrames() != null && jal.getCodonFrames().length > 0)
722 jalview.datamodel.AlignedCodonFrame[] jac = jal.getCodonFrames();
723 for (int i = 0; i < jac.length; i++)
725 AlcodonFrame alc = new AlcodonFrame();
726 vamsasSet.addAlcodonFrame(alc);
727 for (int p = 0; p < jac[i].aaWidth; p++)
729 Alcodon cmap = new Alcodon();
730 if (jac[i].codons[p] != null)
732 // Null codons indicate a gapped column in the translated peptide
734 cmap.setPos1(jac[i].codons[p][0]);
735 cmap.setPos2(jac[i].codons[p][1]);
736 cmap.setPos3(jac[i].codons[p][2]);
738 alc.addAlcodon(cmap);
740 if (jac[i].getProtMappings() != null
741 && jac[i].getProtMappings().length > 0)
743 SequenceI[] dnas = jac[i].getdnaSeqs();
744 jalview.datamodel.Mapping[] pmaps = jac[i].getProtMappings();
745 for (int m = 0; m < pmaps.length; m++)
747 AlcodMap alcmap = new AlcodMap();
748 alcmap.setDnasq(seqHash(dnas[m]));
749 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
751 alc.addAlcodMap(alcmap);
758 // /////////////////////////////////
759 if (av.currentTree != null)
761 // FIND ANY ASSOCIATED TREES
762 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
763 if (Desktop.desktop != null)
765 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
767 for (int t = 0; t < frames.length; t++)
769 if (frames[t] instanceof TreePanel)
771 TreePanel tp = (TreePanel) frames[t];
773 if (tp.treeCanvas.av.getAlignment() == jal)
775 Tree tree = new Tree();
776 tree.setTitle(tp.getTitle());
777 tree.setCurrentTree((av.currentTree == tp.getTree()));
778 tree.setNewick(tp.getTree().toString());
779 tree.setThreshold(tp.treeCanvas.threshold);
781 tree.setFitToWindow(tp.fitToWindow.getState());
782 tree.setFontName(tp.getTreeFont().getName());
783 tree.setFontSize(tp.getTreeFont().getSize());
784 tree.setFontStyle(tp.getTreeFont().getStyle());
785 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
787 tree.setShowBootstrap(tp.bootstrapMenu.getState());
788 tree.setShowDistances(tp.distanceMenu.getState());
790 tree.setHeight(tp.getHeight());
791 tree.setWidth(tp.getWidth());
792 tree.setXpos(tp.getX());
793 tree.setYpos(tp.getY());
794 tree.setId(makeHashCode(tp, null));
803 * store forward refs from an annotationRow to any groups
805 IdentityHashMap groupRefs = new IdentityHashMap();
806 if (jal.getAlignmentAnnotation() != null)
808 jalview.datamodel.AlignmentAnnotation[] aa = jal
809 .getAlignmentAnnotation();
811 for (int i = 0; i < aa.length; i++)
813 Annotation an = new Annotation();
815 if (aa[i].annotationId != null)
817 annotationIds.put(aa[i].annotationId, aa[i]);
820 an.setId(aa[i].annotationId);
822 an.setVisible(aa[i].visible);
824 an.setDescription(aa[i].description);
826 if (aa[i].sequenceRef != null)
828 // TODO later annotation sequenceRef should be the XML ID of the
829 // sequence rather than its display name
830 an.setSequenceRef(aa[i].sequenceRef.getName());
832 if (aa[i].groupRef != null)
834 Object groupIdr = groupRefs.get(aa[i].groupRef);
835 if (groupIdr == null)
837 // make a locally unique String
838 groupRefs.put(aa[i].groupRef,
839 groupIdr = ("" + System.currentTimeMillis()
840 + aa[i].groupRef.getName() + groupRefs.size()));
842 an.setGroupRef(groupIdr.toString());
845 // store all visualization attributes for annotation
846 an.setGraphHeight(aa[i].graphHeight);
847 an.setCentreColLabels(aa[i].centreColLabels);
848 an.setScaleColLabels(aa[i].scaleColLabel);
849 an.setShowAllColLabels(aa[i].showAllColLabels);
850 an.setBelowAlignment(aa[i].belowAlignment);
855 an.setGraphType(aa[i].graph);
856 an.setGraphGroup(aa[i].graphGroup);
857 if (aa[i].getThreshold() != null)
859 ThresholdLine line = new ThresholdLine();
860 line.setLabel(aa[i].getThreshold().label);
861 line.setValue(aa[i].getThreshold().value);
862 line.setColour(aa[i].getThreshold().colour.getRGB());
863 an.setThresholdLine(line);
871 an.setLabel(aa[i].label);
873 if (aa[i] == av.getAlignmentQualityAnnot() || aa[i] == av.getAlignmentConservationAnnotation()
874 || aa[i] == av.getAlignmentConsensusAnnotation() || aa[i].autoCalculated)
876 // new way of indicating autocalculated annotation -
877 an.setAutoCalculated(aa[i].autoCalculated);
879 if (aa[i].hasScore())
881 an.setScore(aa[i].getScore());
884 if (aa[i].getCalcId()!=null)
886 calcIdSet.add(aa[i].getCalcId());
887 an.setCalcId(aa[i].getCalcId());
890 AnnotationElement ae;
891 if (aa[i].annotations != null)
893 an.setScoreOnly(false);
894 for (int a = 0; a < aa[i].annotations.length; a++)
896 if ((aa[i] == null) || (aa[i].annotations[a] == null))
901 ae = new AnnotationElement();
902 if (aa[i].annotations[a].description != null)
903 ae.setDescription(aa[i].annotations[a].description);
904 if (aa[i].annotations[a].displayCharacter != null)
905 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
907 if (!Float.isNaN(aa[i].annotations[a].value))
908 ae.setValue(aa[i].annotations[a].value);
911 if (aa[i].annotations[a].secondaryStructure != ' '
912 && aa[i].annotations[a].secondaryStructure != '\0')
913 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
916 if (aa[i].annotations[a].colour != null
917 && aa[i].annotations[a].colour != java.awt.Color.black)
919 ae.setColour(aa[i].annotations[a].colour.getRGB());
922 an.addAnnotationElement(ae);
923 if (aa[i].autoCalculated)
925 // only write one non-null entry into the annotation row -
926 // sufficient to get the visualization attributes necessary to
934 an.setScoreOnly(true);
936 vamsasSet.addAnnotation(an);
940 if (jal.getGroups() != null)
942 JGroup[] groups = new JGroup[jal.getGroups().size()];
944 for (jalview.datamodel.SequenceGroup sg:jal.getGroups())
946 groups[++i] = new JGroup();
948 groups[i].setStart(sg.getStartRes());
949 groups[i].setEnd(sg.getEndRes());
950 groups[i].setName(sg.getName());
951 if (groupRefs.containsKey(sg))
953 // group has references so set it's ID field
954 groups[i].setId(groupRefs.get(sg).toString());
958 if (sg.cs.conservationApplied())
960 groups[i].setConsThreshold(sg.cs.getConservationInc());
962 if (sg.cs instanceof jalview.schemes.UserColourScheme)
964 groups[i].setColour(SetUserColourScheme(sg.cs, userColours,
970 .setColour(ColourSchemeProperty.getColourName(sg.cs));
973 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
976 .setColour(ColourSchemeProperty
977 .getColourName(((jalview.schemes.AnnotationColourGradient) sg.cs)
980 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
983 .setColour(SetUserColourScheme(sg.cs, userColours, jms));
987 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
990 groups[i].setPidThreshold(sg.cs.getThreshold());
993 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
994 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
995 groups[i].setDisplayText(sg.getDisplayText());
996 groups[i].setColourText(sg.getColourText());
997 groups[i].setTextCol1(sg.textColour.getRGB());
998 groups[i].setTextCol2(sg.textColour2.getRGB());
999 groups[i].setTextColThreshold(sg.thresholdTextColour);
1000 groups[i].setShowUnconserved(sg.getShowNonconserved());
1001 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1002 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
1003 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
1004 for (int s = 0; s < sg.getSize(); s++)
1006 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
1008 groups[i].addSeq(seqHash(seq));
1012 jms.setJGroup(groups);
1015 // /////////SAVE VIEWPORT
1016 Viewport view = new Viewport();
1017 view.setTitle(ap.alignFrame.getTitle());
1018 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1019 av.getSequenceSetId()));
1020 view.setId(av.getViewId());
1021 view.setViewName(av.viewName);
1022 view.setGatheredViews(av.gatherViewsHere);
1024 if (ap.av.explodedPosition != null)
1026 view.setXpos(av.explodedPosition.x);
1027 view.setYpos(av.explodedPosition.y);
1028 view.setWidth(av.explodedPosition.width);
1029 view.setHeight(av.explodedPosition.height);
1033 view.setXpos(ap.alignFrame.getBounds().x);
1034 view.setYpos(ap.alignFrame.getBounds().y);
1035 view.setWidth(ap.alignFrame.getBounds().width);
1036 view.setHeight(ap.alignFrame.getBounds().height);
1039 view.setStartRes(av.startRes);
1040 view.setStartSeq(av.startSeq);
1042 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1044 view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(),
1047 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1049 jalview.schemes.AnnotationColourGradient acg = (jalview.schemes.AnnotationColourGradient) av
1050 .getGlobalColourScheme();
1052 AnnotationColours ac = new AnnotationColours();
1053 ac.setAboveThreshold(acg.getAboveThreshold());
1054 ac.setThreshold(acg.getAnnotationThreshold());
1055 ac.setAnnotation(acg.getAnnotation());
1056 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1058 ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
1063 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1067 ac.setMaxColour(acg.getMaxColour().getRGB());
1068 ac.setMinColour(acg.getMinColour().getRGB());
1069 view.setAnnotationColours(ac);
1070 view.setBgColour("AnnotationColourGradient");
1074 view.setBgColour(ColourSchemeProperty.getColourName(av
1075 .getGlobalColourScheme()));
1078 ColourSchemeI cs = av.getGlobalColourScheme();
1082 if (cs.conservationApplied())
1084 view.setConsThreshold(cs.getConservationInc());
1085 if (cs instanceof jalview.schemes.UserColourScheme)
1087 view.setBgColour(SetUserColourScheme(cs, userColours, jms));
1091 if (cs instanceof ResidueColourScheme)
1093 view.setPidThreshold(cs.getThreshold());
1097 view.setConservationSelected(av.getConservationSelected());
1098 view.setPidSelected(av.getAbovePIDThreshold());
1099 view.setFontName(av.font.getName());
1100 view.setFontSize(av.font.getSize());
1101 view.setFontStyle(av.font.getStyle());
1102 view.setRenderGaps(av.renderGaps);
1103 view.setShowAnnotation(av.getShowAnnotation());
1104 view.setShowBoxes(av.getShowBoxes());
1105 view.setShowColourText(av.getColourText());
1106 view.setShowFullId(av.getShowJVSuffix());
1107 view.setRightAlignIds(av.rightAlignIds);
1108 view.setShowSequenceFeatures(av.showSequenceFeatures);
1109 view.setShowText(av.getShowText());
1110 view.setShowUnconserved(av.getShowUnconserved());
1111 view.setWrapAlignment(av.getWrapAlignment());
1112 view.setTextCol1(av.textColour.getRGB());
1113 view.setTextCol2(av.textColour2.getRGB());
1114 view.setTextColThreshold(av.thresholdTextColour);
1115 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1116 view.setShowSequenceLogo(av.isShowSequenceLogo());
1117 view.setShowGroupConsensus(av.isShowGroupConsensus());
1118 view.setShowGroupConservation(av.isShowGroupConservation());
1119 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1120 view.setShowDbRefTooltip(av.isShowDbRefs());
1121 view.setFollowHighlight(av.followHighlight);
1122 view.setFollowSelection(av.followSelection);
1123 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1124 if (av.featuresDisplayed != null)
1126 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1128 String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;
1130 Vector settingsAdded = new Vector();
1131 Object gstyle = null;
1132 GraduatedColor gcol = null;
1133 if (renderOrder != null)
1135 for (int ro = 0; ro < renderOrder.length; ro++)
1137 gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer()
1138 .getFeatureStyle(renderOrder[ro]);
1139 Setting setting = new Setting();
1140 setting.setType(renderOrder[ro]);
1141 if (gstyle instanceof GraduatedColor)
1143 gcol = (GraduatedColor) gstyle;
1144 setting.setColour(gcol.getMaxColor().getRGB());
1145 setting.setMincolour(gcol.getMinColor().getRGB());
1146 setting.setMin(gcol.getMin());
1147 setting.setMax(gcol.getMax());
1148 setting.setColourByLabel(gcol.isColourByLabel());
1149 setting.setAutoScale(gcol.isAutoScale());
1150 setting.setThreshold(gcol.getThresh());
1151 setting.setThreshstate(gcol.getThreshType());
1155 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1156 .getColour(renderOrder[ro]).getRGB());
1159 setting.setDisplay(av.featuresDisplayed
1160 .containsKey(renderOrder[ro]));
1161 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1162 .getOrder(renderOrder[ro]);
1165 setting.setOrder(rorder);
1167 fs.addSetting(setting);
1168 settingsAdded.addElement(renderOrder[ro]);
1172 // Make sure we save none displayed feature settings
1173 Iterator en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours
1174 .keySet().iterator();
1175 while (en.hasNext())
1177 String key = en.next().toString();
1178 if (settingsAdded.contains(key))
1183 Setting setting = new Setting();
1184 setting.setType(key);
1185 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1186 .getColour(key).getRGB());
1188 setting.setDisplay(false);
1189 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer().getOrder(
1193 setting.setOrder(rorder);
1195 fs.addSetting(setting);
1196 settingsAdded.addElement(key);
1198 en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups.keySet().iterator();
1199 Vector groupsAdded = new Vector();
1200 while (en.hasNext())
1202 String grp = en.next().toString();
1203 if (groupsAdded.contains(grp))
1207 Group g = new Group();
1209 g.setDisplay(((Boolean) ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1210 .get(grp)).booleanValue());
1212 groupsAdded.addElement(grp);
1214 jms.setFeatureSettings(fs);
1218 if (av.hasHiddenColumns())
1220 if (av.getColumnSelection() == null
1221 || av.getColumnSelection().getHiddenColumns() == null)
1223 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1227 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1230 int[] region = (int[]) av.getColumnSelection().getHiddenColumns()
1232 HiddenColumns hc = new HiddenColumns();
1233 hc.setStart(region[0]);
1234 hc.setEnd(region[1]);
1235 view.addHiddenColumns(hc);
1239 if (calcIdSet.size()>0)
1241 for (String calcId:calcIdSet)
1243 if (calcId.trim().length()>0) {
1244 view.addCalcIdParam(createCalcIdParam(calcId, av));
1249 jms.addViewport(view);
1251 object.setJalviewModelSequence(jms);
1252 object.getVamsasModel().addSequenceSet(vamsasSet);
1254 if (jout != null && fileName != null)
1256 // We may not want to write the object to disk,
1257 // eg we can copy the alignViewport to a new view object
1258 // using save and then load
1261 JarEntry entry = new JarEntry(fileName);
1262 jout.putNextEntry(entry);
1263 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1265 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1267 marshaller.marshal(object);
1270 } catch (Exception ex)
1272 // TODO: raise error in GUI if marshalling failed.
1273 ex.printStackTrace();
1279 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1281 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1282 if (settings != null)
1284 CalcIdParam vCalcIdParam = new CalcIdParam();
1285 vCalcIdParam.setCalcId(calcId);
1286 vCalcIdParam.addServiceURL(settings.getServiceURI());
1287 // generic URI allowing a third party to resolve another instance of the
1288 // service used for this calculation
1289 for (String urls:settings.getServiceURLs())
1291 vCalcIdParam.addServiceURL(urls);
1293 vCalcIdParam.setVersion("1.0");
1294 if (settings.getPreset() != null)
1296 WsParamSetI setting = settings.getPreset();
1297 vCalcIdParam.setName(setting.getName());
1298 vCalcIdParam.setDescription(setting.getDescription());
1302 vCalcIdParam.setName("");
1303 vCalcIdParam.setDescription("Last used parameters");
1305 // need to be able to recover 1) settings 2) user-defined presets or
1306 // recreate settings from preset 3) predefined settings provided by
1307 // service - or settings that can be transferred (or discarded)
1308 vCalcIdParam.setParameters(settings
1309 .getWsParamFile().replace("\n", "|\\n|"));
1310 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1311 // todo - decide if updateImmediately is needed for any projects.
1313 return vCalcIdParam;
1318 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1321 if (calcIdParam.getVersion().equals("1.0"))
1323 Jws2Instance service=Jws2Discoverer.getDiscoverer().getPreferredServiceFor(calcIdParam.getServiceURL());
1326 WsParamSetI parmSet=null;
1328 parmSet = service.getParamStore().parseServiceParameterFile(calcIdParam.getName(), calcIdParam.getDescription(), calcIdParam.getServiceURL(), calcIdParam.getParameters().replace("|\\n|", "\n"));
1329 } catch (IOException x)
1331 warn("Couldn't parse parameter data for "+calcIdParam.getCalcId(), x);
1334 List<ArgumentI> argList=null;
1335 if (calcIdParam.getName().length()>0) {
1336 parmSet = service.getParamStore().getPreset(calcIdParam.getName());
1339 // TODO : check we have a good match with settings in AACons - otherwise we'll need to create a new preset
1343 argList = parmSet.getArguments();
1346 AAConsSettings settings = new AAConsSettings(calcIdParam.isAutoUpdate(), service, parmSet, argList);
1347 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings, calcIdParam.isNeedsUpdate());
1350 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1354 throw new Error("Unsupported Version for calcIdparam "
1355 + calcIdParam.toString());
1358 * External mapping between jalview objects and objects yielding a valid and
1359 * unique object ID string. This is null for normal Jalview project IO, but
1360 * non-null when a jalview project is being read or written as part of a
1363 IdentityHashMap jv2vobj = null;
1366 * Construct a unique ID for jvobj using either existing bindings or if none
1367 * exist, the result of the hashcode call for the object.
1370 * jalview data object
1371 * @return unique ID for referring to jvobj
1373 private String makeHashCode(Object jvobj, String altCode)
1375 if (jv2vobj != null)
1377 Object id = jv2vobj.get(jvobj);
1380 return id.toString();
1382 // check string ID mappings
1383 if (jvids2vobj != null && jvobj instanceof String)
1385 id = jvids2vobj.get(jvobj);
1389 return id.toString();
1391 // give up and warn that something has gone wrong
1392 warn("Cannot find ID for object in external mapping : " + jvobj);
1398 * return local jalview object mapped to ID, if it exists
1402 * @return null or object bound to idcode
1404 private Object retrieveExistingObj(String idcode)
1406 if (idcode != null && vobj2jv != null)
1408 return vobj2jv.get(idcode);
1414 * binding from ID strings from external mapping table to jalview data model
1417 private Hashtable vobj2jv;
1419 private Sequence createVamsasSequence(String id, SequenceI jds)
1421 return createVamsasSequence(true, id, jds, null);
1424 private Sequence createVamsasSequence(boolean recurse, String id,
1425 SequenceI jds, SequenceI parentseq)
1427 Sequence vamsasSeq = new Sequence();
1428 vamsasSeq.setId(id);
1429 vamsasSeq.setName(jds.getName());
1430 vamsasSeq.setSequence(jds.getSequenceAsString());
1431 vamsasSeq.setDescription(jds.getDescription());
1432 jalview.datamodel.DBRefEntry[] dbrefs = null;
1433 if (jds.getDatasetSequence() != null)
1435 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1436 if (jds.getDatasetSequence().getDBRef() != null)
1438 dbrefs = jds.getDatasetSequence().getDBRef();
1443 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1444 // dataset sequences only
1445 dbrefs = jds.getDBRef();
1449 for (int d = 0; d < dbrefs.length; d++)
1451 DBRef dbref = new DBRef();
1452 dbref.setSource(dbrefs[d].getSource());
1453 dbref.setVersion(dbrefs[d].getVersion());
1454 dbref.setAccessionId(dbrefs[d].getAccessionId());
1455 if (dbrefs[d].hasMap())
1457 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1459 dbref.setMapping(mp);
1461 vamsasSeq.addDBRef(dbref);
1467 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1468 SequenceI parentseq, SequenceI jds, boolean recurse)
1471 if (jmp.getMap() != null)
1475 jalview.util.MapList mlst = jmp.getMap();
1476 int r[] = mlst.getFromRanges();
1477 for (int s = 0; s < r.length; s += 2)
1479 MapListFrom mfrom = new MapListFrom();
1480 mfrom.setStart(r[s]);
1481 mfrom.setEnd(r[s + 1]);
1482 mp.addMapListFrom(mfrom);
1484 r = mlst.getToRanges();
1485 for (int s = 0; s < r.length; s += 2)
1487 MapListTo mto = new MapListTo();
1489 mto.setEnd(r[s + 1]);
1490 mp.addMapListTo(mto);
1492 mp.setMapFromUnit(mlst.getFromRatio());
1493 mp.setMapToUnit(mlst.getToRatio());
1494 if (jmp.getTo() != null)
1496 MappingChoice mpc = new MappingChoice();
1498 && (parentseq != jmp.getTo() || parentseq
1499 .getDatasetSequence() != jmp.getTo()))
1501 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1507 SequenceI ps = null;
1508 if (parentseq != jmp.getTo()
1509 && parentseq.getDatasetSequence() != jmp.getTo())
1511 // chaining dbref rather than a handshaking one
1512 jmpid = seqHash(ps = jmp.getTo());
1516 jmpid = seqHash(ps = parentseq);
1518 mpc.setDseqFor(jmpid);
1519 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1521 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1522 seqRefIds.put(mpc.getDseqFor(), ps);
1526 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1529 mp.setMappingChoice(mpc);
1535 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1536 Vector userColours, JalviewModelSequence jms)
1539 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1540 boolean newucs = false;
1541 if (!userColours.contains(ucs))
1543 userColours.add(ucs);
1546 id = "ucs" + userColours.indexOf(ucs);
1549 // actually create the scheme's entry in the XML model
1550 java.awt.Color[] colours = ucs.getColours();
1551 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1552 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1554 for (int i = 0; i < colours.length; i++)
1556 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1557 col.setName(ResidueProperties.aa[i]);
1558 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1559 jbucs.addColour(col);
1561 if (ucs.getLowerCaseColours() != null)
1563 colours = ucs.getLowerCaseColours();
1564 for (int i = 0; i < colours.length; i++)
1566 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1567 col.setName(ResidueProperties.aa[i].toLowerCase());
1568 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1569 jbucs.addColour(col);
1574 uc.setUserColourScheme(jbucs);
1575 jms.addUserColours(uc);
1581 jalview.schemes.UserColourScheme GetUserColourScheme(
1582 JalviewModelSequence jms, String id)
1584 UserColours[] uc = jms.getUserColours();
1585 UserColours colours = null;
1587 for (int i = 0; i < uc.length; i++)
1589 if (uc[i].getId().equals(id))
1597 java.awt.Color[] newColours = new java.awt.Color[24];
1599 for (int i = 0; i < 24; i++)
1601 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1602 .getUserColourScheme().getColour(i).getRGB(), 16));
1605 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1608 if (colours.getUserColourScheme().getColourCount() > 24)
1610 newColours = new java.awt.Color[23];
1611 for (int i = 0; i < 23; i++)
1613 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1614 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1616 ucs.setLowerCaseColours(newColours);
1623 * contains last error message (if any) encountered by XML loader.
1625 String errorMessage = null;
1628 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1629 * exceptions are raised during project XML parsing
1631 public boolean attemptversion1parse = true;
1634 * Load a jalview project archive from a jar file
1637 * - HTTP URL or filename
1639 public AlignFrame LoadJalviewAlign(final String file)
1642 jalview.gui.AlignFrame af = null;
1646 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1647 // Workaround is to make sure caller implements the JarInputStreamProvider
1649 // so we can re-open the jar input stream for each entry.
1651 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1652 af = LoadJalviewAlign(jprovider);
1653 } catch (MalformedURLException e)
1655 errorMessage = "Invalid URL format for '" + file + "'";
1661 private jarInputStreamProvider createjarInputStreamProvider(
1662 final String file) throws MalformedURLException
1665 errorMessage = null;
1666 uniqueSetSuffix = null;
1668 viewportsAdded = null;
1669 frefedSequence = null;
1671 if (file.startsWith("http://"))
1673 url = new URL(file);
1675 final URL _url = url;
1676 return new jarInputStreamProvider()
1680 public JarInputStream getJarInputStream() throws IOException
1684 return new JarInputStream(_url.openStream());
1688 return new JarInputStream(new FileInputStream(file));
1693 public String getFilename()
1701 * Recover jalview session from a jalview project archive. Caller may
1702 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1703 * themselves. Any null fields will be initialised with default values,
1704 * non-null fields are left alone.
1709 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1711 errorMessage = null;
1712 if (uniqueSetSuffix == null)
1714 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1716 if (seqRefIds == null)
1718 seqRefIds = new Hashtable();
1720 if (viewportsAdded == null)
1722 viewportsAdded = new Hashtable();
1724 if (frefedSequence == null)
1726 frefedSequence = new Vector();
1729 jalview.gui.AlignFrame af = null;
1730 Hashtable gatherToThisFrame = new Hashtable();
1731 final String file = jprovider.getFilename();
1734 JarInputStream jin = null;
1735 JarEntry jarentry = null;
1740 jin = jprovider.getJarInputStream();
1741 for (int i = 0; i < entryCount; i++)
1743 jarentry = jin.getNextJarEntry();
1746 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1748 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1749 JalviewModel object = new JalviewModel();
1751 Unmarshaller unmar = new Unmarshaller(object);
1752 unmar.setValidation(false);
1753 object = (JalviewModel) unmar.unmarshal(in);
1754 if (true) // !skipViewport(object))
1756 af = LoadFromObject(object, file, true, jprovider);
1757 if (af.viewport.gatherViewsHere)
1759 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
1764 else if (jarentry != null)
1766 // Some other file here.
1769 } while (jarentry != null);
1770 resolveFrefedSequences();
1771 } catch (java.io.FileNotFoundException ex)
1773 ex.printStackTrace();
1774 errorMessage = "Couldn't locate Jalview XML file : " + file;
1775 System.err.println("Exception whilst loading jalview XML file : "
1777 } catch (java.net.UnknownHostException ex)
1779 ex.printStackTrace();
1780 errorMessage = "Couldn't locate Jalview XML file : " + file;
1781 System.err.println("Exception whilst loading jalview XML file : "
1783 } catch (Exception ex)
1785 System.err.println("Parsing as Jalview Version 2 file failed.");
1786 ex.printStackTrace(System.err);
1787 if (attemptversion1parse)
1789 // Is Version 1 Jar file?
1792 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
1793 } catch (Exception ex2)
1795 System.err.println("Exception whilst loading as jalviewXMLV1:");
1796 ex2.printStackTrace();
1800 if (Desktop.instance != null)
1802 Desktop.instance.stopLoading();
1806 System.out.println("Successfully loaded archive file");
1809 ex.printStackTrace();
1811 System.err.println("Exception whilst loading jalview XML file : "
1813 } catch (OutOfMemoryError e)
1815 // Don't use the OOM Window here
1816 errorMessage = "Out of memory loading jalview XML file";
1817 System.err.println("Out of memory whilst loading jalview XML file");
1818 e.printStackTrace();
1821 if (Desktop.instance != null)
1823 Desktop.instance.stopLoading();
1826 Enumeration en = gatherToThisFrame.elements();
1827 while (en.hasMoreElements())
1829 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
1831 if (errorMessage != null)
1839 * check errorMessage for a valid error message and raise an error box in the
1840 * GUI or write the current errorMessage to stderr and then clear the error
1843 protected void reportErrors()
1845 reportErrors(false);
1848 protected void reportErrors(final boolean saving)
1850 if (errorMessage != null)
1852 final String finalErrorMessage = errorMessage;
1855 javax.swing.SwingUtilities.invokeLater(new Runnable()
1860 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1861 finalErrorMessage, "Error "
1862 + (saving ? "saving" : "loading")
1863 + " Jalview file", JOptionPane.WARNING_MESSAGE);
1869 System.err.println("Problem loading Jalview file: " + errorMessage);
1872 errorMessage = null;
1875 Hashtable alreadyLoadedPDB;
1878 * when set, local views will be updated from view stored in JalviewXML
1879 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
1880 * sync if this is set to true.
1882 private final boolean updateLocalViews = false;
1884 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
1886 if (alreadyLoadedPDB == null)
1887 alreadyLoadedPDB = new Hashtable();
1889 if (alreadyLoadedPDB.containsKey(pdbId))
1890 return alreadyLoadedPDB.get(pdbId).toString();
1894 JarInputStream jin = jprovider.getJarInputStream();
1896 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
1897 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
1898 * FileInputStream(jprovider)); }
1901 JarEntry entry = null;
1904 entry = jin.getNextJarEntry();
1905 } while (entry != null && !entry.getName().equals(pdbId));
1908 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
1909 File outFile = File.createTempFile("jalview_pdb", ".txt");
1910 outFile.deleteOnExit();
1911 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
1914 while ((data = in.readLine()) != null)
1921 } catch (Exception foo)
1926 String t=outFile.getAbsolutePath();
1927 alreadyLoadedPDB.put(pdbId, t);
1932 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
1934 } catch (Exception ex)
1936 ex.printStackTrace();
1942 private class JvAnnotRow
1944 public JvAnnotRow(int i, AlignmentAnnotation jaa)
1951 * persisted version of annotation row from which to take vis properties
1953 public jalview.datamodel.AlignmentAnnotation template;
1956 * original position of the annotation row in the alignment
1962 * Load alignment frame from jalview XML DOM object
1967 * filename source string
1968 * @param loadTreesAndStructures
1969 * when false only create Viewport
1971 * data source provider
1972 * @return alignment frame created from view stored in DOM
1974 AlignFrame LoadFromObject(JalviewModel object, String file,
1975 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
1977 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
1978 Sequence[] vamsasSeq = vamsasSet.getSequence();
1980 JalviewModelSequence jms = object.getJalviewModelSequence();
1982 Viewport view = jms.getViewport(0);
1983 // ////////////////////////////////
1986 Vector hiddenSeqs = null;
1987 jalview.datamodel.Sequence jseq;
1989 ArrayList tmpseqs = new ArrayList();
1991 boolean multipleView = false;
1993 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
1994 int vi = 0; // counter in vamsasSeq array
1995 for (int i = 0; i < JSEQ.length; i++)
1997 String seqId = JSEQ[i].getId();
1999 if (seqRefIds.get(seqId) != null)
2001 tmpseqs.add(seqRefIds.get(seqId));
2002 multipleView = true;
2006 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2007 vamsasSeq[vi].getSequence());
2008 jseq.setDescription(vamsasSeq[vi].getDescription());
2009 jseq.setStart(JSEQ[i].getStart());
2010 jseq.setEnd(JSEQ[i].getEnd());
2011 jseq.setVamsasId(uniqueSetSuffix + seqId);
2012 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2017 if (JSEQ[i].getHidden())
2019 if (hiddenSeqs == null)
2021 hiddenSeqs = new Vector();
2024 hiddenSeqs.addElement(seqRefIds
2031 // Create the alignment object from the sequence set
2032 // ///////////////////////////////
2033 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2036 tmpseqs.toArray(orderedSeqs);
2038 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2041 // / Add the alignment properties
2042 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2044 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2045 al.setProperty(ssp.getKey(), ssp.getValue());
2049 // SequenceFeatures are added to the DatasetSequence,
2050 // so we must create or recover the dataset before loading features
2051 // ///////////////////////////////
2052 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2054 // older jalview projects do not have a dataset id.
2055 al.setDataset(null);
2059 recoverDatasetFor(vamsasSet, al);
2061 // ///////////////////////////////
2063 Hashtable pdbloaded = new Hashtable();
2066 // load sequence features, database references and any associated PDB
2067 // structures for the alignment
2068 for (int i = 0; i < vamsasSeq.length; i++)
2070 if (JSEQ[i].getFeaturesCount() > 0)
2072 Features[] features = JSEQ[i].getFeatures();
2073 for (int f = 0; f < features.length; f++)
2075 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2076 features[f].getType(), features[f].getDescription(),
2077 features[f].getStatus(), features[f].getBegin(),
2078 features[f].getEnd(), features[f].getFeatureGroup());
2080 sf.setScore(features[f].getScore());
2081 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2083 OtherData keyValue = features[f].getOtherData(od);
2084 if (keyValue.getKey().startsWith("LINK"))
2086 sf.addLink(keyValue.getValue());
2090 sf.setValue(keyValue.getKey(), keyValue.getValue());
2095 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2098 if (vamsasSeq[i].getDBRefCount() > 0)
2100 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2102 if (JSEQ[i].getPdbidsCount() > 0)
2104 Pdbids[] ids = JSEQ[i].getPdbids();
2105 for (int p = 0; p < ids.length; p++)
2107 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2108 entry.setId(ids[p].getId());
2109 entry.setType(ids[p].getType());
2110 if (ids[p].getFile() != null)
2112 if (!pdbloaded.containsKey(ids[p].getFile()))
2114 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2118 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2122 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2126 } // end !multipleview
2128 // ///////////////////////////////
2129 // LOAD SEQUENCE MAPPINGS
2131 if (vamsasSet.getAlcodonFrameCount() > 0)
2133 // TODO Potentially this should only be done once for all views of an
2135 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2136 for (int i = 0; i < alc.length; i++)
2138 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2139 alc[i].getAlcodonCount());
2140 if (alc[i].getAlcodonCount() > 0)
2142 Alcodon[] alcods = alc[i].getAlcodon();
2143 for (int p = 0; p < cf.codons.length; p++)
2145 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2146 && alcods[p].hasPos3())
2148 // translated codons require three valid positions
2149 cf.codons[p] = new int[3];
2150 cf.codons[p][0] = (int) alcods[p].getPos1();
2151 cf.codons[p][1] = (int) alcods[p].getPos2();
2152 cf.codons[p][2] = (int) alcods[p].getPos3();
2156 cf.codons[p] = null;
2160 if (alc[i].getAlcodMapCount() > 0)
2162 AlcodMap[] maps = alc[i].getAlcodMap();
2163 for (int m = 0; m < maps.length; m++)
2165 SequenceI dnaseq = (SequenceI) seqRefIds
2166 .get(maps[m].getDnasq());
2168 jalview.datamodel.Mapping mapping = null;
2169 // attach to dna sequence reference.
2170 if (maps[m].getMapping() != null)
2172 mapping = addMapping(maps[m].getMapping());
2176 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2181 frefedSequence.add(new Object[]
2182 { maps[m].getDnasq(), cf, mapping });
2186 al.addCodonFrame(cf);
2191 // ////////////////////////////////
2193 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2195 * store any annotations which forward reference a group's ID
2197 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2199 if (vamsasSet.getAnnotationCount() > 0)
2201 Annotation[] an = vamsasSet.getAnnotation();
2203 for (int i = 0; i < an.length; i++)
2206 * test if annotation is automatically calculated for this view only
2208 boolean autoForView = false;
2209 if (an[i].getLabel().equals("Quality")
2210 || an[i].getLabel().equals("Conservation")
2211 || an[i].getLabel().equals("Consensus"))
2213 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2215 if (!an[i].hasAutoCalculated())
2217 an[i].setAutoCalculated(true);
2221 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2223 // remove ID - we don't recover annotation from other views for
2224 // view-specific annotation
2228 // set visiblity for other annotation in this view
2229 if (an[i].getId() != null
2230 && annotationIds.containsKey(an[i].getId()))
2232 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2233 .get(an[i].getId());
2234 // in principle Visible should always be true for annotation displayed
2235 // in multiple views
2236 if (an[i].hasVisible())
2237 jda.visible = an[i].getVisible();
2239 al.addAnnotation(jda);
2243 // Construct new annotation from model.
2244 AnnotationElement[] ae = an[i].getAnnotationElement();
2245 jalview.datamodel.Annotation[] anot = null;
2247 if (!an[i].getScoreOnly())
2249 anot = new jalview.datamodel.Annotation[al.getWidth()];
2250 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2252 if (ae[aa].getPosition() >= anot.length)
2255 anot[ae[aa].getPosition()] = new jalview.datamodel.Annotation(
2257 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2258 (ae[aa].getSecondaryStructure() == null || ae[aa]
2259 .getSecondaryStructure().length() == 0) ? ' '
2260 : ae[aa].getSecondaryStructure().charAt(0),
2264 // JBPNote: Consider verifying dataflow for IO of secondary
2265 // structure annotation read from Stockholm files
2266 // this was added to try to ensure that
2267 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2269 // anot[ae[aa].getPosition()].displayCharacter = "";
2271 anot[ae[aa].getPosition()].colour = new java.awt.Color(
2272 ae[aa].getColour());
2275 jalview.datamodel.AlignmentAnnotation jaa = null;
2277 if (an[i].getGraph())
2279 float llim = 0, hlim = 0;
2280 // if (autoForView || an[i].isAutoCalculated()) {
2283 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2284 an[i].getDescription(), anot, llim, hlim,
2285 an[i].getGraphType());
2287 jaa.graphGroup = an[i].getGraphGroup();
2289 if (an[i].getThresholdLine() != null)
2291 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2292 .getThresholdLine().getValue(), an[i]
2293 .getThresholdLine().getLabel(), new java.awt.Color(
2294 an[i].getThresholdLine().getColour())));
2297 if (autoForView || an[i].isAutoCalculated())
2299 // Hardwire the symbol display line to ensure that labels for
2300 // histograms are displayed
2306 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2307 an[i].getDescription(), anot);
2311 // register new annotation
2312 if (an[i].getId() != null)
2314 annotationIds.put(an[i].getId(), jaa);
2315 jaa.annotationId = an[i].getId();
2317 // recover sequence association
2318 if (an[i].getSequenceRef() != null)
2320 if (al.findName(an[i].getSequenceRef()) != null)
2322 jaa.createSequenceMapping(
2323 al.findName(an[i].getSequenceRef()), 1, true);
2324 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(
2329 // and make a note of any group association
2330 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2332 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2333 .get(an[i].getGroupRef());
2336 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2337 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2342 if (an[i].hasScore())
2344 jaa.setScore(an[i].getScore());
2346 if (an[i].hasVisible())
2347 jaa.visible = an[i].getVisible();
2349 if (an[i].hasCentreColLabels())
2350 jaa.centreColLabels = an[i].getCentreColLabels();
2352 if (an[i].hasScaleColLabels())
2354 jaa.scaleColLabel = an[i].getScaleColLabels();
2356 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2358 // newer files have an 'autoCalculated' flag and store calculation
2359 // state in viewport properties
2360 jaa.autoCalculated = true; // means annotation will be marked for
2361 // update at end of load.
2363 if (an[i].hasGraphHeight())
2365 jaa.graphHeight = an[i].getGraphHeight();
2367 if (an[i].hasBelowAlignment())
2369 jaa.belowAlignment=an[i].isBelowAlignment();
2371 jaa.setCalcId(an[i].getCalcId());
2373 if (jaa.autoCalculated)
2375 autoAlan.add(new JvAnnotRow(i, jaa));
2378 // if (!autoForView)
2380 // add autocalculated group annotation and any user created annotation
2382 al.addAnnotation(jaa);
2387 // ///////////////////////
2389 // Create alignment markup and styles for this view
2390 if (jms.getJGroupCount() > 0)
2392 JGroup[] groups = jms.getJGroup();
2394 for (int i = 0; i < groups.length; i++)
2396 ColourSchemeI cs = null;
2398 if (groups[i].getColour() != null)
2400 if (groups[i].getColour().startsWith("ucs"))
2402 cs = GetUserColourScheme(jms, groups[i].getColour());
2406 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2411 cs.setThreshold(groups[i].getPidThreshold(), true);
2415 Vector seqs = new Vector();
2417 for (int s = 0; s < groups[i].getSeqCount(); s++)
2419 String seqId = groups[i].getSeq(s) + "";
2420 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2425 seqs.addElement(ts);
2429 if (seqs.size() < 1)
2434 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2435 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2436 groups[i].getDisplayText(), groups[i].getColourText(),
2437 groups[i].getStart(), groups[i].getEnd());
2439 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2441 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2442 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2443 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2444 .isShowUnconserved() : false);
2445 sg.thresholdTextColour = groups[i].getTextColThreshold();
2446 if (groups[i].hasShowConsensusHistogram())
2448 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2451 if (groups[i].hasShowSequenceLogo())
2453 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2455 if (groups[i].hasIgnoreGapsinConsensus())
2457 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2459 if (groups[i].getConsThreshold() != 0)
2461 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2462 "All", ResidueProperties.propHash, 3,
2463 sg.getSequences(null), 0, sg.getWidth() - 1);
2465 c.verdict(false, 25);
2466 sg.cs.setConservation(c);
2469 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2471 // re-instate unique group/annotation row reference
2472 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2473 .get(groups[i].getId());
2476 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2479 if (jaa.autoCalculated)
2481 // match up and try to set group autocalc alignment row for this
2483 if (jaa.label.startsWith("Consensus for "))
2485 sg.setConsensus(jaa);
2487 // match up and try to set group autocalc alignment row for this
2489 if (jaa.label.startsWith("Conservation for "))
2491 sg.setConservationRow(jaa);
2502 // ///////////////////////////////
2505 // If we just load in the same jar file again, the sequenceSetId
2506 // will be the same, and we end up with multiple references
2507 // to the same sequenceSet. We must modify this id on load
2508 // so that each load of the file gives a unique id
2509 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2510 String viewId = (view.getId() == null ? null : view.getId()
2512 AlignFrame af = null;
2513 AlignViewport av = null;
2514 // now check to see if we really need to create a new viewport.
2515 if (multipleView && viewportsAdded.size() == 0)
2517 // We recovered an alignment for which a viewport already exists.
2518 // TODO: fix up any settings necessary for overlaying stored state onto
2519 // state recovered from another document. (may not be necessary).
2520 // we may need a binding from a viewport in memory to one recovered from
2522 // and then recover its containing af to allow the settings to be applied.
2523 // TODO: fix for vamsas demo
2525 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2527 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2528 if (seqsetobj != null)
2530 if (seqsetobj instanceof String)
2532 uniqueSeqSetId = (String) seqsetobj;
2534 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2540 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2545 AlignmentPanel ap = null;
2546 boolean isnewview = true;
2549 // Check to see if this alignment already has a view id == viewId
2550 jalview.gui.AlignmentPanel views[] = Desktop
2551 .getAlignmentPanels(uniqueSeqSetId);
2552 if (views != null && views.length > 0)
2554 for (int v = 0; v < views.length; v++)
2556 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2558 // recover the existing alignpanel, alignframe, viewport
2559 af = views[v].alignFrame;
2562 // TODO: could even skip resetting view settings if we don't want to
2563 // change the local settings from other jalview processes
2572 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2573 uniqueSeqSetId, viewId, autoAlan);
2578 // /////////////////////////////////////
2579 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2583 for (int t = 0; t < jms.getTreeCount(); t++)
2586 Tree tree = jms.getTree(t);
2588 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2591 tp = af.ShowNewickTree(
2592 new jalview.io.NewickFile(tree.getNewick()),
2593 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2594 tree.getXpos(), tree.getYpos());
2595 if (tree.getId() != null)
2597 // perhaps bind the tree id to something ?
2602 // update local tree attributes ?
2603 // TODO: should check if tp has been manipulated by user - if so its
2604 // settings shouldn't be modified
2605 tp.setTitle(tree.getTitle());
2606 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2607 .getWidth(), tree.getHeight()));
2608 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2611 tp.treeCanvas.av = av; // af.viewport;
2612 tp.treeCanvas.ap = ap; // af.alignPanel;
2617 warn("There was a problem recovering stored Newick tree: \n"
2618 + tree.getNewick());
2622 tp.fitToWindow.setState(tree.getFitToWindow());
2623 tp.fitToWindow_actionPerformed(null);
2625 if (tree.getFontName() != null)
2627 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2628 .getFontStyle(), tree.getFontSize()));
2632 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2633 .getFontStyle(), tree.getFontSize()));
2636 tp.showPlaceholders(tree.getMarkUnlinked());
2637 tp.showBootstrap(tree.getShowBootstrap());
2638 tp.showDistances(tree.getShowDistances());
2640 tp.treeCanvas.threshold = tree.getThreshold();
2642 if (tree.getCurrentTree())
2644 af.viewport.setCurrentTree(tp.getTree());
2648 } catch (Exception ex)
2650 ex.printStackTrace();
2654 // //LOAD STRUCTURES
2655 if (loadTreesAndStructures)
2657 // run through all PDB ids on the alignment, and collect mappings between
2658 // jmol view ids and all sequences referring to it
2659 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2661 for (int i = 0; i < JSEQ.length; i++)
2663 if (JSEQ[i].getPdbidsCount() > 0)
2665 Pdbids[] ids = JSEQ[i].getPdbids();
2666 for (int p = 0; p < ids.length; p++)
2668 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2670 // check to see if we haven't already created this structure view
2671 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2672 : ids[p].getStructureState(s).getViewId()
2674 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2675 // Originally : ids[p].getFile()
2676 // : TODO: verify external PDB file recovery still works in normal
2677 // jalview project load
2678 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2679 jpdb.setId(ids[p].getId());
2681 int x = ids[p].getStructureState(s).getXpos();
2682 int y = ids[p].getStructureState(s).getYpos();
2683 int width = ids[p].getStructureState(s).getWidth();
2684 int height = ids[p].getStructureState(s).getHeight();
2686 // Probably don't need to do this anymore...
2687 // Desktop.desktop.getComponentAt(x, y);
2688 // TODO: NOW: check that this recovers the PDB file correctly.
2689 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2690 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2691 .get(JSEQ[i].getId() + "");
2692 if (sviewid == null)
2694 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2697 if (!jmolViewIds.containsKey(sviewid))
2699 jmolViewIds.put(sviewid, new Object[]
2701 { x, y, width, height }, "",
2702 new Hashtable<String, Object[]>(), new boolean[]
2703 { false, false, true } });
2704 // Legacy pre-2.7 conversion JAL-823 :
2705 // do not assume any view has to be linked for colour by
2709 // assemble String[] { pdb files }, String[] { id for each
2710 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2711 // seqs_file 2}, boolean[] {
2712 // linkAlignPanel,superposeWithAlignpanel}} from hash
2713 Object[] jmoldat = jmolViewIds.get(sviewid);
2714 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2715 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
2716 s).getAlignwithAlignPanel() : false;
2717 // never colour by linked panel if not specified
2718 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
2719 .hasColourwithAlignPanel() ? ids[p]
2720 .getStructureState(s).getColourwithAlignPanel()
2722 // default for pre-2.7 projects is that Jmol colouring is enabled
2723 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
2724 .hasColourByJmol() ? ids[p].getStructureState(s)
2725 .getColourByJmol() : true;
2727 if (((String) jmoldat[1]).length() < ids[p]
2728 .getStructureState(s).getContent().length())
2731 jmoldat[1] = ids[p].getStructureState(s).getContent();
2734 if (ids[p].getFile() != null)
2736 File mapkey=new File(ids[p].getFile());
2737 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
2739 if (seqstrmaps == null)
2741 ((Hashtable) jmoldat[2]).put(
2743 seqstrmaps = new Object[]
2744 { pdbFile, ids[p].getId(), new Vector(),
2747 if (!((Vector) seqstrmaps[2]).contains(seq))
2749 ((Vector) seqstrmaps[2]).addElement(seq);
2750 // ((Vector)seqstrmaps[3]).addElement(n) :
2751 // in principle, chains
2752 // should be stored here : do we need to
2753 // TODO: store and recover seq/pdb_id :
2759 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");
2768 // Instantiate the associated Jmol views
2769 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
2771 String sviewid = entry.getKey();
2772 Object[] svattrib = entry.getValue();
2773 int[] geom = (int[]) svattrib[0];
2774 String state = (String) svattrib[1];
2775 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
2776 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
2777 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
2778 // collate the pdbfile -> sequence mappings from this view
2779 Vector<String> pdbfilenames = new Vector<String>();
2780 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
2781 Vector<String> pdbids = new Vector<String>();
2783 // Search to see if we've already created this Jmol view
2784 AppJmol comp = null;
2785 JInternalFrame[] frames = null;
2790 frames = Desktop.desktop.getAllFrames();
2791 } catch (ArrayIndexOutOfBoundsException e)
2793 // occasional No such child exceptions are thrown here...
2798 } catch (Exception f)
2803 } while (frames == null);
2804 // search for any Jmol windows already open from other
2805 // alignment views that exactly match the stored structure state
2806 for (int f = 0; comp == null && f < frames.length; f++)
2808 if (frames[f] instanceof AppJmol)
2811 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
2813 // post jalview 2.4 schema includes structure view id
2814 comp = (AppJmol) frames[f];
2816 else if (frames[f].getX() == x && frames[f].getY() == y
2817 && frames[f].getHeight() == height
2818 && frames[f].getWidth() == width)
2820 comp = (AppJmol) frames[f];
2827 // create a new Jmol window.
2828 // First parse the Jmol state to translate filenames loaded into the
2829 // view, and record the order in which files are shown in the Jmol
2830 // view, so we can add the sequence mappings in same order.
2831 StringBuffer newFileLoc = null;
2832 int cp = 0, ncp, ecp;
2833 while ((ncp = state.indexOf("load ", cp)) > -1)
2835 if (newFileLoc == null)
2837 newFileLoc = new StringBuffer();
2840 // look for next filename in load statement
2841 newFileLoc.append(state.substring(cp,
2842 ncp = (state.indexOf("\"", ncp + 1) + 1)));
2843 String oldfilenam = state.substring(ncp,
2844 ecp = state.indexOf("\"", ncp));
2845 // recover the new mapping data for this old filename
2846 // have to normalize filename - since Jmol and jalview do filename
2847 // translation differently.
2848 Object[] filedat = oldFiles.get(new File(oldfilenam));
2849 newFileLoc.append(Platform.escapeString((String) filedat[0]));
2850 pdbfilenames.addElement((String) filedat[0]);
2851 pdbids.addElement((String) filedat[1]);
2852 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2853 .toArray(new SequenceI[0]));
2854 newFileLoc.append("\"");
2855 cp = ecp + 1; // advance beyond last \" and set cursor so we can
2856 // look for next file statement.
2857 } while ((ncp=state.indexOf("/*file*/",cp))>-1);
2861 // just append rest of state
2862 newFileLoc.append(state.substring(cp));
2867 .print("Ignoring incomplete Jmol state for PDB ids: ");
2868 newFileLoc = new StringBuffer(state);
2869 newFileLoc.append("; load append ");
2870 for (File id : oldFiles.keySet())
2872 // add this and any other pdb files that should be present in
2874 Object[] filedat = oldFiles.get(id);
2876 newFileLoc.append(((String) filedat[0]));
2877 pdbfilenames.addElement((String) filedat[0]);
2878 pdbids.addElement((String) filedat[1]);
2879 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2880 .toArray(new SequenceI[0]));
2881 newFileLoc.append(" \"");
2882 newFileLoc.append((String) filedat[0]);
2883 newFileLoc.append("\"");
2886 newFileLoc.append(";");
2889 if (newFileLoc != null)
2891 int histbug = newFileLoc.indexOf("history = ");
2893 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
2895 String val = (diff == -1) ? null : newFileLoc.substring(
2897 if (val != null && val.length() >= 4)
2899 if (val.contains("e"))
2901 if (val.trim().equals("true"))
2909 newFileLoc.replace(histbug, diff, val);
2912 // TODO: assemble String[] { pdb files }, String[] { id for each
2913 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2914 // seqs_file 2}} from hash
2915 final String[] pdbf = pdbfilenames
2916 .toArray(new String[pdbfilenames.size()]), id = pdbids
2917 .toArray(new String[pdbids.size()]);
2918 final SequenceI[][] sq = seqmaps
2919 .toArray(new SequenceI[seqmaps.size()][]);
2920 final String fileloc = newFileLoc.toString(), vid = sviewid;
2921 final AlignFrame alf = af;
2922 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
2926 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
2931 AppJmol sview = null;
2934 sview = new AppJmol(pdbf, id, sq, alf.alignPanel,
2935 useinJmolsuperpos, usetoColourbyseq,
2936 jmolColouring, fileloc, rect, vid);
2937 } catch (OutOfMemoryError ex)
2939 new OOMWarning("restoring structure view for PDB id "
2940 + id, (OutOfMemoryError) ex.getCause());
2941 if (sview != null && sview.isVisible())
2943 sview.closeViewer();
2944 sview.setVisible(false);
2950 } catch (InvocationTargetException ex)
2952 warn("Unexpected error when opening Jmol view.", ex);
2954 } catch (InterruptedException e)
2956 // e.printStackTrace();
2962 // if (comp != null)
2964 // NOTE: if the jalview project is part of a shared session then
2965 // view synchronization should/could be done here.
2967 // add mapping for sequences in this view to an already open Jmol
2969 for (File id : oldFiles.keySet())
2971 // add this and any other pdb files that should be present in the
2973 Object[] filedat = oldFiles.get(id);
2974 String pdbFile = (String) filedat[0];
2975 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
2976 .toArray(new SequenceI[0]);
2977 comp.jmb.ssm.setMapping(seq, null, pdbFile,
2978 jalview.io.AppletFormatAdapter.FILE);
2979 comp.jmb.addSequenceForStructFile(pdbFile, seq);
2981 // and add the AlignmentPanel's reference to the Jmol view
2982 comp.addAlignmentPanel(ap);
2983 if (useinJmolsuperpos)
2985 comp.useAlignmentPanelForSuperposition(ap);
2989 comp.excludeAlignmentPanelForSuperposition(ap);
2991 if (usetoColourbyseq)
2993 comp.useAlignmentPanelForColourbyseq(ap,
2998 comp.excludeAlignmentPanelForColourbyseq(ap);
3004 // and finally return.
3008 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3009 Alignment al, JalviewModelSequence jms, Viewport view,
3010 String uniqueSeqSetId, String viewId,
3011 ArrayList<JvAnnotRow> autoAlan)
3013 AlignFrame af = null;
3014 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3015 uniqueSeqSetId, viewId);
3017 af.setFileName(file, "Jalview");
3019 for (int i = 0; i < JSEQ.length; i++)
3021 af.viewport.setSequenceColour(af.viewport.getAlignment().getSequenceAt(i),
3022 new java.awt.Color(JSEQ[i].getColour()));
3025 af.viewport.gatherViewsHere = view.getGatheredViews();
3027 if (view.getSequenceSetId() != null)
3029 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3030 .get(uniqueSeqSetId);
3032 af.viewport.setSequenceSetId(uniqueSeqSetId);
3035 // propagate shared settings to this new view
3036 af.viewport.historyList = av.historyList;
3037 af.viewport.redoList = av.redoList;
3041 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3043 // TODO: check if this method can be called repeatedly without
3044 // side-effects if alignpanel already registered.
3045 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3047 // apply Hidden regions to view.
3048 if (hiddenSeqs != null)
3050 for (int s = 0; s < JSEQ.length; s++)
3052 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3054 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3057 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3059 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3062 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3065 for (int s = 0; s < hiddenSeqs.size(); s++)
3067 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3070 af.viewport.hideSequence(hseqs);
3073 // recover view properties and display parameters
3074 if (view.getViewName() != null)
3076 af.viewport.viewName = view.getViewName();
3077 af.setInitialTabVisible();
3079 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3082 af.viewport.setShowAnnotation(view.getShowAnnotation());
3083 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3085 af.viewport.setColourText(view.getShowColourText());
3087 af.viewport.setConservationSelected(view.getConservationSelected());
3088 af.viewport.setShowJVSuffix(view.getShowFullId());
3089 af.viewport.rightAlignIds = view.getRightAlignIds();
3090 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3091 .getFontStyle(), view.getFontSize()));
3092 af.alignPanel.fontChanged();
3093 af.viewport.setRenderGaps(view.getRenderGaps());
3094 af.viewport.setWrapAlignment(view.getWrapAlignment());
3095 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3096 af.viewport.setShowAnnotation(view.getShowAnnotation());
3097 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3099 af.viewport.setShowBoxes(view.getShowBoxes());
3101 af.viewport.setShowText(view.getShowText());
3103 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3104 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3105 af.viewport.thresholdTextColour = view.getTextColThreshold();
3106 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3107 .isShowUnconserved() : false);
3108 af.viewport.setStartRes(view.getStartRes());
3109 af.viewport.setStartSeq(view.getStartSeq());
3111 ColourSchemeI cs = null;
3112 // apply colourschemes
3113 if (view.getBgColour() != null)
3115 if (view.getBgColour().startsWith("ucs"))
3117 cs = GetUserColourScheme(jms, view.getBgColour());
3119 else if (view.getBgColour().startsWith("Annotation"))
3121 // int find annotation
3122 if (af.viewport.getAlignment().getAlignmentAnnotation() != null)
3124 for (int i = 0; i < af.viewport.getAlignment()
3125 .getAlignmentAnnotation().length; i++)
3127 if (af.viewport.getAlignment().getAlignmentAnnotation()[i].label
3128 .equals(view.getAnnotationColours().getAnnotation()))
3130 if (af.viewport.getAlignment().getAlignmentAnnotation()[i]
3131 .getThreshold() == null)
3133 af.viewport.getAlignment().getAlignmentAnnotation()[i]
3134 .setThreshold(new jalview.datamodel.GraphLine(view
3135 .getAnnotationColours().getThreshold(),
3136 "Threshold", java.awt.Color.black)
3141 if (view.getAnnotationColours().getColourScheme()
3144 cs = new AnnotationColourGradient(
3145 af.viewport.getAlignment().getAlignmentAnnotation()[i],
3146 new java.awt.Color(view.getAnnotationColours()
3147 .getMinColour()), new java.awt.Color(view
3148 .getAnnotationColours().getMaxColour()),
3149 view.getAnnotationColours().getAboveThreshold());
3151 else if (view.getAnnotationColours().getColourScheme()
3154 cs = new AnnotationColourGradient(
3155 af.viewport.getAlignment().getAlignmentAnnotation()[i],
3156 GetUserColourScheme(jms, view
3157 .getAnnotationColours().getColourScheme()),
3158 view.getAnnotationColours().getAboveThreshold());
3162 cs = new AnnotationColourGradient(
3163 af.viewport.getAlignment().getAlignmentAnnotation()[i],
3164 ColourSchemeProperty.getColour(al, view
3165 .getAnnotationColours().getColourScheme()),
3166 view.getAnnotationColours().getAboveThreshold());
3169 // Also use these settings for all the groups
3170 if (al.getGroups() != null)
3172 for (int g = 0; g < al.getGroups().size(); g++)
3174 jalview.datamodel.SequenceGroup sg = al
3175 .getGroups().get(g);
3184 * (view.getAnnotationColours().getColourScheme().equals("None"
3185 * )) { sg.cs = new AnnotationColourGradient(
3186 * af.viewport.getAlignment().getAlignmentAnnotation()[i], new
3187 * java.awt.Color(view.getAnnotationColours().
3188 * getMinColour()), new
3189 * java.awt.Color(view.getAnnotationColours().
3191 * view.getAnnotationColours().getAboveThreshold()); } else
3194 sg.cs = new AnnotationColourGradient(
3195 af.viewport.getAlignment().getAlignmentAnnotation()[i],
3196 sg.cs, view.getAnnotationColours()
3197 .getAboveThreshold());
3211 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3216 cs.setThreshold(view.getPidThreshold(), true);
3217 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3221 af.viewport.setGlobalColourScheme(cs);
3222 af.viewport.setColourAppliesToAllGroups(false);
3224 if (view.getConservationSelected() && cs != null)
3226 cs.setConservationInc(view.getConsThreshold());
3229 af.changeColour(cs);
3231 af.viewport.setColourAppliesToAllGroups(true);
3233 if (view.getShowSequenceFeatures())
3235 af.viewport.showSequenceFeatures = true;
3237 if (view.hasCentreColumnLabels())
3239 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3241 if (view.hasIgnoreGapsinConsensus())
3243 af.viewport.setIgnoreGapsConsensus(view
3244 .getIgnoreGapsinConsensus(), null);
3246 if (view.hasFollowHighlight())
3248 af.viewport.followHighlight = view.getFollowHighlight();
3250 if (view.hasFollowSelection())
3252 af.viewport.followSelection = view.getFollowSelection();
3254 if (view.hasShowConsensusHistogram())
3256 af.viewport.setShowConsensusHistogram(view
3257 .getShowConsensusHistogram());
3261 af.viewport.setShowConsensusHistogram(true);
3263 if (view.hasShowSequenceLogo())
3265 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3269 af.viewport.setShowSequenceLogo(false);
3271 if (view.hasShowDbRefTooltip())
3273 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3275 if (view.hasShowNPfeatureTooltip())
3277 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3279 if (view.hasShowGroupConsensus())
3281 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3285 af.viewport.setShowGroupConsensus(false);
3287 if (view.hasShowGroupConservation())
3289 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3293 af.viewport.setShowGroupConservation(false);
3296 // recover featre settings
3297 if (jms.getFeatureSettings() != null)
3299 af.viewport.featuresDisplayed = new Hashtable();
3300 String[] renderOrder = new String[jms.getFeatureSettings()
3301 .getSettingCount()];
3302 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3304 Setting setting = jms.getFeatureSettings().getSetting(fs);
3305 if (setting.hasMincolour())
3307 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3308 new java.awt.Color(setting.getMincolour()),
3309 new java.awt.Color(setting.getColour()),
3310 setting.getMin(), setting.getMax()) : new GraduatedColor(
3311 new java.awt.Color(setting.getMincolour()),
3312 new java.awt.Color(setting.getColour()), 0, 1);
3313 if (setting.hasThreshold())
3315 gc.setThresh(setting.getThreshold());
3316 gc.setThreshType(setting.getThreshstate());
3318 gc.setAutoScaled(true); // default
3319 if (setting.hasAutoScale())
3321 gc.setAutoScaled(setting.getAutoScale());
3323 if (setting.hasColourByLabel())
3325 gc.setColourByLabel(setting.getColourByLabel());
3327 // and put in the feature colour table.
3328 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3329 setting.getType(), gc);
3333 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3335 new java.awt.Color(setting.getColour()));
3337 renderOrder[fs] = setting.getType();
3338 if (setting.hasOrder())
3339 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3340 setting.getType(), setting.getOrder());
3342 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3344 fs / jms.getFeatureSettings().getSettingCount());
3345 if (setting.getDisplay())
3347 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3348 setting.getColour()));
3351 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3353 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3354 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3356 Group grp = jms.getFeatureSettings().getGroup(gs);
3357 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3361 if (view.getHiddenColumnsCount() > 0)
3363 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3365 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3366 .getHiddenColumns(c).getEnd() // +1
3370 if (view.getCalcIdParam()!=null)
3372 for (CalcIdParam calcIdParam:view.getCalcIdParam())
3374 if (recoverCalcIdParam(calcIdParam, af.viewport)) {
3376 warn("Couldn't recover parameters for "+calcIdParam.getCalcId());
3380 af.setMenusFromViewport(af.viewport);
3381 // TODO: we don't need to do this if the viewport is aready visible.
3382 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3384 af.alignPanel.updateAnnotation(false); // recompute any autoannotation
3385 reorderAutoannotation(af, al, autoAlan);
3389 private void reorderAutoannotation(AlignFrame af, Alignment al,
3390 ArrayList<JvAnnotRow> autoAlan)
3392 // copy over visualization settings for autocalculated annotation in the
3394 if (al.getAlignmentAnnotation() != null)
3397 * Kludge for magic autoannotation names (see JAL-811)
3399 String[] magicNames = new String[]
3400 { "Consensus", "Quality", "Conservation" };
3401 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3402 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3403 for (String nm : magicNames)
3405 visan.put(nm, nullAnnot);
3407 for (JvAnnotRow auan : autoAlan)
3409 visan.put(auan.template.label+(auan.template.getCalcId()==null ? "" : "\t"+auan.template.getCalcId()), auan);
3411 int hSize = al.getAlignmentAnnotation().length;
3412 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3413 // work through any autoCalculated annotation already on the view
3414 // removing it if it should be placed in a different location on the
3415 // annotation panel.
3416 List<String> remains=new ArrayList(visan.keySet());
3417 for (int h = 0; h < hSize; h++)
3419 jalview.datamodel.AlignmentAnnotation jalan = al
3420 .getAlignmentAnnotation()[h];
3421 if (jalan.autoCalculated)
3424 JvAnnotRow valan = visan.get(k=jalan.label);
3425 if (jalan.getCalcId()!=null)
3427 valan = visan.get(k=jalan.label+ "\t"+jalan.getCalcId());
3432 // delete the auto calculated row from the alignment
3433 al.deleteAnnotation(jalan, false);
3437 if (valan != nullAnnot)
3439 if (jalan != valan.template)
3441 // newly created autoannotation row instance
3442 // so keep a reference to the visible annotation row
3443 // and copy over all relevant attributes
3444 if (valan.template.graphHeight >= 0)
3447 jalan.graphHeight = valan.template.graphHeight;
3449 jalan.visible = valan.template.visible;
3451 reorder.add(new JvAnnotRow(valan.order, jalan));
3456 // Add any (possibly stale) autocalculated rows that were not appended to the view during construction
3457 for (String other:remains)
3459 JvAnnotRow othera=visan.get(other);
3460 if (othera!=nullAnnot && othera.template.getCalcId()!=null && othera.template.getCalcId().length()>0)
3462 reorder.add(othera);
3465 // now put the automatic annotation in its correct place
3466 int s = 0, srt[] = new int[reorder.size()];
3467 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3468 for (JvAnnotRow jvar : reorder)
3471 srt[s++] = jvar.order;
3474 jalview.util.QuickSort.sort(srt, rws);
3475 // and re-insert the annotation at its correct position
3476 for (JvAnnotRow jvar : rws)
3478 al.addAnnotation(jvar.template, jvar.order);
3480 af.alignPanel.adjustAnnotationHeight();
3484 Hashtable skipList = null;
3487 * TODO remove this method
3490 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3491 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3492 * throw new Error("Implementation Error. No skipList defined for this
3493 * Jalview2XML instance."); } return (AlignFrame)
3494 * skipList.get(view.getSequenceSetId()); }
3498 * Check if the Jalview view contained in object should be skipped or not.
3501 * @return true if view's sequenceSetId is a key in skipList
3503 private boolean skipViewport(JalviewModel object)
3505 if (skipList == null)
3510 if (skipList.containsKey(id = object.getJalviewModelSequence()
3511 .getViewport()[0].getSequenceSetId()))
3513 if (Cache.log != null && Cache.log.isDebugEnabled())
3515 Cache.log.debug("Skipping seuqence set id " + id);
3522 public void AddToSkipList(AlignFrame af)
3524 if (skipList == null)
3526 skipList = new Hashtable();
3528 skipList.put(af.getViewport().getSequenceSetId(), af);
3531 public void clearSkipList()
3533 if (skipList != null)
3540 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3542 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3543 Vector dseqs = null;
3546 // create a list of new dataset sequences
3547 dseqs = new Vector();
3549 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3551 Sequence vamsasSeq = vamsasSet.getSequence(i);
3552 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
3554 // create a new dataset
3557 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3558 dseqs.copyInto(dsseqs);
3559 ds = new jalview.datamodel.Alignment(dsseqs);
3560 debug("Created new dataset " + vamsasSet.getDatasetId()
3561 + " for alignment " + System.identityHashCode(al));
3562 addDatasetRef(vamsasSet.getDatasetId(), ds);
3564 // set the dataset for the newly imported alignment.
3565 if (al.getDataset() == null)
3574 * sequence definition to create/merge dataset sequence for
3578 * vector to add new dataset sequence to
3580 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
3581 AlignmentI ds, Vector dseqs)
3583 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
3585 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
3586 .get(vamsasSeq.getId());
3587 jalview.datamodel.SequenceI dsq = null;
3588 if (sq != null && sq.getDatasetSequence() != null)
3590 dsq = sq.getDatasetSequence();
3593 String sqid = vamsasSeq.getDsseqid();
3596 // need to create or add a new dataset sequence reference to this sequence
3599 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
3604 // make a new dataset sequence
3605 dsq = sq.createDatasetSequence();
3608 // make up a new dataset reference for this sequence
3609 sqid = seqHash(dsq);
3611 dsq.setVamsasId(uniqueSetSuffix + sqid);
3612 seqRefIds.put(sqid, dsq);
3617 dseqs.addElement(dsq);
3622 ds.addSequence(dsq);
3628 { // make this dataset sequence sq's dataset sequence
3629 sq.setDatasetSequence(dsq);
3633 // TODO: refactor this as a merge dataset sequence function
3634 // now check that sq (the dataset sequence) sequence really is the union of
3635 // all references to it
3636 // boolean pre = sq.getStart() < dsq.getStart();
3637 // boolean post = sq.getEnd() > dsq.getEnd();
3641 StringBuffer sb = new StringBuffer();
3642 String newres = jalview.analysis.AlignSeq.extractGaps(
3643 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
3644 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
3645 && newres.length() > dsq.getLength())
3647 // Update with the longer sequence.
3651 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
3652 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
3653 * sb.append(newres.substring(newres.length() - sq.getEnd() -
3654 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
3656 dsq.setSequence(sb.toString());
3658 // TODO: merges will never happen if we 'know' we have the real dataset
3659 // sequence - this should be detected when id==dssid
3660 System.err.println("DEBUG Notice: Merged dataset sequence"); // ("
3661 // + (pre ? "prepended" : "") + " "
3662 // + (post ? "appended" : ""));
3667 java.util.Hashtable datasetIds = null;
3669 java.util.IdentityHashMap dataset2Ids = null;
3671 private Alignment getDatasetFor(String datasetId)
3673 if (datasetIds == null)
3675 datasetIds = new Hashtable();
3678 if (datasetIds.containsKey(datasetId))
3680 return (Alignment) datasetIds.get(datasetId);
3685 private void addDatasetRef(String datasetId, Alignment dataset)
3687 if (datasetIds == null)
3689 datasetIds = new Hashtable();
3691 datasetIds.put(datasetId, dataset);
3695 * make a new dataset ID for this jalview dataset alignment
3700 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
3702 if (dataset.getDataset() != null)
3704 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
3706 String datasetId = makeHashCode(dataset, null);
3707 if (datasetId == null)
3709 // make a new datasetId and record it
3710 if (dataset2Ids == null)
3712 dataset2Ids = new IdentityHashMap();
3716 datasetId = (String) dataset2Ids.get(dataset);
3718 if (datasetId == null)
3720 datasetId = "ds" + dataset2Ids.size() + 1;
3721 dataset2Ids.put(dataset, datasetId);
3727 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
3729 for (int d = 0; d < sequence.getDBRefCount(); d++)
3731 DBRef dr = sequence.getDBRef(d);
3732 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
3733 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
3734 .getVersion(), sequence.getDBRef(d).getAccessionId());
3735 if (dr.getMapping() != null)
3737 entry.setMap(addMapping(dr.getMapping()));
3739 datasetSequence.addDBRef(entry);
3743 private jalview.datamodel.Mapping addMapping(Mapping m)
3745 SequenceI dsto = null;
3746 // Mapping m = dr.getMapping();
3747 int fr[] = new int[m.getMapListFromCount() * 2];
3748 Enumeration f = m.enumerateMapListFrom();
3749 for (int _i = 0; f.hasMoreElements(); _i += 2)
3751 MapListFrom mf = (MapListFrom) f.nextElement();
3752 fr[_i] = mf.getStart();
3753 fr[_i + 1] = mf.getEnd();
3755 int fto[] = new int[m.getMapListToCount() * 2];
3756 f = m.enumerateMapListTo();
3757 for (int _i = 0; f.hasMoreElements(); _i += 2)
3759 MapListTo mf = (MapListTo) f.nextElement();
3760 fto[_i] = mf.getStart();
3761 fto[_i + 1] = mf.getEnd();
3763 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
3764 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
3765 if (m.getMappingChoice() != null)
3767 MappingChoice mc = m.getMappingChoice();
3768 if (mc.getDseqFor() != null)
3770 String dsfor = "" + mc.getDseqFor();
3771 if (seqRefIds.containsKey(dsfor))
3776 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
3780 frefedSequence.add(new Object[]
3787 * local sequence definition
3789 Sequence ms = mc.getSequence();
3790 jalview.datamodel.Sequence djs = null;
3791 String sqid = ms.getDsseqid();
3792 if (sqid != null && sqid.length() > 0)
3795 * recover dataset sequence
3797 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
3802 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
3803 sqid = ((Object) ms).toString(); // make up a new hascode for
3804 // undefined dataset sequence hash
3805 // (unlikely to happen)
3811 * make a new dataset sequence and add it to refIds hash
3813 djs = new jalview.datamodel.Sequence(ms.getName(),
3815 djs.setStart(jmap.getMap().getToLowest());
3816 djs.setEnd(jmap.getMap().getToHighest());
3817 djs.setVamsasId(uniqueSetSuffix + sqid);
3819 seqRefIds.put(sqid, djs);
3822 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
3831 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
3832 boolean keepSeqRefs)
3835 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
3841 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
3845 uniqueSetSuffix = "";
3846 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
3851 if (this.frefedSequence == null)
3853 frefedSequence = new Vector();
3856 viewportsAdded = new Hashtable();
3858 AlignFrame af = LoadFromObject(jm, null, false, null);
3859 af.alignPanels.clear();
3860 af.closeMenuItem_actionPerformed(true);
3863 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
3864 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
3865 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
3866 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
3867 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
3870 return af.alignPanel;
3874 * flag indicating if hashtables should be cleared on finalization TODO this
3875 * flag may not be necessary
3877 private final boolean _cleartables = true;
3879 private Hashtable jvids2vobj;
3884 * @see java.lang.Object#finalize()
3887 protected void finalize() throws Throwable
3889 // really make sure we have no buried refs left.
3894 this.seqRefIds = null;
3895 this.seqsToIds = null;
3899 private void warn(String msg)
3904 private void warn(String msg, Exception e)
3906 if (Cache.log != null)
3910 Cache.log.warn(msg, e);
3914 Cache.log.warn(msg);
3919 System.err.println("Warning: " + msg);
3922 e.printStackTrace();
3927 private void debug(String string)
3929 debug(string, null);
3932 private void debug(String msg, Exception e)
3934 if (Cache.log != null)
3938 Cache.log.debug(msg, e);
3942 Cache.log.debug(msg);
3947 System.err.println("Warning: " + msg);
3950 e.printStackTrace();
3956 * set the object to ID mapping tables used to write/recover objects and XML
3957 * ID strings for the jalview project. If external tables are provided then
3958 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
3959 * object goes out of scope. - also populates the datasetIds hashtable with
3960 * alignment objects containing dataset sequences
3963 * Map from ID strings to jalview datamodel
3965 * Map from jalview datamodel to ID strings
3969 public void setObjectMappingTables(Hashtable vobj2jv,
3970 IdentityHashMap jv2vobj)
3972 this.jv2vobj = jv2vobj;
3973 this.vobj2jv = vobj2jv;
3974 Iterator ds = jv2vobj.keySet().iterator();
3976 while (ds.hasNext())
3978 Object jvobj = ds.next();
3979 id = jv2vobj.get(jvobj).toString();
3980 if (jvobj instanceof jalview.datamodel.Alignment)
3982 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
3984 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
3987 else if (jvobj instanceof jalview.datamodel.Sequence)
3989 // register sequence object so the XML parser can recover it.
3990 if (seqRefIds == null)
3992 seqRefIds = new Hashtable();
3994 if (seqsToIds == null)
3996 seqsToIds = new IdentityHashMap();
3998 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
3999 seqsToIds.put(jvobj, id);
4001 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4003 if (annotationIds == null)
4005 annotationIds = new Hashtable();
4008 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4009 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4010 if (jvann.annotationId == null)
4012 jvann.annotationId = anid;
4014 if (!jvann.annotationId.equals(anid))
4016 // TODO verify that this is the correct behaviour
4017 this.warn("Overriding Annotation ID for " + anid
4018 + " from different id : " + jvann.annotationId);
4019 jvann.annotationId = anid;
4022 else if (jvobj instanceof String)
4024 if (jvids2vobj == null)
4026 jvids2vobj = new Hashtable();
4027 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4031 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4036 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4037 * objects created from the project archive. If string is null (default for
4038 * construction) then suffix will be set automatically.
4042 public void setUniqueSetSuffix(String string)
4044 uniqueSetSuffix = string;
4049 * uses skipList2 as the skipList for skipping views on sequence sets
4050 * associated with keys in the skipList
4054 public void setSkipList(Hashtable skipList2)
4056 skipList = skipList2;