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.getProperty("VERSION"));
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 view.setAnnotationColours(ac);
1073 view.setBgColour("AnnotationColourGradient");
1077 view.setBgColour(ColourSchemeProperty.getColourName(av
1078 .getGlobalColourScheme()));
1081 ColourSchemeI cs = av.getGlobalColourScheme();
1085 if (cs.conservationApplied())
1087 view.setConsThreshold(cs.getConservationInc());
1088 if (cs instanceof jalview.schemes.UserColourScheme)
1090 view.setBgColour(SetUserColourScheme(cs, userColours, jms));
1094 if (cs instanceof ResidueColourScheme)
1096 view.setPidThreshold(cs.getThreshold());
1100 view.setConservationSelected(av.getConservationSelected());
1101 view.setPidSelected(av.getAbovePIDThreshold());
1102 view.setFontName(av.font.getName());
1103 view.setFontSize(av.font.getSize());
1104 view.setFontStyle(av.font.getStyle());
1105 view.setRenderGaps(av.renderGaps);
1106 view.setShowAnnotation(av.getShowAnnotation());
1107 view.setShowBoxes(av.getShowBoxes());
1108 view.setShowColourText(av.getColourText());
1109 view.setShowFullId(av.getShowJVSuffix());
1110 view.setRightAlignIds(av.rightAlignIds);
1111 view.setShowSequenceFeatures(av.showSequenceFeatures);
1112 view.setShowText(av.getShowText());
1113 view.setShowUnconserved(av.getShowUnconserved());
1114 view.setWrapAlignment(av.getWrapAlignment());
1115 view.setTextCol1(av.textColour.getRGB());
1116 view.setTextCol2(av.textColour2.getRGB());
1117 view.setTextColThreshold(av.thresholdTextColour);
1118 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1119 view.setShowSequenceLogo(av.isShowSequenceLogo());
1120 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1121 view.setShowGroupConsensus(av.isShowGroupConsensus());
1122 view.setShowGroupConservation(av.isShowGroupConservation());
1123 view.setShowNPfeatureTooltip(av.isShowNpFeats());
1124 view.setShowDbRefTooltip(av.isShowDbRefs());
1125 view.setFollowHighlight(av.followHighlight);
1126 view.setFollowSelection(av.followSelection);
1127 view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
1128 if (av.featuresDisplayed != null)
1130 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1132 String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;
1134 Vector settingsAdded = new Vector();
1135 Object gstyle = null;
1136 GraduatedColor gcol = null;
1137 if (renderOrder != null)
1139 for (int ro = 0; ro < renderOrder.length; ro++)
1141 gstyle = ap.seqPanel.seqCanvas.getFeatureRenderer()
1142 .getFeatureStyle(renderOrder[ro]);
1143 Setting setting = new Setting();
1144 setting.setType(renderOrder[ro]);
1145 if (gstyle instanceof GraduatedColor)
1147 gcol = (GraduatedColor) gstyle;
1148 setting.setColour(gcol.getMaxColor().getRGB());
1149 setting.setMincolour(gcol.getMinColor().getRGB());
1150 setting.setMin(gcol.getMin());
1151 setting.setMax(gcol.getMax());
1152 setting.setColourByLabel(gcol.isColourByLabel());
1153 setting.setAutoScale(gcol.isAutoScale());
1154 setting.setThreshold(gcol.getThresh());
1155 setting.setThreshstate(gcol.getThreshType());
1159 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1160 .getColour(renderOrder[ro]).getRGB());
1163 setting.setDisplay(av.featuresDisplayed
1164 .containsKey(renderOrder[ro]));
1165 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
1166 .getOrder(renderOrder[ro]);
1169 setting.setOrder(rorder);
1171 fs.addSetting(setting);
1172 settingsAdded.addElement(renderOrder[ro]);
1176 // Make sure we save none displayed feature settings
1177 Iterator en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours
1178 .keySet().iterator();
1179 while (en.hasNext())
1181 String key = en.next().toString();
1182 if (settingsAdded.contains(key))
1187 Setting setting = new Setting();
1188 setting.setType(key);
1189 setting.setColour(ap.seqPanel.seqCanvas.getFeatureRenderer()
1190 .getColour(key).getRGB());
1192 setting.setDisplay(false);
1193 float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer().getOrder(
1197 setting.setOrder(rorder);
1199 fs.addSetting(setting);
1200 settingsAdded.addElement(key);
1202 en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1203 .keySet().iterator();
1204 Vector groupsAdded = new Vector();
1205 while (en.hasNext())
1207 String grp = en.next().toString();
1208 if (groupsAdded.contains(grp))
1212 Group g = new Group();
1214 g.setDisplay(((Boolean) ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
1215 .get(grp)).booleanValue());
1217 groupsAdded.addElement(grp);
1219 jms.setFeatureSettings(fs);
1223 if (av.hasHiddenColumns())
1225 if (av.getColumnSelection() == null
1226 || av.getColumnSelection().getHiddenColumns() == null)
1228 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1232 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1235 int[] region = (int[]) av.getColumnSelection().getHiddenColumns()
1237 HiddenColumns hc = new HiddenColumns();
1238 hc.setStart(region[0]);
1239 hc.setEnd(region[1]);
1240 view.addHiddenColumns(hc);
1244 if (calcIdSet.size() > 0)
1246 for (String calcId : calcIdSet)
1248 if (calcId.trim().length() > 0)
1250 CalcIdParam cidp = createCalcIdParam(calcId, av);
1251 // Some calcIds have no parameters.
1254 view.addCalcIdParam(cidp);
1260 jms.addViewport(view);
1262 object.setJalviewModelSequence(jms);
1263 object.getVamsasModel().addSequenceSet(vamsasSet);
1265 if (jout != null && fileName != null)
1267 // We may not want to write the object to disk,
1268 // eg we can copy the alignViewport to a new view object
1269 // using save and then load
1272 JarEntry entry = new JarEntry(fileName);
1273 jout.putNextEntry(entry);
1274 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1276 org.exolab.castor.xml.Marshaller marshaller = new org.exolab.castor.xml.Marshaller(
1278 marshaller.marshal(object);
1281 } catch (Exception ex)
1283 // TODO: raise error in GUI if marshalling failed.
1284 ex.printStackTrace();
1290 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1292 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1293 if (settings != null)
1295 CalcIdParam vCalcIdParam = new CalcIdParam();
1296 vCalcIdParam.setCalcId(calcId);
1297 vCalcIdParam.addServiceURL(settings.getServiceURI());
1298 // generic URI allowing a third party to resolve another instance of the
1299 // service used for this calculation
1300 for (String urls : settings.getServiceURLs())
1302 vCalcIdParam.addServiceURL(urls);
1304 vCalcIdParam.setVersion("1.0");
1305 if (settings.getPreset() != null)
1307 WsParamSetI setting = settings.getPreset();
1308 vCalcIdParam.setName(setting.getName());
1309 vCalcIdParam.setDescription(setting.getDescription());
1313 vCalcIdParam.setName("");
1314 vCalcIdParam.setDescription("Last used parameters");
1316 // need to be able to recover 1) settings 2) user-defined presets or
1317 // recreate settings from preset 3) predefined settings provided by
1318 // service - or settings that can be transferred (or discarded)
1319 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1321 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1322 // todo - decide if updateImmediately is needed for any projects.
1324 return vCalcIdParam;
1329 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1332 if (calcIdParam.getVersion().equals("1.0"))
1334 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1335 .getPreferredServiceFor(calcIdParam.getServiceURL());
1336 if (service != null)
1338 WsParamSetI parmSet = null;
1341 parmSet = service.getParamStore().parseServiceParameterFile(
1342 calcIdParam.getName(), calcIdParam.getDescription(),
1343 calcIdParam.getServiceURL(),
1344 calcIdParam.getParameters().replace("|\\n|", "\n"));
1345 } catch (IOException x)
1347 warn("Couldn't parse parameter data for "
1348 + calcIdParam.getCalcId(), x);
1351 List<ArgumentI> argList = null;
1352 if (calcIdParam.getName().length() > 0)
1354 parmSet = service.getParamStore()
1355 .getPreset(calcIdParam.getName());
1356 if (parmSet != null)
1358 // TODO : check we have a good match with settings in AACon -
1359 // otherwise we'll need to create a new preset
1364 argList = parmSet.getArguments();
1367 AAConSettings settings = new AAConSettings(
1368 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1369 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1370 calcIdParam.isNeedsUpdate());
1375 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1379 throw new Error("Unsupported Version for calcIdparam "
1380 + calcIdParam.toString());
1384 * External mapping between jalview objects and objects yielding a valid and
1385 * unique object ID string. This is null for normal Jalview project IO, but
1386 * non-null when a jalview project is being read or written as part of a
1389 IdentityHashMap jv2vobj = null;
1392 * Construct a unique ID for jvobj using either existing bindings or if none
1393 * exist, the result of the hashcode call for the object.
1396 * jalview data object
1397 * @return unique ID for referring to jvobj
1399 private String makeHashCode(Object jvobj, String altCode)
1401 if (jv2vobj != null)
1403 Object id = jv2vobj.get(jvobj);
1406 return id.toString();
1408 // check string ID mappings
1409 if (jvids2vobj != null && jvobj instanceof String)
1411 id = jvids2vobj.get(jvobj);
1415 return id.toString();
1417 // give up and warn that something has gone wrong
1418 warn("Cannot find ID for object in external mapping : " + jvobj);
1424 * return local jalview object mapped to ID, if it exists
1428 * @return null or object bound to idcode
1430 private Object retrieveExistingObj(String idcode)
1432 if (idcode != null && vobj2jv != null)
1434 return vobj2jv.get(idcode);
1440 * binding from ID strings from external mapping table to jalview data model
1443 private Hashtable vobj2jv;
1445 private Sequence createVamsasSequence(String id, SequenceI jds)
1447 return createVamsasSequence(true, id, jds, null);
1450 private Sequence createVamsasSequence(boolean recurse, String id,
1451 SequenceI jds, SequenceI parentseq)
1453 Sequence vamsasSeq = new Sequence();
1454 vamsasSeq.setId(id);
1455 vamsasSeq.setName(jds.getName());
1456 vamsasSeq.setSequence(jds.getSequenceAsString());
1457 vamsasSeq.setDescription(jds.getDescription());
1458 jalview.datamodel.DBRefEntry[] dbrefs = null;
1459 if (jds.getDatasetSequence() != null)
1461 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
1462 if (jds.getDatasetSequence().getDBRef() != null)
1464 dbrefs = jds.getDatasetSequence().getDBRef();
1469 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
1470 // dataset sequences only
1471 dbrefs = jds.getDBRef();
1475 for (int d = 0; d < dbrefs.length; d++)
1477 DBRef dbref = new DBRef();
1478 dbref.setSource(dbrefs[d].getSource());
1479 dbref.setVersion(dbrefs[d].getVersion());
1480 dbref.setAccessionId(dbrefs[d].getAccessionId());
1481 if (dbrefs[d].hasMap())
1483 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
1485 dbref.setMapping(mp);
1487 vamsasSeq.addDBRef(dbref);
1493 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
1494 SequenceI parentseq, SequenceI jds, boolean recurse)
1497 if (jmp.getMap() != null)
1501 jalview.util.MapList mlst = jmp.getMap();
1502 int r[] = mlst.getFromRanges();
1503 for (int s = 0; s < r.length; s += 2)
1505 MapListFrom mfrom = new MapListFrom();
1506 mfrom.setStart(r[s]);
1507 mfrom.setEnd(r[s + 1]);
1508 mp.addMapListFrom(mfrom);
1510 r = mlst.getToRanges();
1511 for (int s = 0; s < r.length; s += 2)
1513 MapListTo mto = new MapListTo();
1515 mto.setEnd(r[s + 1]);
1516 mp.addMapListTo(mto);
1518 mp.setMapFromUnit(mlst.getFromRatio());
1519 mp.setMapToUnit(mlst.getToRatio());
1520 if (jmp.getTo() != null)
1522 MappingChoice mpc = new MappingChoice();
1524 && (parentseq != jmp.getTo() || parentseq
1525 .getDatasetSequence() != jmp.getTo()))
1527 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
1533 SequenceI ps = null;
1534 if (parentseq != jmp.getTo()
1535 && parentseq.getDatasetSequence() != jmp.getTo())
1537 // chaining dbref rather than a handshaking one
1538 jmpid = seqHash(ps = jmp.getTo());
1542 jmpid = seqHash(ps = parentseq);
1544 mpc.setDseqFor(jmpid);
1545 if (!seqRefIds.containsKey(mpc.getDseqFor()))
1547 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
1548 seqRefIds.put(mpc.getDseqFor(), ps);
1552 jalview.bin.Cache.log.debug("reusing DseqFor ID");
1555 mp.setMappingChoice(mpc);
1561 String SetUserColourScheme(jalview.schemes.ColourSchemeI cs,
1562 Vector userColours, JalviewModelSequence jms)
1565 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
1566 boolean newucs = false;
1567 if (!userColours.contains(ucs))
1569 userColours.add(ucs);
1572 id = "ucs" + userColours.indexOf(ucs);
1575 // actually create the scheme's entry in the XML model
1576 java.awt.Color[] colours = ucs.getColours();
1577 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
1578 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
1580 for (int i = 0; i < colours.length; i++)
1582 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1583 col.setName(ResidueProperties.aa[i]);
1584 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1585 jbucs.addColour(col);
1587 if (ucs.getLowerCaseColours() != null)
1589 colours = ucs.getLowerCaseColours();
1590 for (int i = 0; i < colours.length; i++)
1592 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
1593 col.setName(ResidueProperties.aa[i].toLowerCase());
1594 col.setRGB(jalview.util.Format.getHexString(colours[i]));
1595 jbucs.addColour(col);
1600 uc.setUserColourScheme(jbucs);
1601 jms.addUserColours(uc);
1607 jalview.schemes.UserColourScheme GetUserColourScheme(
1608 JalviewModelSequence jms, String id)
1610 UserColours[] uc = jms.getUserColours();
1611 UserColours colours = null;
1613 for (int i = 0; i < uc.length; i++)
1615 if (uc[i].getId().equals(id))
1623 java.awt.Color[] newColours = new java.awt.Color[24];
1625 for (int i = 0; i < 24; i++)
1627 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1628 .getUserColourScheme().getColour(i).getRGB(), 16));
1631 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
1634 if (colours.getUserColourScheme().getColourCount() > 24)
1636 newColours = new java.awt.Color[23];
1637 for (int i = 0; i < 23; i++)
1639 newColours[i] = new java.awt.Color(Integer.parseInt(colours
1640 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
1642 ucs.setLowerCaseColours(newColours);
1649 * contains last error message (if any) encountered by XML loader.
1651 String errorMessage = null;
1654 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
1655 * exceptions are raised during project XML parsing
1657 public boolean attemptversion1parse = true;
1660 * Load a jalview project archive from a jar file
1663 * - HTTP URL or filename
1665 public AlignFrame LoadJalviewAlign(final String file)
1668 jalview.gui.AlignFrame af = null;
1672 // create list to store references for any new Jmol viewers created
1673 newStructureViewers=new Vector<AppJmol>();
1674 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
1675 // Workaround is to make sure caller implements the JarInputStreamProvider
1677 // so we can re-open the jar input stream for each entry.
1679 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
1680 af = LoadJalviewAlign(jprovider);
1682 } catch (MalformedURLException e)
1684 errorMessage = "Invalid URL format for '" + file + "'";
1690 SwingUtilities.invokeAndWait(new Runnable()
1694 setLoadingFinishedForNewStructureViewers();
1697 } catch (Exception x)
1705 private jarInputStreamProvider createjarInputStreamProvider(
1706 final String file) throws MalformedURLException
1709 errorMessage = null;
1710 uniqueSetSuffix = null;
1712 viewportsAdded = null;
1713 frefedSequence = null;
1715 if (file.startsWith("http://"))
1717 url = new URL(file);
1719 final URL _url = url;
1720 return new jarInputStreamProvider()
1724 public JarInputStream getJarInputStream() throws IOException
1728 return new JarInputStream(_url.openStream());
1732 return new JarInputStream(new FileInputStream(file));
1737 public String getFilename()
1745 * Recover jalview session from a jalview project archive. Caller may
1746 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
1747 * themselves. Any null fields will be initialised with default values,
1748 * non-null fields are left alone.
1753 public AlignFrame LoadJalviewAlign(final jarInputStreamProvider jprovider)
1755 errorMessage = null;
1756 if (uniqueSetSuffix == null)
1758 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
1760 if (seqRefIds == null)
1762 seqRefIds = new Hashtable();
1764 if (viewportsAdded == null)
1766 viewportsAdded = new Hashtable();
1768 if (frefedSequence == null)
1770 frefedSequence = new Vector();
1773 jalview.gui.AlignFrame af = null;
1774 Hashtable gatherToThisFrame = new Hashtable();
1775 final String file = jprovider.getFilename();
1778 JarInputStream jin = null;
1779 JarEntry jarentry = null;
1784 jin = jprovider.getJarInputStream();
1785 for (int i = 0; i < entryCount; i++)
1787 jarentry = jin.getNextJarEntry();
1790 if (jarentry != null && jarentry.getName().endsWith(".xml"))
1792 InputStreamReader in = new InputStreamReader(jin, "UTF-8");
1793 JalviewModel object = new JalviewModel();
1795 Unmarshaller unmar = new Unmarshaller(object);
1796 unmar.setValidation(false);
1797 object = (JalviewModel) unmar.unmarshal(in);
1798 if (true) // !skipViewport(object))
1800 af = LoadFromObject(object, file, true, jprovider);
1801 if (af.viewport.gatherViewsHere)
1803 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
1808 else if (jarentry != null)
1810 // Some other file here.
1813 } while (jarentry != null);
1814 resolveFrefedSequences();
1815 } catch (java.io.FileNotFoundException ex)
1817 ex.printStackTrace();
1818 errorMessage = "Couldn't locate Jalview XML file : " + file;
1819 System.err.println("Exception whilst loading jalview XML file : "
1821 } catch (java.net.UnknownHostException ex)
1823 ex.printStackTrace();
1824 errorMessage = "Couldn't locate Jalview XML file : " + file;
1825 System.err.println("Exception whilst loading jalview XML file : "
1827 } catch (Exception ex)
1829 System.err.println("Parsing as Jalview Version 2 file failed.");
1830 ex.printStackTrace(System.err);
1831 if (attemptversion1parse)
1833 // Is Version 1 Jar file?
1836 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
1837 } catch (Exception ex2)
1839 System.err.println("Exception whilst loading as jalviewXMLV1:");
1840 ex2.printStackTrace();
1844 if (Desktop.instance != null)
1846 Desktop.instance.stopLoading();
1850 System.out.println("Successfully loaded archive file");
1853 ex.printStackTrace();
1855 System.err.println("Exception whilst loading jalview XML file : "
1857 } catch (OutOfMemoryError e)
1859 // Don't use the OOM Window here
1860 errorMessage = "Out of memory loading jalview XML file";
1861 System.err.println("Out of memory whilst loading jalview XML file");
1862 e.printStackTrace();
1865 if (Desktop.instance != null)
1867 Desktop.instance.stopLoading();
1870 Enumeration en = gatherToThisFrame.elements();
1871 while (en.hasMoreElements())
1873 Desktop.instance.gatherViews((AlignFrame) en.nextElement());
1875 if (errorMessage != null)
1883 * check errorMessage for a valid error message and raise an error box in the
1884 * GUI or write the current errorMessage to stderr and then clear the error
1887 protected void reportErrors()
1889 reportErrors(false);
1892 protected void reportErrors(final boolean saving)
1894 if (errorMessage != null)
1896 final String finalErrorMessage = errorMessage;
1899 javax.swing.SwingUtilities.invokeLater(new Runnable()
1904 JOptionPane.showInternalMessageDialog(Desktop.desktop,
1905 finalErrorMessage, "Error "
1906 + (saving ? "saving" : "loading")
1907 + " Jalview file", JOptionPane.WARNING_MESSAGE);
1913 System.err.println("Problem loading Jalview file: " + errorMessage);
1916 errorMessage = null;
1919 Hashtable alreadyLoadedPDB;
1922 * when set, local views will be updated from view stored in JalviewXML
1923 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
1924 * sync if this is set to true.
1926 private final boolean updateLocalViews = false;
1928 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
1930 if (alreadyLoadedPDB == null)
1931 alreadyLoadedPDB = new Hashtable();
1933 if (alreadyLoadedPDB.containsKey(pdbId))
1934 return alreadyLoadedPDB.get(pdbId).toString();
1938 JarInputStream jin = jprovider.getJarInputStream();
1940 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
1941 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
1942 * FileInputStream(jprovider)); }
1945 JarEntry entry = null;
1948 entry = jin.getNextJarEntry();
1949 } while (entry != null && !entry.getName().equals(pdbId));
1952 BufferedReader in = new BufferedReader(new InputStreamReader(jin));
1953 File outFile = File.createTempFile("jalview_pdb", ".txt");
1954 outFile.deleteOnExit();
1955 PrintWriter out = new PrintWriter(new FileOutputStream(outFile));
1958 while ((data = in.readLine()) != null)
1965 } catch (Exception foo)
1970 String t = outFile.getAbsolutePath();
1971 alreadyLoadedPDB.put(pdbId, t);
1976 warn("Couldn't find PDB file entry in Jalview Jar for " + pdbId);
1978 } catch (Exception ex)
1980 ex.printStackTrace();
1986 private class JvAnnotRow
1988 public JvAnnotRow(int i, AlignmentAnnotation jaa)
1995 * persisted version of annotation row from which to take vis properties
1997 public jalview.datamodel.AlignmentAnnotation template;
2000 * original position of the annotation row in the alignment
2006 * Load alignment frame from jalview XML DOM object
2011 * filename source string
2012 * @param loadTreesAndStructures
2013 * when false only create Viewport
2015 * data source provider
2016 * @return alignment frame created from view stored in DOM
2018 AlignFrame LoadFromObject(JalviewModel object, String file,
2019 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2021 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2022 Sequence[] vamsasSeq = vamsasSet.getSequence();
2024 JalviewModelSequence jms = object.getJalviewModelSequence();
2026 Viewport view = jms.getViewport(0);
2027 // ////////////////////////////////
2030 Vector hiddenSeqs = null;
2031 jalview.datamodel.Sequence jseq;
2033 ArrayList tmpseqs = new ArrayList();
2035 boolean multipleView = false;
2037 JSeq[] JSEQ = object.getJalviewModelSequence().getJSeq();
2038 int vi = 0; // counter in vamsasSeq array
2039 for (int i = 0; i < JSEQ.length; i++)
2041 String seqId = JSEQ[i].getId();
2043 if (seqRefIds.get(seqId) != null)
2045 tmpseqs.add(seqRefIds.get(seqId));
2046 multipleView = true;
2050 jseq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2051 vamsasSeq[vi].getSequence());
2052 jseq.setDescription(vamsasSeq[vi].getDescription());
2053 jseq.setStart(JSEQ[i].getStart());
2054 jseq.setEnd(JSEQ[i].getEnd());
2055 jseq.setVamsasId(uniqueSetSuffix + seqId);
2056 seqRefIds.put(vamsasSeq[vi].getId(), jseq);
2061 if (JSEQ[i].getHidden())
2063 if (hiddenSeqs == null)
2065 hiddenSeqs = new Vector();
2068 hiddenSeqs.addElement(seqRefIds.get(seqId));
2074 // Create the alignment object from the sequence set
2075 // ///////////////////////////////
2076 jalview.datamodel.Sequence[] orderedSeqs = new jalview.datamodel.Sequence[tmpseqs
2079 tmpseqs.toArray(orderedSeqs);
2081 jalview.datamodel.Alignment al = new jalview.datamodel.Alignment(
2084 // / Add the alignment properties
2085 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2087 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2088 al.setProperty(ssp.getKey(), ssp.getValue());
2092 // SequenceFeatures are added to the DatasetSequence,
2093 // so we must create or recover the dataset before loading features
2094 // ///////////////////////////////
2095 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2097 // older jalview projects do not have a dataset id.
2098 al.setDataset(null);
2102 recoverDatasetFor(vamsasSet, al);
2104 // ///////////////////////////////
2106 Hashtable pdbloaded = new Hashtable();
2109 // load sequence features, database references and any associated PDB
2110 // structures for the alignment
2111 for (int i = 0; i < vamsasSeq.length; i++)
2113 if (JSEQ[i].getFeaturesCount() > 0)
2115 Features[] features = JSEQ[i].getFeatures();
2116 for (int f = 0; f < features.length; f++)
2118 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2119 features[f].getType(), features[f].getDescription(),
2120 features[f].getStatus(), features[f].getBegin(),
2121 features[f].getEnd(), features[f].getFeatureGroup());
2123 sf.setScore(features[f].getScore());
2124 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2126 OtherData keyValue = features[f].getOtherData(od);
2127 if (keyValue.getKey().startsWith("LINK"))
2129 sf.addLink(keyValue.getValue());
2133 sf.setValue(keyValue.getKey(), keyValue.getValue());
2138 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2141 if (vamsasSeq[i].getDBRefCount() > 0)
2143 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2145 if (JSEQ[i].getPdbidsCount() > 0)
2147 Pdbids[] ids = JSEQ[i].getPdbids();
2148 for (int p = 0; p < ids.length; p++)
2150 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2151 entry.setId(ids[p].getId());
2152 entry.setType(ids[p].getType());
2153 if (ids[p].getFile() != null)
2155 if (!pdbloaded.containsKey(ids[p].getFile()))
2157 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2161 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2165 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2169 } // end !multipleview
2171 // ///////////////////////////////
2172 // LOAD SEQUENCE MAPPINGS
2174 if (vamsasSet.getAlcodonFrameCount() > 0)
2176 // TODO Potentially this should only be done once for all views of an
2178 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2179 for (int i = 0; i < alc.length; i++)
2181 jalview.datamodel.AlignedCodonFrame cf = new jalview.datamodel.AlignedCodonFrame(
2182 alc[i].getAlcodonCount());
2183 if (alc[i].getAlcodonCount() > 0)
2185 Alcodon[] alcods = alc[i].getAlcodon();
2186 for (int p = 0; p < cf.codons.length; p++)
2188 if (alcods[p].hasPos1() && alcods[p].hasPos2()
2189 && alcods[p].hasPos3())
2191 // translated codons require three valid positions
2192 cf.codons[p] = new int[3];
2193 cf.codons[p][0] = (int) alcods[p].getPos1();
2194 cf.codons[p][1] = (int) alcods[p].getPos2();
2195 cf.codons[p][2] = (int) alcods[p].getPos3();
2199 cf.codons[p] = null;
2203 if (alc[i].getAlcodMapCount() > 0)
2205 AlcodMap[] maps = alc[i].getAlcodMap();
2206 for (int m = 0; m < maps.length; m++)
2208 SequenceI dnaseq = (SequenceI) seqRefIds
2209 .get(maps[m].getDnasq());
2211 jalview.datamodel.Mapping mapping = null;
2212 // attach to dna sequence reference.
2213 if (maps[m].getMapping() != null)
2215 mapping = addMapping(maps[m].getMapping());
2219 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2224 frefedSequence.add(new Object[]
2225 { maps[m].getDnasq(), cf, mapping });
2229 al.addCodonFrame(cf);
2234 // ////////////////////////////////
2236 ArrayList<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2238 * store any annotations which forward reference a group's ID
2240 Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, ArrayList<jalview.datamodel.AlignmentAnnotation>>();
2242 if (vamsasSet.getAnnotationCount() > 0)
2244 Annotation[] an = vamsasSet.getAnnotation();
2246 for (int i = 0; i < an.length; i++)
2249 * test if annotation is automatically calculated for this view only
2251 boolean autoForView = false;
2252 if (an[i].getLabel().equals("Quality")
2253 || an[i].getLabel().equals("Conservation")
2254 || an[i].getLabel().equals("Consensus"))
2256 // Kludge for pre 2.5 projects which lacked the autocalculated flag
2258 if (!an[i].hasAutoCalculated())
2260 an[i].setAutoCalculated(true);
2264 || (an[i].hasAutoCalculated() && an[i].isAutoCalculated()))
2266 // remove ID - we don't recover annotation from other views for
2267 // view-specific annotation
2271 // set visiblity for other annotation in this view
2272 if (an[i].getId() != null
2273 && annotationIds.containsKey(an[i].getId()))
2275 jalview.datamodel.AlignmentAnnotation jda = (jalview.datamodel.AlignmentAnnotation) annotationIds
2276 .get(an[i].getId());
2277 // in principle Visible should always be true for annotation displayed
2278 // in multiple views
2279 if (an[i].hasVisible())
2280 jda.visible = an[i].getVisible();
2282 al.addAnnotation(jda);
2286 // Construct new annotation from model.
2287 AnnotationElement[] ae = an[i].getAnnotationElement();
2288 jalview.datamodel.Annotation[] anot = null;
2289 java.awt.Color firstColour = null;
2291 if (!an[i].getScoreOnly())
2293 anot = new jalview.datamodel.Annotation[al.getWidth()];
2294 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
2296 anpos = ae[aa].getPosition();
2298 if (anpos >= anot.length)
2301 anot[anpos] = new jalview.datamodel.Annotation(
2303 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
2304 (ae[aa].getSecondaryStructure() == null || ae[aa]
2305 .getSecondaryStructure().length() == 0) ? ' '
2306 : ae[aa].getSecondaryStructure().charAt(0),
2310 // JBPNote: Consider verifying dataflow for IO of secondary
2311 // structure annotation read from Stockholm files
2312 // this was added to try to ensure that
2313 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
2315 // anot[ae[aa].getPosition()].displayCharacter = "";
2317 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
2318 if (firstColour == null)
2320 firstColour = anot[anpos].colour;
2324 jalview.datamodel.AlignmentAnnotation jaa = null;
2326 if (an[i].getGraph())
2328 float llim = 0, hlim = 0;
2329 // if (autoForView || an[i].isAutoCalculated()) {
2332 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2333 an[i].getDescription(), anot, llim, hlim,
2334 an[i].getGraphType());
2336 jaa.graphGroup = an[i].getGraphGroup();
2337 jaa._linecolour = firstColour;
2338 if (an[i].getThresholdLine() != null)
2340 jaa.setThreshold(new jalview.datamodel.GraphLine(an[i]
2341 .getThresholdLine().getValue(), an[i]
2342 .getThresholdLine().getLabel(), new java.awt.Color(
2343 an[i].getThresholdLine().getColour())));
2346 if (autoForView || an[i].isAutoCalculated())
2348 // Hardwire the symbol display line to ensure that labels for
2349 // histograms are displayed
2355 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
2356 an[i].getDescription(), anot);
2357 jaa._linecolour = firstColour;
2359 // register new annotation
2360 if (an[i].getId() != null)
2362 annotationIds.put(an[i].getId(), jaa);
2363 jaa.annotationId = an[i].getId();
2365 // recover sequence association
2366 if (an[i].getSequenceRef() != null)
2368 if (al.findName(an[i].getSequenceRef()) != null)
2370 jaa.createSequenceMapping(al.findName(an[i].getSequenceRef()),
2372 al.findName(an[i].getSequenceRef()).addAlignmentAnnotation(jaa);
2375 // and make a note of any group association
2376 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
2378 ArrayList<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
2379 .get(an[i].getGroupRef());
2382 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
2383 groupAnnotRefs.put(an[i].getGroupRef(), aal);
2388 if (an[i].hasScore())
2390 jaa.setScore(an[i].getScore());
2392 if (an[i].hasVisible())
2393 jaa.visible = an[i].getVisible();
2395 if (an[i].hasCentreColLabels())
2396 jaa.centreColLabels = an[i].getCentreColLabels();
2398 if (an[i].hasScaleColLabels())
2400 jaa.scaleColLabel = an[i].getScaleColLabels();
2402 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
2404 // newer files have an 'autoCalculated' flag and store calculation
2405 // state in viewport properties
2406 jaa.autoCalculated = true; // means annotation will be marked for
2407 // update at end of load.
2409 if (an[i].hasGraphHeight())
2411 jaa.graphHeight = an[i].getGraphHeight();
2413 if (an[i].hasBelowAlignment())
2415 jaa.belowAlignment = an[i].isBelowAlignment();
2417 jaa.setCalcId(an[i].getCalcId());
2419 if (jaa.autoCalculated)
2421 autoAlan.add(new JvAnnotRow(i, jaa));
2424 // if (!autoForView)
2426 // add autocalculated group annotation and any user created annotation
2428 al.addAnnotation(jaa);
2433 // ///////////////////////
2435 // Create alignment markup and styles for this view
2436 if (jms.getJGroupCount() > 0)
2438 JGroup[] groups = jms.getJGroup();
2440 for (int i = 0; i < groups.length; i++)
2442 ColourSchemeI cs = null;
2444 if (groups[i].getColour() != null)
2446 if (groups[i].getColour().startsWith("ucs"))
2448 cs = GetUserColourScheme(jms, groups[i].getColour());
2452 cs = ColourSchemeProperty.getColour(al, groups[i].getColour());
2457 cs.setThreshold(groups[i].getPidThreshold(), true);
2461 Vector seqs = new Vector();
2463 for (int s = 0; s < groups[i].getSeqCount(); s++)
2465 String seqId = groups[i].getSeq(s) + "";
2466 jalview.datamodel.SequenceI ts = (jalview.datamodel.SequenceI) seqRefIds
2471 seqs.addElement(ts);
2475 if (seqs.size() < 1)
2480 jalview.datamodel.SequenceGroup sg = new jalview.datamodel.SequenceGroup(
2481 seqs, groups[i].getName(), cs, groups[i].getDisplayBoxes(),
2482 groups[i].getDisplayText(), groups[i].getColourText(),
2483 groups[i].getStart(), groups[i].getEnd());
2485 sg.setOutlineColour(new java.awt.Color(groups[i].getOutlineColour()));
2487 sg.textColour = new java.awt.Color(groups[i].getTextCol1());
2488 sg.textColour2 = new java.awt.Color(groups[i].getTextCol2());
2489 sg.setShowNonconserved(groups[i].hasShowUnconserved() ? groups[i]
2490 .isShowUnconserved() : false);
2491 sg.thresholdTextColour = groups[i].getTextColThreshold();
2492 if (groups[i].hasShowConsensusHistogram())
2494 sg.setShowConsensusHistogram(groups[i].isShowConsensusHistogram());
2497 if (groups[i].hasShowSequenceLogo())
2499 sg.setshowSequenceLogo(groups[i].isShowSequenceLogo());
2501 if (groups[i].hasNormaliseSequenceLogo())
2503 sg.setNormaliseSequenceLogo(groups[i].isNormaliseSequenceLogo());
2505 if (groups[i].hasIgnoreGapsinConsensus())
2507 sg.setIgnoreGapsConsensus(groups[i].getIgnoreGapsinConsensus());
2509 if (groups[i].getConsThreshold() != 0)
2511 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
2512 "All", ResidueProperties.propHash, 3,
2513 sg.getSequences(null), 0, sg.getWidth() - 1);
2515 c.verdict(false, 25);
2516 sg.cs.setConservation(c);
2519 if (groups[i].getId() != null && groupAnnotRefs.size() > 0)
2521 // re-instate unique group/annotation row reference
2522 ArrayList<jalview.datamodel.AlignmentAnnotation> jaal = groupAnnotRefs
2523 .get(groups[i].getId());
2526 for (jalview.datamodel.AlignmentAnnotation jaa : jaal)
2529 if (jaa.autoCalculated)
2531 // match up and try to set group autocalc alignment row for this
2533 if (jaa.label.startsWith("Consensus for "))
2535 sg.setConsensus(jaa);
2537 // match up and try to set group autocalc alignment row for this
2539 if (jaa.label.startsWith("Conservation for "))
2541 sg.setConservationRow(jaa);
2552 // ///////////////////////////////
2555 // If we just load in the same jar file again, the sequenceSetId
2556 // will be the same, and we end up with multiple references
2557 // to the same sequenceSet. We must modify this id on load
2558 // so that each load of the file gives a unique id
2559 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
2560 String viewId = (view.getId() == null ? null : view.getId()
2562 AlignFrame af = null;
2563 AlignViewport av = null;
2564 // now check to see if we really need to create a new viewport.
2565 if (multipleView && viewportsAdded.size() == 0)
2567 // We recovered an alignment for which a viewport already exists.
2568 // TODO: fix up any settings necessary for overlaying stored state onto
2569 // state recovered from another document. (may not be necessary).
2570 // we may need a binding from a viewport in memory to one recovered from
2572 // and then recover its containing af to allow the settings to be applied.
2573 // TODO: fix for vamsas demo
2575 .println("About to recover a viewport for existing alignment: Sequence set ID is "
2577 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
2578 if (seqsetobj != null)
2580 if (seqsetobj instanceof String)
2582 uniqueSeqSetId = (String) seqsetobj;
2584 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
2590 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
2595 AlignmentPanel ap = null;
2596 boolean isnewview = true;
2599 // Check to see if this alignment already has a view id == viewId
2600 jalview.gui.AlignmentPanel views[] = Desktop
2601 .getAlignmentPanels(uniqueSeqSetId);
2602 if (views != null && views.length > 0)
2604 for (int v = 0; v < views.length; v++)
2606 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
2608 // recover the existing alignpanel, alignframe, viewport
2609 af = views[v].alignFrame;
2612 // TODO: could even skip resetting view settings if we don't want to
2613 // change the local settings from other jalview processes
2622 af = loadViewport(file, JSEQ, hiddenSeqs, al, jms, view,
2623 uniqueSeqSetId, viewId, autoAlan);
2628 // /////////////////////////////////////
2629 if (loadTreesAndStructures && jms.getTreeCount() > 0)
2633 for (int t = 0; t < jms.getTreeCount(); t++)
2636 Tree tree = jms.getTree(t);
2638 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
2641 tp = af.ShowNewickTree(
2642 new jalview.io.NewickFile(tree.getNewick()),
2643 tree.getTitle(), tree.getWidth(), tree.getHeight(),
2644 tree.getXpos(), tree.getYpos());
2645 if (tree.getId() != null)
2647 // perhaps bind the tree id to something ?
2652 // update local tree attributes ?
2653 // TODO: should check if tp has been manipulated by user - if so its
2654 // settings shouldn't be modified
2655 tp.setTitle(tree.getTitle());
2656 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
2657 .getWidth(), tree.getHeight()));
2658 tp.av = av; // af.viewport; // TODO: verify 'associate with all
2661 tp.treeCanvas.av = av; // af.viewport;
2662 tp.treeCanvas.ap = ap; // af.alignPanel;
2667 warn("There was a problem recovering stored Newick tree: \n"
2668 + tree.getNewick());
2672 tp.fitToWindow.setState(tree.getFitToWindow());
2673 tp.fitToWindow_actionPerformed(null);
2675 if (tree.getFontName() != null)
2677 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
2678 .getFontStyle(), tree.getFontSize()));
2682 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
2683 .getFontStyle(), tree.getFontSize()));
2686 tp.showPlaceholders(tree.getMarkUnlinked());
2687 tp.showBootstrap(tree.getShowBootstrap());
2688 tp.showDistances(tree.getShowDistances());
2690 tp.treeCanvas.threshold = tree.getThreshold();
2692 if (tree.getCurrentTree())
2694 af.viewport.setCurrentTree(tp.getTree());
2698 } catch (Exception ex)
2700 ex.printStackTrace();
2704 // //LOAD STRUCTURES
2705 if (loadTreesAndStructures)
2707 // run through all PDB ids on the alignment, and collect mappings between
2708 // jmol view ids and all sequences referring to it
2709 Hashtable<String, Object[]> jmolViewIds = new Hashtable();
2711 for (int i = 0; i < JSEQ.length; i++)
2713 if (JSEQ[i].getPdbidsCount() > 0)
2715 Pdbids[] ids = JSEQ[i].getPdbids();
2716 for (int p = 0; p < ids.length; p++)
2718 for (int s = 0; s < ids[p].getStructureStateCount(); s++)
2720 // check to see if we haven't already created this structure view
2721 String sviewid = (ids[p].getStructureState(s).getViewId() == null) ? null
2722 : ids[p].getStructureState(s).getViewId()
2724 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
2725 // Originally : ids[p].getFile()
2726 // : TODO: verify external PDB file recovery still works in normal
2727 // jalview project load
2728 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
2729 jpdb.setId(ids[p].getId());
2731 int x = ids[p].getStructureState(s).getXpos();
2732 int y = ids[p].getStructureState(s).getYpos();
2733 int width = ids[p].getStructureState(s).getWidth();
2734 int height = ids[p].getStructureState(s).getHeight();
2736 // Probably don't need to do this anymore...
2737 // Desktop.desktop.getComponentAt(x, y);
2738 // TODO: NOW: check that this recovers the PDB file correctly.
2739 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
2740 jalview.datamodel.SequenceI seq = (jalview.datamodel.SequenceI) seqRefIds
2741 .get(JSEQ[i].getId() + "");
2742 if (sviewid == null)
2744 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
2747 if (!jmolViewIds.containsKey(sviewid))
2749 jmolViewIds.put(sviewid, new Object[]
2751 { x, y, width, height }, "",
2752 new Hashtable<String, Object[]>(), new boolean[]
2753 { false, false, true } });
2754 // Legacy pre-2.7 conversion JAL-823 :
2755 // do not assume any view has to be linked for colour by
2759 // assemble String[] { pdb files }, String[] { id for each
2760 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2761 // seqs_file 2}, boolean[] {
2762 // linkAlignPanel,superposeWithAlignpanel}} from hash
2763 Object[] jmoldat = jmolViewIds.get(sviewid);
2764 ((boolean[]) jmoldat[3])[0] |= ids[p].getStructureState(s)
2765 .hasAlignwithAlignPanel() ? ids[p].getStructureState(
2766 s).getAlignwithAlignPanel() : false;
2767 // never colour by linked panel if not specified
2768 ((boolean[]) jmoldat[3])[1] |= ids[p].getStructureState(s)
2769 .hasColourwithAlignPanel() ? ids[p]
2770 .getStructureState(s).getColourwithAlignPanel()
2772 // default for pre-2.7 projects is that Jmol colouring is enabled
2773 ((boolean[]) jmoldat[3])[2] &= ids[p].getStructureState(s)
2774 .hasColourByJmol() ? ids[p].getStructureState(s)
2775 .getColourByJmol() : true;
2777 if (((String) jmoldat[1]).length() < ids[p]
2778 .getStructureState(s).getContent().length())
2781 jmoldat[1] = ids[p].getStructureState(s).getContent();
2784 if (ids[p].getFile() != null)
2786 File mapkey = new File(ids[p].getFile());
2787 Object[] seqstrmaps = (Object[]) ((Hashtable) jmoldat[2])
2789 if (seqstrmaps == null)
2791 ((Hashtable) jmoldat[2]).put(mapkey,
2792 seqstrmaps = new Object[]
2793 { pdbFile, ids[p].getId(), new Vector(),
2796 if (!((Vector) seqstrmaps[2]).contains(seq))
2798 ((Vector) seqstrmaps[2]).addElement(seq);
2799 // ((Vector)seqstrmaps[3]).addElement(n) :
2800 // in principle, chains
2801 // should be stored here : do we need to
2802 // TODO: store and recover seq/pdb_id :
2808 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");
2817 // Instantiate the associated Jmol views
2818 for (Entry<String, Object[]> entry : jmolViewIds.entrySet())
2820 String sviewid = entry.getKey();
2821 Object[] svattrib = entry.getValue();
2822 int[] geom = (int[]) svattrib[0];
2823 String state = (String) svattrib[1];
2824 Hashtable<File, Object[]> oldFiles = (Hashtable<File, Object[]>) svattrib[2];
2825 final boolean useinJmolsuperpos = ((boolean[]) svattrib[3])[0], usetoColourbyseq = ((boolean[]) svattrib[3])[1], jmolColouring = ((boolean[]) svattrib[3])[2];
2826 int x = geom[0], y = geom[1], width = geom[2], height = geom[3];
2827 // collate the pdbfile -> sequence mappings from this view
2828 Vector<String> pdbfilenames = new Vector<String>();
2829 Vector<SequenceI[]> seqmaps = new Vector<SequenceI[]>();
2830 Vector<String> pdbids = new Vector<String>();
2832 // Search to see if we've already created this Jmol view
2833 AppJmol comp = null;
2834 JInternalFrame[] frames = null;
2839 frames = Desktop.desktop.getAllFrames();
2840 } catch (ArrayIndexOutOfBoundsException e)
2842 // occasional No such child exceptions are thrown here...
2847 } catch (Exception f)
2852 } while (frames == null);
2853 // search for any Jmol windows already open from other
2854 // alignment views that exactly match the stored structure state
2855 for (int f = 0; comp == null && f < frames.length; f++)
2857 if (frames[f] instanceof AppJmol)
2860 && ((AppJmol) frames[f]).getViewId().equals(sviewid))
2862 // post jalview 2.4 schema includes structure view id
2863 comp = (AppJmol) frames[f];
2865 else if (frames[f].getX() == x && frames[f].getY() == y
2866 && frames[f].getHeight() == height
2867 && frames[f].getWidth() == width)
2869 comp = (AppJmol) frames[f];
2876 // create a new Jmol window.
2877 // First parse the Jmol state to translate filenames loaded into the
2878 // view, and record the order in which files are shown in the Jmol
2879 // view, so we can add the sequence mappings in same order.
2880 StringBuffer newFileLoc = null;
2881 int cp = 0, ncp, ecp;
2882 while ((ncp = state.indexOf("load ", cp)) > -1)
2884 if (newFileLoc == null)
2886 newFileLoc = new StringBuffer();
2890 // look for next filename in load statement
2891 newFileLoc.append(state.substring(cp,
2892 ncp = (state.indexOf("\"", ncp + 1) + 1)));
2893 String oldfilenam = state.substring(ncp,
2894 ecp = state.indexOf("\"", ncp));
2895 // recover the new mapping data for this old filename
2896 // have to normalize filename - since Jmol and jalview do
2898 // translation differently.
2899 Object[] filedat = oldFiles.get(new File(oldfilenam));
2900 newFileLoc.append(Platform
2901 .escapeString((String) filedat[0]));
2902 pdbfilenames.addElement((String) filedat[0]);
2903 pdbids.addElement((String) filedat[1]);
2904 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2905 .toArray(new SequenceI[0]));
2906 newFileLoc.append("\"");
2907 cp = ecp + 1; // advance beyond last \" and set cursor so we can
2908 // look for next file statement.
2909 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
2913 // just append rest of state
2914 newFileLoc.append(state.substring(cp));
2919 .print("Ignoring incomplete Jmol state for PDB ids: ");
2920 newFileLoc = new StringBuffer(state);
2921 newFileLoc.append("; load append ");
2922 for (File id : oldFiles.keySet())
2924 // add this and any other pdb files that should be present in
2926 Object[] filedat = oldFiles.get(id);
2928 newFileLoc.append(((String) filedat[0]));
2929 pdbfilenames.addElement((String) filedat[0]);
2930 pdbids.addElement((String) filedat[1]);
2931 seqmaps.addElement(((Vector<SequenceI>) filedat[2])
2932 .toArray(new SequenceI[0]));
2933 newFileLoc.append(" \"");
2934 newFileLoc.append((String) filedat[0]);
2935 newFileLoc.append("\"");
2938 newFileLoc.append(";");
2941 if (newFileLoc != null)
2943 int histbug = newFileLoc.indexOf("history = ");
2945 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";",
2947 String val = (diff == -1) ? null : newFileLoc.substring(
2949 if (val != null && val.length() >= 4)
2951 if (val.contains("e"))
2953 if (val.trim().equals("true"))
2961 newFileLoc.replace(histbug, diff, val);
2964 // TODO: assemble String[] { pdb files }, String[] { id for each
2965 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
2966 // seqs_file 2}} from hash
2967 final String[] pdbf = pdbfilenames
2968 .toArray(new String[pdbfilenames.size()]), id = pdbids
2969 .toArray(new String[pdbids.size()]);
2970 final SequenceI[][] sq = seqmaps
2971 .toArray(new SequenceI[seqmaps.size()][]);
2972 final String fileloc = newFileLoc.toString(), vid = sviewid;
2973 final AlignFrame alf = af;
2974 final java.awt.Rectangle rect = new java.awt.Rectangle(x, y,
2978 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
2983 AppJmol sview = null;
2986 sview = new AppJmol(pdbf, id, sq, alf.alignPanel,
2987 useinJmolsuperpos, usetoColourbyseq,
2988 jmolColouring, fileloc, rect, vid);
2989 addNewStructureViewer(sview);
2990 } catch (OutOfMemoryError ex)
2992 new OOMWarning("restoring structure view for PDB id "
2993 + id, (OutOfMemoryError) ex.getCause());
2994 if (sview != null && sview.isVisible())
2996 sview.closeViewer();
2997 sview.setVisible(false);
3003 } catch (InvocationTargetException ex)
3005 warn("Unexpected error when opening Jmol view.", ex);
3007 } catch (InterruptedException e)
3009 // e.printStackTrace();
3015 // if (comp != null)
3017 // NOTE: if the jalview project is part of a shared session then
3018 // view synchronization should/could be done here.
3020 // add mapping for sequences in this view to an already open Jmol
3022 for (File id : oldFiles.keySet())
3024 // add this and any other pdb files that should be present in the
3026 Object[] filedat = oldFiles.get(id);
3027 String pdbFile = (String) filedat[0];
3028 SequenceI[] seq = ((Vector<SequenceI>) filedat[2])
3029 .toArray(new SequenceI[0]);
3030 comp.jmb.ssm.setMapping(seq, null, pdbFile,
3031 jalview.io.AppletFormatAdapter.FILE);
3032 comp.jmb.addSequenceForStructFile(pdbFile, seq);
3034 // and add the AlignmentPanel's reference to the Jmol view
3035 comp.addAlignmentPanel(ap);
3036 if (useinJmolsuperpos)
3038 comp.useAlignmentPanelForSuperposition(ap);
3042 comp.excludeAlignmentPanelForSuperposition(ap);
3044 if (usetoColourbyseq)
3046 comp.useAlignmentPanelForColourbyseq(ap, !jmolColouring);
3050 comp.excludeAlignmentPanelForColourbyseq(ap);
3056 // and finally return.
3059 Vector<AppJmol> newStructureViewers=null;
3060 protected void addNewStructureViewer(AppJmol sview)
3062 if (newStructureViewers!=null)
3064 sview.jmb.setFinishedLoadingFromArchive(false);
3065 newStructureViewers.add(sview);
3068 protected void setLoadingFinishedForNewStructureViewers()
3070 if (newStructureViewers!=null)
3072 for (AppJmol sview:newStructureViewers)
3074 sview.jmb.setFinishedLoadingFromArchive(true);
3076 newStructureViewers.clear();
3077 newStructureViewers=null;
3081 AlignFrame loadViewport(String file, JSeq[] JSEQ, Vector hiddenSeqs,
3082 Alignment al, JalviewModelSequence jms, Viewport view,
3083 String uniqueSeqSetId, String viewId,
3084 ArrayList<JvAnnotRow> autoAlan)
3086 AlignFrame af = null;
3087 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
3088 uniqueSeqSetId, viewId);
3090 af.setFileName(file, "Jalview");
3092 for (int i = 0; i < JSEQ.length; i++)
3094 af.viewport.setSequenceColour(af.viewport.getAlignment()
3095 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
3098 af.viewport.gatherViewsHere = view.getGatheredViews();
3100 if (view.getSequenceSetId() != null)
3102 jalview.gui.AlignViewport av = (jalview.gui.AlignViewport) viewportsAdded
3103 .get(uniqueSeqSetId);
3105 af.viewport.setSequenceSetId(uniqueSeqSetId);
3108 // propagate shared settings to this new view
3109 af.viewport.historyList = av.historyList;
3110 af.viewport.redoList = av.redoList;
3114 viewportsAdded.put(uniqueSeqSetId, af.viewport);
3116 // TODO: check if this method can be called repeatedly without
3117 // side-effects if alignpanel already registered.
3118 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
3120 // apply Hidden regions to view.
3121 if (hiddenSeqs != null)
3123 for (int s = 0; s < JSEQ.length; s++)
3125 jalview.datamodel.SequenceGroup hidden = new jalview.datamodel.SequenceGroup();
3127 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
3130 al.getSequenceAt(JSEQ[s].getHiddenSequences(r)), false);
3132 af.viewport.hideRepSequences(al.getSequenceAt(s), hidden);
3135 jalview.datamodel.SequenceI[] hseqs = new jalview.datamodel.SequenceI[hiddenSeqs
3138 for (int s = 0; s < hiddenSeqs.size(); s++)
3140 hseqs[s] = (jalview.datamodel.SequenceI) hiddenSeqs.elementAt(s);
3143 af.viewport.hideSequence(hseqs);
3146 // recover view properties and display parameters
3147 if (view.getViewName() != null)
3149 af.viewport.viewName = view.getViewName();
3150 af.setInitialTabVisible();
3152 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
3155 af.viewport.setShowAnnotation(view.getShowAnnotation());
3156 af.viewport.setAbovePIDThreshold(view.getPidSelected());
3158 af.viewport.setColourText(view.getShowColourText());
3160 af.viewport.setConservationSelected(view.getConservationSelected());
3161 af.viewport.setShowJVSuffix(view.getShowFullId());
3162 af.viewport.rightAlignIds = view.getRightAlignIds();
3163 af.viewport.setFont(new java.awt.Font(view.getFontName(), view
3164 .getFontStyle(), view.getFontSize()));
3165 af.alignPanel.fontChanged();
3166 af.viewport.setRenderGaps(view.getRenderGaps());
3167 af.viewport.setWrapAlignment(view.getWrapAlignment());
3168 af.alignPanel.setWrapAlignment(view.getWrapAlignment());
3169 af.viewport.setShowAnnotation(view.getShowAnnotation());
3170 af.alignPanel.setAnnotationVisible(view.getShowAnnotation());
3172 af.viewport.setShowBoxes(view.getShowBoxes());
3174 af.viewport.setShowText(view.getShowText());
3176 af.viewport.textColour = new java.awt.Color(view.getTextCol1());
3177 af.viewport.textColour2 = new java.awt.Color(view.getTextCol2());
3178 af.viewport.thresholdTextColour = view.getTextColThreshold();
3179 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
3180 .isShowUnconserved() : false);
3181 af.viewport.setStartRes(view.getStartRes());
3182 af.viewport.setStartSeq(view.getStartSeq());
3184 ColourSchemeI cs = null;
3185 // apply colourschemes
3186 if (view.getBgColour() != null)
3188 if (view.getBgColour().startsWith("ucs"))
3190 cs = GetUserColourScheme(jms, view.getBgColour());
3192 else if (view.getBgColour().startsWith("Annotation"))
3194 // int find annotation
3195 if (af.viewport.getAlignment().getAlignmentAnnotation() != null)
3197 for (int i = 0; i < af.viewport.getAlignment()
3198 .getAlignmentAnnotation().length; i++)
3200 if (af.viewport.getAlignment().getAlignmentAnnotation()[i].label
3201 .equals(view.getAnnotationColours().getAnnotation()))
3203 if (af.viewport.getAlignment().getAlignmentAnnotation()[i]
3204 .getThreshold() == null)
3206 af.viewport.getAlignment().getAlignmentAnnotation()[i]
3207 .setThreshold(new jalview.datamodel.GraphLine(view
3208 .getAnnotationColours().getThreshold(),
3209 "Threshold", java.awt.Color.black)
3214 if (view.getAnnotationColours().getColourScheme()
3217 cs = new AnnotationColourGradient(af.viewport
3218 .getAlignment().getAlignmentAnnotation()[i],
3219 new java.awt.Color(view.getAnnotationColours()
3220 .getMinColour()), new java.awt.Color(view
3221 .getAnnotationColours().getMaxColour()),
3222 view.getAnnotationColours().getAboveThreshold());
3224 else if (view.getAnnotationColours().getColourScheme()
3227 cs = new AnnotationColourGradient(af.viewport
3228 .getAlignment().getAlignmentAnnotation()[i],
3229 GetUserColourScheme(jms, view
3230 .getAnnotationColours().getColourScheme()),
3231 view.getAnnotationColours().getAboveThreshold());
3235 cs = new AnnotationColourGradient(af.viewport
3236 .getAlignment().getAlignmentAnnotation()[i],
3237 ColourSchemeProperty.getColour(al, view
3238 .getAnnotationColours().getColourScheme()),
3239 view.getAnnotationColours().getAboveThreshold());
3242 // Also use these settings for all the groups
3243 if (al.getGroups() != null)
3245 for (int g = 0; g < al.getGroups().size(); g++)
3247 jalview.datamodel.SequenceGroup sg = al.getGroups()
3257 * (view.getAnnotationColours().getColourScheme().equals("None"
3258 * )) { sg.cs = new AnnotationColourGradient(
3259 * af.viewport.getAlignment().getAlignmentAnnotation()[i], new
3260 * java.awt.Color(view.getAnnotationColours().
3261 * getMinColour()), new
3262 * java.awt.Color(view.getAnnotationColours().
3264 * view.getAnnotationColours().getAboveThreshold()); } else
3267 sg.cs = new AnnotationColourGradient(af.viewport
3268 .getAlignment().getAlignmentAnnotation()[i],
3269 sg.cs, view.getAnnotationColours()
3270 .getAboveThreshold());
3284 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
3289 cs.setThreshold(view.getPidThreshold(), true);
3290 cs.setConsensus(af.viewport.getSequenceConsensusHash());
3294 af.viewport.setGlobalColourScheme(cs);
3295 af.viewport.setColourAppliesToAllGroups(false);
3297 if (view.getConservationSelected() && cs != null)
3299 cs.setConservationInc(view.getConsThreshold());
3302 af.changeColour(cs);
3304 af.viewport.setColourAppliesToAllGroups(true);
3306 if (view.getShowSequenceFeatures())
3308 af.viewport.showSequenceFeatures = true;
3310 if (view.hasCentreColumnLabels())
3312 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
3314 if (view.hasIgnoreGapsinConsensus())
3316 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
3319 if (view.hasFollowHighlight())
3321 af.viewport.followHighlight = view.getFollowHighlight();
3323 if (view.hasFollowSelection())
3325 af.viewport.followSelection = view.getFollowSelection();
3327 if (view.hasShowConsensusHistogram())
3329 af.viewport.setShowConsensusHistogram(view
3330 .getShowConsensusHistogram());
3334 af.viewport.setShowConsensusHistogram(true);
3336 if (view.hasShowSequenceLogo())
3338 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
3342 af.viewport.setShowSequenceLogo(false);
3344 if (view.hasNormaliseSequenceLogo())
3346 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
3348 if (view.hasShowDbRefTooltip())
3350 af.viewport.setShowDbRefs(view.getShowDbRefTooltip());
3352 if (view.hasShowNPfeatureTooltip())
3354 af.viewport.setShowNpFeats(view.hasShowNPfeatureTooltip());
3356 if (view.hasShowGroupConsensus())
3358 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
3362 af.viewport.setShowGroupConsensus(false);
3364 if (view.hasShowGroupConservation())
3366 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
3370 af.viewport.setShowGroupConservation(false);
3373 // recover featre settings
3374 if (jms.getFeatureSettings() != null)
3376 af.viewport.featuresDisplayed = new Hashtable();
3377 String[] renderOrder = new String[jms.getFeatureSettings()
3378 .getSettingCount()];
3379 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
3381 Setting setting = jms.getFeatureSettings().getSetting(fs);
3382 if (setting.hasMincolour())
3384 GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
3385 new java.awt.Color(setting.getMincolour()),
3386 new java.awt.Color(setting.getColour()),
3387 setting.getMin(), setting.getMax()) : new GraduatedColor(
3388 new java.awt.Color(setting.getMincolour()),
3389 new java.awt.Color(setting.getColour()), 0, 1);
3390 if (setting.hasThreshold())
3392 gc.setThresh(setting.getThreshold());
3393 gc.setThreshType(setting.getThreshstate());
3395 gc.setAutoScaled(true); // default
3396 if (setting.hasAutoScale())
3398 gc.setAutoScaled(setting.getAutoScale());
3400 if (setting.hasColourByLabel())
3402 gc.setColourByLabel(setting.getColourByLabel());
3404 // and put in the feature colour table.
3405 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3406 setting.getType(), gc);
3410 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
3412 new java.awt.Color(setting.getColour()));
3414 renderOrder[fs] = setting.getType();
3415 if (setting.hasOrder())
3416 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3417 setting.getType(), setting.getOrder());
3419 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
3421 fs / jms.getFeatureSettings().getSettingCount());
3422 if (setting.getDisplay())
3424 af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
3425 setting.getColour()));
3428 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
3430 af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
3431 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
3433 Group grp = jms.getFeatureSettings().getGroup(gs);
3434 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
3438 if (view.getHiddenColumnsCount() > 0)
3440 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
3442 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
3443 .getHiddenColumns(c).getEnd() // +1
3447 if (view.getCalcIdParam() != null)
3449 for (CalcIdParam calcIdParam : view.getCalcIdParam())
3451 if (calcIdParam != null)
3453 if (recoverCalcIdParam(calcIdParam, af.viewport))
3458 warn("Couldn't recover parameters for "
3459 + calcIdParam.getCalcId());
3464 af.setMenusFromViewport(af.viewport);
3465 // TODO: we don't need to do this if the viewport is aready visible.
3466 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
3468 af.alignPanel.updateAnnotation(false, true); // recompute any autoannotation
3469 reorderAutoannotation(af, al, autoAlan);
3473 private void reorderAutoannotation(AlignFrame af, Alignment al,
3474 ArrayList<JvAnnotRow> autoAlan)
3476 // copy over visualization settings for autocalculated annotation in the
3478 if (al.getAlignmentAnnotation() != null)
3481 * Kludge for magic autoannotation names (see JAL-811)
3483 String[] magicNames = new String[]
3484 { "Consensus", "Quality", "Conservation" };
3485 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
3486 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
3487 for (String nm : magicNames)
3489 visan.put(nm, nullAnnot);
3491 for (JvAnnotRow auan : autoAlan)
3493 visan.put(auan.template.label
3494 + (auan.template.getCalcId() == null ? "" : "\t"
3495 + auan.template.getCalcId()), auan);
3497 int hSize = al.getAlignmentAnnotation().length;
3498 ArrayList<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
3499 // work through any autoCalculated annotation already on the view
3500 // removing it if it should be placed in a different location on the
3501 // annotation panel.
3502 List<String> remains = new ArrayList(visan.keySet());
3503 for (int h = 0; h < hSize; h++)
3505 jalview.datamodel.AlignmentAnnotation jalan = al
3506 .getAlignmentAnnotation()[h];
3507 if (jalan.autoCalculated)
3510 JvAnnotRow valan = visan.get(k = jalan.label);
3511 if (jalan.getCalcId() != null)
3513 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
3518 // delete the auto calculated row from the alignment
3519 al.deleteAnnotation(jalan, false);
3523 if (valan != nullAnnot)
3525 if (jalan != valan.template)
3527 // newly created autoannotation row instance
3528 // so keep a reference to the visible annotation row
3529 // and copy over all relevant attributes
3530 if (valan.template.graphHeight >= 0)
3533 jalan.graphHeight = valan.template.graphHeight;
3535 jalan.visible = valan.template.visible;
3537 reorder.add(new JvAnnotRow(valan.order, jalan));
3542 // Add any (possibly stale) autocalculated rows that were not appended to
3543 // the view during construction
3544 for (String other : remains)
3546 JvAnnotRow othera = visan.get(other);
3547 if (othera != nullAnnot && othera.template.getCalcId() != null
3548 && othera.template.getCalcId().length() > 0)
3550 reorder.add(othera);
3553 // now put the automatic annotation in its correct place
3554 int s = 0, srt[] = new int[reorder.size()];
3555 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
3556 for (JvAnnotRow jvar : reorder)
3559 srt[s++] = jvar.order;
3562 jalview.util.QuickSort.sort(srt, rws);
3563 // and re-insert the annotation at its correct position
3564 for (JvAnnotRow jvar : rws)
3566 al.addAnnotation(jvar.template, jvar.order);
3568 af.alignPanel.adjustAnnotationHeight();
3572 Hashtable skipList = null;
3575 * TODO remove this method
3578 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
3579 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
3580 * throw new Error("Implementation Error. No skipList defined for this
3581 * Jalview2XML instance."); } return (AlignFrame)
3582 * skipList.get(view.getSequenceSetId()); }
3586 * Check if the Jalview view contained in object should be skipped or not.
3589 * @return true if view's sequenceSetId is a key in skipList
3591 private boolean skipViewport(JalviewModel object)
3593 if (skipList == null)
3598 if (skipList.containsKey(id = object.getJalviewModelSequence()
3599 .getViewport()[0].getSequenceSetId()))
3601 if (Cache.log != null && Cache.log.isDebugEnabled())
3603 Cache.log.debug("Skipping seuqence set id " + id);
3610 public void AddToSkipList(AlignFrame af)
3612 if (skipList == null)
3614 skipList = new Hashtable();
3616 skipList.put(af.getViewport().getSequenceSetId(), af);
3619 public void clearSkipList()
3621 if (skipList != null)
3628 private void recoverDatasetFor(SequenceSet vamsasSet, Alignment al)
3630 jalview.datamodel.Alignment ds = getDatasetFor(vamsasSet.getDatasetId());
3631 Vector dseqs = null;
3634 // create a list of new dataset sequences
3635 dseqs = new Vector();
3637 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
3639 Sequence vamsasSeq = vamsasSet.getSequence(i);
3640 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs);
3642 // create a new dataset
3645 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
3646 dseqs.copyInto(dsseqs);
3647 ds = new jalview.datamodel.Alignment(dsseqs);
3648 debug("Created new dataset " + vamsasSet.getDatasetId()
3649 + " for alignment " + System.identityHashCode(al));
3650 addDatasetRef(vamsasSet.getDatasetId(), ds);
3652 // set the dataset for the newly imported alignment.
3653 if (al.getDataset() == null)
3662 * sequence definition to create/merge dataset sequence for
3666 * vector to add new dataset sequence to
3668 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
3669 AlignmentI ds, Vector dseqs)
3671 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
3673 jalview.datamodel.Sequence sq = (jalview.datamodel.Sequence) seqRefIds
3674 .get(vamsasSeq.getId());
3675 jalview.datamodel.SequenceI dsq = null;
3676 if (sq != null && sq.getDatasetSequence() != null)
3678 dsq = sq.getDatasetSequence();
3681 String sqid = vamsasSeq.getDsseqid();
3684 // need to create or add a new dataset sequence reference to this sequence
3687 dsq = (jalview.datamodel.SequenceI) seqRefIds.get(sqid);
3692 // make a new dataset sequence
3693 dsq = sq.createDatasetSequence();
3696 // make up a new dataset reference for this sequence
3697 sqid = seqHash(dsq);
3699 dsq.setVamsasId(uniqueSetSuffix + sqid);
3700 seqRefIds.put(sqid, dsq);
3705 dseqs.addElement(dsq);
3710 ds.addSequence(dsq);
3716 { // make this dataset sequence sq's dataset sequence
3717 sq.setDatasetSequence(dsq);
3721 // TODO: refactor this as a merge dataset sequence function
3722 // now check that sq (the dataset sequence) sequence really is the union of
3723 // all references to it
3724 // boolean pre = sq.getStart() < dsq.getStart();
3725 // boolean post = sq.getEnd() > dsq.getEnd();
3729 StringBuffer sb = new StringBuffer();
3730 String newres = jalview.analysis.AlignSeq.extractGaps(
3731 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
3732 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
3733 && newres.length() > dsq.getLength())
3735 // Update with the longer sequence.
3739 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
3740 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
3741 * sb.append(newres.substring(newres.length() - sq.getEnd() -
3742 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
3744 dsq.setSequence(sb.toString());
3746 // TODO: merges will never happen if we 'know' we have the real dataset
3747 // sequence - this should be detected when id==dssid
3748 System.err.println("DEBUG Notice: Merged dataset sequence"); // ("
3749 // + (pre ? "prepended" : "") + " "
3750 // + (post ? "appended" : ""));
3755 java.util.Hashtable datasetIds = null;
3757 java.util.IdentityHashMap dataset2Ids = null;
3759 private Alignment getDatasetFor(String datasetId)
3761 if (datasetIds == null)
3763 datasetIds = new Hashtable();
3766 if (datasetIds.containsKey(datasetId))
3768 return (Alignment) datasetIds.get(datasetId);
3773 private void addDatasetRef(String datasetId, Alignment dataset)
3775 if (datasetIds == null)
3777 datasetIds = new Hashtable();
3779 datasetIds.put(datasetId, dataset);
3783 * make a new dataset ID for this jalview dataset alignment
3788 private String getDatasetIdRef(jalview.datamodel.Alignment dataset)
3790 if (dataset.getDataset() != null)
3792 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
3794 String datasetId = makeHashCode(dataset, null);
3795 if (datasetId == null)
3797 // make a new datasetId and record it
3798 if (dataset2Ids == null)
3800 dataset2Ids = new IdentityHashMap();
3804 datasetId = (String) dataset2Ids.get(dataset);
3806 if (datasetId == null)
3808 datasetId = "ds" + dataset2Ids.size() + 1;
3809 dataset2Ids.put(dataset, datasetId);
3815 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
3817 for (int d = 0; d < sequence.getDBRefCount(); d++)
3819 DBRef dr = sequence.getDBRef(d);
3820 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
3821 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
3822 .getVersion(), sequence.getDBRef(d).getAccessionId());
3823 if (dr.getMapping() != null)
3825 entry.setMap(addMapping(dr.getMapping()));
3827 datasetSequence.addDBRef(entry);
3831 private jalview.datamodel.Mapping addMapping(Mapping m)
3833 SequenceI dsto = null;
3834 // Mapping m = dr.getMapping();
3835 int fr[] = new int[m.getMapListFromCount() * 2];
3836 Enumeration f = m.enumerateMapListFrom();
3837 for (int _i = 0; f.hasMoreElements(); _i += 2)
3839 MapListFrom mf = (MapListFrom) f.nextElement();
3840 fr[_i] = mf.getStart();
3841 fr[_i + 1] = mf.getEnd();
3843 int fto[] = new int[m.getMapListToCount() * 2];
3844 f = m.enumerateMapListTo();
3845 for (int _i = 0; f.hasMoreElements(); _i += 2)
3847 MapListTo mf = (MapListTo) f.nextElement();
3848 fto[_i] = mf.getStart();
3849 fto[_i + 1] = mf.getEnd();
3851 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
3852 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
3853 if (m.getMappingChoice() != null)
3855 MappingChoice mc = m.getMappingChoice();
3856 if (mc.getDseqFor() != null)
3858 String dsfor = "" + mc.getDseqFor();
3859 if (seqRefIds.containsKey(dsfor))
3864 jmap.setTo((SequenceI) seqRefIds.get(dsfor));
3868 frefedSequence.add(new Object[]
3875 * local sequence definition
3877 Sequence ms = mc.getSequence();
3878 jalview.datamodel.Sequence djs = null;
3879 String sqid = ms.getDsseqid();
3880 if (sqid != null && sqid.length() > 0)
3883 * recover dataset sequence
3885 djs = (jalview.datamodel.Sequence) seqRefIds.get(sqid);
3890 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
3891 sqid = ((Object) ms).toString(); // make up a new hascode for
3892 // undefined dataset sequence hash
3893 // (unlikely to happen)
3899 * make a new dataset sequence and add it to refIds hash
3901 djs = new jalview.datamodel.Sequence(ms.getName(),
3903 djs.setStart(jmap.getMap().getToLowest());
3904 djs.setEnd(jmap.getMap().getToHighest());
3905 djs.setVamsasId(uniqueSetSuffix + sqid);
3907 seqRefIds.put(sqid, djs);
3910 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
3919 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
3920 boolean keepSeqRefs)
3923 jalview.schemabinding.version2.JalviewModel jm = SaveState(ap, null,
3929 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
3933 uniqueSetSuffix = "";
3934 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
3939 if (this.frefedSequence == null)
3941 frefedSequence = new Vector();
3944 viewportsAdded = new Hashtable();
3946 AlignFrame af = LoadFromObject(jm, null, false, null);
3947 af.alignPanels.clear();
3948 af.closeMenuItem_actionPerformed(true);
3951 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
3952 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
3953 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
3954 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
3955 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
3958 return af.alignPanel;
3962 * flag indicating if hashtables should be cleared on finalization TODO this
3963 * flag may not be necessary
3965 private final boolean _cleartables = true;
3967 private Hashtable jvids2vobj;
3972 * @see java.lang.Object#finalize()
3975 protected void finalize() throws Throwable
3977 // really make sure we have no buried refs left.
3982 this.seqRefIds = null;
3983 this.seqsToIds = null;
3987 private void warn(String msg)
3992 private void warn(String msg, Exception e)
3994 if (Cache.log != null)
3998 Cache.log.warn(msg, e);
4002 Cache.log.warn(msg);
4007 System.err.println("Warning: " + msg);
4010 e.printStackTrace();
4015 private void debug(String string)
4017 debug(string, null);
4020 private void debug(String msg, Exception e)
4022 if (Cache.log != null)
4026 Cache.log.debug(msg, e);
4030 Cache.log.debug(msg);
4035 System.err.println("Warning: " + msg);
4038 e.printStackTrace();
4044 * set the object to ID mapping tables used to write/recover objects and XML
4045 * ID strings for the jalview project. If external tables are provided then
4046 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
4047 * object goes out of scope. - also populates the datasetIds hashtable with
4048 * alignment objects containing dataset sequences
4051 * Map from ID strings to jalview datamodel
4053 * Map from jalview datamodel to ID strings
4057 public void setObjectMappingTables(Hashtable vobj2jv,
4058 IdentityHashMap jv2vobj)
4060 this.jv2vobj = jv2vobj;
4061 this.vobj2jv = vobj2jv;
4062 Iterator ds = jv2vobj.keySet().iterator();
4064 while (ds.hasNext())
4066 Object jvobj = ds.next();
4067 id = jv2vobj.get(jvobj).toString();
4068 if (jvobj instanceof jalview.datamodel.Alignment)
4070 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
4072 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
4075 else if (jvobj instanceof jalview.datamodel.Sequence)
4077 // register sequence object so the XML parser can recover it.
4078 if (seqRefIds == null)
4080 seqRefIds = new Hashtable();
4082 if (seqsToIds == null)
4084 seqsToIds = new IdentityHashMap();
4086 seqRefIds.put(jv2vobj.get(jvobj).toString(), jvobj);
4087 seqsToIds.put(jvobj, id);
4089 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
4091 if (annotationIds == null)
4093 annotationIds = new Hashtable();
4096 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvobj);
4097 jalview.datamodel.AlignmentAnnotation jvann = (jalview.datamodel.AlignmentAnnotation) jvobj;
4098 if (jvann.annotationId == null)
4100 jvann.annotationId = anid;
4102 if (!jvann.annotationId.equals(anid))
4104 // TODO verify that this is the correct behaviour
4105 this.warn("Overriding Annotation ID for " + anid
4106 + " from different id : " + jvann.annotationId);
4107 jvann.annotationId = anid;
4110 else if (jvobj instanceof String)
4112 if (jvids2vobj == null)
4114 jvids2vobj = new Hashtable();
4115 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
4119 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
4124 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
4125 * objects created from the project archive. If string is null (default for
4126 * construction) then suffix will be set automatically.
4130 public void setUniqueSetSuffix(String string)
4132 uniqueSetSuffix = string;
4137 * uses skipList2 as the skipList for skipping views on sequence sets
4138 * associated with keys in the skipList
4142 public void setSkipList(Hashtable skipList2)
4144 skipList = skipList2;