2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
23 import jalview.api.FeatureColourI;
24 import jalview.api.ViewStyleI;
25 import jalview.api.structures.JalviewStructureDisplayI;
26 import jalview.bin.Cache;
27 import jalview.datamodel.AlignedCodonFrame;
28 import jalview.datamodel.Alignment;
29 import jalview.datamodel.AlignmentAnnotation;
30 import jalview.datamodel.AlignmentI;
31 import jalview.datamodel.PDBEntry;
32 import jalview.datamodel.RnaViewerModel;
33 import jalview.datamodel.SequenceGroup;
34 import jalview.datamodel.SequenceI;
35 import jalview.datamodel.StructureViewerModel;
36 import jalview.datamodel.StructureViewerModel.StructureData;
37 import jalview.ext.varna.RnaModel;
38 import jalview.gui.StructureViewer.ViewerType;
39 import jalview.schemabinding.version2.AlcodMap;
40 import jalview.schemabinding.version2.AlcodonFrame;
41 import jalview.schemabinding.version2.Annotation;
42 import jalview.schemabinding.version2.AnnotationColours;
43 import jalview.schemabinding.version2.AnnotationElement;
44 import jalview.schemabinding.version2.CalcIdParam;
45 import jalview.schemabinding.version2.DBRef;
46 import jalview.schemabinding.version2.Features;
47 import jalview.schemabinding.version2.Group;
48 import jalview.schemabinding.version2.HiddenColumns;
49 import jalview.schemabinding.version2.JGroup;
50 import jalview.schemabinding.version2.JSeq;
51 import jalview.schemabinding.version2.JalviewModel;
52 import jalview.schemabinding.version2.JalviewModelSequence;
53 import jalview.schemabinding.version2.MapListFrom;
54 import jalview.schemabinding.version2.MapListTo;
55 import jalview.schemabinding.version2.Mapping;
56 import jalview.schemabinding.version2.MappingChoice;
57 import jalview.schemabinding.version2.OtherData;
58 import jalview.schemabinding.version2.PdbentryItem;
59 import jalview.schemabinding.version2.Pdbids;
60 import jalview.schemabinding.version2.Property;
61 import jalview.schemabinding.version2.RnaViewer;
62 import jalview.schemabinding.version2.SecondaryStructure;
63 import jalview.schemabinding.version2.Sequence;
64 import jalview.schemabinding.version2.SequenceSet;
65 import jalview.schemabinding.version2.SequenceSetProperties;
66 import jalview.schemabinding.version2.Setting;
67 import jalview.schemabinding.version2.StructureState;
68 import jalview.schemabinding.version2.ThresholdLine;
69 import jalview.schemabinding.version2.Tree;
70 import jalview.schemabinding.version2.UserColours;
71 import jalview.schemabinding.version2.Viewport;
72 import jalview.schemes.AnnotationColourGradient;
73 import jalview.schemes.ColourSchemeI;
74 import jalview.schemes.ColourSchemeProperty;
75 import jalview.schemes.FeatureColour;
76 import jalview.schemes.ResidueColourScheme;
77 import jalview.schemes.ResidueProperties;
78 import jalview.schemes.UserColourScheme;
79 import jalview.structure.StructureSelectionManager;
80 import jalview.structures.models.AAStructureBindingModel;
81 import jalview.util.MessageManager;
82 import jalview.util.Platform;
83 import jalview.util.StringUtils;
84 import jalview.util.jarInputStreamProvider;
85 import jalview.viewmodel.AlignmentViewport;
86 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
87 import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
88 import jalview.ws.jws2.Jws2Discoverer;
89 import jalview.ws.jws2.dm.AAConSettings;
90 import jalview.ws.jws2.jabaws2.Jws2Instance;
91 import jalview.ws.params.ArgumentI;
92 import jalview.ws.params.AutoCalcSetting;
93 import jalview.ws.params.WsParamSetI;
95 import java.awt.Color;
96 import java.awt.Rectangle;
97 import java.io.BufferedReader;
98 import java.io.DataInputStream;
99 import java.io.DataOutputStream;
101 import java.io.FileInputStream;
102 import java.io.FileOutputStream;
103 import java.io.IOException;
104 import java.io.InputStreamReader;
105 import java.io.OutputStreamWriter;
106 import java.io.PrintWriter;
107 import java.lang.reflect.InvocationTargetException;
108 import java.net.MalformedURLException;
110 import java.util.ArrayList;
111 import java.util.Enumeration;
112 import java.util.HashMap;
113 import java.util.HashSet;
114 import java.util.Hashtable;
115 import java.util.IdentityHashMap;
116 import java.util.Iterator;
117 import java.util.LinkedHashMap;
118 import java.util.List;
119 import java.util.Map;
120 import java.util.Map.Entry;
121 import java.util.Set;
122 import java.util.Vector;
123 import java.util.jar.JarEntry;
124 import java.util.jar.JarInputStream;
125 import java.util.jar.JarOutputStream;
127 import javax.swing.JInternalFrame;
128 import javax.swing.JOptionPane;
129 import javax.swing.SwingUtilities;
131 import org.exolab.castor.xml.Marshaller;
132 import org.exolab.castor.xml.Unmarshaller;
135 * Write out the current jalview desktop state as a Jalview XML stream.
137 * Note: the vamsas objects referred to here are primitive versions of the
138 * VAMSAS project schema elements - they are not the same and most likely never
142 * @version $Revision: 1.134 $
144 public class Jalview2XML
146 private static final String VIEWER_PREFIX = "viewer_";
148 private static final String RNA_PREFIX = "rna_";
150 private static final String UTF_8 = "UTF-8";
152 // use this with nextCounter() to make unique names for entities
153 private int counter = 0;
156 * SequenceI reference -> XML ID string in jalview XML. Populated as XML reps
157 * of sequence objects are created.
159 IdentityHashMap<SequenceI, String> seqsToIds = null;
162 * jalview XML Sequence ID to jalview sequence object reference (both dataset
163 * and alignment sequences. Populated as XML reps of sequence objects are
166 Map<String, SequenceI> seqRefIds = null;
168 Map<String, SequenceI> incompleteSeqs = null;
170 List<SeqFref> frefedSequence = null;
172 boolean raiseGUI = true; // whether errors are raised in dialog boxes or not
175 * Map of reconstructed AlignFrame objects that appear to have come from
176 * SplitFrame objects (have a dna/protein complement view).
178 private Map<Viewport, AlignFrame> splitFrameCandidates = new HashMap<Viewport, AlignFrame>();
181 * Map from displayed rna structure models to their saved session state jar
184 private Map<RnaModel, String> rnaSessions = new HashMap<RnaModel, String>();
187 * create/return unique hash string for sq
190 * @return new or existing unique string for sq
192 String seqHash(SequenceI sq)
194 if (seqsToIds == null)
198 if (seqsToIds.containsKey(sq))
200 return seqsToIds.get(sq);
204 // create sequential key
205 String key = "sq" + (seqsToIds.size() + 1);
206 key = makeHashCode(sq, key); // check we don't have an external reference
208 seqsToIds.put(sq, key);
217 if (seqRefIds != null)
221 if (seqsToIds != null)
225 if (incompleteSeqs != null)
227 incompleteSeqs.clear();
235 warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
236 // seqRefIds = new Hashtable();
237 // seqsToIds = new IdentityHashMap();
243 if (seqsToIds == null)
245 seqsToIds = new IdentityHashMap<SequenceI, String>();
247 if (seqRefIds == null)
249 seqRefIds = new HashMap<String, SequenceI>();
251 if (incompleteSeqs == null)
253 incompleteSeqs = new HashMap<String, SequenceI>();
255 if (frefedSequence == null)
257 frefedSequence = new ArrayList<SeqFref>();
265 public Jalview2XML(boolean raiseGUI)
267 this.raiseGUI = raiseGUI;
271 * base class for resolving forward references to sequences by their ID
276 abstract class SeqFref
280 public SeqFref(String _sref)
285 public String getSref()
290 public SequenceI getSrefSeq()
292 return seqRefIds.get(sref);
295 public boolean isResolvable()
297 return seqRefIds.get(sref) != null;
300 public SequenceI getSrefDatasetSeq()
302 SequenceI sq = seqRefIds.get(sref);
305 while (sq.getDatasetSequence() != null)
307 sq = sq.getDatasetSequence();
313 * @return true if the forward reference was fully resolved
315 abstract boolean resolve();
319 * create forward reference for a mapping
325 public SeqFref newMappingRef(final String sref,
326 final jalview.datamodel.Mapping _jmap)
328 SeqFref fref = new SeqFref(sref)
330 public jalview.datamodel.Mapping jmap = _jmap;
335 SequenceI seq = getSrefDatasetSeq();
347 public SeqFref newAlcodMapRef(final String sref,
348 final AlignedCodonFrame _cf, final jalview.datamodel.Mapping _jmap)
351 SeqFref fref = new SeqFref(sref)
353 AlignedCodonFrame cf = _cf;
355 public jalview.datamodel.Mapping mp = _jmap;
360 SequenceI seq = getSrefDatasetSeq();
365 cf.addMap(seq, mp.getTo(), mp.getMap());
372 public void resolveFrefedSequences()
374 Iterator<SeqFref> nextFref=frefedSequence.iterator();
375 int toresolve=frefedSequence.size();
376 int unresolved=0,failedtoresolve=0;
377 while (nextFref.hasNext()) {
378 SeqFref ref = nextFref.next();
379 if (ref.isResolvable())
388 } catch (Exception x) {
389 System.err.println("IMPLEMENTATION ERROR: Failed to resolve forward reference for sequence "+ref.getSref());
399 System.err.println("There were "+unresolved+" forward references left unresolved on the stack.");
401 if (failedtoresolve>0)
403 System.err.println("SERIOUS! " + failedtoresolve
404 + " resolvable forward references failed to resolve.");
406 if (incompleteSeqs != null && incompleteSeqs.size() > 0)
408 System.err.println("Jalview Project Import: There are "
409 + incompleteSeqs.size()
410 + " sequences which may have incomplete metadata.");
411 if (incompleteSeqs.size() < 10)
413 for (SequenceI s : incompleteSeqs.values())
415 System.err.println(s.toString());
421 .println("Too many to report. Skipping output of incomplete sequences.");
427 * This maintains a map of viewports, the key being the seqSetId. Important to
428 * set historyItem and redoList for multiple views
430 Map<String, AlignViewport> viewportsAdded = new HashMap<String, AlignViewport>();
432 Map<String, AlignmentAnnotation> annotationIds = new HashMap<String, AlignmentAnnotation>();
434 String uniqueSetSuffix = "";
437 * List of pdbfiles added to Jar
439 List<String> pdbfiles = null;
441 // SAVES SEVERAL ALIGNMENT WINDOWS TO SAME JARFILE
442 public void saveState(File statefile)
444 FileOutputStream fos = null;
447 fos = new FileOutputStream(statefile);
448 JarOutputStream jout = new JarOutputStream(fos);
451 } catch (Exception e)
453 // TODO: inform user of the problem - they need to know if their data was
455 if (errorMessage == null)
457 errorMessage = "Couldn't write Jalview Archive to output file '"
458 + statefile + "' - See console error log for details";
462 errorMessage += "(output file was '" + statefile + "')";
472 } catch (IOException e)
482 * Writes a jalview project archive to the given Jar output stream.
486 public void saveState(JarOutputStream jout)
488 AlignFrame[] frames = Desktop.getAlignFrames();
495 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
498 * ensure cached data is clear before starting
500 // todo tidy up seqRefIds, seqsToIds initialisation / reset
502 splitFrameCandidates.clear();
507 // NOTE UTF-8 MUST BE USED FOR WRITING UNICODE CHARS
508 // //////////////////////////////////////////////////
510 List<String> shortNames = new ArrayList<String>();
511 List<String> viewIds = new ArrayList<String>();
514 for (int i = frames.length - 1; i > -1; i--)
516 AlignFrame af = frames[i];
520 .containsKey(af.getViewport().getSequenceSetId()))
525 String shortName = makeFilename(af, shortNames);
527 int ap, apSize = af.alignPanels.size();
529 for (ap = 0; ap < apSize; ap++)
531 AlignmentPanel apanel = af.alignPanels.get(ap);
532 String fileName = apSize == 1 ? shortName : ap + shortName;
533 if (!fileName.endsWith(".xml"))
535 fileName = fileName + ".xml";
538 saveState(apanel, fileName, jout, viewIds);
540 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
542 if (!dsses.containsKey(dssid))
544 dsses.put(dssid, af);
549 writeDatasetFor(dsses, "" + jout.hashCode() + " " + uniqueSetSuffix,
555 } catch (Exception foo)
560 } catch (Exception ex)
562 // TODO: inform user of the problem - they need to know if their data was
564 if (errorMessage == null)
566 errorMessage = "Couldn't write Jalview Archive - see error output for details";
568 ex.printStackTrace();
573 * Generates a distinct file name, based on the title of the AlignFrame, by
574 * appending _n for increasing n until an unused name is generated. The new
575 * name (without its extension) is added to the list.
579 * @return the generated name, with .xml extension
581 protected String makeFilename(AlignFrame af, List<String> namesUsed)
583 String shortName = af.getTitle();
585 if (shortName.indexOf(File.separatorChar) > -1)
587 shortName = shortName.substring(shortName
588 .lastIndexOf(File.separatorChar) + 1);
593 while (namesUsed.contains(shortName))
595 if (shortName.endsWith("_" + (count - 1)))
597 shortName = shortName.substring(0, shortName.lastIndexOf("_"));
600 shortName = shortName.concat("_" + count);
604 namesUsed.add(shortName);
606 if (!shortName.endsWith(".xml"))
608 shortName = shortName + ".xml";
613 // USE THIS METHOD TO SAVE A SINGLE ALIGNMENT WINDOW
614 public boolean saveAlignment(AlignFrame af, String jarFile,
620 int apSize = af.alignPanels.size();
621 FileOutputStream fos = new FileOutputStream(jarFile);
622 JarOutputStream jout = new JarOutputStream(fos);
623 Hashtable<String, AlignFrame> dsses = new Hashtable<String, AlignFrame>();
624 List<String> viewIds = new ArrayList<String>();
626 for (AlignmentPanel apanel : af.alignPanels)
628 String jfileName = apSize == 1 ? fileName : fileName + ap;
630 if (!jfileName.endsWith(".xml"))
632 jfileName = jfileName + ".xml";
634 saveState(apanel, jfileName, jout, viewIds);
635 String dssid = getDatasetIdRef(af.getViewport().getAlignment()
637 if (!dsses.containsKey(dssid))
639 dsses.put(dssid, af);
642 writeDatasetFor(dsses, fileName, jout);
646 } catch (Exception foo)
652 } catch (Exception ex)
654 errorMessage = "Couldn't Write alignment view to Jalview Archive - see error output for details";
655 ex.printStackTrace();
660 private void writeDatasetFor(Hashtable<String, AlignFrame> dsses,
661 String fileName, JarOutputStream jout)
664 for (String dssids : dsses.keySet())
666 AlignFrame _af = dsses.get(dssids);
667 String jfileName = fileName + " Dataset for " + _af.getTitle();
668 if (!jfileName.endsWith(".xml"))
670 jfileName = jfileName + ".xml";
672 saveState(_af.alignPanel, jfileName, true, jout, null);
677 * create a JalviewModel from an alignment view and marshall it to a
681 * panel to create jalview model for
683 * name of alignment panel written to output stream
690 public JalviewModel saveState(AlignmentPanel ap, String fileName,
691 JarOutputStream jout, List<String> viewIds)
693 return saveState(ap, fileName, false, jout, viewIds);
697 * create a JalviewModel from an alignment view and marshall it to a
701 * panel to create jalview model for
703 * name of alignment panel written to output stream
705 * when true, only write the dataset for the alignment, not the data
706 * associated with the view.
712 public JalviewModel saveState(AlignmentPanel ap, String fileName,
713 boolean storeDS, JarOutputStream jout, List<String> viewIds)
717 viewIds = new ArrayList<String>();
722 List<UserColourScheme> userColours = new ArrayList<UserColourScheme>();
724 AlignViewport av = ap.av;
726 JalviewModel object = new JalviewModel();
727 object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
729 object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
730 object.setVersion(jalview.bin.Cache.getDefault("VERSION",
731 "Development Build"));
734 * rjal is full height alignment, jal is actual alignment with full metadata
735 * but excludes hidden sequences.
737 jalview.datamodel.AlignmentI rjal = av.getAlignment(), jal = rjal;
739 if (av.hasHiddenRows())
741 rjal = jal.getHiddenSequences().getFullAlignment();
744 SequenceSet vamsasSet = new SequenceSet();
746 JalviewModelSequence jms = new JalviewModelSequence();
748 vamsasSet.setGapChar(jal.getGapCharacter() + "");
750 if (jal.getDataset() != null)
752 // dataset id is the dataset's hashcode
753 vamsasSet.setDatasetId(getDatasetIdRef(jal.getDataset()));
756 // switch jal and the dataset
757 jal = jal.getDataset();
761 if (jal.getProperties() != null)
763 Enumeration en = jal.getProperties().keys();
764 while (en.hasMoreElements())
766 String key = en.nextElement().toString();
767 SequenceSetProperties ssp = new SequenceSetProperties();
769 ssp.setValue(jal.getProperties().get(key).toString());
770 vamsasSet.addSequenceSetProperties(ssp);
775 Set<String> calcIdSet = new HashSet<String>();
778 for (final SequenceI jds : rjal.getSequences())
780 final SequenceI jdatasq = jds.getDatasetSequence() == null ? jds
781 : jds.getDatasetSequence();
782 String id = seqHash(jds);
784 if (seqRefIds.get(id) != null)
786 // This happens for two reasons: 1. multiple views are being serialised.
787 // 2. the hashCode has collided with another sequence's code. This DOES
788 // HAPPEN! (PF00072.15.stk does this)
789 // JBPNote: Uncomment to debug writing out of files that do not read
790 // back in due to ArrayOutOfBoundExceptions.
791 // System.err.println("vamsasSeq backref: "+id+"");
792 // System.err.println(jds.getName()+"
793 // "+jds.getStart()+"-"+jds.getEnd()+" "+jds.getSequenceAsString());
794 // System.err.println("Hashcode: "+seqHash(jds));
795 // SequenceI rsq = (SequenceI) seqRefIds.get(id + "");
796 // System.err.println(rsq.getName()+"
797 // "+rsq.getStart()+"-"+rsq.getEnd()+" "+rsq.getSequenceAsString());
798 // System.err.println("Hashcode: "+seqHash(rsq));
802 vamsasSeq = createVamsasSequence(id, jds);
803 vamsasSet.addSequence(vamsasSeq);
804 seqRefIds.put(id, jds);
808 jseq.setStart(jds.getStart());
809 jseq.setEnd(jds.getEnd());
810 jseq.setColour(av.getSequenceColour(jds).getRGB());
812 jseq.setId(id); // jseq id should be a string not a number
815 // Store any sequences this sequence represents
816 if (av.hasHiddenRows())
818 // use rjal, contains the full height alignment
819 jseq.setHidden(av.getAlignment().getHiddenSequences()
822 if (av.isHiddenRepSequence(jds))
824 jalview.datamodel.SequenceI[] reps = av
825 .getRepresentedSequences(jds)
826 .getSequencesInOrder(rjal);
828 for (int h = 0; h < reps.length; h++)
832 jseq.addHiddenSequences(rjal.findIndex(reps[h]));
837 // mark sequence as reference - if it is the reference for this view
840 jseq.setViewreference(jds == jal.getSeqrep());
844 // TODO: omit sequence features from each alignment view's XML dump if we
845 // are storing dataset
846 if (jds.getSequenceFeatures() != null)
848 jalview.datamodel.SequenceFeature[] sf = jds.getSequenceFeatures();
850 while (index < sf.length)
852 Features features = new Features();
854 features.setBegin(sf[index].getBegin());
855 features.setEnd(sf[index].getEnd());
856 features.setDescription(sf[index].getDescription());
857 features.setType(sf[index].getType());
858 features.setFeatureGroup(sf[index].getFeatureGroup());
859 features.setScore(sf[index].getScore());
860 if (sf[index].links != null)
862 for (int l = 0; l < sf[index].links.size(); l++)
864 OtherData keyValue = new OtherData();
865 keyValue.setKey("LINK_" + l);
866 keyValue.setValue(sf[index].links.elementAt(l).toString());
867 features.addOtherData(keyValue);
870 if (sf[index].otherDetails != null)
873 Iterator<String> keys = sf[index].otherDetails.keySet()
875 while (keys.hasNext())
878 OtherData keyValue = new OtherData();
879 keyValue.setKey(key);
880 keyValue.setValue(sf[index].otherDetails.get(key).toString());
881 features.addOtherData(keyValue);
885 jseq.addFeatures(features);
890 if (jdatasq.getAllPDBEntries() != null)
892 Enumeration en = jdatasq.getAllPDBEntries().elements();
893 while (en.hasMoreElements())
895 Pdbids pdb = new Pdbids();
896 jalview.datamodel.PDBEntry entry = (jalview.datamodel.PDBEntry) en
899 String pdbId = entry.getId();
901 pdb.setType(entry.getType());
904 * Store any structure views associated with this sequence. This
905 * section copes with duplicate entries in the project, so a dataset
906 * only view *should* be coped with sensibly.
908 // This must have been loaded, is it still visible?
909 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
910 String matchedFile = null;
911 for (int f = frames.length - 1; f > -1; f--)
913 if (frames[f] instanceof StructureViewerBase)
915 StructureViewerBase viewFrame = (StructureViewerBase) frames[f];
916 matchedFile = saveStructureState(ap, jds, pdb, entry,
917 viewIds, matchedFile, viewFrame);
919 * Only store each structure viewer's state once in the project
920 * jar. First time through only (storeDS==false)
922 String viewId = viewFrame.getViewId();
923 if (!storeDS && !viewIds.contains(viewId))
928 String viewerState = viewFrame.getStateInfo();
929 writeJarEntry(jout, getViewerJarEntryName(viewId),
930 viewerState.getBytes());
931 } catch (IOException e)
933 System.err.println("Error saving viewer state: "
940 if (matchedFile != null || entry.getFile() != null)
942 if (entry.getFile() != null)
945 matchedFile = entry.getFile();
947 pdb.setFile(matchedFile); // entry.getFile());
948 if (pdbfiles == null)
950 pdbfiles = new ArrayList<String>();
953 if (!pdbfiles.contains(pdbId))
956 copyFileToJar(jout, matchedFile, pdbId);
960 if (entry.getProperty() != null && !entry.getProperty().isEmpty())
962 PdbentryItem item = new PdbentryItem();
963 Hashtable properties = entry.getProperty();
964 Enumeration en2 = properties.keys();
965 while (en2.hasMoreElements())
967 Property prop = new Property();
968 String key = en2.nextElement().toString();
970 prop.setValue(properties.get(key).toString());
971 item.addProperty(prop);
973 pdb.addPdbentryItem(item);
980 saveRnaViewers(jout, jseq, jds, viewIds, ap, storeDS);
985 if (!storeDS && av.hasHiddenRows())
987 jal = av.getAlignment();
990 if (jal.getCodonFrames() != null)
992 List<AlignedCodonFrame> jac = jal.getCodonFrames();
993 for (AlignedCodonFrame acf : jac)
995 AlcodonFrame alc = new AlcodonFrame();
996 if (acf.getProtMappings() != null
997 && acf.getProtMappings().length > 0)
999 boolean hasMap = false;
1000 SequenceI[] dnas = acf.getdnaSeqs();
1001 jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1002 for (int m = 0; m < pmaps.length; m++)
1004 AlcodMap alcmap = new AlcodMap();
1005 alcmap.setDnasq(seqHash(dnas[m]));
1006 alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1008 alc.addAlcodMap(alcmap);
1013 vamsasSet.addAlcodonFrame(alc);
1016 // TODO: delete this ? dead code from 2.8.3->2.9 ?
1018 // AlcodonFrame alc = new AlcodonFrame();
1019 // vamsasSet.addAlcodonFrame(alc);
1020 // for (int p = 0; p < acf.aaWidth; p++)
1022 // Alcodon cmap = new Alcodon();
1023 // if (acf.codons[p] != null)
1025 // // Null codons indicate a gapped column in the translated peptide
1027 // cmap.setPos1(acf.codons[p][0]);
1028 // cmap.setPos2(acf.codons[p][1]);
1029 // cmap.setPos3(acf.codons[p][2]);
1031 // alc.addAlcodon(cmap);
1033 // if (acf.getProtMappings() != null
1034 // && acf.getProtMappings().length > 0)
1036 // SequenceI[] dnas = acf.getdnaSeqs();
1037 // jalview.datamodel.Mapping[] pmaps = acf.getProtMappings();
1038 // for (int m = 0; m < pmaps.length; m++)
1040 // AlcodMap alcmap = new AlcodMap();
1041 // alcmap.setDnasq(seqHash(dnas[m]));
1042 // alcmap.setMapping(createVamsasMapping(pmaps[m], dnas[m], null,
1044 // alc.addAlcodMap(alcmap);
1051 // /////////////////////////////////
1052 if (!storeDS && av.currentTree != null)
1054 // FIND ANY ASSOCIATED TREES
1055 // NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
1056 if (Desktop.desktop != null)
1058 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1060 for (int t = 0; t < frames.length; t++)
1062 if (frames[t] instanceof TreePanel)
1064 TreePanel tp = (TreePanel) frames[t];
1066 if (tp.treeCanvas.av.getAlignment() == jal)
1068 Tree tree = new Tree();
1069 tree.setTitle(tp.getTitle());
1070 tree.setCurrentTree((av.currentTree == tp.getTree()));
1071 tree.setNewick(tp.getTree().toString());
1072 tree.setThreshold(tp.treeCanvas.threshold);
1074 tree.setFitToWindow(tp.fitToWindow.getState());
1075 tree.setFontName(tp.getTreeFont().getName());
1076 tree.setFontSize(tp.getTreeFont().getSize());
1077 tree.setFontStyle(tp.getTreeFont().getStyle());
1078 tree.setMarkUnlinked(tp.placeholdersMenu.getState());
1080 tree.setShowBootstrap(tp.bootstrapMenu.getState());
1081 tree.setShowDistances(tp.distanceMenu.getState());
1083 tree.setHeight(tp.getHeight());
1084 tree.setWidth(tp.getWidth());
1085 tree.setXpos(tp.getX());
1086 tree.setYpos(tp.getY());
1087 tree.setId(makeHashCode(tp, null));
1097 * store forward refs from an annotationRow to any groups
1099 IdentityHashMap<SequenceGroup, String> groupRefs = new IdentityHashMap<SequenceGroup, String>();
1102 for (SequenceI sq : jal.getSequences())
1104 // Store annotation on dataset sequences only
1105 AlignmentAnnotation[] aa = sq.getAnnotation();
1106 if (aa != null && aa.length > 0)
1108 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1115 if (jal.getAlignmentAnnotation() != null)
1117 // Store the annotation shown on the alignment.
1118 AlignmentAnnotation[] aa = jal.getAlignmentAnnotation();
1119 storeAlignmentAnnotation(aa, groupRefs, av, calcIdSet, storeDS,
1124 if (jal.getGroups() != null)
1126 JGroup[] groups = new JGroup[jal.getGroups().size()];
1128 for (jalview.datamodel.SequenceGroup sg : jal.getGroups())
1130 JGroup jGroup = new JGroup();
1131 groups[++i] = jGroup;
1133 jGroup.setStart(sg.getStartRes());
1134 jGroup.setEnd(sg.getEndRes());
1135 jGroup.setName(sg.getName());
1136 if (groupRefs.containsKey(sg))
1138 // group has references so set its ID field
1139 jGroup.setId(groupRefs.get(sg));
1143 if (sg.cs.conservationApplied())
1145 jGroup.setConsThreshold(sg.cs.getConservationInc());
1147 if (sg.cs instanceof jalview.schemes.UserColourScheme)
1149 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1153 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1156 else if (sg.cs instanceof jalview.schemes.AnnotationColourGradient)
1158 jGroup.setColour("AnnotationColourGradient");
1159 jGroup.setAnnotationColours(constructAnnotationColours(
1160 (jalview.schemes.AnnotationColourGradient) sg.cs,
1163 else if (sg.cs instanceof jalview.schemes.UserColourScheme)
1165 jGroup.setColour(setUserColourScheme(sg.cs, userColours, jms));
1169 jGroup.setColour(ColourSchemeProperty.getColourName(sg.cs));
1172 jGroup.setPidThreshold(sg.cs.getThreshold());
1175 jGroup.setOutlineColour(sg.getOutlineColour().getRGB());
1176 jGroup.setDisplayBoxes(sg.getDisplayBoxes());
1177 jGroup.setDisplayText(sg.getDisplayText());
1178 jGroup.setColourText(sg.getColourText());
1179 jGroup.setTextCol1(sg.textColour.getRGB());
1180 jGroup.setTextCol2(sg.textColour2.getRGB());
1181 jGroup.setTextColThreshold(sg.thresholdTextColour);
1182 jGroup.setShowUnconserved(sg.getShowNonconserved());
1183 jGroup.setIgnoreGapsinConsensus(sg.getIgnoreGapsConsensus());
1184 jGroup.setShowConsensusHistogram(sg.isShowConsensusHistogram());
1185 jGroup.setShowSequenceLogo(sg.isShowSequenceLogo());
1186 jGroup.setNormaliseSequenceLogo(sg.isNormaliseSequenceLogo());
1187 for (SequenceI seq : sg.getSequences())
1189 jGroup.addSeq(seqHash(seq));
1193 jms.setJGroup(groups);
1197 // /////////SAVE VIEWPORT
1198 Viewport view = new Viewport();
1199 view.setTitle(ap.alignFrame.getTitle());
1200 view.setSequenceSetId(makeHashCode(av.getSequenceSetId(),
1201 av.getSequenceSetId()));
1202 view.setId(av.getViewId());
1203 if (av.getCodingComplement() != null)
1205 view.setComplementId(av.getCodingComplement().getViewId());
1207 view.setViewName(av.viewName);
1208 view.setGatheredViews(av.isGatherViewsHere());
1210 Rectangle size = ap.av.getExplodedGeometry();
1211 Rectangle position = size;
1214 size = ap.alignFrame.getBounds();
1215 if (av.getCodingComplement() != null)
1217 position = ((SplitFrame) ap.alignFrame.getSplitViewContainer())
1225 view.setXpos(position.x);
1226 view.setYpos(position.y);
1228 view.setWidth(size.width);
1229 view.setHeight(size.height);
1231 view.setStartRes(av.startRes);
1232 view.setStartSeq(av.startSeq);
1234 if (av.getGlobalColourScheme() instanceof jalview.schemes.UserColourScheme)
1236 view.setBgColour(setUserColourScheme(av.getGlobalColourScheme(),
1239 else if (av.getGlobalColourScheme() instanceof jalview.schemes.AnnotationColourGradient)
1241 AnnotationColours ac = constructAnnotationColours(
1242 (jalview.schemes.AnnotationColourGradient) av
1243 .getGlobalColourScheme(),
1246 view.setAnnotationColours(ac);
1247 view.setBgColour("AnnotationColourGradient");
1251 view.setBgColour(ColourSchemeProperty.getColourName(av
1252 .getGlobalColourScheme()));
1255 ColourSchemeI cs = av.getGlobalColourScheme();
1259 if (cs.conservationApplied())
1261 view.setConsThreshold(cs.getConservationInc());
1262 if (cs instanceof jalview.schemes.UserColourScheme)
1264 view.setBgColour(setUserColourScheme(cs, userColours, jms));
1268 if (cs instanceof ResidueColourScheme)
1270 view.setPidThreshold(cs.getThreshold());
1274 view.setConservationSelected(av.getConservationSelected());
1275 view.setPidSelected(av.getAbovePIDThreshold());
1276 view.setFontName(av.font.getName());
1277 view.setFontSize(av.font.getSize());
1278 view.setFontStyle(av.font.getStyle());
1279 view.setScaleProteinAsCdna(av.getViewStyle().isScaleProteinAsCdna());
1280 view.setRenderGaps(av.isRenderGaps());
1281 view.setShowAnnotation(av.isShowAnnotation());
1282 view.setShowBoxes(av.getShowBoxes());
1283 view.setShowColourText(av.getColourText());
1284 view.setShowFullId(av.getShowJVSuffix());
1285 view.setRightAlignIds(av.isRightAlignIds());
1286 view.setShowSequenceFeatures(av.isShowSequenceFeatures());
1287 view.setShowText(av.getShowText());
1288 view.setShowUnconserved(av.getShowUnconserved());
1289 view.setWrapAlignment(av.getWrapAlignment());
1290 view.setTextCol1(av.getTextColour().getRGB());
1291 view.setTextCol2(av.getTextColour2().getRGB());
1292 view.setTextColThreshold(av.getThresholdTextColour());
1293 view.setShowConsensusHistogram(av.isShowConsensusHistogram());
1294 view.setShowSequenceLogo(av.isShowSequenceLogo());
1295 view.setNormaliseSequenceLogo(av.isNormaliseSequenceLogo());
1296 view.setShowGroupConsensus(av.isShowGroupConsensus());
1297 view.setShowGroupConservation(av.isShowGroupConservation());
1298 view.setShowNPfeatureTooltip(av.isShowNPFeats());
1299 view.setShowDbRefTooltip(av.isShowDBRefs());
1300 view.setFollowHighlight(av.isFollowHighlight());
1301 view.setFollowSelection(av.followSelection);
1302 view.setIgnoreGapsinConsensus(av.isIgnoreGapsConsensus());
1303 if (av.getFeaturesDisplayed() != null)
1305 jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
1307 String[] renderOrder = ap.getSeqPanel().seqCanvas
1308 .getFeatureRenderer().getRenderOrder()
1309 .toArray(new String[0]);
1311 Vector<String> settingsAdded = new Vector<String>();
1312 if (renderOrder != null)
1314 for (String featureType : renderOrder)
1316 FeatureColourI fcol = ap.getSeqPanel().seqCanvas
1317 .getFeatureRenderer()
1318 .getFeatureStyle(featureType);
1319 Setting setting = new Setting();
1320 setting.setType(featureType);
1321 if (!fcol.isSimpleColour())
1323 setting.setColour(fcol.getMaxColour().getRGB());
1324 setting.setMincolour(fcol.getMinColour().getRGB());
1325 setting.setMin(fcol.getMin());
1326 setting.setMax(fcol.getMax());
1327 setting.setColourByLabel(fcol.isColourByLabel());
1328 setting.setAutoScale(fcol.isAutoScaled());
1329 setting.setThreshold(fcol.getThreshold());
1330 // -1 = No threshold, 0 = Below, 1 = Above
1331 setting.setThreshstate(fcol.isAboveThreshold() ? 1
1332 : (fcol.isBelowThreshold() ? 0 : -1));
1336 setting.setColour(fcol.getColour().getRGB());
1339 setting.setDisplay(av.getFeaturesDisplayed().isVisible(
1341 float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
1342 .getOrder(featureType);
1345 setting.setOrder(rorder);
1347 fs.addSetting(setting);
1348 settingsAdded.addElement(featureType);
1352 // is groups actually supposed to be a map here ?
1353 Iterator<String> en = ap.getSeqPanel().seqCanvas
1354 .getFeatureRenderer()
1355 .getFeatureGroups().iterator();
1356 Vector<String> groupsAdded = new Vector<String>();
1357 while (en.hasNext())
1359 String grp = en.next();
1360 if (groupsAdded.contains(grp))
1364 Group g = new Group();
1366 g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
1367 .getFeatureRenderer().checkGroupVisibility(grp, false))
1370 groupsAdded.addElement(grp);
1372 jms.setFeatureSettings(fs);
1375 if (av.hasHiddenColumns())
1377 if (av.getColumnSelection() == null
1378 || av.getColumnSelection().getHiddenColumns() == null)
1380 warn("REPORT BUG: avoided null columnselection bug (DMAM reported). Please contact Jim about this.");
1384 for (int c = 0; c < av.getColumnSelection().getHiddenColumns()
1387 int[] region = av.getColumnSelection().getHiddenColumns()
1389 HiddenColumns hc = new HiddenColumns();
1390 hc.setStart(region[0]);
1391 hc.setEnd(region[1]);
1392 view.addHiddenColumns(hc);
1396 if (calcIdSet.size() > 0)
1398 for (String calcId : calcIdSet)
1400 if (calcId.trim().length() > 0)
1402 CalcIdParam cidp = createCalcIdParam(calcId, av);
1403 // Some calcIds have no parameters.
1406 view.addCalcIdParam(cidp);
1412 jms.addViewport(view);
1414 object.setJalviewModelSequence(jms);
1415 object.getVamsasModel().addSequenceSet(vamsasSet);
1417 if (jout != null && fileName != null)
1419 // We may not want to write the object to disk,
1420 // eg we can copy the alignViewport to a new view object
1421 // using save and then load
1424 System.out.println("Writing jar entry " + fileName);
1425 JarEntry entry = new JarEntry(fileName);
1426 jout.putNextEntry(entry);
1427 PrintWriter pout = new PrintWriter(new OutputStreamWriter(jout,
1429 Marshaller marshaller = new Marshaller(pout);
1430 marshaller.marshal(object);
1433 } catch (Exception ex)
1435 // TODO: raise error in GUI if marshalling failed.
1436 ex.printStackTrace();
1443 * Save any Varna viewers linked to this sequence. Writes an rnaViewer element
1444 * for each viewer, with
1446 * <li>viewer geometry (position, size, split pane divider location)</li>
1447 * <li>index of the selected structure in the viewer (currently shows gapped
1449 * <li>the id of the annotation holding RNA secondary structure</li>
1450 * <li>(currently only one SS is shown per viewer, may be more in future)</li>
1452 * Varna viewer state is also written out (in native Varna XML) to separate
1453 * project jar entries. A separate entry is written for each RNA structure
1454 * displayed, with the naming convention
1456 * <li>rna_viewId_sequenceId_annotationId_[gapped|trimmed]</li>
1464 * @param storeDataset
1466 protected void saveRnaViewers(JarOutputStream jout, JSeq jseq,
1467 final SequenceI jds, List<String> viewIds, AlignmentPanel ap,
1468 boolean storeDataset)
1470 if (Desktop.desktop == null)
1474 JInternalFrame[] frames = Desktop.desktop.getAllFrames();
1475 for (int f = frames.length - 1; f > -1; f--)
1477 if (frames[f] instanceof AppVarna)
1479 AppVarna varna = (AppVarna) frames[f];
1481 * link the sequence to every viewer that is showing it and is linked to
1482 * its alignment panel
1484 if (varna.isListeningFor(jds) && ap == varna.getAlignmentPanel())
1486 String viewId = varna.getViewId();
1487 RnaViewer rna = new RnaViewer();
1488 rna.setViewId(viewId);
1489 rna.setTitle(varna.getTitle());
1490 rna.setXpos(varna.getX());
1491 rna.setYpos(varna.getY());
1492 rna.setWidth(varna.getWidth());
1493 rna.setHeight(varna.getHeight());
1494 rna.setDividerLocation(varna.getDividerLocation());
1495 rna.setSelectedRna(varna.getSelectedIndex());
1496 jseq.addRnaViewer(rna);
1499 * Store each Varna panel's state once in the project per sequence.
1500 * First time through only (storeDataset==false)
1502 // boolean storeSessions = false;
1503 // String sequenceViewId = viewId + seqsToIds.get(jds);
1504 // if (!storeDataset && !viewIds.contains(sequenceViewId))
1506 // viewIds.add(sequenceViewId);
1507 // storeSessions = true;
1509 for (RnaModel model : varna.getModels())
1511 if (model.seq == jds)
1514 * VARNA saves each view (sequence or alignment secondary
1515 * structure, gapped or trimmed) as a separate XML file
1517 String jarEntryName = rnaSessions.get(model);
1518 if (jarEntryName == null)
1521 String varnaStateFile = varna.getStateInfo(model.rna);
1522 jarEntryName = RNA_PREFIX + viewId + "_" + nextCounter();
1523 copyFileToJar(jout, varnaStateFile, jarEntryName);
1524 rnaSessions.put(model, jarEntryName);
1526 SecondaryStructure ss = new SecondaryStructure();
1527 String annotationId = varna.getAnnotation(jds).annotationId;
1528 ss.setAnnotationId(annotationId);
1529 ss.setViewerState(jarEntryName);
1530 ss.setGapped(model.gapped);
1531 ss.setTitle(model.title);
1532 rna.addSecondaryStructure(ss);
1541 * Copy the contents of a file to a new entry added to the output jar
1545 * @param jarEntryName
1547 protected void copyFileToJar(JarOutputStream jout, String infilePath,
1548 String jarEntryName)
1550 DataInputStream dis = null;
1553 File file = new File(infilePath);
1554 if (file.exists() && jout != null)
1556 dis = new DataInputStream(new FileInputStream(file));
1557 byte[] data = new byte[(int) file.length()];
1558 dis.readFully(data);
1559 writeJarEntry(jout, jarEntryName, data);
1561 } catch (Exception ex)
1563 ex.printStackTrace();
1571 } catch (IOException e)
1580 * Write the data to a new entry of given name in the output jar file
1583 * @param jarEntryName
1585 * @throws IOException
1587 protected void writeJarEntry(JarOutputStream jout, String jarEntryName,
1588 byte[] data) throws IOException
1592 System.out.println("Writing jar entry " + jarEntryName);
1593 jout.putNextEntry(new JarEntry(jarEntryName));
1594 DataOutputStream dout = new DataOutputStream(jout);
1595 dout.write(data, 0, data.length);
1602 * Save the state of a structure viewer
1607 * the archive XML element under which to save the state
1610 * @param matchedFile
1614 protected String saveStructureState(AlignmentPanel ap, SequenceI jds,
1615 Pdbids pdb, PDBEntry entry, List<String> viewIds,
1616 String matchedFile, StructureViewerBase viewFrame)
1618 final AAStructureBindingModel bindingModel = viewFrame.getBinding();
1621 * Look for any bindings for this viewer to the PDB file of interest
1622 * (including part matches excluding chain id)
1624 for (int peid = 0; peid < bindingModel.getPdbCount(); peid++)
1626 final PDBEntry pdbentry = bindingModel.getPdbEntry(peid);
1627 final String pdbId = pdbentry.getId();
1628 if (!pdbId.equals(entry.getId())
1629 && !(entry.getId().length() > 4 && entry.getId()
1630 .toLowerCase().startsWith(pdbId.toLowerCase())))
1633 * not interested in a binding to a different PDB entry here
1637 if (matchedFile == null)
1639 matchedFile = pdbentry.getFile();
1641 else if (!matchedFile.equals(pdbentry.getFile()))
1644 .warn("Probably lost some PDB-Sequence mappings for this structure file (which apparently has same PDB Entry code): "
1645 + pdbentry.getFile());
1649 // can get at it if the ID
1650 // match is ambiguous (e.g.
1653 for (int smap = 0; smap < viewFrame.getBinding().getSequence()[peid].length; smap++)
1655 // if (jal.findIndex(jmol.jmb.sequence[peid][smap]) > -1)
1656 if (jds == viewFrame.getBinding().getSequence()[peid][smap])
1658 StructureState state = new StructureState();
1659 state.setVisible(true);
1660 state.setXpos(viewFrame.getX());
1661 state.setYpos(viewFrame.getY());
1662 state.setWidth(viewFrame.getWidth());
1663 state.setHeight(viewFrame.getHeight());
1664 final String viewId = viewFrame.getViewId();
1665 state.setViewId(viewId);
1666 state.setAlignwithAlignPanel(viewFrame.isUsedforaligment(ap));
1667 state.setColourwithAlignPanel(viewFrame.isUsedforcolourby(ap));
1668 state.setColourByJmol(viewFrame.isColouredByViewer());
1669 state.setType(viewFrame.getViewerType().toString());
1670 pdb.addStructureState(state);
1677 private AnnotationColours constructAnnotationColours(
1678 AnnotationColourGradient acg, List<UserColourScheme> userColours,
1679 JalviewModelSequence jms)
1681 AnnotationColours ac = new AnnotationColours();
1682 ac.setAboveThreshold(acg.getAboveThreshold());
1683 ac.setThreshold(acg.getAnnotationThreshold());
1684 ac.setAnnotation(acg.getAnnotation());
1685 if (acg.getBaseColour() instanceof jalview.schemes.UserColourScheme)
1687 ac.setColourScheme(setUserColourScheme(acg.getBaseColour(),
1692 ac.setColourScheme(ColourSchemeProperty.getColourName(acg
1696 ac.setMaxColour(acg.getMaxColour().getRGB());
1697 ac.setMinColour(acg.getMinColour().getRGB());
1698 ac.setPerSequence(acg.isSeqAssociated());
1699 ac.setPredefinedColours(acg.isPredefinedColours());
1703 private void storeAlignmentAnnotation(AlignmentAnnotation[] aa,
1704 IdentityHashMap<SequenceGroup, String> groupRefs,
1705 AlignmentViewport av, Set<String> calcIdSet, boolean storeDS,
1706 SequenceSet vamsasSet)
1709 for (int i = 0; i < aa.length; i++)
1711 Annotation an = new Annotation();
1713 AlignmentAnnotation annotation = aa[i];
1714 if (annotation.annotationId != null)
1716 annotationIds.put(annotation.annotationId, annotation);
1719 an.setId(annotation.annotationId);
1721 an.setVisible(annotation.visible);
1723 an.setDescription(annotation.description);
1725 if (annotation.sequenceRef != null)
1727 // 2.9 JAL-1781 xref on sequence id rather than name
1728 an.setSequenceRef(seqsToIds.get(annotation.sequenceRef));
1730 if (annotation.groupRef != null)
1732 String groupIdr = groupRefs.get(annotation.groupRef);
1733 if (groupIdr == null)
1735 // make a locally unique String
1737 annotation.groupRef,
1738 groupIdr = ("" + System.currentTimeMillis()
1739 + annotation.groupRef.getName() + groupRefs
1742 an.setGroupRef(groupIdr.toString());
1745 // store all visualization attributes for annotation
1746 an.setGraphHeight(annotation.graphHeight);
1747 an.setCentreColLabels(annotation.centreColLabels);
1748 an.setScaleColLabels(annotation.scaleColLabel);
1749 an.setShowAllColLabels(annotation.showAllColLabels);
1750 an.setBelowAlignment(annotation.belowAlignment);
1752 if (annotation.graph > 0)
1755 an.setGraphType(annotation.graph);
1756 an.setGraphGroup(annotation.graphGroup);
1757 if (annotation.getThreshold() != null)
1759 ThresholdLine line = new ThresholdLine();
1760 line.setLabel(annotation.getThreshold().label);
1761 line.setValue(annotation.getThreshold().value);
1762 line.setColour(annotation.getThreshold().colour.getRGB());
1763 an.setThresholdLine(line);
1771 an.setLabel(annotation.label);
1773 if (annotation == av.getAlignmentQualityAnnot()
1774 || annotation == av.getAlignmentConservationAnnotation()
1775 || annotation == av.getAlignmentConsensusAnnotation()
1776 || annotation.autoCalculated)
1778 // new way of indicating autocalculated annotation -
1779 an.setAutoCalculated(annotation.autoCalculated);
1781 if (annotation.hasScore())
1783 an.setScore(annotation.getScore());
1786 if (annotation.getCalcId() != null)
1788 calcIdSet.add(annotation.getCalcId());
1789 an.setCalcId(annotation.getCalcId());
1791 if (annotation.hasProperties())
1793 for (String pr : annotation.getProperties())
1795 Property prop = new Property();
1797 prop.setValue(annotation.getProperty(pr));
1798 an.addProperty(prop);
1802 AnnotationElement ae;
1803 if (annotation.annotations != null)
1805 an.setScoreOnly(false);
1806 for (int a = 0; a < annotation.annotations.length; a++)
1808 if ((annotation == null) || (annotation.annotations[a] == null))
1813 ae = new AnnotationElement();
1814 if (annotation.annotations[a].description != null)
1816 ae.setDescription(annotation.annotations[a].description);
1818 if (annotation.annotations[a].displayCharacter != null)
1820 ae.setDisplayCharacter(annotation.annotations[a].displayCharacter);
1823 if (!Float.isNaN(annotation.annotations[a].value))
1825 ae.setValue(annotation.annotations[a].value);
1829 if (annotation.annotations[a].secondaryStructure > ' ')
1831 ae.setSecondaryStructure(annotation.annotations[a].secondaryStructure
1835 if (annotation.annotations[a].colour != null
1836 && annotation.annotations[a].colour != java.awt.Color.black)
1838 ae.setColour(annotation.annotations[a].colour.getRGB());
1841 an.addAnnotationElement(ae);
1842 if (annotation.autoCalculated)
1844 // only write one non-null entry into the annotation row -
1845 // sufficient to get the visualization attributes necessary to
1853 an.setScoreOnly(true);
1855 if (!storeDS || (storeDS && !annotation.autoCalculated))
1857 // skip autocalculated annotation - these are only provided for
1859 vamsasSet.addAnnotation(an);
1865 private CalcIdParam createCalcIdParam(String calcId, AlignViewport av)
1867 AutoCalcSetting settings = av.getCalcIdSettingsFor(calcId);
1868 if (settings != null)
1870 CalcIdParam vCalcIdParam = new CalcIdParam();
1871 vCalcIdParam.setCalcId(calcId);
1872 vCalcIdParam.addServiceURL(settings.getServiceURI());
1873 // generic URI allowing a third party to resolve another instance of the
1874 // service used for this calculation
1875 for (String urls : settings.getServiceURLs())
1877 vCalcIdParam.addServiceURL(urls);
1879 vCalcIdParam.setVersion("1.0");
1880 if (settings.getPreset() != null)
1882 WsParamSetI setting = settings.getPreset();
1883 vCalcIdParam.setName(setting.getName());
1884 vCalcIdParam.setDescription(setting.getDescription());
1888 vCalcIdParam.setName("");
1889 vCalcIdParam.setDescription("Last used parameters");
1891 // need to be able to recover 1) settings 2) user-defined presets or
1892 // recreate settings from preset 3) predefined settings provided by
1893 // service - or settings that can be transferred (or discarded)
1894 vCalcIdParam.setParameters(settings.getWsParamFile().replace("\n",
1896 vCalcIdParam.setAutoUpdate(settings.isAutoUpdate());
1897 // todo - decide if updateImmediately is needed for any projects.
1899 return vCalcIdParam;
1904 private boolean recoverCalcIdParam(CalcIdParam calcIdParam,
1907 if (calcIdParam.getVersion().equals("1.0"))
1909 Jws2Instance service = Jws2Discoverer.getDiscoverer()
1910 .getPreferredServiceFor(calcIdParam.getServiceURL());
1911 if (service != null)
1913 WsParamSetI parmSet = null;
1916 parmSet = service.getParamStore().parseServiceParameterFile(
1917 calcIdParam.getName(), calcIdParam.getDescription(),
1918 calcIdParam.getServiceURL(),
1919 calcIdParam.getParameters().replace("|\\n|", "\n"));
1920 } catch (IOException x)
1922 warn("Couldn't parse parameter data for "
1923 + calcIdParam.getCalcId(), x);
1926 List<ArgumentI> argList = null;
1927 if (calcIdParam.getName().length() > 0)
1929 parmSet = service.getParamStore()
1930 .getPreset(calcIdParam.getName());
1931 if (parmSet != null)
1933 // TODO : check we have a good match with settings in AACon -
1934 // otherwise we'll need to create a new preset
1939 argList = parmSet.getArguments();
1942 AAConSettings settings = new AAConSettings(
1943 calcIdParam.isAutoUpdate(), service, parmSet, argList);
1944 av.setCalcIdSettingsFor(calcIdParam.getCalcId(), settings,
1945 calcIdParam.isNeedsUpdate());
1950 warn("Cannot resolve a service for the parameters used in this project. Try configuring a JABAWS server.");
1954 throw new Error(MessageManager.formatMessage(
1955 "error.unsupported_version_calcIdparam",
1956 new Object[] { calcIdParam.toString() }));
1960 * External mapping between jalview objects and objects yielding a valid and
1961 * unique object ID string. This is null for normal Jalview project IO, but
1962 * non-null when a jalview project is being read or written as part of a
1965 IdentityHashMap jv2vobj = null;
1968 * Construct a unique ID for jvobj using either existing bindings or if none
1969 * exist, the result of the hashcode call for the object.
1972 * jalview data object
1973 * @return unique ID for referring to jvobj
1975 private String makeHashCode(Object jvobj, String altCode)
1977 if (jv2vobj != null)
1979 Object id = jv2vobj.get(jvobj);
1982 return id.toString();
1984 // check string ID mappings
1985 if (jvids2vobj != null && jvobj instanceof String)
1987 id = jvids2vobj.get(jvobj);
1991 return id.toString();
1993 // give up and warn that something has gone wrong
1994 warn("Cannot find ID for object in external mapping : " + jvobj);
2000 * return local jalview object mapped to ID, if it exists
2004 * @return null or object bound to idcode
2006 private Object retrieveExistingObj(String idcode)
2008 if (idcode != null && vobj2jv != null)
2010 return vobj2jv.get(idcode);
2016 * binding from ID strings from external mapping table to jalview data model
2019 private Hashtable vobj2jv;
2021 private Sequence createVamsasSequence(String id, SequenceI jds)
2023 return createVamsasSequence(true, id, jds, null);
2026 private Sequence createVamsasSequence(boolean recurse, String id,
2027 SequenceI jds, SequenceI parentseq)
2029 Sequence vamsasSeq = new Sequence();
2030 vamsasSeq.setId(id);
2031 vamsasSeq.setName(jds.getName());
2032 vamsasSeq.setSequence(jds.getSequenceAsString());
2033 vamsasSeq.setDescription(jds.getDescription());
2034 jalview.datamodel.DBRefEntry[] dbrefs = null;
2035 if (jds.getDatasetSequence() != null)
2037 vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
2038 if (jds.getDatasetSequence().getDBRefs() != null)
2040 dbrefs = jds.getDatasetSequence().getDBRefs();
2045 vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
2046 // dataset sequences only
2047 dbrefs = jds.getDBRefs();
2051 for (int d = 0; d < dbrefs.length; d++)
2053 DBRef dbref = new DBRef();
2054 dbref.setSource(dbrefs[d].getSource());
2055 dbref.setVersion(dbrefs[d].getVersion());
2056 dbref.setAccessionId(dbrefs[d].getAccessionId());
2057 if (dbrefs[d].hasMap())
2059 Mapping mp = createVamsasMapping(dbrefs[d].getMap(), parentseq,
2061 dbref.setMapping(mp);
2063 vamsasSeq.addDBRef(dbref);
2069 private Mapping createVamsasMapping(jalview.datamodel.Mapping jmp,
2070 SequenceI parentseq, SequenceI jds, boolean recurse)
2073 if (jmp.getMap() != null)
2077 jalview.util.MapList mlst = jmp.getMap();
2078 List<int[]> r = mlst.getFromRanges();
2079 for (int[] range : r)
2081 MapListFrom mfrom = new MapListFrom();
2082 mfrom.setStart(range[0]);
2083 mfrom.setEnd(range[1]);
2084 mp.addMapListFrom(mfrom);
2086 r = mlst.getToRanges();
2087 for (int[] range : r)
2089 MapListTo mto = new MapListTo();
2090 mto.setStart(range[0]);
2091 mto.setEnd(range[1]);
2092 mp.addMapListTo(mto);
2094 mp.setMapFromUnit(mlst.getFromRatio());
2095 mp.setMapToUnit(mlst.getToRatio());
2096 if (jmp.getTo() != null)
2098 MappingChoice mpc = new MappingChoice();
2100 && (parentseq != jmp.getTo() || parentseq
2101 .getDatasetSequence() != jmp.getTo()))
2103 mpc.setSequence(createVamsasSequence(false, seqHash(jmp.getTo()),
2109 SequenceI ps = null;
2110 if (parentseq != jmp.getTo()
2111 && parentseq.getDatasetSequence() != jmp.getTo())
2113 // chaining dbref rather than a handshaking one
2114 jmpid = seqHash(ps = jmp.getTo());
2118 jmpid = seqHash(ps = parentseq);
2120 mpc.setDseqFor(jmpid);
2121 if (!seqRefIds.containsKey(mpc.getDseqFor()))
2123 jalview.bin.Cache.log.debug("creatign new DseqFor ID");
2124 seqRefIds.put(mpc.getDseqFor(), ps);
2128 jalview.bin.Cache.log.debug("reusing DseqFor ID");
2131 mp.setMappingChoice(mpc);
2137 String setUserColourScheme(jalview.schemes.ColourSchemeI cs,
2138 List<UserColourScheme> userColours, JalviewModelSequence jms)
2141 jalview.schemes.UserColourScheme ucs = (jalview.schemes.UserColourScheme) cs;
2142 boolean newucs = false;
2143 if (!userColours.contains(ucs))
2145 userColours.add(ucs);
2148 id = "ucs" + userColours.indexOf(ucs);
2151 // actually create the scheme's entry in the XML model
2152 java.awt.Color[] colours = ucs.getColours();
2153 jalview.schemabinding.version2.UserColours uc = new jalview.schemabinding.version2.UserColours();
2154 jalview.schemabinding.version2.UserColourScheme jbucs = new jalview.schemabinding.version2.UserColourScheme();
2156 for (int i = 0; i < colours.length; i++)
2158 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2159 col.setName(ResidueProperties.aa[i]);
2160 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2161 jbucs.addColour(col);
2163 if (ucs.getLowerCaseColours() != null)
2165 colours = ucs.getLowerCaseColours();
2166 for (int i = 0; i < colours.length; i++)
2168 jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
2169 col.setName(ResidueProperties.aa[i].toLowerCase());
2170 col.setRGB(jalview.util.Format.getHexString(colours[i]));
2171 jbucs.addColour(col);
2176 uc.setUserColourScheme(jbucs);
2177 jms.addUserColours(uc);
2183 jalview.schemes.UserColourScheme getUserColourScheme(
2184 JalviewModelSequence jms, String id)
2186 UserColours[] uc = jms.getUserColours();
2187 UserColours colours = null;
2189 for (int i = 0; i < uc.length; i++)
2191 if (uc[i].getId().equals(id))
2199 java.awt.Color[] newColours = new java.awt.Color[24];
2201 for (int i = 0; i < 24; i++)
2203 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2204 .getUserColourScheme().getColour(i).getRGB(), 16));
2207 jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(
2210 if (colours.getUserColourScheme().getColourCount() > 24)
2212 newColours = new java.awt.Color[23];
2213 for (int i = 0; i < 23; i++)
2215 newColours[i] = new java.awt.Color(Integer.parseInt(colours
2216 .getUserColourScheme().getColour(i + 24).getRGB(), 16));
2218 ucs.setLowerCaseColours(newColours);
2225 * contains last error message (if any) encountered by XML loader.
2227 String errorMessage = null;
2230 * flag to control whether the Jalview2XML_V1 parser should be deferred to if
2231 * exceptions are raised during project XML parsing
2233 public boolean attemptversion1parse = true;
2236 * Load a jalview project archive from a jar file
2239 * - HTTP URL or filename
2241 public AlignFrame loadJalviewAlign(final String file)
2244 jalview.gui.AlignFrame af = null;
2248 // create list to store references for any new Jmol viewers created
2249 newStructureViewers = new Vector<JalviewStructureDisplayI>();
2250 // UNMARSHALLER SEEMS TO CLOSE JARINPUTSTREAM, MOST ANNOYING
2251 // Workaround is to make sure caller implements the JarInputStreamProvider
2253 // so we can re-open the jar input stream for each entry.
2255 jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
2256 af = loadJalviewAlign(jprovider);
2258 } catch (MalformedURLException e)
2260 errorMessage = "Invalid URL format for '" + file + "'";
2266 SwingUtilities.invokeAndWait(new Runnable()
2271 setLoadingFinishedForNewStructureViewers();
2274 } catch (Exception x)
2276 System.err.println("Error loading alignment: " + x.getMessage());
2282 private jarInputStreamProvider createjarInputStreamProvider(
2283 final String file) throws MalformedURLException
2286 errorMessage = null;
2287 uniqueSetSuffix = null;
2289 viewportsAdded.clear();
2290 frefedSequence = null;
2292 if (file.startsWith("http://"))
2294 url = new URL(file);
2296 final URL _url = url;
2297 return new jarInputStreamProvider()
2301 public JarInputStream getJarInputStream() throws IOException
2305 return new JarInputStream(_url.openStream());
2309 return new JarInputStream(new FileInputStream(file));
2314 public String getFilename()
2322 * Recover jalview session from a jalview project archive. Caller may
2323 * initialise uniqueSetSuffix, seqRefIds, viewportsAdded and frefedSequence
2324 * themselves. Any null fields will be initialised with default values,
2325 * non-null fields are left alone.
2330 public AlignFrame loadJalviewAlign(final jarInputStreamProvider jprovider)
2332 errorMessage = null;
2333 if (uniqueSetSuffix == null)
2335 uniqueSetSuffix = System.currentTimeMillis() % 100000 + "";
2337 if (seqRefIds == null)
2341 AlignFrame af = null, _af = null;
2342 Map<String, AlignFrame> gatherToThisFrame = new HashMap<String, AlignFrame>();
2343 final String file = jprovider.getFilename();
2346 JarInputStream jin = null;
2347 JarEntry jarentry = null;
2352 jin = jprovider.getJarInputStream();
2353 for (int i = 0; i < entryCount; i++)
2355 jarentry = jin.getNextJarEntry();
2358 if (jarentry != null && jarentry.getName().endsWith(".xml"))
2360 InputStreamReader in = new InputStreamReader(jin, UTF_8);
2361 JalviewModel object = new JalviewModel();
2363 Unmarshaller unmar = new Unmarshaller(object);
2364 unmar.setValidation(false);
2365 object = (JalviewModel) unmar.unmarshal(in);
2366 if (true) // !skipViewport(object))
2368 _af = loadFromObject(object, file, true, jprovider);
2369 if (object.getJalviewModelSequence().getViewportCount() > 0)
2372 if (af.viewport.isGatherViewsHere())
2374 gatherToThisFrame.put(af.viewport.getSequenceSetId(), af);
2380 else if (jarentry != null)
2382 // Some other file here.
2385 } while (jarentry != null);
2386 resolveFrefedSequences();
2387 } catch (IOException ex)
2389 ex.printStackTrace();
2390 errorMessage = "Couldn't locate Jalview XML file : " + file;
2391 System.err.println("Exception whilst loading jalview XML file : "
2393 } catch (Exception ex)
2395 System.err.println("Parsing as Jalview Version 2 file failed.");
2396 ex.printStackTrace(System.err);
2397 if (attemptversion1parse)
2399 // Is Version 1 Jar file?
2402 af = new Jalview2XML_V1(raiseGUI).LoadJalviewAlign(jprovider);
2403 } catch (Exception ex2)
2405 System.err.println("Exception whilst loading as jalviewXMLV1:");
2406 ex2.printStackTrace();
2410 if (Desktop.instance != null)
2412 Desktop.instance.stopLoading();
2416 System.out.println("Successfully loaded archive file");
2419 ex.printStackTrace();
2421 System.err.println("Exception whilst loading jalview XML file : "
2423 } catch (OutOfMemoryError e)
2425 // Don't use the OOM Window here
2426 errorMessage = "Out of memory loading jalview XML file";
2427 System.err.println("Out of memory whilst loading jalview XML file");
2428 e.printStackTrace();
2431 if (Desktop.instance != null)
2433 Desktop.instance.stopLoading();
2437 * Regather multiple views (with the same sequence set id) to the frame (if
2438 * any) that is flagged as the one to gather to, i.e. convert them to tabbed
2439 * views instead of separate frames. Note this doesn't restore a state where
2440 * some expanded views in turn have tabbed views - the last "first tab" read
2441 * in will play the role of gatherer for all.
2443 for (AlignFrame fr : gatherToThisFrame.values())
2445 Desktop.instance.gatherViews(fr);
2448 restoreSplitFrames();
2450 if (errorMessage != null)
2458 * Try to reconstruct and display SplitFrame windows, where each contains
2459 * complementary dna and protein alignments. Done by pairing up AlignFrame
2460 * objects (created earlier) which have complementary viewport ids associated.
2462 protected void restoreSplitFrames()
2464 List<SplitFrame> gatherTo = new ArrayList<SplitFrame>();
2465 List<AlignFrame> addedToSplitFrames = new ArrayList<AlignFrame>();
2466 Map<String, AlignFrame> dna = new HashMap<String, AlignFrame>();
2469 * Identify the DNA alignments
2471 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2474 AlignFrame af = candidate.getValue();
2475 if (af.getViewport().getAlignment().isNucleotide())
2477 dna.put(candidate.getKey().getId(), af);
2482 * Try to match up the protein complements
2484 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2487 AlignFrame af = candidate.getValue();
2488 if (!af.getViewport().getAlignment().isNucleotide())
2490 String complementId = candidate.getKey().getComplementId();
2491 // only non-null complements should be in the Map
2492 if (complementId != null && dna.containsKey(complementId))
2494 final AlignFrame dnaFrame = dna.get(complementId);
2495 SplitFrame sf = createSplitFrame(dnaFrame, af);
2496 addedToSplitFrames.add(dnaFrame);
2497 addedToSplitFrames.add(af);
2498 if (af.viewport.isGatherViewsHere())
2507 * Open any that we failed to pair up (which shouldn't happen!) as
2508 * standalone AlignFrame's.
2510 for (Entry<Viewport, AlignFrame> candidate : splitFrameCandidates
2513 AlignFrame af = candidate.getValue();
2514 if (!addedToSplitFrames.contains(af))
2516 Viewport view = candidate.getKey();
2517 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
2519 System.err.println("Failed to restore view " + view.getTitle()
2520 + " to split frame");
2525 * Gather back into tabbed views as flagged.
2527 for (SplitFrame sf : gatherTo)
2529 Desktop.instance.gatherViews(sf);
2532 splitFrameCandidates.clear();
2536 * Construct and display one SplitFrame holding DNA and protein alignments.
2539 * @param proteinFrame
2542 protected SplitFrame createSplitFrame(AlignFrame dnaFrame,
2543 AlignFrame proteinFrame)
2545 SplitFrame splitFrame = new SplitFrame(dnaFrame, proteinFrame);
2546 String title = MessageManager.getString("label.linked_view_title");
2547 int width = (int) dnaFrame.getBounds().getWidth();
2548 int height = (int) (dnaFrame.getBounds().getHeight()
2549 + proteinFrame.getBounds().getHeight() + 50);
2552 * SplitFrame location is saved to both enclosed frames
2554 splitFrame.setLocation(dnaFrame.getX(), dnaFrame.getY());
2555 Desktop.addInternalFrame(splitFrame, title, width, height);
2558 * And compute cDNA consensus (couldn't do earlier with consensus as
2559 * mappings were not yet present)
2561 proteinFrame.viewport.alignmentChanged(proteinFrame.alignPanel);
2567 * check errorMessage for a valid error message and raise an error box in the
2568 * GUI or write the current errorMessage to stderr and then clear the error
2571 protected void reportErrors()
2573 reportErrors(false);
2576 protected void reportErrors(final boolean saving)
2578 if (errorMessage != null)
2580 final String finalErrorMessage = errorMessage;
2583 javax.swing.SwingUtilities.invokeLater(new Runnable()
2588 JOptionPane.showInternalMessageDialog(Desktop.desktop,
2589 finalErrorMessage, "Error "
2590 + (saving ? "saving" : "loading")
2591 + " Jalview file", JOptionPane.WARNING_MESSAGE);
2597 System.err.println("Problem loading Jalview file: " + errorMessage);
2600 errorMessage = null;
2603 Map<String, String> alreadyLoadedPDB = new HashMap<String, String>();
2606 * when set, local views will be updated from view stored in JalviewXML
2607 * Currently (28th Sep 2008) things will go horribly wrong in vamsas document
2608 * sync if this is set to true.
2610 private final boolean updateLocalViews = false;
2613 * Returns the path to a temporary file holding the PDB file for the given PDB
2614 * id. The first time of asking, searches for a file of that name in the
2615 * Jalview project jar, and copies it to a new temporary file. Any repeat
2616 * requests just return the path to the file previously created.
2622 String loadPDBFile(jarInputStreamProvider jprovider, String pdbId)
2624 if (alreadyLoadedPDB.containsKey(pdbId))
2626 return alreadyLoadedPDB.get(pdbId).toString();
2629 String tempFile = copyJarEntry(jprovider, pdbId, "jalview_pdb");
2630 if (tempFile != null)
2632 alreadyLoadedPDB.put(pdbId, tempFile);
2638 * Copies the jar entry of given name to a new temporary file and returns the
2639 * path to the file, or null if the entry is not found.
2642 * @param jarEntryName
2644 * a prefix for the temporary file name, must be at least three
2648 protected String copyJarEntry(jarInputStreamProvider jprovider,
2649 String jarEntryName, String prefix)
2651 BufferedReader in = null;
2652 PrintWriter out = null;
2656 JarInputStream jin = jprovider.getJarInputStream();
2658 * if (jprovider.startsWith("http://")) { jin = new JarInputStream(new
2659 * URL(jprovider).openStream()); } else { jin = new JarInputStream(new
2660 * FileInputStream(jprovider)); }
2663 JarEntry entry = null;
2666 entry = jin.getNextJarEntry();
2667 } while (entry != null && !entry.getName().equals(jarEntryName));
2670 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
2671 File outFile = File.createTempFile(prefix, ".tmp");
2672 outFile.deleteOnExit();
2673 out = new PrintWriter(new FileOutputStream(outFile));
2676 while ((data = in.readLine()) != null)
2681 String t = outFile.getAbsolutePath();
2686 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
2688 } catch (Exception ex)
2690 ex.printStackTrace();
2698 } catch (IOException e)
2712 private class JvAnnotRow
2714 public JvAnnotRow(int i, AlignmentAnnotation jaa)
2721 * persisted version of annotation row from which to take vis properties
2723 public jalview.datamodel.AlignmentAnnotation template;
2726 * original position of the annotation row in the alignment
2732 * Load alignment frame from jalview XML DOM object
2737 * filename source string
2738 * @param loadTreesAndStructures
2739 * when false only create Viewport
2741 * data source provider
2742 * @return alignment frame created from view stored in DOM
2744 AlignFrame loadFromObject(JalviewModel object, String file,
2745 boolean loadTreesAndStructures, jarInputStreamProvider jprovider)
2747 SequenceSet vamsasSet = object.getVamsasModel().getSequenceSet(0);
2748 Sequence[] vamsasSeq = vamsasSet.getSequence();
2750 JalviewModelSequence jms = object.getJalviewModelSequence();
2752 Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
2755 // ////////////////////////////////
2758 List<SequenceI> hiddenSeqs = null;
2761 List<SequenceI> tmpseqs = new ArrayList<SequenceI>();
2763 boolean multipleView = false;
2764 SequenceI referenceseqForView = null;
2765 JSeq[] jseqs = object.getJalviewModelSequence().getJSeq();
2766 int vi = 0; // counter in vamsasSeq array
2767 for (int i = 0; i < jseqs.length; i++)
2769 String seqId = jseqs[i].getId();
2771 SequenceI tmpSeq = seqRefIds.get(seqId);
2774 if (!incompleteSeqs.containsKey(seqId))
2776 // may not need this check, but keep it for at least 2.9,1 release
2777 if (tmpSeq.getStart()!=jseqs[i].getStart() || tmpSeq.getEnd()!=jseqs[i].getEnd())
2780 .println("Warning JAL-2154 regression: updating start/end for sequence "
2781 + tmpSeq.toString());
2784 incompleteSeqs.remove(seqId);
2786 tmpSeq.setStart(jseqs[i].getStart());
2787 tmpSeq.setEnd(jseqs[i].getEnd());
2788 tmpseqs.add(tmpSeq);
2789 multipleView = true;
2793 tmpSeq = new jalview.datamodel.Sequence(vamsasSeq[vi].getName(),
2794 vamsasSeq[vi].getSequence());
2795 tmpSeq.setDescription(vamsasSeq[vi].getDescription());
2796 tmpSeq.setStart(jseqs[i].getStart());
2797 tmpSeq.setEnd(jseqs[i].getEnd());
2798 tmpSeq.setVamsasId(uniqueSetSuffix + seqId);
2799 seqRefIds.put(vamsasSeq[vi].getId(), tmpSeq);
2800 tmpseqs.add(tmpSeq);
2804 if (jseqs[i].hasViewreference() && jseqs[i].getViewreference())
2806 referenceseqForView = tmpseqs.get(tmpseqs.size() - 1);
2809 if (jseqs[i].getHidden())
2811 if (hiddenSeqs == null)
2813 hiddenSeqs = new ArrayList<SequenceI>();
2816 hiddenSeqs.add(tmpSeq);
2821 // Create the alignment object from the sequence set
2822 // ///////////////////////////////
2823 SequenceI[] orderedSeqs = tmpseqs
2824 .toArray(new SequenceI[tmpseqs.size()]);
2826 AlignmentI al = new Alignment(orderedSeqs);
2828 if (referenceseqForView != null)
2830 al.setSeqrep(referenceseqForView);
2832 // / Add the alignment properties
2833 for (int i = 0; i < vamsasSet.getSequenceSetPropertiesCount(); i++)
2835 SequenceSetProperties ssp = vamsasSet.getSequenceSetProperties(i);
2836 al.setProperty(ssp.getKey(), ssp.getValue());
2840 // SequenceFeatures are added to the DatasetSequence,
2841 // so we must create or recover the dataset before loading features
2842 // ///////////////////////////////
2843 if (vamsasSet.getDatasetId() == null || vamsasSet.getDatasetId() == "")
2845 // older jalview projects do not have a dataset id.
2846 al.setDataset(null);
2850 // recover dataset - passing on flag indicating if this a 'viewless'
2851 // sequence set (a.k.a. a stored dataset for the project)
2852 recoverDatasetFor(vamsasSet, al, object.getJalviewModelSequence()
2853 .getViewportCount() == 0);
2855 // ///////////////////////////////
2857 Hashtable pdbloaded = new Hashtable(); // TODO nothing writes to this??
2860 // load sequence features, database references and any associated PDB
2861 // structures for the alignment
2862 for (int i = 0; i < vamsasSeq.length; i++)
2864 if (jseqs[i].getFeaturesCount() > 0)
2866 Features[] features = jseqs[i].getFeatures();
2867 for (int f = 0; f < features.length; f++)
2869 jalview.datamodel.SequenceFeature sf = new jalview.datamodel.SequenceFeature(
2870 features[f].getType(), features[f].getDescription(),
2871 features[f].getStatus(), features[f].getBegin(),
2872 features[f].getEnd(), features[f].getFeatureGroup());
2874 sf.setScore(features[f].getScore());
2875 for (int od = 0; od < features[f].getOtherDataCount(); od++)
2877 OtherData keyValue = features[f].getOtherData(od);
2878 if (keyValue.getKey().startsWith("LINK"))
2880 sf.addLink(keyValue.getValue());
2884 sf.setValue(keyValue.getKey(), keyValue.getValue());
2889 al.getSequenceAt(i).getDatasetSequence().addSequenceFeature(sf);
2892 if (vamsasSeq[i].getDBRefCount() > 0)
2894 addDBRefs(al.getSequenceAt(i).getDatasetSequence(), vamsasSeq[i]);
2896 if (jseqs[i].getPdbidsCount() > 0)
2898 Pdbids[] ids = jseqs[i].getPdbids();
2899 for (int p = 0; p < ids.length; p++)
2901 jalview.datamodel.PDBEntry entry = new jalview.datamodel.PDBEntry();
2902 entry.setId(ids[p].getId());
2903 if (ids[p].getType() != null)
2905 if (ids[p].getType().equalsIgnoreCase("PDB"))
2907 entry.setType(PDBEntry.Type.PDB);
2911 entry.setType(PDBEntry.Type.FILE);
2914 if (ids[p].getFile() != null)
2916 if (!pdbloaded.containsKey(ids[p].getFile()))
2918 entry.setFile(loadPDBFile(jprovider, ids[p].getId()));
2922 entry.setFile(pdbloaded.get(ids[p].getId()).toString());
2925 StructureSelectionManager.getStructureSelectionManager(
2926 Desktop.instance).registerPDBEntry(entry);
2927 al.getSequenceAt(i).getDatasetSequence().addPDBId(entry);
2931 } // end !multipleview
2933 // ///////////////////////////////
2934 // LOAD SEQUENCE MAPPINGS
2936 if (vamsasSet.getAlcodonFrameCount() > 0)
2938 // TODO Potentially this should only be done once for all views of an
2940 AlcodonFrame[] alc = vamsasSet.getAlcodonFrame();
2941 for (int i = 0; i < alc.length; i++)
2943 AlignedCodonFrame cf = new AlignedCodonFrame();
2944 if (alc[i].getAlcodMapCount() > 0)
2946 AlcodMap[] maps = alc[i].getAlcodMap();
2947 for (int m = 0; m < maps.length; m++)
2949 SequenceI dnaseq = seqRefIds.get(maps[m].getDnasq());
2951 jalview.datamodel.Mapping mapping = null;
2952 // attach to dna sequence reference.
2953 if (maps[m].getMapping() != null)
2955 mapping = addMapping(maps[m].getMapping());
2957 if (dnaseq != null && mapping.getTo() != null)
2959 cf.addMap(dnaseq, mapping.getTo(), mapping.getMap());
2964 frefedSequence.add(newAlcodMapRef(maps[m].getDnasq(), cf,
2968 al.addCodonFrame(cf);
2973 // ////////////////////////////////
2975 List<JvAnnotRow> autoAlan = new ArrayList<JvAnnotRow>();
2978 * store any annotations which forward reference a group's ID
2980 Map<String, List<AlignmentAnnotation>> groupAnnotRefs = new Hashtable<String, List<AlignmentAnnotation>>();
2982 if (vamsasSet.getAnnotationCount() > 0)
2984 Annotation[] an = vamsasSet.getAnnotation();
2986 for (int i = 0; i < an.length; i++)
2988 Annotation annotation = an[i];
2991 * test if annotation is automatically calculated for this view only
2993 boolean autoForView = false;
2994 if (annotation.getLabel().equals("Quality")
2995 || annotation.getLabel().equals("Conservation")
2996 || annotation.getLabel().equals("Consensus"))
2998 // Kludge for pre 2.5 projects which lacked the autocalculated flag
3000 if (!annotation.hasAutoCalculated())
3002 annotation.setAutoCalculated(true);
3006 || (annotation.hasAutoCalculated() && annotation
3007 .isAutoCalculated()))
3009 // remove ID - we don't recover annotation from other views for
3010 // view-specific annotation
3011 annotation.setId(null);
3014 // set visiblity for other annotation in this view
3015 String annotationId = annotation.getId();
3016 if (annotationId != null && annotationIds.containsKey(annotationId))
3018 AlignmentAnnotation jda = annotationIds.get(annotationId);
3019 // in principle Visible should always be true for annotation displayed
3020 // in multiple views
3021 if (annotation.hasVisible())
3023 jda.visible = annotation.getVisible();
3026 al.addAnnotation(jda);
3030 // Construct new annotation from model.
3031 AnnotationElement[] ae = annotation.getAnnotationElement();
3032 jalview.datamodel.Annotation[] anot = null;
3033 java.awt.Color firstColour = null;
3035 if (!annotation.getScoreOnly())
3037 anot = new jalview.datamodel.Annotation[al.getWidth()];
3038 for (int aa = 0; aa < ae.length && aa < anot.length; aa++)
3040 anpos = ae[aa].getPosition();
3042 if (anpos >= anot.length)
3047 anot[anpos] = new jalview.datamodel.Annotation(
3049 ae[aa].getDisplayCharacter(), ae[aa].getDescription(),
3050 (ae[aa].getSecondaryStructure() == null || ae[aa]
3051 .getSecondaryStructure().length() == 0) ? ' '
3052 : ae[aa].getSecondaryStructure().charAt(0),
3056 // JBPNote: Consider verifying dataflow for IO of secondary
3057 // structure annotation read from Stockholm files
3058 // this was added to try to ensure that
3059 // if (anot[ae[aa].getPosition()].secondaryStructure>' ')
3061 // anot[ae[aa].getPosition()].displayCharacter = "";
3063 anot[anpos].colour = new java.awt.Color(ae[aa].getColour());
3064 if (firstColour == null)
3066 firstColour = anot[anpos].colour;
3070 jalview.datamodel.AlignmentAnnotation jaa = null;
3072 if (annotation.getGraph())
3074 float llim = 0, hlim = 0;
3075 // if (autoForView || an[i].isAutoCalculated()) {
3078 jaa = new jalview.datamodel.AlignmentAnnotation(
3079 annotation.getLabel(), annotation.getDescription(), anot,
3080 llim, hlim, annotation.getGraphType());
3082 jaa.graphGroup = annotation.getGraphGroup();
3083 jaa._linecolour = firstColour;
3084 if (annotation.getThresholdLine() != null)
3086 jaa.setThreshold(new jalview.datamodel.GraphLine(annotation
3087 .getThresholdLine().getValue(), annotation
3088 .getThresholdLine().getLabel(), new java.awt.Color(
3089 annotation.getThresholdLine().getColour())));
3092 if (autoForView || annotation.isAutoCalculated())
3094 // Hardwire the symbol display line to ensure that labels for
3095 // histograms are displayed
3101 jaa = new jalview.datamodel.AlignmentAnnotation(an[i].getLabel(),
3102 an[i].getDescription(), anot);
3103 jaa._linecolour = firstColour;
3105 // register new annotation
3106 if (an[i].getId() != null)
3108 annotationIds.put(an[i].getId(), jaa);
3109 jaa.annotationId = an[i].getId();
3111 // recover sequence association
3112 String sequenceRef = an[i].getSequenceRef();
3113 if (sequenceRef != null)
3115 // from 2.9 sequenceRef is to sequence id (JAL-1781)
3116 SequenceI sequence = seqRefIds.get(sequenceRef);
3117 if (sequence == null)
3119 // in pre-2.9 projects sequence ref is to sequence name
3120 sequence = al.findName(sequenceRef);
3122 if (sequence != null)
3124 jaa.createSequenceMapping(sequence, 1, true);
3125 sequence.addAlignmentAnnotation(jaa);
3128 // and make a note of any group association
3129 if (an[i].getGroupRef() != null && an[i].getGroupRef().length() > 0)
3131 List<jalview.datamodel.AlignmentAnnotation> aal = groupAnnotRefs
3132 .get(an[i].getGroupRef());
3135 aal = new ArrayList<jalview.datamodel.AlignmentAnnotation>();
3136 groupAnnotRefs.put(an[i].getGroupRef(), aal);
3141 if (an[i].hasScore())
3143 jaa.setScore(an[i].getScore());
3145 if (an[i].hasVisible())
3147 jaa.visible = an[i].getVisible();
3150 if (an[i].hasCentreColLabels())
3152 jaa.centreColLabels = an[i].getCentreColLabels();
3155 if (an[i].hasScaleColLabels())
3157 jaa.scaleColLabel = an[i].getScaleColLabels();
3159 if (an[i].hasAutoCalculated() && an[i].isAutoCalculated())
3161 // newer files have an 'autoCalculated' flag and store calculation
3162 // state in viewport properties
3163 jaa.autoCalculated = true; // means annotation will be marked for
3164 // update at end of load.
3166 if (an[i].hasGraphHeight())
3168 jaa.graphHeight = an[i].getGraphHeight();
3170 if (an[i].hasBelowAlignment())
3172 jaa.belowAlignment = an[i].isBelowAlignment();
3174 jaa.setCalcId(an[i].getCalcId());
3175 if (an[i].getPropertyCount() > 0)
3177 for (jalview.schemabinding.version2.Property prop : an[i]
3180 jaa.setProperty(prop.getName(), prop.getValue());
3183 if (jaa.autoCalculated)
3185 autoAlan.add(new JvAnnotRow(i, jaa));
3188 // if (!autoForView)
3190 // add autocalculated group annotation and any user created annotation
3192 al.addAnnotation(jaa);
3196 // ///////////////////////
3198 // Create alignment markup and styles for this view
3199 if (jms.getJGroupCount() > 0)
3201 JGroup[] groups = jms.getJGroup();
3202 boolean addAnnotSchemeGroup = false;
3203 for (int i = 0; i < groups.length; i++)
3205 JGroup jGroup = groups[i];
3206 ColourSchemeI cs = null;
3207 if (jGroup.getColour() != null)
3209 if (jGroup.getColour().startsWith("ucs"))
3211 cs = getUserColourScheme(jms, jGroup.getColour());
3213 else if (jGroup.getColour().equals("AnnotationColourGradient")
3214 && jGroup.getAnnotationColours() != null)
3216 addAnnotSchemeGroup = true;
3221 cs = ColourSchemeProperty.getColour(al, jGroup.getColour());
3226 cs.setThreshold(jGroup.getPidThreshold(), true);
3230 Vector<SequenceI> seqs = new Vector<SequenceI>();
3232 for (int s = 0; s < jGroup.getSeqCount(); s++)
3234 String seqId = jGroup.getSeq(s) + "";
3235 SequenceI ts = seqRefIds.get(seqId);
3239 seqs.addElement(ts);
3243 if (seqs.size() < 1)
3248 SequenceGroup sg = new SequenceGroup(seqs, jGroup.getName(), cs,
3249 jGroup.getDisplayBoxes(), jGroup.getDisplayText(),
3250 jGroup.getColourText(), jGroup.getStart(), jGroup.getEnd());
3252 sg.setOutlineColour(new java.awt.Color(jGroup.getOutlineColour()));
3254 sg.textColour = new java.awt.Color(jGroup.getTextCol1());
3255 sg.textColour2 = new java.awt.Color(jGroup.getTextCol2());
3256 sg.setShowNonconserved(jGroup.hasShowUnconserved() ? jGroup
3257 .isShowUnconserved() : false);
3258 sg.thresholdTextColour = jGroup.getTextColThreshold();
3259 if (jGroup.hasShowConsensusHistogram())
3261 sg.setShowConsensusHistogram(jGroup.isShowConsensusHistogram());
3264 if (jGroup.hasShowSequenceLogo())
3266 sg.setshowSequenceLogo(jGroup.isShowSequenceLogo());
3268 if (jGroup.hasNormaliseSequenceLogo())
3270 sg.setNormaliseSequenceLogo(jGroup.isNormaliseSequenceLogo());
3272 if (jGroup.hasIgnoreGapsinConsensus())
3274 sg.setIgnoreGapsConsensus(jGroup.getIgnoreGapsinConsensus());
3276 if (jGroup.getConsThreshold() != 0)
3278 jalview.analysis.Conservation c = new jalview.analysis.Conservation(
3279 "All", ResidueProperties.propHash, 3,
3280 sg.getSequences(null), 0, sg.getWidth() - 1);
3282 c.verdict(false, 25);
3283 sg.cs.setConservation(c);
3286 if (jGroup.getId() != null && groupAnnotRefs.size() > 0)
3288 // re-instate unique group/annotation row reference
3289 List<AlignmentAnnotation> jaal = groupAnnotRefs.get(jGroup
3293 for (AlignmentAnnotation jaa : jaal)
3296 if (jaa.autoCalculated)
3298 // match up and try to set group autocalc alignment row for this
3300 if (jaa.label.startsWith("Consensus for "))
3302 sg.setConsensus(jaa);
3304 // match up and try to set group autocalc alignment row for this
3306 if (jaa.label.startsWith("Conservation for "))
3308 sg.setConservationRow(jaa);
3315 if (addAnnotSchemeGroup)
3317 // reconstruct the annotation colourscheme
3318 sg.cs = constructAnnotationColour(jGroup.getAnnotationColours(),
3319 null, al, jms, false);
3325 // only dataset in this model, so just return.
3328 // ///////////////////////////////
3331 // If we just load in the same jar file again, the sequenceSetId
3332 // will be the same, and we end up with multiple references
3333 // to the same sequenceSet. We must modify this id on load
3334 // so that each load of the file gives a unique id
3335 String uniqueSeqSetId = view.getSequenceSetId() + uniqueSetSuffix;
3336 String viewId = (view.getId() == null ? null : view.getId()
3338 AlignFrame af = null;
3339 AlignViewport av = null;
3340 // now check to see if we really need to create a new viewport.
3341 if (multipleView && viewportsAdded.size() == 0)
3343 // We recovered an alignment for which a viewport already exists.
3344 // TODO: fix up any settings necessary for overlaying stored state onto
3345 // state recovered from another document. (may not be necessary).
3346 // we may need a binding from a viewport in memory to one recovered from
3348 // and then recover its containing af to allow the settings to be applied.
3349 // TODO: fix for vamsas demo
3351 .println("About to recover a viewport for existing alignment: Sequence set ID is "
3353 Object seqsetobj = retrieveExistingObj(uniqueSeqSetId);
3354 if (seqsetobj != null)
3356 if (seqsetobj instanceof String)
3358 uniqueSeqSetId = (String) seqsetobj;
3360 .println("Recovered extant sequence set ID mapping for ID : New Sequence set ID is "
3366 .println("Warning : Collision between sequence set ID string and existing jalview object mapping.");
3372 * indicate that annotation colours are applied across all groups (pre
3373 * Jalview 2.8.1 behaviour)
3375 boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan(
3376 "2.8.1", object.getVersion());
3378 AlignmentPanel ap = null;
3379 boolean isnewview = true;
3382 // Check to see if this alignment already has a view id == viewId
3383 jalview.gui.AlignmentPanel views[] = Desktop
3384 .getAlignmentPanels(uniqueSeqSetId);
3385 if (views != null && views.length > 0)
3387 for (int v = 0; v < views.length; v++)
3389 if (views[v].av.getViewId().equalsIgnoreCase(viewId))
3391 // recover the existing alignpanel, alignframe, viewport
3392 af = views[v].alignFrame;
3395 // TODO: could even skip resetting view settings if we don't want to
3396 // change the local settings from other jalview processes
3405 af = loadViewport(file, jseqs, hiddenSeqs, al, jms, view,
3406 uniqueSeqSetId, viewId, autoAlan);
3412 * Load any trees, PDB structures and viewers
3414 * Not done if flag is false (when this method is used for New View)
3416 if (loadTreesAndStructures)
3418 loadTrees(jms, view, af, av, ap);
3419 loadPDBStructures(jprovider, jseqs, af, ap);
3420 loadRnaViewers(jprovider, jseqs, ap);
3422 // and finally return.
3427 * Instantiate and link any saved RNA (Varna) viewers. The state of the Varna
3428 * panel is restored from separate jar entries, two (gapped and trimmed) per
3429 * sequence and secondary structure.
3431 * Currently each viewer shows just one sequence and structure (gapped and
3432 * trimmed), however this method is designed to support multiple sequences or
3433 * structures in viewers if wanted in future.
3439 private void loadRnaViewers(jarInputStreamProvider jprovider,
3440 JSeq[] jseqs, AlignmentPanel ap)
3443 * scan the sequences for references to viewers; create each one the first
3444 * time it is referenced, add Rna models to existing viewers
3446 for (JSeq jseq : jseqs)
3448 for (int i = 0; i < jseq.getRnaViewerCount(); i++)
3450 RnaViewer viewer = jseq.getRnaViewer(i);
3451 AppVarna appVarna = findOrCreateVarnaViewer(viewer,
3452 uniqueSetSuffix, ap);
3454 for (int j = 0; j < viewer.getSecondaryStructureCount(); j++)
3456 SecondaryStructure ss = viewer.getSecondaryStructure(j);
3457 SequenceI seq = seqRefIds.get(jseq.getId());
3458 AlignmentAnnotation ann = this.annotationIds.get(ss
3459 .getAnnotationId());
3462 * add the structure to the Varna display (with session state copied
3463 * from the jar to a temporary file)
3465 boolean gapped = ss.isGapped();
3466 String rnaTitle = ss.getTitle();
3467 String sessionState = ss.getViewerState();
3468 String tempStateFile = copyJarEntry(jprovider, sessionState,
3470 RnaModel rna = new RnaModel(rnaTitle, ann, seq, null, gapped);
3471 appVarna.addModelSession(rna, rnaTitle, tempStateFile);
3473 appVarna.setInitialSelection(viewer.getSelectedRna());
3479 * Locate and return an already instantiated matching AppVarna, or create one
3483 * @param viewIdSuffix
3487 protected AppVarna findOrCreateVarnaViewer(RnaViewer viewer,
3488 String viewIdSuffix, AlignmentPanel ap)
3491 * on each load a suffix is appended to the saved viewId, to avoid conflicts
3492 * if load is repeated
3494 String postLoadId = viewer.getViewId() + viewIdSuffix;
3495 for (JInternalFrame frame : getAllFrames())
3497 if (frame instanceof AppVarna)
3499 AppVarna varna = (AppVarna) frame;
3500 if (postLoadId.equals(varna.getViewId()))
3502 // this viewer is already instantiated
3503 // could in future here add ap as another 'parent' of the
3504 // AppVarna window; currently just 1-to-many
3511 * viewer not found - make it
3513 RnaViewerModel model = new RnaViewerModel(postLoadId,
3514 viewer.getTitle(), viewer.getXpos(), viewer.getYpos(),
3515 viewer.getWidth(), viewer.getHeight(),
3516 viewer.getDividerLocation());
3517 AppVarna varna = new AppVarna(model, ap);
3523 * Load any saved trees
3531 protected void loadTrees(JalviewModelSequence jms, Viewport view,
3532 AlignFrame af, AlignViewport av, AlignmentPanel ap)
3534 // TODO result of automated refactoring - are all these parameters needed?
3537 for (int t = 0; t < jms.getTreeCount(); t++)
3540 Tree tree = jms.getTree(t);
3542 TreePanel tp = (TreePanel) retrieveExistingObj(tree.getId());
3545 tp = af.ShowNewickTree(
3546 new jalview.io.NewickFile(tree.getNewick()),
3547 tree.getTitle(), tree.getWidth(), tree.getHeight(),
3548 tree.getXpos(), tree.getYpos());
3549 if (tree.getId() != null)
3551 // perhaps bind the tree id to something ?
3556 // update local tree attributes ?
3557 // TODO: should check if tp has been manipulated by user - if so its
3558 // settings shouldn't be modified
3559 tp.setTitle(tree.getTitle());
3560 tp.setBounds(new Rectangle(tree.getXpos(), tree.getYpos(), tree
3561 .getWidth(), tree.getHeight()));
3562 tp.av = av; // af.viewport; // TODO: verify 'associate with all
3565 tp.treeCanvas.av = av; // af.viewport;
3566 tp.treeCanvas.ap = ap; // af.alignPanel;
3571 warn("There was a problem recovering stored Newick tree: \n"
3572 + tree.getNewick());
3576 tp.fitToWindow.setState(tree.getFitToWindow());
3577 tp.fitToWindow_actionPerformed(null);
3579 if (tree.getFontName() != null)
3581 tp.setTreeFont(new java.awt.Font(tree.getFontName(), tree
3582 .getFontStyle(), tree.getFontSize()));
3586 tp.setTreeFont(new java.awt.Font(view.getFontName(), view
3587 .getFontStyle(), tree.getFontSize()));
3590 tp.showPlaceholders(tree.getMarkUnlinked());
3591 tp.showBootstrap(tree.getShowBootstrap());
3592 tp.showDistances(tree.getShowDistances());
3594 tp.treeCanvas.threshold = tree.getThreshold();
3596 if (tree.getCurrentTree())
3598 af.viewport.setCurrentTree(tp.getTree());
3602 } catch (Exception ex)
3604 ex.printStackTrace();
3609 * Load and link any saved structure viewers.
3616 protected void loadPDBStructures(jarInputStreamProvider jprovider,
3617 JSeq[] jseqs, AlignFrame af, AlignmentPanel ap)
3620 * Run through all PDB ids on the alignment, and collect mappings between
3621 * distinct view ids and all sequences referring to that view.
3623 Map<String, StructureViewerModel> structureViewers = new LinkedHashMap<String, StructureViewerModel>();
3625 for (int i = 0; i < jseqs.length; i++)
3627 if (jseqs[i].getPdbidsCount() > 0)
3629 Pdbids[] ids = jseqs[i].getPdbids();
3630 for (int p = 0; p < ids.length; p++)
3632 final int structureStateCount = ids[p].getStructureStateCount();
3633 for (int s = 0; s < structureStateCount; s++)
3635 // check to see if we haven't already created this structure view
3636 final StructureState structureState = ids[p]
3637 .getStructureState(s);
3638 String sviewid = (structureState.getViewId() == null) ? null
3639 : structureState.getViewId() + uniqueSetSuffix;
3640 jalview.datamodel.PDBEntry jpdb = new jalview.datamodel.PDBEntry();
3641 // Originally : ids[p].getFile()
3642 // : TODO: verify external PDB file recovery still works in normal
3643 // jalview project load
3644 jpdb.setFile(loadPDBFile(jprovider, ids[p].getId()));
3645 jpdb.setId(ids[p].getId());
3647 int x = structureState.getXpos();
3648 int y = structureState.getYpos();
3649 int width = structureState.getWidth();
3650 int height = structureState.getHeight();
3652 // Probably don't need to do this anymore...
3653 // Desktop.desktop.getComponentAt(x, y);
3654 // TODO: NOW: check that this recovers the PDB file correctly.
3655 String pdbFile = loadPDBFile(jprovider, ids[p].getId());
3656 jalview.datamodel.SequenceI seq = seqRefIds.get(jseqs[i]
3658 if (sviewid == null)
3660 sviewid = "_jalview_pre2_4_" + x + "," + y + "," + width
3663 if (!structureViewers.containsKey(sviewid))
3665 structureViewers.put(sviewid,
3666 new StructureViewerModel(x, y, width, height, false,
3667 false, true, structureState.getViewId(),
3668 structureState.getType()));
3669 // Legacy pre-2.7 conversion JAL-823 :
3670 // do not assume any view has to be linked for colour by
3674 // assemble String[] { pdb files }, String[] { id for each
3675 // file }, orig_fileloc, SequenceI[][] {{ seqs_file 1 }, {
3676 // seqs_file 2}, boolean[] {
3677 // linkAlignPanel,superposeWithAlignpanel}} from hash
3678 StructureViewerModel jmoldat = structureViewers.get(sviewid);
3679 jmoldat.setAlignWithPanel(jmoldat.isAlignWithPanel()
3680 | (structureState.hasAlignwithAlignPanel() ? structureState
3681 .getAlignwithAlignPanel() : false));
3684 * Default colour by linked panel to false if not specified (e.g.
3685 * for pre-2.7 projects)
3687 boolean colourWithAlignPanel = jmoldat.isColourWithAlignPanel();
3688 colourWithAlignPanel |= (structureState
3689 .hasColourwithAlignPanel() ? structureState
3690 .getColourwithAlignPanel() : false);
3691 jmoldat.setColourWithAlignPanel(colourWithAlignPanel);
3694 * Default colour by viewer to true if not specified (e.g. for
3697 boolean colourByViewer = jmoldat.isColourByViewer();
3698 colourByViewer &= structureState.hasColourByJmol() ? structureState
3699 .getColourByJmol() : true;
3700 jmoldat.setColourByViewer(colourByViewer);
3702 if (jmoldat.getStateData().length() < structureState
3703 .getContent().length())
3706 jmoldat.setStateData(structureState.getContent());
3709 if (ids[p].getFile() != null)
3711 File mapkey = new File(ids[p].getFile());
3712 StructureData seqstrmaps = jmoldat.getFileData().get(mapkey);
3713 if (seqstrmaps == null)
3715 jmoldat.getFileData().put(
3717 seqstrmaps = jmoldat.new StructureData(pdbFile,
3720 if (!seqstrmaps.getSeqList().contains(seq))
3722 seqstrmaps.getSeqList().add(seq);
3728 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");
3735 // Instantiate the associated structure views
3736 for (Entry<String, StructureViewerModel> entry : structureViewers
3741 createOrLinkStructureViewer(entry, af, ap, jprovider);
3742 } catch (Exception e)
3744 System.err.println("Error loading structure viewer: "
3746 // failed - try the next one
3758 protected void createOrLinkStructureViewer(
3759 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3760 AlignmentPanel ap, jarInputStreamProvider jprovider)
3762 final StructureViewerModel stateData = viewerData.getValue();
3765 * Search for any viewer windows already open from other alignment views
3766 * that exactly match the stored structure state
3768 StructureViewerBase comp = findMatchingViewer(viewerData);
3772 linkStructureViewer(ap, comp, stateData);
3777 * From 2.9: stateData.type contains JMOL or CHIMERA, data is in jar entry
3778 * "viewer_"+stateData.viewId
3780 if (ViewerType.CHIMERA.toString().equals(stateData.getType()))
3782 createChimeraViewer(viewerData, af, jprovider);
3787 * else Jmol (if pre-2.9, stateData contains JMOL state string)
3789 createJmolViewer(viewerData, af, jprovider);
3794 * Create a new Chimera viewer.
3800 protected void createChimeraViewer(
3801 Entry<String, StructureViewerModel> viewerData, AlignFrame af,
3802 jarInputStreamProvider jprovider)
3804 StructureViewerModel data = viewerData.getValue();
3805 String chimeraSessionFile = data.getStateData();
3808 * Copy Chimera session from jar entry "viewer_"+viewId to a temporary file
3810 * NB this is the 'saved' viewId as in the project file XML, _not_ the
3811 * 'uniquified' sviewid used to reconstruct the viewer here
3813 String viewerJarEntryName = getViewerJarEntryName(data.getViewId());
3814 chimeraSessionFile = copyJarEntry(jprovider, viewerJarEntryName,
3817 Set<Entry<File, StructureData>> fileData = data.getFileData()
3819 List<PDBEntry> pdbs = new ArrayList<PDBEntry>();
3820 List<SequenceI[]> allseqs = new ArrayList<SequenceI[]>();
3821 for (Entry<File, StructureData> pdb : fileData)
3823 String filePath = pdb.getValue().getFilePath();
3824 String pdbId = pdb.getValue().getPdbId();
3825 // pdbs.add(new PDBEntry(filePath, pdbId));
3826 pdbs.add(new PDBEntry(pdbId, null, PDBEntry.Type.PDB, filePath));
3827 final List<SequenceI> seqList = pdb.getValue().getSeqList();
3828 SequenceI[] seqs = seqList.toArray(new SequenceI[seqList.size()]);
3832 boolean colourByChimera = data.isColourByViewer();
3833 boolean colourBySequence = data.isColourWithAlignPanel();
3835 // TODO use StructureViewer as a factory here, see JAL-1761
3836 final PDBEntry[] pdbArray = pdbs.toArray(new PDBEntry[pdbs.size()]);
3837 final SequenceI[][] seqsArray = allseqs.toArray(new SequenceI[allseqs
3839 String newViewId = viewerData.getKey();
3841 ChimeraViewFrame cvf = new ChimeraViewFrame(chimeraSessionFile,
3842 af.alignPanel, pdbArray, seqsArray, colourByChimera,
3843 colourBySequence, newViewId);
3844 cvf.setSize(data.getWidth(), data.getHeight());
3845 cvf.setLocation(data.getX(), data.getY());
3849 * Create a new Jmol window. First parse the Jmol state to translate filenames
3850 * loaded into the view, and record the order in which files are shown in the
3851 * Jmol view, so we can add the sequence mappings in same order.
3857 protected void createJmolViewer(
3858 final Entry<String, StructureViewerModel> viewerData,
3859 AlignFrame af, jarInputStreamProvider jprovider)
3861 final StructureViewerModel svattrib = viewerData.getValue();
3862 String state = svattrib.getStateData();
3865 * Pre-2.9: state element value is the Jmol state string
3867 * 2.9+: @type is "JMOL", state data is in a Jar file member named "viewer_"
3870 if (ViewerType.JMOL.toString().equals(svattrib.getType()))
3872 state = readJarEntry(jprovider,
3873 getViewerJarEntryName(svattrib.getViewId()));
3876 List<String> pdbfilenames = new ArrayList<String>();
3877 List<SequenceI[]> seqmaps = new ArrayList<SequenceI[]>();
3878 List<String> pdbids = new ArrayList<String>();
3879 StringBuilder newFileLoc = new StringBuilder(64);
3880 int cp = 0, ncp, ecp;
3881 Map<File, StructureData> oldFiles = svattrib.getFileData();
3882 while ((ncp = state.indexOf("load ", cp)) > -1)
3886 // look for next filename in load statement
3887 newFileLoc.append(state.substring(cp,
3888 ncp = (state.indexOf("\"", ncp + 1) + 1)));
3889 String oldfilenam = state.substring(ncp,
3890 ecp = state.indexOf("\"", ncp));
3891 // recover the new mapping data for this old filename
3892 // have to normalize filename - since Jmol and jalview do
3894 // translation differently.
3895 StructureData filedat = oldFiles.get(new File(oldfilenam));
3896 newFileLoc.append(Platform.escapeString(filedat.getFilePath()));
3897 pdbfilenames.add(filedat.getFilePath());
3898 pdbids.add(filedat.getPdbId());
3899 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3900 newFileLoc.append("\"");
3901 cp = ecp + 1; // advance beyond last \" and set cursor so we can
3902 // look for next file statement.
3903 } while ((ncp = state.indexOf("/*file*/", cp)) > -1);
3907 // just append rest of state
3908 newFileLoc.append(state.substring(cp));
3912 System.err.print("Ignoring incomplete Jmol state for PDB ids: ");
3913 newFileLoc = new StringBuilder(state);
3914 newFileLoc.append("; load append ");
3915 for (File id : oldFiles.keySet())
3917 // add this and any other pdb files that should be present in
3919 StructureData filedat = oldFiles.get(id);
3920 newFileLoc.append(filedat.getFilePath());
3921 pdbfilenames.add(filedat.getFilePath());
3922 pdbids.add(filedat.getPdbId());
3923 seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
3924 newFileLoc.append(" \"");
3925 newFileLoc.append(filedat.getFilePath());
3926 newFileLoc.append("\"");
3929 newFileLoc.append(";");
3932 if (newFileLoc.length() == 0)
3936 int histbug = newFileLoc.indexOf("history = ");
3940 * change "history = [true|false];" to "history = [1|0];"
3943 int diff = histbug == -1 ? -1 : newFileLoc.indexOf(";", histbug);
3944 String val = (diff == -1) ? null : newFileLoc
3945 .substring(histbug, diff);
3946 if (val != null && val.length() >= 4)
3948 if (val.contains("e")) // eh? what can it be?
3950 if (val.trim().equals("true"))
3958 newFileLoc.replace(histbug, diff, val);
3963 final String[] pdbf = pdbfilenames.toArray(new String[pdbfilenames
3965 final String[] id = pdbids.toArray(new String[pdbids.size()]);
3966 final SequenceI[][] sq = seqmaps
3967 .toArray(new SequenceI[seqmaps.size()][]);
3968 final String fileloc = newFileLoc.toString();
3969 final String sviewid = viewerData.getKey();
3970 final AlignFrame alf = af;
3971 final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
3972 svattrib.getWidth(), svattrib.getHeight());
3975 javax.swing.SwingUtilities.invokeAndWait(new Runnable()
3980 JalviewStructureDisplayI sview = null;
3983 sview = new StructureViewer(alf.alignPanel
3984 .getStructureSelectionManager()).createView(
3985 StructureViewer.ViewerType.JMOL, pdbf, id, sq,
3986 alf.alignPanel, svattrib, fileloc, rect, sviewid);
3987 addNewStructureViewer(sview);
3988 } catch (OutOfMemoryError ex)
3990 new OOMWarning("restoring structure view for PDB id " + id,
3991 (OutOfMemoryError) ex.getCause());
3992 if (sview != null && sview.isVisible())
3994 sview.closeViewer(false);
3995 sview.setVisible(false);
4001 } catch (InvocationTargetException ex)
4003 warn("Unexpected error when opening Jmol view.", ex);
4005 } catch (InterruptedException e)
4007 // e.printStackTrace();
4013 * Generates a name for the entry in the project jar file to hold state
4014 * information for a structure viewer
4019 protected String getViewerJarEntryName(String viewId)
4021 return VIEWER_PREFIX + viewId;
4025 * Returns any open frame that matches given structure viewer data. The match
4026 * is based on the unique viewId, or (for older project versions) the frame's
4032 protected StructureViewerBase findMatchingViewer(
4033 Entry<String, StructureViewerModel> viewerData)
4035 final String sviewid = viewerData.getKey();
4036 final StructureViewerModel svattrib = viewerData.getValue();
4037 StructureViewerBase comp = null;
4038 JInternalFrame[] frames = getAllFrames();
4039 for (JInternalFrame frame : frames)
4041 if (frame instanceof StructureViewerBase)
4044 * Post jalview 2.4 schema includes structure view id
4047 && ((StructureViewerBase) frame).getViewId()
4050 comp = (StructureViewerBase) frame;
4051 break; // break added in 2.9
4054 * Otherwise test for matching position and size of viewer frame
4056 else if (frame.getX() == svattrib.getX()
4057 && frame.getY() == svattrib.getY()
4058 && frame.getHeight() == svattrib.getHeight()
4059 && frame.getWidth() == svattrib.getWidth())
4061 comp = (StructureViewerBase) frame;
4062 // no break in faint hope of an exact match on viewId
4070 * Link an AlignmentPanel to an existing structure viewer.
4075 * @param useinViewerSuperpos
4076 * @param usetoColourbyseq
4077 * @param viewerColouring
4079 protected void linkStructureViewer(AlignmentPanel ap,
4080 StructureViewerBase viewer, StructureViewerModel stateData)
4082 // NOTE: if the jalview project is part of a shared session then
4083 // view synchronization should/could be done here.
4085 final boolean useinViewerSuperpos = stateData.isAlignWithPanel();
4086 final boolean usetoColourbyseq = stateData.isColourWithAlignPanel();
4087 final boolean viewerColouring = stateData.isColourByViewer();
4088 Map<File, StructureData> oldFiles = stateData.getFileData();
4091 * Add mapping for sequences in this view to an already open viewer
4093 final AAStructureBindingModel binding = viewer.getBinding();
4094 for (File id : oldFiles.keySet())
4096 // add this and any other pdb files that should be present in the
4098 StructureData filedat = oldFiles.get(id);
4099 String pdbFile = filedat.getFilePath();
4100 SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
4101 binding.getSsm().setMapping(seq, null, pdbFile,
4102 jalview.io.AppletFormatAdapter.FILE);
4103 binding.addSequenceForStructFile(pdbFile, seq);
4105 // and add the AlignmentPanel's reference to the view panel
4106 viewer.addAlignmentPanel(ap);
4107 if (useinViewerSuperpos)
4109 viewer.useAlignmentPanelForSuperposition(ap);
4113 viewer.excludeAlignmentPanelForSuperposition(ap);
4115 if (usetoColourbyseq)
4117 viewer.useAlignmentPanelForColourbyseq(ap, !viewerColouring);
4121 viewer.excludeAlignmentPanelForColourbyseq(ap);
4126 * Get all frames within the Desktop.
4130 protected JInternalFrame[] getAllFrames()
4132 JInternalFrame[] frames = null;
4133 // TODO is this necessary - is it safe - risk of hanging?
4138 frames = Desktop.desktop.getAllFrames();
4139 } catch (ArrayIndexOutOfBoundsException e)
4141 // occasional No such child exceptions are thrown here...
4145 } catch (InterruptedException f)
4149 } while (frames == null);
4154 * Answers true if 'version' is equal to or later than 'supported', where each
4155 * is formatted as major/minor versions like "2.8.3" or "2.3.4b1" for bugfix
4156 * changes. Development and test values for 'version' are leniently treated
4160 * - minimum version we are comparing against
4162 * - version of data being processsed
4165 public static boolean isVersionStringLaterThan(String supported,
4168 if (supported == null || version == null
4169 || version.equalsIgnoreCase("DEVELOPMENT BUILD")
4170 || version.equalsIgnoreCase("Test")
4171 || version.equalsIgnoreCase("AUTOMATED BUILD"))
4173 System.err.println("Assuming project file with "
4174 + (version == null ? "null" : version)
4175 + " is compatible with Jalview version " + supported);
4180 return StringUtils.compareVersions(version, supported, "b") >= 0;
4184 Vector<JalviewStructureDisplayI> newStructureViewers = null;
4186 protected void addNewStructureViewer(JalviewStructureDisplayI sview)
4188 if (newStructureViewers != null)
4190 sview.getBinding().setFinishedLoadingFromArchive(false);
4191 newStructureViewers.add(sview);
4195 protected void setLoadingFinishedForNewStructureViewers()
4197 if (newStructureViewers != null)
4199 for (JalviewStructureDisplayI sview : newStructureViewers)
4201 sview.getBinding().setFinishedLoadingFromArchive(true);
4203 newStructureViewers.clear();
4204 newStructureViewers = null;
4208 AlignFrame loadViewport(String file, JSeq[] JSEQ,
4209 List<SequenceI> hiddenSeqs, AlignmentI al,
4210 JalviewModelSequence jms, Viewport view, String uniqueSeqSetId,
4211 String viewId, List<JvAnnotRow> autoAlan)
4213 AlignFrame af = null;
4214 af = new AlignFrame(al, view.getWidth(), view.getHeight(),
4215 uniqueSeqSetId, viewId);
4217 af.setFileName(file, "Jalview");
4219 for (int i = 0; i < JSEQ.length; i++)
4221 af.viewport.setSequenceColour(af.viewport.getAlignment()
4222 .getSequenceAt(i), new java.awt.Color(JSEQ[i].getColour()));
4227 af.getViewport().setColourByReferenceSeq(true);
4228 af.getViewport().setDisplayReferenceSeq(true);
4231 af.viewport.setGatherViewsHere(view.getGatheredViews());
4233 if (view.getSequenceSetId() != null)
4235 AlignmentViewport av = viewportsAdded.get(uniqueSeqSetId);
4237 af.viewport.setSequenceSetId(uniqueSeqSetId);
4240 // propagate shared settings to this new view
4241 af.viewport.setHistoryList(av.getHistoryList());
4242 af.viewport.setRedoList(av.getRedoList());
4246 viewportsAdded.put(uniqueSeqSetId, af.viewport);
4248 // TODO: check if this method can be called repeatedly without
4249 // side-effects if alignpanel already registered.
4250 PaintRefresher.Register(af.alignPanel, uniqueSeqSetId);
4252 // apply Hidden regions to view.
4253 if (hiddenSeqs != null)
4255 for (int s = 0; s < JSEQ.length; s++)
4257 SequenceGroup hidden = new SequenceGroup();
4258 boolean isRepresentative = false;
4259 for (int r = 0; r < JSEQ[s].getHiddenSequencesCount(); r++)
4261 isRepresentative = true;
4262 SequenceI sequenceToHide = al.getSequenceAt(JSEQ[s]
4263 .getHiddenSequences(r));
4264 hidden.addSequence(sequenceToHide, false);
4265 // remove from hiddenSeqs list so we don't try to hide it twice
4266 hiddenSeqs.remove(sequenceToHide);
4268 if (isRepresentative)
4270 SequenceI representativeSequence = al.getSequenceAt(s);
4271 hidden.addSequence(representativeSequence, false);
4272 af.viewport.hideRepSequences(representativeSequence, hidden);
4276 SequenceI[] hseqs = hiddenSeqs.toArray(new SequenceI[hiddenSeqs
4278 af.viewport.hideSequence(hseqs);
4281 // recover view properties and display parameters
4282 if (view.getViewName() != null)
4284 af.viewport.viewName = view.getViewName();
4285 af.setInitialTabVisible();
4287 af.setBounds(view.getXpos(), view.getYpos(), view.getWidth(),
4290 af.viewport.setShowAnnotation(view.getShowAnnotation());
4291 af.viewport.setAbovePIDThreshold(view.getPidSelected());
4293 af.viewport.setColourText(view.getShowColourText());
4295 af.viewport.setConservationSelected(view.getConservationSelected());
4296 af.viewport.setShowJVSuffix(view.getShowFullId());
4297 af.viewport.setRightAlignIds(view.getRightAlignIds());
4298 af.viewport.setFont(
4299 new java.awt.Font(view.getFontName(), view.getFontStyle(), view
4300 .getFontSize()), true);
4301 ViewStyleI vs = af.viewport.getViewStyle();
4302 vs.setScaleProteinAsCdna(view.isScaleProteinAsCdna());
4303 af.viewport.setViewStyle(vs);
4304 // TODO: allow custom charWidth/Heights to be restored by updating them
4305 // after setting font - which means set above to false
4306 af.viewport.setRenderGaps(view.getRenderGaps());
4307 af.viewport.setWrapAlignment(view.getWrapAlignment());
4308 af.viewport.setShowAnnotation(view.getShowAnnotation());
4310 af.viewport.setShowBoxes(view.getShowBoxes());
4312 af.viewport.setShowText(view.getShowText());
4314 af.viewport.setTextColour(new java.awt.Color(view.getTextCol1()));
4315 af.viewport.setTextColour2(new java.awt.Color(view.getTextCol2()));
4316 af.viewport.setThresholdTextColour(view.getTextColThreshold());
4317 af.viewport.setShowUnconserved(view.hasShowUnconserved() ? view
4318 .isShowUnconserved() : false);
4319 af.viewport.setStartRes(view.getStartRes());
4320 af.viewport.setStartSeq(view.getStartSeq());
4321 af.alignPanel.updateLayout();
4322 ColourSchemeI cs = null;
4323 // apply colourschemes
4324 if (view.getBgColour() != null)
4326 if (view.getBgColour().startsWith("ucs"))
4328 cs = getUserColourScheme(jms, view.getBgColour());
4330 else if (view.getBgColour().startsWith("Annotation"))
4332 AnnotationColours viewAnnColour = view.getAnnotationColours();
4333 cs = constructAnnotationColour(viewAnnColour, af, al, jms, true);
4340 cs = ColourSchemeProperty.getColour(al, view.getBgColour());
4345 cs.setThreshold(view.getPidThreshold(), true);
4346 cs.setConsensus(af.viewport.getSequenceConsensusHash());
4350 af.viewport.setGlobalColourScheme(cs);
4351 af.viewport.setColourAppliesToAllGroups(false);
4353 if (view.getConservationSelected() && cs != null)
4355 cs.setConservationInc(view.getConsThreshold());
4358 af.changeColour(cs);
4360 af.viewport.setColourAppliesToAllGroups(true);
4362 af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
4364 if (view.hasCentreColumnLabels())
4366 af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
4368 if (view.hasIgnoreGapsinConsensus())
4370 af.viewport.setIgnoreGapsConsensus(view.getIgnoreGapsinConsensus(),
4373 if (view.hasFollowHighlight())
4375 af.viewport.setFollowHighlight(view.getFollowHighlight());
4377 if (view.hasFollowSelection())
4379 af.viewport.followSelection = view.getFollowSelection();
4381 if (view.hasShowConsensusHistogram())
4383 af.viewport.setShowConsensusHistogram(view
4384 .getShowConsensusHistogram());
4388 af.viewport.setShowConsensusHistogram(true);
4390 if (view.hasShowSequenceLogo())
4392 af.viewport.setShowSequenceLogo(view.getShowSequenceLogo());
4396 af.viewport.setShowSequenceLogo(false);
4398 if (view.hasNormaliseSequenceLogo())
4400 af.viewport.setNormaliseSequenceLogo(view.getNormaliseSequenceLogo());
4402 if (view.hasShowDbRefTooltip())
4404 af.viewport.setShowDBRefs(view.getShowDbRefTooltip());
4406 if (view.hasShowNPfeatureTooltip())
4408 af.viewport.setShowNPFeats(view.hasShowNPfeatureTooltip());
4410 if (view.hasShowGroupConsensus())
4412 af.viewport.setShowGroupConsensus(view.getShowGroupConsensus());
4416 af.viewport.setShowGroupConsensus(false);
4418 if (view.hasShowGroupConservation())
4420 af.viewport.setShowGroupConservation(view.getShowGroupConservation());
4424 af.viewport.setShowGroupConservation(false);
4427 // recover featre settings
4428 if (jms.getFeatureSettings() != null)
4430 FeaturesDisplayed fdi;
4431 af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
4432 String[] renderOrder = new String[jms.getFeatureSettings()
4433 .getSettingCount()];
4434 Map<String, FeatureColourI> featureColours = new Hashtable<String, FeatureColourI>();
4435 Map<String, Float> featureOrder = new Hashtable<String, Float>();
4437 for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
4439 Setting setting = jms.getFeatureSettings().getSetting(fs);
4440 if (setting.hasMincolour())
4442 FeatureColourI gc = setting.hasMin() ? new FeatureColour(
4443 new Color(setting.getMincolour()), new Color(
4444 setting.getColour()), setting.getMin(),
4445 setting.getMax()) : new FeatureColour(new Color(
4446 setting.getMincolour()), new Color(setting.getColour()),
4448 if (setting.hasThreshold())
4450 gc.setThreshold(setting.getThreshold());
4451 int threshstate = setting.getThreshstate();
4452 // -1 = None, 0 = Below, 1 = Above threshold
4453 if (threshstate == 0)
4455 gc.setBelowThreshold(true);
4457 else if (threshstate == 1)
4459 gc.setAboveThreshold(true);
4462 gc.setAutoScaled(true); // default
4463 if (setting.hasAutoScale())
4465 gc.setAutoScaled(setting.getAutoScale());
4467 if (setting.hasColourByLabel())
4469 gc.setColourByLabel(setting.getColourByLabel());
4471 // and put in the feature colour table.
4472 featureColours.put(setting.getType(), gc);
4476 featureColours.put(setting.getType(), new FeatureColour(
4477 new Color(setting.getColour())));
4479 renderOrder[fs] = setting.getType();
4480 if (setting.hasOrder())
4482 featureOrder.put(setting.getType(), setting.getOrder());
4486 featureOrder.put(setting.getType(), new Float(fs
4487 / jms.getFeatureSettings().getSettingCount()));
4489 if (setting.getDisplay())
4491 fdi.setVisible(setting.getType());
4494 Map<String, Boolean> fgtable = new Hashtable<String, Boolean>();
4495 for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
4497 Group grp = jms.getFeatureSettings().getGroup(gs);
4498 fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
4500 // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
4501 // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
4502 // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
4503 FeatureRendererSettings frs = new FeatureRendererSettings(
4504 renderOrder, fgtable, featureColours, 1.0f, featureOrder);
4505 af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
4506 .transferSettings(frs);
4510 if (view.getHiddenColumnsCount() > 0)
4512 for (int c = 0; c < view.getHiddenColumnsCount(); c++)
4514 af.viewport.hideColumns(view.getHiddenColumns(c).getStart(), view
4515 .getHiddenColumns(c).getEnd() // +1
4519 if (view.getCalcIdParam() != null)
4521 for (CalcIdParam calcIdParam : view.getCalcIdParam())
4523 if (calcIdParam != null)
4525 if (recoverCalcIdParam(calcIdParam, af.viewport))
4530 warn("Couldn't recover parameters for "
4531 + calcIdParam.getCalcId());
4536 af.setMenusFromViewport(af.viewport);
4538 // TODO: we don't need to do this if the viewport is aready visible.
4540 * Add the AlignFrame to the desktop (it may be 'gathered' later), unless it
4541 * has a 'cdna/protein complement' view, in which case save it in order to
4542 * populate a SplitFrame once all views have been read in.
4544 String complementaryViewId = view.getComplementId();
4545 if (complementaryViewId == null)
4547 Desktop.addInternalFrame(af, view.getTitle(), view.getWidth(),
4549 // recompute any autoannotation
4550 af.alignPanel.updateAnnotation(false, true);
4551 reorderAutoannotation(af, al, autoAlan);
4552 af.alignPanel.alignmentChanged();
4556 splitFrameCandidates.put(view, af);
4561 private ColourSchemeI constructAnnotationColour(
4562 AnnotationColours viewAnnColour, AlignFrame af, AlignmentI al,
4563 JalviewModelSequence jms, boolean checkGroupAnnColour)
4565 boolean propagateAnnColour = false;
4566 ColourSchemeI cs = null;
4567 AlignmentI annAlignment = af != null ? af.viewport.getAlignment() : al;
4568 if (checkGroupAnnColour && al.getGroups() != null
4569 && al.getGroups().size() > 0)
4571 // pre 2.8.1 behaviour
4572 // check to see if we should transfer annotation colours
4573 propagateAnnColour = true;
4574 for (jalview.datamodel.SequenceGroup sg : al.getGroups())
4576 if (sg.cs instanceof AnnotationColourGradient)
4578 propagateAnnColour = false;
4582 // int find annotation
4583 if (annAlignment.getAlignmentAnnotation() != null)
4585 for (int i = 0; i < annAlignment.getAlignmentAnnotation().length; i++)
4587 if (annAlignment.getAlignmentAnnotation()[i].label
4588 .equals(viewAnnColour.getAnnotation()))
4590 if (annAlignment.getAlignmentAnnotation()[i].getThreshold() == null)
4592 annAlignment.getAlignmentAnnotation()[i]
4593 .setThreshold(new jalview.datamodel.GraphLine(
4594 viewAnnColour.getThreshold(), "Threshold",
4595 java.awt.Color.black)
4600 if (viewAnnColour.getColourScheme().equals("None"))
4602 cs = new AnnotationColourGradient(
4603 annAlignment.getAlignmentAnnotation()[i],
4604 new java.awt.Color(viewAnnColour.getMinColour()),
4605 new java.awt.Color(viewAnnColour.getMaxColour()),
4606 viewAnnColour.getAboveThreshold());
4608 else if (viewAnnColour.getColourScheme().startsWith("ucs"))
4610 cs = new AnnotationColourGradient(
4611 annAlignment.getAlignmentAnnotation()[i],
4612 getUserColourScheme(jms,
4613 viewAnnColour.getColourScheme()),
4614 viewAnnColour.getAboveThreshold());
4618 cs = new AnnotationColourGradient(
4619 annAlignment.getAlignmentAnnotation()[i],
4620 ColourSchemeProperty.getColour(al,
4621 viewAnnColour.getColourScheme()),
4622 viewAnnColour.getAboveThreshold());
4624 if (viewAnnColour.hasPerSequence())
4626 ((AnnotationColourGradient) cs).setSeqAssociated(viewAnnColour
4629 if (viewAnnColour.hasPredefinedColours())
4631 ((AnnotationColourGradient) cs)
4632 .setPredefinedColours(viewAnnColour
4633 .isPredefinedColours());
4635 if (propagateAnnColour && al.getGroups() != null)
4637 // Also use these settings for all the groups
4638 for (int g = 0; g < al.getGroups().size(); g++)
4640 jalview.datamodel.SequenceGroup sg = al.getGroups().get(g);
4648 * if (viewAnnColour.getColourScheme().equals("None" )) { sg.cs =
4649 * new AnnotationColourGradient(
4650 * annAlignment.getAlignmentAnnotation()[i], new
4651 * java.awt.Color(viewAnnColour. getMinColour()), new
4652 * java.awt.Color(viewAnnColour. getMaxColour()),
4653 * viewAnnColour.getAboveThreshold()); } else
4656 sg.cs = new AnnotationColourGradient(
4657 annAlignment.getAlignmentAnnotation()[i], sg.cs,
4658 viewAnnColour.getAboveThreshold());
4659 if (cs instanceof AnnotationColourGradient)
4661 if (viewAnnColour.hasPerSequence())
4663 ((AnnotationColourGradient) cs)
4664 .setSeqAssociated(viewAnnColour.isPerSequence());
4666 if (viewAnnColour.hasPredefinedColours())
4668 ((AnnotationColourGradient) cs)
4669 .setPredefinedColours(viewAnnColour
4670 .isPredefinedColours());
4686 private void reorderAutoannotation(AlignFrame af, AlignmentI al,
4687 List<JvAnnotRow> autoAlan)
4689 // copy over visualization settings for autocalculated annotation in the
4691 if (al.getAlignmentAnnotation() != null)
4694 * Kludge for magic autoannotation names (see JAL-811)
4696 String[] magicNames = new String[] { "Consensus", "Quality",
4698 JvAnnotRow nullAnnot = new JvAnnotRow(-1, null);
4699 Hashtable<String, JvAnnotRow> visan = new Hashtable<String, JvAnnotRow>();
4700 for (String nm : magicNames)
4702 visan.put(nm, nullAnnot);
4704 for (JvAnnotRow auan : autoAlan)
4706 visan.put(auan.template.label
4707 + (auan.template.getCalcId() == null ? "" : "\t"
4708 + auan.template.getCalcId()), auan);
4710 int hSize = al.getAlignmentAnnotation().length;
4711 List<JvAnnotRow> reorder = new ArrayList<JvAnnotRow>();
4712 // work through any autoCalculated annotation already on the view
4713 // removing it if it should be placed in a different location on the
4714 // annotation panel.
4715 List<String> remains = new ArrayList<String>(visan.keySet());
4716 for (int h = 0; h < hSize; h++)
4718 jalview.datamodel.AlignmentAnnotation jalan = al
4719 .getAlignmentAnnotation()[h];
4720 if (jalan.autoCalculated)
4723 JvAnnotRow valan = visan.get(k = jalan.label);
4724 if (jalan.getCalcId() != null)
4726 valan = visan.get(k = jalan.label + "\t" + jalan.getCalcId());
4731 // delete the auto calculated row from the alignment
4732 al.deleteAnnotation(jalan, false);
4736 if (valan != nullAnnot)
4738 if (jalan != valan.template)
4740 // newly created autoannotation row instance
4741 // so keep a reference to the visible annotation row
4742 // and copy over all relevant attributes
4743 if (valan.template.graphHeight >= 0)
4746 jalan.graphHeight = valan.template.graphHeight;
4748 jalan.visible = valan.template.visible;
4750 reorder.add(new JvAnnotRow(valan.order, jalan));
4755 // Add any (possibly stale) autocalculated rows that were not appended to
4756 // the view during construction
4757 for (String other : remains)
4759 JvAnnotRow othera = visan.get(other);
4760 if (othera != nullAnnot && othera.template.getCalcId() != null
4761 && othera.template.getCalcId().length() > 0)
4763 reorder.add(othera);
4766 // now put the automatic annotation in its correct place
4767 int s = 0, srt[] = new int[reorder.size()];
4768 JvAnnotRow[] rws = new JvAnnotRow[reorder.size()];
4769 for (JvAnnotRow jvar : reorder)
4772 srt[s++] = jvar.order;
4775 jalview.util.QuickSort.sort(srt, rws);
4776 // and re-insert the annotation at its correct position
4777 for (JvAnnotRow jvar : rws)
4779 al.addAnnotation(jvar.template, jvar.order);
4781 af.alignPanel.adjustAnnotationHeight();
4785 Hashtable skipList = null;
4788 * TODO remove this method
4791 * @return AlignFrame bound to sequenceSetId from view, if one exists. private
4792 * AlignFrame getSkippedFrame(Viewport view) { if (skipList==null) {
4793 * throw new Error("Implementation Error. No skipList defined for this
4794 * Jalview2XML instance."); } return (AlignFrame)
4795 * skipList.get(view.getSequenceSetId()); }
4799 * Check if the Jalview view contained in object should be skipped or not.
4802 * @return true if view's sequenceSetId is a key in skipList
4804 private boolean skipViewport(JalviewModel object)
4806 if (skipList == null)
4811 if (skipList.containsKey(id = object.getJalviewModelSequence()
4812 .getViewport()[0].getSequenceSetId()))
4814 if (Cache.log != null && Cache.log.isDebugEnabled())
4816 Cache.log.debug("Skipping seuqence set id " + id);
4823 public void addToSkipList(AlignFrame af)
4825 if (skipList == null)
4827 skipList = new Hashtable();
4829 skipList.put(af.getViewport().getSequenceSetId(), af);
4832 public void clearSkipList()
4834 if (skipList != null)
4841 private void recoverDatasetFor(SequenceSet vamsasSet, AlignmentI al,
4842 boolean ignoreUnrefed)
4844 jalview.datamodel.AlignmentI ds = getDatasetFor(vamsasSet
4846 Vector dseqs = null;
4849 // create a list of new dataset sequences
4850 dseqs = new Vector();
4852 for (int i = 0, iSize = vamsasSet.getSequenceCount(); i < iSize; i++)
4854 Sequence vamsasSeq = vamsasSet.getSequence(i);
4855 ensureJalviewDatasetSequence(vamsasSeq, ds, dseqs, ignoreUnrefed);
4857 // create a new dataset
4860 SequenceI[] dsseqs = new SequenceI[dseqs.size()];
4861 dseqs.copyInto(dsseqs);
4862 ds = new jalview.datamodel.Alignment(dsseqs);
4863 debug("Created new dataset " + vamsasSet.getDatasetId()
4864 + " for alignment " + System.identityHashCode(al));
4865 addDatasetRef(vamsasSet.getDatasetId(), ds);
4867 // set the dataset for the newly imported alignment.
4868 if (al.getDataset() == null && !ignoreUnrefed)
4877 * sequence definition to create/merge dataset sequence for
4881 * vector to add new dataset sequence to
4883 private void ensureJalviewDatasetSequence(Sequence vamsasSeq,
4884 AlignmentI ds, Vector dseqs, boolean ignoreUnrefed)
4886 // JBP TODO: Check this is called for AlCodonFrames to support recovery of
4888 SequenceI sq = seqRefIds.get(vamsasSeq.getId());
4889 SequenceI dsq = null;
4890 if (sq != null && sq.getDatasetSequence() != null)
4892 dsq = sq.getDatasetSequence();
4894 if (sq == null && ignoreUnrefed)
4898 String sqid = vamsasSeq.getDsseqid();
4901 // need to create or add a new dataset sequence reference to this sequence
4904 dsq = seqRefIds.get(sqid);
4909 // make a new dataset sequence
4910 dsq = sq.createDatasetSequence();
4913 // make up a new dataset reference for this sequence
4914 sqid = seqHash(dsq);
4916 dsq.setVamsasId(uniqueSetSuffix + sqid);
4917 seqRefIds.put(sqid, dsq);
4922 dseqs.addElement(dsq);
4927 ds.addSequence(dsq);
4933 { // make this dataset sequence sq's dataset sequence
4934 sq.setDatasetSequence(dsq);
4935 // and update the current dataset alignment
4940 if (!dseqs.contains(dsq))
4947 if (ds.findIndex(dsq) < 0)
4949 ds.addSequence(dsq);
4956 // TODO: refactor this as a merge dataset sequence function
4957 // now check that sq (the dataset sequence) sequence really is the union of
4958 // all references to it
4959 // boolean pre = sq.getStart() < dsq.getStart();
4960 // boolean post = sq.getEnd() > dsq.getEnd();
4964 // StringBuffer sb = new StringBuffer();
4965 String newres = jalview.analysis.AlignSeq.extractGaps(
4966 jalview.util.Comparison.GapChars, sq.getSequenceAsString());
4967 if (!newres.equalsIgnoreCase(dsq.getSequenceAsString())
4968 && newres.length() > dsq.getLength())
4970 // Update with the longer sequence.
4974 * if (pre) { sb.insert(0, newres .substring(0, dsq.getStart() -
4975 * sq.getStart())); dsq.setStart(sq.getStart()); } if (post) {
4976 * sb.append(newres.substring(newres.length() - sq.getEnd() -
4977 * dsq.getEnd())); dsq.setEnd(sq.getEnd()); }
4979 dsq.setSequence(newres);
4981 // TODO: merges will never happen if we 'know' we have the real dataset
4982 // sequence - this should be detected when id==dssid
4984 .println("DEBUG Notice: Merged dataset sequence (if you see this often, post at http://issues.jalview.org/browse/JAL-1474)"); // ("
4985 // + (pre ? "prepended" : "") + " "
4986 // + (post ? "appended" : ""));
4992 * TODO use AlignmentI here and in related methods - needs
4993 * AlignmentI.getDataset() changed to return AlignmentI instead of Alignment
4995 Hashtable<String, AlignmentI> datasetIds = null;
4997 IdentityHashMap<AlignmentI, String> dataset2Ids = null;
4999 private AlignmentI getDatasetFor(String datasetId)
5001 if (datasetIds == null)
5003 datasetIds = new Hashtable<String, AlignmentI>();
5006 if (datasetIds.containsKey(datasetId))
5008 return datasetIds.get(datasetId);
5013 private void addDatasetRef(String datasetId, AlignmentI dataset)
5015 if (datasetIds == null)
5017 datasetIds = new Hashtable<String, AlignmentI>();
5019 datasetIds.put(datasetId, dataset);
5023 * make a new dataset ID for this jalview dataset alignment
5028 private String getDatasetIdRef(AlignmentI dataset)
5030 if (dataset.getDataset() != null)
5032 warn("Serious issue! Dataset Object passed to getDatasetIdRef is not a Jalview DATASET alignment...");
5034 String datasetId = makeHashCode(dataset, null);
5035 if (datasetId == null)
5037 // make a new datasetId and record it
5038 if (dataset2Ids == null)
5040 dataset2Ids = new IdentityHashMap<AlignmentI, String>();
5044 datasetId = dataset2Ids.get(dataset);
5046 if (datasetId == null)
5048 datasetId = "ds" + dataset2Ids.size() + 1;
5049 dataset2Ids.put(dataset, datasetId);
5055 private void addDBRefs(SequenceI datasetSequence, Sequence sequence)
5057 for (int d = 0; d < sequence.getDBRefCount(); d++)
5059 DBRef dr = sequence.getDBRef(d);
5060 jalview.datamodel.DBRefEntry entry = new jalview.datamodel.DBRefEntry(
5061 sequence.getDBRef(d).getSource(), sequence.getDBRef(d)
5062 .getVersion(), sequence.getDBRef(d).getAccessionId());
5063 if (dr.getMapping() != null)
5065 entry.setMap(addMapping(dr.getMapping()));
5067 datasetSequence.addDBRef(entry);
5071 private jalview.datamodel.Mapping addMapping(Mapping m)
5073 SequenceI dsto = null;
5074 // Mapping m = dr.getMapping();
5075 int fr[] = new int[m.getMapListFromCount() * 2];
5076 Enumeration f = m.enumerateMapListFrom();
5077 for (int _i = 0; f.hasMoreElements(); _i += 2)
5079 MapListFrom mf = (MapListFrom) f.nextElement();
5080 fr[_i] = mf.getStart();
5081 fr[_i + 1] = mf.getEnd();
5083 int fto[] = new int[m.getMapListToCount() * 2];
5084 f = m.enumerateMapListTo();
5085 for (int _i = 0; f.hasMoreElements(); _i += 2)
5087 MapListTo mf = (MapListTo) f.nextElement();
5088 fto[_i] = mf.getStart();
5089 fto[_i + 1] = mf.getEnd();
5091 jalview.datamodel.Mapping jmap = new jalview.datamodel.Mapping(dsto,
5092 fr, fto, (int) m.getMapFromUnit(), (int) m.getMapToUnit());
5093 if (m.getMappingChoice() != null)
5095 MappingChoice mc = m.getMappingChoice();
5096 if (mc.getDseqFor() != null)
5098 String dsfor = "" + mc.getDseqFor();
5099 if (seqRefIds.containsKey(dsfor))
5104 jmap.setTo(seqRefIds.get(dsfor));
5108 frefedSequence.add(newMappingRef(dsfor, jmap));
5114 * local sequence definition
5116 Sequence ms = mc.getSequence();
5117 SequenceI djs = null;
5118 String sqid = ms.getDsseqid();
5119 if (sqid != null && sqid.length() > 0)
5122 * recover dataset sequence
5124 djs = seqRefIds.get(sqid);
5129 .println("Warning - making up dataset sequence id for DbRef sequence map reference");
5130 sqid = ((Object) ms).toString(); // make up a new hascode for
5131 // undefined dataset sequence hash
5132 // (unlikely to happen)
5138 * make a new dataset sequence and add it to refIds hash
5140 djs = new jalview.datamodel.Sequence(ms.getName(),
5142 djs.setStart(jmap.getMap().getToLowest());
5143 djs.setEnd(jmap.getMap().getToHighest());
5144 djs.setVamsasId(uniqueSetSuffix + sqid);
5146 incompleteSeqs.put(sqid, djs);
5147 seqRefIds.put(sqid, djs);
5150 jalview.bin.Cache.log.debug("about to recurse on addDBRefs.");
5159 public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
5160 boolean keepSeqRefs)
5163 JalviewModel jm = saveState(ap, null, null, null);
5168 jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
5172 uniqueSetSuffix = "";
5173 jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
5178 if (this.frefedSequence == null)
5180 frefedSequence = new Vector();
5183 viewportsAdded.clear();
5185 AlignFrame af = loadFromObject(jm, null, false, null);
5186 af.alignPanels.clear();
5187 af.closeMenuItem_actionPerformed(true);
5190 * if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
5191 * i<ap.av.getAlignment().getAlignmentAnnotation().length; i++) {
5192 * if(!ap.av.getAlignment().getAlignmentAnnotation()[i].autoCalculated) {
5193 * af.alignPanel.av.getAlignment().getAlignmentAnnotation()[i] =
5194 * ap.av.getAlignment().getAlignmentAnnotation()[i]; } } }
5197 return af.alignPanel;
5201 * flag indicating if hashtables should be cleared on finalization TODO this
5202 * flag may not be necessary
5204 private final boolean _cleartables = true;
5206 private Hashtable jvids2vobj;
5211 * @see java.lang.Object#finalize()
5214 protected void finalize() throws Throwable
5216 // really make sure we have no buried refs left.
5221 this.seqRefIds = null;
5222 this.seqsToIds = null;
5226 private void warn(String msg)
5231 private void warn(String msg, Exception e)
5233 if (Cache.log != null)
5237 Cache.log.warn(msg, e);
5241 Cache.log.warn(msg);
5246 System.err.println("Warning: " + msg);
5249 e.printStackTrace();
5254 private void debug(String string)
5256 debug(string, null);
5259 private void debug(String msg, Exception e)
5261 if (Cache.log != null)
5265 Cache.log.debug(msg, e);
5269 Cache.log.debug(msg);
5274 System.err.println("Warning: " + msg);
5277 e.printStackTrace();
5283 * set the object to ID mapping tables used to write/recover objects and XML
5284 * ID strings for the jalview project. If external tables are provided then
5285 * finalize and clearSeqRefs will not clear the tables when the Jalview2XML
5286 * object goes out of scope. - also populates the datasetIds hashtable with
5287 * alignment objects containing dataset sequences
5290 * Map from ID strings to jalview datamodel
5292 * Map from jalview datamodel to ID strings
5296 public void setObjectMappingTables(Hashtable vobj2jv,
5297 IdentityHashMap jv2vobj)
5299 this.jv2vobj = jv2vobj;
5300 this.vobj2jv = vobj2jv;
5301 Iterator ds = jv2vobj.keySet().iterator();
5303 while (ds.hasNext())
5305 Object jvobj = ds.next();
5306 id = jv2vobj.get(jvobj).toString();
5307 if (jvobj instanceof jalview.datamodel.Alignment)
5309 if (((jalview.datamodel.Alignment) jvobj).getDataset() == null)
5311 addDatasetRef(id, (jalview.datamodel.Alignment) jvobj);
5314 else if (jvobj instanceof jalview.datamodel.Sequence)
5316 // register sequence object so the XML parser can recover it.
5317 if (seqRefIds == null)
5319 seqRefIds = new HashMap<String, SequenceI>();
5321 if (seqsToIds == null)
5323 seqsToIds = new IdentityHashMap<SequenceI, String>();
5325 seqRefIds.put(jv2vobj.get(jvobj).toString(), (SequenceI) jvobj);
5326 seqsToIds.put((SequenceI) jvobj, id);
5328 else if (jvobj instanceof jalview.datamodel.AlignmentAnnotation)
5331 AlignmentAnnotation jvann = (AlignmentAnnotation) jvobj;
5332 annotationIds.put(anid = jv2vobj.get(jvobj).toString(), jvann);
5333 if (jvann.annotationId == null)
5335 jvann.annotationId = anid;
5337 if (!jvann.annotationId.equals(anid))
5339 // TODO verify that this is the correct behaviour
5340 this.warn("Overriding Annotation ID for " + anid
5341 + " from different id : " + jvann.annotationId);
5342 jvann.annotationId = anid;
5345 else if (jvobj instanceof String)
5347 if (jvids2vobj == null)
5349 jvids2vobj = new Hashtable();
5350 jvids2vobj.put(jvobj, jv2vobj.get(jvobj).toString());
5355 Cache.log.debug("Ignoring " + jvobj.getClass() + " (ID = " + id);
5361 * set the uniqueSetSuffix used to prefix/suffix object IDs for jalview
5362 * objects created from the project archive. If string is null (default for
5363 * construction) then suffix will be set automatically.
5367 public void setUniqueSetSuffix(String string)
5369 uniqueSetSuffix = string;
5374 * uses skipList2 as the skipList for skipping views on sequence sets
5375 * associated with keys in the skipList
5379 public void setSkipList(Hashtable skipList2)
5381 skipList = skipList2;
5385 * Reads the jar entry of given name and returns its contents, or null if the
5386 * entry is not found.
5389 * @param jarEntryName
5392 protected String readJarEntry(jarInputStreamProvider jprovider,
5393 String jarEntryName)
5395 String result = null;
5396 BufferedReader in = null;
5401 * Reopen the jar input stream and traverse its entries to find a matching
5404 JarInputStream jin = jprovider.getJarInputStream();
5405 JarEntry entry = null;
5408 entry = jin.getNextJarEntry();
5409 } while (entry != null && !entry.getName().equals(jarEntryName));
5413 StringBuilder out = new StringBuilder(256);
5414 in = new BufferedReader(new InputStreamReader(jin, UTF_8));
5417 while ((data = in.readLine()) != null)
5421 result = out.toString();
5425 warn("Couldn't find entry in Jalview Jar for " + jarEntryName);
5427 } catch (Exception ex)
5429 ex.printStackTrace();
5437 } catch (IOException e)
5448 * Returns an incrementing counter (0, 1, 2...)
5452 private synchronized int nextCounter()