2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8)
3 * Copyright (C) 2012 J Procter, AM Waterhouse, LM Lui, J Engelhardt, 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.Jws2Discoverer;
42 import jalview.ws.jws2.dm.AAConSettings;
43 import jalview.ws.jws2.jabaws2.Jws2Instance;
44 import jalview.ws.params.ArgumentI;
45 import jalview.ws.params.AutoCalcSetting;
46 import jalview.ws.params.WsParamSetI;
49 * Write out the current jalview desktop state as a Jalview XML stream.
51 * Note: the vamsas objects referred to here are primitive versions of the
52 * VAMSAS project schema elements - they are not the same and most likely never
56 * @version $Revision: 1.134 $
58 public class Jalview2XML
61 * create/return unique hash string for sq
64 * @return new or existing unique string for sq
66 String seqHash(SequenceI sq)
68 if (seqsToIds == null)
72 if (seqsToIds.containsKey(sq))
74 return (String) seqsToIds.get(sq);
78 // create sequential key
79 String key = "sq" + (seqsToIds.size() + 1);
80 key = makeHashCode(sq, key); // check we don't have an external reference
82 seqsToIds.put(sq, key);
91 if (seqRefIds != null)
95 if (seqsToIds != null)
105 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
106 // seqRefIds = new Hashtable();
107 // seqsToIds = new IdentityHashMap();
113 if (seqsToIds == null)
115 seqsToIds = new IdentityHashMap();
117 if (seqRefIds == null)
119 seqRefIds = new Hashtable();
124 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
125 * of sequence objects are created.
127 java.util.IdentityHashMap seqsToIds = null;
130 * jalview XML Sequence ID to jalview sequence object reference (both dataset
131 * and alignment sequences. Populated as XML reps of sequence objects are
134 java.util.Hashtable seqRefIds = null; // key->SequenceI resolution
136 Vector frefedSequence = null;
138 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
144 public Jalview2XML(boolean raiseGUI)
146 this.raiseGUI = raiseGUI;
149 public void resolveFrefedSequences()
151 if (frefedSequence.size() > 0)
153 int r = 0, rSize = frefedSequence.size();
156 Object[] ref = (Object[]) frefedSequence.elementAt(r);
159 String sref = (String) ref[0];
160 if (seqRefIds.containsKey(sref))
162 if (ref[1] instanceof jalview.datamodel.Mapping)
164 SequenceI seq = (SequenceI) seqRefIds.get(sref);
165 while (seq.getDatasetSequence() != null)
167 seq = seq.getDatasetSequence();
169 ((jalview.datamodel.Mapping) ref[1]).setTo(seq);
173 if (ref[1] instanceof jalview.datamodel.AlignedCodonFrame)
175 SequenceI seq = (SequenceI) seqRefIds.get(sref);
176 while (seq.getDatasetSequence() != null)
178 seq = seq.getDatasetSequence();
181 && ref[2] instanceof jalview.datamodel.Mapping)
183 jalview.datamodel.Mapping mp = (jalview.datamodel.Mapping) ref[2];
184 ((jalview.datamodel.AlignedCodonFrame) ref[1]).addMap(
185 seq, mp.getTo(), mp.getMap());
190 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for AlcodonFrames involving "
191 + ref[2].getClass() + " type objects.");
197 .println("IMPLEMENTATION ERROR: Unimplemented forward sequence references for "
198 + ref[1].getClass() + " type objects.");
201 frefedSequence.remove(r);
207 .println("IMPLEMENTATION WARNING: Unresolved forward reference for hash string "
209 + " with objecttype "
210 + ref[1].getClass());
217 frefedSequence.remove(r);
225 * This maintains a list of viewports, the key being the seqSetId. Important
226 * to set historyItem and redoList for multiple views
228 Hashtable viewportsAdded;
230 Hashtable annotationIds = new Hashtable();
232 String uniqueSetSuffix = "";
235 * List of pdbfiles added to Jar
237 Vector pdbfiles = null;
239 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
240 public void SaveState(File statefile)
244 FileOutputStream fos = new FileOutputStream(statefile);
245 JarOutputStream jout = new JarOutputStream(fos);
248 } catch (Exception e)
250 // TODO: inform user of the problem - they need to know if their data was
252 if (errorMessage == null)
254 errorMessage = "Couldn't write Jalview Archive to output file '"
255 + statefile + "' - See console error log for details";
259 errorMessage += "(output file was '" + statefile + "')";
267 * Writes a jalview project archive to the given Jar output stream.
271 public void SaveState(JarOutputStream jout)
273 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
283 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
284 // //////////////////////////////////////////////////
285 // NOTE ALSO new PrintWriter must be used for each new JarEntry
286 PrintWriter out = null;
288 Vector shortNames = new Vector();
291 for (int i = frames.length - 1; i > -1; i--)
293 if (frames[i] instanceof AlignFrame)
295 AlignFrame af = (AlignFrame) frames[i];
298 && skipList.containsKey(af.getViewport()
299 .getSequenceSetId()))
304 String shortName = af.getTitle();
306 if (shortName.indexOf(File.separatorChar) > -1)
308 shortName = shortName.substring(shortName
309 .lastIndexOf(File.separatorChar) + 1);
314 while (shortNames.contains(shortName))
316 if (shortName.endsWith("_" + (count - 1)))
318 shortName = shortName
319 .substring(0, shortName.lastIndexOf("_"));
322 shortName = shortName.concat("_" + count);
326 shortNames.addElement(shortName);
328 if (!shortName.endsWith(".xml"))
330 shortName = shortName + ".xml";
333 int ap, apSize = af.alignPanels.size();
334 for (ap = 0; ap < apSize; ap++)
336 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
338 String fileName = apSize == 1 ? shortName : ap + shortName;
339 if (!fileName.endsWith(".xml"))
341 fileName = fileName + ".xml";
344 SaveState(apanel, fileName, jout);
351 } catch (Exception foo)
356 } catch (Exception ex)
358 // TODO: inform user of the problem - they need to know if their data was
360 if (errorMessage == null)
362 errorMessage = "Couldn't write Jalview Archive - see error output for details";
364 ex.printStackTrace();
368 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
369 public boolean SaveAlignment(AlignFrame af, String jarFile,
374 int ap, apSize = af.alignPanels.size();
375 FileOutputStream fos = new FileOutputStream(jarFile);
376 JarOutputStream jout = new JarOutputStream(fos);
377 for (ap = 0; ap < apSize; ap++)
379 AlignmentPanel apanel = (AlignmentPanel) af.alignPanels
381 String jfileName = apSize == 1 ? fileName : fileName + ap;
382 if (!jfileName.endsWith(".xml"))
384 jfileName = jfileName + ".xml";
386 SaveState(apanel, jfileName, jout);
392 } catch (Exception foo)
398 } catch (Exception ex)
400 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
401 ex.printStackTrace();
407 * create a JalviewModel from an algnment view and marshall it to a
411 * panel to create jalview model for
413 * name of alignment panel written to output stream
419 public JalviewModel SaveState(AlignmentPanel ap, String fileName,
420 JarOutputStream jout)
423 Vector jmolViewIds = new Vector(); //
424 Vector userColours = new Vector();
426 AlignViewport av = ap.av;
428 JalviewModel object = new JalviewModel();
429 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
431 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
432 object.setVersion(jalview.bin.Cache.getDefault("VERSION","Development Build"));
434 jalview.datamodel.AlignmentI jal = av.getAlignment();
436 if (av.hasHiddenRows())
438 jal = jal.getHiddenSequences().getFullAlignment();
441 SequenceSet vamsasSet = new SequenceSet();
443 JalviewModelSequence jms = new JalviewModelSequence();
445 vamsasSet.setGapChar(jal.getGapCharacter() + "");
447 if (jal.getDataset() != null)
449 // dataset id is the dataset's hashcode
450 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
452 if (jal.getProperties() != null)
454 Enumeration en = jal.getProperties().keys();
455 while (en.hasMoreElements())
457 String key = en.nextElement().toString();
458 SequenceSetProperties ssp = new SequenceSetProperties();
460 ssp.setValue(jal.getProperties().get(key).toString());
461 vamsasSet.addSequenceSetProperties(ssp);
466 Set<String> calcIdSet = new HashSet<String>();
470 jalview.datamodel.SequenceI jds;
471 for (int i = 0; i < jal.getHeight(); i++)
473 jds = jal.getSequenceAt(i);
476 if (seqRefIds.get(id) != null)
478 // This happens for two reasons: 1. multiple views are being serialised.
479 // 2. the hashCode has collided with another sequence's code. This DOES
480 // HAPPEN! (PF00072.15.stk does this)
481 // JBPNote: Uncomment to debug writing out of files that do not read
482 // back in due to ArrayOutOfBoundExceptions.
483 // System.err.println("vamsasSeq backref: "+id+"");
484 // System.err.println(jds.getName()+"
485 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
486 // System.err.println("Hashcode: "+seqHash(jds));
487 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
488 // System.err.println(rsq.getName()+"
489 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
490 // System.err.println("Hashcode: "+seqHash(rsq));
494 vamsasSeq = createVamsasSequence(id, jds);
495 vamsasSet.addSequence(vamsasSeq);
496 seqRefIds.put(id, jds);
500 jseq.setStart(jds.getStart());
501 jseq.setEnd(jds.getEnd());
502 jseq.setColour(av.getSequenceColour(jds).getRGB());
504 jseq.setId(id); // jseq id should be a string not a number
506 if (av.hasHiddenRows())
508 jseq.setHidden(av.getAlignment().getHiddenSequences().isHidden(jds));
510 if (av.isHiddenRepSequence(jal.getSequenceAt(i)))
512 jalview.datamodel.SequenceI[] reps = av.getRepresentedSequences(
513 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()
874 || aa[i] == av.getAlignmentConservationAnnotation()
875 || aa[i] == av.getAlignmentConsensusAnnotation()
876 || aa[i].autoCalculated)
878 // new way of indicating autocalculated annotation -
879 an.setAutoCalculated(aa[i].autoCalculated);
881 if (aa[i].hasScore())
883 an.setScore(aa[i].getScore());
886 if (aa[i].getCalcId() != null)
888 calcIdSet.add(aa[i].getCalcId());
889 an.setCalcId(aa[i].getCalcId());
892 AnnotationElement ae;
893 if (aa[i].annotations != null)
895 an.setScoreOnly(false);
896 for (int a = 0; a < aa[i].annotations.length; a++)
898 if ((aa[i] == null) || (aa[i].annotations[a] == null))
903 ae = new AnnotationElement();
904 if (aa[i].annotations[a].description != null)
905 ae.setDescription(aa[i].annotations[a].description);
906 if (aa[i].annotations[a].displayCharacter != null)
907 ae.setDisplayCharacter(aa[i].annotations[a].displayCharacter);
909 if (!Float.isNaN(aa[i].annotations[a].value))
910 ae.setValue(aa[i].annotations[a].value);
913 if (aa[i].annotations[a].secondaryStructure != ' '
914 && aa[i].annotations[a].secondaryStructure != '\0')
915 ae.setSecondaryStructure(aa[i].annotations[a].secondaryStructure
918 if (aa[i].annotations[a].colour != null
919 && aa[i].annotations[a].colour != java.awt.Color.black)
921 ae.setColour(aa[i].annotations[a].colour.getRGB());
924 an.addAnnotationElement(ae);
925 if (aa[i].autoCalculated)
927 // only write one non-null entry into the annotation row -
928 // sufficient to get the visualization attributes necessary to
936 an.setScoreOnly(true);
938 vamsasSet.addAnnotation(an);
942 if (jal.getGroups() != null)
944 JGroup[] groups = new JGroup[jal.getGroups().size()];
946 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
948 groups[++i] = new JGroup();
950 groups[i].setStart(sg.getStartRes());
951 groups[i].setEnd(sg.getEndRes());
952 groups[i].setName(sg.getName());
953 if (groupRefs.containsKey(sg))
955 // group has references so set it's ID field
956 groups[i].setId(groupRefs.get(sg).toString());
960 if (sg.cs.conservationApplied())
962 groups[i].setConsThreshold(sg.cs.getConservationInc());
964 if (sg.cs instanceof jalview.schemes.UserColourScheme)
966 groups[i].setColour(SetUserColourScheme(sg.cs, userColours,
972 .setColour(ColourSchemeProperty.getColourName(sg.cs));
975 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
978 .setColour(ColourSchemeProperty
979 .getColourName(((jalview.schemes.AnnotationColourGradient) sg.cs)
982 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
985 .setColour(SetUserColourScheme(sg.cs, userColours, jms));
989 groups[i].setColour(ColourSchemeProperty.getColourName(sg.cs));
992 groups[i].setPidThreshold(sg.cs.getThreshold());
995 groups[i].setOutlineColour(sg.getOutlineColour().getRGB());
996 groups[i].setDisplayBoxes(sg.getDisplayBoxes());
997 groups[i].setDisplayText(sg.getDisplayText());
998 groups[i].setColourText(sg.getColourText());
999 groups[i].setTextCol1(sg.textColour.getRGB());
1000 groups[i].setTextCol2(sg.textColour2.getRGB());
1001 groups[i].setTextColThreshold(sg.thresholdTextColour);
1002 groups[i].setShowUnconserved(sg.getShowNonconserved());
1003 groups[i].setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1004 groups[i].setShowConsensusHistogram(sg.isShowConsensusHistogram());
1005 groups[i].setShowSequenceLogo(sg.isShowSequenceLogo());
1006 groups[i].setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1007 for (int s = 0; s < sg.getSize(); s++)
1009 jalview.datamodel.Sequence seq = (jalview.datamodel.Sequence) sg
1011 groups[i].addSeq(seqHash(seq));
1015 jms.setJGroup(groups);
1018 // /////////SAVE VIEWPORT
1019 Viewport view = new Viewport();
1020 view.setTitle(ap.alignFrame.getTitle());
1021 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1022 av.getSequenceSetId()));
1023 view.setId(av.getViewId());
1024 view.setViewName(av.viewName);
1025 view.setGatheredViews(av.gatherViewsHere);
1027 if (ap.av.explodedPosition != null)
1029 view.setXpos(av.explodedPosition.x);
1030 view.setYpos(av.explodedPosition.y);
1031 view.setWidth(av.explodedPosition.width);
1032 view.setHeight(av.explodedPosition.height);
1036 view.setXpos(ap.alignFrame.getBounds().x);
1037 view.setYpos(ap.alignFrame.getBounds().y);
1038 view.setWidth(ap.alignFrame.getBounds().width);
1039 view.setHeight(ap.alignFrame.getBounds().height);
1042 view.setStartRes(av.startRes);
1043 view.setStartSeq(av.startSeq);
1045 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1047 view.setBgColour(SetUserColourScheme(av.getGlobalColourScheme(),
1050 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1052 jalview.schemes.AnnotationColourGradient acg = (jalview.schemes.AnnotationColourGradient) av
1053 .getGlobalColourScheme();
1055 AnnotationColours ac = new AnnotationColours();
1056 ac.setAboveThreshold(acg.getAboveThreshold());
1057 ac.setThreshold(acg.getAnnotationThreshold());
1058 ac.setAnnotation(acg.getAnnotation());
1059 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1061 ac.setColourScheme(SetUserColourScheme(acg.getBaseColour(),
1066 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1070 ac.setMaxColour(acg.getMaxColour().getRGB());
1071 ac.setMinColour(acg.getMinColour().getRGB());
1072 ac.setPerSequence(acg.isSeqAssociated());
1073 ac.setPredefinedColours(acg.isPredefinedColours());
1074 view.setAnnotationColours(ac);
1075 view.setBgColour("AnnotationColourGradient");
1079 view.setBgColour(ColourSchemeProperty.getColourName(av
1080 .getGlobalColourScheme()));
1083 ColourSchemeI cs = av.getGlobalColourScheme();
1087 if (cs.conservationApplied())
1089 view.setConsThreshold(cs.getConservationInc());
1090 if (cs instanceof jalview.schemes.UserColourScheme)
1092 view.setBgColour(SetUserColourScheme(cs, userColours, jms));
1096 if (cs instanceof ResidueColourScheme)
1098 view.setPidThreshold(cs.getThreshold());
1102 view.setConservationSelected(av.getConservationSelected());
1103 view.setPidSelected(av.getAbovePIDThreshold());
1104 view.setFontName(av.font.getName());
1105 view.setFontSize(av.font.getSize());
1106 view.setFontStyle(av.font.getStyle());
1107 view.setRenderGaps(av.renderGaps);
1108 view.setShowAnnotation(av.getShowAnnotation());
1109 view.setShowBoxes(av.getShowBoxes());
1110 view.setShowColourText(av.getColourText());
1111 view.setShowFullId(av.getShowJVSuffix());
1112 view.setRightAlignIds(av.rightAlignIds);
1113 view.setShowSequenceFeatures(av.showSequenceFeatures);
1114 view.setShowText(av.getShowText());
1115 view.setShowUnconserved(av.getShowUnconserved());
1116 view.setWrapAlignment(av.getWrapAlignment());
1117 view.setTextCol1(av.textColour.getRGB());
1118 view.setTextCol2(av.textColour2.getRGB());
1119 view.setTextColThreshold(av.thresholdTextColour);
1120 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1121 view.setShowSequenceLogo(av.isShowSequenceLogo());
1122 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1123 view.setShowGroupConsensus(av.isShowGroupConsensus());
1124 view.setShowGroupConservation(av.isShowGroupConservation());
1125 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1126 view.setShowDbRefTooltip(av.isShowDbRefs());
1127 view.setFollowHighlight(av.followHighlight);
1128 view.setFollowSelection(av.followSelection);
1129 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1130 if (av.featuresDisplayed != null)
1132 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1134 String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;
1136 Vector settingsAdded = new Vector();
1137 Object gstyle = null;
1138 GraduatedColor gcol = null;
1139 if (renderOrder != null)
1141 for (int ro = 0; ro < renderOrder.length; ro++)
1143 gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer()
1144 .getFeatureStyle(renderOrder[ro]);
1145 Setting setting = new Setting();
1146 setting.setType(renderOrder[ro]);
1147 if (gstyle instanceof GraduatedColor)
1149 gcol = (GraduatedColor) gstyle;
1150 setting.setColour(gcol.getMaxColor().getRGB());
1151 setting.setMincolour(gcol.getMinColor().getRGB());
1152 setting.setMin(gcol.getMin());
1153 setting.setMax(gcol.getMax());
1154 setting.setColourByLabel(gcol.isColourByLabel());
1155 setting.setAutoScale(gcol.isAutoScale());
1156 setting.setThreshold(gcol.getThresh());
1157 setting.setThreshstate(gcol.getThreshType());
1161 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1162 .getColour(renderOrder[ro]).getRGB());
1165 setting.setDisplay(av.featuresDisplayed
1166 .containsKey(renderOrder[ro]));
1167 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1168 .getOrder(renderOrder[ro]);
1171 setting.setOrder(rorder);
1173 fs.addSetting(setting);
1174 settingsAdded.addElement(renderOrder[ro]);
1178 // Make sure we save none displayed feature settings
1179 Iterator en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours
1180 .keySet().iterator();
1181 while (en.hasNext())
1183 String key = en.next().toString();
1184 if (settingsAdded.contains(key))
1189 Setting setting = new Setting();
1190 setting.setType(key);
1191 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1192 .getColour(key).getRGB());
1194 setting.setDisplay(false);
1195 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer().getOrder(
1199 setting.setOrder(rorder);
1201 fs.addSetting(setting);
1202 settingsAdded.addElement(key);
1204 en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1205 .keySet().iterator();
1206 Vector groupsAdded = new Vector();
1207 while (en.hasNext())
1209 String grp = en.next().toString();
1210 if (groupsAdded.contains(grp))
1214 Group g = new Group();
1216 g.setDisplay(((Boolean) ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1217 .get(grp)).booleanValue());
1219 groupsAdded.addElement(grp);
1221 jms.setFeatureSettings(fs);
1225 if (av.hasHiddenColumns())
1227 if (av.getColumnSelection() == null
1228 || av.getColumnSelection().getHiddenColumns() == null)
1230 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1234 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1237 int[] region = (int[]) av.getColumnSelection().getHiddenColumns()
1239 HiddenColumns hc = new HiddenColumns();
1240 hc.setStart(region[0]);
1241 hc.setEnd(region[1]);
1242 view.addHiddenColumns(hc);
1246 if (calcIdSet.size() > 0)
1248 for (String calcId : calcIdSet)
1250 if (calcId.trim().length() > 0)
1252 CalcIdParam cidp = createCalcIdParam(calcId, av);
1253 // Some calcIds have no parameters.
1256 view.addCalcIdParam(cidp);
1262 jms.addViewport(view);
1264 object.setJalviewModelSequence(jms);
1265 object.getVamsasModel().addSequenceSet(vamsasSet);
1267 if (jout != null && fileName != null)
1269 // We may not want to write the object to disk,
1270 // eg we can copy the alignViewport to a new view object
1271 // using save and then load
1274 JarEntry entry = new JarEntry(fileName);
1275 jout.putNextEntry(entry);
1276 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1278 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1280 marshaller.marshal(object);
1283 } catch (Exception ex)
1285 // TODO: raise error in GUI if marshalling failed.
1286 ex.printStackTrace();
1292 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1294 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1295 if (settings != null)
1297 CalcIdParam vCalcIdParam = new CalcIdParam();
1298 vCalcIdParam.setCalcId(calcId);
1299 vCalcIdParam.addServiceURL(settings.getServiceURI());
1300 // generic URI allowing a third party to resolve another instance of the
1301 // service used for this calculation
1302 for (String urls : settings.getServiceURLs())
1304 vCalcIdParam.addServiceURL(urls);
1306 vCalcIdParam.setVersion("1.0");
1307 if (settings.getPreset() != null)
1309 WsParamSetI setting = settings.getPreset();
1310 vCalcIdParam.setName(setting.getName());
1311 vCalcIdParam.setDescription(setting.getDescription());
1315 vCalcIdParam.setName("");
1316 vCalcIdParam.setDescription("Last used parameters");
1318 // need to be able to recover 1) settings 2) user-defined presets or
1319 // recreate settings from preset 3) predefined settings provided by
1320 // service - or settings that can be transferred (or discarded)
1321 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1323 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1324 // todo - decide if updateImmediately is needed for any projects.
1326 return vCalcIdParam;
1331 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1334 if (calcIdParam.getVersion().equals("1.0"))
1336 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1337 .getPreferredServiceFor(calcIdParam.getServiceURL());
1338 if (service != null)
1340 WsParamSetI parmSet = null;
1343 parmSet = service.getParamStore().parseServiceParameterFile(
1344 calcIdParam.getName(), calcIdParam.getDescription(),
1345 calcIdParam.getServiceURL(),
1346 calcIdParam.getParameters().replace("|\\n|", "\n"));
1347 } catch (IOException x)
1349 warn("Couldn't parse parameter data for "
1350 + calcIdParam.getCalcId(), x);
1353 List<ArgumentI> argList = null;
1354 if (calcIdParam.getName().length() > 0)
1356 parmSet = service.getParamStore()
1357 .getPreset(calcIdParam.getName());
1358 if (parmSet != null)
1360 // TODO : check we have a good match with settings in AACon -
1361 // otherwise we'll need to create a new preset
1366 argList = parmSet.getArguments();
1369 AAConSettings settings = new AAConSettings(
1370 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1371 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1372 calcIdParam.isNeedsUpdate());
1377 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1381 throw new Error("Unsupported Version for calcIdparam "
1382 + calcIdParam.toString());
1386 * External mapping between jalview objects and objects yielding a valid and
1387 * unique object ID string. This is null for normal Jalview project IO, but
1388 * non-null when a jalview project is being read or written as part of a
1391 IdentityHashMap jv2vobj = null;
1394 * Construct a unique ID for jvobj using either existing bindings or if none
1395 * exist, the result of the hashcode call for the object.
1398 * jalview data object
1399 * @return unique ID for referring to jvobj
1401 private String makeHashCode(Object jvobj, String altCode)
1403 if (jv2vobj != null)
1405 Object id = jv2vobj.get(jvobj);
1408 return id.toString();
1410 // check string ID mappings
1411 if (jvids2vobj != null && jvobj instanceof String)
1413 id = jvids2vobj.get(jvobj);
1417 return id.toString();
1419 // give up and warn that something has gone wrong
1420 warn("Cannot find ID for object in external mapping : " + jvobj);
1426 * return local jalview object mapped to ID, if it exists
1430 * @return null or object bound to idcode
1432 private Object retrieveExistingObj(String idcode)
1434 if (idcode != null && vobj2jv != null)
1436 return vobj2jv.get(idcode);
1442 * binding from ID strings from external mapping table to jalview data model
1445 private Hashtable vobj2jv;
1447 private Sequence createVamsasSequence(String id, SequenceI jds)
1449 return createVamsasSequence(true, id, jds, null);
1452 private Sequence createVamsasSequence(boolean recurse, String id,
1453 SequenceI jds, SequenceI parentseq)
1455 Sequence vamsasSeq = new Sequence();
1456 vamsasSeq.setId(id);
1457 vamsasSeq.setName(jds.getName());
1458 vamsasSeq.setSequence(jds.getSequenceAsString());
1459 vamsasSeq.setDescription(jds.getDescription());
1460 jalview.datamodel.DBRefEntry[] dbrefs = null;
1461 if (jds.getDatasetSequence() != null)
1463 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1464 if (jds.getDatasetSequence().getDBRef() != null)
1466 dbrefs = jds.getDatasetSequence().getDBRef();
1471 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1472 // dataset sequences only
1473 dbrefs = jds.getDBRef();
1477 for (int d = 0; d < dbrefs.length; d++)
1479 DBRef dbref = new DBRef();
1480 dbref.setSource(dbrefs[d].getSource());
1481 dbref.setVersion(dbrefs[d].getVersion());
1482 dbref.setAccessionId(dbrefs[d].getAccessionId());
1483 if (dbrefs[d].hasMap())
1485 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1487 dbref.setMapping(mp);
1489 vamsasSeq.addDBRef(dbref);
1495 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1496 SequenceI parentseq, SequenceI jds, boolean recurse)
1499 if (jmp.getMap() != null)
1503 jalview.util.MapList mlst = jmp.getMap();
1504 int r[] = mlst.getFromRanges();
1505 for (int s = 0; s < r.length; s += 2)
1507 MapListFrom mfrom = new MapListFrom();
1508 mfrom.setStart(r[s]);
1509 mfrom.setEnd(r[s + 1]);
1510 mp.addMapListFrom(mfrom);
1512 r = mlst.getToRanges();
1513 for (int s = 0; s < r.length; s += 2)
1515 MapListTo mto = new MapListTo();
1517 mto.setEnd(r[s + 1]);
1518 mp.addMapListTo(mto);
1520 mp.setMapFromUnit(mlst.getFromRatio());
1521 mp.setMapToUnit(mlst.getToRatio());
1522 if (jmp.getTo() != null)
1524 MappingChoice mpc = new MappingChoice();
1526 && (parentseq != jmp.getTo() || parentseq
1527 .getDatasetSequence() != jmp.getTo()))
1529 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1535 SequenceI ps = null;
1536 if (parentseq != jmp.getTo()
1537 && parentseq.getDatasetSequence() != jmp.getTo())
1539 // chaining dbref rather than a handshaking one
1540 jmpid = seqHash(ps = jmp.getTo());
1544 jmpid = seqHash(ps = parentseq);
1546 mpc.setDseqFor(jmpid);
1547 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1549 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1550 seqRefIds.put(mpc.getDseqFor(), ps);
1554 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1557 mp.setMappingChoice(mpc);
1563 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1564 Vector userColours, JalviewModelSequence jms)
1567 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1568 boolean newucs = false;
1569 if (!userColours.contains(ucs))
1571 userColours.add(ucs);
1574 id = "ucs" + userColours.indexOf(ucs);
1577 // actually create the scheme's entry in the XML model
1578 java.awt.Color[] colours = ucs.getColours();
1579 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1580 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1582 for (int i = 0; i < colours.length; i++)
1584 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1585 col.setName(ResidueProperties.aa[i]);
1586 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1587 jbucs.addColour(col);
1589 if (ucs.getLowerCaseColours() != null)
1591 colours = ucs.getLowerCaseColours();
1592 for (int i = 0; i < colours.length; i++)
1594 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1595 col.setName(ResidueProperties.aa[i].toLowerCase());
1596 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1597 jbucs.addColour(col);
1602 uc.setUserColourScheme(jbucs);
1603 jms.addUserColours(uc);
1609 jalview.schemes.UserColourScheme GetUserColourScheme(
1610 JalviewModelSequence jms, String id)
1612 UserColours[] uc = jms.getUserColours();
1613 UserColours colours = null;
1615 for (int i = 0; i < uc.length; i++)
1617 if (uc[i].getId().equals(id))
1625 java.awt.Color[] newColours = new java.awt.Color[24];
1627 for (int i = 0; i < 24; i++)
1629 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1630 .getUserColourScheme().getColour(i).getRGB(), 16));
1633 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1636 if (colours.getUserColourScheme().getColourCount() > 24)
1638 newColours = new java.awt.Color[23];
1639 for (int i = 0; i < 23; i++)
1641 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1642 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1644 ucs.setLowerCaseColours(newColours);
1651 * contains last error message (if any) encountered by XML loader.
1653 String errorMessage = null;
1656 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1657 * exceptions are raised during project XML parsing
1659 public boolean attemptversion1parse = true;
1662 * Load a jalview project archive from a jar file
1665 * - HTTP URL or filename
1667 public AlignFrame LoadJalviewAlign(final String file)
1670 jalview.gui.AlignFrame af = null;
1674 // create list to store references for any new Jmol viewers created
1675 newStructureViewers=new Vector<AppJmol>();
1676 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1677 // Workaround is to make sure caller implements the JarInputStreamProvider
1679 // so we can re-open the jar input stream for each entry.
1681 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1682 af = LoadJalviewAlign(jprovider);
1684 } catch (MalformedURLException e)
1686 errorMessage = "Invalid URL format for '" + file + "'";
1692 SwingUtilities.invokeAndWait(new Runnable()
1696 setLoadingFinishedForNewStructureViewers();
1699 } catch (Exception x)
1707 private jarInputStreamProvider createjarInputStreamProvider(
1708 final String file) throws MalformedURLException
1711 errorMessage = null;
1712 uniqueSetSuffix = null;
1714 viewportsAdded = null;
1715 frefedSequence = null;
1717 if (file.startsWith("http://"))
1719 url = new URL(file);
1721 final URL _url = url;
1722 return new jarInputStreamProvider()
1726 public JarInputStream getJarInputStream() throws IOException
1730 return new JarInputStream(_url.openStream());
1734 return new JarInputStream(new FileInputStream(file));
1739 public String getFilename()
1747 * Recover jalview session from a jalview project archive. Caller may
1748 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1749 * themselves. Any null fields will be initialised with default values,
1750 * non-null fields are left alone.
1755 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1757 errorMessage = null;
1758 if (uniqueSetSuffix == null)
1760 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1762 if (seqRefIds == null)
1764 seqRefIds = new Hashtable();
1766 if (viewportsAdded == null)
1768 viewportsAdded = new Hashtable();
1770 if (frefedSequence == null)
1772 frefedSequence = new Vector();
1775 jalview.gui.AlignFrame af = null;
1776 Hashtable gatherToThisFrame = new Hashtable();
1777 final String file = jprovider.getFilename();
1780 JarInputStream jin = null;
1781 JarEntry jarentry = null;
1786 jin = jprovider.getJarInputStream();
1787 for (int i = 0; i < entryCount; i++)
1789 jarentry = jin.getNextJarEntry();
1792 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1794 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1795 JalviewModel object = new JalviewModel();
1797 Unmarshaller unmar = new Unmarshaller(object);
1798 unmar.setValidation(false);
1799 object = (JalviewModel) unmar.unmarshal(in);
1800 if (true) // !skipViewport(object))
1802 af = LoadFromObject(object, file, true, jprovider);
1803 if (af.viewport.gatherViewsHere)
1805 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
1810 else if (jarentry != null)
1812 // Some other file here.
1815 } while (jarentry != null);
1816 resolveFrefedSequences();
1817 } catch (java.io.FileNotFoundException ex)
1819 ex.printStackTrace();
1820 errorMessage = "Couldn't locate Jalview XML file : " + file;
1821 System.err.println("Exception whilst loading jalview XML file : "
1823 } catch (java.net.UnknownHostException ex)
1825 ex.printStackTrace();
1826 errorMessage = "Couldn't locate Jalview XML file : " + file;
1827 System.err.println("Exception whilst loading jalview XML file : "
1829 } catch (Exception ex)
1831 System.err.println("Parsing as Jalview Version 2 file failed.");
1832 ex.printStackTrace(System.err);
1833 if (attemptversion1parse)
1835 // Is Version 1 Jar file?
1838 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
1839 } catch (Exception ex2)
1841 System.err.println("Exception whilst loading as jalviewXMLV1:");
1842 ex2.printStackTrace();
1846 if (Desktop.instance != null)
1848 Desktop.instance.stopLoading();
1852 System.out.println("Successfully loaded archive file");
1855 ex.printStackTrace();
1857 System.err.println("Exception whilst loading jalview XML file : "
1859 } catch (OutOfMemoryError e)
1861 // Don't use the OOM Window here
1862 errorMessage = "Out of memory loading jalview XML file";
1863 System.err.println("Out of memory whilst loading jalview XML file");
1864 e.printStackTrace();
1867 if (Desktop.instance != null)
1869 Desktop.instance.stopLoading();
1872 Enumeration en = gatherToThisFrame.elements();
1873 while (en.hasMoreElements())
1875 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
1877 if (errorMessage != null)
1885 * check errorMessage for a valid error message and raise an error box in the
1886 * GUI or write the current errorMessage to stderr and then clear the error
1889 protected void reportErrors()
1891 reportErrors(false);
1894 protected void reportErrors(final boolean saving)
1896 if (errorMessage != null)
1898 final String finalErrorMessage = errorMessage;
1901 javax.swing.SwingUtilities.invokeLater(new Runnable()
1906 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1907 finalErrorMessage, "Error "
1908 + (saving ? "saving" : "loading")
1909 + " Jalview file", JOptionPane.WARNING_MESSAGE);
1915 System.err.println("Problem loading Jalview file: " + errorMessage);
1918 errorMessage = null;
1921 Hashtable alreadyLoadedPDB;
1924 * when set, local views will be updated from view stored in JalviewXML
1925 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
1926 * sync if this is set to true.
1928 private final boolean updateLocalViews = false;
1930 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
1932 if (alreadyLoadedPDB == null)
1933 alreadyLoadedPDB = new Hashtable();
1935 if (alreadyLoadedPDB.containsKey(pdbId))
1936 return alreadyLoadedPDB.get(pdbId).toString();
1940 JarInputStream jin = jprovider.getJarInputStream();
1942 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
1943 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
1944 * FileInputStream(jprovider)); }
1947 JarEntry entry = null;
1950 entry = jin.getNextJarEntry();
1951 } while (entry != null && !entry.getName().equals(pdbId));
1954 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
1955 File outFile = File.createTempFile("jalview_pdb", ".txt");
1956 outFile.deleteOnExit();
1957 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
1960 while ((data = in.readLine()) != null)
1967 } catch (Exception foo)
1972 String t = outFile.getAbsolutePath();
1973 alreadyLoadedPDB.put(pdbId, t);
1978 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
1980 } catch (Exception ex)
1982 ex.printStackTrace();
1988 private class JvAnnotRow
1990 public JvAnnotRow(int i, AlignmentAnnotation jaa)
1997 * persisted version of annotation row from which to take vis properties
1999 public jalview.datamodel.AlignmentAnnotation template;
2002 * original position of the annotation row in the alignment
2008 * Load alignment frame from jalview XML DOM object
2013 * filename source string
2014 * @param loadTreesAndStructures
2015 * when false only create Viewport
2017 * data source provider
2018 * @return alignment frame created from view stored in DOM
2020 AlignFrame LoadFromObject(JalviewModel object, String file,
2021 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2023 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2024 Sequence[] vamsasSeq = vamsasSet.getSequence();
2026 JalviewModelSequence jms = object.getJalviewModelSequence();
2028 Viewport view = jms.getViewport(0);
2029 // ////////////////////////////////
2032 Vector hiddenSeqs = null;
2033 jalview.datamodel.Sequence jseq;
2035 ArrayList tmpseqs = new ArrayList();
2037 boolean multipleView = false;
2039 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
2040 int vi = 0; // counter in vamsasSeq array
2041 for (int i = 0; i < JSEQ.length; i++)
2043 String seqId = JSEQ[i].getId();
2045 if (seqRefIds.get(seqId) != null)
2047 tmpseqs.add(seqRefIds.get(seqId));
2048 multipleView = true;
2052 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2053 vamsasSeq[vi].getSequence());
2054 jseq.setDescription(vamsasSeq[vi].getDescription());
2055 jseq.setStart(JSEQ[i].getStart());
2056 jseq.setEnd(JSEQ[i].getEnd());
2057 jseq.setVamsasId(uniqueSetSuffix + seqId);
2058 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2063 if (JSEQ[i].getHidden())
2065 if (hiddenSeqs == null)
2067 hiddenSeqs = new Vector();
2070 hiddenSeqs.addElement(seqRefIds.get(seqId));
2076 // Create the alignment object from the sequence set
2077 // ///////////////////////////////
2078 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2081 tmpseqs.toArray(orderedSeqs);
2083 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2086 // / Add the alignment properties
2087 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2089 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2090 al.setProperty(ssp.getKey(), ssp.getValue());
2094 // SequenceFeatures are added to the DatasetSequence,
2095 // so we must create or recover the dataset before loading features
2096 // ///////////////////////////////
2097 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2099 // older jalview projects do not have a dataset id.
2100 al.setDataset(null);
2104 recoverDatasetFor(vamsasSet, al);
2106 // ///////////////////////////////
2108 Hashtable pdbloaded = new Hashtable();
2111 // load sequence features, database references and any associated PDB
2112 // structures for the alignment
2113 for (int i = 0; i < vamsasSeq.length; i++)
2115 if (JSEQ[i].getFeaturesCount() > 0)
2117 Features[] features = JSEQ[i].getFeatures();
2118 for (int f = 0; f < features.length; f++)
2120 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2121 features[f].getType(), features[f].getDescription(),
2122 features[f].getStatus(), features[f].getBegin(),
2123 features[f].getEnd(), features[f].getFeatureGroup());
2125 sf.setScore(features[f].getScore());
2126 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2128 OtherData keyValue = features[f].getOtherData(od);
2129 if (keyValue.getKey().startsWith("LINK"))
2131 sf.addLink(keyValue.getValue());
2135 sf.setValue(keyValue.getKey(), keyValue.getValue());
2140 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2143 if (vamsasSeq[i].getDBRefCount() > 0)
2145 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2147 if (JSEQ[i].getPdbidsCount() > 0)
2149 Pdbids[] ids = JSEQ[i].getPdbids();
2150 for (int p = 0; p < ids.length; p++)
2152 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2153 entry.setId(ids[p].getId());
2154 entry.setType(ids[p].getType());
2155 if (ids[p].getFile() != null)
2157 if (!pdbloaded.containsKey(ids[p].getFile()))
2159 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2163 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2167 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2171 } // end !multipleview
2173 // ///////////////////////////////
2174 // LOAD SEQUENCE MAPPINGS
2176 if (vamsasSet.getAlcodonFrameCount() > 0)
2178 // TODO Potentially this should only be done once for all views of an
2180 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2181 for (int i = 0; i < alc.length; i++)
2183 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2184 alc[i].getAlcodonCount());
2185 if (alc[i].getAlcodonCount() > 0)
2187 Alcodon[] alcods = alc[i].getAlcodon();
2188 for (int p = 0; p < cf.codons.length; p++)
2190 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2191 && alcods[p].hasPos3())
2193 // translated codons require three valid positions
2194 cf.codons[p] = new int[3];
2195 cf.codons[p][0] = (int) alcods[p].getPos1();
2196 cf.codons[p][1] = (int) alcods[p].getPos2();
2197 cf.codons[p][2] = (int) alcods[p].getPos3();
2201 cf.codons[p] = null;
2205 if (alc[i].getAlcodMapCount() > 0)
2207 AlcodMap[] maps = alc[i].getAlcodMap();
2208 for (int m = 0; m < maps.length; m++)
2210 SequenceI dnaseq = (SequenceI) seqRefIds
2211 .get(maps[m].getDnasq());
2213 jalview.datamodel.Mapping mapping = null;
2214 // attach to dna sequence reference.
2215 if (maps[m].getMapping() != null)
2217 mapping = addMapping(maps[m].getMapping());
2221 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2226 frefedSequence.add(new Object[]
2227 { maps[m].getDnasq(), cf, mapping });
2231 al.addCodonFrame(cf);
2236 // ////////////////////////////////
2238 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2240 * store any annotations which forward reference a group's ID
2242 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2244 if (vamsasSet.getAnnotationCount() > 0)
2246 Annotation[] an = vamsasSet.getAnnotation();
2248 for (int i = 0; i < an.length; i++)
2251 * test if annotation is automatically calculated for this view only
2253 boolean autoForView = false;
2254 if (an[i].getLabel().equals("Quality")
2255 || an[i].getLabel().equals("Conservation")
2256 || an[i].getLabel().equals("Consensus"))
2258 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2260 if (!an[i].hasAutoCalculated())
2262 an[i].setAutoCalculated(true);
2266 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2268 // remove ID - we don't recover annotation from other views for
2269 // view-specific annotation
2273 // set visiblity for other annotation in this view
2274 if (an[i].getId() != null
2275 && annotationIds.containsKey(an[i].getId()))
2277 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2278 .get(an[i].getId());
2279 // in principle Visible should always be true for annotation displayed
2280 // in multiple views
2281 if (an[i].hasVisible())
2282 jda.visible = an[i].getVisible();
2284 al.addAnnotation(jda);
2288 // Construct new annotation from model.
2289 AnnotationElement[] ae = an[i].getAnnotationElement();
2290 jalview.datamodel.Annotation[] anot = null;
2291 java.awt.Color firstColour = null;
2293 if (!an[i].getScoreOnly())
2295 anot = new jalview.datamodel.Annotation[al.getWidth()];
2296 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2298 anpos = ae[aa].getPosition();
2300 if (anpos >= anot.length)
2303 anot[anpos] = new jalview.datamodel.Annotation(
2305 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2306 (ae[aa].getSecondaryStructure() == null || ae[aa]
2307 .getSecondaryStructure().length() == 0) ? ' '
2308 : ae[aa].getSecondaryStructure().charAt(0),
2312 // JBPNote: Consider verifying dataflow for IO of secondary
2313 // structure annotation read from Stockholm files
2314 // this was added to try to ensure that
2315 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2317 // anot[ae[aa].getPosition()].displayCharacter = "";
2319 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2320 if (firstColour == null)
2322 firstColour = anot[anpos].colour;
2326 jalview.datamodel.AlignmentAnnotation jaa = null;
2328 if (an[i].getGraph())
2330 float llim = 0, hlim = 0;
2331 // if (autoForView || an[i].isAutoCalculated()) {
2334 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2335 an[i].getDescription(), anot, llim, hlim,
2336 an[i].getGraphType());
2338 jaa.graphGroup = an[i].getGraphGroup();
2339 jaa._linecolour = firstColour;
2340 if (an[i].getThresholdLine() != null)
2342 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2343 .getThresholdLine().getValue(), an[i]
2344 .getThresholdLine().getLabel(), new java.awt.Color(
2345 an[i].getThresholdLine().getColour())));
2348 if (autoForView || an[i].isAutoCalculated())
2350 // Hardwire the symbol display line to ensure that labels for
2351 // histograms are displayed
2357 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2358 an[i].getDescription(), anot);
2359 jaa._linecolour = firstColour;
2361 // register new annotation
2362 if (an[i].getId() != null)
2364 annotationIds.put(an[i].getId(), jaa);
2365 jaa.annotationId = an[i].getId();
2367 // recover sequence association
2368 if (an[i].getSequenceRef() != null)
2370 if (al.findName(an[i].getSequenceRef()) != null)
2372 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2374 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2377 // and make a note of any group association
2378 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2380 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2381 .get(an[i].getGroupRef());
2384 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2385 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2390 if (an[i].hasScore())
2392 jaa.setScore(an[i].getScore());
2394 if (an[i].hasVisible())
2395 jaa.visible = an[i].getVisible();
2397 if (an[i].hasCentreColLabels())
2398 jaa.centreColLabels = an[i].getCentreColLabels();
2400 if (an[i].hasScaleColLabels())
2402 jaa.scaleColLabel = an[i].getScaleColLabels();
2404 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2406 // newer files have an 'autoCalculated' flag and store calculation
2407 // state in viewport properties
2408 jaa.autoCalculated = true; // means annotation will be marked for
2409 // update at end of load.
2411 if (an[i].hasGraphHeight())
2413 jaa.graphHeight = an[i].getGraphHeight();
2415 if (an[i].hasBelowAlignment())
2417 jaa.belowAlignment = an[i].isBelowAlignment();
2419 jaa.setCalcId(an[i].getCalcId());
2421 if (jaa.autoCalculated)
2423 autoAlan.add(new JvAnnotRow(i, jaa));
2426 // if (!autoForView)
2428 // add autocalculated group annotation and any user created annotation
2430 al.addAnnotation(jaa);
2435 // ///////////////////////
2437 // Create alignment markup and styles for this view
2438 if (jms.getJGroupCount() > 0)
2440 JGroup[] groups = jms.getJGroup();
2442 for (int i = 0; i < groups.length; i++)
2444 ColourSchemeI cs = null;
2446 if (groups[i].getColour() != null)
2448 if (groups[i].getColour().startsWith("ucs"))
2450 cs = GetUserColourScheme(jms, groups[i].getColour());
2454 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2459 cs.setThreshold(groups[i].getPidThreshold(), true);
2463 Vector seqs = new Vector();
2465 for (int s = 0; s < groups[i].getSeqCount(); s++)
2467 String seqId = groups[i].getSeq(s) + "";
2468 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2473 seqs.addElement(ts);
2477 if (seqs.size() < 1)
2482 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2483 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2484 groups[i].getDisplayText(), groups[i].getColourText(),
2485 groups[i].getStart(), groups[i].getEnd());
2487 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2489 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2490 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2491 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2492 .isShowUnconserved() : false);
2493 sg.thresholdTextColour = groups[i].getTextColThreshold();
2494 if (groups[i].hasShowConsensusHistogram())
2496 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2499 if (groups[i].hasShowSequenceLogo())
2501 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2503 if (groups[i].hasNormaliseSequenceLogo())
2505 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2507 if (groups[i].hasIgnoreGapsinConsensus())
2509 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2511 if (groups[i].getConsThreshold() != 0)
2513 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2514 "All", ResidueProperties.propHash, 3,
2515 sg.getSequences(null), 0, sg.getWidth() - 1);
2517 c.verdict(false, 25);
2518 sg.cs.setConservation(c);
2521 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2523 // re-instate unique group/annotation row reference
2524 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2525 .get(groups[i].getId());
2528 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2531 if (jaa.autoCalculated)
2533 // match up and try to set group autocalc alignment row for this
2535 if (jaa.label.startsWith("Consensus for "))
2537 sg.setConsensus(jaa);
2539 // match up and try to set group autocalc alignment row for this
2541 if (jaa.label.startsWith("Conservation for "))
2543 sg.setConservationRow(jaa);
2554 // ///////////////////////////////
2557 // If we just load in the same jar file again, the sequenceSetId
2558 // will be the same, and we end up with multiple references
2559 // to the same sequenceSet. We must modify this id on load
2560 // so that each load of the file gives a unique id
2561 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2562 String viewId = (view.getId() == null ? null : view.getId()
2564 AlignFrame af = null;
2565 AlignViewport av = null;
2566 // now check to see if we really need to create a new viewport.
2567 if (multipleView && viewportsAdded.size() == 0)
2569 // We recovered an alignment for which a viewport already exists.
2570 // TODO: fix up any settings necessary for overlaying stored state onto
2571 // state recovered from another document. (may not be necessary).
2572 // we may need a binding from a viewport in memory to one recovered from
2574 // and then recover its containing af to allow the settings to be applied.
2575 // TODO: fix for vamsas demo
2577 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2579 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2580 if (seqsetobj != null)
2582 if (seqsetobj instanceof String)
2584 uniqueSeqSetId = (String) seqsetobj;
2586 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2592 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2597 AlignmentPanel ap = null;
2598 boolean isnewview = true;
2601 // Check to see if this alignment already has a view id == viewId
2602 jalview.gui.AlignmentPanel views[] = Desktop
2603 .getAlignmentPanels(uniqueSeqSetId);
2604 if (views != null && views.length > 0)
2606 for (int v = 0; v < views.length; v++)
2608 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2610 // recover the existing alignpanel, alignframe, viewport
2611 af = views[v].alignFrame;
2614 // TODO: could even skip resetting view settings if we don't want to
2615 // change the local settings from other jalview processes
2624 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2625 uniqueSeqSetId, viewId, autoAlan);
2630 // /////////////////////////////////////
2631 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2635 for (int t = 0; t < jms.getTreeCount(); t++)
2638 Tree tree = jms.getTree(t);
2640 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2643 tp = af.ShowNewickTree(
2644 new jalview.io.NewickFile(tree.getNewick()),
2645 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2646 tree.getXpos(), tree.getYpos());
2647 if (tree.getId() != null)
2649 // perhaps bind the tree id to something ?
2654 // update local tree attributes ?
2655 // TODO: should check if tp has been manipulated by user - if so its
2656 // settings shouldn't be modified
2657 tp.setTitle(tree.getTitle());
2658 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2659 .getWidth(), tree.getHeight()));
2660 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2663 tp.treeCanvas.av = av; // af.viewport;
2664 tp.treeCanvas.ap = ap; // af.alignPanel;
2669 warn("There was a problem recovering stored Newick tree: \n"
2670 + tree.getNewick());
2674 tp.fitToWindow.setState(tree.getFitToWindow());
2675 tp.fitToWindow_actionPerformed(null);
2677 if (tree.getFontName() != null)
2679 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2680 .getFontStyle(), tree.getFontSize()));
2684 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2685 .getFontStyle(), tree.getFontSize()));
2688 tp.showPlaceholders(tree.getMarkUnlinked());
2689 tp.showBootstrap(tree.getShowBootstrap());
2690 tp.showDistances(tree.getShowDistances());
2692 tp.treeCanvas.threshold = tree.getThreshold();
2694 if (tree.getCurrentTree())
2696 af.viewport.setCurrentTree(tp.getTree());
2700 } catch (Exception ex)
2702 ex.printStackTrace();
2706 // //LOAD STRUCTURES
2707 if (loadTreesAndStructures)
2709 // run through all PDB ids on the alignment, and collect mappings between
2710 // jmol view ids and all sequences referring to it
2711 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2713 for (int i = 0; i < JSEQ.length; i++)
2715 if (JSEQ[i].getPdbidsCount() > 0)
2717 Pdbids[] ids = JSEQ[i].getPdbids();
2718 for (int p = 0; p < ids.length; p++)
2720 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2722 // check to see if we haven't already created this structure view
2723 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2724 : ids[p].getStructureState(s).getViewId()
2726 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2727 // Originally : ids[p].getFile()
2728 // : TODO: verify external PDB file recovery still works in normal
2729 // jalview project load
2730 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2731 jpdb.setId(ids[p].getId());
2733 int x = ids[p].getStructureState(s).getXpos();
2734 int y = ids[p].getStructureState(s).getYpos();
2735 int width = ids[p].getStructureState(s).getWidth();
2736 int height = ids[p].getStructureState(s).getHeight();
2738 // Probably don't need to do this anymore...
2739 // Desktop.desktop.getComponentAt(x, y);
2740 // TODO: NOW: check that this recovers the PDB file correctly.
2741 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2742 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2743 .get(JSEQ[i].getId() + "");
2744 if (sviewid == null)
2746 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2749 if (!jmolViewIds.containsKey(sviewid))
2751 jmolViewIds.put(sviewid, new Object[]
2753 { x, y, width, height }, "",
2754 new Hashtable<String, Object[]>(), new boolean[]
2755 { false, false, true } });
2756 // Legacy pre-2.7 conversion JAL-823 :
2757 // do not assume any view has to be linked for colour by
2761 // assemble String[] { pdb files }, String[] { id for each
2762 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2763 // seqs_file 2}, boolean[] {
2764 // linkAlignPanel,superposeWithAlignpanel}} from hash
2765 Object[] jmoldat = jmolViewIds.get(sviewid);
2766 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2767 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
2768 s).getAlignwithAlignPanel() : false;
2769 // never colour by linked panel if not specified
2770 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
2771 .hasColourwithAlignPanel() ? ids[p]
2772 .getStructureState(s).getColourwithAlignPanel()
2774 // default for pre-2.7 projects is that Jmol colouring is enabled
2775 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
2776 .hasColourByJmol() ? ids[p].getStructureState(s)
2777 .getColourByJmol() : true;
2779 if (((String) jmoldat[1]).length() < ids[p]
2780 .getStructureState(s).getContent().length())
2783 jmoldat[1] = ids[p].getStructureState(s).getContent();
2786 if (ids[p].getFile() != null)
2788 File mapkey = new File(ids[p].getFile());
2789 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
2791 if (seqstrmaps == null)
2793 ((Hashtable) jmoldat[2]).put(mapkey,
2794 seqstrmaps = new Object[]
2795 { pdbFile, ids[p].getId(), new Vector(),
2798 if (!((Vector) seqstrmaps[2]).contains(seq))
2800 ((Vector) seqstrmaps[2]).addElement(seq);
2801 // ((Vector)seqstrmaps[3]).addElement(n) :
2802 // in principle, chains
2803 // should be stored here : do we need to
2804 // TODO: store and recover seq/pdb_id :
2810 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");
2819 // Instantiate the associated Jmol views
2820 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
2822 String sviewid = entry.getKey();
2823 Object[] svattrib = entry.getValue();
2824 int[] geom = (int[]) svattrib[0];
2825 String state = (String) svattrib[1];
2826 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
2827 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
2828 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
2829 // collate the pdbfile -> sequence mappings from this view
2830 Vector<String> pdbfilenames = new Vector<String>();
2831 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
2832 Vector<String> pdbids = new Vector<String>();
2834 // Search to see if we've already created this Jmol view
2835 AppJmol comp = null;
2836 JInternalFrame[] frames = null;
2841 frames = Desktop.desktop.getAllFrames();
2842 } catch (ArrayIndexOutOfBoundsException e)
2844 // occasional No such child exceptions are thrown here...
2849 } catch (Exception f)
2854 } while (frames == null);
2855 // search for any Jmol windows already open from other
2856 // alignment views that exactly match the stored structure state
2857 for (int f = 0; comp == null && f < frames.length; f++)
2859 if (frames[f] instanceof AppJmol)
2862 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
2864 // post jalview 2.4 schema includes structure view id
2865 comp = (AppJmol) frames[f];
2867 else if (frames[f].getX() == x && frames[f].getY() == y
2868 && frames[f].getHeight() == height
2869 && frames[f].getWidth() == width)
2871 comp = (AppJmol) frames[f];
2878 // create a new Jmol window.
2879 // First parse the Jmol state to translate filenames loaded into the
2880 // view, and record the order in which files are shown in the Jmol
2881 // view, so we can add the sequence mappings in same order.
2882 StringBuffer newFileLoc = null;
2883 int cp = 0, ncp, ecp;
2884 while ((ncp = state.indexOf("load ", cp)) > -1)
2886 if (newFileLoc == null)
2888 newFileLoc = new StringBuffer();
2892 // look for next filename in load statement
2893 newFileLoc.append(state.substring(cp,
2894 ncp = (state.indexOf("\"", ncp + 1) + 1)));
2895 String oldfilenam = state.substring(ncp,
2896 ecp = state.indexOf("\"", ncp));
2897 // recover the new mapping data for this old filename
2898 // have to normalize filename - since Jmol and jalview do
2900 // translation differently.
2901 Object[] filedat = oldFiles.get(new File(oldfilenam));
2902 newFileLoc.append(Platform
2903 .escapeString((String) filedat[0]));
2904 pdbfilenames.addElement((String) filedat[0]);
2905 pdbids.addElement((String) filedat[1]);
2906 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2907 .toArray(new SequenceI[0]));
2908 newFileLoc.append("\"");
2909 cp = ecp + 1; // advance beyond last \" and set cursor so we can
2910 // look for next file statement.
2911 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
2915 // just append rest of state
2916 newFileLoc.append(state.substring(cp));
2921 .print("Ignoring incomplete Jmol state for PDB ids: ");
2922 newFileLoc = new StringBuffer(state);
2923 newFileLoc.append("; load append ");
2924 for (File id : oldFiles.keySet())
2926 // add this and any other pdb files that should be present in
2928 Object[] filedat = oldFiles.get(id);
2930 newFileLoc.append(((String) filedat[0]));
2931 pdbfilenames.addElement((String) filedat[0]);
2932 pdbids.addElement((String) filedat[1]);
2933 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2934 .toArray(new SequenceI[0]));
2935 newFileLoc.append(" \"");
2936 newFileLoc.append((String) filedat[0]);
2937 newFileLoc.append("\"");
2940 newFileLoc.append(";");
2943 if (newFileLoc != null)
2945 int histbug = newFileLoc.indexOf("history = ");
2947 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
2949 String val = (diff == -1) ? null : newFileLoc.substring(
2951 if (val != null && val.length() >= 4)
2953 if (val.contains("e"))
2955 if (val.trim().equals("true"))
2963 newFileLoc.replace(histbug, diff, val);
2966 // TODO: assemble String[] { pdb files }, String[] { id for each
2967 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2968 // seqs_file 2}} from hash
2969 final String[] pdbf = pdbfilenames
2970 .toArray(new String[pdbfilenames.size()]), id = pdbids
2971 .toArray(new String[pdbids.size()]);
2972 final SequenceI[][] sq = seqmaps
2973 .toArray(new SequenceI[seqmaps.size()][]);
2974 final String fileloc = newFileLoc.toString(), vid = sviewid;
2975 final AlignFrame alf = af;
2976 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
2980 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
2985 AppJmol sview = null;
2988 sview = new AppJmol(pdbf, id, sq, alf.alignPanel,
2989 useinJmolsuperpos, usetoColourbyseq,
2990 jmolColouring, fileloc, rect, vid);
2991 addNewStructureViewer(sview);
2992 } catch (OutOfMemoryError ex)
2994 new OOMWarning("restoring structure view for PDB id "
2995 + id, (OutOfMemoryError) ex.getCause());
2996 if (sview != null && sview.isVisible())
2998 sview.closeViewer();
2999 sview.setVisible(false);
3005 } catch (InvocationTargetException ex)
3007 warn("Unexpected error when opening Jmol view.", ex);
3009 } catch (InterruptedException e)
3011 // e.printStackTrace();
3017 // if (comp != null)
3019 // NOTE: if the jalview project is part of a shared session then
3020 // view synchronization should/could be done here.
3022 // add mapping for sequences in this view to an already open Jmol
3024 for (File id : oldFiles.keySet())
3026 // add this and any other pdb files that should be present in the
3028 Object[] filedat = oldFiles.get(id);
3029 String pdbFile = (String) filedat[0];
3030 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3031 .toArray(new SequenceI[0]);
3032 comp.jmb.ssm.setMapping(seq, null, pdbFile,
3033 jalview.io.AppletFormatAdapter.FILE);
3034 comp.jmb.addSequenceForStructFile(pdbFile, seq);
3036 // and add the AlignmentPanel's reference to the Jmol view
3037 comp.addAlignmentPanel(ap);
3038 if (useinJmolsuperpos)
3040 comp.useAlignmentPanelForSuperposition(ap);
3044 comp.excludeAlignmentPanelForSuperposition(ap);
3046 if (usetoColourbyseq)
3048 comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3052 comp.excludeAlignmentPanelForColourbyseq(ap);
3058 // and finally return.
3061 Vector<AppJmol> newStructureViewers=null;
3062 protected void addNewStructureViewer(AppJmol sview)
3064 if (newStructureViewers!=null)
3066 sview.jmb.setFinishedLoadingFromArchive(false);
3067 newStructureViewers.add(sview);
3070 protected void setLoadingFinishedForNewStructureViewers()
3072 if (newStructureViewers!=null)
3074 for (AppJmol sview:newStructureViewers)
3076 sview.jmb.setFinishedLoadingFromArchive(true);
3078 newStructureViewers.clear();
3079 newStructureViewers=null;
3083 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3084 Alignment al, JalviewModelSequence jms, Viewport view,
3085 String uniqueSeqSetId, String viewId,
3086 ArrayList<JvAnnotRow> autoAlan)
3088 AlignFrame af = null;
3089 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3090 uniqueSeqSetId, viewId);
3092 af.setFileName(file, "Jalview");
3094 for (int i = 0; i < JSEQ.length; i++)
3096 af.viewport.setSequenceColour(af.viewport.getAlignment()
3097 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3100 af.viewport.gatherViewsHere = view.getGatheredViews();
3102 if (view.getSequenceSetId() != null)
3104 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3105 .get(uniqueSeqSetId);
3107 af.viewport.setSequenceSetId(uniqueSeqSetId);
3110 // propagate shared settings to this new view
3111 af.viewport.historyList = av.historyList;
3112 af.viewport.redoList = av.redoList;
3116 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3118 // TODO: check if this method can be called repeatedly without
3119 // side-effects if alignpanel already registered.
3120 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3122 // apply Hidden regions to view.
3123 if (hiddenSeqs != null)
3125 for (int s = 0; s < JSEQ.length; s++)
3127 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3129 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3132 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3134 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3137 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3140 for (int s = 0; s < hiddenSeqs.size(); s++)
3142 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3145 af.viewport.hideSequence(hseqs);
3148 // recover view properties and display parameters
3149 if (view.getViewName() != null)
3151 af.viewport.viewName = view.getViewName();
3152 af.setInitialTabVisible();
3154 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3157 af.viewport.setShowAnnotation(view.getShowAnnotation());
3158 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3160 af.viewport.setColourText(view.getShowColourText());
3162 af.viewport.setConservationSelected(view.getConservationSelected());
3163 af.viewport.setShowJVSuffix(view.getShowFullId());
3164 af.viewport.rightAlignIds = view.getRightAlignIds();
3165 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3166 .getFontStyle(), view.getFontSize()));
3167 af.alignPanel.fontChanged();
3168 af.viewport.setRenderGaps(view.getRenderGaps());
3169 af.viewport.setWrapAlignment(view.getWrapAlignment());
3170 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3171 af.viewport.setShowAnnotation(view.getShowAnnotation());
3172 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3174 af.viewport.setShowBoxes(view.getShowBoxes());
3176 af.viewport.setShowText(view.getShowText());
3178 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3179 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3180 af.viewport.thresholdTextColour = view.getTextColThreshold();
3181 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3182 .isShowUnconserved() : false);
3183 af.viewport.setStartRes(view.getStartRes());
3184 af.viewport.setStartSeq(view.getStartSeq());
3186 ColourSchemeI cs = null;
3187 // apply colourschemes
3188 if (view.getBgColour() != null)
3190 if (view.getBgColour().startsWith("ucs"))
3192 cs = GetUserColourScheme(jms, view.getBgColour());
3194 else if (view.getBgColour().startsWith("Annotation"))
3196 // int find annotation
3197 if (af.viewport.getAlignment().getAlignmentAnnotation() != null)
3199 for (int i = 0; i < af.viewport.getAlignment()
3200 .getAlignmentAnnotation().length; i++)
3202 if (af.viewport.getAlignment().getAlignmentAnnotation()[i].label
3203 .equals(view.getAnnotationColours().getAnnotation()))
3205 if (af.viewport.getAlignment().getAlignmentAnnotation()[i]
3206 .getThreshold() == null)
3208 af.viewport.getAlignment().getAlignmentAnnotation()[i]
3209 .setThreshold(new jalview.datamodel.GraphLine(view
3210 .getAnnotationColours().getThreshold(),
3211 "Threshold", java.awt.Color.black)
3216 if (view.getAnnotationColours().getColourScheme()
3219 cs = new AnnotationColourGradient(af.viewport
3220 .getAlignment().getAlignmentAnnotation()[i],
3221 new java.awt.Color(view.getAnnotationColours()
3222 .getMinColour()), new java.awt.Color(view
3223 .getAnnotationColours().getMaxColour()),
3224 view.getAnnotationColours().getAboveThreshold());
3226 else if (view.getAnnotationColours().getColourScheme()
3229 cs = new AnnotationColourGradient(af.viewport
3230 .getAlignment().getAlignmentAnnotation()[i],
3231 GetUserColourScheme(jms, view
3232 .getAnnotationColours().getColourScheme()),
3233 view.getAnnotationColours().getAboveThreshold());
3237 cs = new AnnotationColourGradient(af.viewport
3238 .getAlignment().getAlignmentAnnotation()[i],
3239 ColourSchemeProperty.getColour(al, view
3240 .getAnnotationColours().getColourScheme()),
3241 view.getAnnotationColours().getAboveThreshold());
3243 if (view.getAnnotationColours().hasPerSequence())
3245 ((AnnotationColourGradient)cs).setSeqAssociated(view.getAnnotationColours().isPerSequence());
3247 if (view.getAnnotationColours().hasPredefinedColours())
3249 ((AnnotationColourGradient)cs).setPredefinedColours(view.getAnnotationColours().isPredefinedColours());
3251 // Also use these settings for all the groups
3252 if (al.getGroups() != null)
3254 for (int g = 0; g < al.getGroups().size(); g++)
3256 jalview.datamodel.SequenceGroup sg = al.getGroups()
3266 * (view.getAnnotationColours().getColourScheme().equals("None"
3267 * )) { sg.cs = new AnnotationColourGradient(
3268 * af.viewport.getAlignment().getAlignmentAnnotation()[i], new
3269 * java.awt.Color(view.getAnnotationColours().
3270 * getMinColour()), new
3271 * java.awt.Color(view.getAnnotationColours().
3273 * view.getAnnotationColours().getAboveThreshold()); } else
3276 sg.cs = new AnnotationColourGradient(af.viewport
3277 .getAlignment().getAlignmentAnnotation()[i],
3278 sg.cs, view.getAnnotationColours()
3279 .getAboveThreshold());
3280 if (cs instanceof AnnotationColourGradient)
3282 if (view.getAnnotationColours().hasPerSequence())
3284 ((AnnotationColourGradient)cs).setSeqAssociated(view.getAnnotationColours().isPerSequence());
3286 if (view.getAnnotationColours().hasPredefinedColours())
3288 ((AnnotationColourGradient)cs).setPredefinedColours(view.getAnnotationColours().isPredefinedColours());
3304 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3309 cs.setThreshold(view.getPidThreshold(), true);
3310 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3314 af.viewport.setGlobalColourScheme(cs);
3315 af.viewport.setColourAppliesToAllGroups(false);
3317 if (view.getConservationSelected() && cs != null)
3319 cs.setConservationInc(view.getConsThreshold());
3322 af.changeColour(cs);
3324 af.viewport.setColourAppliesToAllGroups(true);
3326 if (view.getShowSequenceFeatures())
3328 af.viewport.showSequenceFeatures = true;
3330 if (view.hasCentreColumnLabels())
3332 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3334 if (view.hasIgnoreGapsinConsensus())
3336 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3339 if (view.hasFollowHighlight())
3341 af.viewport.followHighlight = view.getFollowHighlight();
3343 if (view.hasFollowSelection())
3345 af.viewport.followSelection = view.getFollowSelection();
3347 if (view.hasShowConsensusHistogram())
3349 af.viewport.setShowConsensusHistogram(view
3350 .getShowConsensusHistogram());
3354 af.viewport.setShowConsensusHistogram(true);
3356 if (view.hasShowSequenceLogo())
3358 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3362 af.viewport.setShowSequenceLogo(false);
3364 if (view.hasNormaliseSequenceLogo())
3366 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3368 if (view.hasShowDbRefTooltip())
3370 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3372 if (view.hasShowNPfeatureTooltip())
3374 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3376 if (view.hasShowGroupConsensus())
3378 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3382 af.viewport.setShowGroupConsensus(false);
3384 if (view.hasShowGroupConservation())
3386 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3390 af.viewport.setShowGroupConservation(false);
3393 // recover featre settings
3394 if (jms.getFeatureSettings() != null)
3396 af.viewport.featuresDisplayed = new Hashtable();
3397 String[] renderOrder = new String[jms.getFeatureSettings()
3398 .getSettingCount()];
3399 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3401 Setting setting = jms.getFeatureSettings().getSetting(fs);
3402 if (setting.hasMincolour())
3404 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3405 new java.awt.Color(setting.getMincolour()),
3406 new java.awt.Color(setting.getColour()),
3407 setting.getMin(), setting.getMax()) : new GraduatedColor(
3408 new java.awt.Color(setting.getMincolour()),
3409 new java.awt.Color(setting.getColour()), 0, 1);
3410 if (setting.hasThreshold())
3412 gc.setThresh(setting.getThreshold());
3413 gc.setThreshType(setting.getThreshstate());
3415 gc.setAutoScaled(true); // default
3416 if (setting.hasAutoScale())
3418 gc.setAutoScaled(setting.getAutoScale());
3420 if (setting.hasColourByLabel())
3422 gc.setColourByLabel(setting.getColourByLabel());
3424 // and put in the feature colour table.
3425 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3426 setting.getType(), gc);
3430 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3432 new java.awt.Color(setting.getColour()));
3434 renderOrder[fs] = setting.getType();
3435 if (setting.hasOrder())
3436 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3437 setting.getType(), setting.getOrder());
3439 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3441 fs / jms.getFeatureSettings().getSettingCount());
3442 if (setting.getDisplay())
3444 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3445 setting.getColour()));
3448 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3450 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3451 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3453 Group grp = jms.getFeatureSettings().getGroup(gs);
3454 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3458 if (view.getHiddenColumnsCount() > 0)
3460 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3462 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3463 .getHiddenColumns(c).getEnd() // +1
3467 if (view.getCalcIdParam() != null)
3469 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3471 if (calcIdParam != null)
3473 if (recoverCalcIdParam(calcIdParam, af.viewport))
3478 warn("Couldn't recover parameters for "
3479 + calcIdParam.getCalcId());
3484 af.setMenusFromViewport(af.viewport);
3485 // TODO: we don't need to do this if the viewport is aready visible.
3486 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3488 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3489 reorderAutoannotation(af, al, autoAlan);
3490 af.alignPanel.alignmentChanged();
3494 private void reorderAutoannotation(AlignFrame af, Alignment al,
3495 ArrayList<JvAnnotRow> autoAlan)
3497 // copy over visualization settings for autocalculated annotation in the
3499 if (al.getAlignmentAnnotation() != null)
3502 * Kludge for magic autoannotation names (see JAL-811)
3504 String[] magicNames = new String[]
3505 { "Consensus", "Quality", "Conservation" };
3506 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3507 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3508 for (String nm : magicNames)
3510 visan.put(nm, nullAnnot);
3512 for (JvAnnotRow auan : autoAlan)
3514 visan.put(auan.template.label
3515 + (auan.template.getCalcId() == null ? "" : "\t"
3516 + auan.template.getCalcId()), auan);
3518 int hSize = al.getAlignmentAnnotation().length;
3519 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3520 // work through any autoCalculated annotation already on the view
3521 // removing it if it should be placed in a different location on the
3522 // annotation panel.
3523 List<String> remains = new ArrayList(visan.keySet());
3524 for (int h = 0; h < hSize; h++)
3526 jalview.datamodel.AlignmentAnnotation jalan = al
3527 .getAlignmentAnnotation()[h];
3528 if (jalan.autoCalculated)
3531 JvAnnotRow valan = visan.get(k = jalan.label);
3532 if (jalan.getCalcId() != null)
3534 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
3539 // delete the auto calculated row from the alignment
3540 al.deleteAnnotation(jalan, false);
3544 if (valan != nullAnnot)
3546 if (jalan != valan.template)
3548 // newly created autoannotation row instance
3549 // so keep a reference to the visible annotation row
3550 // and copy over all relevant attributes
3551 if (valan.template.graphHeight >= 0)
3554 jalan.graphHeight = valan.template.graphHeight;
3556 jalan.visible = valan.template.visible;
3558 reorder.add(new JvAnnotRow(valan.order, jalan));
3563 // Add any (possibly stale) autocalculated rows that were not appended to
3564 // the view during construction
3565 for (String other : remains)
3567 JvAnnotRow othera = visan.get(other);
3568 if (othera != nullAnnot && othera.template.getCalcId() != null
3569 && othera.template.getCalcId().length() > 0)
3571 reorder.add(othera);
3574 // now put the automatic annotation in its correct place
3575 int s = 0, srt[] = new int[reorder.size()];
3576 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3577 for (JvAnnotRow jvar : reorder)
3580 srt[s++] = jvar.order;
3583 jalview.util.QuickSort.sort(srt, rws);
3584 // and re-insert the annotation at its correct position
3585 for (JvAnnotRow jvar : rws)
3587 al.addAnnotation(jvar.template, jvar.order);
3589 af.alignPanel.adjustAnnotationHeight();
3593 Hashtable skipList = null;
3596 * TODO remove this method
3599 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3600 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3601 * throw new Error("Implementation Error. No skipList defined for this
3602 * Jalview2XML instance."); } return (AlignFrame)
3603 * skipList.get(view.getSequenceSetId()); }
3607 * Check if the Jalview view contained in object should be skipped or not.
3610 * @return true if view's sequenceSetId is a key in skipList
3612 private boolean skipViewport(JalviewModel object)
3614 if (skipList == null)
3619 if (skipList.containsKey(id = object.getJalviewModelSequence()
3620 .getViewport()[0].getSequenceSetId()))
3622 if (Cache.log != null && Cache.log.isDebugEnabled())
3624 Cache.log.debug("Skipping seuqence set id " + id);
3631 public void AddToSkipList(AlignFrame af)
3633 if (skipList == null)
3635 skipList = new Hashtable();
3637 skipList.put(af.getViewport().getSequenceSetId(), af);
3640 public void clearSkipList()
3642 if (skipList != null)
3649 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3651 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3652 Vector dseqs = null;
3655 // create a list of new dataset sequences
3656 dseqs = new Vector();
3658 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3660 Sequence vamsasSeq = vamsasSet.getSequence(i);
3661 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
3663 // create a new dataset
3666 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3667 dseqs.copyInto(dsseqs);
3668 ds = new jalview.datamodel.Alignment(dsseqs);
3669 debug("Created new dataset " + vamsasSet.getDatasetId()
3670 + " for alignment " + System.identityHashCode(al));
3671 addDatasetRef(vamsasSet.getDatasetId(), ds);
3673 // set the dataset for the newly imported alignment.
3674 if (al.getDataset() == null)
3683 * sequence definition to create/merge dataset sequence for
3687 * vector to add new dataset sequence to
3689 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
3690 AlignmentI ds, Vector dseqs)
3692 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
3694 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
3695 .get(vamsasSeq.getId());
3696 jalview.datamodel.SequenceI dsq = null;
3697 if (sq != null && sq.getDatasetSequence() != null)
3699 dsq = sq.getDatasetSequence();
3702 String sqid = vamsasSeq.getDsseqid();
3705 // need to create or add a new dataset sequence reference to this sequence
3708 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
3713 // make a new dataset sequence
3714 dsq = sq.createDatasetSequence();
3717 // make up a new dataset reference for this sequence
3718 sqid = seqHash(dsq);
3720 dsq.setVamsasId(uniqueSetSuffix + sqid);
3721 seqRefIds.put(sqid, dsq);
3726 dseqs.addElement(dsq);
3731 ds.addSequence(dsq);
3737 { // make this dataset sequence sq's dataset sequence
3738 sq.setDatasetSequence(dsq);
3742 // TODO: refactor this as a merge dataset sequence function
3743 // now check that sq (the dataset sequence) sequence really is the union of
3744 // all references to it
3745 // boolean pre = sq.getStart() < dsq.getStart();
3746 // boolean post = sq.getEnd() > dsq.getEnd();
3750 StringBuffer sb = new StringBuffer();
3751 String newres = jalview.analysis.AlignSeq.extractGaps(
3752 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
3753 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
3754 && newres.length() > dsq.getLength())
3756 // Update with the longer sequence.
3760 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
3761 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
3762 * sb.append(newres.substring(newres.length() - sq.getEnd() -
3763 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
3765 dsq.setSequence(sb.toString());
3767 // TODO: merges will never happen if we 'know' we have the real dataset
3768 // sequence - this should be detected when id==dssid
3769 System.err.println("DEBUG Notice: Merged dataset sequence"); // ("
3770 // + (pre ? "prepended" : "") + " "
3771 // + (post ? "appended" : ""));
3776 java.util.Hashtable datasetIds = null;
3778 java.util.IdentityHashMap dataset2Ids = null;
3780 private Alignment getDatasetFor(String datasetId)
3782 if (datasetIds == null)
3784 datasetIds = new Hashtable();
3787 if (datasetIds.containsKey(datasetId))
3789 return (Alignment) datasetIds.get(datasetId);
3794 private void addDatasetRef(String datasetId, Alignment dataset)
3796 if (datasetIds == null)
3798 datasetIds = new Hashtable();
3800 datasetIds.put(datasetId, dataset);
3804 * make a new dataset ID for this jalview dataset alignment
3809 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
3811 if (dataset.getDataset() != null)
3813 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
3815 String datasetId = makeHashCode(dataset, null);
3816 if (datasetId == null)
3818 // make a new datasetId and record it
3819 if (dataset2Ids == null)
3821 dataset2Ids = new IdentityHashMap();
3825 datasetId = (String) dataset2Ids.get(dataset);
3827 if (datasetId == null)
3829 datasetId = "ds" + dataset2Ids.size() + 1;
3830 dataset2Ids.put(dataset, datasetId);
3836 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
3838 for (int d = 0; d < sequence.getDBRefCount(); d++)
3840 DBRef dr = sequence.getDBRef(d);
3841 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
3842 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
3843 .getVersion(), sequence.getDBRef(d).getAccessionId());
3844 if (dr.getMapping() != null)
3846 entry.setMap(addMapping(dr.getMapping()));
3848 datasetSequence.addDBRef(entry);
3852 private jalview.datamodel.Mapping addMapping(Mapping m)
3854 SequenceI dsto = null;
3855 // Mapping m = dr.getMapping();
3856 int fr[] = new int[m.getMapListFromCount() * 2];
3857 Enumeration f = m.enumerateMapListFrom();
3858 for (int _i = 0; f.hasMoreElements(); _i += 2)
3860 MapListFrom mf = (MapListFrom) f.nextElement();
3861 fr[_i] = mf.getStart();
3862 fr[_i + 1] = mf.getEnd();
3864 int fto[] = new int[m.getMapListToCount() * 2];
3865 f = m.enumerateMapListTo();
3866 for (int _i = 0; f.hasMoreElements(); _i += 2)
3868 MapListTo mf = (MapListTo) f.nextElement();
3869 fto[_i] = mf.getStart();
3870 fto[_i + 1] = mf.getEnd();
3872 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
3873 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
3874 if (m.getMappingChoice() != null)
3876 MappingChoice mc = m.getMappingChoice();
3877 if (mc.getDseqFor() != null)
3879 String dsfor = "" + mc.getDseqFor();
3880 if (seqRefIds.containsKey(dsfor))
3885 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
3889 frefedSequence.add(new Object[]
3896 * local sequence definition
3898 Sequence ms = mc.getSequence();
3899 jalview.datamodel.Sequence djs = null;
3900 String sqid = ms.getDsseqid();
3901 if (sqid != null && sqid.length() > 0)
3904 * recover dataset sequence
3906 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
3911 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
3912 sqid = ((Object) ms).toString(); // make up a new hascode for
3913 // undefined dataset sequence hash
3914 // (unlikely to happen)
3920 * make a new dataset sequence and add it to refIds hash
3922 djs = new jalview.datamodel.Sequence(ms.getName(),
3924 djs.setStart(jmap.getMap().getToLowest());
3925 djs.setEnd(jmap.getMap().getToHighest());
3926 djs.setVamsasId(uniqueSetSuffix + sqid);
3928 seqRefIds.put(sqid, djs);
3931 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
3940 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
3941 boolean keepSeqRefs)
3944 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
3950 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
3954 uniqueSetSuffix = "";
3955 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
3960 if (this.frefedSequence == null)
3962 frefedSequence = new Vector();
3965 viewportsAdded = new Hashtable();
3967 AlignFrame af = LoadFromObject(jm, null, false, null);
3968 af.alignPanels.clear();
3969 af.closeMenuItem_actionPerformed(true);
3972 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
3973 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
3974 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
3975 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
3976 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
3979 return af.alignPanel;
3983 * flag indicating if hashtables should be cleared on finalization TODO this
3984 * flag may not be necessary
3986 private final boolean _cleartables = true;
3988 private Hashtable jvids2vobj;
3993 * @see java.lang.Object#finalize()
3996 protected void finalize() throws Throwable
3998 // really make sure we have no buried refs left.
4003 this.seqRefIds = null;
4004 this.seqsToIds = null;
4008 private void warn(String msg)
4013 private void warn(String msg, Exception e)
4015 if (Cache.log != null)
4019 Cache.log.warn(msg, e);
4023 Cache.log.warn(msg);
4028 System.err.println("Warning: " + msg);
4031 e.printStackTrace();
4036 private void debug(String string)
4038 debug(string, null);
4041 private void debug(String msg, Exception e)
4043 if (Cache.log != null)
4047 Cache.log.debug(msg, e);
4051 Cache.log.debug(msg);
4056 System.err.println("Warning: " + msg);
4059 e.printStackTrace();
4065 * set the object to ID mapping tables used to write/recover objects and XML
4066 * ID strings for the jalview project. If external tables are provided then
4067 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4068 * object goes out of scope. - also populates the datasetIds hashtable with
4069 * alignment objects containing dataset sequences
4072 * Map from ID strings to jalview datamodel
4074 * Map from jalview datamodel to ID strings
4078 public void setObjectMappingTables(Hashtable vobj2jv,
4079 IdentityHashMap jv2vobj)
4081 this.jv2vobj = jv2vobj;
4082 this.vobj2jv = vobj2jv;
4083 Iterator ds = jv2vobj.keySet().iterator();
4085 while (ds.hasNext())
4087 Object jvobj = ds.next();
4088 id = jv2vobj.get(jvobj).toString();
4089 if (jvobj instanceof jalview.datamodel.Alignment)
4091 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4093 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4096 else if (jvobj instanceof jalview.datamodel.Sequence)
4098 // register sequence object so the XML parser can recover it.
4099 if (seqRefIds == null)
4101 seqRefIds = new Hashtable();
4103 if (seqsToIds == null)
4105 seqsToIds = new IdentityHashMap();
4107 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
4108 seqsToIds.put(jvobj, id);
4110 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4112 if (annotationIds == null)
4114 annotationIds = new Hashtable();
4117 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4118 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4119 if (jvann.annotationId == null)
4121 jvann.annotationId = anid;
4123 if (!jvann.annotationId.equals(anid))
4125 // TODO verify that this is the correct behaviour
4126 this.warn("Overriding Annotation ID for " + anid
4127 + " from different id : " + jvann.annotationId);
4128 jvann.annotationId = anid;
4131 else if (jvobj instanceof String)
4133 if (jvids2vobj == null)
4135 jvids2vobj = new Hashtable();
4136 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4140 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4145 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4146 * objects created from the project archive. If string is null (default for
4147 * construction) then suffix will be set automatically.
4151 public void setUniqueSetSuffix(String string)
4153 uniqueSetSuffix = string;
4158 * uses skipList2 as the skipList for skipping views on sequence sets
4159 * associated with keys in the skipList
4163 public void setSkipList(Hashtable skipList2)
4165 skipList = skipList2;